use core::arch::asm;
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PmuEvent {
NoEvent = 0,
Cycles = 1,
RetiredInst0 = 2,
RetiredInst1 = 3,
Branches0 = 4,
Branches1 = 5,
DcacheAccess0 = 6,
DcacheAccess1 = 7,
DcacheMisses0 = 8,
DcacheMisses1 = 9,
L2MissReq = 10,
L2MissReqRej = 11,
L2EvictReq = 12,
L2EvictReqRej = 13,
TlInst = 14,
TlOps = 15,
TsInst = 16,
TsOps = 17,
TfmaWaitTenb = 18,
TimaOps = 19,
TxFma3216Ops = 20,
TxFma32Ops = 21,
TxFmaIntOps = 22,
TransOps = 23,
ShortOps = 24,
MaskOps = 25,
TfmaInst = 26,
TreduceInst = 27,
TquantInst = 28,
}
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NeighborhoodEvent {
NoEvent = 0,
EtLinkSend = 1,
EtLinkRecv = 2,
CoopLoadSend = 3,
CoopLoadInterNeighSend = 4,
CoopLoadRecv = 5,
CoopStoreSend = 6,
CoopStoreRecv = 7,
IcacheReqSend = 8,
IcacheRespRecv = 9,
PtwReqSend = 10,
PtwRespRecv = 11,
FlnMsg = 12,
IcacheEtLinkSend = 13,
IcacheEtLinkRecv = 14,
IcacheL1Req = 15,
IcacheL1Resp = 16,
PtwEtLinkSend = 17,
PtwEtLinkRecv = 18,
EtLinkFifoIn = 21,
EtLinkBankFifoIn = 22,
EtLinkScUcIn = 23,
}
macro_rules! csr_read {
($csr:literal) => {{
let v: u64;
unsafe {
asm!(
".align 4",
concat!("csrrs {v0}, ", stringify!($csr), ", x0"),
concat!("csrrs {v1}, ", stringify!($csr), ", x0"),
concat!("csrrs {v2}, ", stringify!($csr), ", x0"),
concat!("csrrs {v}, ", stringify!($csr), ", x0"),
v0 = out(reg) _,
v1 = out(reg) _,
v2 = out(reg) _,
v = out(reg) v,
options(nostack, preserves_flags),
);
}
v
}};
}
#[inline(always)]
pub fn pmu_read_cycle() -> u64 {
csr_read!(0xC00)
}
#[inline(always)]
pub fn pmu_read_instret() -> u64 {
csr_read!(0xC02)
}
#[inline(always)]
#[rustfmt::skip] pub fn pmu_read(counter: u8) -> u64 {
match counter {
3 => csr_read!(0xC03),
4 => csr_read!(0xC04),
5 => csr_read!(0xC05),
6 => csr_read!(0xC06),
7 => csr_read!(0xC07),
8 => csr_read!(0xC08),
9 => csr_read!(0xC09),
10 => csr_read!(0xC0A),
11 => csr_read!(0xC0B),
12 => csr_read!(0xC0C),
13 => csr_read!(0xC0D),
14 => csr_read!(0xC0E),
15 => csr_read!(0xC0F),
16 => csr_read!(0xC10),
17 => csr_read!(0xC11),
18 => csr_read!(0xC12),
19 => csr_read!(0xC13),
20 => csr_read!(0xC14),
21 => csr_read!(0xC15),
22 => csr_read!(0xC16),
23 => csr_read!(0xC17),
24 => csr_read!(0xC18),
25 => csr_read!(0xC19),
26 => csr_read!(0xC1A),
27 => csr_read!(0xC1B),
28 => csr_read!(0xC1C),
29 => csr_read!(0xC1D),
30 => csr_read!(0xC1E),
31 => csr_read!(0xC1F),
_ => 0,
}
}
#[rustfmt::skip] const _: () = {
assert!(PmuEvent::NoEvent as u64 == 0);
assert!(PmuEvent::Cycles as u64 == 1);
assert!(PmuEvent::RetiredInst0 as u64 == 2);
assert!(PmuEvent::RetiredInst1 as u64 == 3);
assert!(PmuEvent::Branches0 as u64 == 4);
assert!(PmuEvent::Branches1 as u64 == 5);
assert!(PmuEvent::DcacheAccess0 as u64 == 6);
assert!(PmuEvent::DcacheAccess1 as u64 == 7);
assert!(PmuEvent::DcacheMisses0 as u64 == 8);
assert!(PmuEvent::DcacheMisses1 as u64 == 9);
assert!(PmuEvent::L2MissReq as u64 == 10);
assert!(PmuEvent::L2MissReqRej as u64 == 11);
assert!(PmuEvent::L2EvictReq as u64 == 12);
assert!(PmuEvent::L2EvictReqRej as u64 == 13);
assert!(PmuEvent::TlInst as u64 == 14);
assert!(PmuEvent::TlOps as u64 == 15);
assert!(PmuEvent::TsInst as u64 == 16);
assert!(PmuEvent::TsOps as u64 == 17);
assert!(PmuEvent::TfmaWaitTenb as u64 == 18);
assert!(PmuEvent::TimaOps as u64 == 19);
assert!(PmuEvent::TxFma3216Ops as u64 == 20);
assert!(PmuEvent::TxFma32Ops as u64 == 21);
assert!(PmuEvent::TxFmaIntOps as u64 == 22);
assert!(PmuEvent::TransOps as u64 == 23);
assert!(PmuEvent::ShortOps as u64 == 24);
assert!(PmuEvent::MaskOps as u64 == 25);
assert!(PmuEvent::TfmaInst as u64 == 26);
assert!(PmuEvent::TreduceInst as u64 == 27);
assert!(PmuEvent::TquantInst as u64 == 28);
assert!(NeighborhoodEvent::NoEvent as u64 == 0);
assert!(NeighborhoodEvent::EtLinkSend as u64 == 1);
assert!(NeighborhoodEvent::EtLinkRecv as u64 == 2);
assert!(NeighborhoodEvent::CoopLoadSend as u64 == 3);
assert!(NeighborhoodEvent::CoopLoadInterNeighSend as u64 == 4);
assert!(NeighborhoodEvent::CoopLoadRecv as u64 == 5);
assert!(NeighborhoodEvent::CoopStoreSend as u64 == 6);
assert!(NeighborhoodEvent::CoopStoreRecv as u64 == 7);
assert!(NeighborhoodEvent::IcacheReqSend as u64 == 8);
assert!(NeighborhoodEvent::IcacheRespRecv as u64 == 9);
assert!(NeighborhoodEvent::PtwReqSend as u64 == 10);
assert!(NeighborhoodEvent::PtwRespRecv as u64 == 11);
assert!(NeighborhoodEvent::FlnMsg as u64 == 12);
assert!(NeighborhoodEvent::IcacheEtLinkSend as u64 == 13);
assert!(NeighborhoodEvent::IcacheEtLinkRecv as u64 == 14);
assert!(NeighborhoodEvent::IcacheL1Req as u64 == 15);
assert!(NeighborhoodEvent::IcacheL1Resp as u64 == 16);
assert!(NeighborhoodEvent::PtwEtLinkSend as u64 == 17);
assert!(NeighborhoodEvent::PtwEtLinkRecv as u64 == 18);
assert!(NeighborhoodEvent::EtLinkFifoIn as u64 == 21);
assert!(NeighborhoodEvent::EtLinkBankFifoIn as u64 == 22);
assert!(NeighborhoodEvent::EtLinkScUcIn as u64 == 23);
};