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 post_allocator();
38 fn irq_is_enabled(irq: IrqId) -> bool;
39 fn irq_set_enabled(irq: IrqId, enabled: bool);
40
41 fn shutdown() -> !;
42
43 fn fdt_addr() -> Option<NonNull<u8>>;
44 fn post_paging();
45}
46
47#[trait_ffi::def_extern_trait(not_def_impl, mod_path = "hal::al")]
48pub trait Cpu {
49 fn current_cpu_id() -> usize;
50 fn irq_local_is_enabled() -> bool;
51 fn irq_local_set_enable(enabled: bool);
52 fn systick_irq_id() -> IrqId;
53 fn systick_enable();
54 fn systick_irq_enable();
55 fn systick_irq_disable();
56 fn systick_irq_is_enabled() -> bool;
57 fn systick_ack();
59 fn systick_frequency() -> usize;
60 fn systick_ticks() -> usize;
62 fn systick_set_interval(ticks: usize);
64}
65
66#[trait_ffi::def_extern_trait(mod_path = "hal::al", not_def_impl)]
67pub trait Console {
68 fn early_write(bytes: &[u8]) -> usize;
69 fn early_read() -> Option<u8>;
70}
71
72pub fn handle_irq(irq: IrqId) {
73 crate::os::irq::handle_irq(irq);
74}
75
76pub trait PageTable: Send + 'static {
77 fn addr(&self) -> PhysAddr;
78 fn map(
79 &mut self,
80 virt_start: VirtAddr,
81 phys_start: PhysAddr,
82 size: usize,
83 settings: MemConfig,
84 flush: bool,
85 ) -> Result<(), PagingError>;
86 fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError>;
87
88 fn ioremap(
89 &mut self,
90 phys_start: PhysAddr,
91 size: usize,
92 flush: bool,
93 ) -> Result<IoMemAddr, PagingError> {
94 let virt = __io(phys_start);
95 let end = virt + size;
96 let vaddr = virt.align_down(page_size());
97 let paddr = phys_start.align_down(page_size());
98 let end = end.align_up(page_size());
99 let size = end - vaddr;
100 debug!("ioremap: phys={}, virt={}, size=0x{:x}", paddr, vaddr, size);
101 let settings = MemConfig {
102 access: AccessFlags::READ | AccessFlags::WRITE,
103 attrs: MemAttributes::Device,
104 };
105
106 self.map(
107 vaddr.raw().into(),
108 paddr.raw().into(),
109 size,
110 settings,
111 flush,
112 )?;
113
114 Ok(virt.raw().into())
115 }
116}
117
118define_type! {
119 IrqId(usize, "{:#x}"),
121 PhysAddr(usize, "{:#x}"),
123 VirtAddr(usize, "{:#x}"),
125 IoMemAddr(usize, "{:#x}"),
127 Asid(usize, "{:#x}"),
129}