Add support for cacheless PIM
This commit is contained in:
@@ -6,6 +6,9 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
forced-target = "aarch64-unknown-none"
|
||||
|
||||
[features]
|
||||
cacheless = []
|
||||
|
||||
[dependencies]
|
||||
aarch64-cpu = "9.4.0"
|
||||
half = { version = "2.3.1", default-features = false }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use aarch64_cpu::asm::barrier;
|
||||
use core::{
|
||||
arch::global_asm,
|
||||
fmt::Write,
|
||||
panic::PanicInfo,
|
||||
sync::atomic::{compiler_fence, Ordering},
|
||||
@@ -15,13 +15,11 @@ use pim::{
|
||||
};
|
||||
use pim_isa::BankMode;
|
||||
use uart::Uart0;
|
||||
|
||||
mod boot;
|
||||
mod m5ops;
|
||||
mod pim;
|
||||
mod uart;
|
||||
|
||||
global_asm!(include_str!("start.s"));
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn entry() -> ! {
|
||||
let mut pim_state = PimState::new(&TEST_KERNEL);
|
||||
@@ -52,6 +50,7 @@ pub extern "C" fn entry() -> ! {
|
||||
// Invalidate and flush array just in case
|
||||
compute_array.invalidate_flush();
|
||||
dummy_array.invalidate_flush();
|
||||
barrier::dsb(barrier::SY);
|
||||
|
||||
pim_state.set_bank_mode(BankMode::PimAllBank);
|
||||
compute_array.0[0].execute_instruction_read();
|
||||
@@ -62,6 +61,7 @@ pub extern "C" fn entry() -> ! {
|
||||
pim_state.set_bank_mode(BankMode::SingleBank);
|
||||
|
||||
compute_array.invalidate();
|
||||
barrier::dsb(barrier::SY);
|
||||
|
||||
writeln!(
|
||||
&mut uart,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use aarch64_cpu::asm::barrier;
|
||||
use core::arch::asm;
|
||||
use half::f16;
|
||||
|
||||
@@ -17,8 +18,13 @@ impl Default for BankArray {
|
||||
|
||||
impl BankArray {
|
||||
pub fn execute_instruction_read(&self) {
|
||||
if !cfg!(cacheless) {
|
||||
self.invalidate_single_bank(0);
|
||||
barrier::dsb(barrier::SY);
|
||||
}
|
||||
|
||||
self.read_data();
|
||||
barrier::dsb(barrier::SY);
|
||||
}
|
||||
|
||||
pub fn read_data(&self) {
|
||||
@@ -30,11 +36,20 @@ impl BankArray {
|
||||
}
|
||||
|
||||
pub fn execute_instruction_write(&mut self) {
|
||||
if !cfg!(cacheless) {
|
||||
self.preload_zero();
|
||||
barrier::dsb(barrier::SY);
|
||||
}
|
||||
|
||||
self.write_data();
|
||||
|
||||
if !cfg!(cacheless) {
|
||||
self.invalidate_flush_single_bank(0);
|
||||
}
|
||||
|
||||
barrier::dsb(barrier::SY);
|
||||
}
|
||||
|
||||
pub fn write_data(&mut self) {
|
||||
unsafe {
|
||||
// Write to first bank
|
||||
@@ -53,7 +68,6 @@ impl BankArray {
|
||||
unsafe {
|
||||
// Invalidate first bank
|
||||
asm!("dc ivac, {val}", val = in(reg) &self.0[idx]);
|
||||
asm!("dsb sy");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +81,6 @@ impl BankArray {
|
||||
unsafe {
|
||||
// Invalidate and flush first bank
|
||||
asm!("dc civac, {val}", val = in(reg) &self.0[idx]);
|
||||
asm!("dsb sy");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +94,6 @@ impl BankArray {
|
||||
unsafe {
|
||||
// Preload first bank
|
||||
asm!("dc zva, {val}", val = in(reg) &self.0[idx]);
|
||||
asm!("dsb sy");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::boot;
|
||||
|
||||
use super::config::PimWriter;
|
||||
use pim_isa::{BankMode, Kernel, PimConfig};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PimState {
|
||||
kernel: Kernel,
|
||||
bank_mode: BankMode,
|
||||
writer: PimWriter,
|
||||
}
|
||||
|
||||
@@ -12,18 +13,24 @@ impl PimState {
|
||||
pub fn new(kernel: &Kernel) -> Self {
|
||||
Self {
|
||||
kernel: kernel.clone(),
|
||||
bank_mode: BankMode::SingleBank,
|
||||
writer: PimWriter,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO return token and return to singlebank when dropped
|
||||
pub fn set_bank_mode(&mut self, bank_mode: BankMode) {
|
||||
self.bank_mode = bank_mode;
|
||||
if cfg!(cacheless) {
|
||||
match bank_mode {
|
||||
BankMode::SingleBank => unsafe { boot::set_page_table_cache() },
|
||||
BankMode::AllBank => (),
|
||||
BankMode::PimAllBank => unsafe { boot::set_page_table_non_cache() },
|
||||
}
|
||||
}
|
||||
|
||||
self.writer.write(
|
||||
serde_json_core::to_string::<PimConfig, 1024>(&PimConfig {
|
||||
kernel: self.kernel.clone(),
|
||||
bank_mode: self.bank_mode,
|
||||
bank_mode,
|
||||
})
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.globl _start
|
||||
|
||||
.extern LD_STACK_PTR
|
||||
|
||||
// Put a 64-bit value with little endianness.
|
||||
@@ -36,39 +36,55 @@ BLOCK_1GB (ADDR << 29), 0, 0x74C
|
||||
.set ADDR, ADDR+2
|
||||
.endr
|
||||
|
||||
.align 12
|
||||
ttb0_base_non_cache:
|
||||
.set ADDR, 0x000
|
||||
.rept 0x02
|
||||
BLOCK_1GB (ADDR << 29), 0, 0x740
|
||||
.set ADDR, ADDR+2
|
||||
.endr
|
||||
.rept 0x3E
|
||||
BLOCK_1GB (ADDR << 29), 0, 0x740
|
||||
.set ADDR, ADDR+2
|
||||
.endr
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
ldr x30, =LD_STACK_PTR
|
||||
mov sp, x30
|
||||
|
||||
// Initialize translation table control registers
|
||||
LDR X1, =0x13520 // 64GB space 4KB granularity Inner-shareable. Normal Inner and Outer Cacheable.
|
||||
MSR TCR_EL3, X1
|
||||
ldr x1, =0x13520 // 64GB space 4KB granularity Inner-shareable. Normal Inner and Outer Cacheable.
|
||||
msr tcr_el3, x1
|
||||
|
||||
LDR X1, =0xFF440400
|
||||
MSR MAIR_EL3, X1 // ATTR0 Device-nGnRnE ATTR1 Device. ATTR2 Normal Non-Cacheable. ATTR3 Normal Cacheable.
|
||||
ldr x1, =0xFF440400
|
||||
msr mair_el3, x1 // ATTR0 Device-nGnRnE ATTR1 Device. ATTR2 Normal Non-Cacheable. ATTR3 Normal Cacheable.
|
||||
|
||||
ADR X0, ttb0_base
|
||||
MSR TTBR0_EL3, X0
|
||||
bl set_page_table_cache
|
||||
|
||||
// Enable MMU and caches
|
||||
// It is implemented in the CPUECTLR register.
|
||||
MRS X0, S3_1_C15_C2_1
|
||||
ORR X0, X0, #(0x1 << 6) // The SMP bit.
|
||||
MSR S3_1_C15_C2_1, X0
|
||||
|
||||
// Enable caches and the MMU.
|
||||
MRS X0, SCTLR_EL3
|
||||
ORR X0, X0, #(0x1 << 2) // The C bit (data cache).
|
||||
ORR X0, X0, #(0x1 << 12) // The I bit (instruction cache).
|
||||
ORR X0, X0, #0x1 // The M bit (MMU).
|
||||
MSR SCTLR_EL3, X0
|
||||
DSB SY
|
||||
ISB
|
||||
mrs x0, sctlr_el3
|
||||
orr x0, x0, #(0x1 << 2) // The C bit (data cache).
|
||||
orr x0, x0, #(0x1 << 12) // The I bit (instruction cache).
|
||||
orr x0, x0, #0x1 // The M bit (MMU).
|
||||
msr sctlr_el3, x0
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
bl entry
|
||||
|
||||
.equ PSCI_SYSTEM_OFF, 0x84000008
|
||||
.globl system_off
|
||||
system_off:
|
||||
ldr x0, =PSCI_SYSTEM_OFF
|
||||
hvc #0
|
||||
.globl set_page_table_cache
|
||||
set_page_table_cache:
|
||||
adr x0, ttb0_base
|
||||
msr ttbr0_el3, x0
|
||||
tlbi alle3
|
||||
isb
|
||||
ret
|
||||
|
||||
.globl set_page_table_non_cache
|
||||
set_page_table_non_cache:
|
||||
adr x0, ttb0_base_non_cache
|
||||
msr ttbr0_el3, x0
|
||||
tlbi alle3
|
||||
isb
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user