0
|
1 // BSP support routine
|
|
2 #include "types.h"
|
|
3 #include "defs.h"
|
|
4 #include "param.h"
|
|
5 #include "memlayout.h"
|
|
6 #include "proc.h"
|
|
7 #include "arm.h"
|
|
8 #include "mmu.h"
|
|
9
|
|
10 void cli (void)
|
|
11 {
|
|
12 uint val;
|
|
13
|
|
14 // ok, enable paging using read/modify/write
|
|
15 asm("MRS %[v], cpsr": [v]"=r" (val)::);
|
|
16 val |= DIS_INT;
|
|
17 asm("MSR cpsr_cxsf, %[v]": :[v]"r" (val):);
|
|
18 }
|
|
19
|
|
20 void sti (void)
|
|
21 {
|
|
22 uint val;
|
|
23
|
|
24 // ok, enable paging using read/modify/write
|
|
25 asm("MRS %[v], cpsr": [v]"=r" (val)::);
|
|
26 val &= ~DIS_INT;
|
|
27 asm("MSR cpsr_cxsf, %[v]": :[v]"r" (val):);
|
|
28 }
|
|
29
|
|
30 // return the cpsr used for user program
|
|
31 uint spsr_usr ()
|
|
32 {
|
|
33 uint val;
|
|
34
|
|
35 // ok, enable paging using read/modify/write
|
|
36 asm("MRS %[v], cpsr": [v]"=r" (val)::);
|
|
37 val &= ~MODE_MASK;
|
|
38 val |= USR_MODE;
|
|
39
|
|
40 return val;
|
|
41 }
|
|
42
|
|
43 // return whether interrupt is currently enabled
|
|
44 int int_enabled ()
|
|
45 {
|
|
46 uint val;
|
|
47
|
|
48 // ok, enable paging using read/modify/write
|
|
49 asm("MRS %[v], cpsr": [v]"=r" (val)::);
|
|
50
|
|
51 return !(val & DIS_INT);
|
|
52 }
|
|
53
|
|
54 // Pushcli/popcli are like cli/sti except that they are matched:
|
|
55 // it takes two popcli to undo two pushcli. Also, if interrupts
|
|
56 // are off, then pushcli, popcli leaves them off.
|
|
57
|
|
58 void pushcli (void)
|
|
59 {
|
|
60 int enabled;
|
|
61
|
|
62 enabled = int_enabled();
|
|
63
|
|
64 cli();
|
|
65
|
|
66 if (cpu->ncli++ == 0) {
|
|
67 cpu->intena = enabled;
|
|
68 }
|
|
69 }
|
|
70
|
|
71 void popcli (void)
|
|
72 {
|
|
73 if (int_enabled()) {
|
|
74 panic("popcli - interruptible");
|
|
75 }
|
|
76
|
|
77 if (--cpu->ncli < 0) {
|
|
78 cprintf("cpu (%d)->ncli: %d\n", cpu, cpu->ncli);
|
|
79 panic("popcli -- ncli < 0");
|
|
80 }
|
|
81
|
|
82 if ((cpu->ncli == 0) && cpu->intena) {
|
|
83 sti();
|
|
84 }
|
|
85 }
|
|
86
|
|
87 // Record the current call stack in pcs[] by following the call chain.
|
|
88 // In ARM ABI, the function prologue is as:
|
|
89 // push {fp, lr}
|
|
90 // add fp, sp, #4
|
|
91 // so, fp points to lr, the return address
|
|
92 void getcallerpcs (void * v, uint pcs[])
|
|
93 {
|
|
94 uint *fp;
|
|
95 int i;
|
|
96
|
|
97 fp = (uint*) v;
|
|
98
|
|
99 for (i = 0; i < N_CALLSTK; i++) {
|
|
100 if ((fp == 0) || (fp < (uint*) KERNBASE) || (fp == (uint*) 0xffffffff)) {
|
|
101 break;
|
|
102 }
|
|
103
|
|
104 fp = fp - 1; // points fp to the saved fp
|
|
105 pcs[i] = fp[1]; // saved lr
|
|
106 fp = (uint*) fp[0]; // saved fp
|
|
107 }
|
|
108
|
|
109 for (; i < N_CALLSTK; i++) {
|
|
110 pcs[i] = 0;
|
|
111 }
|
|
112 }
|
|
113
|
|
114 void show_callstk (char *s)
|
|
115 {
|
|
116 int i;
|
|
117 uint pcs[N_CALLSTK];
|
|
118
|
|
119 cprintf("%s\n", s);
|
|
120
|
|
121 getcallerpcs(get_fp(), pcs);
|
|
122
|
|
123 for (i = N_CALLSTK - 1; i >= 0; i--) {
|
|
124 cprintf("%d: 0x%x\n", i + 1, pcs[i]);
|
|
125 }
|
|
126
|
|
127 }
|