Skip to main content

oxigdal_embedded/target/
mod.rs

1//! Target-specific optimizations and support
2//!
3//! Provides architecture-specific implementations for embedded platforms
4
5pub mod arm;
6pub mod common;
7pub mod esp32;
8pub mod riscv;
9
10/// Target architecture trait
11pub trait TargetArch {
12    /// Get the target name
13    fn name(&self) -> &'static str;
14
15    /// Get the native pointer size in bytes
16    fn pointer_size(&self) -> usize;
17
18    /// Get the native alignment
19    fn native_alignment(&self) -> usize;
20
21    /// Check if target supports unaligned access
22    fn supports_unaligned_access(&self) -> bool;
23
24    /// Perform a memory barrier
25    fn memory_barrier(&self);
26
27    /// Get cycle counter if available
28    fn cycle_count(&self) -> Option<u64>;
29}
30
31/// Memory ordering for atomic operations
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum MemoryOrder {
34    /// Relaxed ordering
35    Relaxed,
36    /// Acquire ordering
37    Acquire,
38    /// Release ordering
39    Release,
40    /// Acquire-Release ordering
41    AcquireRelease,
42    /// Sequentially consistent ordering
43    SeqCst,
44}
45
46/// Cache operation type
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum CacheOp {
49    /// Clean cache (write back dirty lines)
50    Clean,
51    /// Invalidate cache (discard lines)
52    Invalidate,
53    /// Clean and invalidate
54    CleanInvalidate,
55}
56
57/// Target capabilities
58#[derive(Debug, Clone, Copy)]
59pub struct TargetCapabilities {
60    /// Has hardware floating point
61    pub has_fpu: bool,
62    /// Has SIMD instructions
63    pub has_simd: bool,
64    /// Has hardware AES
65    pub has_aes: bool,
66    /// Has hardware CRC
67    pub has_crc: bool,
68    /// Cache line size in bytes
69    pub cache_line_size: usize,
70    /// Number of cores
71    pub num_cores: usize,
72}
73
74impl Default for TargetCapabilities {
75    fn default() -> Self {
76        Self {
77            has_fpu: false,
78            has_simd: false,
79            has_aes: false,
80            has_crc: false,
81            cache_line_size: 64,
82            num_cores: 1,
83        }
84    }
85}
86
87/// Get current target capabilities
88pub fn get_capabilities() -> TargetCapabilities {
89    #[cfg(feature = "arm")]
90    {
91        arm::get_capabilities()
92    }
93
94    #[cfg(all(feature = "riscv", not(feature = "arm")))]
95    {
96        riscv::get_capabilities()
97    }
98
99    #[cfg(all(feature = "esp32", not(any(feature = "arm", feature = "riscv"))))]
100    {
101        esp32::get_capabilities()
102    }
103
104    #[cfg(not(any(feature = "arm", feature = "riscv", feature = "esp32")))]
105    {
106        TargetCapabilities::default()
107    }
108}
109
110/// Perform a memory barrier appropriate for the target
111#[inline]
112pub fn memory_barrier() {
113    #[cfg(feature = "arm")]
114    arm::memory_barrier();
115
116    #[cfg(all(feature = "riscv", not(feature = "arm")))]
117    riscv::memory_barrier();
118
119    #[cfg(all(feature = "esp32", not(any(feature = "arm", feature = "riscv"))))]
120    esp32::memory_barrier();
121
122    #[cfg(not(any(feature = "arm", feature = "riscv", feature = "esp32")))]
123    core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
124}
125
126/// Get cycle count if available
127#[inline]
128pub fn cycle_count() -> Option<u64> {
129    #[cfg(feature = "arm")]
130    {
131        arm::cycle_count()
132    }
133
134    #[cfg(all(feature = "riscv", not(feature = "arm")))]
135    {
136        riscv::cycle_count()
137    }
138
139    #[cfg(all(feature = "esp32", not(any(feature = "arm", feature = "riscv"))))]
140    {
141        esp32::cycle_count()
142    }
143
144    #[cfg(not(any(feature = "arm", feature = "riscv", feature = "esp32")))]
145    {
146        None
147    }
148}
149
150#[cfg(test)]
151mod tests {
152    use super::*;
153
154    #[test]
155    fn test_capabilities() {
156        let caps = get_capabilities();
157        assert!(caps.cache_line_size > 0);
158        assert!(caps.num_cores > 0);
159    }
160
161    #[test]
162    fn test_memory_barrier() {
163        // Should not panic
164        memory_barrier();
165    }
166}