intc: allow any call in intc_handler_function()

This commit is contained in:
Lephe 2021-04-28 17:37:40 +02:00
parent 0233088565
commit 42081c9968
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
5 changed files with 19 additions and 28 deletions

View file

@ -6,6 +6,7 @@
#define GINT_INTC #define GINT_INTC
#include <gint/defs/types.h> #include <gint/defs/types.h>
#include <gint/defs/call.h>
//--- //---
// Interrupt names // Interrupt names
@ -120,7 +121,7 @@ void *intc_handler(int event_code, void const *handler, size_t size);
/* intc_handler_function(): Install a function as an interrupt handler /* intc_handler_function(): Install a function as an interrupt handler
This function can be used to install simple interrupt handlers. It installs This function can be used to install simple interrupt handlers. It installs
a pre-written interrupt handler that calls back the provided function. a pre-written interrupt handler that performs the provided indirect call.
Essentially it means that the interrupt handler can be written in C without Essentially it means that the interrupt handler can be written in C without
the numerous constraints of intc_handler(), at the cost of always going back the numerous constraints of intc_handler(), at the cost of always going back
to userspace and a small time overhead. to userspace and a small time overhead.
@ -128,6 +129,6 @@ void *intc_handler(int event_code, void const *handler, size_t size);
@event_code Identifier of the interrupt block @event_code Identifier of the interrupt block
@function Function to use as a handler @function Function to use as a handler
Returns true on success, false if the event code is invalid. */ Returns true on success, false if the event code is invalid. */
bool intc_handler_function(int event_code, void (*function)(void)); bool intc_handler_function(int event_code, gint_call_t function);
#endif /* GINT_INTC */ #endif /* GINT_INTC */

View file

@ -1,3 +1,5 @@
#include <gint/intc.h>
#include <gint/gint.h>
#include <gint/drivers.h> #include <gint/drivers.h>
#include <gint/drivers/states.h> #include <gint/drivers/states.h>
#include <gint/hardware.h> #include <gint/hardware.h>
@ -170,15 +172,17 @@ void *intc_handler(int event_code, const void *handler, size_t size)
return memcpy(dest, handler, size); return memcpy(dest, handler, size);
} }
bool intc_handler_function(int event_code, void (*function)(void)) bool intc_handler_function(int event_code, gint_call_t function)
{ {
/* Install the genric handler */ /* Install the generic handler */
extern void intc_generic_handler(void); extern void intc_generic_handler(void);
void *h = intc_handler(event_code, intc_generic_handler, 32); void *h = intc_handler(event_code, intc_generic_handler, 32);
if(!h) return false; if(!h) return false;
/* Set the function to be called */ /* Copy the call */
*(void **)(h + 24) = function; memcpy(h + 8, &function, 20);
/* Copy the runtime address of gint_inth_callback() */
*(void **)(h + 28) = gint_inth_callback;
return true; return true;
} }

View file

@ -10,24 +10,10 @@
.align 4 .align 4
_intc_generic_handler: _intc_generic_handler:
/* Create a GINT_CALL() object with no arguments */ mova 1f, r0
sts.l pr, @-r15 mov.l 2f, r1
add #-20, r15 jmp @r1
mov.l .function, r0 mov r0, r4
mov.l r0, @r15
/* Call back to the function in userspace */ 1: .zero 20 /* Indirect call to be made */
mov.l .gint_inth_callback, r0 2: .long 0 /* Address of _gint_inth_callback at runtime */
mov.l @r0, r0
jsr @r0
mov r15, r4
add #20, r15
lds.l @r15+, pr
rts
nop
.function:
.long 0 /* Function, set when handler is installed */
.gint_inth_callback:
.long _gint_inth_callback

View file

@ -164,7 +164,7 @@ static void configure(void)
RTC->RCR2.PEF = 0; RTC->RCR2.PEF = 0;
/* Install the RTC interrupt handler */ /* Install the RTC interrupt handler */
intc_handler_function(0xaa0, rtc_periodic_interrupt); intc_handler_function(0xaa0, GINT_CALL(rtc_periodic_interrupt));
/* Disable the RTC interrupts for now. Give them priority 1; higher /* Disable the RTC interrupts for now. Give them priority 1; higher
priorities cause freezes when going back to the system on SH3 priorities cause freezes when going back to the system on SH3

View file

@ -169,7 +169,7 @@ int usb_open(usb_interface_t const **interfaces, gint_call_t callback)
USB.NRDYENB.word = 0x0000; USB.NRDYENB.word = 0x0000;
USB.BEMPENB.word = 0x0000; USB.BEMPENB.word = 0x0000;
intc_handler_function(0xa20, usb_interrupt_handler); intc_handler_function(0xa20, GINT_CALL(usb_interrupt_handler));
intc_priority(INTC_USB, 15); intc_priority(INTC_USB, 15);
usb_open_status = true; usb_open_status = true;