diff options
author | Tzung-Bi Shih <tzungbi@chromium.org> | 2020-11-27 13:01:11 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-11-27 13:41:44 +0000 |
commit | d0775dff769aceae002671c9d72a9a9823aedbfe (patch) | |
tree | e1ff9193db41e02e211fe4df592eb569d0a870ed | |
parent | d1df46fd72a668cfaaecbdca8868f13db5164af0 (diff) | |
download | chrome-ec-d0775dff769aceae002671c9d72a9a9823aedbfe.tar.gz |
chip/mt8192_scp: support PMU counter
Supports performance monitor unit counters.
Introduces new console commands:
- enable_pmu
- disable_pmu
- show_pmu
> enable_pmu X
Parameter 1 invalid
Usage: enable_pmu [I | D | C]
> enable_pmu i
select "I"
> show_pmu
cycles: 842443131
retired instructions: 32855
I-cache:
access: 22324
miss: 0 (0.0%)
non-cacheable I: 0
> enable_pmu d
select "D"
> show_pmu
cycles: 1137656582
retired instructions: 36619
D-cache:
access: 13779
miss: 0 (0.0%)
non-cacheable D: 1072
> enable_pmu c
select "C"
> show_pmu
cycles: 2656349519
retired instructions: 74746
control transfer instruction:
total: 20767
miss-predict: 13346 (64.26%)
interrupts: 262
BRANCH=none
BUG=b:172988651
TEST=define DEBUG && make BOARD=asurada_scp
Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org>
Change-Id: I461ae51b84badb25e9b50ef1af7e3a81139cea47
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2562910
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
-rw-r--r-- | chip/mt8192_scp/cache.c | 158 | ||||
-rw-r--r-- | chip/mt8192_scp/csr.h | 24 |
2 files changed, 182 insertions, 0 deletions
diff --git a/chip/mt8192_scp/cache.c b/chip/mt8192_scp/cache.c index 11051e6d18..c9f593fc2a 100644 --- a/chip/mt8192_scp/cache.c +++ b/chip/mt8192_scp/cache.c @@ -6,6 +6,7 @@ #include "cache.h" #include "common.h" #include "compile_time_macros.h" +#include "console.h" #include "csr.h" #include "util.h" @@ -140,3 +141,160 @@ void cache_init(void) /* fence */ asm volatile ("fence.i" ::: "memory"); } + +#ifdef DEBUG +/* + * I for I-cache + * D for D-cache + * C for control transfer instructions (branch, jump, ret, interrupt, ...) + */ +static enum { + PMU_SELECT_I = 0, + PMU_SELECT_D, + PMU_SELECT_C +} pmu_select; + +int command_enable_pmu(int argc, char **argv) +{ + static const char * const selectors[] = { + [PMU_SELECT_I] = "I", + [PMU_SELECT_D] = "D", + [PMU_SELECT_C] = "C", + }; + int i; + + if (argc != 2) + return EC_ERROR_PARAM1; + + for (i = 0; i < ARRAY_SIZE(selectors); ++i) { + if (strcasecmp(argv[1], selectors[i]) == 0) { + pmu_select = i; + break; + } + } + if (i >= ARRAY_SIZE(selectors)) + return EC_ERROR_PARAM1; + + ccprintf("select \"%s\"\n", selectors[pmu_select]); + + /* disable all PMU */ + clear_csr(CSR_PMU_MPMUCTR, + CSR_PMU_MPMUCTR_C | CSR_PMU_MPMUCTR_I | + CSR_PMU_MPMUCTR_H3 | CSR_PMU_MPMUCTR_H4 | + CSR_PMU_MPMUCTR_H5); + + /* reset cycle count */ + write_csr(CSR_PMU_MCYCLE, 0); + write_csr(CSR_PMU_MCYCLEH, 0); + /* reset retired-instruction count */ + write_csr(CSR_PMU_MINSTRET, 0); + write_csr(CSR_PMU_MINSTRETH, 0); + /* reset counter{3,4,5} */ + write_csr(CSR_PMU_MHPMCOUNTER3, 0); + write_csr(CSR_PMU_MHPMCOUNTER3H, 0); + write_csr(CSR_PMU_MHPMCOUNTER4, 0); + write_csr(CSR_PMU_MHPMCOUNTER4H, 0); + write_csr(CSR_PMU_MHPMCOUNTER5, 0); + write_csr(CSR_PMU_MHPMCOUNTER5H, 0); + + /* select different event IDs for counter{3,4,5} */ + switch (pmu_select) { + case PMU_SELECT_I: + /* I-cache access count */ + write_csr(CSR_PMU_MHPMEVENT3, 1); + /* I-cache miss count */ + write_csr(CSR_PMU_MHPMEVENT4, 3); + /* noncacheable I-AXI access count */ + write_csr(CSR_PMU_MHPMEVENT5, 5); + break; + case PMU_SELECT_D: + /* D-cache access count */ + write_csr(CSR_PMU_MHPMEVENT3, 11); + /* D-cache miss count */ + write_csr(CSR_PMU_MHPMEVENT4, 12); + /* noncacheable D-AXI access count */ + write_csr(CSR_PMU_MHPMEVENT5, 14); + break; + case PMU_SELECT_C: + /* control transfer instruction count */ + write_csr(CSR_PMU_MHPMEVENT3, 27); + /* control transfer miss-predict count */ + write_csr(CSR_PMU_MHPMEVENT4, 28); + /* interrupt count */ + write_csr(CSR_PMU_MHPMEVENT5, 29); + break; + } + + /* enable all PMU */ + set_csr(CSR_PMU_MPMUCTR, + CSR_PMU_MPMUCTR_C | CSR_PMU_MPMUCTR_I | + CSR_PMU_MPMUCTR_H3 | CSR_PMU_MPMUCTR_H4 | + CSR_PMU_MPMUCTR_H5); + + return EC_SUCCESS; +} +DECLARE_SAFE_CONSOLE_COMMAND(enable_pmu, command_enable_pmu, + "[I | D | C]", "Enable PMU"); + +int command_disable_pmu(int argc, char **argv) +{ + clear_csr(CSR_PMU_MPMUCTR, + CSR_PMU_MPMUCTR_C | CSR_PMU_MPMUCTR_I | + CSR_PMU_MPMUCTR_H3 | CSR_PMU_MPMUCTR_H4 | + CSR_PMU_MPMUCTR_H5); + return EC_SUCCESS; +} +DECLARE_SAFE_CONSOLE_COMMAND(disable_pmu, command_disable_pmu, + NULL, "Disable PMU"); + +int command_show_pmu(int argc, char **argv) +{ + uint64_t val3, val4, val5; + uint32_t p; + + val3 = ((uint64_t)read_csr(CSR_PMU_MCYCLEH) << 32) | + read_csr(CSR_PMU_MCYCLE); + ccprintf("cycles: %lld\n", val3); + + val3 = ((uint64_t)read_csr(CSR_PMU_MINSTRETH) << 32) | + read_csr(CSR_PMU_MINSTRET); + ccprintf("retired instructions: %lld\n", val3); + + val3 = ((uint64_t)read_csr(CSR_PMU_MHPMCOUNTER3H) << 32) | + read_csr(CSR_PMU_MHPMCOUNTER3); + val4 = ((uint64_t)read_csr(CSR_PMU_MHPMCOUNTER4H) << 32) | + read_csr(CSR_PMU_MHPMCOUNTER4); + val5 = ((uint64_t)read_csr(CSR_PMU_MHPMCOUNTER5H) << 32) | + read_csr(CSR_PMU_MHPMCOUNTER5); + + if (val3) + p = val4 * 10000 / val3; + else + p = 0; + + switch (pmu_select) { + case PMU_SELECT_I: + ccprintf("I-cache:\n"); + ccprintf(" access: %lld\n", val3); + ccprintf(" miss: %lld (%d.%d%%)\n", val4, p / 100, p % 100); + ccprintf("non-cacheable I: %lld\n", val5); + break; + case PMU_SELECT_D: + ccprintf("D-cache:\n"); + ccprintf(" access: %lld\n", val3); + ccprintf(" miss: %lld (%d.%d%%)\n", val4, p / 100, p % 100); + ccprintf("non-cacheable D: %lld\n", val5); + break; + case PMU_SELECT_C: + ccprintf("control transfer instruction:\n"); + ccprintf(" total: %lld\n", val3); + ccprintf(" miss-predict: %lld (%d.%d%%)\n", + val4, p / 100, p % 100); + ccprintf("interrupts: %lld\n", val5); + break; + } + + return EC_SUCCESS; +} +DECLARE_SAFE_CONSOLE_COMMAND(show_pmu, command_show_pmu, NULL, "Show PMU"); +#endif diff --git a/chip/mt8192_scp/csr.h b/chip/mt8192_scp/csr.h index e43c84294a..7c767d0592 100644 --- a/chip/mt8192_scp/csr.h +++ b/chip/mt8192_scp/csr.h @@ -84,4 +84,28 @@ static inline uint32_t clear_csr(uint32_t reg, uint32_t bit) /* Bufferable */ #define MPU_ATTR_B BIT(9) +/* PMU */ +#define CSR_PMU_MPMUCTR (0xbc0) +#define CSR_PMU_MPMUCTR_C BIT(0) +#define CSR_PMU_MPMUCTR_I BIT(1) +#define CSR_PMU_MPMUCTR_H3 BIT(2) +#define CSR_PMU_MPMUCTR_H4 BIT(3) +#define CSR_PMU_MPMUCTR_H5 BIT(4) + +#define CSR_PMU_MCYCLE (0xb00) +#define CSR_PMU_MINSTRET (0xb02) +#define CSR_PMU_MHPMCOUNTER3 (0xb03) +#define CSR_PMU_MHPMCOUNTER4 (0xb04) +#define CSR_PMU_MHPMCOUNTER5 (0xb05) + +#define CSR_PMU_MCYCLEH (0xb80) +#define CSR_PMU_MINSTRETH (0xb82) +#define CSR_PMU_MHPMCOUNTER3H (0xb83) +#define CSR_PMU_MHPMCOUNTER4H (0xb84) +#define CSR_PMU_MHPMCOUNTER5H (0xb85) + +#define CSR_PMU_MHPMEVENT3 (0x323) +#define CSR_PMU_MHPMEVENT4 (0x324) +#define CSR_PMU_MHPMEVENT5 (0x325) + #endif /* __CROS_EC_CSR_H */ |