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