feat: add mach_rpi3 target
This commit is contained in:
parent
b440a3c975
commit
6bd252f18e
18
Makefile
18
Makefile
@ -20,23 +20,25 @@ CARGO_BUILD_OPTS+=--release
|
||||
endif
|
||||
|
||||
QEMU_OPTS=-s \
|
||||
-chardev stdio,id=serial0,mux=on
|
||||
-chardev stdio,id=serial1,mux=on
|
||||
ifeq ($(ARCH),x86_64)
|
||||
$(error TODO)
|
||||
else
|
||||
ifeq ($(MACH),qemu)
|
||||
QEMU_OPTS+=-kernel $(O)/kernel \
|
||||
QEMU_OPTS+=-kernel $(O)/kernel.bin \
|
||||
-M virt,virtualization=on \
|
||||
-cpu cortex-a72 \
|
||||
-m 512 \
|
||||
-serial chardev:serial0 \
|
||||
-device virtio-serial-pci
|
||||
-serial chardev:serial1 \
|
||||
-device qemu-xhci \
|
||||
-net none
|
||||
endif
|
||||
ifeq ($(MACH),rpi3b)
|
||||
ifeq ($(MACH),rpi3)
|
||||
QEMU_OPTS+=-kernel $(O)/kernel.bin \
|
||||
-dtb etc/bcm2837-rpi-3-b-plus.dtb \
|
||||
-M raspi3b \
|
||||
-serial null \
|
||||
-serial chardev:serial0
|
||||
-serial chardev:serial1
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -53,10 +55,12 @@ all: kernel
|
||||
|
||||
kernel:
|
||||
cd kernel && cargo build $(CARGO_BUILD_OPTS)
|
||||
ifeq ($(MACH),orangepi3)
|
||||
ifeq ($(ARCH),aarch64)
|
||||
$(LLVM_BASE)/llvm-strip -o $(O)/kernel.strip $(O)/kernel
|
||||
$(LLVM_BASE)/llvm-size $(O)/kernel.strip
|
||||
$(OBJCOPY) -O binary $(O)/kernel.strip $(O)/kernel.bin
|
||||
endif
|
||||
ifeq ($(MACH),orangepi3)
|
||||
$(MKIMAGE) \
|
||||
-A arm64 \
|
||||
-O linux \
|
||||
|
17
etc/aarch64-rpi3.json
Normal file
17
etc/aarch64-rpi3.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"arch": "aarch64",
|
||||
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
|
||||
"disable-redzone": true,
|
||||
"executables": true,
|
||||
"features": "+strict-align,+neon,+fp-armv8",
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "ld.lld",
|
||||
"llvm-target": "aarch64-unknown-none",
|
||||
"max-atomic-width": 128,
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "pic",
|
||||
"target-pointer-width": "64",
|
||||
"pre-link-args": {
|
||||
"ld.lld": [ "-Tetc/aarch64-rpi3.ld" ]
|
||||
}
|
||||
}
|
45
etc/aarch64-rpi3.ld
Normal file
45
etc/aarch64-rpi3.ld
Normal file
@ -0,0 +1,45 @@
|
||||
ENTRY(_entry);
|
||||
|
||||
KERNEL_OFFSET = 0xFFFFFF8000000000;
|
||||
BASE_OFFSET = 0x80000;
|
||||
|
||||
SECTIONS {
|
||||
. = BASE_OFFSET;
|
||||
|
||||
.text.lower : {
|
||||
*(.text._entry)
|
||||
}
|
||||
|
||||
. = ALIGN(16);
|
||||
. = . + KERNEL_OFFSET;
|
||||
|
||||
PROVIDE(__kernel_start = .);
|
||||
|
||||
.text : AT(. - KERNEL_OFFSET) {
|
||||
*(.text._entry_upper)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
.rodata : AT(. - KERNEL_OFFSET) {
|
||||
*(.rodata*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
.data : AT(. - KERNEL_OFFSET) {
|
||||
*(.data*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
PROVIDE(__bss_start_phys = . - KERNEL_OFFSET);
|
||||
PROVIDE(__bss_start = .);
|
||||
.bss : AT(. - KERNEL_OFFSET) {
|
||||
*(COMMON)
|
||||
*(.bss*)
|
||||
. = ALIGN(4K);
|
||||
}
|
||||
PROVIDE(__bss_end_phys = . - KERNEL_OFFSET);
|
||||
|
||||
PROVIDE(__kernel_end = .);
|
||||
PROVIDE(__kernel_end_phys = . - KERNEL_OFFSET);
|
||||
}
|
BIN
etc/bcm2837-rpi-3-b-plus.dtb
Normal file
BIN
etc/bcm2837-rpi-3-b-plus.dtb
Normal file
Binary file not shown.
@ -21,3 +21,4 @@ cortex-a = { version = "6.x.x" }
|
||||
[features]
|
||||
mach_qemu = []
|
||||
mach_orangepi3 = []
|
||||
mach_rpi3 = []
|
||||
|
40
kernel/src/arch/aarch64/mach_rpi3/irqchip.rs
Normal file
40
kernel/src/arch/aarch64/mach_rpi3/irqchip.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use crate::dev::{Device, irq::{IntController, IntSource, IrqContext}};
|
||||
use error::Errno;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct IrqNumber(u32);
|
||||
|
||||
pub(super) struct Bcm283xIntController {}
|
||||
|
||||
impl Device for Bcm283xIntController {
|
||||
fn name(&self) -> &'static str {
|
||||
"BCM283x interrupt controller"
|
||||
}
|
||||
|
||||
unsafe fn enable(&self) -> Result<(), Errno> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntController for Bcm283xIntController {
|
||||
type IrqNumber = IrqNumber;
|
||||
|
||||
fn register_handler(&self, irq: IrqNumber, handler: &'static (dyn IntSource + Sync)) -> Result<(), Errno> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn enable_irq(&self, irq: IrqNumber) -> Result<(), Errno> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn handle_pending_irqs<'q>(&'q self, _ic: &IrqContext<'q>) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Bcm283xIntController {
|
||||
pub const unsafe fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
46
kernel/src/arch/aarch64/mach_rpi3/mod.rs
Normal file
46
kernel/src/arch/aarch64/mach_rpi3/mod.rs
Normal file
@ -0,0 +1,46 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::arch::aarch64::timer::GenericTimer;
|
||||
use crate::dev::{irq::IntController, serial::SerialDevice, timer::TimestampSource, Device};
|
||||
use crate::mem::phys;
|
||||
use error::Errno;
|
||||
|
||||
mod irqchip;
|
||||
use irqchip::Bcm283xIntController;
|
||||
pub use irqchip::IrqNumber;
|
||||
mod uart;
|
||||
use uart::Bcm283xMiniUart;
|
||||
|
||||
pub fn init_board_early() -> Result<(), Errno> {
|
||||
unsafe {
|
||||
MUART.enable()?;
|
||||
|
||||
phys::init_from_region(0x0, 0x30000000);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init_board() -> Result<(), Errno> {
|
||||
unsafe {
|
||||
INTC.enable()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn console() -> &'static impl SerialDevice {
|
||||
&MUART
|
||||
}
|
||||
|
||||
/// Returns the timer used as CPU-local periodic IRQ source
|
||||
#[inline]
|
||||
pub fn local_timer() -> &'static impl TimestampSource {
|
||||
&LOCAL_TIMER
|
||||
}
|
||||
|
||||
pub fn intc() -> &'static impl IntController<IrqNumber = IrqNumber> {
|
||||
&INTC
|
||||
}
|
||||
|
||||
static INTC: Bcm283xIntController = unsafe { Bcm283xIntController::new() };
|
||||
static MUART: Bcm283xMiniUart = unsafe { Bcm283xMiniUart::new(0x3F215040) };
|
||||
static LOCAL_TIMER: GenericTimer = GenericTimer {};
|
67
kernel/src/arch/aarch64/mach_rpi3/uart.rs
Normal file
67
kernel/src/arch/aarch64/mach_rpi3/uart.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use crate::dev::{serial::SerialDevice, Device};
|
||||
use crate::mem::virt::DeviceMemoryIo;
|
||||
use crate::sync::IrqSafeNullLock;
|
||||
use crate::util::InitOnce;
|
||||
use error::Errno;
|
||||
use tock_registers::{
|
||||
interfaces::{ReadWriteable, Readable, Writeable},
|
||||
register_bitfields, register_structs,
|
||||
registers::{ReadOnly, ReadWrite, WriteOnly},
|
||||
};
|
||||
|
||||
register_structs! {
|
||||
Regs {
|
||||
(0x00 => IO: ReadWrite<u32>),
|
||||
(0x04 => @END),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Bcm283xMiniUart {
|
||||
regs: InitOnce<IrqSafeNullLock<DeviceMemoryIo<Regs>>>,
|
||||
base: usize,
|
||||
}
|
||||
|
||||
impl Device for Bcm283xMiniUart {
|
||||
fn name(&self) -> &'static str {
|
||||
"BCM283x Mini-UART"
|
||||
}
|
||||
|
||||
unsafe fn enable(&self) -> Result<(), Errno> {
|
||||
self.regs.init(IrqSafeNullLock::new(DeviceMemoryIo::map(
|
||||
self.name(),
|
||||
self.base,
|
||||
1,
|
||||
)?));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SerialDevice for Bcm283xMiniUart {
|
||||
fn send(&self, byte: u8) -> Result<(), Errno> {
|
||||
if !self.regs.is_initialized() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let regs = self.regs.get().lock();
|
||||
regs.IO.set(byte as u32);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn recv(&self, _blocking: bool) -> Result<u8, Errno> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Bcm283xMiniUart {
|
||||
/// Constructs an instance of MiniUART device.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Does not perform `base` validation.
|
||||
pub const unsafe fn new(base: usize) -> Self {
|
||||
Self {
|
||||
regs: InitOnce::new(),
|
||||
base,
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,10 @@ cfg_if! {
|
||||
pub mod mach_orangepi3;
|
||||
|
||||
pub use mach_orangepi3 as machine;
|
||||
} else if #[cfg(feature = "mach_rpi3")] {
|
||||
pub mod mach_rpi3;
|
||||
|
||||
pub use mach_rpi3 as machine;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user