rv64: fix smp init in asymmetric systems
This commit is contained in:
parent
909980f4eb
commit
cfc11c402a
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user