kernel/arch/riscv64/boot/
entry.rs1use core::{arch::naked_asm, mem::transmute};
2
3use crate::{
4 arch::{
5 Riscv64,
6 riscv64::{CPUS, trap_init},
7 },
8 device::fdt::{create_bootinfo_from_fdt, init_fdt, relocate_fdt},
9 environment::STACK_SIZE,
10 mem::{__FDT_RESERVED_START, init_bss},
11 start_kernel,
12};
13
14#[unsafe(link_section = ".init")]
16#[unsafe(export_name = "_entry")]
17#[unsafe(naked)]
18pub extern "C" fn _entry() {
19 unsafe {
20 naked_asm!("
21 .attribute arch, \"rv64gc\"
22 .option norvc
23 .option norelax
24 .align 8
25 // a0 = hartid
26 li t0, {}
27 mv t1, a0
28 addi t1, t1, 1
29 mul t1, t1, a0
30 la sp, KERNEL_STACK
31 add sp, sp, t0
32
33 la t0, arch_start_kernel
34 jr t0
35 ", const STACK_SIZE
36 );
37 }
38}
39
40#[unsafe(link_section = ".init")]
42#[unsafe(export_name = "_entry_ap")]
43#[unsafe(naked)]
44pub extern "C" fn _entry_ap() {
45 unsafe {
46 naked_asm!("
47 .attribute arch, \"rv64gc\"
48 .option norvc
49 .option norelax
50 .align 8
51 // a0 = hartid
52 li t0, {}
53 mv t1, a0
54 addi t1, t1, 1
55 mul t1, t1, a0
56 la sp, KERNEL_STACK
57 add sp, sp, t0
58
59 // Use indirect jump to avoid JAL range limitation
60 la t0, start_ap
61 jr t0
62 ", const STACK_SIZE
63 );
64 }
65}
66
67#[unsafe(no_mangle)]
68pub extern "C" fn arch_start_kernel(hartid: usize, fdt_ptr: usize) {
69 init_bss();
71 init_fdt(fdt_ptr);
73
74 let fdt_reloc_start = unsafe { &__FDT_RESERVED_START as *const usize as usize };
76 let dest_ptr = fdt_reloc_start as *mut u8;
77 let relocated_fdt_area = relocate_fdt(dest_ptr);
78
79 let bootinfo = create_bootinfo_from_fdt(hartid, relocated_fdt_area.start);
81
82 crate::arch::init_user_context_from_fdt();
84
85 crate::early_println!("Hart {}: Initializing core....", hartid);
86 let riscv: &mut Riscv64 = unsafe { transmute(&CPUS[hartid] as *const _ as usize) };
88 trap_init(riscv);
89
90 start_kernel(&bootinfo);
91}