hw/riscv/virt: virt-acpi-build.c: Add RHCT Table

RISC-V ACPI platforms need to provide RISC-V Hart Capabilities
Table (RHCT). Add this to the ACPI tables.

Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20230302091212.999767-7-sunilvl@ventanamicro.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
Sunil V L 2023-03-02 14:42:10 +05:30 committed by Palmer Dabbelt
parent 6cc40ea211
commit ebfd392893
No known key found for this signature in database
GPG key ID: 2E1319F35FBB1889

View file

@ -33,6 +33,7 @@
#include "migration/vmstate.h"
#include "hw/riscv/virt.h"
#include "hw/riscv/numa.h"
#include "hw/intc/riscv_aclint.h"
#define ACPI_BUILD_TABLE_SIZE 0x20000
@ -111,6 +112,80 @@ static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
aml_append(scope, dev);
}
/* RHCT Node[N] starts at offset 56 */
#define RHCT_NODE_ARRAY_OFFSET 56
/*
* ACPI spec, Revision 6.5+
* 5.2.36 RISC-V Hart Capabilities Table (RHCT)
* REF: https://github.com/riscv-non-isa/riscv-acpi/issues/16
* https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
*/
static void build_rhct(GArray *table_data,
BIOSLinker *linker,
RISCVVirtState *s)
{
MachineClass *mc = MACHINE_GET_CLASS(s);
MachineState *ms = MACHINE(s);
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
size_t len, aligned_len;
uint32_t isa_offset, num_rhct_nodes;
RISCVCPU *cpu;
char *isa;
AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id,
.oem_table_id = s->oem_table_id };
acpi_table_begin(&table, table_data);
build_append_int_noprefix(table_data, 0x0, 4); /* Reserved */
/* Time Base Frequency */
build_append_int_noprefix(table_data,
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, 8);
/* ISA + N hart info */
num_rhct_nodes = 1 + ms->smp.cpus;
/* Number of RHCT nodes*/
build_append_int_noprefix(table_data, num_rhct_nodes, 4);
/* Offset to the RHCT node array */
build_append_int_noprefix(table_data, RHCT_NODE_ARRAY_OFFSET, 4);
/* ISA String Node */
isa_offset = table_data->len - table.table_offset;
build_append_int_noprefix(table_data, 0, 2); /* Type 0 */
cpu = &s->soc[0].harts[0];
isa = riscv_isa_string(cpu);
len = 8 + strlen(isa) + 1;
aligned_len = (len % 2) ? (len + 1) : len;
build_append_int_noprefix(table_data, aligned_len, 2); /* Length */
build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
/* ISA string length including NUL */
build_append_int_noprefix(table_data, strlen(isa) + 1, 2);
g_array_append_vals(table_data, isa, strlen(isa) + 1); /* ISA string */
if (aligned_len != len) {
build_append_int_noprefix(table_data, 0x0, 1); /* Optional Padding */
}
/* Hart Info Node */
for (int i = 0; i < arch_ids->len; i++) {
build_append_int_noprefix(table_data, 0xFFFF, 2); /* Type */
build_append_int_noprefix(table_data, 16, 2); /* Length */
build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
build_append_int_noprefix(table_data, 1, 2); /* Number of offsets */
build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */
build_append_int_noprefix(table_data, isa_offset, 4); /* Offsets[0] */
}
acpi_table_end(linker, &table);
}
/* FADT */
static void build_fadt_rev6(GArray *table_data,
BIOSLinker *linker,
@ -215,6 +290,9 @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables)
acpi_add_table(table_offsets, tables_blob);
build_madt(tables_blob, tables->linker, s);
acpi_add_table(table_offsets, tables_blob);
build_rhct(tables_blob, tables->linker, s);
/* XSDT is pointed to by RSDP */
xsdt = tables_blob->len;
build_xsdt(tables_blob, tables->linker, table_offsets, s->oem_id,