49ea0cdc488a81017170096921be0bea8aee2481
[my-code/arm.git] / betty / interrupts.c
1 /*
2  * interrupts.c - arm exception handling
3  *
4  * author: hackbard@hackdaworld.org
5  *
6  */
7
8 #include "interrupts.h"
9
10 // 'module global' interrupt variable
11 static t_interrupt interrupt;
12
13 /*
14  * functions
15  */
16
17 void interrupt_init(void) {
18
19         memset(&interrupt,0,sizeof(t_interrupt));
20         VICSoftIntClear=0xff;
21         VICIntEnClear=0xff;
22         VICDefVectAddr=0;
23 }
24
25 void interrupt_set_default_callback(u32 callback_addr) {
26
27         VICDefVectAddr=callback_addr;
28 }
29
30 void interrupt_set_soft_callback(void (*callback)(void)) {
31
32         interrupt->default_soft_callback=callback;
33 }
34
35 void interrupt_soft_clear(u8 src_number) {
36
37         VICSoftIntClear=(1<<src_number);
38 }
39 void interrupt_clear(u8 src_number) {
40
41         int cnt;
42         u32 *addr;
43         u32 *cntl;
44
45         VICIntEnClear=(1<<src_number);
46         VICIntSelect&=~(1<<src_number);
47
48         addr=&VICVectAddr0;
49         cntl=&VICVectCntl0;
50
51         for(cnt=0;cnt<INTERRUPT_MAX_VIC;cnt++) {
52                 if(cntl[cnt]&0x1f==src_number) {
53                         *((volatile u32 *)(addr+cnt))=0;
54                         *((volatile u32 *)(cntl+cnt))=0;
55                 }
56         }
57 }
58
59 void interrupt_soft_enable(u8 src_number) {
60         
61         VICSoftInt=(1<<src_number);
62 }
63
64 int interrupt_enable(u8 src_number,u8 mode,u8 priority,u32 callback_addr) {
65
66         u32 *addr;
67         u32 *cntl;
68
69         addr=&VICVectAddr0;
70         cntl=&VICVectCntl0;
71
72         /* check whether this ir source is allready assigned */
73         if(VICIntEnable&(1<<src_number))
74                 return INTERRUPT_USED;
75
76         /* force interrupt */
77         VICIntEnable=(1<<src_number);
78
79         switch(mode) {
80                 case INTERRUPT_MODE_FIQ:
81                         VICIntSelect|=(1<<src_number);
82                         break;
83                 case INTERRUPT_MODE_VIRQ:
84                         if(addr[p]&0x3f)
85                                 return INTERRUP_PRIORITY_USED;
86                         *((volatile u32 *)(addr+p))=callback_addr;
87                         *((volatile u32 *)(cntl+p))=src_number&0x1f+(1<<5);
88                 case INTERRUPT_MODE_IRQ:
89                 case default:
90         }
91
92         return INTERRUPT_SET;
93 }
94
95 void interrupt_ext_ir_config(u8 eint,u8 wakeup,u8 mode,u8 polarity) {
96
97         if(eint>3)
98                 return;
99
100         if(wakeup)
101                 EXTWAKE=(EXTWAKE&0xf)|(1<<eint);
102
103         EXTMODE=(EXTMODE&0xf)|(mode<<eint);
104         EXTPOLAR=(EXTPOLAR&0xf)|(polarity<<eint);
105         EXTINT=(EXTINT&0xf)|(1<<eint);
106 }
107
108 /*
109  * the actual exception handlers (as defined in startup.s)
110  */
111
112 // reset
113 void interrupt_handler_reset(void) {
114 }
115
116 // undefined instruction
117 void interrupt_handler_undef_instruction(void) {
118 }
119
120 // software interrupt
121 void interrupt_handler_soft_ir(void) {
122         
123         if(interrupt.default_soft_callback)
124                 interrupt.default_soft_callback();
125 }
126
127 // prefetch abort
128 void interrupt_handler_prefetch_abort(void) {
129 }
130
131 // data abort
132 void interrupt_handler_data_abort(void) {
133 }
134
135 // fiq
136 void interrupt_handler_fiq(void) {
137 }
138