rv64: fix smp init in asymmetric systems

This commit is contained in:
Mark Poliakov 2025-01-21 16:53:57 +02:00
parent 909980f4eb
commit cfc11c402a
4 changed files with 36 additions and 21 deletions

View File

@ -121,7 +121,6 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
let sp = stack.build();
// TODO stack is leaked
log::info!("stack = {:#x}", stack_base);
let satp = InMemoryRegister::new(0);
let kernel_table_phys =
((&raw const mem::KERNEL_TABLES).addr() - KERNEL_VIRT_OFFSET) as u64;

View File

@ -1,5 +1,5 @@
#![allow(missing_docs)]
use core::sync::atomic::{self, AtomicBool, AtomicU32, Ordering};
use core::sync::atomic::{self, AtomicU32, Ordering};
use abi::error::Error;
use alloc::sync::Arc;
@ -44,13 +44,11 @@ pub static BOOT_HART_ID: AtomicU32 = AtomicU32::new(u32::MAX);
pub struct Riscv64 {
dt: OneTimeInit<DeviceTree<'static>>,
initrd: OneTimeInit<PhysicalRef<'static, [u8]>>,
smp: AtomicBool,
}
pub static PLATFORM: Riscv64 = Riscv64 {
dt: OneTimeInit::new(),
initrd: OneTimeInit::new(),
smp: AtomicBool::new(true),
};
#[derive(Debug, Clone, Copy)]
@ -69,22 +67,16 @@ impl Platform for Riscv64 {
}
unsafe fn send_ipi(&self, target: IpiDeliveryTarget, msg: IpiMessage) -> Result<bool, Error> {
if self.smp.load(Ordering::Acquire) {
smp::send_ipi(target, msg)?;
Ok(true)
} else {
Ok(false)
}
smp::send_ipi(target, msg)?;
Ok(true)
}
unsafe fn start_application_processors(&self) {
// TODO asymmetric systems with different hart types are not yet supported.
// e.g., in JH7110 there're two different types of cores
if self.smp.load(Ordering::Acquire) {
let dt = self.dt.get();
if let Err(error) = smp::start_secondary_harts(dt) {
log::error!("Couldn't start secondary harts: {error:?}");
}
let dt = self.dt.get();
if let Err(error) = smp::start_secondary_harts(dt) {
log::error!("Couldn't start secondary harts: {error:?}");
}
}
@ -260,10 +252,6 @@ impl Riscv64 {
fn apply_board_workarounds(compatible: &str) {
#[allow(clippy::single_match)]
match compatible {
"starfive,visionfive-2-v1.3b" => {
log::warn!("VisionFive 2: disabling SMP, OS doesn't yet handle the HARTs properly");
PLATFORM.smp.store(false, Ordering::Release);
}
_ => (),
}
}

View File

@ -61,11 +61,40 @@ pub fn start_secondary_harts(dt: &DeviceTree) -> Result<(), Error> {
let boot_hart_id = BOOT_HART_ID.load(Ordering::Acquire);
let cpus = dt.find_absolute("/cpus").ok_or(Error::DoesNotExist)?;
// Find the boot hart
let boot_hart_isa = cpus
.children()
.find(|child| child.prop_cell_usize("reg") == Some(boot_hart_id as usize))
.and_then(|child| child.prop_string("riscv,isa"))
.ok_or(Error::DoesNotExist)
.inspect_err(|_| log::error!("Could not find the boot hart {boot_hart_id} in the dtb"))?;
// Print a list of HARTs
for cpu in cpus.children() {
let Some(reg) = cpu.prop_cell_usize("reg") else {
continue;
};
if reg == boot_hart_id as usize {
let isa = cpu.prop_string("riscv,isa").unwrap_or("???");
let letter = if reg == boot_hart_id as usize {
'@'
} else if isa == boot_hart_isa {
'+'
} else {
'-'
};
log::info!("{letter} {reg}: {isa}");
}
for cpu in cpus.children() {
let Some(reg) = cpu.prop_cell_usize("reg") else {
continue;
};
let isa = cpu.prop_string("riscv,isa").unwrap_or("???");
if reg == boot_hart_id as usize || isa != boot_hart_isa {
continue;
}

View File

@ -73,7 +73,6 @@ pub unsafe fn enter() -> ! {
AP_CAN_ENTER.signal();
}
log::info!("Start queue_index={}", cpu.queue_index());
let queue = CpuQueue::for_cpu(cpu.queue_index());
cpu.set_scheduler(queue);