diff options
Diffstat (limited to 'Documentation/frv/kernel-ABI.txt')
-rw-r--r-- | Documentation/frv/kernel-ABI.txt | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/Documentation/frv/kernel-ABI.txt b/Documentation/frv/kernel-ABI.txt deleted file mode 100644 index aaa1cec86f0b..000000000000 --- a/Documentation/frv/kernel-ABI.txt +++ /dev/null @@ -1,262 +0,0 @@ - ================================= - 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. - -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 -=================== - -The FR-V CPU has three basic operating modes. In order of increasing -capability: - - (1) User mode. - - Basic userspace running mode. - - (2) Kernel mode. - - 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: - - (a) Exceptions enabled (PSR.T == 1). - - Exceptions will invoke the appropriate normal kernel mode - handler. On entry to the handler, the PSR.T bit will be cleared. - - (b) Exceptions disabled (PSR.T == 0). - - 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. - - (3) Debug mode. - - 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. - - All kernel mode registers may be accessed, plus a few extra debugging - specific registers. - - -================================= -INTERNAL KERNEL-MODE REGISTER ABI -================================= - -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. - - - REGISTER FLAVOUR USE - =============== ======= ============================================== - 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 - CCCR.CC3 Cleared by exception prologue - (atomic op emulation) - SCR0 MMU See mmu-layout.txt. - SCR1 MMU See mmu-layout.txt. - SCR2 MMU Save for EAR0 (destroyed by icache insns - in debug mode) - 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 - =============== =============================== ====================== - GR0 Fixed Zero - - GR2 Function call frame pointer - GR3 Special Preserved - GR3-GR7 - Clobbered - GR8 Function call arg #1 Return value - (or clobbered) - GR9 Function call arg #2 Return value MSW - (or clobbered) - GR10-GR13 Function call arg #3-#6 Clobbered - GR14 - Clobbered - GR15-GR16 Special Preserved - GR17-GR27 - Preserved - GR28-GR31 Special Only accessed - explicitly - LR Return address after CALL Clobbered - CCR/CCCR - Mostly Clobbered - - -================================ -INTERNAL DEBUG-MODE REGISTER ABI -================================ - -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. - - REGISTER FLAVOUR USE - =============== ======= ============================================== - GR1 Debug stack pointer - GR16 GP-Rel base register for small data - GR31 Current debug exception frame pointer - (__debug_frame) - SCR3 MMU Saved value of GR31 - - -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. - -Furthermore, break.S is so complicated because single-step mode does not -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. - - -========================== -VIRTUAL INTERRUPT HANDLING -========================== - -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 -kernel - it does not affect userspace. - -The flags we use are: - - (*) CCR.ICC2.Z [Zero flag] - - Set to virtually disable interrupts, clear when interrupts are - virtually enabled. Can be modified by logical instructions without - affecting the Carry flag. - - (*) 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. - - (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. - - (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. - - 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). - - (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. - - (6) If interrupts were then saved and disabled again (local_irq_save): - - ICC2.Z would be shifted into the save variable and masked off - (giving a 1). - - ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be - unaffected (ie: 0). - - (7) If interrupts were then restored from state (6) (local_irq_restore): - - 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. - - ICC2.C would remain unaffected (ie: 0). - - A TIHI #2 instruction would be used to again assay the current state, - but this would do nothing as Z==1. - - (8) If interrupts were then enabled (local_irq_enable): - - ICC2.Z would be cleared. ICC2.C would be left unaffected. Both - flags would now be 0. - - 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. - - (9) The trap #2 handler would simply enable hardware interrupts - (set PSR.PIL to 0), set ICC2.C to 1 and return. - -(10) Immediately upon returning, the pending interrupt would be taken. - -(11) The interrupt handler would take the path of actually processing the - interrupt (ICC2.Z is clear, BEQ fails as per step (2)). - -(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. - -(13) On return from the interrupt handler, things would be back to state (1). - -This trap (#2) is only available in kernel mode. In user mode it will -result in SIGILL. |