Skip to content

Commit 9ca8756

Browse files
vlsunilpalmer-dabbelt
authored andcommitted
RISC-V: ACPI: RHCT: Add function to get CBO block sizes
Cache Block Operation (CBO) related block size in ACPI is provided by RHCT. Add support to read the CMO node in RHCT to get this information. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/20231018124007.1306159-4-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent a068352 commit 9ca8756

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

arch/riscv/include/asm/acpi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ int acpi_get_riscv_isa(struct acpi_table_header *table,
6666
unsigned int cpu, const char **isa);
6767

6868
static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; }
69+
void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size,
70+
u32 *cboz_size, u32 *cbop_size);
6971
#else
7072
static inline void acpi_init_rintc_map(void) { }
7173
static inline struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
@@ -79,6 +81,10 @@ static inline int acpi_get_riscv_isa(struct acpi_table_header *table,
7981
return -EINVAL;
8082
}
8183

84+
static inline void acpi_get_cbo_block_size(struct acpi_table_header *table,
85+
u32 *cbom_size, u32 *cboz_size,
86+
u32 *cbop_size) { }
87+
8288
#endif /* CONFIG_ACPI */
8389

8490
#endif /*_ASM_ACPI_H*/

drivers/acpi/riscv/rhct.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define pr_fmt(fmt) "ACPI: RHCT: " fmt
99

1010
#include <linux/acpi.h>
11+
#include <linux/bits.h>
1112

1213
static struct acpi_table_rhct *acpi_get_rhct(void)
1314
{
@@ -81,3 +82,89 @@ int acpi_get_riscv_isa(struct acpi_table_header *table, unsigned int cpu, const
8182

8283
return -1;
8384
}
85+
86+
static void acpi_parse_hart_info_cmo_node(struct acpi_table_rhct *rhct,
87+
struct acpi_rhct_hart_info *hart_info,
88+
u32 *cbom_size, u32 *cboz_size, u32 *cbop_size)
89+
{
90+
u32 size_hartinfo = sizeof(struct acpi_rhct_hart_info);
91+
u32 size_hdr = sizeof(struct acpi_rhct_node_header);
92+
struct acpi_rhct_node_header *ref_node;
93+
struct acpi_rhct_cmo_node *cmo_node;
94+
u32 *hart_info_node_offset;
95+
96+
hart_info_node_offset = ACPI_ADD_PTR(u32, hart_info, size_hartinfo);
97+
for (int i = 0; i < hart_info->num_offsets; i++) {
98+
ref_node = ACPI_ADD_PTR(struct acpi_rhct_node_header,
99+
rhct, hart_info_node_offset[i]);
100+
if (ref_node->type == ACPI_RHCT_NODE_TYPE_CMO) {
101+
cmo_node = ACPI_ADD_PTR(struct acpi_rhct_cmo_node,
102+
ref_node, size_hdr);
103+
if (cbom_size && cmo_node->cbom_size <= 30) {
104+
if (!*cbom_size)
105+
*cbom_size = BIT(cmo_node->cbom_size);
106+
else if (*cbom_size != BIT(cmo_node->cbom_size))
107+
pr_warn("CBOM size is not the same across harts\n");
108+
}
109+
110+
if (cboz_size && cmo_node->cboz_size <= 30) {
111+
if (!*cboz_size)
112+
*cboz_size = BIT(cmo_node->cboz_size);
113+
else if (*cboz_size != BIT(cmo_node->cboz_size))
114+
pr_warn("CBOZ size is not the same across harts\n");
115+
}
116+
117+
if (cbop_size && cmo_node->cbop_size <= 30) {
118+
if (!*cbop_size)
119+
*cbop_size = BIT(cmo_node->cbop_size);
120+
else if (*cbop_size != BIT(cmo_node->cbop_size))
121+
pr_warn("CBOP size is not the same across harts\n");
122+
}
123+
}
124+
}
125+
}
126+
127+
/*
128+
* During early boot, the caller should call acpi_get_table() and pass its pointer to
129+
* these functions (and free up later). At run time, since this table can be used
130+
* multiple times, pass NULL so that the table remains in memory.
131+
*/
132+
void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size,
133+
u32 *cboz_size, u32 *cbop_size)
134+
{
135+
u32 size_hdr = sizeof(struct acpi_rhct_node_header);
136+
struct acpi_rhct_node_header *node, *end;
137+
struct acpi_rhct_hart_info *hart_info;
138+
struct acpi_table_rhct *rhct;
139+
140+
if (acpi_disabled)
141+
return;
142+
143+
if (table) {
144+
rhct = (struct acpi_table_rhct *)table;
145+
} else {
146+
rhct = acpi_get_rhct();
147+
if (!rhct)
148+
return;
149+
}
150+
151+
if (cbom_size)
152+
*cbom_size = 0;
153+
154+
if (cboz_size)
155+
*cboz_size = 0;
156+
157+
if (cbop_size)
158+
*cbop_size = 0;
159+
160+
end = ACPI_ADD_PTR(struct acpi_rhct_node_header, rhct, rhct->header.length);
161+
for (node = ACPI_ADD_PTR(struct acpi_rhct_node_header, rhct, rhct->node_offset);
162+
node < end;
163+
node = ACPI_ADD_PTR(struct acpi_rhct_node_header, node, node->length)) {
164+
if (node->type == ACPI_RHCT_NODE_TYPE_HART_INFO) {
165+
hart_info = ACPI_ADD_PTR(struct acpi_rhct_hart_info, node, size_hdr);
166+
acpi_parse_hart_info_cmo_node(rhct, hart_info, cbom_size,
167+
cboz_size, cbop_size);
168+
}
169+
}
170+
}

0 commit comments

Comments
 (0)