Skip to main content

sparreal_kernel/hal/
al.rs

1use core::ptr::NonNull;
2
3use alloc::boxed::Box;
4pub use heapless::Vec as StackVec;
5use kernutil::define_type;
6pub use kernutil::memory::{MemoryDescriptor, PageTableInfo};
7pub use page_table_generic::{AccessFlags, MemAttributes, MemConfig, PagingError};
8pub use rdrive::register::DriverRegisterSlice;
9
10use crate::os::mem::{__io, page_size};
11
12#[trait_ffi::def_extern_trait(mod_path = "hal::al")]
13pub trait Memory {
14    fn _va(paddr: PhysAddr) -> VirtAddr;
15    fn _io(paddr: PhysAddr) -> VirtAddr;
16    fn _percpu(paddr: PhysAddr) -> VirtAddr;
17
18    /// 内核镜像在虚拟地址空间中的偏移
19    fn kimage_offset() -> isize;
20
21    /// Convert virtual address to physical address
22    fn virt_to_phys(virt: VirtAddr) -> PhysAddr;
23
24    fn page_size() -> usize;
25    fn memory_map() -> &'static [MemoryDescriptor];
26
27    fn page_table_new() -> Result<Box<dyn PageTable>, PagingError>;
28
29    fn kernel_page_table() -> PhysAddr;
30    fn set_kernel_page_table(pt: PhysAddr);
31    fn user_page_table() -> PageTableInfo;
32    fn set_user_page_table(pt: PageTableInfo);
33}
34
35#[trait_ffi::def_extern_trait(not_def_impl, mod_path = "hal::al")]
36pub trait Platform {
37    fn irq_is_enabled(irq: IrqId) -> bool;
38    fn irq_set_enabled(irq: IrqId, enabled: bool);
39
40    fn shutdown() -> !;
41
42    fn fdt_addr() -> Option<NonNull<u8>>;
43    fn post_paging();
44}
45
46#[trait_ffi::def_extern_trait(not_def_impl, mod_path = "hal::al")]
47pub trait Cpu {
48    fn cpu_count() -> usize;
49    /// Power on logical CPU index.
50    ///
51    /// Return values:
52    /// - 0: success
53    /// - 1: not supported
54    /// - 2: already on
55    /// - 3: invalid parameters
56    /// - 4: other error
57    fn cpu_on(cpu_idx: usize) -> usize;
58    fn current_cpu_id() -> usize;
59    fn irq_local_is_enabled() -> bool;
60    fn irq_local_set_enable(enabled: bool);
61    fn systick_irq_id() -> IrqId;
62    fn systick_enable();
63    fn systick_irq_enable();
64    fn systick_irq_disable();
65    fn systick_irq_is_enabled() -> bool;
66    // fn systimer_set_next_event(intval: Duration);
67    fn systick_ack();
68    fn systick_frequency() -> usize;
69    // fn systimer_since_boot() -> Duration;
70    fn systick_ticks() -> usize;
71    /// Set next irq interval in ticks
72    fn systick_set_interval(ticks: usize);
73}
74
75#[trait_ffi::def_extern_trait(mod_path = "hal::al", not_def_impl)]
76pub trait Console {
77    fn early_write(bytes: &[u8]) -> usize;
78    fn early_read() -> Option<u8>;
79}
80
81pub fn handle_irq(irq: IrqId) {
82    crate::os::irq::handle_irq(irq);
83}
84
85pub trait PageTable: Send + 'static {
86    fn addr(&self) -> PhysAddr;
87    fn map(
88        &mut self,
89        virt_start: VirtAddr,
90        phys_start: PhysAddr,
91        size: usize,
92        settings: MemConfig,
93        flush: bool,
94    ) -> Result<(), PagingError>;
95    fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError>;
96
97    fn ioremap(
98        &mut self,
99        phys_start: PhysAddr,
100        size: usize,
101        flush: bool,
102    ) -> Result<IoMemAddr, PagingError> {
103        let virt = __io(phys_start);
104        let end = virt + size;
105        let vaddr = virt.align_down(page_size());
106        let paddr = phys_start.align_down(page_size());
107        let end = end.align_up(page_size());
108        let size = end - vaddr;
109        debug!("ioremap: phys={}, virt={}, size=0x{:x}", paddr, vaddr, size);
110        let settings = MemConfig {
111            access: AccessFlags::READ | AccessFlags::WRITE,
112            attrs: MemAttributes::Device,
113        };
114
115        self.map(
116            vaddr.raw().into(),
117            paddr.raw().into(),
118            size,
119            settings,
120            flush,
121        )?;
122
123        Ok(virt.raw().into())
124    }
125}
126
127define_type! {
128    /// Interrupt Request Identifier
129    IrqId(usize, "{:#x}"),
130    /// Physical Address
131    PhysAddr(usize, "{:#x}"),
132    /// Virtual Address
133    VirtAddr(usize, "{:#x}"),
134    /// I/O Memory Address
135    IoMemAddr(usize, "{:#x}"),
136    ///
137    Asid(usize, "{:#x}"),
138}