diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c index 306d1105b8..d81f1dc2a2 100644 --- a/tools/firmware/hvmloader/acpi/build.c +++ b/tools/firmware/hvmloader/acpi/build.c @@ -297,6 +297,20 @@ static int construct_secondary_tables(unsigned long *table_ptrs, return nr_tables; } +unsigned long new_vm_gid(void) +{ + uint64_t gid; + unsigned char *buf; + + buf = mem_alloc(8, 8); + if (!buf) return 0; + + gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0); + *(uint64_t *)buf = gid; + + return virt_to_phys(buf); +} + void acpi_build_tables(struct acpi_config *config, unsigned int physical) { struct acpi_info *acpi_info; @@ -309,6 +323,7 @@ void acpi_build_tables(struct acpi_config *config, unsigned int physical) unsigned char *dsdt; unsigned long secondary_tables[16]; int nr_secondaries, i; + unsigned long vm_gid_addr; /* Allocate and initialise the acpi info area. */ mem_hole_populate_ram(ACPI_INFO_PHYSICAL_ADDRESS >> PAGE_SHIFT, 1); @@ -421,12 +436,16 @@ void acpi_build_tables(struct acpi_config *config, unsigned int physical) offsetof(struct acpi_20_rsdp, extended_checksum), sizeof(struct acpi_20_rsdp)); + vm_gid_addr = new_vm_gid(); + if (!vm_gid_addr) goto oom; + acpi_info->com1_present = uart_exists(0x3f8); acpi_info->com2_present = uart_exists(0x2f8); acpi_info->lpt1_present = lpt_exists(0x378); acpi_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS); acpi_info->pci_min = pci_mem_start; acpi_info->pci_len = pci_mem_end - pci_mem_start; + acpi_info->vm_gid_addr = vm_gid_addr; return; diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index 1bad9bcf09..b0e28217c2 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -205,6 +205,78 @@ strlen(const char *s) return i; } +static inline int __digit(char c, int base) +{ + int d = -1; + + if ( (c >= '0') && (c <= '9') ) + d = c - '0'; + + if ( (c >= 'A') && (c <= 'Z') ) + d = c - 'A' + 10; + + if ( (c >= 'a') && (c <= 'z') ) + d = c - 'a' + 10; + + if (d >= base) + d = -1; + + return d; +} + +long long +strtoll(const char *s, char **end, int base) +{ + long long v = 0; + int sign = 1; + + while ( (*s != '\0') && isspace(*s) ) + s++; + + if ( *s == '\0' ) goto out; + + if ( *s == '-' ) { + sign = -1; + s++; + } else { + if ( *s == '+' ) + s++; + } + + if ( *s == '\0' ) goto out; + + if ( *s == '0' ) { + s++; + if ( *s == '\0' ) goto out; + + if ( *s == 'x' ) { + if ( base != 0 && base != 16) goto out; + base = 16; + s++; + } else { + if ( base != 0 && base != 8) goto out; + base = 8; + } + } else { + if (base != 0 && base != 10) goto out; + base = 10; + } + + while ( *s != '\0' ) { + int d = __digit(*s, base); + + if ( d < 0 ) goto out; + + v = (v * base) + d; + s++; + } + +out: + if (end) *end = (char *)s; + + return sign * v; +} + void * memset(void *s, int c, unsigned n) { diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index fa73ba7a38..ed844462b2 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -152,6 +152,7 @@ int strncmp(const char *s1, const char *s2, uint32_t n); char *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, unsigned n); unsigned strlen(const char *s); +long long strtoll(const char *s, char **end, int base); int memcmp(const void *s1, const void *s2, unsigned n); void *memcpy(void *dest, const void *src, unsigned n); void *memmove(void *dest, const void *src, unsigned n);