Move kernel_main into the elna code

This commit is contained in:
2025-08-02 23:38:30 +02:00
parent badac1378d
commit ed4b26f445
4 changed files with 80 additions and 80 deletions

View File

@@ -31,14 +31,18 @@ _start:
mv a0, s2
mv a1, sp
call get_page_tables_size
mv a3, a0
mv a0, s2
mv a1, sp
mv a2, s4
mv a1, s2
mv a2, sp
mv a3, s4
jal imem_initialize
mv a0, s3
mv a1, s3
jal imem_mirror
# Save the address where the initial page tables end in a variable.
add a0, a0, s3
la t0, pmem_address
sw a0, (t0)
call set_up_trap_routine
add sp, sp, s4 # Move the stack to the virtual memory.
@@ -48,11 +52,10 @@ _start:
mv a1, sp
call imem_zero
mv a0, sp
mv a1, s1
mv a0, s1
lui t0, %hi(kernel_main)
jr t0, %lo(kernel_main)
lui t0, %hi(device_tree)
jr t0, %lo(device_tree)
# Given the start and end addresses of the kernel, calculates how
# much additional storage should be mapped to store the page tables.
@@ -74,6 +77,8 @@ _start:
# Returns the result in a0.
.type get_page_tables_size, @function
get_page_tables_size:
li t0, 0xffc00000
and a0, a0, t0
sub a0, a1, a0
srli a0, a0, 22
@@ -119,7 +124,11 @@ imem_zero:
# Copies the identity mappings to the higher half.
#
# Parameters:
# a0 - Start of the kernel virtual space.
# a0 - Size of additional page tables.
# a1 - Start of the kernel virtual space.
#
# Returns a pointer pointing to the end of the last page table
# with higher half mappings in a0.
.type imem_mirror, @function
imem_mirror:
csrr t0, satp
@@ -127,12 +136,14 @@ imem_mirror:
li t3, PAGE_SIZE
add t1, t0, t3 # Original page table.
add t2, t1, t3 # Copied page table.
add t2, t1, a0 # Copied page table.
li t5, 0xffffffcf
mv t3, t2
.Limem_mirror_copy:
lw t4, (t1)
and t4, t4, t5 # Clear "dirty" and "accessed" bits.
sw t4, (t3)
addi t3, t3, 4
@@ -140,11 +151,13 @@ imem_mirror:
blt t1, t2, .Limem_mirror_copy
# Persist the copied page table in the root page table.
srli t4, a0, 20 # VPN[1] * PTESIZE.
srli t4, a1, 20 # VPN[1] * PTESIZE.
add t4, t0, t4 # a + VPN[1] * PTESIZE.
srli t3, t2, 2
ori t3, t3, 0b1
sw t3, (t4)
srli t5, t2, 2
ori t5, t5, 0b1
sw t5, (t4)
mv a0, t3
ret
@@ -152,10 +165,12 @@ imem_mirror:
# Allocates enough pages for the kernel and its stack.
#
# Parameters:
# a0 - Physical start of the text section.
# a1 - Page aligned address following the kernel (kernel end).
# a2 - Offset from the physical to virtual memory.
# a3 - Size of additional page tables.
# a0 - Size of additional page tables.
# a1 - Physical start of the text section.
# a2 - Page aligned address following the kernel (kernel end).
# a3 - Offset from the physical to virtual memory.
#
# Returns the size of the created page tables (a0) in a0.
.type imem_initialize, @function
imem_initialize:
# Prologue.
@@ -164,55 +179,54 @@ imem_initialize:
sw s0, 24(sp)
addi s0, sp, 32
sw a0, 20(sp)
sw s1, 16(sp)
sw s2, 12(sp)
sw s3, 8(sp)
sw a0, 4(sp)
sw a1, 4(sp)
# Set s1 to the beginning of free memory (skipping root page table).
li s1, PAGE_SIZE
add s1, a1, s1
slli a3, a3, 1 # Multiply by two to account for the copy in virtual memory.
# s1 is a1 + PAGE, where PAGE is a free page reserved for future use,
# since the size of the root page table is already included in a3.
# s1 is used to avoid calculating a1 + PAGE_SIZE twice.
add a3, s1, a3
sw a3, 20(sp)
add s1, a2, s1
# Set boundaries between segments.
lui s2, %hi(etext)
sub s2, s2, a2
sub s2, s2, a3
lui s3, %hi(_data)
sub s3, s3, a2
sub s3, s3, a3
# Set the root page since it is used by mapping functions,
# but don't activate paging before the segments are property mapped.
srli t0, a1, 12
srli t0, a2, 12
csrw satp, t0
# Zero memory for page tables.
mv a0, a1
add a1, s1, a3
mv a0, a2
add a1, s1, a0
call imem_zero
# Executable section.
mv a0, s1
lw a1, 4(sp)
addi a2, s2, %lo(etext)
li a3, 0b1010 # Read and execute.
li a3, PAGE_READ | PAGE_EXECUTE
jal imem_map_range
# Read only section.
addi a1, s2, %lo(etext)
addi a2, s3, %lo(_data)
li a3, 0b0010 # Read.
li a3, PAGE_READ
jal imem_map_range
# Data section.
addi a1, s3, %lo(_data)
lw a2, 20(sp)
li a3, 0b0110 # Read and write.
slli a2, a2, 1 # Multiply by two to account for the copy in virtual memory.
# s1 is a2 + PAGE, where PAGE is a free page reserved for future use,
# since the size of the root page table is already included in a0.
# s1 is used to avoid calculating a2 + PAGE_SIZE twice.
add a2, s1, a2
li a3, PAGE_READ | PAGE_WRITE
jal imem_map_range
# Enable paging.
@@ -227,6 +241,7 @@ imem_initialize:
lw s3, 8(sp)
lw s2, 12(sp)
lw s1, 16(sp)
lw a0, 20(sp)
# Epilogue.
lw ra, 28(sp)
@@ -338,40 +353,6 @@ imem_map_at:
.section .text
.type kernel_main, @function
kernel_main:
# Prologue.
addi sp, sp, -32
sw ra, 28(sp)
sw s0, 24(sp)
addi s0, sp, 32
sw a0, 20(sp)
sw a1, 16(sp)
# Map flat device tree to the virtual memory.
lw a0, 16(sp)
li t0, 0xffc00000
and a0, a0, t0
mv a1, a0
lw a2, 20(sp)
li a3, 0
li a4, 0b0010
call pmem_map_at
lw a0, 16(sp)
call device_tree
# Do nothing in a loop.
.Lkernel_main:
j .Lkernel_main
# Epilogue.
lw ra, 28(sp)
lw s0, 24(sp)
addi sp, sp, 32
ret
.balign 4
.type trap_routine, @function
trap_routine: