annotate src/device/picirq.c @ 48:58ec26c64601

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