Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
# - `ARCH`: Target architecture: x86_64, riscv64, aarch64, loongarch64
# - `MYPLAT`: Package name of the target platform crate.
# - `PLAT_CONFIG`: Path to the platform configuration file.
# - `SMP`: Number of CPUs. If not set, use the default value from platform config.
# - `SMP`: Override maximum CPU number specified in the platform config. For
# statically configured platforms, this is also the number of CPUs to boot
# and for platforms with runtime CPU detection, this is the upper limit of
# CPUs.
# - `MODE`: Build mode: release, debug
# - `LOG:` Logging level: warn, error, info, debug, trace
# - `V`: Verbose level: (empty), 1, 2
Expand Down
7 changes: 6 additions & 1 deletion api/arceos_api/src/imp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ mod stdio {
}
}

mod sys {
pub use axhal::cpu_num as ax_get_cpu_num;
pub use axhal::power::system_off as ax_terminate;
}

mod time {
pub use axhal::time::{
TimeValue as AxTimeValue, monotonic_time as ax_monotonic_time, wall_time as ax_wall_time,
Expand All @@ -47,8 +52,8 @@ mod time {

pub use self::mem::*;
pub use self::stdio::*;
pub use self::sys::*;
pub use self::task::*;
pub use self::time::*;

pub use axhal::power::system_off as ax_terminate;
pub use axio::PollState as AxPollState;
3 changes: 3 additions & 0 deletions api/arceos_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ pub mod sys {
define_api! {
/// Shutdown the whole system and all CPUs.
pub fn ax_terminate() -> !;

/// Returns the number of CPUs in the system.
pub fn ax_get_cpu_num() -> usize;
}
}

Expand Down
2 changes: 1 addition & 1 deletion api/arceos_posix_api/src/imp/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn sys_sysconf(name: c_int) -> c_long {
// Page size
ctypes::_SC_PAGE_SIZE => Ok(PAGE_SIZE_4K),
// Number of processors in use
ctypes::_SC_NPROCESSORS_ONLN => Ok(axconfig::plat::CPU_NUM),
ctypes::_SC_NPROCESSORS_ONLN => Ok(axhal::cpu_num()),
// Total physical pages
ctypes::_SC_PHYS_PAGES => Ok(axhal::mem::total_ram_size() / PAGE_SIZE_4K),
// Avaliable physical pages
Expand Down
5 changes: 3 additions & 2 deletions configs/custom/x86_64-pc-oslab.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ package = "axplat-x86-pc" # str
# Platform configs
#
[plat]
# Number of CPUs.
cpu-num = 8 # uint
# Maximum number of CPUs. For platforms that do not support runtime CPU number
# detection, it's also the number of CPUs to boot (like this platform).
max-cpu-num = 8 # uint
# Base address of the whole physical memory.
phys-memory-base = 0 # uint
# Size of the whole physical memory. (2G)
Expand Down
5 changes: 3 additions & 2 deletions configs/dummy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ ticks-per-sec = 100 # uint
#
[plat]
# Platform family.
# Number of CPUs
cpu-num = 1 # uint
# Maximum number of CPUs. For platforms that do not support runtime CPU number
# detection, it's also the number of CPUs to boot.
max-cpu-num = 1 # uint
# Base address of the whole physical memory.
phys-memory-base = 0 # uint
# Size of the whole physical memory.
Expand Down
14 changes: 7 additions & 7 deletions examples/helloworld-myplat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ cfg-if = "1.0"
axstd = { workspace = true, features = ["myplat"], optional = true }

[target.'cfg(target_arch = "x86_64")'.dependencies]
axplat-x86-pc = { version = "0.2", features = ["smp", "irq"], optional = true }
axplat-x86-pc = { version = "0.3", features = ["smp", "irq"], optional = true }

[target.'cfg(target_arch = "aarch64")'.dependencies]
axplat-aarch64-qemu-virt = { version = "0.2", features = ["smp", "irq"], optional = true }
axplat-aarch64-raspi = { version = "0.2", features = ["smp", "irq"], optional = true }
axplat-aarch64-bsta1000b = { version = "0.2", features = ["smp", "irq"], optional = true }
axplat-aarch64-phytium-pi = { version = "0.2", features = ["smp", "irq"], optional = true }
axplat-aarch64-qemu-virt = { version = "0.3", features = ["smp", "irq"], optional = true }
axplat-aarch64-raspi = { version = "0.3", features = ["smp", "irq"], optional = true }
axplat-aarch64-bsta1000b = { version = "0.3", features = ["smp", "irq"], optional = true }
axplat-aarch64-phytium-pi = { version = "0.3", features = ["smp", "irq"], optional = true }

[target.'cfg(target_arch = "riscv64")'.dependencies]
axplat-riscv64-qemu-virt = { version = "0.2", features = ["smp", "irq"], optional = true }
axplat-riscv64-qemu-virt = { version = "0.3", features = ["smp", "irq"], optional = true }

[target.'cfg(target_arch = "loongarch64")'.dependencies]
axplat-loongarch64-qemu-virt = { version = "0.2", features = ["smp", "irq"], optional = true }
axplat-loongarch64-qemu-virt = { version = "0.3", features = ["smp", "irq"], optional = true }
10 changes: 5 additions & 5 deletions modules/axhal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,23 @@ memory_addr = "0.4"
linkme = { version = "0.3.33", optional = true }
page_table_multiarch = { version = "0.5", features = ["copy-from"], optional = true }
axcpu = "0.2"
axplat = "0.2"
axplat = "0.3"
axlog = { workspace = true }
axconfig = { workspace = true }
axalloc = { workspace = true, optional = true }

[target.'cfg(target_arch = "x86_64")'.dependencies]
axplat-x86-pc = { version = "0.2", optional = true }
axplat-x86-pc = { version = "0.3", optional = true }

[target.'cfg(target_arch = "aarch64")'.dependencies]
aarch64-cpu = "10.0"
axplat-aarch64-qemu-virt = { version = "0.2", optional = true }
axplat-aarch64-qemu-virt = { version = "0.3", optional = true }

[target.'cfg(target_arch = "riscv64")'.dependencies]
axplat-riscv64-qemu-virt = { version = "0.2", optional = true }
axplat-riscv64-qemu-virt = { version = "0.3", optional = true }

[target.'cfg(target_arch = "loongarch64")'.dependencies]
axplat-loongarch64-qemu-virt = { version = "0.2", optional = true }
axplat-loongarch64-qemu-virt = { version = "0.3", optional = true }

[build-dependencies]
axconfig = { workspace = true }
2 changes: 1 addition & 1 deletion modules/axhal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn gen_linker_script(arch: &str, platform: &str) -> Result<()> {
"%KERNEL_BASE%",
&format!("{:#x}", axconfig::plat::KERNEL_BASE_VADDR),
);
let ld_content = ld_content.replace("%CPU_NUM%", &format!("{}", axconfig::plat::CPU_NUM));
let ld_content = ld_content.replace("%CPU_NUM%", &format!("{}", axconfig::plat::MAX_CPU_NUM));

// target/<target_triple>/<mode>/build/axhal-xxxx/out
let out_dir = std::env::var("OUT_DIR").unwrap();
Expand Down
4 changes: 4 additions & 0 deletions modules/axhal/src/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ impl PowerIf for DummyPower {
fn system_off() -> ! {
unimplemented!()
}

fn cpu_num() -> usize {
1
}
}

#[cfg(feature = "irq")]
Expand Down
66 changes: 66 additions & 0 deletions modules/axhal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
#[macro_use]
extern crate log;

#[allow(unused_imports)]
#[macro_use]
extern crate axlog;

#[allow(unused_imports)]
#[macro_use]
extern crate memory_addr;
Expand Down Expand Up @@ -107,6 +111,8 @@ pub use axplat::init::init_later;

#[cfg(feature = "smp")]
pub use axplat::init::{init_early_secondary, init_later_secondary};
#[cfg(feature = "smp")]
use core::sync::atomic::{AtomicUsize, Ordering};

/// Initializes CPU-local data structures for the primary core.
///
Expand Down Expand Up @@ -141,3 +147,63 @@ pub fn init_early(cpu_id: usize, arg: usize) {
pub fn get_bootarg() -> usize {
*BOOT_ARG
}

/// The number of CPUs in the system. Based on the number declared by the
/// platform crate and limited by the configured maximum CPU number.
#[cfg(feature = "smp")]
static CPU_NUM: AtomicUsize = AtomicUsize::new(1);

/// Gets the number of CPUs running in the system.
///
/// When SMP is disabled, this function always returns 1.
///
/// When SMP is enabled, it's the smaller one between the platform-declared CPU
/// number [`axplat::power::cpu_num`] and the configured maximum CPU number
/// `axconfig::plat::MAX_CPU_NUM`.
///
/// This value is determined during the BSP initialization phase.
pub fn cpu_num() -> usize {
#[cfg(feature = "smp")]
{
// Relaxed is used here for best performance, as this value is only set
// once during initialization and never changed afterwards.
//
// The BSP will always see the correct value because `CPU_NUM` is set by
// itself.
//
// All APs will see the correct value because it is written with
// `Ordering::Release` and read with `Ordering::Acquire`, ensuring
// memory visibility.
CPU_NUM.load(Ordering::Acquire)
}
#[cfg(not(feature = "smp"))]
{
1
}
}

/// Initializes the CPU number information.
pub fn init_cpu_num() {
#[cfg(feature = "smp")]
{
let plat_cpu_num = axplat::power::cpu_num();
let max_cpu_num = axconfig::plat::MAX_CPU_NUM;
let cpu_num = plat_cpu_num.min(max_cpu_num);

info!("CPU number: max = {max_cpu_num}, platform = {plat_cpu_num}, use = {cpu_num}",);
ax_println!("smp = {}", cpu_num); // for test purposes

if plat_cpu_num > max_cpu_num {
warn!(
"platform declares more CPUs ({plat_cpu_num}) than configured max ({max_cpu_num}), \
only the first {max_cpu_num} CPUs will be used."
);
}

CPU_NUM.store(cpu_num, Ordering::Release);
}
#[cfg(not(feature = "smp"))]
{
ax_println!("smp = 1"); // for test purposes
}
}
2 changes: 1 addition & 1 deletion modules/axipi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub fn run_on_cpu<T: Into<Callback>>(dest_cpu: usize, callback: T) {
pub fn run_on_each_cpu<T: Into<MulticastCallback>>(callback: T) {
info!("Send IPI event to all other CPUs");
let current_cpu_id = this_cpu_id();
let cpu_num = axconfig::plat::CPU_NUM;
let cpu_num = axhal::cpu_num();
let callback = callback.into();

// Execute callback on current CPU immediately
Expand Down
2 changes: 1 addition & 1 deletion modules/axruntime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ axnet = { workspace = true, optional = true }
axdisplay = { workspace = true, optional = true }
axtask = { workspace = true, optional = true }
axipi = { workspace = true, optional = true }
axplat = "0.2"
axplat = "0.3"

crate_interface = "0.1"
percpu = { version = "0.2", optional = true }
Expand Down
7 changes: 4 additions & 3 deletions modules/axruntime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ impl axlog::LogIf for LogIfImpl {

use core::sync::atomic::{AtomicUsize, Ordering};

/// Number of CPUs that have completed initialization.
static INITED_CPUS: AtomicUsize = AtomicUsize::new(0);

fn is_init_ok() -> bool {
INITED_CPUS.load(Ordering::Acquire) == axconfig::plat::CPU_NUM
INITED_CPUS.load(Ordering::Acquire) == axhal::cpu_num()
}

/// The main entry point of the ArceOS runtime.
Expand All @@ -116,14 +117,12 @@ pub fn rust_main(cpu_id: usize, arg: usize) -> ! {
target = {}\n\
build_mode = {}\n\
log_level = {}\n\
smp = {}\n\
",
axconfig::ARCH,
axconfig::PLATFORM,
option_env!("AX_TARGET").unwrap_or(""),
option_env!("AX_MODE").unwrap_or(""),
option_env!("AX_LOG").unwrap_or(""),
axconfig::plat::CPU_NUM,
);
#[cfg(feature = "rtc")]
ax_println!(
Expand Down Expand Up @@ -157,6 +156,8 @@ pub fn rust_main(cpu_id: usize, arg: usize) -> ! {
info!("Initialize platform devices...");
axhal::init_later(cpu_id, arg);

axhal::init_cpu_num();

#[cfg(feature = "multitask")]
axtask::init_scheduler();

Expand Down
Loading
Loading