kernel-ABI.txt 9.17 KB
Newer Older
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.
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 43

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
===================

44 45
The FR-V CPU has three basic operating modes. In order of increasing
capability:
46 47 48 49 50 51 52

  (1) User mode.

      Basic userspace running mode.

  (2) Kernel mode.

53 54 55
      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:
56 57 58

      (a) Exceptions enabled (PSR.T == 1).

59 60
	  Exceptions will invoke the appropriate normal kernel mode
	  handler. On entry to the handler, the PSR.T bit will be cleared.
61 62 63

      (b) Exceptions disabled (PSR.T == 0).

64 65 66
	  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.
67 68 69

  (3) Debug mode.

70 71 72 73 74
      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.
75

76 77
      All kernel mode registers may be accessed, plus a few extra debugging
      specific registers.
78 79 80 81 82 83


=================================
INTERNAL KERNEL-MODE REGISTER ABI
=================================

84 85 86 87 88
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.
89 90 91


	REGISTER	FLAVOUR	USE
92
	===============	=======	==============================================
93 94 95 96 97 98 99 100 101
	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
102 103
	CCCR.CC3		Cleared by exception prologue 
				(atomic op emulation)
104 105
	SCR0		MMU	See mmu-layout.txt.
	SCR1		MMU	See mmu-layout.txt.
106 107
	SCR2		MMU	Save for EAR0 (destroyed by icache insns 
					       in debug mode)
108 109 110 111 112 113 114 115
	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
116
	===============	===============================	======================
117 118 119 120
	GR0		Fixed Zero			-
	GR2		Function call frame pointer
	GR3		Special				Preserved
	GR3-GR7		-				Clobbered
121 122 123 124
	GR8		Function call arg #1		Return value 
							(or clobbered)
	GR9		Function call arg #2		Return value MSW 
							(or clobbered)
125 126 127 128
	GR10-GR13	Function call arg #3-#6		Clobbered
	GR14		-				Clobbered
	GR15-GR16	Special				Preserved
	GR17-GR27	-				Preserved
129 130
	GR28-GR31	Special				Only accessed 
							explicitly
131 132 133 134 135 136 137 138
	LR		Return address after CALL	Clobbered
	CCR/CCCR	-				Mostly Clobbered


================================
INTERNAL DEBUG-MODE REGISTER ABI
================================

139 140 141 142
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.
143 144

	REGISTER	FLAVOUR	USE
145
	===============	=======	==============================================
146 147
	GR1			Debug stack pointer
	GR16			GP-Rel base register for small data
148 149
	GR31			Current debug exception frame pointer 
				(__debug_frame)
150 151 152
	SCR3		MMU	Saved value of GR31


153 154 155 156 157
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.
158

159
Furthermore, break.S is so complicated because single-step mode does not
160 161 162
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.
163 164 165 166 167 168


==========================
VIRTUAL INTERRUPT HANDLING
==========================

169 170 171 172 173 174 175 176
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
177 178 179 180 181 182
kernel - it does not affect userspace.

The flags we use are:

 (*) CCR.ICC2.Z [Zero flag]

183 184 185
     Set to virtually disable interrupts, clear when interrupts are
     virtually enabled. Can be modified by logical instructions without
     affecting the Carry flag.
186 187 188 189 190 191 192 193 194 195 196 197

 (*) 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.

198 199 200
 (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.
201 202 203 204 205 206 207 208 209

 (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.

210 211 212 213
     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).
214

215 216 217 218
 (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.
219 220 221

 (6) If interrupts were then saved and disabled again (local_irq_save):

222 223
	ICC2.Z would be shifted into the save variable and masked off 
	(giving a 1).
224

225 226
	ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be
	unaffected (ie: 0).
227 228 229

 (7) If interrupts were then restored from state (6) (local_irq_restore):

230 231 232
	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.
233 234 235

	ICC2.C would remain unaffected (ie: 0).

236 237
     A TIHI #2 instruction would be used to again assay the current state,
     but this would do nothing as Z==1.
238 239 240

 (8) If interrupts were then enabled (local_irq_enable):

241 242
	ICC2.Z would be cleared. ICC2.C would be left unaffected. Both
	flags would now be 0.
243

244 245 246
     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.
247

248 249
 (9) The trap #2 handler would simply enable hardware interrupts 
     (set PSR.PIL to 0), set ICC2.C to 1 and return.
250 251 252

(10) Immediately upon returning, the pending interrupt would be taken.

253 254
(11) The interrupt handler would take the path of actually processing the
     interrupt (ICC2.Z is clear, BEQ fails as per step (2)).
255

256 257
(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.
258 259 260

(13) On return from the interrupt handler, things would be back to state (1).

261 262
This trap (#2) is only available in kernel mode. In user mode it will
result in SIGILL.