hal_riscv/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#![no_std]

pub mod hw;
pub mod paging;

pub mod platform_d1;
pub mod platform_virt;

cfg_if::cfg_if! {
    if #[cfg(feature = "platform_rv64_virt")] {
        pub use platform_virt as platform;
    } else if #[cfg(feature = "platform_mq_pro")] {
        pub use platform_d1 as platform;
    } else {
        pub mod platform {
            /*
             * If a platform feature hasn't been selected, we define what's effectively a fake platform
             * module. This documents the desired API a platform should provide, but also provides
             * information to tools such as `rust-analyzer` such as to allow completions without
             * faffing about with fake platform features.
             */
            pub mod memory {
                use hal::memory::PAddr;

                pub const DRAM_START: PAddr = PAddr::new(0x0).unwrap();
                pub const SEED_START: PAddr = PAddr::new(0x0).unwrap();
                pub const RAMDISK_ADDR: PAddr = PAddr::new(0x0).unwrap();
            }

            pub const VIRTUAL_ADDRESS_BITS: usize = 39;
            pub type PageTableImpl = crate::paging::PageTableImpl<crate::paging::Level3>;

            pub mod kernel_map {
                use hal::memory::{PAddr, VAddr, Bytes};

                /// Platforms using `Level4` paging schemes define this to set which P4 entry is
                /// duplicated across all page tables as the kernel's entry.
                pub const KERNEL_P4_ENTRY: usize = 0;

                pub const KERNEL_ADDRESS_SPACE_START: VAddr = VAddr::new(0xffff_ff80_0000_0000);
                pub const PHYSICAL_MAP_BASE: VAddr = KERNEL_ADDRESS_SPACE_START;

                /// Access a given physical address through the physical mapping. This cannot be used until the kernel page tables
                /// have been switched to.
                ///
                /// # Safety
                /// This itself is safe, because to cause memory unsafety a raw pointer must be created and accessed from the
                /// `VAddr`, which is unsafe.
                pub fn physical_to_virtual(address: PAddr) -> VAddr {
                    PHYSICAL_MAP_BASE + usize::from(address)
                }

                pub const KERNEL_STACKS_BASE: VAddr = VAddr::new(0x0);
                /*
                 * There is an imposed maximum number of tasks because of the simple way we're allocating task kernel stacks.
                 * This is currently 65536 with a task kernel stack size of 2MiB.
                 */
                pub const STACK_SLOT_SIZE: Bytes = 0;
                pub const MAX_TASKS: usize = 0;

                /// The kernel starts at -2GiB. The kernel image is loaded directly at this address, and the following space until
                /// the top of memory is managed dynamically and contains the boot info structures, memory map, and kernel heap.
                pub const KERNEL_BASE: VAddr = VAddr::new(0xffff_ffff_8000_0000);
            }

            /// Get the ID of the PLIC context corresponding to the S-mode interrupt target for the
            /// given HART ID. The mapping between these IDs is platform-specific, but might have a
            /// better conversion mechanism in the future.
            pub fn hart_to_plic_context_id(_hart_id: usize) -> usize {
                0
            }
        }
    }
}