Skip to content

Commit ce46a9f

Browse files
author
Esther Z
committed
lib: sbi: Add Sscpuutil (CPU Utilization) extension support
Add support for the Sscpuutil extension which enables frequency- invariant CPU utilization tracking by the OS scheduler. The extension provides dedicated CSR counters (corecyc at 0xc30 and acttime at 0xc31) for computing CPU utilization. Their ratio gives: effective_freq = ref_freq * (Dcycle / Dacttime) Key implementation details: - Detect Sscpuutil by probing CSR_MACTTIME (0xb31). - Enable S/U-mode access via mcpuutilen (0x320) and scpuutilen (0x120). Signed-off-by: Esther Z <zhangfengxue.zfx@alibaba-inc.com>
1 parent a32a910 commit ce46a9f

3 files changed

Lines changed: 64 additions & 2 deletions

File tree

include/sbi/riscv_encoding.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@
265265
#define CSR_CYCLE 0xc00
266266
#define CSR_TIME 0xc01
267267
#define CSR_INSTRET 0xc02
268+
269+
/* Sscpuutil: CPU active time counter (address TBD, using placeholder) */
270+
#define CSR_ACTTIME 0xc31
271+
#define CSR_ACTTIMEH 0xcb1
268272
#define CSR_HPMCOUNTER3 0xc03
269273
#define CSR_HPMCOUNTER4 0xc04
270274
#define CSR_HPMCOUNTER5 0xc05
@@ -612,6 +616,12 @@
612616
#define CSR_MHPMCOUNTER29 0xb1d
613617
#define CSR_MHPMCOUNTER30 0xb1e
614618
#define CSR_MHPMCOUNTER31 0xb1f
619+
620+
/* Sscpuutil: M-mode CPU active time counter (address TBD, using placeholder) */
621+
#define CSR_MACTTIME 0xb31
622+
#define CSR_MACTTIMEH 0xbb1
623+
#define CSR_MCPUUTILEN 0x320
624+
#define CSR_SCPUUTILEN 0x120
615625
#define CSR_MCYCLEH 0xb80
616626
#define CSR_MINSTRETH 0xb82
617627
#define CSR_MHPMCOUNTER3H 0xb83
@@ -827,6 +837,14 @@
827837
#define SMSTATEEN0_HSENVCFG (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
828838
#define SMSTATEEN_STATEN_SHIFT 63
829839
#define SMSTATEEN_STATEN (_ULL(1) << SMSTATEEN_STATEN_SHIFT)
840+
/* Sscpuutil: acttime access control (bit position TBD) */
841+
#define SMSTATEEN0_CPUUTIL_SHIFT 55
842+
#define SMSTATEEN0_CPUUTIL (_ULL(1) << SMSTATEEN0_CPUUTIL_SHIFT)
843+
844+
/* Sscpuutil mcpuutilen enable bits */
845+
#define CPUUTILEN_CORECYC (1UL << 0)
846+
#define CPUUTILEN_ACTTIME (1UL << 1)
847+
#define CPUUTILEN_ALL (CPUUTILEN_CORECYC | CPUUTILEN_ACTTIME)
830848

831849
/* ===== Instruction Encodings ===== */
832850

include/sbi/sbi_hart.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ enum sbi_hart_extensions {
8181
SBI_HART_EXT_SSCTR,
8282
/** HART has Ssstateen extension **/
8383
SBI_HART_EXT_SSSTATEEN,
84+
/** Hart has Sscpuutil extension (CPU utilization) */
85+
SBI_HART_EXT_SSCPUUTIL,
8486

8587
/** Maximum index of Hart extension */
8688
SBI_HART_EXT_MAX,

lib/sbi/sbi_hart.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,17 @@ static void mstatus_init(struct sbi_scratch *scratch)
6363
csr_write(CSR_MCOUNTEREN, -1);
6464

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

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

122+
if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCPUUTIL))
123+
mstateen_val |= SMSTATEEN0_CPUUTIL;
124+
else
125+
mstateen_val &= ~SMSTATEEN0_CPUUTIL;
126+
113127
csr_write64(CSR_MSTATEEN0, mstateen_val);
114128
csr_write64(CSR_MSTATEEN1, SMSTATEEN_STATEN);
115129
csr_write64(CSR_MSTATEEN2, SMSTATEEN_STATEN);
116130
csr_write64(CSR_MSTATEEN3, SMSTATEEN_STATEN);
117131
}
118132

133+
/*
134+
* For platforms with dedicated mcpuutilen (Sscpuutil-style),
135+
* enable both counters for S/U-mode access.
136+
* Directly probe the CSR since extension detection may not
137+
* cover all naming variants (sscpuutil vs sscpuutil).
138+
*/
139+
{
140+
struct sbi_trap_info __trap = {0};
141+
csr_read_allowed(CSR_MCPUUTILEN, &__trap);
142+
if (!__trap.cause) {
143+
csr_write(CSR_MCPUUTILEN, CPUUTILEN_ALL);
144+
csr_write(CSR_SCPUUTILEN, CPUUTILEN_ALL);
145+
sbi_printf("mcpuutilen/scpuutilen: set to 0x%lx (direct probe)\n",
146+
(unsigned long)CPUUTILEN_ALL);
147+
} else {
148+
sbi_printf("mcpuutilen: CSR not present (cause=%lu)\n",
149+
__trap.cause);
150+
}
151+
}
152+
119153
if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSSTATEEN)) {
120154
if (misa_extension('S')) {
121155
csr_write(CSR_SSTATEEN0, 0);
@@ -715,6 +749,7 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
715749
__SBI_HART_EXT_DATA(smctr, SBI_HART_EXT_SMCTR),
716750
__SBI_HART_EXT_DATA(ssctr, SBI_HART_EXT_SSCTR),
717751
__SBI_HART_EXT_DATA(ssstateen, SBI_HART_EXT_SSSTATEEN),
752+
__SBI_HART_EXT_DATA(sscpuutil, SBI_HART_EXT_SSCPUUTIL),
718753
};
719754

720755
_Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
@@ -959,6 +994,13 @@ static int hart_detect_features(struct sbi_scratch *scratch)
959994
}
960995

961996
/* Counter overflow/filtering is not useful without mcounter/inhibit */
997+
/* Detect if hart supports Sscpuutil (CPU utilization) */
998+
csr_read_allowed(CSR_MACTTIME, &trap);
999+
sbi_printf("SSCPUUTIL: CSR_MACTTIME(0xb21) probe: trap.cause=%lu\n",
1000+
trap.cause);
1001+
__check_ext_csr(SBI_HART_PRIV_VER_1_12,
1002+
CSR_MACTTIME, SBI_HART_EXT_SSCPUUTIL);
1003+
9621004
/* Detect if hart supports sscofpmf */
9631005
__check_ext_csr(SBI_HART_PRIV_VER_1_11,
9641006
CSR_SCOUNTOVF, SBI_HART_EXT_SSCOFPMF);

0 commit comments

Comments
 (0)