fighting with interrupt vectors
[rpikern] / src / intr.c
1 #include <stdio.h>
2 #include "intr.h"
3 #include "rpi.h"
4 #include "rpi_ioreg.h"
5 #include "asm.h"
6 #include "sysctl.h"
7 #include "debug.h"
8
9 void startup();
10 void intr_entry_nop();
11 void intr_entry_irq();
12
13 void intr_init(void)
14 {
15         /* setup interrupt vectors */
16         setvect(INTR_RESET, (uint32_t)startup);
17         setvect(INTR_UNDEF, (uint32_t)intr_entry_nop);
18         setvect(INTR_SWI, (uint32_t)intr_entry_nop);
19         setvect(INTR_IABORT, (uint32_t)intr_entry_nop);
20         setvect(INTR_DABORT, (uint32_t)intr_entry_nop);
21         setvect(INTR_IRQ, (uint32_t)intr_entry_irq);
22         setvect(INTR_FIQ, (uint32_t)intr_entry_irq);
23
24         printf("Exception vectors:\n");
25         hexdump(0, 32);
26 }
27
28 void setvect(int idx, uint32_t addr)
29 {
30         uint32_t *ivec = 0;
31         uint32_t pc = (idx << 2) + 8;
32
33         printf("setvect(%d, %lx)\n", idx, (unsigned long)addr);
34
35         /* construct branch instruction */
36         ivec[idx] = 0xea000000 | (addr - pc) >> 2;
37
38         /* we also probably need to invalidate the instr. cache */
39         sysctl_icache_inval(0, 32);
40 }
41
42 void enable_arm_irq(int irq)
43 {
44         mem_barrier();
45         if(irq == IRQ_TIMER) {
46                 IRQ_FIQCTL_REG = IRQ_FIQCTL_SELARM(IRQ_TIMER) | IRQ_FIQCTL_ENABLE;
47         } else {
48                 IRQ_ENABLE0_REG |= 1 << irq;
49         }
50         mem_barrier();
51 }
52
53 void disable_arm_irq(int irq)
54 {
55         mem_barrier();
56         if(irq == IRQ_TIMER) {
57                 IRQ_FIQCTL_REG = 0;
58         } else {
59                 IRQ_ENABLE0_REG &= ~(1 << irq);
60         }
61         mem_barrier();
62 }
63
64 void enable_gpu_irq(int irq)
65 {
66         mem_barrier();
67         /*if(irq == IRQ_GPU_TIMER1) {
68                 IRQ_FIQCTL_REG = IRQ_FIQCTL_SELGPU(IRQ_GPU_TIMER1) | IRQ_FIQCTL_ENABLE;
69         } else */if(irq < 32) {
70                 IRQ_ENABLE1_REG |= 1 << irq;
71         } else {
72                 IRQ_ENABLE2_REG |= 1 << (irq - 32);
73         }
74         mem_barrier();
75 }
76
77 void disable_gpu_irq(int irq)
78 {
79         mem_barrier();
80         /*if(irq == IRQ_GPU_TIMER1) {
81                 IRQ_FIQCTL_REG = 0;
82         } else */if(irq < 32) {
83                 IRQ_ENABLE1_REG &= ~(1 << irq);
84         } else {
85                 IRQ_ENABLE2_REG &= ~(1 << (irq - 32));
86         }
87         mem_barrier();
88 }