Boot process
On reset, all QCPU features (e.g. prot, virtual memory) are disabled and the microprocessor jumps to the 0x0800 entrypoint in physical memory. For any direct application or kernel, the first step to perform is to set up a stack pointer and enable kernel logical mapping.
64 KiB
(16 bit)
0x0000 0xC000 0xFFFF
|------------------------|--------|
| userland | kernel |
48 KiB 16 KiB
QCPU has a single virtual address space, divided into multiple regions. For hardware simplicity, the kernel-protected region from 0xC000 is fixed.
1 Setting up a stack
A stack is configured by setting the sp register. It grows downwards, as memory operations take a static unsigned immediate as offset, so the stack pointer is set to the last element in the region.
@section stack
@align 256
@region 512
@define stlen, 512
@define stbase, .sttop + @slen
.sttop: reserve u8, @stlen ; top of stack
@end
@section root
@align 2
_: lui sp, @stbase
bkpt
For allocating to the stack, use the alloc pseudo-instruction:
alloc -4 ; 4 bytes
mstw x1, sp, 0 ; sp+0 sp+1 = x1
mstw x2, sp, 2 ; sp+2 sp+3 = x2
2 Kernel space
Kernel space is divided into two parts: logical space, and virtually-mapped space:
16 KiB
0xC000 0xF000 0xFFFF
|-----------|-----------|
| userland | kfixed | kvariable |
12 KiB 4 KiB
Kernel text and global data is put in the logical kfixed space. Note how there exists two virtually-mapped regions in the virtual memory address space: userland and kernel-protected virtual memory. These regions are configured independently through the CSRs.
For architectural simplicity, address 0xC000 is the fixed watermark of the kernel. Any pages above the watermark are kernel-protected when in kernel-protected mode (enabled in the ft CSR).
System calls, and any other hardware interrupt, put the CPU into kernel mode and jump to designated parts of kernel space (configured in the vec CSR). If any other operation in userland tries to access kernel space, a page fault is triggered. Jumping out of kernel space exits kernel mode. Memory accesses from within kernel mode are allowed anywhere, given that a page mapping exists.
3 Kernel logical space
Kernel logical space is one of two virtual memory mapping types. When the kernel-protection bit is set in the ft CSR, virtual region 0xC000 - 0xFFFF is mapped to its equivalent starting from 0x0000 in physical memory.
@section root
@align 2
// executed in 0x0800 physical memory
_: lli x1, 0b00000001 ; enable bit for kp/kernel-protect
csrw x1, 0x043 ; write features
ftlb ; TLB flush on next jump
jmp .kmain ; absolute jump to virtual memory addr
// executed in 0xC8XX logical memory
@align 32
.kmain: bkpt
// linked as virtual memory, so don't try to use labels in the time
// we're in physical memory, except when jumping to the virtual-translated
// entrypoint after flush
@linkinfo(origin) root, 0xC800
With kernel protection/logical mapping disabled, the CPU is in kernel mode, and therefore doesn’t trigger a page fault going into the now kernel-protected space.
4 Page mapping
Page mapping translates virtual pages to physical pages through the kernel’s page table. There are two page table CSRs available: pmat and pmatk (physical memory address translation user/kernel, respectively). They hold the address to the separate page tables.
Cleverly, having two page tables allows the kernel to switch userland by updating the pmat CSR only, keeping kernel mappings intact.
64 KiB
{ }---------\/{ }
|-----------|---------MM|-----------|
| userland | kfixed | kvariable |
48 KiB 12 KiB 4 KiB