feat?: it boots on orange pi 3
This commit is contained in:
parent
683861b401
commit
e21d7fdd59
11
Makefile
11
Makefile
@ -6,6 +6,7 @@ GDB?=gdb-multiarch
|
|||||||
|
|
||||||
LLVM_BASE=$(shell llvm-config --bindir)
|
LLVM_BASE=$(shell llvm-config --bindir)
|
||||||
OBJCOPY=$(LLVM_BASE)/llvm-objcopy
|
OBJCOPY=$(LLVM_BASE)/llvm-objcopy
|
||||||
|
MKIMAGE?=mkimage
|
||||||
|
|
||||||
PROFILE?=debug
|
PROFILE?=debug
|
||||||
O=target/$(ARCH)-$(MACH)/$(PROFILE)
|
O=target/$(ARCH)-$(MACH)/$(PROFILE)
|
||||||
@ -30,6 +31,12 @@ QEMU_OPTS+=-kernel $(O)/kernel.bin \
|
|||||||
-m 512 \
|
-m 512 \
|
||||||
-serial chardev:serial0
|
-serial chardev:serial0
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(MACH),rpi3b)
|
||||||
|
QEMU_OPTS+=-kernel $(O)/kernel.bin \
|
||||||
|
-M raspi3b \
|
||||||
|
-serial null \
|
||||||
|
-serial chardev:serial0
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: address error etc kernel src
|
.PHONY: address error etc kernel src
|
||||||
@ -41,6 +48,10 @@ kernel:
|
|||||||
ifeq ($(ARCH),aarch64)
|
ifeq ($(ARCH),aarch64)
|
||||||
$(OBJCOPY) -O binary $(O)/kernel $(O)/kernel.bin
|
$(OBJCOPY) -O binary $(O)/kernel $(O)/kernel.bin
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(MACH),orangepi3)
|
||||||
|
$(LLVM_BASE)/llvm-strip $(O)/kernel
|
||||||
|
$(LLVM_BASE)/llvm-size $(O)/kernel
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cargo clean
|
cargo clean
|
||||||
|
17
etc/aarch64-orangepi3.json
Normal file
17
etc/aarch64-orangepi3.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": "static",
|
||||||
|
"target-pointer-width": "64",
|
||||||
|
"pre-link-args": {
|
||||||
|
"ld.lld": [ "-Tetc/aarch64-orangepi3.ld" ]
|
||||||
|
}
|
||||||
|
}
|
35
etc/aarch64-orangepi3.ld
Normal file
35
etc/aarch64-orangepi3.ld
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
ENTRY(_entry);
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
ram : ORIGIN = 0x48000000, LENGTH = 992M
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
PROVIDE(__kernel_start = .);
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.text._entry)
|
||||||
|
*(.text*)
|
||||||
|
} >ram
|
||||||
|
|
||||||
|
. = ALIGN(4K);
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata*)
|
||||||
|
} >ram
|
||||||
|
|
||||||
|
. = ALIGN(4K);
|
||||||
|
.data : {
|
||||||
|
*(.data*)
|
||||||
|
} >ram
|
||||||
|
|
||||||
|
. = ALIGN(4K);
|
||||||
|
.bss : {
|
||||||
|
PROVIDE(__bss_start = .);
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss*)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
PROVIDE(__bss_end = .);
|
||||||
|
} >ram
|
||||||
|
|
||||||
|
PROVIDE(__kernel_end = .);
|
||||||
|
}
|
@ -20,4 +20,4 @@ cortex-a = { version = "6.x.x" }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
mach_qemu = []
|
mach_qemu = []
|
||||||
default = ["mach_qemu"]
|
mach_orangepi3 = []
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// vi:ft=a64asm.asm:
|
||||||
|
|
||||||
.macro ADR_REL reg, sym
|
.macro ADR_REL reg, sym
|
||||||
adrp \reg, \sym
|
adrp \reg, \sym
|
||||||
add \reg, \reg, #:lo12:\sym
|
add \reg, \reg, #:lo12:\sym
|
||||||
|
@ -1,37 +1,71 @@
|
|||||||
//! aarch64 common boot logic
|
//! aarch64 common boot logic
|
||||||
use crate::arch::aarch64::asm::CPACR_EL1;
|
|
||||||
use cortex_a::registers::VBAR_EL1;
|
use crate::arch::aarch64::asm::{CPACR_EL1};
|
||||||
use tock_registers::interfaces::Writeable;
|
use cortex_a::registers::{VBAR_EL1, SCTLR_EL1};
|
||||||
|
use tock_registers::interfaces::{Writeable, ReadWriteable};
|
||||||
|
|
||||||
|
use cortex_a::asm::barrier::{self, dsb, isb};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn __aa64_bsp_main() {
|
fn __aa64_bsp_main() {
|
||||||
// Disable FP instruction trapping
|
// Disable FP instruction trapping
|
||||||
CPACR_EL1.write(CPACR_EL1::FPEN::TrapNone);
|
CPACR_EL1.modify(CPACR_EL1::FPEN::TrapNone);
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static aa64_el1_vectors: u8;
|
static aa64_el1_vectors: u8;
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
VBAR_EL1.set(&aa64_el1_vectors as *const _ as u64);
|
VBAR_EL1.set(&aa64_el1_vectors as *const _ as u64);
|
||||||
|
|
||||||
|
// Setup caching in SCTLR_EL1
|
||||||
|
dsb(barrier::SY);
|
||||||
|
isb(barrier::SY);
|
||||||
|
|
||||||
|
SCTLR_EL1.modify(SCTLR_EL1::I::SET +
|
||||||
|
SCTLR_EL1::SA::SET +
|
||||||
|
SCTLR_EL1::C::SET +
|
||||||
|
SCTLR_EL1::A::SET);
|
||||||
|
|
||||||
|
dsb(barrier::SY);
|
||||||
|
isb(barrier::SY);
|
||||||
}
|
}
|
||||||
|
|
||||||
debugln!("Test");
|
debugln!("Test");
|
||||||
|
|
||||||
use crate::arch::machine;
|
let mut el: u64;
|
||||||
use crate::dev::{serial::SerialDevice, timer::TimestampSource, Device};
|
let mut sctlr_el1: u64;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
machine::console().lock().enable().unwrap();
|
asm!("mrs {}, currentel", out(reg) el);
|
||||||
machine::local_timer().lock().enable().unwrap();
|
asm!("mrs {}, sctlr_el1", out(reg) sctlr_el1);
|
||||||
}
|
}
|
||||||
|
el >>= 2;
|
||||||
|
el &= 0x3;
|
||||||
|
|
||||||
let base = machine::local_timer().lock().timestamp().unwrap();
|
debugln!("Current EL = {}", el);
|
||||||
|
debugln!("SCTLR_EL1 = {:#x}", sctlr_el1);
|
||||||
|
|
||||||
|
//use crate::arch::machine;
|
||||||
|
//use crate::dev::{serial::SerialDevice, timer::TimestampSource, Device};
|
||||||
|
|
||||||
|
//unsafe {
|
||||||
|
//machine::console().lock().enable().unwrap();
|
||||||
|
//machine::local_timer().lock().enable().unwrap();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//let base = machine::local_timer().lock().timestamp().unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let count = machine::local_timer().lock().timestamp().unwrap();
|
cortex_a::asm::wfe();
|
||||||
let ch = machine::console().lock().recv(true).unwrap();
|
//let count = machine::local_timer().lock().timestamp().unwrap();
|
||||||
debugln!("[{:?}] {:#04x} = '{}'!", count - base, ch, ch as char);
|
//let ch = machine::console().lock().recv(true).unwrap();
|
||||||
|
//debugln!("[{:?}] {:#04x} = '{}'!", count - base, ch, ch as char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global_asm!(include_str!("entry.S"));
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "mach_orangepi3")] {
|
||||||
|
global_asm!(include_str!("uboot.S"));
|
||||||
|
} else {
|
||||||
|
global_asm!(include_str!("entry.S"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
46
kernel/src/arch/aarch64/boot/uboot.S
Normal file
46
kernel/src/arch/aarch64/boot/uboot.S
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// vi:ft=a64asm.asm:
|
||||||
|
|
||||||
|
.set UART0_BASE, 0x05000000
|
||||||
|
|
||||||
|
.set SPSR_EL2_EL1h, 0x5
|
||||||
|
.set HCR_EL2_RW, 1 << 31
|
||||||
|
.set HCR_EL2_HCD, 1 << 29
|
||||||
|
|
||||||
|
.macro ADR_REL reg, sym
|
||||||
|
adrp \reg, \sym
|
||||||
|
add \reg, \reg, #:lo12:\sym
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.section .text._entry
|
||||||
|
.global _entry
|
||||||
|
_entry:
|
||||||
|
// Test for EL2
|
||||||
|
mrs x0, CurrentEL
|
||||||
|
lsr x0, x0, #2
|
||||||
|
cmp x0, #2
|
||||||
|
bne 1f
|
||||||
|
// Exit EL2
|
||||||
|
// TODO cnthtctl_el2 setup
|
||||||
|
|
||||||
|
ADR_REL x0, 1f
|
||||||
|
msr elr_el2, x0
|
||||||
|
mov x0, #SPSR_EL2_EL1h
|
||||||
|
msr spsr_el2, x0
|
||||||
|
mov x0, #(HCR_EL2_RW | HCR_EL2_HCD)
|
||||||
|
msr hcr_el2, x0
|
||||||
|
|
||||||
|
eret
|
||||||
|
1:
|
||||||
|
dsb sy
|
||||||
|
isb
|
||||||
|
|
||||||
|
ADR_REL x0, bsp_stack_top
|
||||||
|
mov sp, x0
|
||||||
|
|
||||||
|
b __aa64_bsp_main
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
.p2align 12
|
||||||
|
bsp_stack_bottom:
|
||||||
|
.skip 32768
|
||||||
|
bsp_stack_top:
|
62
kernel/src/arch/aarch64/mach_orangepi3/mod.rs
Normal file
62
kernel/src/arch/aarch64/mach_orangepi3/mod.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//! QEMU virt machine
|
||||||
|
|
||||||
|
use crate::arch::aarch64::timer::GenericTimer;
|
||||||
|
use crate::dev::{Device, serial::SerialDevice};
|
||||||
|
use crate::dev::timer::TimestampSource;
|
||||||
|
use crate::sync::Spin;
|
||||||
|
use error::Errno;
|
||||||
|
|
||||||
|
fn delay(mut p: usize) {
|
||||||
|
while p != 0 {
|
||||||
|
cortex_a::asm::nop();
|
||||||
|
p -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Uart {
|
||||||
|
base: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Device for Uart {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"Allwinner H6 UART"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn enable(&mut self) -> Result<(), Errno> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SerialDevice for Uart {
|
||||||
|
fn send(&mut self, byte: u8) -> Result<(), Errno> {
|
||||||
|
unsafe {
|
||||||
|
if byte == b'\n' {
|
||||||
|
core::ptr::write_volatile(self.base as *mut u32, 13u32);
|
||||||
|
delay(10000);
|
||||||
|
}
|
||||||
|
core::ptr::write_volatile(self.base as *mut u32, byte as u32);
|
||||||
|
delay(10000);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv(&mut self, blocking: bool) -> Result<u8, Errno> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const UART0_BASE: usize = 0x05000000;
|
||||||
|
|
||||||
|
/// Returns primary console for this machine
|
||||||
|
#[inline]
|
||||||
|
pub fn console() -> &'static Spin<impl SerialDevice> {
|
||||||
|
&UART0
|
||||||
|
}
|
||||||
|
|
||||||
|
///// Returns the timer used as CPU-local periodic IRQ source
|
||||||
|
//#[inline]
|
||||||
|
//pub fn local_timer() -> &'static Spin<impl TimestampSource> {
|
||||||
|
// &LOCAL_TIMER
|
||||||
|
//}
|
||||||
|
|
||||||
|
static UART0: Spin<Uart> = Spin::new(Uart { base: UART0_BASE });
|
@ -10,5 +10,9 @@ cfg_if! {
|
|||||||
pub mod mach_qemu;
|
pub mod mach_qemu;
|
||||||
|
|
||||||
pub use mach_qemu as machine;
|
pub use mach_qemu as machine;
|
||||||
|
} else if #[cfg(feature = "mach_orangepi3")] {
|
||||||
|
pub mod mach_orangepi3;
|
||||||
|
|
||||||
|
pub use mach_orangepi3 as machine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user