Introduce some PIM data structures

This commit is contained in:
2023-11-22 17:42:27 +01:00
parent b729c823b0
commit b6d043dbd8
8 changed files with 144 additions and 89 deletions

View File

@@ -1,5 +1,5 @@
[package] [package]
name = "aarch64" name = "pim-os"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"

View File

@@ -1,29 +1,16 @@
use core::arch::asm;
const M5OPS_ADDR: u64 = 0x10010000;
const EXIT_ADDR: *const u64 = (M5OPS_ADDR + (0x21 << 8)) as _;
// const DUMP_STATS_ADDR: *const u64 = (M5OPS_ADDR + (0x40 << 8)) as _;
// const RESET_STATS_ADDR: *const u64 = (M5OPS_ADDR + (0x41 << 8)) as _;
// const DUMP_RESET_STATS_ADDR: *const u64 = (M5OPS_ADDR + (0x42 << 8)) as _;
// const CHECKPOINT_ADDR: *const u64 = (M5OPS_ADDR + (0x43 << 8)) as _;
pub fn exit() { pub fn exit() {
unsafe { unsafe {
core::ptr::read_volatile((0x10010000 + (0x21 << 8)) as *mut u64); core::ptr::read_volatile(EXIT_ADDR);
asm!("dsb sy");
} }
} }
pub fn checkpoint() {
unsafe {
core::ptr::read_volatile((0x10010000 + (0x43 << 8)) as *mut u64);
}
}
// pub fn dump_stats() {
// unsafe {
// core::ptr::read_volatile((0x10010000 + (0x40 << 8)) as *mut u64);
// }
// }
// pub fn reset_stats() {
// unsafe {
// core::ptr::read_volatile((0x10010000 + (0x41 << 8)) as *mut u64);
// }
// }
// pub fn dump_reset_stats() {
// unsafe {
// core::ptr::read_volatile((0x10010000 + (0x42 << 8)) as *mut u64);
// }
// }

View File

@@ -1,10 +1,14 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
use crate::uart::Uart0; use core::{
use core::arch::asm; arch::{asm, global_asm},
use core::sync::atomic::{self, Ordering}; fmt::Write,
use core::{arch::global_asm, fmt::Write, panic::PanicInfo}; panic::PanicInfo,
sync::atomic::{self, Ordering},
};
use pim::{array::PimArray, config::PimConfig, kernel::NOP_KERNEL};
use uart::Uart0;
mod m5ops; mod m5ops;
mod pim; mod pim;
@@ -12,35 +16,69 @@ mod uart;
global_asm!(include_str!("start.s")); global_asm!(include_str!("start.s"));
static mut TEST_ARRAY: PimArray = PimArray([0; 256]);
#[no_mangle] #[no_mangle]
pub extern "C" fn entry() -> ! { pub extern "C" fn entry() -> ! {
let pim_config = pim::PimConfig { let mut pim_config = pim::config::PimConfig {
bank_mode: pim::BankMode::SingleBank, bank_mode: pim::config::BankMode::AllBank,
kernel: NOP_KERNEL,
}; };
let mut pim_writer = pim::PimWriter; let mut pim_writer = pim::config::PimWriter;
write!(
&mut pim_writer,
"{}",
serde_json_core::to_string::<_, 256>(&pim_config).unwrap()
)
.unwrap();
let mut uart = Uart0 {}; let mut uart = Uart0 {};
for i in 0..3 { unsafe {
writeln!(&mut uart, "Hello from Rust {i}!").unwrap(); // Toggle AllBank
} pim_writer.write(
serde_json_core::to_string::<PimConfig, 256>(&pim_config)
.unwrap()
.as_str(),
);
for val in 0..64 { writeln!(&mut uart, "Enable AllBank").unwrap();
unsafe {
asm!("dc cvac, {val}", val = in(reg) &val); writeln!(&mut uart, "Write single cache line").unwrap();
asm!("dsb sy"); TEST_ARRAY.0[0] = 0xaa;
TEST_ARRAY.0[1] = 0xaa;
TEST_ARRAY.0[2] = 0xaa;
TEST_ARRAY.0[3] = 0xaa;
TEST_ARRAY.0[4] = 0xaa;
TEST_ARRAY.0[5] = 0xaa;
TEST_ARRAY.0[6] = 0xaa;
TEST_ARRAY.0[7] = 0xaa;
// Flush and invalidate array
for element in TEST_ARRAY.0.iter().step_by(8) {
asm!("dc civac, {val}", val = in(reg) element);
} }
// Wait on all flushes to complete
asm!("dsb sy");
// Toggle AllBank
pim_config.bank_mode = pim::config::BankMode::SingleBank;
pim_writer.write(
serde_json_core::to_string::<PimConfig, 256>(&pim_config)
.unwrap()
.as_str(),
);
writeln!(&mut uart, "Disable AllBank").unwrap();
// Print array
writeln!(
&mut uart,
"{:?}: {:x?}",
core::ptr::addr_of!(TEST_ARRAY),
TEST_ARRAY
)
.unwrap();
} }
m5ops::checkpoint();
m5ops::exit(); m5ops::exit();
unreachable!();
loop {
atomic::compiler_fence(Ordering::SeqCst);
}
} }
#[panic_handler] #[panic_handler]

View File

@@ -1,40 +1,4 @@
use core::arch::asm; pub mod array;
use core::fmt::Write; pub mod config;
use serde::{Deserialize, Serialize}; pub mod instruction;
pub mod kernel;
#[link_section = ".pim_config"]
static mut PIM_CONFIG_REGION: [u8; 0x4000] = [0; 0x4000];
pub struct PimWriter;
impl Write for PimWriter {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
unsafe {
PIM_CONFIG_REGION[..s.len()].copy_from_slice(s.as_bytes());
PIM_CONFIG_REGION[s.len()] = b'\0';
// Flush all cache lines that were affected by write operation
// A cache line is 64 bytes so we only need to flush every 64th virtual address
for element in PIM_CONFIG_REGION[..s.len()].iter().step_by(64) {
asm!("dc cvac, {val}", val = in(reg) element);
}
// Wait on all flushes to complete
asm!("dsb sy");
}
Ok(())
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PimConfig {
pub bank_mode: BankMode,
}
#[derive(Serialize, Deserialize, Debug)]
pub enum BankMode {
SingleBank,
AllBank,
PimAllBank,
}

3
src/pim/array.rs Normal file
View File

@@ -0,0 +1,3 @@
#[derive(Debug)]
#[repr(C, align(1024))]
pub struct PimArray(pub [u32; 256]);

40
src/pim/config.rs Normal file
View File

@@ -0,0 +1,40 @@
use core::arch::asm;
use serde::Serialize;
use super::kernel::Kernel;
#[link_section = ".pim_config"]
static mut PIM_CONFIG_REGION: [u8; 0x4000] = [0; 0x4000];
pub struct PimWriter;
impl PimWriter {
pub fn write(&mut self, s: &str) {
unsafe {
PIM_CONFIG_REGION[..s.len()].copy_from_slice(s.as_bytes());
PIM_CONFIG_REGION[s.len()] = b'\0';
// Flush all cache lines that were affected by write operation
// A cache line is 32 bytes so we only need to flush every 64th virtual address
for element in PIM_CONFIG_REGION[..s.len()].iter().step_by(32) {
asm!("dc civac, {val}", val = in(reg) element);
}
// Wait on all flushes to complete
asm!("dsb sy");
}
}
}
#[derive(Serialize, Debug)]
pub struct PimConfig {
pub bank_mode: BankMode,
pub kernel: Kernel,
}
#[derive(Serialize, Debug)]
pub enum BankMode {
SingleBank,
AllBank,
PimAllBank,
}

16
src/pim/instruction.rs Normal file
View File

@@ -0,0 +1,16 @@
use serde::Serialize;
#[derive(Clone, Copy, Debug, Serialize)]
pub enum Instruction {
NOP,
JUMP(JUMP),
}
#[derive(Clone, Copy, Debug, Serialize)]
pub struct NOP;
#[derive(Clone, Copy, Debug, Serialize)]
pub struct JUMP {
pub offset: u8,
pub count: u8,
}

7
src/pim/kernel.rs Normal file
View File

@@ -0,0 +1,7 @@
use super::instruction::{Instruction, NOP};
use serde::Serialize;
#[derive(Debug, Serialize)]
pub struct Kernel([Instruction; 32]);
pub const NOP_KERNEL: Kernel = Kernel([Instruction::NOP; 32]);