feat?: it boots on orange pi 3
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// vi:ft=a64asm.asm:
|
||||
|
||||
.macro ADR_REL reg, sym
|
||||
adrp \reg, \sym
|
||||
add \reg, \reg, #:lo12:\sym
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 });
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user