Add support for cacheless PIM

This commit is contained in:
2023-12-11 18:52:02 +01:00
parent 71c766736a
commit beaa224252
5 changed files with 77 additions and 39 deletions

View File

@@ -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 }

View File

@@ -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,

View File

@@ -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) {
self.invalidate_single_bank(0);
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,9 +36,18 @@ impl BankArray {
}
pub fn execute_instruction_write(&mut self) {
self.preload_zero();
if !cfg!(cacheless) {
self.preload_zero();
barrier::dsb(barrier::SY);
}
self.write_data();
self.invalidate_flush_single_bank(0);
if !cfg!(cacheless) {
self.invalidate_flush_single_bank(0);
}
barrier::dsb(barrier::SY);
}
pub fn write_data(&mut self) {
@@ -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");
}
}
}

View File

@@ -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(),

View File

@@ -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