From mboxrd@z Thu Jan 1 00:00:00 1970 From: Wei Liu Subject: [PATCH v5 13/24] hvmloader: construct SRAT Date: Thu, 12 Feb 2015 19:44:43 +0000 Message-ID: <1423770294-9779-14-git-send-email-wei.liu2@citrix.com> References: <1423770294-9779-1-git-send-email-wei.liu2@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1423770294-9779-1-git-send-email-wei.liu2@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: Wei Liu , ian.campbell@citrix.com, andrew.cooper3@citrix.com, dario.faggioli@citrix.com, ian.jackson@eu.citrix.com, JBeulich@suse.com, ufimtseva@gmail.com List-Id: xen-devel@lists.xenproject.org Signed-off-by: Wei Liu Acked-by: Jan Beulich --- Changes in v3: 1. Remove redundant variable. 2. Coding style fix. 3. Add assertion. Changes in v2: 1. Remove explicit zero initializers. 2. Adapt to new vNUMA retrieval routine. 3. Move SRAT very late in secondary table build. --- tools/firmware/hvmloader/acpi/acpi2_0.h | 53 ++++++++++++++++++++++++ tools/firmware/hvmloader/acpi/build.c | 72 +++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/tools/firmware/hvmloader/acpi/acpi2_0.h b/tools/firmware/hvmloader/acpi/acpi2_0.h index 7b22d80..6169213 100644 --- a/tools/firmware/hvmloader/acpi/acpi2_0.h +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h @@ -364,6 +364,57 @@ struct acpi_20_madt_intsrcovr { }; /* + * 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. */ #define ACPI_2_0_RSDP_SIGNATURE ASCII64('R','S','D',' ','P','T','R',' ') @@ -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 () diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c index 1431296..3e96c23 100644 --- a/tools/firmware/hvmloader/acpi/build.c +++ b/tools/firmware/hvmloader/acpi/build.c @@ -23,6 +23,7 @@ #include "ssdt_pm.h" #include "../config.h" #include "../util.h" +#include "../vnuma.h" #include #include @@ -203,6 +204,66 @@ 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; + 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 = p; + memset(srat, 0, sizeof(*srat)); + 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++ ) + { + memset(processor, 0, sizeof(*processor)); + 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++ ) + { + memset(memory, 0, sizeof(*memory)); + 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) { @@ -257,6 +318,7 @@ static int construct_secondary_tables(unsigned long *table_ptrs, struct acpi_20_hpet *hpet; struct acpi_20_waet *waet; struct acpi_20_tcpa *tcpa; + struct acpi_20_srat *srat; unsigned char *ssdt; static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001}; uint16_t *tis_hdr; @@ -346,6 +408,16 @@ static int construct_secondary_tables(unsigned long *table_ptrs, } } + /* SRAT */ + if ( nr_vnodes > 0 ) + { + 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); -- 1.9.1