mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
intc: allow any call in intc_handler_function()
This commit is contained in:
parent
0233088565
commit
42081c9968
5 changed files with 19 additions and 28 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue