sys-interrupt.c
00001 #include <sys-interrupt.h>
00002 #include <interrupt-utils.h>
00003 #include <AT91SAM7S64.h>
00004
00005 #define ATTR
00006
00007 #ifndef NULL
00008 #define NULL 0
00009 #endif
00010
00011
00012 static SystemInterruptHandler *handlers = NULL;
00013
00014 static void
00015 system_int_safe (void) __attribute__((noinline));
00016
00017 static void
00018 system_int_safe (void)
00019 {
00020 SystemInterruptHandler *h;
00021 h = handlers;
00022 while (h) {
00023 if (h->handler()) break;
00024 h = h->next;
00025 }
00026 }
00027
00028 static void NACKEDFUNC ATTR
00029 system_int (void)
00030 {
00031 ISR_ENTRY();
00032 system_int_safe();
00033 *AT91C_AIC_EOICR = 0;
00034 ISR_EXIT();
00035 }
00036
00037 static unsigned int enabled = 0;
00038
00039
00040 #define DIS_INT *AT91C_AIC_IDCR = (1 << AT91C_ID_SYS)
00041 #define EN_INT if (enabled > 0) *AT91C_AIC_IECR = (1 << AT91C_ID_SYS)
00042
00043 void
00044 sys_interrupt_enable()
00045 {
00046 if (enabled++ == 0) {
00047
00048 AT91C_AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
00049
00050 AT91C_AIC_SVR[AT91C_ID_SYS] = (unsigned long) system_int;
00051
00052 EN_INT;
00053 }
00054 }
00055
00056
00057 void
00058 sys_interrupt_disable()
00059 {
00060 if (--enabled == 0) {
00061 DIS_INT;
00062 }
00063 }
00064
00065 void
00066 sys_interrupt_append_handler(SystemInterruptHandler *handler)
00067 {
00068 SystemInterruptHandler **h = &handlers;
00069 while(*h) {
00070 h = &(*h)->next;
00071 }
00072 DIS_INT;
00073 *h = handler;
00074 handler->next = NULL;
00075 EN_INT;
00076 }
00077
00078 void
00079 sys_interrupt_prepend_handler(SystemInterruptHandler *handler)
00080 {
00081 DIS_INT;
00082 handler->next = handlers;
00083 handlers = handler;
00084 EN_INT;
00085 }
00086
00087 void
00088 sys_interrupt_remove_handler(SystemInterruptHandler *handler)
00089 {
00090 SystemInterruptHandler **h = &handlers;
00091 while(*h) {
00092 if (*h == handler) {
00093 DIS_INT;
00094 *h = handler->next;
00095 EN_INT;
00096 break;
00097 }
00098 h = &(*h)->next;
00099 }
00100 }