Move kernel_main into the elna code
This commit is contained in:
@@ -4,6 +4,11 @@
|
||||
|
||||
.include "./arch/riscv/constants.s"
|
||||
|
||||
.section .data
|
||||
|
||||
.globl pmem_address
|
||||
pmem_address: .word
|
||||
|
||||
.section .text
|
||||
|
||||
# a0 - First pointer.
|
||||
@@ -245,9 +250,8 @@ memset:
|
||||
# Parameters:
|
||||
# a0 - Corresponding virtual address.
|
||||
# a1 - Physical page address.
|
||||
# a2 - Free memory page that can be used to create a leaf page table.
|
||||
# a3 - Page table level. If a3 is 0 a superpage is allocated, otherwise a normal page.
|
||||
# a4 - Flags.
|
||||
# a2 - Page table level. If a2 is 0 a superpage is allocated, otherwise a normal page.
|
||||
# a3 - Flags.
|
||||
#
|
||||
# If the function creates new page tables in a2, it advances a2 by the page size and
|
||||
# returns it in a0.
|
||||
@@ -268,7 +272,7 @@ pmem_map_at:
|
||||
and t2, t2, t5 # 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)
|
||||
andi t6, t3, 0b1
|
||||
@@ -281,27 +285,29 @@ pmem_map_at:
|
||||
j .Lpmem_map_at_next
|
||||
|
||||
.Lpmem_map_at_create:
|
||||
la a7, pmem_address
|
||||
# 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.
|
||||
mv t0, a2
|
||||
lw t0, (a7)
|
||||
srli t3, t0, 2
|
||||
ori t3, t3, 0b1
|
||||
sw t3, (t2)
|
||||
|
||||
li t6, PAGE_SIZE
|
||||
add a2, a2, t6
|
||||
add t0, t0, t6
|
||||
sw t0, (a7)
|
||||
|
||||
.Lpmem_map_at_next:
|
||||
# Calculate the next page table address for the next level.
|
||||
addi t1, t1, -10
|
||||
addi a3, a3, -1
|
||||
addi a2, a2, -1
|
||||
|
||||
j .Lpmem_map_at_loop
|
||||
|
||||
.Lpmem_map_at_leaf:
|
||||
srli t3, a1, 2 # Physical page number mapped to 12 bits of the page table entry.
|
||||
ori a4, a4, 0b1
|
||||
or t3, t3, a4 # Execute, write, read and valid.
|
||||
ori a3, a3, 0b1
|
||||
or t3, t3, a3 # Execute, write, read and valid.
|
||||
sw t3, (t2)
|
||||
|
||||
mv a0, a2
|
||||
|
@@ -1 +1,4 @@
|
||||
.equ PAGE_SIZE, 4096
|
||||
.equ PAGE_READ, 0b0010
|
||||
.equ PAGE_WRITE, 0b0100
|
||||
.equ PAGE_EXECUTE, 0b1000
|
||||
|
@@ -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:
|
||||
|
@@ -25,6 +25,7 @@ type
|
||||
|
||||
proc write_c(value: Char); extern;
|
||||
proc write_s(value: String); extern;
|
||||
proc pmem_map_at(virtual: Pointer, physical: Pointer, level: Word, flags: Word); extern;
|
||||
|
||||
proc separator*() -> Char;
|
||||
return ','
|
||||
@@ -382,7 +383,12 @@ proc device_tree*(raw: Pointer);
|
||||
var
|
||||
raw_as_char: ^Char;
|
||||
header: fdt_header;
|
||||
raw_virtual: Pointer;
|
||||
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);
|
||||
|
||||
parse_header(raw_as_char, @header);
|
||||
@@ -390,7 +396,11 @@ begin
|
||||
|
||||
write_c('\n');
|
||||
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.
|
||||
|
Reference in New Issue
Block a user