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