mielin_hal/
lib.rs

1//! MielinOS Hardware Abstraction Layer
2//!
3//! A `no_std` hardware abstraction layer providing unified interfaces across
4//! x86_64, AArch64, RISC-V, and ARM Cortex-M architectures.
5//!
6//! ## Quick Start
7//!
8//! ```no_run
9//! use mielin_hal::{detect_architecture, capabilities, cache, system};
10//!
11//! // Detect architecture
12//! let arch = detect_architecture();
13//! println!("Running on: {}", arch);
14//!
15//! // Get hardware capabilities
16//! let profile = capabilities::HardwareProfile::detect();
17//! println!("Cores: {}, Memory: {} MB", profile.core_count, profile.memory_size / 1024 / 1024);
18//!
19//! // Cache information
20//! let cache = cache::CacheTopology::detect();
21//! println!("L1: {} KB", cache.l1_total_size() / 1024);
22//! ```
23//!
24//! ## Modules
25//!
26//! - [`arch`]: Architecture-specific implementations (x86_64, AArch64, RISC-V, Cortex-M)
27//! - [`capabilities`]: SIMD and hardware feature detection
28//! - [`cache`]: Cache topology and size information
29//! - [`system`]: Memory and CPU topology
30//! - [`platform`]: Platform-specific detection (Raspberry Pi, STM32, ESP32, BeagleBone)
31//! - [`gpu`]: GPU detection and capabilities
32//! - [`accelerator`]: NPU/TPU accelerator detection
33//! - [`power`]: Power management and frequency information
34//! - [`pmu`]: Performance Monitoring Unit (PMU) and hardware counters
35//! - [`virtualization`]: Hypervisor and container detection
36//! - [`devicetree`]: Device Tree parsing and querying
37//! - [`acpi`]: ACPI table parsing and hardware enumeration
38//! - [`runtime`]: Runtime capability switching and optimal path selection
39//! - [`error`]: Error types and handling
40//! - [`traits`]: Common trait abstractions
41//!
42//! ## Common Use Cases
43//!
44//! ### SIMD Feature Detection
45//!
46//! ```no_run
47//! use mielin_hal::capabilities::{HardwareProfile, HardwareCapabilities};
48//!
49//! let caps = HardwareProfile::detect();
50//!
51//! // x86_64
52//! if caps.capabilities.contains(HardwareCapabilities::AVX2) {
53//!     println!("AVX2 available for 256-bit SIMD");
54//! }
55//!
56//! // AArch64
57//! if caps.capabilities.contains(HardwareCapabilities::SVE) {
58//!     println!("SVE available with {} -bit vectors", caps.max_vector_width());
59//! }
60//!
61//! // RISC-V (note: RVV feature flag not yet added, use NEON as placeholder)
62//! if caps.capabilities.contains(HardwareCapabilities::NEON) {
63//!     println!("Vector extension available");
64//! }
65//! ```
66//!
67//! ### Platform-Specific Code
68//!
69//! ```no_run
70//! use mielin_hal::platform::{detect_platform, Platform, RaspberryPiCapabilities};
71//!
72//! match detect_platform() {
73//!     Platform::RaspberryPi(model) => {
74//!         let caps = RaspberryPiCapabilities::detect();
75//!         println!("Raspberry Pi {} with {} GPIO pins", model, caps.gpio_pins);
76//!     }
77//!     Platform::Stm32(family) => {
78//!         println!("STM32{} microcontroller", family);
79//!     }
80//!     Platform::Esp32(variant) => {
81//!         println!("ESP32 {} with WiFi/Bluetooth", variant);
82//!     }
83//!     _ => println!("Generic platform"),
84//! }
85//! ```
86//!
87//! ### Cache-Aware Optimization
88//!
89//! ```no_run
90//! use mielin_hal::cache::CacheTopology;
91//!
92//! let cache = CacheTopology::detect();
93//! let l1_size = cache.l1_total_size();
94//!
95//! // Use cache size for optimization
96//! println!("L1 cache: {} KB", l1_size / 1024);
97//! ```
98//!
99//! ### Power Management
100//!
101//! ```no_run
102//! use mielin_hal::power::detect_power_info;
103//!
104//! let power = detect_power_info();
105//! println!("CPU: {} - {} MHz", power.frequency.min_mhz, power.frequency.max_mhz);
106//!
107//! if power.turbo_supported {
108//!     println!("Turbo boost available");
109//! }
110//! ```
111//!
112//! ## Architecture Coverage
113//!
114//! | Architecture | Detection | SIMD | Caches | Platform | Power |
115//! |--------------|-----------|------|--------|----------|-------|
116//! | x86_64       | ✓         | ✓    | ✓      | Generic  | ✓     |
117//! | AArch64      | ✓         | ✓    | ✓      | RPi, BB  | Partial |
118//! | RISC-V       | ✓         | ✓    | ✓      | Generic  | Partial |
119//! | Cortex-M     | ✓         | Partial | ✓   | STM32, ESP32 | Limited |
120//!
121//! ## Common Traits
122//!
123//! The `traits` module provides common abstractions:
124//! - `Named` - For types with human-readable names
125//! - `DeviceInfo` - Basic device information
126//! - `ComputeDevice` - Compute-capable device interface
127//! - `MemoryDevice` - Memory information interface
128//! - `PowerDevice` - Power-aware device interface
129//!
130//! ## Safety Requirements for Architecture-Specific Code
131//!
132//! This crate contains architecture-specific code that directly accesses hardware
133//! registers and uses platform-specific instructions. When using this crate, the
134//! following safety requirements must be met:
135//!
136//! ### General Safety Requirements
137//!
138//! 1. **Correct Target Configuration**: The crate must be compiled with the correct
139//!    target triple for your hardware. Mismatched configurations may result in
140//!    undefined behavior or incorrect hardware access.
141//!
142//! 2. **Hardware Availability**: Detection functions assume the presence of standard
143//!    hardware components (e.g., CPUID on x86_64, system registers on AArch64).
144//!    Attempting to access non-existent hardware may cause faults.
145//!
146//! 3. **Privilege Level**: Some hardware detection requires specific privilege levels:
147//!    - x86_64: CPUID is generally unprivileged, but some MSRs require ring 0
148//!    - AArch64: System registers may require EL1 or higher
149//!    - Cortex-M: Some registers require privileged mode
150//!
151//! ### Architecture-Specific Safety Requirements
152//!
153//! #### x86_64
154//!
155//! - **CPUID Instructions**: The crate uses inline assembly to execute CPUID instructions.
156//!   These are safe on all x86_64 processors but may return different results based on
157//!   the CPU vendor and model.
158//!
159//! - **Register Clobbering**: Inline assembly carefully preserves register state, but
160//!   calling code should be aware of potential side effects.
161//!
162//! - **Feature Detection**: Capability detection via CPUID is inherently safe but may
163//!   not reflect runtime state (e.g., features disabled by hypervisor).
164//!
165//! #### AArch64
166//!
167//! - **System Registers**: Reading system registers (e.g., CTR_EL0) requires appropriate
168//!   exception level. The crate uses registers accessible from EL0 when possible.
169//!
170//! - **SVE/SME Detection**: Vector length detection assumes SVE/SME is enabled in the
171//!   system. Accessing disabled vector units may cause undefined instruction exceptions.
172//!
173//! #### RISC-V
174//!
175//! - **CSR Access**: Control and Status Register access may require M-mode or S-mode.
176//!   User-mode code may trap when accessing privileged CSRs.
177//!
178//! - **Vector Extension**: RVV detection assumes the vector extension is present and
179//!   enabled. Accessing disabled vector units causes illegal instruction exceptions.
180//!
181//! #### Cortex-M
182//!
183//! - **Memory-Mapped Registers**: The Cortex-M module directly accesses memory-mapped
184//!   peripheral registers. These accesses are safe ONLY when:
185//!   - Running on actual Cortex-M hardware
186//!   - The memory map matches standard Cortex-M layout (SCB at 0xE000_ED00)
187//!   - The processor is in a valid state (not halted, not in fault handler)
188//!
189//! - **Privileged Operations**: Some register reads require privileged (Handler/Thread)
190//!   mode. Unprivileged access may result in faults.
191//!
192//! - **MPU Considerations**: If the Memory Protection Unit (MPU) is enabled, it must
193//!   allow read access to SCB/NVIC registers.
194//!
195//! ### Error Handling
196//!
197//! The crate provides error types via the `error` module to handle:
198//! - Unsupported architecture features
199//! - Detection failures
200//! - Invalid parameters
201//! - Hardware access errors
202//!
203//! Always check return values and handle errors appropriately in production code.
204//!
205//! ### Testing Safety
206//!
207//! When writing tests:
208//! - Use `#[cfg(target_arch = "...")]` to ensure tests only run on supported architectures
209//! - Stub out hardware access for unit tests when possible
210//! - Use integration tests on real hardware for validation
211//! - Be aware that tests in CI may run on different hardware than production
212//!
213//! ### Examples
214//!
215//! ```no_run
216//! use mielin_hal::{Architecture, detect_architecture, error::check_architecture_support};
217//!
218//! // Check if a feature is supported before using it
219//! let result = check_architecture_support(
220//!     "SVE2",
221//!     &[Architecture::AArch64]
222//! );
223//!
224//! match result {
225//!     Ok(()) => {
226//!         // Safe to use SVE2 features
227//!     }
228//!     Err(e) => {
229//!         // Handle unsupported architecture
230//!         eprintln!("Error: {}", e);
231//!     }
232//! }
233//! ```
234
235#![no_std]
236
237extern crate alloc;
238
239pub mod accelerator;
240pub mod acpi;
241pub mod arch;
242pub mod cache;
243pub mod capabilities;
244pub mod devicetree;
245pub mod error;
246pub mod gpu;
247pub mod hardware_db;
248pub mod platform;
249pub mod pmu;
250pub mod power;
251pub mod runtime;
252pub mod system;
253pub mod traits;
254pub mod virtualization;
255
256// Re-export common traits and types at crate root
257pub use traits::{ComputeDevice, DeviceInfo, MemoryDevice, Named, PowerDevice};
258
259// Re-export error types
260pub use error::{Error, Result};
261
262// Re-export Cortex-M types when on Cortex-M architecture
263#[cfg(all(target_arch = "arm", target_os = "none"))]
264pub use arch::cortex_m::{CortexMCapabilities, DspInfo, FpuInfo, FpuVariant, MpuInfo, NvicInfo};
265
266// Re-export platform types
267pub use platform::{
268    BeagleBoneModel, Esp32Capabilities, Esp32Variant, JetsonModel, Platform, PlatformCapabilities,
269    RaspberryPiCapabilities, RaspberryPiModel, Stm32Capabilities, Stm32Family,
270};
271
272use core::fmt;
273
274#[derive(Debug, Clone, Copy, PartialEq, Eq)]
275pub enum Architecture {
276    AArch64,
277    RiscV64,
278    X86_64,
279    ArmCortexM,
280    CortexM,
281    LoongArch64,
282    Xtensa,
283}
284
285impl fmt::Display for Architecture {
286    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287        match self {
288            Architecture::AArch64 => write!(f, "aarch64"),
289            Architecture::RiscV64 => write!(f, "riscv64"),
290            Architecture::X86_64 => write!(f, "x86_64"),
291            Architecture::ArmCortexM => write!(f, "arm-cortex-m"),
292            Architecture::CortexM => write!(f, "cortex-m"),
293            Architecture::LoongArch64 => write!(f, "loongarch64"),
294            Architecture::Xtensa => write!(f, "xtensa"),
295        }
296    }
297}
298
299pub fn detect_architecture() -> Architecture {
300    #[cfg(target_arch = "aarch64")]
301    return Architecture::AArch64;
302
303    #[cfg(target_arch = "riscv64")]
304    return Architecture::RiscV64;
305
306    #[cfg(target_arch = "x86_64")]
307    return Architecture::X86_64;
308
309    #[cfg(all(target_arch = "arm", target_os = "none"))]
310    return Architecture::ArmCortexM;
311}
312
313#[cfg(test)]
314mod tests {
315    use super::*;
316
317    #[test]
318    fn test_architecture_detection() {
319        let arch = detect_architecture();
320        assert!(matches!(
321            arch,
322            Architecture::AArch64
323                | Architecture::RiscV64
324                | Architecture::X86_64
325                | Architecture::ArmCortexM
326        ));
327    }
328}