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

@@ -4,6 +4,11 @@
.include "./arch/riscv/constants.s" .include "./arch/riscv/constants.s"
.section .data
.globl pmem_address
pmem_address: .word
.section .text .section .text
# a0 - First pointer. # a0 - First pointer.
@@ -245,9 +250,8 @@ memset:
# Parameters: # Parameters:
# a0 - Corresponding virtual address. # a0 - Corresponding virtual address.
# a1 - Physical page address. # a1 - Physical page address.
# a2 - Free memory page that can be used to create a leaf page table. # a2 - Page table level. If a2 is 0 a superpage is allocated, otherwise a normal page.
# a3 - Page table level. If a3 is 0 a superpage is allocated, otherwise a normal page. # a3 - Flags.
# a4 - Flags.
# #
# If the function creates new page tables in a2, it advances a2 by the page size and # If the function creates new page tables in a2, it advances a2 by the page size and
# returns it in a0. # returns it in a0.
@@ -268,7 +272,7 @@ pmem_map_at:
and t2, t2, t5 # VPN[i] * PTESIZE. and t2, t2, t5 # VPN[i] * PTESIZE.
add t2, t0, t2 # a + VPN[i] * PTESIZE. add t2, t0, t2 # a + VPN[i] * PTESIZE.
beqz a3, .Lpmem_map_at_leaf beqz a2, .Lpmem_map_at_leaf
lw t3, (t2) lw t3, (t2)
andi t6, t3, 0b1 andi t6, t3, 0b1
@@ -281,27 +285,29 @@ pmem_map_at:
j .Lpmem_map_at_next j .Lpmem_map_at_next
.Lpmem_map_at_create: .Lpmem_map_at_create:
la a7, pmem_address
# Take a chunk of free memory and use it as the next page table. # Take a chunk of free memory and use it as the next page table.
# The beginning addres off the chunk is the base address (a) for the next level. # The beginning addres off the chunk is the base address (a) for the next level.
mv t0, a2 lw t0, (a7)
srli t3, t0, 2 srli t3, t0, 2
ori t3, t3, 0b1 ori t3, t3, 0b1
sw t3, (t2) sw t3, (t2)
li t6, PAGE_SIZE li t6, PAGE_SIZE
add a2, a2, t6 add t0, t0, t6
sw t0, (a7)
.Lpmem_map_at_next: .Lpmem_map_at_next:
# Calculate the next page table address for the next level. # Calculate the next page table address for the next level.
addi t1, t1, -10 addi t1, t1, -10
addi a3, a3, -1 addi a2, a2, -1
j .Lpmem_map_at_loop j .Lpmem_map_at_loop
.Lpmem_map_at_leaf: .Lpmem_map_at_leaf:
srli t3, a1, 2 # Physical page number mapped to 12 bits of the page table entry. srli t3, a1, 2 # Physical page number mapped to 12 bits of the page table entry.
ori a4, a4, 0b1 ori a3, a3, 0b1
or t3, t3, a4 # Execute, write, read and valid. or t3, t3, a3 # Execute, write, read and valid.
sw t3, (t2) sw t3, (t2)
mv a0, a2 mv a0, a2

View File

@@ -1 +1,4 @@
.equ PAGE_SIZE, 4096 .equ PAGE_SIZE, 4096
.equ PAGE_READ, 0b0010
.equ PAGE_WRITE, 0b0100
.equ PAGE_EXECUTE, 0b1000

View File

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

View File

@@ -25,6 +25,7 @@ type
proc write_c(value: Char); extern; proc write_c(value: Char); extern;
proc write_s(value: String); extern; proc write_s(value: String); extern;
proc pmem_map_at(virtual: Pointer, physical: Pointer, level: Word, flags: Word); extern;
proc separator*() -> Char; proc separator*() -> Char;
return ',' return ','
@@ -382,7 +383,12 @@ proc device_tree*(raw: Pointer);
var var
raw_as_char: ^Char; raw_as_char: ^Char;
header: fdt_header; header: fdt_header;
raw_virtual: Pointer;
begin begin
(* Map flat device tree to the virtual memory. *)
raw_virtual := cast(cast(raw: Word) & 4290772992u: Pointer);
pmem_map_at(raw_virtual, raw_virtual, 0u, 2u);
raw_as_char := cast(raw: ^Char); raw_as_char := cast(raw: ^Char);
parse_header(raw_as_char, @header); parse_header(raw_as_char, @header);
@@ -390,7 +396,11 @@ begin
write_c('\n'); write_c('\n');
find_memory(raw_as_char, @header); find_memory(raw_as_char, @header);
reserve_memory(raw_as_char, @header) reserve_memory(raw_as_char, @header);
(* Do nothing in a loop. *)
while true do
end
end; end;
end. end.