feat?: it boots on orange pi 3

This commit is contained in:
2021-10-01 18:37:47 +03:00
parent 683861b401
commit e21d7fdd59
9 changed files with 226 additions and 15 deletions
+2
View File
@@ -1,3 +1,5 @@
// vi:ft=a64asm.asm:
.macro ADR_REL reg, sym
adrp \reg, \sym
add \reg, \reg, #:lo12:\sym
+48 -14
View File
@@ -1,37 +1,71 @@
//! aarch64 common boot logic
use crate::arch::aarch64::asm::CPACR_EL1;
use cortex_a::registers::VBAR_EL1;
use tock_registers::interfaces::Writeable;
use crate::arch::aarch64::asm::{CPACR_EL1};
use cortex_a::registers::{VBAR_EL1, SCTLR_EL1};
use tock_registers::interfaces::{Writeable, ReadWriteable};
use cortex_a::asm::barrier::{self, dsb, isb};
#[no_mangle]
fn __aa64_bsp_main() {
// Disable FP instruction trapping
CPACR_EL1.write(CPACR_EL1::FPEN::TrapNone);
CPACR_EL1.modify(CPACR_EL1::FPEN::TrapNone);
extern "C" {
static aa64_el1_vectors: u8;
}
unsafe {
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");
use crate::arch::machine;
use crate::dev::{serial::SerialDevice, timer::TimestampSource, Device};
let mut el: u64;
let mut sctlr_el1: u64;
unsafe {
machine::console().lock().enable().unwrap();
machine::local_timer().lock().enable().unwrap();
asm!("mrs {}, currentel", out(reg) el);
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 {
let count = machine::local_timer().lock().timestamp().unwrap();
let ch = machine::console().lock().recv(true).unwrap();
debugln!("[{:?}] {:#04x} = '{}'!", count - base, ch, ch as char);
cortex_a::asm::wfe();
//let count = machine::local_timer().lock().timestamp().unwrap();
//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
View 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:
@@ -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 });
+4
View File
@@ -10,5 +10,9 @@ cfg_if! {
pub mod mach_qemu;
pub use mach_qemu as machine;
} else if #[cfg(feature = "mach_orangepi3")] {
pub mod mach_orangepi3;
pub use mach_orangepi3 as machine;
}
}