summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorTzung-Bi Shih <tzungbi@chromium.org>2020-11-27 13:01:11 +0800
committerCommit Bot <commit-bot@chromium.org>2020-11-27 13:41:44 +0000
commitd0775dff769aceae002671c9d72a9a9823aedbfe (patch)
treee1ff9193db41e02e211fe4df592eb569d0a870ed /chip
parentd1df46fd72a668cfaaecbdca8868f13db5164af0 (diff)
downloadchrome-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>
Diffstat (limited to 'chip')
-rw-r--r--chip/mt8192_scp/cache.c158
-rw-r--r--chip/mt8192_scp/csr.h24
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 */