Explorar o código

feat(prototyper): add firmware event statistics to the corresponding firmware event

Signed-off-by: guttatus <[email protected]>
guttatus hai 2 semanas
pai
achega
8538374efd

+ 4 - 0
prototyper/prototyper/src/sbi/ipi.rs

@@ -1,3 +1,4 @@
+use super::pmu::pmu_firmware_counter_increment;
 use crate::platform::PLATFORM;
 use crate::riscv::csr::stimecmp;
 use crate::riscv::current_hartid;
@@ -8,6 +9,7 @@ use crate::sbi::trap_stack::hart_context;
 use alloc::boxed::Box;
 use core::sync::atomic::Ordering::Relaxed;
 use rustsbi::{HartMask, SbiRet};
+use sbi_spec::pmu::firmware_event;
 use spin::Mutex;
 
 /// IPI type for supervisor software interrupt.
@@ -46,6 +48,7 @@ impl rustsbi::Timer for SbiIpi {
     /// Set timer value for current hart.
     #[inline]
     fn set_timer(&self, stime_value: u64) {
+        pmu_firmware_counter_increment(firmware_event::SET_TIMER);
         let hart_id = current_hartid();
         let uses_sstc = hart_extension_probe(hart_id, Extension::Sstc);
 
@@ -69,6 +72,7 @@ impl rustsbi::Ipi for SbiIpi {
     /// Send IPI to specified harts.
     #[inline]
     fn send_ipi(&self, hart_mask: rustsbi::HartMask) -> SbiRet {
+        pmu_firmware_counter_increment(firmware_event::IPI_SENT);
         let mut hart_mask = hart_mask;
 
         for hart_id in 0..=self.max_hart_id {

+ 9 - 0
prototyper/prototyper/src/sbi/rfence.rs

@@ -1,4 +1,5 @@
 use rustsbi::{HartMask, SbiRet};
+use sbi_spec::pmu::firmware_event;
 use spin::Mutex;
 
 use crate::cfg::{PAGE_SIZE, TLB_FLUSH_LIMIT};
@@ -10,6 +11,8 @@ use core::arch::asm;
 
 use core::sync::atomic::{AtomicU32, Ordering};
 
+use super::pmu::pmu_firmware_counter_increment;
+
 /// Cell for managing remote fence operations between harts.
 pub(crate) struct RFenceCell {
     // Queue of fence operations with source hart ID
@@ -198,6 +201,7 @@ fn remote_fence_process(rfence_ctx: RFenceContext, hart_mask: HartMask) -> SbiRe
 impl rustsbi::Fence for SbiRFence {
     /// Remote instruction fence for specified harts.
     fn remote_fence_i(&self, hart_mask: HartMask) -> SbiRet {
+        pmu_firmware_counter_increment(firmware_event::FENCE_I_SENT);
         remote_fence_process(
             RFenceContext {
                 start_addr: 0,
@@ -212,6 +216,7 @@ impl rustsbi::Fence for SbiRFence {
 
     /// Remote supervisor fence for virtual memory on specified harts.
     fn remote_sfence_vma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
+        pmu_firmware_counter_increment(firmware_event::SFENCE_VMA_SENT);
         let flush_size = match validate_address_range(start_addr, size) {
             Ok(size) => size,
             Err(e) => return e,
@@ -237,6 +242,7 @@ impl rustsbi::Fence for SbiRFence {
         size: usize,
         asid: usize,
     ) -> SbiRet {
+        pmu_firmware_counter_increment(firmware_event::SFENCE_VMA_ASID_SENT);
         let flush_size = match validate_address_range(start_addr, size) {
             Ok(size) => size,
             Err(e) => return e,
@@ -263,11 +269,13 @@ pub fn rfence_single_handler() {
         match ctx.op {
             // Handle instruction fence
             RFenceType::FenceI => unsafe {
+                pmu_firmware_counter_increment(firmware_event::FENCE_I_RECEIVED);
                 asm!("fence.i");
                 remote_rfence(id).unwrap().sub();
             },
             // Handle virtual memory address fence
             RFenceType::SFenceVma => {
+                pmu_firmware_counter_increment(firmware_event::SFENCE_VMA_RECEIVED);
                 // If the flush size is greater than the maximum limit then simply flush all
                 if (ctx.start_addr == 0 && ctx.size == 0)
                     || (ctx.size == usize::MAX)
@@ -288,6 +296,7 @@ pub fn rfence_single_handler() {
             }
             // Handle virtual memory address fence with ASID
             RFenceType::SFenceVmaAsid => {
+                pmu_firmware_counter_increment(firmware_event::SFENCE_VMA_ASID_RECEIVED);
                 let asid = ctx.asid;
                 // If the flush size is greater than the maximum limit then simply flush all
                 if (ctx.start_addr == 0 && ctx.size == 0)

+ 4 - 1
prototyper/prototyper/src/sbi/trap/handler.rs

@@ -2,6 +2,7 @@ use fast_trap::{EntireContext, EntireContextSeparated, EntireResult, FastContext
 use riscv::register::{mepc, mie, mstatus, mtval, satp, sstatus};
 use riscv_decode::{Instruction, decode};
 use rustsbi::RustSBI;
+use sbi_spec::pmu::firmware_event;
 
 use crate::platform::PLATFORM;
 use crate::riscv::csr::{CSR_TIME, CSR_TIMEH};
@@ -9,6 +10,7 @@ use crate::riscv::current_hartid;
 use crate::sbi::console;
 use crate::sbi::hsm::local_hsm;
 use crate::sbi::ipi;
+use crate::sbi::pmu::pmu_firmware_counter_increment;
 use crate::sbi::rfence;
 
 use super::helper::*;
@@ -34,6 +36,7 @@ pub fn msoft_ipi_handler() {
     let ipi_type = get_and_reset_ipi_type();
     // Handle supervisor software interrupt
     if (ipi_type & ipi::IPI_TYPE_SSOFT) != 0 {
+        pmu_firmware_counter_increment(firmware_event::IPI_RECEIVED);
         unsafe {
             riscv::register::mip::set_ssoft();
         }
@@ -67,7 +70,7 @@ pub fn msoft_handler(ctx: FastContext) -> FastResult {
             riscv::asm::wfi();
             ctx.restore()
         }
-        // Handle RFence
+        // Handle IPI and RFence
         _ => {
             msoft_ipi_handler();
             ctx.restore()

+ 2 - 0
prototyper/prototyper/src/sbi/trap/mod.rs

@@ -64,10 +64,12 @@ pub extern "C" fn fast_handler(
                     ctx.continue_with(handler::illegal_instruction_handler, ())
                 }
                 Trap::Exception(Exception::LoadMisaligned) => {
+                    pmu_firmware_counter_increment(firmware_event::MISALIGNED_LOAD);
                     save_regs(&mut ctx);
                     ctx.continue_with(handler::load_misaligned_handler, ())
                 }
                 Trap::Exception(Exception::StoreMisaligned) => {
+                    pmu_firmware_counter_increment(firmware_event::MISALIGNED_STORE);
                     save_regs(&mut ctx);
                     ctx.continue_with(handler::store_misaligned_handler, ())
                 }