@@ -1783,27 +1783,32 @@ void build_cache_hierarchy(GArray *tbl,
/*
* ACPI 6.3: 5.2.29.1 Processor hierarchy node structure (Type 0)
*/
-void build_socket_hierarchy(GArray *tbl, uint32_t parent, uint32_t id)
+void build_socket_hierarchy(GArray *tbl, uint32_t parent,
+ uint32_t offset, uint32_t id)
{
build_append_byte(tbl, 0); /* Type 0 - processor */
- build_append_byte(tbl, 20); /* Length, no private resources */
+ build_append_byte(tbl, 24); /* Length, no private resources */
build_append_int_noprefix(tbl, 0, 2); /* Reserved */
build_append_int_noprefix(tbl, 1, 4); /* Flags: Physical package */
build_append_int_noprefix(tbl, parent, 4); /* Parent */
build_append_int_noprefix(tbl, id, 4); /* ACPI processor ID */
- build_append_int_noprefix(tbl, 0, 4); /* Number of private resources */
+ build_append_int_noprefix(tbl, 1, 4); /* Number of private resources */
+ build_append_int_noprefix(tbl, offset, 4); /* Private resources */
}
-void build_processor_hierarchy(GArray *tbl, uint32_t flags,
- uint32_t parent, uint32_t id)
+void build_processor_hierarchy(GArray *tbl, uint32_t flags, uint32_t parent,
+ AcpiCacheOffset offset, uint32_t id)
{
build_append_byte(tbl, 0); /* Type 0 - processor */
- build_append_byte(tbl, 20); /* Length, no private resources */
+ build_append_byte(tbl, 32); /* Length, no private resources */
build_append_int_noprefix(tbl, 0, 2); /* Reserved */
build_append_int_noprefix(tbl, flags, 4); /* Flags */
build_append_int_noprefix(tbl, parent, 4); /* Parent */
build_append_int_noprefix(tbl, id, 4); /* ACPI processor ID */
- build_append_int_noprefix(tbl, 0, 4); /* Number of private resources */
+ build_append_int_noprefix(tbl, 3, 4); /* Number of private resources */
+ build_append_int_noprefix(tbl, offset.l1d_offset, 4);/* Private resources */
+ build_append_int_noprefix(tbl, offset.l1i_offset, 4);/* Private resources */
+ build_append_int_noprefix(tbl, offset.l2_offset, 4); /* Private resources */
}
void build_smt_hierarchy(GArray *tbl, uint32_t parent, uint32_t id)
@@ -594,29 +594,69 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
"SRAT", table_data->len - srat_start, 3, NULL, NULL);
}
-static void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms)
+static inline void arm_acpi_cache_info(CPUCacheInfo *cpu_cache,
+ AcpiCacheInfo *acpi_cache)
{
+ acpi_cache->size = cpu_cache->size;
+ acpi_cache->sets = cpu_cache->sets;
+ acpi_cache->associativity = cpu_cache->associativity;
+ acpi_cache->attributes = cpu_cache->attributes;
+ acpi_cache->line_size = cpu_cache->line_size;
+}
+
+static void build_pptt(GArray *table_data, BIOSLinker *linker,
+ VirtMachineState *vms)
+{
+ MachineState *ms = MACHINE(vms);
int pptt_start = table_data->len;
int uid = 0, cpus = 0, socket;
unsigned int smp_cores = ms->smp.cores;
unsigned int smp_threads = ms->smp.threads;
+ AcpiCacheOffset offset;
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(cpus));
+ AcpiCacheInfo cache_info;
acpi_data_push(table_data, sizeof(AcpiTableHeader));
for (socket = 0; cpus < ms->possible_cpus->len; socket++) {
- uint32_t socket_offset = table_data->len - pptt_start;
+ uint32_t l3_offset = table_data->len - pptt_start;
+ uint32_t socket_offset;
int core;
- build_socket_hierarchy(table_data, 0, socket);
+ /* L3 cache type structure */
+ arm_acpi_cache_info(cpu->caches.l3_cache, &cache_info);
+ build_cache_hierarchy(table_data, 0, &cache_info);
+
+ socket_offset = table_data->len - pptt_start;
+ build_socket_hierarchy(table_data, 0, l3_offset, socket);
for (core = 0; core < smp_cores; core++) {
uint32_t core_offset = table_data->len - pptt_start;
int thread;
+ /* L2 cache tpe structure */
+ offset.l2_offset = table_data->len - pptt_start;
+ arm_acpi_cache_info(cpu->caches.l2_cache, &cache_info);
+ build_cache_hierarchy(table_data, 0, &cache_info);
+
+ /* L1d cache type structure */
+ offset.l1d_offset = table_data->len - pptt_start;
+ arm_acpi_cache_info(cpu->caches.l1d_cache, &cache_info);
+ build_cache_hierarchy(table_data, offset.l2_offset, &cache_info);
+
+ /* L1i cache type structure */
+ offset.l1i_offset = table_data->len - pptt_start;
+ arm_acpi_cache_info(cpu->caches.l1i_cache, &cache_info);
+ build_cache_hierarchy(table_data, offset.l2_offset, &cache_info);
+
+ core_offset = table_data->len - pptt_start;
if (smp_threads <= 1) {
- build_processor_hierarchy(table_data, 2, socket_offset, uid++);
+ build_processor_hierarchy(table_data, 2, socket_offset,
+ offset, uid++);
} else {
- build_processor_hierarchy(table_data, 0, socket_offset, core);
+
+ build_processor_hierarchy(table_data, 0, socket_offset,
+ offset, core);
for (thread = 0; thread < smp_threads; thread++) {
build_smt_hierarchy(table_data, core_offset, uid++);
}
@@ -892,7 +932,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
if (cpu_topology_enabled) {
acpi_add_table(table_offsets, tables_blob);
- build_pptt(tables_blob, tables->linker, ms);
+ build_pptt(tables_blob, tables->linker, vms);
}
acpi_add_table(table_offsets, tables_blob);
@@ -626,4 +626,10 @@ typedef struct AcpiCacheInfo {
uint16_t line_size;
} AcpiCacheInfo;
+typedef struct AcpiCacheOffset {
+ uint32_t l1d_offset;
+ uint32_t l1i_offset;
+ uint32_t l2_offset;
+} AcpiCacheOffset;
+
#endif
@@ -438,10 +438,11 @@ void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms);
void build_cache_hierarchy(GArray *tbl,
uint32_t next_level, AcpiCacheInfo *cache_info);
-void build_socket_hierarchy(GArray *tbl, uint32_t parent, uint32_t id);
+void build_socket_hierarchy(GArray *tbl, uint32_t parent,
+ uint32_t offset, uint32_t id);
-void build_processor_hierarchy(GArray *tbl, uint32_t flags,
- uint32_t parent, uint32_t id);
+void build_processor_hierarchy(GArray *tbl, uint32_t flags, uint32_t parent,
+ AcpiCacheOffset offset, uint32_t id);
void build_smt_hierarchy(GArray *tbl, uint32_t parent, uint32_t id);