kernel/arch/riscv64/boot/
entry.rs

1use 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/// Entry point for the primary core
15#[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/// Entry point for the secondary cores
41#[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    // Initialize .bss section
70    init_bss();
71    // Initialize FDT
72    init_fdt(fdt_ptr);
73
74    // Relocate FDT to safe memory
75    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    // Create BootInfo with relocated FDT address
80    let bootinfo = create_bootinfo_from_fdt(hartid, relocated_fdt_area.start);
81
82    // Decide whether user-mode FPU/Vector handling is enabled based on DTB.
83    crate::arch::init_user_context_from_fdt();
84
85    crate::early_println!("Hart {}: Initializing core....", hartid);
86    // Get raw Riscv64 struct
87    let riscv: &mut Riscv64 = unsafe { transmute(&CPUS[hartid] as *const _ as usize) };
88    trap_init(riscv);
89
90    start_kernel(&bootinfo);
91}