mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
hvmloader: construct SRAT
Signed-off-by: Wei Liu <wei.liu2@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
2edb2d8c4a
commit
e9c8ef535b
2 files changed
+122
No files matched your search
@@ -363,6 +363,57 @@ struct acpi_20_madt_intsrcovr {
|
||||
uint16_t flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* System Resource Affinity Table header definition (SRAT)
|
||||
*/
|
||||
struct acpi_20_srat {
|
||||
struct acpi_header header;
|
||||
uint32_t table_revision;
|
||||
uint32_t reserved2[2];
|
||||
};
|
||||
|
||||
#define ACPI_SRAT_TABLE_REVISION 1
|
||||
|
||||
/*
|
||||
* System Resource Affinity Table structure types.
|
||||
*/
|
||||
#define ACPI_PROCESSOR_AFFINITY 0x0
|
||||
#define ACPI_MEMORY_AFFINITY 0x1
|
||||
struct acpi_20_srat_processor {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t domain;
|
||||
uint8_t apic_id;
|
||||
uint32_t flags;
|
||||
uint8_t sapic_id;
|
||||
uint8_t domain_hi[3];
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
/*
|
||||
* Local APIC Affinity Flags. All other bits are reserved and must be 0.
|
||||
*/
|
||||
#define ACPI_LOCAL_APIC_AFFIN_ENABLED (1 << 0)
|
||||
|
||||
struct acpi_20_srat_memory {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint32_t domain;
|
||||
uint16_t reserved;
|
||||
uint64_t base_address;
|
||||
uint64_t mem_length;
|
||||
uint32_t reserved2;
|
||||
uint32_t flags;
|
||||
uint64_t reserved3;
|
||||
};
|
||||
|
||||
/*
|
||||
* Memory Affinity Flags. All other bits are reserved and must be 0.
|
||||
*/
|
||||
#define ACPI_MEM_AFFIN_ENABLED (1 << 0)
|
||||
#define ACPI_MEM_AFFIN_HOTPLUGGABLE (1 << 1)
|
||||
#define ACPI_MEM_AFFIN_NONVOLATILE (1 << 2)
|
||||
|
||||
/*
|
||||
* Table Signatures.
|
||||
*/
|
||||
@@ -375,6 +426,7 @@ struct acpi_20_madt_intsrcovr {
|
||||
#define ACPI_2_0_TCPA_SIGNATURE ASCII32('T','C','P','A')
|
||||
#define ACPI_2_0_HPET_SIGNATURE ASCII32('H','P','E','T')
|
||||
#define ACPI_2_0_WAET_SIGNATURE ASCII32('W','A','E','T')
|
||||
#define ACPI_2_0_SRAT_SIGNATURE ASCII32('S','R','A','T')
|
||||
|
||||
/*
|
||||
* Table revision numbers.
|
||||
@@ -388,6 +440,7 @@ struct acpi_20_madt_intsrcovr {
|
||||
#define ACPI_2_0_HPET_REVISION 0x01
|
||||
#define ACPI_2_0_WAET_REVISION 0x01
|
||||
#define ACPI_1_0_FADT_REVISION 0x01
|
||||
#define ACPI_2_0_SRAT_REVISION 0x01
|
||||
|
||||
#pragma pack ()
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "ssdt_pm.h"
|
||||
#include "../config.h"
|
||||
#include "../util.h"
|
||||
#include "../vnuma.h"
|
||||
#include <xen/hvm/hvm_xs_strings.h>
|
||||
#include <xen/hvm/params.h>
|
||||
|
||||
@@ -203,6 +204,63 @@ static struct acpi_20_waet *construct_waet(void)
|
||||
return waet;
|
||||
}
|
||||
|
||||
static struct acpi_20_srat *construct_srat(void)
|
||||
{
|
||||
struct acpi_20_srat *srat;
|
||||
struct acpi_20_srat_processor *processor;
|
||||
struct acpi_20_srat_memory *memory;
|
||||
unsigned int size;
|
||||
void *p;
|
||||
unsigned int i;
|
||||
|
||||
size = sizeof(*srat) + sizeof(*processor) * hvm_info->nr_vcpus +
|
||||
sizeof(*memory) * nr_vmemranges;
|
||||
|
||||
p = mem_alloc(size, 16);
|
||||
if ( !p )
|
||||
return NULL;
|
||||
|
||||
srat = memset(p, 0, size);
|
||||
srat->header.signature = ACPI_2_0_SRAT_SIGNATURE;
|
||||
srat->header.revision = ACPI_2_0_SRAT_REVISION;
|
||||
fixed_strcpy(srat->header.oem_id, ACPI_OEM_ID);
|
||||
fixed_strcpy(srat->header.oem_table_id, ACPI_OEM_TABLE_ID);
|
||||
srat->header.oem_revision = ACPI_OEM_REVISION;
|
||||
srat->header.creator_id = ACPI_CREATOR_ID;
|
||||
srat->header.creator_revision = ACPI_CREATOR_REVISION;
|
||||
srat->table_revision = ACPI_SRAT_TABLE_REVISION;
|
||||
|
||||
processor = (struct acpi_20_srat_processor *)(srat + 1);
|
||||
for ( i = 0; i < hvm_info->nr_vcpus; i++ )
|
||||
{
|
||||
processor->type = ACPI_PROCESSOR_AFFINITY;
|
||||
processor->length = sizeof(*processor);
|
||||
processor->domain = vcpu_to_vnode[i];
|
||||
processor->apic_id = LAPIC_ID(i);
|
||||
processor->flags = ACPI_LOCAL_APIC_AFFIN_ENABLED;
|
||||
processor++;
|
||||
}
|
||||
|
||||
memory = (struct acpi_20_srat_memory *)processor;
|
||||
for ( i = 0; i < nr_vmemranges; i++ )
|
||||
{
|
||||
memory->type = ACPI_MEMORY_AFFINITY;
|
||||
memory->length = sizeof(*memory);
|
||||
memory->domain = vmemrange[i].nid;
|
||||
memory->flags = ACPI_MEM_AFFIN_ENABLED;
|
||||
memory->base_address = vmemrange[i].start;
|
||||
memory->mem_length = vmemrange[i].end - vmemrange[i].start;
|
||||
memory++;
|
||||
}
|
||||
|
||||
ASSERT(((unsigned long)memory) - ((unsigned long)p) == size);
|
||||
|
||||
srat->header.length = size;
|
||||
set_checksum(srat, offsetof(struct acpi_header, checksum), size);
|
||||
|
||||
return srat;
|
||||
}
|
||||
|
||||
static int construct_passthrough_tables(unsigned long *table_ptrs,
|
||||
int nr_tables)
|
||||
{
|
||||
@@ -346,6 +404,17 @@ static int construct_secondary_tables(unsigned long *table_ptrs,
|
||||
}
|
||||
}
|
||||
|
||||
/* SRAT */
|
||||
if ( nr_vnodes > 0 )
|
||||
{
|
||||
struct acpi_20_srat *srat = construct_srat();
|
||||
|
||||
if ( srat )
|
||||
table_ptrs[nr_tables++] = (unsigned long)srat;
|
||||
else
|
||||
printf("Failed to build SRAT, skipping...\n");
|
||||
}
|
||||
|
||||
/* Load any additional tables passed through. */
|
||||
nr_tables += construct_passthrough_tables(table_ptrs, nr_tables);
|
||||
|
||||
|
||||