sparreal_kernel/hal/
al.rs1use 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 fn kimage_offset() -> isize;
20
21 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 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 systick_ack();
68 fn systick_frequency() -> usize;
69 fn systick_ticks() -> usize;
71 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 IrqId(usize, "{:#x}"),
130 PhysAddr(usize, "{:#x}"),
132 VirtAddr(usize, "{:#x}"),
134 IoMemAddr(usize, "{:#x}"),
136 Asid(usize, "{:#x}"),
138}