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
17 fn kimage_offset() -> isize;
19
20 fn virt_to_phys(virt: VirtAddr) -> PhysAddr;
22
23 fn page_size() -> usize;
24 fn memory_map() -> &'static [MemoryDescriptor];
25
26 fn page_table_new() -> Result<Box<dyn PageTable>, PagingError>;
27
28 fn kernel_page_table() -> PhysAddr;
29 fn set_kernel_page_table(pt: PhysAddr);
30 fn user_page_table() -> PageTableInfo;
31 fn set_user_page_table(pt: PageTableInfo);
32}
33
34#[trait_ffi::def_extern_trait(not_def_impl, mod_path = "hal::al")]
35pub trait Platform {
36 fn post_allocator();
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 current_cpu_id() -> usize;
49 fn irq_local_is_enabled() -> bool;
50 fn irq_local_set_enable(enabled: bool);
51 fn systick_irq_id() -> IrqId;
52 fn systick_enable();
53 fn systick_irq_enable();
54 fn systick_irq_disable();
55 fn systick_irq_is_enabled() -> bool;
56 fn systick_ack();
58 fn systick_frequency() -> usize;
59 fn systick_ticks() -> usize;
61 fn systick_set_interval(ticks: usize);
63}
64
65#[trait_ffi::def_extern_trait(mod_path = "hal::al", not_def_impl)]
66pub trait Console {
67 fn early_write(bytes: &[u8]) -> usize;
68 fn early_read() -> Option<u8>;
69}
70
71pub fn handle_irq(irq: IrqId) {
72 crate::os::irq::handle_irq(irq);
73}
74
75pub trait PageTable: Send + 'static {
76 fn addr(&self) -> PhysAddr;
77 fn map(
78 &mut self,
79 virt_start: VirtAddr,
80 phys_start: PhysAddr,
81 size: usize,
82 settings: MemConfig,
83 flush: bool,
84 ) -> Result<(), PagingError>;
85 fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError>;
86
87 fn ioremap(
88 &mut self,
89 phys_start: PhysAddr,
90 size: usize,
91 flush: bool,
92 ) -> Result<IoMemAddr, PagingError> {
93 let virt = __io(phys_start);
94 let end = virt + size;
95 let vaddr = virt.align_down(page_size());
96 let paddr = phys_start.align_down(page_size());
97 let end = end.align_up(page_size());
98 let size = end - vaddr;
99 debug!("ioremap: phys={}, virt={}, size=0x{:x}", paddr, vaddr, size);
100 let settings = MemConfig {
101 access: AccessFlags::READ | AccessFlags::WRITE,
102 attrs: MemAttributes::Device,
103 };
104
105 self.map(
106 vaddr.raw().into(),
107 paddr.raw().into(),
108 size,
109 settings,
110 flush,
111 )?;
112
113 Ok(virt.raw().into())
114 }
115}
116
117define_type! {
118 IrqId(usize, "{:#x}"),
120 PhysAddr(usize, "{:#x}"),
122 VirtAddr(usize, "{:#x}"),
124 IoMemAddr(usize, "{:#x}"),
126 Asid(usize, "{:#x}"),
128}