aarch64: prettify cache init

This commit is contained in:
Mark Poliakov 2024-12-15 15:20:09 +02:00
parent a2adff85a7
commit ccb5a6a7eb
5 changed files with 64 additions and 43 deletions

View File

@ -6,7 +6,7 @@ use core::{
use aarch64_cpu::{ use aarch64_cpu::{
asm::barrier, asm::barrier,
registers::{PAR_EL1, TTBR0_EL1, TTBR1_EL1}, registers::{MAIR_EL1, PAR_EL1, SCTLR_EL1, TTBR0_EL1, TTBR1_EL1},
}; };
use kernel_arch_interface::{ use kernel_arch_interface::{
mem::{DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping}, mem::{DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping},
@ -18,7 +18,7 @@ use libk_mm_interface::{
}; };
use memtables::aarch64::{FixedTables, KERNEL_L3_COUNT}; use memtables::aarch64::{FixedTables, KERNEL_L3_COUNT};
use static_assertions::const_assert_eq; use static_assertions::const_assert_eq;
use tock_registers::interfaces::{Readable, Writeable}; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
use yggdrasil_abi::error::Error; use yggdrasil_abi::error::Error;
use crate::ArchitectureImpl; use crate::ArchitectureImpl;
@ -496,3 +496,47 @@ pub unsafe fn init_fixed_tables() {
tlb_flush_all(); tlb_flush_all();
} }
pub fn setup_memory_attributes() {
// TODO: Figure out why WriteBack_NonTransient_ReadWriteAlloc doesn't work on Pi 4B
MAIR_EL1.write(
//// Attribute 0 -- normal memory
MAIR_EL1::Attr0_Normal_Inner::WriteBack_NonTransient +
MAIR_EL1::Attr0_Normal_Outer::WriteBack_NonTransient +
//// Attribute 1 -- normal non-cacheable memory
MAIR_EL1::Attr0_Normal_Inner::NonCacheable +
MAIR_EL1::Attr0_Normal_Outer::NonCacheable +
//// Attribute 2 -- device memory
MAIR_EL1::Attr1_Device::nonGathering_nonReordering_EarlyWriteAck,
);
}
pub unsafe fn enable_dcache() {
barrier::dsb(barrier::ISHST);
barrier::isb(barrier::SY);
SCTLR_EL1.modify(SCTLR_EL1::C::Cacheable);
barrier::dsb(barrier::ISH);
barrier::isb(barrier::SY);
}
pub unsafe fn enable_icache() {
barrier::isb(barrier::SY);
SCTLR_EL1.modify(SCTLR_EL1::I::Cacheable);
barrier::dsb(barrier::ISH);
barrier::isb(barrier::SY);
}
pub unsafe fn disable_icache() {
barrier::isb(barrier::SY);
ic_iallu();
SCTLR_EL1.modify(SCTLR_EL1::I::NonCacheable);
barrier::dsb(barrier::ISH);
barrier::isb(barrier::SY);
}

View File

@ -41,7 +41,8 @@ bitflags! {
const SH_INNER = 3 << 8; const SH_INNER = 3 << 8;
const PAGE_ATTR_NORMAL = 0 << 2; const PAGE_ATTR_NORMAL = 0 << 2;
const PAGE_ATTR_DEVICE = 1 << 2; const PAGE_ATTR_NORMAL_NC = 1 << 2;
const PAGE_ATTR_DEVICE = 2 << 2;
const NON_GLOBAL = 1 << 11; const NON_GLOBAL = 1 << 11;

View File

@ -3,10 +3,10 @@ use core::arch::global_asm;
use aarch64_cpu::{ use aarch64_cpu::{
asm::barrier, asm::barrier,
registers::{CPACR_EL1, ID_AA64MMFR0_EL1, MAIR_EL1, SCTLR_EL1, TCR_EL1, TTBR0_EL1}, registers::{CPACR_EL1, ID_AA64MMFR0_EL1, SCTLR_EL1, TCR_EL1, TTBR0_EL1},
}; };
use kernel_arch::{absolute_address, Architecture, ArchitectureImpl}; use kernel_arch::{absolute_address, Architecture, ArchitectureImpl};
use kernel_arch_aarch64::mem::ic_iallu; use kernel_arch_aarch64::mem;
use libk::{devfs, task::runtime}; use libk::{devfs, task::runtime};
use libk_mm::address::PhysicalAddress; use libk_mm::address::PhysicalAddress;
use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
@ -22,26 +22,17 @@ unsafe fn check_mmu_features() {
} }
unsafe fn pre_init_mmu() { unsafe fn pre_init_mmu() {
// TODO: Figure out why WriteBack_NonTransient_ReadWriteAlloc doesn't work on Pi 4B mem::setup_memory_attributes();
MAIR_EL1.write(
//// Attribute 0 -- normal memory
// Inner
MAIR_EL1::Attr0_Normal_Inner::WriteBack_NonTransient +
// Outer
MAIR_EL1::Attr0_Normal_Outer::WriteBack_NonTransient +
//// Attribute 1 -- device memory
MAIR_EL1::Attr1_Device::nonGathering_nonReordering_EarlyWriteAck,
);
TCR_EL1.write( TCR_EL1.write(
TCR_EL1::AS::ASID8Bits + TCR_EL1::AS::ASID8Bits +
TCR_EL1::A1::TTBR0 + TCR_EL1::A1::TTBR0 +
// General // General
TCR_EL1::IPS::Bits_48 + TCR_EL1::IPS::Bits_48 +
// TTBR0 // TTBR0
TCR_EL1::TG0::KiB_4 + TCR_EL1::T0SZ.val(25) + TCR_EL1::SH0::Outer + TCR_EL1::TG0::KiB_4 + TCR_EL1::T0SZ.val(25) + TCR_EL1::SH0::Inner +
// TTBR1 // TTBR1
TCR_EL1::TG1::KiB_4 + TCR_EL1::T1SZ.val(25) + TCR_EL1::SH1::Outer, TCR_EL1::TG1::KiB_4 + TCR_EL1::T1SZ.val(25) + TCR_EL1::SH1::Inner,
); );
} }
@ -66,18 +57,9 @@ unsafe fn enable_mmu() {
// Enable translation // Enable translation
SCTLR_EL1.modify(SCTLR_EL1::M::Enable); SCTLR_EL1.modify(SCTLR_EL1::M::Enable);
barrier::dsb(barrier::ISH); // Enable caches
barrier::isb(barrier::SY); mem::enable_icache();
mem::enable_dcache();
ic_iallu();
SCTLR_EL1.modify(SCTLR_EL1::I::Cacheable);
barrier::dsb(barrier::ISH);
barrier::isb(barrier::SY);
SCTLR_EL1.modify(SCTLR_EL1::C::Cacheable);
barrier::isb(barrier::SY);
} }
unsafe fn enter_higher_half(sp: usize, elr: usize, x0: usize) -> ! { unsafe fn enter_higher_half(sp: usize, elr: usize, x0: usize) -> ! {

View File

@ -2,10 +2,7 @@
use core::sync::atomic::{self, Ordering}; use core::sync::atomic::{self, Ordering};
use aarch64_cpu::{ use aarch64_cpu::registers::{CNTP_CTL_EL0, CNTP_TVAL_EL0};
asm::barrier,
registers::{CNTP_CTL_EL0, CNTP_TVAL_EL0, SCTLR_EL1},
};
use abi::error::Error; use abi::error::Error;
use alloc::sync::Arc; use alloc::sync::Arc;
use device_api::{ use device_api::{
@ -16,7 +13,7 @@ use device_tree::dt::{DevTreeIndexNodePropGet, DeviceTree, FdtMemoryRegionIter};
use kernel_arch::Architecture; use kernel_arch::Architecture;
use kernel_arch_aarch64::{ use kernel_arch_aarch64::{
mem::{ mem::{
ic_iallu, self,
table::{L1, L3}, table::{L1, L3},
EarlyMapping, MEMORY_LIMIT, RAM_MAPPING_L1_COUNT, EarlyMapping, MEMORY_LIMIT, RAM_MAPPING_L1_COUNT,
}, },
@ -34,7 +31,7 @@ use libk_mm::{
table::EntryLevelExt, table::EntryLevelExt,
}; };
use libk_util::OneTimeInit; use libk_util::OneTimeInit;
use tock_registers::interfaces::{ReadWriteable, Writeable}; use tock_registers::interfaces::Writeable;
use ygg_driver_pci::PciBusManager; use ygg_driver_pci::PciBusManager;
use crate::{ use crate::{
@ -237,14 +234,7 @@ impl AArch64 {
"raspberrypi,4-model-b" => { "raspberrypi,4-model-b" => {
// XXX Workaround for Raspberry Pi 4B: // XXX Workaround for Raspberry Pi 4B:
// Instruction cache totally freaks out at EL0 and I don't know why // Instruction cache totally freaks out at EL0 and I don't know why
barrier::dsb(barrier::ISH); unsafe { mem::disable_icache() };
barrier::isb(barrier::SY);
ic_iallu();
SCTLR_EL1.modify(SCTLR_EL1::I::NonCacheable);
barrier::dsb(barrier::ISH);
barrier::isb(barrier::SY);
} }
_ => (), _ => (),
} }

View File

@ -71,6 +71,10 @@ pub struct Bcm2835AuxUart {
impl Regs { impl Regs {
fn write_byte(&self, byte: u8) -> Result<(), Error> { fn write_byte(&self, byte: u8) -> Result<(), Error> {
if byte == b'\n' {
self.write_byte(b'\r').ok();
}
while !self while !self
.AUX_MU_LSR_REG .AUX_MU_LSR_REG
.matches_all(AUX_MU_LSR_REG::TX_EMPTY::SET) .matches_all(AUX_MU_LSR_REG::TX_EMPTY::SET)