diff --git a/example/Cargo.toml b/example/Cargo.toml index 033764c..11e46cf 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -12,6 +12,7 @@ polyhal = { version = "0.1.2", features = [ "boot", "trap", "graphic", + "multicore" ] } log = "0.4" fdt = "0.1.5" diff --git a/example/Makefile b/example/Makefile index 562a5d4..17d7430 100644 --- a/example/Makefile +++ b/example/Makefile @@ -2,6 +2,7 @@ ARCH := riscv64 TEST := false GUI := false +SMP := 1 ifeq ($(TEST), true) QEMU_EXEC := timeout 40 @@ -35,7 +36,7 @@ else ifeq ($(ARCH), loongarch64) TARGET := loongarch64-unknown-none KERNEL_ELF := target/$(TARGET)/release/example KERNEL_BIN := $(KERNEL_ELF).bin - QEMU_EXEC += qemu-system-$(ARCH) -kernel $(KERNEL_ELF) + QEMU_EXEC += qemu-system-$(ARCH) -kernel $(KERNEL_ELF) -M virt -m 1G BUILD_ARGS += -Z build-std=core,alloc BUS := pci else @@ -69,8 +70,8 @@ run: run-inner ifneq ($(GUI), true) QEMU_EXEC += -nographic endif -QEMU_EXEC += -smp 1 -QEMU_EXEC += -D qemu.log -d in_asm,int,pcall,cpu_reset,guest_errors +QEMU_EXEC += -smp $(SMP) +QEMU_EXEC += -D qemu-%d.log -d in_asm,int,pcall,cpu_reset,guest_errors,tid ifeq ($(TEST), true) QEMU_EXEC += >output.log 2>&1 || echo "QEMU exited" endif @@ -81,6 +82,9 @@ ifeq ($(TEST), true) grep "\[kernel\] Hello, world!" output.log endif +debug: build + $(QEMU_EXEC) -s -S + test: make ARCH=aarch64 run make ARCH=riscv64 run @@ -89,9 +93,15 @@ test: iso: build cp $(KERNEL_ELF) iso/example - grub-mkrescue -o bootable.iso iso + grub2-mkrescue -o bootable.iso iso boot-iso: iso - qemu-system-x86_64 -cdrom bootable.iso + qemu-system-x86_64 -cdrom bootable.iso -serial stdio + +gdb: + gdb \ + -ex 'file $(KERNEL_ELF)' \ + -ex 'set arch x86_64' \ + -ex 'target remote localhost:1234' .PHONY: build env kernel clean run-inner diff --git a/example/linker/linker-loongarch64.ld b/example/linker/linker-loongarch64.ld index 554931d..c98e52e 100644 --- a/example/linker/linker-loongarch64.ld +++ b/example/linker/linker-loongarch64.ld @@ -1,7 +1,7 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0x9000000090000000; +BASE_ADDRESS = 0x9000000080000000; SECTIONS { diff --git a/example/src/main.rs b/example/src/main.rs index 7d4aa2f..99b7248 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -57,6 +57,10 @@ fn kernel_interrupt(ctx: &mut TrapFrame, trap_type: TrapType) { #[polyhal::arch_entry] /// kernel main function, entry point. fn main(hartid: usize) { + if hartid != 0 { + log::info!("Hello Other Hart: {}", hartid); + loop {} + } if hartid != 0 { return; } @@ -76,6 +80,9 @@ fn main(hartid: usize) { // frame::add_frame_range(start, start + size); }); + polyhal::multicore::MultiCore::boot_all(); + + crate::pci::init(); loop { diff --git a/src/components/boot/loongarch64.rs b/src/components/boot/loongarch64.rs index 9ed5100..c18b47e 100644 --- a/src/components/boot/loongarch64.rs +++ b/src/components/boot/loongarch64.rs @@ -27,9 +27,6 @@ unsafe extern "C" fn _start() -> ! { lu52i.d $t0, $t0, -1792 # CA, PLV0, 0x9000 xxxx xxxx xxxx csrwr $t0, 0x181 # LOONGARCH_CSR_DMWIN1 - // csrrd $t1, 0x20 # read cpu from csr - // bnez $t1, _start_secondary - # Enable PG li.w $t0, 0xb0 # PLV=0, IE=0, PG=1 csrwr $t0, 0x0 # LOONGARCH_CSR_CRMD @@ -56,16 +53,33 @@ unsafe extern "C" fn _start() -> ! { /// The earliest entry point for the primary CPU. /// /// We can't use bl to jump to higher address, so we use jirl to jump to higher address. +/// TODO: Dynamic Stack Pointer. #[naked] #[no_mangle] #[link_section = ".text.entry"] -unsafe extern "C" fn _start_secondary() -> ! { +pub(crate) unsafe extern "C" fn _start_secondary() -> ! { core::arch::asm!( " - idle 1 - b _start_secondary + ori $t0, $zero, 0x1 # CSR_DMW1_PLV0 + lu52i.d $t0, $t0, -2048 # UC, PLV0, 0x8000 xxxx xxxx xxxx + csrwr $t0, 0x180 # LOONGARCH_CSR_DMWIN0 + ori $t0, $zero, 0x11 # CSR_DMW1_MAT | CSR_DMW1_PLV0 + lu52i.d $t0, $t0, -1792 # CA, PLV0, 0x9000 xxxx xxxx xxxx + csrwr $t0, 0x181 # LOONGARCH_CSR_DMWIN1 + + la.abs $sp, {sec_boot_stack_top} + li.d $t0, {boot_stack_size} + add.d $sp, $sp, $t0 # setup boot stack + + csrrd $a0, 0x20 # cpuid + la.global $t0, {entry} + + jirl $zero,$t0,0 ", options(noreturn), + sec_boot_stack_top = sym crate::components::boot::BOOT_STACK, + boot_stack_size = const crate::components::boot::STACK_SIZE, + entry = sym _rust_secondary_main, ) } @@ -110,7 +124,19 @@ fn init_cpu() { } /// The entry point for the second core. -pub(crate) extern "C" fn _rust_secondary_main(_hartid: usize) {} +pub(crate) extern "C" fn _rust_secondary_main(hart_id: usize) { + percpu_area_init(hart_id); + + #[cfg(feature = "trap")] + crate::components::trap::set_trap_vector_base(); + // Initialize CPU Configuration. + init_cpu(); + crate::components::timer::init_timer(); + #[cfg(feature = "trap")] + crate::components::trap::tlb_init(crate::components::trap::tlb_fill as _); + + unsafe { crate::components::boot::_main_for_arch(hart_id) }; +} pub fn boot_page_table() -> PageTable { // FIXME: This should return a valid page table. diff --git a/src/components/multicore/loongarch64.rs b/src/components/multicore/loongarch64.rs index d25f99a..e9b6763 100644 --- a/src/components/multicore/loongarch64.rs +++ b/src/components/multicore/loongarch64.rs @@ -1,5 +1,11 @@ +use loongArch64::ipi::{csr_mail_send, send_ipi_single}; + use crate::components::multicore::MultiCore; impl MultiCore { - pub fn boot_all() {} + pub fn boot_all() { + csr_mail_send(crate::components::boot::_start_secondary as _, 1, 0); + send_ipi_single(1, 1); + loop {} + } }