-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
The instruction set is mostly orthogonal, and as such the hardware doesn't impose many rules on how registers are used.
NOTE : Despite this, in practice, when developing any piece of non-trivial code, it's necessary to agree to set of rules on how registers can be used. This allows, for example, to reuse code from other people. See ABI.
Integer registers
Name | Purpose |
---|---|
r0 ... r11
|
General purpose registers |
r12 /ip
|
Normally called scratch register. Some instructions and architecture features use this register specifically. Also used in interrupt handling. |
r13 /sp
|
Stack pointer. Although the architecture doesn't explicitly require this register to be the stack pointer, some pseudo instructions do so (e.g: push ,pop ,fpush ,fpop ) |
r14 /lr
|
Link register. Holds the return address of a bl instruction (branch with linking).Also holds the crtsk value of the interrupted context when an interrupt happens. |
r15 /pc
|
Instruction pointer. Points to the next instruction to be executed. |
Floating point registers
Name | Purpose |
---|---|
f0 ... f15
|
General purpose registers |
Control registers
Control registers are mostly for advanced features, such as controlling user/supervisor mode, context switching, interrupt handling, etc.
Name | Purpose |
---|---|
cr0 /flags
|
Flags register |
cr1 /criqmsk
|
IRQ masking register |
cr2 /crtsk
|
Current task (aka: context) physical address. When an interrupt happens, the full interrupted context is saved to memory address [crtsk] . This allows the interrupt handler to resume the interrupted context |
cr3 ... cr7
|
General purpose at the moment. The OS can use these for whatever it wants. WARNING: Some of these might be used by the architecture in the future. |
cr8 /crirqs
|
IRQ pins. A bit set to 1 means that device needs servicing. |
cr9 ... cr15
|
General purpose at the moment. The OS can use it for whatever it wants. WARNING: Some of these might be used by the architecture in the future. |
The flags
register layout
\3\3\2\2\2\2\2\2\ \2\2\2\2\1\1\1\1\ \1\1\1\1\1\1\ \ \ \ \ \ \ \ \ \ \ \
\1\0\9\8\7\6\5\4\ \3\2\1\0\9\8\7\6\ \5\4\3\2\1\0\9\8\ \7\6\5\4\3\2\1\0\
N Z C V S [ Reserved for future use ] [Process Key]
| | | | |
| | | | !--- Supervisor mode
| | | !----- Overflow
| | !------- Carry
| !--------- Zero
!----------- Negative
- Contrary to most architectures, the condition flags (
N
,Z
,C
,V
) are only set by thecmp
/fcmp
instructions - When in user mode, only the condition flags can set by the user. Bits
26
to0
can only be set while in supervisor mode
Control registers permissions
Access to write or read control registers varies, depending on the cpu mode and the register in question. Attempting to read or write a register when not allowed will generated an IllegalInstruction exception.
Supervisor Read |
Supervisor Write |
User mode Read |
User mode Write |
|
---|---|---|---|---|
cr0 |
Y | Y | Y | Y(1) |
cr1 |
Y | Y | N | N |
cr2 |
Y | Y | N | N |
cr3 |
Y | Y | N | N |
cr4 |
Y | Y | N | N |
cr5 |
Y | Y | N | N |
cr6 |
Y | Y | N | N |
cr7 |
Y | Y | N | N |
- | - | - | - | - |
cr8 |
Y | N | N | N |
cr9 |
Y | Y | N | N |
cr10 |
Y | Y | N | N |
cr11 |
Y | Y | N | N |
cr12 |
Y | Y | N | N |
cr13 |
Y | Y | N | N |
cr14 |
Y | Y | N | N |
cr15 |
Y | Y | N | N |
(1) Write is allowed, but anything other than the condition flags will be ignored.
To allow creation of a complex OS, multithreaded programs, or simply coroutines, the entire register set can be saved/loaded with dedicated instructions (see ctxswitch
/fullctxswitch
).
What registers can be saved/loaded depends on if the CPU is in user or supervisor mode.
For this, you can think of a context simply as a user mode context or a full context.
A user mode context consists of the integer registers (r0
...r15
) and floating point registers (f0
...f15
).
A full context consists of the integer registers (r0
...r15
), floating point registers (f0
...f15
), and the cr0
...cr7
control registers.
The cr8
...cr15
control registers are not included in the saving/loading of a context.
For example, consider the cr8
(aka crirqs
) register. It represents what devices need attention. This information is not context sensitive, and therefore doesn't make sense to copy/save when context switching.
Some address ranges are reserved for special purposes, as follow:
Address | Size | Purpose |
---|---|---|
0x0 |
4 bytes | Reset handler address. When booting, this contains the address to jump to. |
0x4 |
128 bytes (4*32) |
IRQ vector table. This is an array of 32 words, where each entry is the address to jump to when the respective IRQ pin is set. |
0x84 |
224 bytes | Full context to load when an interrupt/exception is raised. |
To better understand this, a very simple boot file would look like this:
.text
.word _startup; Reset handler
.zero 128; Interrupt vector table: 4*32
.zero 224; Interrupt context
_startup:
; … your startup code
A more complex boot file, where you specify the IRQ handlers:
.text
.word _startup; Reset handler
.word _cpuExceptionHandler; IRQ 0 - CPU
.word _genericIRQHandler ; IRQ 1
; ... handlers for IRQ 2 .. 30
.word _genericIRQHandler ; IRQ 31
.zero 224; Interrupt context
_startup:
; … your startup code
1 2 3 4 5