···6677use crate::{bindings, device::Device, error::Result, prelude::ENODEV};8899+/// Returns the maximum number of possible CPUs in the current system configuration.1010+#[inline]1111+pub fn nr_cpu_ids() -> u32 {1212+ #[cfg(any(NR_CPUS_1, CONFIG_FORCE_NR_CPUS))]1313+ {1414+ bindings::NR_CPUS1515+ }1616+1717+ #[cfg(not(any(NR_CPUS_1, CONFIG_FORCE_NR_CPUS)))]1818+ // SAFETY: `nr_cpu_ids` is a valid global provided by the kernel.1919+ unsafe {2020+ bindings::nr_cpu_ids2121+ }2222+}2323+2424+/// The CPU ID.2525+///2626+/// Represents a CPU identifier as a wrapper around an [`u32`].2727+///2828+/// # Invariants2929+///3030+/// The CPU ID lies within the range `[0, nr_cpu_ids())`.3131+///3232+/// # Examples3333+///3434+/// ```3535+/// use kernel::cpu::CpuId;3636+///3737+/// let cpu = 0;3838+///3939+/// // SAFETY: 0 is always a valid CPU number.4040+/// let id = unsafe { CpuId::from_u32_unchecked(cpu) };4141+///4242+/// assert_eq!(id.as_u32(), cpu);4343+/// assert!(CpuId::from_i32(0).is_some());4444+/// assert!(CpuId::from_i32(-1).is_none());4545+/// ```4646+#[derive(Copy, Clone, PartialEq, Eq, Debug)]4747+pub struct CpuId(u32);4848+4949+impl CpuId {5050+ /// Creates a new [`CpuId`] from the given `id` without checking bounds.5151+ ///5252+ /// # Safety5353+ ///5454+ /// The caller must ensure that `id` is a valid CPU ID (i.e., `0 <= id < nr_cpu_ids()`).5555+ #[inline]5656+ pub unsafe fn from_i32_unchecked(id: i32) -> Self {5757+ debug_assert!(id >= 0);5858+ debug_assert!((id as u32) < nr_cpu_ids());5959+6060+ // INVARIANT: The function safety guarantees `id` is a valid CPU id.6161+ Self(id as u32)6262+ }6363+6464+ /// Creates a new [`CpuId`] from the given `id`, checking that it is valid.6565+ pub fn from_i32(id: i32) -> Option<Self> {6666+ if id < 0 || id as u32 >= nr_cpu_ids() {6767+ None6868+ } else {6969+ // INVARIANT: `id` has just been checked as a valid CPU ID.7070+ Some(Self(id as u32))7171+ }7272+ }7373+7474+ /// Creates a new [`CpuId`] from the given `id` without checking bounds.7575+ ///7676+ /// # Safety7777+ ///7878+ /// The caller must ensure that `id` is a valid CPU ID (i.e., `0 <= id < nr_cpu_ids()`).7979+ #[inline]8080+ pub unsafe fn from_u32_unchecked(id: u32) -> Self {8181+ debug_assert!(id < nr_cpu_ids());8282+8383+ // Ensure the `id` fits in an [`i32`] as it's also representable that way.8484+ debug_assert!(id <= i32::MAX as u32);8585+8686+ // INVARIANT: The function safety guarantees `id` is a valid CPU id.8787+ Self(id)8888+ }8989+9090+ /// Creates a new [`CpuId`] from the given `id`, checking that it is valid.9191+ pub fn from_u32(id: u32) -> Option<Self> {9292+ if id >= nr_cpu_ids() {9393+ None9494+ } else {9595+ // INVARIANT: `id` has just been checked as a valid CPU ID.9696+ Some(Self(id))9797+ }9898+ }9999+100100+ /// Returns CPU number.101101+ #[inline]102102+ pub fn as_u32(&self) -> u32 {103103+ self.0104104+ }105105+}106106+107107+impl From<CpuId> for u32 {108108+ fn from(id: CpuId) -> Self {109109+ id.as_u32()110110+ }111111+}112112+113113+impl From<CpuId> for i32 {114114+ fn from(id: CpuId) -> Self {115115+ id.as_u32() as i32116116+ }117117+}118118+9119/// Creates a new instance of CPU's device.10120///11121/// # Safety