Move kernel_main into the elna code
This commit is contained in:
@@ -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
|
||||||
|
@@ -1 +1,4 @@
|
|||||||
.equ PAGE_SIZE, 4096
|
.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 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:
|
||||||
|
@@ -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.
|
||||||
|
Reference in New Issue
Block a user