Commit | Line | Data |
---|---|---|
08039264 H |
1 | ================================= |
2 | INTERNAL KERNEL ABI FOR FR-V ARCH | |
3 | ================================= | |
4 | ||
5 | The internal FRV kernel ABI is not quite the same as the userspace ABI. A | |
6 | number of the registers are used for special purposed, and the ABI is not | |
7 | consistent between modules vs core, and MMU vs no-MMU. | |
8 | ||
9 | This partly stems from the fact that FRV CPUs do not have a separate | |
10 | supervisor stack pointer, and most of them do not have any scratch | |
11 | registers, thus requiring at least one general purpose register to be | |
12 | clobbered in such an event. Also, within the kernel core, it is possible to | |
13 | simply jump or call directly between functions using a relative offset. | |
14 | This cannot be extended to modules for the displacement is likely to be too | |
15 | far. Thus in modules the address of a function to call must be calculated | |
16 | in a register and then used, requiring two extra instructions. | |
28baebae DH |
17 | |
18 | This document has the following sections: | |
19 | ||
20 | (*) System call register ABI | |
21 | (*) CPU operating modes | |
22 | (*) Internal kernel-mode register ABI | |
23 | (*) Internal debug-mode register ABI | |
24 | (*) Virtual interrupt handling | |
25 | ||
26 | ||
27 | ======================== | |
28 | SYSTEM CALL REGISTER ABI | |
29 | ======================== | |
30 | ||
31 | When a system call is made, the following registers are effective: | |
32 | ||
33 | REGISTERS CALL RETURN | |
34 | =============== ======================= ======================= | |
35 | GR7 System call number Preserved | |
36 | GR8 Syscall arg #1 Return value | |
37 | GR9-GR13 Syscall arg #2-6 Preserved | |
38 | ||
39 | ||
40 | =================== | |
41 | CPU OPERATING MODES | |
42 | =================== | |
43 | ||
08039264 H |
44 | The FR-V CPU has three basic operating modes. In order of increasing |
45 | capability: | |
28baebae DH |
46 | |
47 | (1) User mode. | |
48 | ||
49 | Basic userspace running mode. | |
50 | ||
51 | (2) Kernel mode. | |
52 | ||
08039264 H |
53 | Normal kernel mode. There are many additional control registers |
54 | available that may be accessed in this mode, in addition to all the | |
55 | stuff available to user mode. This has two submodes: | |
28baebae DH |
56 | |
57 | (a) Exceptions enabled (PSR.T == 1). | |
58 | ||
08039264 H |
59 | Exceptions will invoke the appropriate normal kernel mode |
60 | handler. On entry to the handler, the PSR.T bit will be cleared. | |
28baebae DH |
61 | |
62 | (b) Exceptions disabled (PSR.T == 0). | |
63 | ||
08039264 H |
64 | No exceptions or interrupts may happen. Any mandatory exceptions |
65 | will cause the CPU to halt unless the CPU is told to jump into | |
66 | debug mode instead. | |
28baebae DH |
67 | |
68 | (3) Debug mode. | |
69 | ||
08039264 H |
70 | No exceptions may happen in this mode. Memory protection and |
71 | management exceptions will be flagged for later consideration, but | |
72 | the exception handler won't be invoked. Debugging traps such as | |
73 | hardware breakpoints and watchpoints will be ignored. This mode is | |
74 | entered only by debugging events obtained from the other two modes. | |
28baebae | 75 | |
08039264 H |
76 | All kernel mode registers may be accessed, plus a few extra debugging |
77 | specific registers. | |
28baebae DH |
78 | |
79 | ||
80 | ================================= | |
81 | INTERNAL KERNEL-MODE REGISTER ABI | |
82 | ================================= | |
83 | ||
08039264 H |
84 | There are a number of permanent register assignments that are set up by |
85 | entry.S in the exception prologue. Note that there is a complete set of | |
86 | exception prologues for each of user->kernel transition and kernel->kernel | |
87 | transition. There are also user->debug and kernel->debug mode transition | |
88 | prologues. | |
28baebae DH |
89 | |
90 | ||
91 | REGISTER FLAVOUR USE | |
08039264 | 92 | =============== ======= ============================================== |
28baebae DH |
93 | GR1 Supervisor stack pointer |
94 | GR15 Current thread info pointer | |
95 | GR16 GP-Rel base register for small data | |
96 | GR28 Current exception frame pointer (__frame) | |
97 | GR29 Current task pointer (current) | |
98 | GR30 Destroyed by kernel mode entry | |
99 | GR31 NOMMU Destroyed by debug mode entry | |
100 | GR31 MMU Destroyed by TLB miss kernel mode entry | |
101 | CCR.ICC2 Virtual interrupt disablement tracking | |
08039264 H |
102 | CCCR.CC3 Cleared by exception prologue |
103 | (atomic op emulation) | |
28baebae DH |
104 | SCR0 MMU See mmu-layout.txt. |
105 | SCR1 MMU See mmu-layout.txt. | |
08039264 H |
106 | SCR2 MMU Save for EAR0 (destroyed by icache insns |
107 | in debug mode) | |
28baebae DH |
108 | SCR3 MMU Save for GR31 during debug exceptions |
109 | DAMR/IAMR NOMMU Fixed memory protection layout. | |
110 | DAMR/IAMR MMU See mmu-layout.txt. | |
111 | ||
112 | ||
113 | Certain registers are also used or modified across function calls: | |
114 | ||
115 | REGISTER CALL RETURN | |
08039264 | 116 | =============== =============================== ====================== |
28baebae DH |
117 | GR0 Fixed Zero - |
118 | GR2 Function call frame pointer | |
119 | GR3 Special Preserved | |
120 | GR3-GR7 - Clobbered | |
08039264 H |
121 | GR8 Function call arg #1 Return value |
122 | (or clobbered) | |
123 | GR9 Function call arg #2 Return value MSW | |
124 | (or clobbered) | |
28baebae DH |
125 | GR10-GR13 Function call arg #3-#6 Clobbered |
126 | GR14 - Clobbered | |
127 | GR15-GR16 Special Preserved | |
128 | GR17-GR27 - Preserved | |
08039264 H |
129 | GR28-GR31 Special Only accessed |
130 | explicitly | |
28baebae DH |
131 | LR Return address after CALL Clobbered |
132 | CCR/CCCR - Mostly Clobbered | |
133 | ||
134 | ||
135 | ================================ | |
136 | INTERNAL DEBUG-MODE REGISTER ABI | |
137 | ================================ | |
138 | ||
08039264 H |
139 | This is the same as the kernel-mode register ABI for functions calls. The |
140 | difference is that in debug-mode there's a different stack and a different | |
141 | exception frame. Almost all the global registers from kernel-mode | |
142 | (including the stack pointer) may be changed. | |
28baebae DH |
143 | |
144 | REGISTER FLAVOUR USE | |
08039264 | 145 | =============== ======= ============================================== |
28baebae DH |
146 | GR1 Debug stack pointer |
147 | GR16 GP-Rel base register for small data | |
08039264 H |
148 | GR31 Current debug exception frame pointer |
149 | (__debug_frame) | |
28baebae DH |
150 | SCR3 MMU Saved value of GR31 |
151 | ||
152 | ||
08039264 H |
153 | Note that debug mode is able to interfere with the kernel's emulated atomic |
154 | ops, so it must be exceedingly careful not to do any that would interact | |
155 | with the main kernel in this regard. Hence the debug mode code (gdbstub) is | |
156 | almost completely self-contained. The only external code used is the | |
157 | sprintf family of functions. | |
28baebae | 158 | |
5d3f083d | 159 | Furthermore, break.S is so complicated because single-step mode does not |
08039264 H |
160 | switch off on entry to an exception. That means unless manually disabled, |
161 | single-stepping will blithely go on stepping into things like interrupts. | |
162 | See gdbstub.txt for more information. | |
28baebae DH |
163 | |
164 | ||
165 | ========================== | |
166 | VIRTUAL INTERRUPT HANDLING | |
167 | ========================== | |
168 | ||
08039264 H |
169 | Because accesses to the PSR is so slow, and to disable interrupts we have |
170 | to access it twice (once to read and once to write), we don't actually | |
171 | disable interrupts at all if we don't have to. What we do instead is use | |
172 | the ICC2 condition code flags to note virtual disablement, such that if we | |
173 | then do take an interrupt, we note the flag, really disable interrupts, set | |
174 | another flag and resume execution at the point the interrupt happened. | |
175 | Setting condition flags as a side effect of an arithmetic or logical | |
176 | instruction is really fast. This use of the ICC2 only occurs within the | |
28baebae DH |
177 | kernel - it does not affect userspace. |
178 | ||
179 | The flags we use are: | |
180 | ||
181 | (*) CCR.ICC2.Z [Zero flag] | |
182 | ||
08039264 H |
183 | Set to virtually disable interrupts, clear when interrupts are |
184 | virtually enabled. Can be modified by logical instructions without | |
185 | affecting the Carry flag. | |
28baebae DH |
186 | |
187 | (*) CCR.ICC2.C [Carry flag] | |
188 | ||
189 | Clear to indicate hardware interrupts are really disabled, set otherwise. | |
190 | ||
191 | ||
192 | What happens is this: | |
193 | ||
194 | (1) Normal kernel-mode operation. | |
195 | ||
196 | ICC2.Z is 0, ICC2.C is 1. | |
197 | ||
08039264 H |
198 | (2) An interrupt occurs. The exception prologue examines ICC2.Z and |
199 | determines that nothing needs doing. This is done simply with an | |
200 | unlikely BEQ instruction. | |
28baebae DH |
201 | |
202 | (3) The interrupts are disabled (local_irq_disable) | |
203 | ||
204 | ICC2.Z is set to 1. | |
205 | ||
206 | (4) If interrupts were then re-enabled (local_irq_enable): | |
207 | ||
208 | ICC2.Z would be set to 0. | |
209 | ||
08039264 H |
210 | A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would |
211 | be used to trap if interrupts were now virtually enabled, but | |
212 | physically disabled - which they're not, so the trap isn't taken. The | |
213 | kernel would then be back to state (1). | |
28baebae | 214 | |
08039264 H |
215 | (5) An interrupt occurs. The exception prologue examines ICC2.Z and |
216 | determines that the interrupt shouldn't actually have happened. It | |
217 | jumps aside, and there disabled interrupts by setting PSR.PIL to 14 | |
218 | and then it clears ICC2.C. | |
28baebae DH |
219 | |
220 | (6) If interrupts were then saved and disabled again (local_irq_save): | |
221 | ||
08039264 H |
222 | ICC2.Z would be shifted into the save variable and masked off |
223 | (giving a 1). | |
28baebae | 224 | |
08039264 H |
225 | ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be |
226 | unaffected (ie: 0). | |
28baebae DH |
227 | |
228 | (7) If interrupts were then restored from state (6) (local_irq_restore): | |
229 | ||
08039264 H |
230 | ICC2.Z would be set to indicate the result of XOR'ing the saved |
231 | value (ie: 1) with 1, which gives a result of 0 - thus leaving | |
232 | ICC2.Z set. | |
28baebae DH |
233 | |
234 | ICC2.C would remain unaffected (ie: 0). | |
235 | ||
08039264 H |
236 | A TIHI #2 instruction would be used to again assay the current state, |
237 | but this would do nothing as Z==1. | |
28baebae DH |
238 | |
239 | (8) If interrupts were then enabled (local_irq_enable): | |
240 | ||
08039264 H |
241 | ICC2.Z would be cleared. ICC2.C would be left unaffected. Both |
242 | flags would now be 0. | |
28baebae | 243 | |
08039264 H |
244 | A TIHI #2 instruction again issued to assay the current state would |
245 | then trap as both Z==0 [interrupts virtually enabled] and C==0 | |
246 | [interrupts really disabled] would then be true. | |
28baebae | 247 | |
08039264 H |
248 | (9) The trap #2 handler would simply enable hardware interrupts |
249 | (set PSR.PIL to 0), set ICC2.C to 1 and return. | |
28baebae DH |
250 | |
251 | (10) Immediately upon returning, the pending interrupt would be taken. | |
252 | ||
08039264 H |
253 | (11) The interrupt handler would take the path of actually processing the |
254 | interrupt (ICC2.Z is clear, BEQ fails as per step (2)). | |
28baebae | 255 | |
08039264 H |
256 | (12) The interrupt handler would then set ICC2.C to 1 since hardware |
257 | interrupts are definitely enabled - or else the kernel wouldn't be here. | |
28baebae DH |
258 | |
259 | (13) On return from the interrupt handler, things would be back to state (1). | |
260 | ||
08039264 H |
261 | This trap (#2) is only available in kernel mode. In user mode it will |
262 | result in SIGILL. |