LoGin 9284987850
riscv: 完成UEFI初始化,能正确设置memblock的信息 (#501)
* riscv: 完成UEFI初始化,能正确设置memblock的信息

* sbi增加reset功能

* 把虚拟CPU修改为sifive-u54,使qemu能更正确地模拟硬件行为

* 修复内存页面映射未设置“DIRTY”、”ACCESSED“、”GLOBAL“位,导致真机page fault的问题
2024-01-26 18:08:39 +08:00

379 lines
7.3 KiB
ArmAsm
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "common/asm.h"
.section .bootstrap
#define CSR_SSTATUS 0x100
#define CSR_SIE 0x104
#define CSR_STVEC 0x105
#define CSR_SIP 0x144
# define CSR_TVEC CSR_STVEC
# define CSR_STATUS CSR_SSTATUS
#define CSR_IE CSR_SIE
#define CSR_IP CSR_SIP
#define SR_FS 0x00006000
#define SR_VS 0x00000600
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
#define SATP_MODE_39 0x8000000000000000ULL
#define SATP_MODE_48 0x9000000000000000ULL
#define SATP_MODE_57 0xa000000000000000ULL
#define PAGE_OFFSET 0xffffffc000000000
#define KERNEL_LINK_OFFSET 0x1000000
#define KERNEL_VIRT_START (PAGE_OFFSET + KERNEL_LINK_OFFSET)
// DragonStub
//
// a0: hartid ID
// a1: fdt
.global _start
.type _start, @function
ENTRY(_start)
/* Mask all interrupts */
csrw CSR_IE, zero
csrw CSR_IP, zero
// hartid
la t0, __initial_hartid_ptr
sd a0, 0(t0)
//
la t0, __initial_fdt_ptr
sd a1, 0(t0)
// _startDragonStub
auipc t0, 0
li t1, -4095
and t0, t0, t1
la t1, __initial_start_load_paddr
sd t0, 0(t1)
//
la a0, __initial_pgtable
call __initial_clear_pgtable
la a0, __initial_l1_pgtable
call __initial_clear_pgtable
la a0, __initial_l1_pgtable
li a1, 4096
add a0, a0, a1
call __initial_clear_pgtable
//
la a0, __initial_start_load_paddr
ld a0, 0(a0)
// 0xffffffc000000000L0
// 16M0x1000000
li a1, KERNEL_VIRT_START
//
call initial_map_256M_phys_addr
//
la a0, __initial_start_load_paddr
ld a0, 0(a0)
mv a1, a0
call initial_map_1g_identical
__init_set_pgtable_loop_end:
call __initial_reloacate_enable_mmu
.option push
.option norelax
la a0, BSP_IDLE_STACK_SPACE
mv sp, a0
li t0, 32752 // 16
add sp, sp, t0
.option pop
/*
* Disable FPU & VECTOR to detect illegal usage of
* floating point or vector in kernel space
*/
li t0, SR_FS_VS
csrc CSR_STATUS, t0
/* Call the kernel */
la a0, __initial_hartid_ptr
ld a0, 0(a0)
la a1, __initial_fdt_ptr
ld a1, 0(a1)
// kernel_main
call kernel_main
nop
wfi
__initial_reloacate_enable_mmu:
//
la t0, __initial_start_load_paddr
ld t0, 0(t0)
li t1, KERNEL_VIRT_START
sub t1, t1, t0
//
add ra, ra, t1
/* Point stvec to virtual address of intruction after satp write */
/* Set trap vector to spin forever to help debug */
la a2, 1f
add a2, a2, t1
csrw CSR_TVEC, a2
// enable MMU
la a2, __initial_pgtable
srli a2, a2, 12
la a0, __initial_satp_mode
ld a0, 0(a0)
or a2, a2, a0
sfence.vma
csrw satp, a2
1:
la a0, __initial_Lsecondary_park
add a0, a0, t1
csrw CSR_TVEC, a0
csrw satp, a2
sfence.vma
ret
// (2M1G)
//
// a0:
// a1:
initial_map_256M_phys_addr:
// 2M
li t0, 0x1fffff
and t0, t0, a0
bnez t0, __initial_map_1g_phys_failed
// 2M
li t0, 0x1fffff
and t0, t0, a1
bnez t0, __initial_map_1g_phys_failed
// t2
mv t2, a1
// 2M
li t1, -0x200000
and t2, t2, t1
// L0
srli t2, t2, 30
andi t2, t2, 511
// L0
la t4, __initial_pgtable
slli t5, t2, 3 // t5 = t2 * 8
add t4, t4, t5 // t4 = t4 + t5 t4L0
// L1
la t5, __initial_l1_pgtable
srli t5, t5, 12
slli t5, t5, 10
ori t5, t5, 0x1 // L1V = 1
// L0
sd t5, 0(t4)
// L1L1
addi t3, t2, 128
li t5, 512
blt t3, t5, __initial_set_l1_pgtable
// L1
la t3, __initial_l1_pgtable
li t5, 4096
add t3, t3, t5
srli t3, t3, 12
slli t3, t3, 10
ori t3, t3, 0x1 // L1V = 1
// L0
sd t3, 8(t4)
__initial_set_l1_pgtable: // L1
//
mv t6, a0
// L1
la t0, __initial_l1_pgtable
// L1
mv t3, a1
srli t3, t3, 21
andi t3, t3, 511
slli t3, t3, 3 // t3 = t3 * 8
add t0, t0, t3 // t0 = t0 + t3
//
li t5, 0
__initial_set_l1_pgtable_loop:
mv t3, t6
srli t3, t3, 12 // t3 = t6 >> 12 (page frame number)
li t1, 0x3FFFFFFFFFFFFF
and t3, t3, t1 // t3 = t3 & 0x3FFFFFFFFFFFFF
slli t3, t3, 10 // t3 = t3 << 10
ori t3, t3, 0xEF // L1set R/W/X/V/A/D/G = 1
// L1
sd t3, 0(t0)
//
addi t0, t0, 8
// t6 (2M)
li t2, 0x200000
add t6, t6, t2
//
addi t5, t5, 1
// 128
li t2, 128
blt t5, t2, __initial_set_l1_pgtable_loop
//
ret
__initial_map_1g_phys_failed:
// 2M
wfi
la a0, __initial_map_1g_phys_failed
//
jr a0
//
//
// a0:
initial_map_1g_identical:
mv a1, a0
// _start1GB
li t0, -0x40000000
// ,t0
and t0, t0, a0
// t2
mv t2, a1
// 1g
li t1, -0x40000000
and t2, t2, t1
// 30L0
srli t2, t2, 30
// 511L0
andi t2, t2, 511
//
la t4, __initial_pgtable
slli t3, t2, 3 // t3 = t2 * 8
add t4, t4, t3 // t4 = t4 + t3
mv t3, t0
srli t3, t3, 12 // t3 = t0 >> 12 (page frame number)
slli t3, t3, 10 // t3 = t3 << 10
ori t3, t3, 0xEF // set R/W/X/V/A/D/G = 1
// deltapfn
li t2, 0x40000000
srli t2, t2, 12
// delta pfn10
slli t2, t2, 10
li t1, 2
__loop_set_8g:
sd t3, 0(t4)
// t4
addi t4, t4, 8
// 1Gpfn
add t3, t3, t2
addi t1, t1, -1
bnez t1, __loop_set_8g
ret
//
//
// a0: page table address
__initial_clear_pgtable:
mv t0, a0
li t1, 512
li t2, 0 // 0
__initial_clear_pgtable_loop:
sd t2, 0(t0) // 0 word
addi t0, t0, 8 // t0
addi t1, t1, -1 // word
bnez t1, __initial_clear_pgtable_loop
ret
.align 2
__initial_Lsecondary_park:
/* We lack SMP support or have too many harts, so park this hart */
wfi
j __initial_Lsecondary_park
// hartid
.global __initial_fdt_ptr
__initial_fdt_ptr:
.quad 0
.global __initial_hartid_ptr
__initial_hartid_ptr:
.quad 0
// _start
.global __initial_start_load_paddr
__initial_start_load_paddr:
.quad 0
__initial_kernel_main_vaddr:
.quad 0
.global __initial_satp_mode
__initial_satp_mode:
.quad SATP_MODE_39
// sv39L0
.section .initial_pgtable_section
.global __initial_pgtable
__initial_pgtable:
.skip 4096
.global __initial_l1_pgtable
__initial_l1_pgtable:
.skip 8192