Split up into pim-os, pim-vm and pim-isa crate

This commit is contained in:
2023-11-28 20:41:09 +01:00
parent 8f1c43defd
commit 54bf6bda11
22 changed files with 1078 additions and 109 deletions

6
pim-os/.cargo/config Normal file
View File

@@ -0,0 +1,6 @@
[build]
target = "aarch64-unknown-none"
rustflags = [
"-C", "link-arg=-Taarch64-gem5.ld",
]

225
pim-os/Cargo.lock generated Normal file
View File

@@ -0,0 +1,225 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aarch64-cpu"
version = "9.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac42a04a61c19fc8196dd728022a784baecc5d63d7e256c01ad1b3fbfab26287"
dependencies = [
"tock-registers",
]
[[package]]
name = "atomic-polyfill"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
dependencies = [
"critical-section",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "half"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872"
dependencies = [
"cfg-if",
"crunchy",
]
[[package]]
name = "hash32"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
dependencies = [
"atomic-polyfill",
"hash32",
"rustc_version",
"spin",
"stable_deref_trait",
]
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "pim-isa"
version = "0.1.0"
dependencies = [
"serde",
]
[[package]]
name = "pim-os"
version = "0.1.0"
dependencies = [
"aarch64-cpu",
"half",
"pim-isa",
"serde",
"serde-json-core",
]
[[package]]
name = "proc-macro2"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "serde"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde-json-core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c9e1ab533c0bc414c34920ec7e5f097101d126ed5eac1a1aac711222e0bbb33"
dependencies = [
"heapless",
"ryu",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tock-registers"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "696941a0aee7e276a165a978b37918fd5d22c55c3d6bda197813070ca9c0f21c"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"

17
pim-os/Cargo.toml Normal file
View File

@@ -0,0 +1,17 @@
[package]
name = "pim-os"
version = "0.1.0"
edition = "2021"
[dependencies]
aarch64-cpu = "9.4.0"
half = { version = "2.3.1", default-features = false }
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde-json-core = "0.5.1"
pim-isa = { path = "../pim-isa", default-features = false }
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"

21
pim-os/aarch64-gem5.ld Normal file
View File

@@ -0,0 +1,21 @@
MEMORY
{
bootmem : ORIGIN = 0x0, LENGTH = 0x10000
dram : ORIGIN = 0x80000000, LENGTH = 0x100000000
}
ENTRY(_start)
SECTIONS
{
.init : { *(.init) } > bootmem
.pim_config : { KEEP(*(.pim_config)) } > dram
# . = . + 0x4000;
.text : { KEEP(*(.text)) } > dram
.data : { *(.data) } > dram
.rodata : { *(.rodata) } > dram
.bss : { *(.bss) } > dram
. = ALIGN(8);
. = . + 0x8000;
LD_STACK_PTR = .;
}

16
pim-os/src/m5ops.rs Normal file
View File

@@ -0,0 +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(EXIT_ADDR);
asm!("dsb sy");
}
}

107
pim-os/src/main.rs Normal file
View File

@@ -0,0 +1,107 @@
#![no_std]
#![no_main]
use core::{
arch::{asm, global_asm},
fmt::Write,
panic::PanicInfo,
sync::atomic::{self, Ordering},
};
use half::f16;
use pim::{array::BankArray, kernel::TEST_KERNEL};
use pim_isa::{BankMode, PimConfig};
use uart::Uart0;
mod m5ops;
mod pim;
mod uart;
global_asm!(include_str!("start.s"));
static mut TEST_ARRAY: BankArray = BankArray([f16::ZERO; 512]);
#[no_mangle]
pub extern "C" fn entry() -> ! {
let mut pim_config = PimConfig {
bank_mode: BankMode::PimAllBank,
kernel: TEST_KERNEL,
};
let mut pim_writer = pim::config::PimWriter;
let mut uart = Uart0 {};
unsafe {
writeln!(
&mut uart,
"PIM array is at {:x?}",
core::ptr::addr_of!(TEST_ARRAY)
)
.unwrap();
writeln!(&mut uart, "Read from all banks").unwrap();
// Invalidate and flush array just in case
for element in TEST_ARRAY.0.iter().step_by(8) {
asm!("dc civac, {val}", val = in(reg) element);
}
asm!("dsb sy");
// Fetch single cache line in array
// core::ptr::read_volatile(&TEST_ARRAY.0[0]);
// Zero array to prevent fetch
// for element in TEST_ARRAY.0.iter().step_by(8) {
// asm!("dc zva, {val}", val = in(reg) element);
// }
asm!("dc zva, {val}", val = in(reg) &TEST_ARRAY.0[0]);
asm!("dsb sy");
pim_writer.write(
serde_json_core::to_string::<PimConfig, 1024>(&pim_config)
.unwrap()
.as_str(),
);
core::ptr::write_volatile(&mut TEST_ARRAY.0[0], f16::ZERO);
// Invalidate and flush
// for element in TEST_ARRAY.0.iter().step_by(8) {
asm!("dc civac, {val}", val = in(reg) &TEST_ARRAY.0[0]);
// }
asm!("dsb sy");
pim_config.bank_mode = BankMode::SingleBank;
pim_writer.write(
serde_json_core::to_string::<PimConfig, 1024>(&pim_config)
.unwrap()
.as_str(),
);
// Invalidate array
for element in TEST_ARRAY.0.iter().step_by(8) {
asm!("dc ivac, {val}", val = in(reg) element);
}
writeln!(
&mut uart,
"{:?}: {:x?}",
core::ptr::addr_of!(TEST_ARRAY),
TEST_ARRAY
)
.unwrap();
}
m5ops::exit();
loop {
atomic::compiler_fence(Ordering::SeqCst);
}
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
writeln!(Uart0, "{info}").unwrap();
loop {
atomic::compiler_fence(Ordering::SeqCst);
}
}

3
pim-os/src/pim.rs Normal file
View File

@@ -0,0 +1,3 @@
pub mod array;
pub mod config;
pub mod kernel;

8
pim-os/src/pim/array.rs Normal file
View File

@@ -0,0 +1,8 @@
use half::f16;
#[derive(Debug)]
#[repr(C, align(1024))]
pub struct BankArray(pub [f16; 512]);
#[derive(Debug)]
pub struct ComputeArray<const N: usize>(pub [BankArray; N]);

26
pim-os/src/pim/config.rs Normal file
View File

@@ -0,0 +1,26 @@
use core::arch::asm;
#[link_section = ".pim_config"]
static mut PIM_CONFIG_REGION: [u8; 0x4000] = [0; 0x4000];
const CACHE_LINE_SIZE: usize = 32;
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
for element in PIM_CONFIG_REGION[..s.len()].iter().step_by(CACHE_LINE_SIZE) {
asm!("dc civac, {val}", val = in(reg) element);
}
// Wait on all flushes to complete
asm!("dsb sy");
}
}
}

45
pim-os/src/pim/kernel.rs Normal file
View File

@@ -0,0 +1,45 @@
use pim_isa::{File, Instruction, Kernel};
pub const TEST_KERNEL: Kernel = Kernel([
Instruction::FILL {
src: File::Grf { index: 0 },
dst: File::Bank,
},
Instruction::MOV {
src: File::Bank,
dst: File::Grf { index: 1 },
},
Instruction::JUMP {
offset: 1,
count: 12,
},
Instruction::EXIT,
Instruction::NOP,
Instruction::EXIT,
Instruction::NOP,
Instruction::EXIT,
Instruction::NOP,
Instruction::EXIT,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
Instruction::NOP,
]);

74
pim-os/src/start.s Normal file
View File

@@ -0,0 +1,74 @@
.globl _start
.extern LD_STACK_PTR
// Put a 64-bit value with little endianness.
.macro PUT_64B high, low
.word \low
.word \high
.endm
// Create an entry pointing to a next-level table.
.macro TABLE_ENTRY PA, ATTR
PUT_64B \ATTR, (\PA) + 0x3
.endm
// Create an entry for a 1GB block.
.macro BLOCK_1GB PA, ATTR_HI, ATTR_LO
PUT_64B \ATTR_HI | ((\PA) >> 32), ((\PA) & 0xC0000000) | \ATTR_LO | 0x1
.endm
// Create an entry for a 2MB block.
.macro BLOCK_2MB PA, ATTR_HI, ATTR_LO
PUT_64B \ATTR_HI, ((\PA) & 0xFFE00000) | \ATTR_LO | 0x1
.endm
.section .init
.align 12
ttb0_base:
.set ADDR, 0x000
.rept 0x02
BLOCK_1GB (ADDR << 29), 0, 0x740
.set ADDR, ADDR+2
.endr
.rept 0x3E
BLOCK_1GB (ADDR << 29), 0, 0x74C
.set ADDR, ADDR+2
.endr
_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, =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
// 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
bl entry
.equ PSCI_SYSTEM_OFF, 0x84000008
.globl system_off
system_off:
ldr x0, =PSCI_SYSTEM_OFF
hvc #0

16
pim-os/src/uart.rs Normal file
View File

@@ -0,0 +1,16 @@
use core::{fmt::Write, ptr::write_volatile};
const UART0_ADDR: *mut u32 = 0x1c090000 as _;
pub struct Uart0;
impl Write for Uart0 {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
for &byte in s.as_bytes() {
unsafe {
write_volatile(UART0_ADDR, byte as _);
}
}
Ok(())
}
}