feat: orangepi3 higher-half poc
Reset is broken
This commit is contained in:
parent
a8b7e88cfe
commit
189229ca7a
2
Makefile
2
Makefile
@ -57,7 +57,7 @@ ifeq ($(ARCH),aarch64)
|
||||
$(OBJCOPY) -O binary $(O)/kernel $(O)/kernel.bin
|
||||
endif
|
||||
ifeq ($(MACH),orangepi3)
|
||||
$(LLVM_BASE)/llvm-strip $(O)/kernel
|
||||
# $(LLVM_BASE)/llvm-strip $(O)/kernel
|
||||
$(LLVM_BASE)/llvm-size $(O)/kernel
|
||||
endif
|
||||
|
||||
|
@ -1,35 +1,44 @@
|
||||
ENTRY(_entry);
|
||||
|
||||
MEMORY {
|
||||
ram : ORIGIN = 0x48000000, LENGTH = 992M
|
||||
}
|
||||
KERNEL_OFFSET = 0xFFFFFF8000000000;
|
||||
BASE_OFFSET = 0x42000000;
|
||||
|
||||
SECTIONS {
|
||||
. = BASE_OFFSET;
|
||||
|
||||
.text.lower : {
|
||||
*(.text._entry)
|
||||
}
|
||||
|
||||
. = ALIGN(16);
|
||||
. = . + KERNEL_OFFSET;
|
||||
|
||||
PROVIDE(__kernel_start = .);
|
||||
|
||||
.text : {
|
||||
*(.text._entry)
|
||||
.text : AT(. - KERNEL_OFFSET) {
|
||||
*(.text._entry_upper)
|
||||
*(.text*)
|
||||
} >ram
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
.rodata : {
|
||||
.rodata : AT(. - KERNEL_OFFSET) {
|
||||
*(.rodata*)
|
||||
} >ram
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
.data : {
|
||||
.data : AT(. - KERNEL_OFFSET) {
|
||||
*(.data*)
|
||||
} >ram
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
.bss : {
|
||||
PROVIDE(__bss_start = .);
|
||||
PROVIDE(__bss_start_phys = . - KERNEL_OFFSET);
|
||||
PROVIDE(__bss_start = .);
|
||||
.bss : AT(. - KERNEL_OFFSET) {
|
||||
*(COMMON)
|
||||
*(.bss*)
|
||||
. = ALIGN(4K);
|
||||
PROVIDE(__bss_end = .);
|
||||
} >ram
|
||||
}
|
||||
PROVIDE(__bss_end_phys = . - KERNEL_OFFSET);
|
||||
|
||||
PROVIDE(__kernel_end = .);
|
||||
}
|
||||
|
@ -1,17 +1,4 @@
|
||||
// vi:ft=a64asm.asm:
|
||||
|
||||
.macro ADR_REL reg, sym
|
||||
adrp \reg, \sym
|
||||
add \reg, \reg, #:lo12:\sym
|
||||
.endm
|
||||
|
||||
.macro ADR_ABS reg, sym
|
||||
movz \reg, #:abs_g3:\sym
|
||||
movk \reg, #:abs_g2_nc:\sym
|
||||
movk \reg, #:abs_g1_nc:\sym
|
||||
movk \reg, #:abs_g0_nc:\sym
|
||||
.endm
|
||||
|
||||
.section .text._entry
|
||||
.global _entry
|
||||
_entry:
|
||||
|
16
kernel/src/arch/aarch64/boot/macros.S
Normal file
16
kernel/src/arch/aarch64/boot/macros.S
Normal file
@ -0,0 +1,16 @@
|
||||
.macro MOV_L reg, value
|
||||
mov \reg, #((\value) & 0xFFFF)
|
||||
movk \reg, #((\value) >> 16), lsl #16
|
||||
.endm
|
||||
|
||||
.macro ADR_REL reg, sym
|
||||
adrp \reg, \sym
|
||||
add \reg, \reg, #:lo12:\sym
|
||||
.endm
|
||||
|
||||
.macro ADR_ABS reg, sym
|
||||
movz \reg, #:abs_g3:\sym
|
||||
movk \reg, #:abs_g2_nc:\sym
|
||||
movk \reg, #:abs_g1_nc:\sym
|
||||
movk \reg, #:abs_g0_nc:\sym
|
||||
.endm
|
@ -34,8 +34,10 @@ fn __aa64_bsp_main(fdt_base: usize) {
|
||||
|
||||
machine::init_board().unwrap();
|
||||
|
||||
let fdt = DeviceTree::from_phys(fdt_base + 0xFFFFFF8000000000).expect("Failed to obtain a device tree");
|
||||
fdt.dump();
|
||||
// let fdt = DeviceTree::from_phys(fdt_base + 0xFFFFFF8000000000).expect("Failed to obtain a device tree");
|
||||
// fdt.dump();
|
||||
|
||||
debugln!("Machine init finished");
|
||||
|
||||
unsafe {
|
||||
machine::local_timer().enable().unwrap();
|
||||
@ -47,6 +49,8 @@ fn __aa64_bsp_main(fdt_base: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
global_asm!(include_str!("macros.S"));
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "mach_orangepi3")] {
|
||||
global_asm!(include_str!("uboot.S"));
|
||||
|
@ -10,19 +10,11 @@
|
||||
.set CNTHCTL_EL2_EL1PCEN, 1 << 1
|
||||
.set CNTHCTL_EL2_EL1PCTEN, 1 << 0
|
||||
|
||||
.macro ADR_REL reg, sym
|
||||
adrp \reg, \sym
|
||||
add \reg, \reg, #:lo12:\sym
|
||||
.endm
|
||||
|
||||
.macro MOV_L reg, value
|
||||
mov \reg, #((\value) & 0xFFFF)
|
||||
movk \reg, #((\value) >> 16), lsl #16
|
||||
.endm
|
||||
|
||||
.section .text._entry
|
||||
.global _entry
|
||||
_entry:
|
||||
mov x8, x0
|
||||
|
||||
// Test for EL2
|
||||
mrs x0, CurrentEL
|
||||
lsr x0, x0, #2
|
||||
@ -45,7 +37,7 @@ _entry:
|
||||
orr x0, x0, #SPSR_EL2_MASK_DAIF
|
||||
msr spsr_el2, x0
|
||||
|
||||
ADR_REL x0, 1f
|
||||
adr x0, 1f
|
||||
msr elr_el2, x0
|
||||
|
||||
isb
|
||||
@ -54,8 +46,27 @@ _entry:
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
ADR_REL x0, bsp_stack_top
|
||||
mov sp, x0
|
||||
// Zero .bss
|
||||
ADR_ABS x0, __bss_start_phys
|
||||
ADR_ABS x1, __bss_end_phys
|
||||
1:
|
||||
cmp x0, x1
|
||||
beq 2f
|
||||
|
||||
str xzr, [x0], #8
|
||||
|
||||
b 1b
|
||||
2:
|
||||
|
||||
ADR_ABS x9, __aa64_entry_upper
|
||||
b __aa64_enter_upper
|
||||
|
||||
.section .text._entry_upper
|
||||
__aa64_entry_upper:
|
||||
// x0 -- fdt address
|
||||
|
||||
ADR_REL x1, bsp_stack_top
|
||||
mov sp, x1
|
||||
|
||||
mov lr, xzr
|
||||
bl __aa64_bsp_main
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
.set MAIR_EL1_Attr0_Normal_Inner_NC, (4 << 0)
|
||||
.set MAIR_EL1_Attr0_Normal_Outer_NC, (4 << 4)
|
||||
.set MAIR_EL1_Attr1_Device, (0 << 4)
|
||||
.set MAIR_EL1_Attr1_Device_nGnRnE, (0 << 4)
|
||||
.set MAIR_EL1_Attr1_Device, (0 << 12)
|
||||
.set MAIR_EL1_Attr1_Device_nGnRE, (1 << 8)
|
||||
|
||||
.set ID_AA64MMFR0_EL1_TGran4, (0xF << 28)
|
||||
|
||||
@ -27,13 +27,10 @@
|
||||
|
||||
.set TCR_EL1_ATTRS, (TCR_EL1_TG1_4K | TCR_EL1_SH1_Outer | TCR_EL1_TG0_4K | TCR_EL1_SH0_Outer | (25 << TCR_EL1_T1SZ_SHIFT) | (25 << TCR_EL1_T0SZ_SHIFT))
|
||||
|
||||
.set SCTLR_EL1_I, (1 << 12)
|
||||
.set SCTLR_EL1_C, (1 << 2)
|
||||
.set SCTLR_EL1_M, (1 << 0)
|
||||
|
||||
.macro MOV_L reg, value
|
||||
mov \reg, #((\value) & 0xFFFF)
|
||||
movk \reg, #((\value) >> 16), lsl #16
|
||||
.endm
|
||||
|
||||
.section .text._entry
|
||||
.global __aa64_enter_upper
|
||||
.type __aa64_enter_upper, %function
|
||||
@ -65,7 +62,9 @@ __aa64_enter_upper:
|
||||
cbnz x2, 1b
|
||||
|
||||
.init_mmu_regs:
|
||||
mov x0, #(MAIR_EL1_Attr0_Normal_Outer_NC | MAIR_EL1_Attr0_Normal_Inner_NC | MAIR_EL1_Attr1_Device | MAIR_EL1_Attr1_Device_nGnRnE)
|
||||
mov x0, #(MAIR_EL1_Attr0_Normal_Outer_NC | MAIR_EL1_Attr0_Normal_Inner_NC | MAIR_EL1_Attr1_Device | MAIR_EL1_Attr1_Device_nGnRE)
|
||||
msr mair_el1, x0
|
||||
|
||||
// Test for 4KiB page support
|
||||
mrs x0, ID_AA64MMFR0_EL1
|
||||
mov x1, ID_AA64MMFR0_EL1_TGran4
|
||||
@ -79,11 +78,12 @@ __aa64_enter_upper:
|
||||
orr x0, x0, x1
|
||||
msr tcr_el1, x0
|
||||
|
||||
msr mair_el1, x0
|
||||
|
||||
msr ttbr0_el1, x5
|
||||
msr ttbr1_el1, x5
|
||||
|
||||
dsb ish
|
||||
isb
|
||||
|
||||
mrs x0, sctlr_el1
|
||||
orr x0, x0, #SCTLR_EL1_M
|
||||
msr sctlr_el1, x0
|
||||
|
@ -5,12 +5,13 @@
|
||||
//! 1. CPUS-PORT (TODO PL, PM)
|
||||
//! 2. CPUX-PORT (PC, PD, PF, PG, PH)
|
||||
//!
|
||||
use crate::arch::MemoryIo;
|
||||
use crate::dev::{
|
||||
gpio::{GpioDevice, PinConfig, PinMode, PullMode},
|
||||
Device,
|
||||
};
|
||||
use crate::mem::virt::DeviceMemoryIo;
|
||||
use crate::sync::IrqSafeNullLock;
|
||||
use crate::util::InitOnce;
|
||||
use error::Errno;
|
||||
use tock_registers::interfaces::{Readable, Writeable};
|
||||
use tock_registers::register_structs;
|
||||
@ -28,11 +29,12 @@ register_structs! {
|
||||
}
|
||||
|
||||
struct CpuxGpio {
|
||||
regs: MemoryIo<[CpuxPortRegs; 8]>,
|
||||
regs: DeviceMemoryIo<[CpuxPortRegs; 8]>,
|
||||
}
|
||||
|
||||
pub struct Gpio {
|
||||
cpux: IrqSafeNullLock<CpuxGpio>,
|
||||
cpux: InitOnce<IrqSafeNullLock<CpuxGpio>>,
|
||||
cpux_base: usize,
|
||||
}
|
||||
|
||||
/// Structure combining bank and pin numbers
|
||||
@ -142,6 +144,9 @@ impl Device for Gpio {
|
||||
}
|
||||
|
||||
unsafe fn enable(&self) -> Result<(), Errno> {
|
||||
self.cpux.init(IrqSafeNullLock::new(CpuxGpio {
|
||||
regs: DeviceMemoryIo::map(self.name(), self.cpux_base, 1)?,
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -155,7 +160,7 @@ impl GpioDevice for Gpio {
|
||||
|
||||
match bank {
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => self.cpux.lock().set_pin_config(bank, pin, cfg),
|
||||
_ => self.cpux.get().lock().set_pin_config(bank, pin, cfg),
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,7 +174,7 @@ impl GpioDevice for Gpio {
|
||||
|
||||
match bank {
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => self.cpux.lock().write_pin(bank, pin, state),
|
||||
_ => self.cpux.get().lock().write_pin(bank, pin, state),
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +184,7 @@ impl GpioDevice for Gpio {
|
||||
|
||||
match bank {
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => self.cpux.lock().toggle_pin(bank, pin),
|
||||
_ => self.cpux.get().lock().toggle_pin(bank, pin),
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +194,7 @@ impl GpioDevice for Gpio {
|
||||
|
||||
match bank {
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => Ok(self.cpux.lock().read_pin(bank, pin)),
|
||||
_ => Ok(self.cpux.get().lock().read_pin(bank, pin)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,11 +205,10 @@ impl Gpio {
|
||||
self.set_pin_config(PinAddress::new(7, 1), &PinConfig::alt(2))
|
||||
}
|
||||
|
||||
pub const unsafe fn new(base: usize) -> Self {
|
||||
pub const unsafe fn new(cpux_base: usize) -> Self {
|
||||
Self {
|
||||
cpux: IrqSafeNullLock::new(CpuxGpio {
|
||||
regs: MemoryIo::new(base),
|
||||
}),
|
||||
cpux: InitOnce::new(),
|
||||
cpux_base,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,14 +28,17 @@ use wdog::RWdog;
|
||||
#[allow(missing_docs)]
|
||||
pub fn init_board() -> Result<(), Errno> {
|
||||
unsafe {
|
||||
UART0.enable()?;
|
||||
GIC.enable()?;
|
||||
GPIO.enable()?;
|
||||
|
||||
UART0.init_irqs()?;
|
||||
|
||||
R_WDOG.enable()?;
|
||||
|
||||
GPIO.cfg_uart0_ph0_ph1()?;
|
||||
GPIO.set_pin_config(PinAddress::new(3, 26), &PinConfig::out_pull_down())?;
|
||||
|
||||
UART0.enable()?;
|
||||
UART0.init_irqs()?;
|
||||
|
||||
RTC.enable()?;
|
||||
RTC.init_irqs()?;
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
use crate::arch::{
|
||||
machine::{self, IrqNumber},
|
||||
MemoryIo,
|
||||
};
|
||||
use crate::arch::machine::{self, IrqNumber};
|
||||
use crate::dev::{
|
||||
irq::{IntController, IntSource},
|
||||
rtc::RtcDevice,
|
||||
Device,
|
||||
};
|
||||
use crate::mem::virt::DeviceMemoryIo;
|
||||
use crate::sync::IrqSafeNullLock;
|
||||
use crate::util::InitOnce;
|
||||
use error::Errno;
|
||||
use tock_registers::{
|
||||
interfaces::{Readable, Writeable},
|
||||
@ -48,7 +47,8 @@ register_structs! {
|
||||
}
|
||||
|
||||
pub struct Rtc {
|
||||
regs: IrqSafeNullLock<MemoryIo<Regs>>,
|
||||
regs: InitOnce<IrqSafeNullLock<DeviceMemoryIo<Regs>>>,
|
||||
base: usize,
|
||||
irq: IrqNumber,
|
||||
}
|
||||
|
||||
@ -70,13 +70,14 @@ impl RtcDevice for Rtc {}
|
||||
|
||||
impl IntSource for Rtc {
|
||||
fn handle_irq(&self) -> Result<(), Errno> {
|
||||
self.regs.lock().arm_alarm0_irq(1);
|
||||
self.regs.get().lock().arm_alarm0_irq(1);
|
||||
debugln!("Tick!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_irqs(&'static self) -> Result<(), Errno> {
|
||||
machine::intc().register_handler(self.irq, self)?;
|
||||
self.regs.lock().arm_alarm0_irq(1);
|
||||
self.regs.get().lock().arm_alarm0_irq(1);
|
||||
machine::intc().enable_irq(self.irq)?;
|
||||
|
||||
Ok(())
|
||||
@ -89,6 +90,7 @@ impl Device for Rtc {
|
||||
}
|
||||
|
||||
unsafe fn enable(&self) -> Result<(), Errno> {
|
||||
self.regs.init(IrqSafeNullLock::new(DeviceMemoryIo::map(self.name(), self.base, 1)?));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -101,7 +103,8 @@ impl Rtc {
|
||||
/// Does not perform `base` validation.
|
||||
pub const unsafe fn new(base: usize, irq: IrqNumber) -> Self {
|
||||
Self {
|
||||
regs: IrqSafeNullLock::new(MemoryIo::new(base)),
|
||||
regs: InitOnce::new(),
|
||||
base,
|
||||
irq,
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::arch::{
|
||||
machine::{self, IrqNumber},
|
||||
MemoryIo,
|
||||
};
|
||||
use crate::sync::IrqSafeNullLock;
|
||||
use crate::util::InitOnce;
|
||||
use crate::mem::virt::DeviceMemoryIo;
|
||||
use crate::dev::{
|
||||
irq::{IntController, IntSource},
|
||||
serial::SerialDevice,
|
||||
@ -73,8 +74,13 @@ register_structs! {
|
||||
}
|
||||
}
|
||||
|
||||
struct UartInner {
|
||||
regs: DeviceMemoryIo<Regs>
|
||||
}
|
||||
|
||||
pub(super) struct Uart {
|
||||
regs: IrqSafeNullLock<MemoryIo<Regs>>,
|
||||
inner: InitOnce<IrqSafeNullLock<UartInner>>,
|
||||
base: usize,
|
||||
irq: IrqNumber
|
||||
}
|
||||
|
||||
@ -84,33 +90,41 @@ impl Device for Uart {
|
||||
}
|
||||
|
||||
unsafe fn enable(&self) -> Result<(), Errno> {
|
||||
let mut inner = UartInner {
|
||||
regs: DeviceMemoryIo::map(self.name(), self.base, 1)?
|
||||
};
|
||||
// TODO
|
||||
self.inner.init(IrqSafeNullLock::new(inner));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SerialDevice for Uart {
|
||||
fn send(&self, byte: u8) -> Result<(), Errno> {
|
||||
let regs = self.regs.lock();
|
||||
while !regs.LSR.matches_all(LSR::THRE::SET) {
|
||||
if !self.inner.is_initialized() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let inner = self.inner.get().lock();
|
||||
while !inner.regs.LSR.matches_all(LSR::THRE::SET) {
|
||||
cortex_a::asm::nop();
|
||||
}
|
||||
regs.DR_DLL.set(byte as u32);
|
||||
inner.regs.DR_DLL.set(byte as u32);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn recv(&self, _blocking: bool) -> Result<u8, Errno> {
|
||||
let regs = self.regs.lock();
|
||||
while !regs.LSR.matches_all(LSR::DR::SET) {
|
||||
let inner = self.inner.get().lock();
|
||||
while !inner.regs.LSR.matches_all(LSR::DR::SET) {
|
||||
cortex_a::asm::nop();
|
||||
}
|
||||
Ok(regs.DR_DLL.get() as u8)
|
||||
Ok(inner.regs.DR_DLL.get() as u8)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntSource for Uart {
|
||||
fn handle_irq(&self) -> Result<(), Errno> {
|
||||
let byte = self.regs.lock().DR_DLL.get();
|
||||
let byte = self.inner.get().lock().regs.DR_DLL.get();
|
||||
debugln!("irq byte = {:#04x}!", byte);
|
||||
|
||||
if byte == 0x1B {
|
||||
@ -127,7 +141,7 @@ impl IntSource for Uart {
|
||||
|
||||
fn init_irqs(&'static self) -> Result<(), Errno> {
|
||||
machine::intc().register_handler(self.irq, self)?;
|
||||
self.regs.lock().IER_DLH.modify(IER::ERBFI::SET);
|
||||
self.inner.get().lock().regs.IER_DLH.modify(IER::ERBFI::SET);
|
||||
machine::intc().enable_irq(self.irq)?;
|
||||
|
||||
Ok(())
|
||||
@ -137,7 +151,8 @@ impl IntSource for Uart {
|
||||
impl Uart {
|
||||
pub const unsafe fn new(base: usize, irq: IrqNumber) -> Self {
|
||||
Self {
|
||||
regs: IrqSafeNullLock::new(MemoryIo::new(base)),
|
||||
inner: InitOnce::new(),
|
||||
base,
|
||||
irq
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
use crate::arch::MemoryIo;
|
||||
use crate::dev::Device;
|
||||
use crate::mem::virt::DeviceMemoryIo;
|
||||
use crate::sync::IrqSafeNullLock;
|
||||
use crate::util::InitOnce;
|
||||
use error::Errno;
|
||||
use tock_registers::{
|
||||
interfaces::Writeable, register_bitfields, register_structs, registers::ReadWrite,
|
||||
};
|
||||
@ -36,7 +39,23 @@ register_structs! {
|
||||
}
|
||||
|
||||
pub(super) struct RWdog {
|
||||
regs: IrqSafeNullLock<MemoryIo<RWdogRegs>>,
|
||||
inner: InitOnce<IrqSafeNullLock<DeviceMemoryIo<RWdogRegs>>>,
|
||||
base: usize,
|
||||
}
|
||||
|
||||
impl Device for RWdog {
|
||||
fn name(&self) -> &'static str {
|
||||
"Allwinner H6 R_WDOG"
|
||||
}
|
||||
|
||||
unsafe fn enable(&self) -> Result<(), Errno> {
|
||||
self.inner.init(IrqSafeNullLock::new(DeviceMemoryIo::map(
|
||||
self.name(),
|
||||
self.base,
|
||||
1,
|
||||
)?));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl RWdog {
|
||||
@ -46,7 +65,7 @@ impl RWdog {
|
||||
///
|
||||
/// Unsafe: may interrupt critical processes
|
||||
pub unsafe fn reset_board(&self) -> ! {
|
||||
let regs = self.regs.lock();
|
||||
let regs = self.inner.get().lock();
|
||||
|
||||
regs.CFG.write(CFG::CONFIG::System);
|
||||
regs.MODE.write(MODE::EN::SET);
|
||||
@ -64,7 +83,8 @@ impl RWdog {
|
||||
/// Does not perform `base` validation.
|
||||
pub const unsafe fn new(base: usize) -> Self {
|
||||
Self {
|
||||
regs: IrqSafeNullLock::new(MemoryIo::new(base)),
|
||||
inner: InitOnce::new(),
|
||||
base,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,28 @@ pub mod mem;
|
||||
pub mod sync;
|
||||
pub mod util;
|
||||
|
||||
use core::fmt::{Write, self};
|
||||
struct DummyUart;
|
||||
|
||||
impl Write for DummyUart {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for b in s.bytes() {
|
||||
unsafe {
|
||||
core::ptr::write_volatile(0xFFFFFFC000000000 as *mut u32, b as u32);
|
||||
for _ in 0..100000 {
|
||||
asm!("nop");
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
|
||||
let mut u = DummyUart;
|
||||
write!(&mut u, "Panic occurred!\r\n");
|
||||
write!(&mut u, "{:?}", pi);
|
||||
// TODO
|
||||
loop {}
|
||||
}
|
||||
|
@ -10,10 +10,12 @@ use error::Errno;
|
||||
use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
|
||||
|
||||
const PTE_BLOCK_AF: u64 = 1 << 10;
|
||||
const PTE_BLOCK_NSH: u64 = 0 << 8;
|
||||
const PTE_BLOCK_ISH: u64 = 3 << 8;
|
||||
const PTE_BLOCK_OSH: u64 = 2 << 8;
|
||||
const PTE_TABLE: u64 = 1 << 1;
|
||||
const PTE_PRESENT: u64 = 1 << 0;
|
||||
const PTE_ATTR1: u64 = 1 << 2;
|
||||
|
||||
#[repr(C, align(0x1000))]
|
||||
struct Table([u64; 512]);
|
||||
@ -59,7 +61,8 @@ impl DeviceMemory {
|
||||
HUGE_COUNT += 1;
|
||||
|
||||
KERNEL_TTBR1.0[count + 256] =
|
||||
(phys as u64) | PTE_PRESENT | PTE_BLOCK_OSH | PTE_BLOCK_AF;
|
||||
(phys as u64) | PTE_PRESENT | PTE_BLOCK_OSH | PTE_BLOCK_AF | PTE_ATTR1;
|
||||
asm!("dsb ish; isb");
|
||||
|
||||
DEVICE_MAP_OFFSET + (count << 30)
|
||||
}
|
||||
@ -70,7 +73,8 @@ impl DeviceMemory {
|
||||
}
|
||||
BIG_COUNT += 1;
|
||||
|
||||
KERNEL_L1.0[count] = (phys as u64) | PTE_PRESENT | PTE_BLOCK_OSH | PTE_BLOCK_AF;
|
||||
KERNEL_L1.0[count] = (phys as u64) | PTE_PRESENT | PTE_BLOCK_OSH | PTE_BLOCK_AF | PTE_ATTR1;
|
||||
asm!("dsb ish; isb");
|
||||
|
||||
DEVICE_MAP_OFFSET + (count << 21)
|
||||
}
|
||||
@ -82,7 +86,9 @@ impl DeviceMemory {
|
||||
COUNT += 1;
|
||||
|
||||
KERNEL_L2.0[count] =
|
||||
(phys as u64) | PTE_TABLE | PTE_PRESENT | PTE_BLOCK_OSH | PTE_BLOCK_AF;
|
||||
(phys as u64) | PTE_TABLE | PTE_BLOCK_OSH | PTE_PRESENT | PTE_BLOCK_AF | PTE_ATTR1;
|
||||
asm!("tlbi vaae1, {}", in(reg) (DEVICE_MAP_OFFSET + (count << 12)), options(nostack, nomem));
|
||||
asm!("dsb ish; isb");
|
||||
|
||||
DEVICE_MAP_OFFSET + (count << 12)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user