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