Mercurial > hg > Members > anatofuz > CbC_xv6
comparison src/arm.c @ 0:83c23a36980d
Init
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 26 May 2017 23:11:05 +0900 |
parents | |
children | d876c9a65239 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:83c23a36980d |
---|---|
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 } |