Move assembly into the arch directory
This commit is contained in:
213
arch/riscv/common.s
Normal file
213
arch/riscv/common.s
Normal file
@@ -0,0 +1,213 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
# obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
.global write_s, write_c
|
||||
.global memcmp, memchr, memmem, memcpy
|
||||
|
||||
.section .text
|
||||
|
||||
# a0 - First pointer.
|
||||
# a1 - Second pointer.
|
||||
# a2 - The length to compare.
|
||||
#
|
||||
# Returns 0 in a0 if memory regions are equal.
|
||||
.type memcmp, @function
|
||||
memcmp:
|
||||
mv t0, a0
|
||||
li a0, 0
|
||||
|
||||
.Lmemcmp_loop:
|
||||
beqz a2, .Lmemcmp_end
|
||||
|
||||
lbu t1, (t0)
|
||||
lbu t2, (a1)
|
||||
sub a0, t1, t2
|
||||
|
||||
bnez a0, .Lmemcmp_end
|
||||
|
||||
addi t0, t0, 1
|
||||
addi a1, a1, 1
|
||||
addi a2, a2, -1
|
||||
|
||||
j .Lmemcmp_loop
|
||||
|
||||
.Lmemcmp_end:
|
||||
ret
|
||||
|
||||
# Prints a string.
|
||||
#
|
||||
# Parameters:
|
||||
# a0 - String pointer.
|
||||
# a1 - Length of the string.
|
||||
.type write_s, @function
|
||||
write_s:
|
||||
# Prologue.
|
||||
addi sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
sw s0, 24(sp)
|
||||
addi s0, sp, 32
|
||||
|
||||
sw s1, 20(sp)
|
||||
sw s2, 16(sp)
|
||||
|
||||
mv s1, a1
|
||||
mv s2, a0
|
||||
|
||||
.Lwrite_s_if:
|
||||
beqz s1, .Lwrite_s_end
|
||||
|
||||
lw a0, (s2)
|
||||
call write_c
|
||||
|
||||
addi s1, s1, -1
|
||||
addi s2, s2, 1
|
||||
|
||||
j .Lwrite_s_if
|
||||
|
||||
.Lwrite_s_end:
|
||||
lw s1, 20(sp)
|
||||
lw s2, 16(sp)
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 28(sp)
|
||||
lw s0, 24(sp)
|
||||
addi sp, sp, 32
|
||||
ret
|
||||
|
||||
# Prints a character from a0.
|
||||
#
|
||||
# Arguments:
|
||||
# a0 - Character.
|
||||
.type write_c, @function
|
||||
write_c:
|
||||
li a1, 0
|
||||
li a2, 0
|
||||
li a3, 0
|
||||
li a4, 0
|
||||
li a5, 0
|
||||
li a6, 0
|
||||
li a7, 1 # sbi_console_putchar.
|
||||
|
||||
ecall
|
||||
ret
|
||||
|
||||
# Searches for the occurences of a character in the given memory block.
|
||||
#
|
||||
# Parameters:
|
||||
# a0 - Memory block.
|
||||
# a1 - Needle.
|
||||
# a2 - Memory size.
|
||||
#
|
||||
# Sets a0 to the pointer to the found character or to null if the character
|
||||
# doesn't occur in the memory block.
|
||||
.type memchr, @function
|
||||
memchr:
|
||||
.Lmemchr_loop:
|
||||
beqz a2, .Lmemchr_nil # Exit if the length is 0.
|
||||
|
||||
lbu t0, (a0) # Load the character from the memory block.
|
||||
beq t0, a1, .Lmemchr_end # Exit if the character was found.
|
||||
|
||||
# Otherwise, continue with the next character.
|
||||
addi a0, a0, 1
|
||||
addi a2, a2, -1
|
||||
|
||||
j .Lmemchr_loop
|
||||
|
||||
.Lmemchr_nil:
|
||||
li a0, 0
|
||||
|
||||
.Lmemchr_end:
|
||||
ret
|
||||
|
||||
# Locates a substring.
|
||||
#
|
||||
# Parameters:
|
||||
# a0 - Haystack.
|
||||
# a1 - Haystack size.
|
||||
# a2 - Needle.
|
||||
# a3 - Needle size.
|
||||
#
|
||||
# Sets a0 to the pointer to the beginning of the substring in memory or to 0
|
||||
# if the substring doesn't occur in the block.
|
||||
.type memmem, @function
|
||||
memmem:
|
||||
# Prologue.
|
||||
addi sp, sp, -24
|
||||
sw ra, 20(sp)
|
||||
sw s0, 16(sp)
|
||||
addi s0, sp, 24
|
||||
|
||||
# Save preserved registers. They are used to keep arguments.
|
||||
sw s1, 12(sp)
|
||||
sw s2, 8(sp)
|
||||
sw s3, 4(sp)
|
||||
sw s4, 0(sp)
|
||||
|
||||
mv s1, a0
|
||||
mv s2, a1
|
||||
mv s3, a2
|
||||
mv s4, a3
|
||||
|
||||
.Lmemmem_loop:
|
||||
blt s2, s3, .Lmemmem_nil # Exit if the needle length is greater than memory.
|
||||
|
||||
mv a0, s1
|
||||
mv a1, s3
|
||||
mv a2, s4
|
||||
call memcmp
|
||||
|
||||
mv t0, a0 # memcmp result.
|
||||
mv a0, s1 # Memory pointer for the case the substring was found.
|
||||
beqz t0, .Lmemmem_end
|
||||
|
||||
addi s1, s1, 1
|
||||
add s2, s2, -1
|
||||
|
||||
j .Lmemmem_loop
|
||||
|
||||
.Lmemmem_nil:
|
||||
li a0, 0
|
||||
|
||||
.Lmemmem_end:
|
||||
|
||||
# Restore the preserved registers.
|
||||
lw s1, 12(sp)
|
||||
lw s2, 8(sp)
|
||||
lw s3, 4(sp)
|
||||
lw s4, 0(sp)
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 20(sp)
|
||||
lw s0, 16(sp)
|
||||
add sp, sp, 24
|
||||
ret
|
||||
|
||||
# Copies memory.
|
||||
#
|
||||
# Parameters:
|
||||
# a0 - Destination.
|
||||
# a1 - Source.
|
||||
# a2 - Size.
|
||||
#
|
||||
# Preserves a0.
|
||||
.type memcpy, @function
|
||||
memcpy:
|
||||
mv t0, a0
|
||||
|
||||
.Lmemcpy_loop:
|
||||
beqz a2, .Lmemcpy_end
|
||||
|
||||
lbu t1, (a1)
|
||||
sb t1, (a0)
|
||||
|
||||
addi a0, a0, 1
|
||||
addi a1, a1, 1
|
||||
addi a2, a2, -1
|
||||
|
||||
j .Lmemcpy_loop
|
||||
|
||||
.Lmemcpy_end:
|
||||
mv a0, t0
|
||||
ret
|
227
arch/riscv/kernel.s
Normal file
227
arch/riscv/kernel.s
Normal file
@@ -0,0 +1,227 @@
|
||||
.global kernel_main, __bss, __bss_end, __stack_top
|
||||
|
||||
.section .rodata
|
||||
|
||||
panic_message: .asciz "\nPanic"
|
||||
.equ PANIC_MESSAGE_SIZE, . - panic_message
|
||||
|
||||
.section .text
|
||||
|
||||
bzero:
|
||||
la t0, __bss
|
||||
la t1, __bss_end
|
||||
|
||||
.Lbzero_loop:
|
||||
bgt t0, t1, .Lbzero_end
|
||||
sw zero, (t0)
|
||||
addi t0, t0, 4
|
||||
|
||||
.Lbzero_end:
|
||||
ret
|
||||
|
||||
.type kernel_main, @function
|
||||
kernel_main:
|
||||
# Prologue.
|
||||
addi sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
sw s0, 24(sp)
|
||||
addi s0, sp, 32
|
||||
|
||||
la t0, kernel_entry
|
||||
csrw stvec, t0
|
||||
|
||||
mv a0, a1
|
||||
call device_tree
|
||||
|
||||
# Prepare the kernel root memory table.
|
||||
la a0, __kernel_base
|
||||
srli a0, a0, 22
|
||||
andi a0, a0, 0x3ff # VPN[1].
|
||||
|
||||
# Multiply VPN[1] by 4 and add to the start address of the page table.
|
||||
# This gives the physical address of the page table entry.
|
||||
la t0, __free_ram
|
||||
slli a0, a0, 2
|
||||
add a0, t0, a0
|
||||
|
||||
# Calculate PPN[1] (10 most significant bits of the physical address
|
||||
# and map it to 12 bits of the table page entry.
|
||||
la a1, __kernel_base
|
||||
srli a1, a1, 2
|
||||
li t0, 0xff300000
|
||||
and a1, a1, t0
|
||||
ori a1, a1, 0b1111
|
||||
|
||||
sw a1, (a0) # Save the page entry.
|
||||
|
||||
la a0, __free_ram
|
||||
srli a0, a0, 12
|
||||
li t0, 0x80000000
|
||||
or a0, a0, t0
|
||||
|
||||
sfence.vma
|
||||
csrw satp, a0
|
||||
sfence.vma
|
||||
|
||||
# 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 kernel_entry, @function
|
||||
kernel_entry:
|
||||
csrw sscratch, sp
|
||||
addi sp, sp, -4 * 31
|
||||
|
||||
sw ra, 0(sp)
|
||||
sw gp, 4(sp)
|
||||
sw tp, 8(sp)
|
||||
sw t0, 12(sp)
|
||||
sw t1, 16(sp)
|
||||
sw t2, 20(sp)
|
||||
sw t3, 24(sp)
|
||||
sw t4, 28(sp)
|
||||
sw t5, 32(sp)
|
||||
sw t6, 36(sp)
|
||||
sw a0, 40(sp)
|
||||
sw a1, 44(sp)
|
||||
sw a2, 48(sp)
|
||||
sw a3, 52(sp)
|
||||
sw a4, 56(sp)
|
||||
sw a5, 60(sp)
|
||||
sw a6, 64(sp)
|
||||
sw a7, 68(sp)
|
||||
sw s0, 72(sp)
|
||||
sw s1, 76(sp)
|
||||
sw s2, 80(sp)
|
||||
sw s3, 84(sp)
|
||||
sw s4, 88(sp)
|
||||
sw s5, 92(sp)
|
||||
sw s6, 96(sp)
|
||||
sw s7, 100(sp)
|
||||
sw s8, 104(sp)
|
||||
sw s9, 108(sp)
|
||||
sw s10, 112(sp)
|
||||
sw s11, 116(sp)
|
||||
|
||||
csrr a0, sscratch
|
||||
sw a0, 120(sp)
|
||||
|
||||
mv a0, sp
|
||||
call handle_trap
|
||||
|
||||
lw ra, 0(sp)
|
||||
lw gp, 4(sp)
|
||||
lw tp, 8(sp)
|
||||
lw t0, 12(sp)
|
||||
lw t1, 16(sp)
|
||||
lw t2, 20(sp)
|
||||
lw t3, 24(sp)
|
||||
lw t4, 28(sp)
|
||||
lw t5, 32(sp)
|
||||
lw t6, 36(sp)
|
||||
lw a0, 40(sp)
|
||||
lw a1, 44(sp)
|
||||
lw a2, 48(sp)
|
||||
lw a3, 52(sp)
|
||||
lw a4, 56(sp)
|
||||
lw a5, 60(sp)
|
||||
lw a6, 64(sp)
|
||||
lw a7, 68(sp)
|
||||
lw s0, 72(sp)
|
||||
lw s1, 76(sp)
|
||||
lw s2, 80(sp)
|
||||
lw s3, 84(sp)
|
||||
lw s4, 88(sp)
|
||||
lw s5, 92(sp)
|
||||
lw s6, 96(sp)
|
||||
lw s7, 100(sp)
|
||||
lw s8, 104(sp)
|
||||
lw s9, 108(sp)
|
||||
lw s10, 112(sp)
|
||||
lw s11, 116(sp)
|
||||
lw sp, 120(sp)
|
||||
|
||||
sret
|
||||
|
||||
.type handle_trap, @function
|
||||
handle_trap:
|
||||
# Prologue.
|
||||
addi sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
sw s0, 24(sp)
|
||||
addi s0, sp, 32
|
||||
|
||||
csrr t0, scause
|
||||
csrr t1, stval
|
||||
csrr t2, sepc
|
||||
|
||||
li a1, PANIC_MESSAGE_SIZE
|
||||
la a0, panic_message
|
||||
call write_s
|
||||
|
||||
li a0, ' '
|
||||
call write_c
|
||||
|
||||
csrr a0, scause
|
||||
la a1, write_c
|
||||
call print_i
|
||||
|
||||
call separator
|
||||
call write_c
|
||||
|
||||
csrr a0, stval
|
||||
la a1, write_c
|
||||
call print_i
|
||||
|
||||
call separator
|
||||
call write_c
|
||||
|
||||
csrr a0, sepc
|
||||
la a1, write_c
|
||||
call print_i
|
||||
|
||||
call panic
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 28(sp)
|
||||
lw s0, 24(sp)
|
||||
addi sp, sp, 32
|
||||
ret
|
||||
|
||||
.type panic, @function
|
||||
panic:
|
||||
# Prologue.
|
||||
addi sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
sw s0, 24(sp)
|
||||
addi s0, sp, 32
|
||||
|
||||
li a0, '\n'
|
||||
call write_c
|
||||
.Lpanic:
|
||||
j .Lpanic
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 28(sp)
|
||||
lw s0, 24(sp)
|
||||
addi sp, sp, 32
|
||||
ret
|
||||
|
||||
.section .text.boot
|
||||
boot:
|
||||
la t0, __stack_top
|
||||
mv sp, t0 # Set the stack pointer
|
||||
|
||||
lw t0, (__free_ram)
|
||||
la t1, next_paddr
|
||||
sw t0, (t1)
|
||||
|
||||
call bzero
|
||||
j kernel_main
|
Reference in New Issue
Block a user