Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions include/sbi/riscv_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@
#define CSR_CYCLE 0xc00
#define CSR_TIME 0xc01
#define CSR_INSTRET 0xc02

/* Sscpuutil: CPU active time counter (address TBD, using placeholder) */
#define CSR_ACTTIME 0xc31
#define CSR_ACTTIMEH 0xcb1
#define CSR_HPMCOUNTER3 0xc03
#define CSR_HPMCOUNTER4 0xc04
#define CSR_HPMCOUNTER5 0xc05
Expand Down Expand Up @@ -612,6 +616,12 @@
#define CSR_MHPMCOUNTER29 0xb1d
#define CSR_MHPMCOUNTER30 0xb1e
#define CSR_MHPMCOUNTER31 0xb1f

/* Sscpuutil: M-mode CPU active time counter (address TBD, using placeholder) */
#define CSR_MACTTIME 0xb31
#define CSR_MACTTIMEH 0xbb1
#define CSR_MCPUUTILEN 0x320
#define CSR_SCPUUTILEN 0x120
#define CSR_MCYCLEH 0xb80
#define CSR_MINSTRETH 0xb82
#define CSR_MHPMCOUNTER3H 0xb83
Expand Down Expand Up @@ -827,6 +837,14 @@
#define SMSTATEEN0_HSENVCFG (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
#define SMSTATEEN_STATEN_SHIFT 63
#define SMSTATEEN_STATEN (_ULL(1) << SMSTATEEN_STATEN_SHIFT)
/* Sscpuutil: acttime access control (bit position TBD) */
#define SMSTATEEN0_CPUUTIL_SHIFT 55
#define SMSTATEEN0_CPUUTIL (_ULL(1) << SMSTATEEN0_CPUUTIL_SHIFT)

/* Sscpuutil mcpuutilen enable bits */
#define CPUUTILEN_CORECYC (1UL << 0)
#define CPUUTILEN_ACTTIME (1UL << 1)
#define CPUUTILEN_ALL (CPUUTILEN_CORECYC | CPUUTILEN_ACTTIME)

/* ===== Instruction Encodings ===== */

Expand Down
2 changes: 2 additions & 0 deletions include/sbi/sbi_hart.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ enum sbi_hart_extensions {
SBI_HART_EXT_SSCTR,
/** HART has Ssstateen extension **/
SBI_HART_EXT_SSSTATEEN,
/** Hart has Sscpuutil extension (CPU utilization) */
SBI_HART_EXT_SSCPUUTIL,

/** Maximum index of Hart extension */
SBI_HART_EXT_MAX,
Expand Down
46 changes: 44 additions & 2 deletions lib/sbi/sbi_hart.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,17 @@ static void mstatus_init(struct sbi_scratch *scratch)
csr_write(CSR_MCOUNTEREN, -1);

/* All programmable counters will start running at runtime after S-mode request */
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11)
csr_write(CSR_MCOUNTINHIBIT, 0xFFFFFFF8);
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11) {
unsigned long inhibit_val = 0xFFFFFFF8;
/*
* When Sscpuutil is available, keep cycle running
* (clear mcountinhibit.CY) so that the frequency ratio
* Dcycle/Dacttime remains valid.
*/
if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCPUUTIL))
inhibit_val &= ~(1UL << 0);
csr_write(CSR_MCOUNTINHIBIT, inhibit_val);
}

/**
* The mhpmeventn[h] CSR should be initialized with interrupt disabled
Expand Down Expand Up @@ -110,12 +119,37 @@ static void mstatus_init(struct sbi_scratch *scratch)
else
mstateen_val &= ~SMSTATEEN0_CTR;

if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCPUUTIL))
mstateen_val |= SMSTATEEN0_CPUUTIL;
else
mstateen_val &= ~SMSTATEEN0_CPUUTIL;

csr_write64(CSR_MSTATEEN0, mstateen_val);
csr_write64(CSR_MSTATEEN1, SMSTATEEN_STATEN);
csr_write64(CSR_MSTATEEN2, SMSTATEEN_STATEN);
csr_write64(CSR_MSTATEEN3, SMSTATEEN_STATEN);
}

/*
* For platforms with dedicated mcpuutilen (Sscpuutil-style),
* enable both counters for S/U-mode access.
* Directly probe the CSR since extension detection may not
* cover all naming variants (sscpuutil vs sscpuutil).
*/
{
struct sbi_trap_info __trap = {0};
csr_read_allowed(CSR_MCPUUTILEN, &__trap);
if (!__trap.cause) {
csr_write(CSR_MCPUUTILEN, CPUUTILEN_ALL);
csr_write(CSR_SCPUUTILEN, CPUUTILEN_ALL);
sbi_printf("mcpuutilen/scpuutilen: set to 0x%lx (direct probe)\n",
(unsigned long)CPUUTILEN_ALL);
} else {
sbi_printf("mcpuutilen: CSR not present (cause=%lu)\n",
__trap.cause);
}
}

if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSSTATEEN)) {
if (misa_extension('S')) {
csr_write(CSR_SSTATEEN0, 0);
Expand Down Expand Up @@ -715,6 +749,7 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
__SBI_HART_EXT_DATA(smctr, SBI_HART_EXT_SMCTR),
__SBI_HART_EXT_DATA(ssctr, SBI_HART_EXT_SSCTR),
__SBI_HART_EXT_DATA(ssstateen, SBI_HART_EXT_SSSTATEEN),
__SBI_HART_EXT_DATA(sscpuutil, SBI_HART_EXT_SSCPUUTIL),
};

_Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
Expand Down Expand Up @@ -959,6 +994,13 @@ static int hart_detect_features(struct sbi_scratch *scratch)
}

/* Counter overflow/filtering is not useful without mcounter/inhibit */
/* Detect if hart supports Sscpuutil (CPU utilization) */
csr_read_allowed(CSR_MACTTIME, &trap);
sbi_printf("SSCPUUTIL: CSR_MACTTIME(0xb21) probe: trap.cause=%lu\n",
trap.cause);
__check_ext_csr(SBI_HART_PRIV_VER_1_12,
CSR_MACTTIME, SBI_HART_EXT_SSCPUUTIL);

/* Detect if hart supports sscofpmf */
__check_ext_csr(SBI_HART_PRIV_VER_1_11,
CSR_SCOUNTOVF, SBI_HART_EXT_SSCOFPMF);
Expand Down
Loading