]> hackdaworld.org Git - my-code/arm.git/commitdiff
basic interrupt functions implemented
authorhackbard <hackbard@sage.physik.uni-augsburg.de>
Thu, 20 Sep 2007 12:57:57 +0000 (14:57 +0200)
committerhackbard <hackbard@sage.physik.uni-augsburg.de>
Thu, 20 Sep 2007 12:57:57 +0000 (14:57 +0200)
betty/interrupts.c
betty/interrupts.h

index 5327588fb12be0df7822d7e250f520c33d70a7bd..a96cc2f2a60581e2e9f3c936f7afe4b943279f9d 100644 (file)
@@ -7,27 +7,74 @@
 
 #include "interrupts.h"
 
+/*
+ * module static interrupt variable
+ */
+
+static t_interrupt interrupt;
+
 /*
  * functions
  */
 
+void interrupt_init(void) {
+
+       memset(&interrupt,0,sizeof(t_interrupt));
+       VICSoftIntClear=0xff;
+       VICIntEnClear=0xff;
+       VICDefVectAddr=0;
+}
+
 void interrupt_set_default_callback(void *callback) {
 
        VICDefVectAddr=(u32)callback;
-       
 }
 
+void interrupt_set_soft_callback(void (*callback)(void)) {
+
+       interrupt->default_soft_callback=callback;
+}
+
+void interrupt_soft_clear(u8 src_number) {
+
+       VICSoftIntClear=(1<<src_number);
+}
 void interrupt_clear(u8 src_number) {
 
+       int cnt;
+       u32 *addr;
+       u32 *cntl;
+
        VICIntEnClear=(1<<src_number);
+       VICIntSelect&=~(1<<src_number);
 
+       addr=&VICVectAddr0;
+       cntl=&VICVectCntl0;
+
+       for(cnt=0;cnt<INTERRUPT_MAX_VIC;cnt++) {
+               if(cntl[cnt]&0x1f==src_number) {
+                       *((volatile u32 *)(addr+cnt))=0;
+                       *((volatile u32 *)(cntl+cnt))=0;
+               }
+       }
 }
 
-int interrupt_enable(u8 src_number,u8 mode,u8 priority,void *callback) {
+void interrupt_soft_enable(u8 src_number) {
+       
+       VICSoftInt=(1<<src_number);
+}
+
+int interrupt_enable(u8 src_number,u8 mode,u8 priority,u32 callback_addr) {
+
+       u32 *addr;
+       u32 *cntl;
+
+       addr=&VICVectAddr0;
+       cntl=&VICVectCntl0;
 
        /* check whether this ir source is allready assigned */
        if(VICIntEnable&(1<<src_number))
-               return INTERRUPT_EINUSE;
+               return INTERRUPT_USED;
 
        /* force interrupt */
        VICIntEnable=(1<<src_number);
@@ -37,7 +84,10 @@ int interrupt_enable(u8 src_number,u8 mode,u8 priority,void *callback) {
                        VICIntSelect|=(1<<src_number);
                        break;
                case INTERRUPT_VIRQ:
-                       
+                       if(addr[p]&0x3f)
+                               return INTERRUP_PRIORITY_USED;
+                       *((volatile u32 *)(addr+p))=callback_addr;
+                       *((volatile u32 *)(cntl+p))=src_number&0x1f+(1<<5);
                case INTERRUPT_IRQ:
                case default:
        }
@@ -59,6 +109,9 @@ void interrupt_handler_undef_instruction(void) {
 
 // software interrupt
 void interrupt_handler_soft_ir(void) {
+       
+       if(interrupt.default_soft_callback)
+               interrupt.default_soft_callback();
 }
 
 // prefetch abort
index ab93f8f1ab1c5a0e508bf6b43d4bb71dd4197842..4ddee8fd697160357e9c64a379c60d5ac586b145 100644 (file)
 #define INTERRUPT_EXT_POLAR_HIGH       1
 
 #define INTERRUPT_SET                  0x00
-#define INTERRUPT_EINUSE               0x01
+#define INTERRUPT_USED                 0x01
+#define INTERRUPT_PRIORITY_USED                0x02
 
 /* type definitions */
 
 typedef struct s_interrupt {
-       void *default_callback;
-       u8 default_mode;
-       void *callback[INTERRUPT_MAX_VIC];
-       u8 mode[INTERRUPT_MAX_VIC];
+       void (*default_soft_callback)(void);
 } t_interrupt;
 
 /* function prototypes */