1 ================================= 2 INTERNAL KERNEL ABI FOR FR-V ARCH 3 ================================= 4 5The internal FRV kernel ABI is not quite the same as the userspace ABI. A 6number of the registers are used for special purposed, and the ABI is not 7consistent between modules vs core, and MMU vs no-MMU. 8 9This partly stems from the fact that FRV CPUs do not have a separate 10supervisor stack pointer, and most of them do not have any scratch 11registers, thus requiring at least one general purpose register to be 12clobbered in such an event. Also, within the kernel core, it is possible to 13simply jump or call directly between functions using a relative offset. 14This cannot be extended to modules for the displacement is likely to be too 15far. Thus in modules the address of a function to call must be calculated 16in a register and then used, requiring two extra instructions. 17 18This 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======================== 28SYSTEM CALL REGISTER ABI 29======================== 30 31When 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=================== 41CPU OPERATING MODES 42=================== 43 44The FR-V CPU has three basic operating modes. In order of increasing 45capability: 46 47 (1) User mode. 48 49 Basic userspace running mode. 50 51 (2) Kernel mode. 52 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: 56 57 (a) Exceptions enabled (PSR.T == 1). 58 59 Exceptions will invoke the appropriate normal kernel mode 60 handler. On entry to the handler, the PSR.T bit will be cleared. 61 62 (b) Exceptions disabled (PSR.T == 0). 63 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. 67 68 (3) Debug mode. 69 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. 75 76 All kernel mode registers may be accessed, plus a few extra debugging 77 specific registers. 78 79 80================================= 81INTERNAL KERNEL-MODE REGISTER ABI 82================================= 83 84There are a number of permanent register assignments that are set up by 85entry.S in the exception prologue. Note that there is a complete set of 86exception prologues for each of user->kernel transition and kernel->kernel 87transition. There are also user->debug and kernel->debug mode transition 88prologues. 89 90 91 REGISTER FLAVOUR USE 92 =============== ======= ============================================== 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 102 CCCR.CC3 Cleared by exception prologue 103 (atomic op emulation) 104 SCR0 MMU See mmu-layout.txt. 105 SCR1 MMU See mmu-layout.txt. 106 SCR2 MMU Save for EAR0 (destroyed by icache insns 107 in debug mode) 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 113Certain registers are also used or modified across function calls: 114 115 REGISTER CALL RETURN 116 =============== =============================== ====================== 117 GR0 Fixed Zero - 118 GR2 Function call frame pointer 119 GR3 Special Preserved 120 GR3-GR7 - Clobbered 121 GR8 Function call arg #1 Return value 122 (or clobbered) 123 GR9 Function call arg #2 Return value MSW 124 (or clobbered) 125 GR10-GR13 Function call arg #3-#6 Clobbered 126 GR14 - Clobbered 127 GR15-GR16 Special Preserved 128 GR17-GR27 - Preserved 129 GR28-GR31 Special Only accessed 130 explicitly 131 LR Return address after CALL Clobbered 132 CCR/CCCR - Mostly Clobbered 133 134 135================================ 136INTERNAL DEBUG-MODE REGISTER ABI 137================================ 138 139This is the same as the kernel-mode register ABI for functions calls. The 140difference is that in debug-mode there's a different stack and a different 141exception frame. Almost all the global registers from kernel-mode 142(including the stack pointer) may be changed. 143 144 REGISTER FLAVOUR USE 145 =============== ======= ============================================== 146 GR1 Debug stack pointer 147 GR16 GP-Rel base register for small data 148 GR31 Current debug exception frame pointer 149 (__debug_frame) 150 SCR3 MMU Saved value of GR31 151 152 153Note that debug mode is able to interfere with the kernel's emulated atomic 154ops, so it must be exceedingly careful not to do any that would interact 155with the main kernel in this regard. Hence the debug mode code (gdbstub) is 156almost completely self-contained. The only external code used is the 157sprintf family of functions. 158 159Furthermore, break.S is so complicated because single-step mode does not 160switch off on entry to an exception. That means unless manually disabled, 161single-stepping will blithely go on stepping into things like interrupts. 162See gdbstub.txt for more information. 163 164 165========================== 166VIRTUAL INTERRUPT HANDLING 167========================== 168 169Because accesses to the PSR is so slow, and to disable interrupts we have 170to access it twice (once to read and once to write), we don't actually 171disable interrupts at all if we don't have to. What we do instead is use 172the ICC2 condition code flags to note virtual disablement, such that if we 173then do take an interrupt, we note the flag, really disable interrupts, set 174another flag and resume execution at the point the interrupt happened. 175Setting condition flags as a side effect of an arithmetic or logical 176instruction is really fast. This use of the ICC2 only occurs within the 177kernel - it does not affect userspace. 178 179The flags we use are: 180 181 (*) CCR.ICC2.Z [Zero flag] 182 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. 186 187 (*) CCR.ICC2.C [Carry flag] 188 189 Clear to indicate hardware interrupts are really disabled, set otherwise. 190 191 192What happens is this: 193 194 (1) Normal kernel-mode operation. 195 196 ICC2.Z is 0, ICC2.C is 1. 197 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. 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 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). 214 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. 219 220 (6) If interrupts were then saved and disabled again (local_irq_save): 221 222 ICC2.Z would be shifted into the save variable and masked off 223 (giving a 1). 224 225 ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be 226 unaffected (ie: 0). 227 228 (7) If interrupts were then restored from state (6) (local_irq_restore): 229 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. 233 234 ICC2.C would remain unaffected (ie: 0). 235 236 A TIHI #2 instruction would be used to again assay the current state, 237 but this would do nothing as Z==1. 238 239 (8) If interrupts were then enabled (local_irq_enable): 240 241 ICC2.Z would be cleared. ICC2.C would be left unaffected. Both 242 flags would now be 0. 243 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. 247 248 (9) The trap #2 handler would simply enable hardware interrupts 249 (set PSR.PIL to 0), set ICC2.C to 1 and return. 250 251(10) Immediately upon returning, the pending interrupt would be taken. 252 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)). 255 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. 258 259(13) On return from the interrupt handler, things would be back to state (1). 260 261This trap (#2) is only available in kernel mode. In user mode it will 262result in SIGILL. 263