diff --git a/Cargo.toml b/Cargo.toml index dd40a7d..ff06dbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "aarch64" +name = "pim-os" version = "0.1.0" edition = "2021" diff --git a/src/m5ops.rs b/src/m5ops.rs index 1435428..5217844 100644 --- a/src/m5ops.rs +++ b/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() { 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); -// } -// } diff --git a/src/main.rs b/src/main.rs index 96b9af1..cf7e8cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,14 @@ #![no_std] #![no_main] -use crate::uart::Uart0; -use core::arch::asm; -use core::sync::atomic::{self, Ordering}; -use core::{arch::global_asm, fmt::Write, panic::PanicInfo}; +use core::{ + arch::{asm, global_asm}, + fmt::Write, + panic::PanicInfo, + sync::atomic::{self, Ordering}, +}; +use pim::{array::PimArray, config::PimConfig, kernel::NOP_KERNEL}; +use uart::Uart0; mod m5ops; mod pim; @@ -12,35 +16,69 @@ mod uart; global_asm!(include_str!("start.s")); +static mut TEST_ARRAY: PimArray = PimArray([0; 256]); + #[no_mangle] pub extern "C" fn entry() -> ! { - let pim_config = pim::PimConfig { - bank_mode: pim::BankMode::SingleBank, + let mut pim_config = pim::config::PimConfig { + bank_mode: pim::config::BankMode::AllBank, + kernel: NOP_KERNEL, }; - let mut pim_writer = pim::PimWriter; - - write!( - &mut pim_writer, - "{}", - serde_json_core::to_string::<_, 256>(&pim_config).unwrap() - ) - .unwrap(); + let mut pim_writer = pim::config::PimWriter; let mut uart = Uart0 {}; - for i in 0..3 { - writeln!(&mut uart, "Hello from Rust {i}!").unwrap(); - } + unsafe { + // Toggle AllBank + pim_writer.write( + serde_json_core::to_string::(&pim_config) + .unwrap() + .as_str(), + ); - for val in 0..64 { - unsafe { - asm!("dc cvac, {val}", val = in(reg) &val); - asm!("dsb sy"); + writeln!(&mut uart, "Enable AllBank").unwrap(); + + writeln!(&mut uart, "Write single cache line").unwrap(); + 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::(&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(); - unreachable!(); + + loop { + atomic::compiler_fence(Ordering::SeqCst); + } } #[panic_handler] diff --git a/src/pim.rs b/src/pim.rs index ea013e9..9aefa56 100644 --- a/src/pim.rs +++ b/src/pim.rs @@ -1,40 +1,4 @@ -use core::arch::asm; -use core::fmt::Write; -use serde::{Deserialize, Serialize}; - -#[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, -} +pub mod array; +pub mod config; +pub mod instruction; +pub mod kernel; diff --git a/src/pim/array.rs b/src/pim/array.rs new file mode 100644 index 0000000..685a108 --- /dev/null +++ b/src/pim/array.rs @@ -0,0 +1,3 @@ +#[derive(Debug)] +#[repr(C, align(1024))] +pub struct PimArray(pub [u32; 256]); diff --git a/src/pim/config.rs b/src/pim/config.rs new file mode 100644 index 0000000..e719d83 --- /dev/null +++ b/src/pim/config.rs @@ -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, +} diff --git a/src/pim/instruction.rs b/src/pim/instruction.rs new file mode 100644 index 0000000..8eba06f --- /dev/null +++ b/src/pim/instruction.rs @@ -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, +} diff --git a/src/pim/kernel.rs b/src/pim/kernel.rs new file mode 100644 index 0000000..f297dab --- /dev/null +++ b/src/pim/kernel.rs @@ -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]);