rust-kernel
Rustbelt: a hobby x86_64 kernel written in Rust
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | //! The Raspberry Pi 3 (BCM2837, four Cortex-A53 cores): a **skeleton**.
//! Nothing here is used or tested yet; it writes down where things are so
//! the next stages have a place to start (see "Raspberry Pi roadmap" in
//! the README). QEMU can emulate it too: `qemu-system-aarch64 -M raspi3b`.
//!
//! How it differs from QEMU's virt:
//!
//! ```text
//! 0x0000_0000 RAM (1 GiB minus what the GPU keeps; the firmware loads
//! kernel8.img at 0x8_0000 and passes the DTB in x0)
//! 0x3f00_0000 peripherals ("0x7e..." in Broadcom's manual = 0x3f... here)
//! 0x3f00_b200 the BCM2835 interrupt controller (not a GIC!)
//! 0x3f00_b880 the mailbox (ask the GPU for a framebuffer)
//! 0x3f20_1000 PL011 UART0 (same driver as virt)
//! 0x3f21_5040 the mini-UART (UART1, a different, simpler chip)
//! 0x3f30_0000 EMMC SD card controller (0x3f20_2000: SDHOST, the other one)
//! 0x3f98_0000 USB (DWC2); networking is a LAN9514 on that USB bus
//! 0x4000_0000 the "ARM local" block: per-core timer interrupts, mailboxes
//! ```
//!
//! So RAM and devices share the first GiB: the 1 GiB blocks paging.rs
//! uses for virt aren't fine enough, and the Pi needs 2 MiB blocks (TODO).
use Pl011;
use ;
use crateFdt;
use String;
use Vec;
pub const PERIPHERAL_BASE: usize = 0x3f00_0000;
pub const UART0_BASE: usize = PERIPHERAL_BASE + 0x20_1000;
pub const MINI_UART_BASE: usize = PERIPHERAL_BASE + 0x21_5040;
pub const IRQ_BASE: usize = PERIPHERAL_BASE + 0xb200;
pub const MAILBOX_BASE: usize = PERIPHERAL_BASE + 0xb880;
pub const EMMC_BASE: usize = PERIPHERAL_BASE + 0x30_0000;
pub const SDHOST_BASE: usize = PERIPHERAL_BASE + 0x20_2000;
pub const USB_BASE: usize = PERIPHERAL_BASE + 0x98_0000;
pub const LOCAL_BASE: usize = 0x4000_0000;
/// ARM local block: core 0's timer interrupt control (CNTVIRQ is bit 3).
pub const LOCAL_TIMER_INT_CTRL0: usize = LOCAL_BASE + 0x40;
/// ARM local block: core 0's interrupt source register.
pub const LOCAL_IRQ_SOURCE0: usize = LOCAL_BASE + 0x60;
/// The BCM2835 interrupt controller plus the ARM local block. TODO: the
/// timer goes through the local block (set bit 3 of LOCAL_TIMER_INT_CTRL0,
/// read LOCAL_IRQ_SOURCE0); devices through the BCM2835 pending registers.
;
/// Not selected by `board::current()` yet.
pub static RASPI3: Raspi3 = Raspi3 ;
/// TODO(Pi 3): needs 2 MiB granularity (RAM up to 0x3f00_0000, devices after).
static MAP: = ;
|