Skip to content

Commit 44ce0b4

Browse files
committed
platform: xuantie: Harden xuantie link pmu init
Several robustness fixes in xuantie_link_pmu_device_init(): - Use `>= 0` to validate fdt_node_offset_by_compatible() result; the previous `> 0` check would miss a node at offset 0. - Iterate all instances of each PMU compatible instead of only the first one, so multi-cluster SoCs initialise every L3 PMU. - Skip nodes with status = "disabled" via fdt_node_is_enabled(). - Default-inhibit all counters (matches the kernel driver probe behaviour) so counters do not free-run between OpenSBI and kernel handoff. - Replace magic numbers with named macros (CNT_BITMAP, AUTHCR_AUTH, AUTHCR_INTPEND). - Bail out early if fdt_get_address_rw() returns NULL. Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
1 parent 64355e7 commit 44ce0b4

2 files changed

Lines changed: 44 additions & 18 deletions

File tree

platform/generic/include/xuantie/xuantie_link.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
/* HPCP reg */
99
#define XUANTIE_LINK_PMU_L3IMP 0x048
1010
#define XUANTIE_LINK_PMU_L3MAUTHCR 0x200
11+
#define XUANTIE_LINK_PMU_L3HAUTHCR 0x210 // XL300
12+
#define XUANTIE_LINK_PMU_L3SAUTHCR 0x220 // XL300
1113
#define XUANTIE_LINK_PMU_HPCPCOUNT0 0x500
1214
#define XUANTIE_LINK_PMU_HPCPCOUNT1 0x508
1315
#define XUANTIE_LINK_PMU_HPCPCOUNT2 0x510
@@ -28,6 +30,12 @@
2830
#define XUANTIE_LINK_PMU_HPCPINTPEND 0x5e8
2931
#define XUANTIE_LINK_PMU_VENDOR_N_IMP_ID 0x600 // XL300
3032

33+
#define XUANTIE_LINK_PMU_NUM_COUNTERS 6
34+
#define XUANTIE_LINK_PMU_CNT_BITMAP GENMASK_ULL(XUANTIE_LINK_PMU_NUM_COUNTERS - 1, 0)
35+
#define XUANTIE_LINK_PMU_L3AUTHCR_ALLAU BIT_ULL(0)
36+
#define XUANTIE_LINK_PMU_AUTHCR_AUTH BIT_ULL(40)
37+
#define XUANTIE_LINK_PMU_AUTHCR_INTPEND BIT_ULL(32)
38+
3139
/* HPCP dev type */
3240
#define XUANTIE_LINK_DEV_TYPE_XL100 100
3341
#define XUANTIE_LINK_DEV_TYPE_XL200 200

platform/generic/xuantie/xuantie_link.c

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,47 @@
1212
int xuantie_link_pmu_device_init(void)
1313
{
1414
#if __riscv_xlen == 64
15-
int nodeoffset, rc, dev_type;
16-
uint64_t addr;
15+
static const struct {
16+
const char *compat;
17+
int dev_type;
18+
} pmu_match[] = {
19+
{ "xuantie,xl100-pmu", XUANTIE_LINK_DEV_TYPE_XL100 },
20+
{ "xuantie,xl200-pmu", XUANTIE_LINK_DEV_TYPE_XL200 },
21+
{ "xuantie,xl300-pmu", XUANTIE_LINK_DEV_TYPE_XL300 },
22+
};
1723
void *fdt = fdt_get_address_rw();
24+
bool found = false;
25+
unsigned int i;
1826

19-
if ((nodeoffset = fdt_node_offset_by_compatible(fdt, -1, "xuantie,xl100-pmu")) > 0)
20-
dev_type = XUANTIE_LINK_DEV_TYPE_XL100;
21-
else if ((nodeoffset = fdt_node_offset_by_compatible(fdt, -1, "xuantie,xl200-pmu")) > 0)
22-
dev_type = XUANTIE_LINK_DEV_TYPE_XL200;
23-
else if ((nodeoffset = fdt_node_offset_by_compatible(fdt, -1, "xuantie,xl300-pmu")) > 0)
24-
dev_type = XUANTIE_LINK_DEV_TYPE_XL300;
25-
else
27+
if (!fdt)
2628
return SBI_ENODEV;
2729

28-
rc = fdt_get_node_addr_size(fdt, nodeoffset, 0, &addr, NULL);
29-
if (rc)
30-
return SBI_ENODEV;
30+
for (i = 0; i < array_size(pmu_match); i++) {
31+
int nodeoffset = -1;
32+
33+
while ((nodeoffset = fdt_node_offset_by_compatible(
34+
fdt, nodeoffset, pmu_match[i].compat)) >= 0) {
35+
uint64_t addr;
36+
37+
if (!fdt_node_is_enabled(fdt, nodeoffset))
38+
continue;
39+
if (fdt_get_node_addr_size(fdt, nodeoffset, 0, &addr, NULL))
40+
continue;
3141

32-
if (dev_type == XUANTIE_LINK_DEV_TYPE_XL300)
33-
writeq(BIT_ULL(40) | BIT_ULL(32) | 0x3f, (void *)addr + XUANTIE_LINK_PMU_HPCPHAUTHCR);
34-
writeq(0x3f, (void *)addr + XUANTIE_LINK_PMU_HPCPMAUTHCR);
35-
writeq(0x3f, (void *)addr + XUANTIE_LINK_PMU_HPCPSAUTHCR);
36-
writeq(0x1, (void *)addr + XUANTIE_LINK_PMU_L3MAUTHCR);
37-
writeq(0x0, (void *)addr + XUANTIE_LINK_PMU_HPCPINHIBIT);
42+
if (pmu_match[i].dev_type == XUANTIE_LINK_DEV_TYPE_XL300)
43+
writeq(XUANTIE_LINK_PMU_AUTHCR_AUTH |
44+
XUANTIE_LINK_PMU_AUTHCR_INTPEND |
45+
XUANTIE_LINK_PMU_CNT_BITMAP,
46+
(void *)addr + XUANTIE_LINK_PMU_HPCPHAUTHCR);
47+
writeq(XUANTIE_LINK_PMU_CNT_BITMAP, (void *)addr + XUANTIE_LINK_PMU_HPCPMAUTHCR);
48+
writeq(XUANTIE_LINK_PMU_L3AUTHCR_ALLAU, (void *)addr + XUANTIE_LINK_PMU_L3MAUTHCR);
49+
writeq(XUANTIE_LINK_PMU_CNT_BITMAP, (void *)addr + XUANTIE_LINK_PMU_HPCPINHIBIT);
50+
found = true;
51+
}
52+
}
53+
54+
if (!found)
55+
return SBI_ENODEV;
3856
#endif
3957
return SBI_OK;
4058
}

0 commit comments

Comments
 (0)