pub const RAM_BASE: usize = 0x80000000; pub const RAM_SIZE: usize = 128 * 1024 * 1024; pub const UART_BASE: usize = 0x10000000; pub const VIRTIO_BASE: usize = 0x10001000; pub const VIRTIO_SIZE: usize = 0x8000; pub const PLIC_BASE: usize = 0x0C000000; pub const CLINT_BASE: usize = 0x02000000; pub const USER_POOL_BASE: usize = 0x84000000; /// 64 MiB, up to the end of RAM (QEMU virt's default 128 MiB). pub const USER_POOL_PAGES: usize = 16384; pub const TICK_INTERVAL: u64 = 10_000_000; /// QEMU virt's PLIC lines. const UART_IRQ: u16 = 10; const VIRTIO_IRQ_BASE: u16 = 1; const VIRTIO_SLOT_SIZE: usize = 0x1000; const VIRTIO_SLOTS: usize = VIRTIO_SIZE / VIRTIO_SLOT_SIZE; pub const BOARD_DEVICES: usize = 1 + VIRTIO_SLOTS; /// What each entry of `devices()` is, for init's BootInfo. pub fn kinds() -> [u64; BOARD_DEVICES] { let mut kinds = [types::bootinfo::KIND_VIRTIO; BOARD_DEVICES]; kinds[0] = types::bootinfo::KIND_UART_16550; kinds } /// Every device userspace may drive: the UART and each VirtIO MMIO slot. /// The PLIC, CLINT and RAM stay the kernel's. pub fn devices() -> Option<[kernel::BoardDevice; BOARD_DEVICES]> { use types::{address::PhysicalAddress, bounded::PageCount, id::IrqId}; let one = PageCount::new(1)?; let device = |base: usize, irq: u16| kernel::BoardDevice { base: PhysicalAddress::from_raw(base), pages: one, irq: Some(IrqId::from_raw(irq)), }; let mut all = [device(UART_BASE, UART_IRQ); BOARD_DEVICES]; for (i, d) in all.iter_mut().skip(1).enumerate() { *d = device( VIRTIO_BASE + i * VIRTIO_SLOT_SIZE, VIRTIO_IRQ_BASE + i as u16, ); } Some(all) }