feat(arm64): higher-half kernel, early MMU in boot, and VMM
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
#include "Types.h"
|
||||
#include <Arch/DTB.h>
|
||||
#include <OS/Panic.h>
|
||||
#include <OS/Log.h>
|
||||
@@ -73,6 +72,11 @@ void DTBParse(Pointer dtb, VMBootMemoryMap* bootMap) {
|
||||
bootMap->reserved[index].size = size;
|
||||
bootMap->reservedCount++;
|
||||
}
|
||||
else if (StringStartsWith(currentNode, "pl011")) {
|
||||
UInt32* cells = (UInt32*)structs;
|
||||
bootMap->UART.base = Merge32To64(BytesSwap32(cells[1]), BytesSwap32(cells[0]));
|
||||
bootMap->UART.size = Merge32To64(BytesSwap32(cells[3]), BytesSwap32(cells[2]));
|
||||
}
|
||||
}
|
||||
|
||||
structs += propertyLength;
|
||||
|
||||
+116
-5
@@ -1,10 +1,121 @@
|
||||
.section .text.boot, "ax"
|
||||
.global _start
|
||||
|
||||
_start:
|
||||
sub sp, sp, #16
|
||||
str x0, [sp]
|
||||
// disable interrupts
|
||||
msr daifset, #3
|
||||
// save phys addr of Bootinfo* in x0 to x20
|
||||
mov x20, x0
|
||||
|
||||
// get phys addr of tables
|
||||
adrp x0, early_ttbr0_l0
|
||||
adrp x1, early_ttbr1_l0
|
||||
|
||||
// memzero that tables (4 tables = 16 KB)
|
||||
mov x2, #16384
|
||||
mov x3, x0
|
||||
1: str xzr, [x3], #8
|
||||
subs x2, x2, #8
|
||||
b.ne 1b
|
||||
|
||||
// set up ttbr0 (identity map of 512 gb)
|
||||
adrp x0, early_ttbr0_l0
|
||||
adrp x1, early_ttbr1_l0
|
||||
|
||||
// early_ttbr0_l0[0] -> early_ttbr0_l1 (Valid + Table = 0x3)
|
||||
ldr x2, =0x3
|
||||
orr x3, x1, x2
|
||||
str x3, [x0, #0]
|
||||
|
||||
// fill l1 table with 512 entrie
|
||||
// flags 0x701 = valid + block + accessflag + innershareable + normalram
|
||||
mov x2, xzr
|
||||
mov x3, #512
|
||||
ldr x4, =0x701
|
||||
mov x6, #(1 << 30)
|
||||
2: orr x5, x2, x4
|
||||
str x5, [x1], #8 // early_ttbr0_l1[i] = base | flags
|
||||
add x2, x2, x6
|
||||
subs x3, x3, #1
|
||||
b.ne 2b
|
||||
|
||||
// set up ttbr1 (HH: 0xFFFFFFFF80000000)
|
||||
adrp x0, early_ttbr1_l0
|
||||
adrp x1, early_ttbr1_l1
|
||||
|
||||
// early_ttbr1_l0[511] -> early_ttbr1_l1 (Valid + Table = 0x3)
|
||||
ldr x2, =0x3
|
||||
orr x3, x1, x2
|
||||
mov x4, #(511 * 8)
|
||||
str x3, [x0, x4]
|
||||
|
||||
// determine where is kernel rn
|
||||
adr x2, _start // curr pc in absoule addr
|
||||
lsr x2, x2, #30 // leave only number of gig
|
||||
lsl x2, x2, #30 // return it in absoule addr
|
||||
|
||||
// map that at 510 (0xFFFFFFFF80000000)
|
||||
ldr x3, =0x701 // flags
|
||||
orr x2, x2, x3
|
||||
mov x4, #(510 * 8)
|
||||
str x2, [x1, x4] // early_ttbr1_l1[510] = base | flags
|
||||
|
||||
// enable MMU (MAIR, TCR, SCTLR)
|
||||
// see Kernel/Include/Arch/CPU.h for explanaition
|
||||
ldr x2, =((0xFF << 0) | (0x00 << 8))
|
||||
msr mair_el1, x2
|
||||
|
||||
ldr x2, =((16 << 0) | (16 << 16) | (0 << 14) | (2 << 30) | (3 << 28) | (3 << 12) | (5 << 32))
|
||||
msr tcr_el1, x2
|
||||
|
||||
adrp x0, early_ttbr0_l0
|
||||
adrp x1, early_ttbr1_l0
|
||||
msr ttbr0_el1, x0
|
||||
msr ttbr1_el1, x1
|
||||
dsb ish
|
||||
isb
|
||||
|
||||
mrs x2, sctlr_el1
|
||||
ldr x3, =0x1005
|
||||
orr x2, x2, x3
|
||||
msr sctlr_el1, x2
|
||||
isb
|
||||
|
||||
ldr x2, =higher_half_jump
|
||||
br x2
|
||||
|
||||
higher_half_jump:
|
||||
ldr x3, =_boot_stack_top
|
||||
mov sp, x3
|
||||
|
||||
// clean .bss
|
||||
ldr x1, =__bss_start
|
||||
ldr x2, =__bss_end
|
||||
cbz x1, 4f
|
||||
cmp x1, x2
|
||||
b.eq 4f
|
||||
3: str xzr, [x1], #8
|
||||
cmp x1, x2
|
||||
b.lt 3b
|
||||
4:
|
||||
bl ExceptionsVectorsInit
|
||||
ldr x0, [sp]
|
||||
add sp, sp, #16
|
||||
|
||||
mov x0, x20 // return phys of Bootinfo* in x20
|
||||
|
||||
bl KernelMain
|
||||
b .
|
||||
|
||||
halt:
|
||||
wfi
|
||||
b halt
|
||||
|
||||
.section .data
|
||||
.align 12
|
||||
early_ttbr0_l0: .fill 4096, 1, 0
|
||||
early_ttbr0_l1: .fill 4096, 1, 0
|
||||
early_ttbr1_l0: .fill 4096, 1, 0
|
||||
early_ttbr1_l1: .fill 4096, 1, 0
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
.skip 16384
|
||||
_boot_stack_top:
|
||||
Reference in New Issue
Block a user