Mercurial > hg > Members > menikon > CbC_xv6
comparison src/device/picirq.c @ 0:83c23a36980d
Init
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 26 May 2017 23:11:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:83c23a36980d |
---|---|
1 // Support of ARM PrimeCell Vectored Interrrupt Controller (PL190) | |
2 #include "types.h" | |
3 #include "defs.h" | |
4 #include "param.h" | |
5 #include "arm.h" | |
6 #include "memlayout.h" | |
7 #include "mmu.h" | |
8 | |
9 // PL190 supports the vectored interrupts and non-vectored interrupts. | |
10 // In this code, we use non-vected interrupts (aka. simple interrupt). | |
11 // The flow to handle simple interrupts is as the following: | |
12 // 1. an interrupt (IRQ) occurs, trap.c branches to our IRQ handler | |
13 // 2. read the VICIRQStatus register, for each source generating | |
14 // the interrrupt: | |
15 // 2.1 locate the correct ISR | |
16 // 2.2 execute the ISR | |
17 // 2.3 clear the interrupt | |
18 // 3 return to trap.c, which will resume interrupted routines | |
19 // Note: must not read VICVectorAddr | |
20 | |
21 | |
22 // define the register offsets (in the unit of 4 bytes). The base address | |
23 // of the VIC depends on the board | |
24 static volatile uint* vic_base; | |
25 | |
26 #define VIC_IRQSTATUS 0 // status of interrupts after masking by ENABLE and SEL | |
27 #define VIC_FIQSTATUS 1 // status of interrupts after masking | |
28 #define VIC_RAWINTR 2 // status of interrupts before masking | |
29 #define VIC_INTSEL 3 // interrupt select (IRQ or FIQ), by default IRQ | |
30 #define VIC_INTENABLE 4 // enable interrupts (1 - enabled, 0 - disabled) | |
31 #define VIC_INTCLEAR 5 // clear bits in ENABLE register (1 - clear it) | |
32 #define VIC_PROTECTIOIN 8 // who can access: user or privileged | |
33 | |
34 #define NUM_INTSRC 32 // numbers of interrupt source supported | |
35 | |
36 static ISR isrs[NUM_INTSRC]; | |
37 | |
38 static void default_isr (struct trapframe *tf, int n) | |
39 { | |
40 cprintf ("unhandled interrupt: %d\n", n); | |
41 } | |
42 | |
43 // initialize the PL190 VIC | |
44 void pic_init (void * base) | |
45 { | |
46 int i; | |
47 | |
48 // set the base for the controller and disable all interrupts | |
49 vic_base = base; | |
50 vic_base[VIC_INTCLEAR] = 0xFFFFFFFF; | |
51 | |
52 for (i = 0; i < NUM_INTSRC; i++) { | |
53 isrs[i] = default_isr; | |
54 } | |
55 } | |
56 | |
57 // enable an interrupt (with the ISR) | |
58 void pic_enable (int n, ISR isr) | |
59 { | |
60 if ((n<0) || (n >= NUM_INTSRC)) { | |
61 panic ("invalid interrupt source"); | |
62 } | |
63 | |
64 // write 1 bit enable the interrupt, 0 bit has no effect | |
65 isrs[n] = isr; | |
66 vic_base[VIC_INTENABLE] = (1 << n); | |
67 } | |
68 | |
69 // disable an interrupt | |
70 void pic_disable (int n) | |
71 { | |
72 if ((n<0) || (n >= NUM_INTSRC)) { | |
73 panic ("invalid interrupt source"); | |
74 } | |
75 | |
76 vic_base[VIC_INTCLEAR] = (1 << n); | |
77 isrs[n] = default_isr; | |
78 } | |
79 | |
80 // dispatch the interrupt | |
81 void pic_dispatch (struct trapframe *tp) | |
82 { | |
83 uint intstatus; | |
84 int i; | |
85 | |
86 intstatus = vic_base[VIC_IRQSTATUS]; | |
87 | |
88 for (i = 0; i < NUM_INTSRC; i++) { | |
89 if (intstatus & (1<<i)) { | |
90 isrs[i](tp, i); | |
91 } | |
92 } | |
93 | |
94 intstatus = vic_base[VIC_IRQSTATUS]; | |
95 } | |
96 |