Introduce some PIM data structures
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "aarch64"
|
name = "pim-os"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|||||||
37
src/m5ops.rs
37
src/m5ops.rs
@@ -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);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
84
src/main.rs
84
src/main.rs
@@ -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]
|
||||||
|
|||||||
44
src/pim.rs
44
src/pim.rs
@@ -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
3
src/pim/array.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
#[repr(C, align(1024))]
|
||||||
|
pub struct PimArray(pub [u32; 256]);
|
||||||
40
src/pim/config.rs
Normal file
40
src/pim/config.rs
Normal 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
16
src/pim/instruction.rs
Normal 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
7
src/pim/kernel.rs
Normal 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]);
|
||||||
Reference in New Issue
Block a user