Skip to content

Commit f995611

Browse files
vlsunilpalmer-dabbelt
authored andcommitted
RISC-V: ACPI: Cache and retrieve the RINTC structure
RINTC structures in the MADT provide mapping between the hartid and the CPU. This is required many times even at run time like cpuinfo. So, instead of parsing the ACPI table every time, cache the RINTC structures and provide a function to get the correct RINTC structure for a given cpu. Signed-off-by: Sunil V L <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 724f4c0 commit f995611

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

arch/riscv/include/asm/acpi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ static inline bool acpi_has_cpu_in_madt(void)
5959

6060
static inline void arch_fix_phys_package_id(int num, u32 slot) { }
6161

62+
void acpi_init_rintc_map(void);
63+
struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
64+
u32 get_acpi_id_for_cpu(int cpu);
65+
#else
66+
static inline void acpi_init_rintc_map(void) { }
67+
static inline struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
68+
{
69+
return NULL;
70+
}
71+
6272
#endif /* CONFIG_ACPI */
6373

6474
#endif /*_ASM_ACPI_H*/

arch/riscv/kernel/acpi.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ static bool param_acpi_off __initdata;
2929
static bool param_acpi_on __initdata;
3030
static bool param_acpi_force __initdata;
3131

32+
static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
33+
3234
static int __init parse_acpi(char *arg)
3335
{
3436
if (!arg)
@@ -150,6 +152,49 @@ void __init acpi_boot_table_init(void)
150152
}
151153
}
152154

155+
static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
156+
{
157+
struct acpi_madt_rintc *rintc = (struct acpi_madt_rintc *)header;
158+
int cpuid;
159+
160+
if (!(rintc->flags & ACPI_MADT_ENABLED))
161+
return 0;
162+
163+
cpuid = riscv_hartid_to_cpuid(rintc->hart_id);
164+
/*
165+
* When CONFIG_SMP is disabled, mapping won't be created for
166+
* all cpus.
167+
* CPUs more than num_possible_cpus, will be ignored.
168+
*/
169+
if (cpuid >= 0 && cpuid < num_possible_cpus())
170+
cpu_madt_rintc[cpuid] = *rintc;
171+
172+
return 0;
173+
}
174+
175+
/*
176+
* Instead of parsing (and freeing) the ACPI table, cache
177+
* the RINTC structures since they are frequently used
178+
* like in cpuinfo.
179+
*/
180+
void __init acpi_init_rintc_map(void)
181+
{
182+
if (acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_madt_rintc, 0) <= 0) {
183+
pr_err("No valid RINTC entries exist\n");
184+
BUG();
185+
}
186+
}
187+
188+
struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
189+
{
190+
return &cpu_madt_rintc[cpu];
191+
}
192+
193+
u32 get_acpi_id_for_cpu(int cpu)
194+
{
195+
return acpi_cpu_get_madt_rintc(cpu)->uid;
196+
}
197+
153198
/*
154199
* __acpi_map_table() will be called before paging_init(), so early_ioremap()
155200
* or early_memremap() should be called here to for ACPI table mapping.

arch/riscv/kernel/setup.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/efi.h>
2323
#include <linux/crash_dump.h>
2424

25+
#include <asm/acpi.h>
2526
#include <asm/alternative.h>
2627
#include <asm/cacheflush.h>
2728
#include <asm/cpu_ops.h>
@@ -298,6 +299,9 @@ void __init setup_arch(char **cmdline_p)
298299
setup_smp();
299300
#endif
300301

302+
if (!acpi_disabled)
303+
acpi_init_rintc_map();
304+
301305
riscv_init_cbo_blocksizes();
302306
riscv_fill_hwcap();
303307
apply_boot_alternatives();

0 commit comments

Comments
 (0)