Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
81 changes: 76 additions & 5 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 @@ -103,10 +107,11 @@ pub mod context {
}

pub use axcpu::asm;
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 All @@ -125,19 +130,85 @@ pub fn init_percpu_secondary(cpu_id: usize) {
self::percpu::init_secondary(cpu_id);
}

use lazyinit::LazyInit;

static BOOT_ARG: LazyInit<usize> = LazyInit::new();

/// Initializes the platform and boot argument.
/// This function should be called as early as possible.
pub fn init_early(cpu_id: usize, arg: usize) {
BOOT_ARG.init_once(arg);
axplat::init::init_early(cpu_id, arg);
}

/// Initializes the platform later stage.
pub fn init_later(cpu_id: usize, arg: usize) {
axplat::init::init_later(cpu_id, arg);
init_cpu_num();
}

use lazyinit::LazyInit;

static BOOT_ARG: LazyInit<usize> = LazyInit::new();

/// Returns the boot argument.
/// This is typically the device tree blob address passed from the bootloader.
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")]
{
// 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.
//
// Acquire may result in a performance penalty, but this function is not
// expected to be called frequently in normal operation.
CPU_NUM.load(Ordering::Acquire)
}
#[cfg(not(feature = "smp"))]
{
1
}
}

/// Initializes the CPU number information.
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
Loading
Loading