aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware
diff options
context:
space:
mode:
authorRoss Philipson <ross.philipson@citrix.com>2013-01-10 17:18:43 +0000
committerRoss Philipson <ross.philipson@citrix.com>2013-01-10 17:18:43 +0000
commit4a281d45f59bcc2cc21d63e7f6ec1f4bae642a9b (patch)
tree323334b652d7772fdb5ca97fedb0ae8471e783bc /tools/firmware
parent4d23036e709627bb5013eac9f3ee46343b8c49f0 (diff)
downloadxen-4a281d45f59bcc2cc21d63e7f6ec1f4bae642a9b.tar.gz
xen-4a281d45f59bcc2cc21d63e7f6ec1f4bae642a9b.tar.bz2
xen-4a281d45f59bcc2cc21d63e7f6ec1f4bae642a9b.zip
HVM firmware passthrough ACPI processing
ACPI table passthrough support allowing additional static tables and SSDTs (AML code) to be loaded. These additional tables are added at the end of the secondary table list in the RSDT/XSDT tables. Signed-off-by: Ross Philipson <ross.philipson@citrix.com> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'tools/firmware')
-rw-r--r--tools/firmware/hvmloader/acpi/build.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c
index d09785d0a1..9026e09eba 100644
--- a/tools/firmware/hvmloader/acpi/build.c
+++ b/tools/firmware/hvmloader/acpi/build.c
@@ -23,6 +23,9 @@
#include "ssdt_pm.h"
#include "../config.h"
#include "../util.h"
+#include <xen/hvm/hvm_xs_strings.h>
+
+#define ACPI_MAX_SECONDARY_TABLES 16
#define align16(sz) (((sz) + 15) & ~15)
#define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
@@ -198,6 +201,52 @@ static struct acpi_20_waet *construct_waet(void)
return waet;
}
+static int construct_passthrough_tables(unsigned long *table_ptrs,
+ int nr_tables)
+{
+ const char *s;
+ uint8_t *acpi_pt_addr;
+ uint32_t acpi_pt_length;
+ struct acpi_header *header;
+ int nr_added;
+ int nr_max = (ACPI_MAX_SECONDARY_TABLES - nr_tables - 1);
+ uint32_t total = 0;
+ uint8_t *buffer;
+
+ s = xenstore_read(HVM_XS_ACPI_PT_ADDRESS, NULL);
+ if ( s == NULL )
+ return 0;
+
+ acpi_pt_addr = (uint8_t*)(uint32_t)strtoll(s, NULL, 0);
+ if ( acpi_pt_addr == NULL )
+ return 0;
+
+ s = xenstore_read(HVM_XS_ACPI_PT_LENGTH, NULL);
+ if ( s == NULL )
+ return 0;
+
+ acpi_pt_length = (uint32_t)strtoll(s, NULL, 0);
+
+ for ( nr_added = 0; nr_added < nr_max; nr_added++ )
+ {
+ if ( (acpi_pt_length - total) < sizeof(struct acpi_header) )
+ break;
+
+ header = (struct acpi_header*)acpi_pt_addr;
+
+ buffer = mem_alloc(header->length, 16);
+ if ( buffer == NULL )
+ break;
+ memcpy(buffer, header, header->length);
+
+ table_ptrs[nr_tables++] = (unsigned long)buffer;
+ total += header->length;
+ acpi_pt_addr += header->length;
+ }
+
+ return nr_added;
+}
+
static int construct_secondary_tables(unsigned long *table_ptrs,
struct acpi_info *info)
{
@@ -293,6 +342,9 @@ static int construct_secondary_tables(unsigned long *table_ptrs,
}
}
+ /* Load any additional tables passed through. */
+ nr_tables += construct_passthrough_tables(table_ptrs, nr_tables);
+
table_ptrs[nr_tables] = 0;
return nr_tables;
}
@@ -327,7 +379,7 @@ void acpi_build_tables(struct acpi_config *config, unsigned int physical)
struct acpi_10_fadt *fadt_10;
struct acpi_20_facs *facs;
unsigned char *dsdt;
- unsigned long secondary_tables[16];
+ unsigned long secondary_tables[ACPI_MAX_SECONDARY_TABLES];
int nr_secondaries, i;
unsigned long vm_gid_addr;