aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware
diff options
context:
space:
mode:
authorPaul Durrant <paul.durrant@citrix.com>2011-11-30 06:53:36 -0800
committerPaul Durrant <paul.durrant@citrix.com>2011-11-30 06:53:36 -0800
commiteda65f1efeceb87b8be4cfdac229ac07b0c39b8a (patch)
tree1bdc1d4e364466b3336ef81bab03c069d7652c12 /tools/firmware
parent7f1c7895760a624d2ed5371fa7493da9935f99ce (diff)
downloadxen-eda65f1efeceb87b8be4cfdac229ac07b0c39b8a.tar.gz
xen-eda65f1efeceb87b8be4cfdac229ac07b0c39b8a.tar.bz2
xen-eda65f1efeceb87b8be4cfdac229ac07b0c39b8a.zip
hvmloader: Allocate an 8 byte buffer to contain the VM generation id
and populate it at boot time with a value read from "platform/generation_id". Also add code to libxl to populate this xenstore key with the value of a new 'generation_id' parameter in the VM config file. Populate the ADDR package of VM_Gen_Counter ACPI device such that the first integer evaluates to the low order 32 bits of the buffer address and the second integer evaluates to the high order 32 bits of the buffer address. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'tools/firmware')
-rw-r--r--tools/firmware/hvmloader/acpi/build.c19
-rw-r--r--tools/firmware/hvmloader/util.c72
-rw-r--r--tools/firmware/hvmloader/util.h1
3 files changed, 92 insertions, 0 deletions
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);