[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 34/41] arm : acpi create and map acpi tables



XSDT table cannot be passed as is to DOM0 because xen creates additional
tables which have to be added to XSDT table entry.
Copy existing XSDT and modify table to add new entries.
Create status override table,xen environment table.
Copy the tables to DOM0 memory.

Signed-off-by: Parth Dixit <parth.dixit@xxxxxxxxxx>
---
 xen/arch/arm/domain_build.c | 108 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 90bdd01..36b072b 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -10,6 +10,7 @@
 #include <xen/errno.h>
 #include <xen/device_tree.h>
 #include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <xen/efi.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/guest_access.h>
@@ -1225,16 +1226,123 @@ static int handle_node(struct domain *d, struct 
kernel_info *kinfo,
     return res;
 }
 #ifdef CONFIG_ACPI
+
+static int create_xen_acpi_tables(struct kernel_info *kinfo, struct domain *d,
+                                  struct membank tbl_add[])
+{
+    unsigned long res;
+    int offset=0;
+    u64 size;
+    u8 checksum;
+    u64 *table_entry;
+    u64 addr;
+    u8 *base_ptr;
+    struct acpi_table_xenv *xenv=NULL;
+    struct acpi_table_stao *stao=NULL;
+    struct acpi_table_header *table;
+    void * __user tbl_virt = (void * __user)(register_t)kinfo->acpi_paddr;
+
+    set_acpi_size(0);
+    addr = tbl_add[TBL_XSDT].start;
+    size = tbl_add[TBL_XSDT].size
+       - ( NR_NEW_XEN_TABLES*sizeof(acpi_native_uint) );
+
+    table = acpi_os_map_memory(addr, size);
+    size =   tbl_add[TBL_XSDT].size
+          +  tbl_add[TBL_XENV].size
+          +  tbl_add[TBL_STAO].size;
+
+    base_ptr = xzalloc_bytes(size);
+    if( base_ptr == NULL)
+        return -ENOMEM;
+
+    res = vgic_allocate_ppi(d);
+    if ( res < 0 )
+        panic("Unable to allocate a PPI for the event channel interrupt\n");
+
+    d->arch.evtchn_irq = res;
+
+    printk("Allocating PPI %u for event channel interrupt\n",
+           d->arch.evtchn_irq);
+
+   /* add xen env table */
+    tbl_add[TBL_XENV].start =(u64)(base_ptr);
+    xenv = (struct acpi_table_xenv *)(tbl_add[TBL_XENV].start);
+    ACPI_MEMCPY((void *)xenv, table, sizeof(struct acpi_table_header));
+    ACPI_MEMCPY(xenv->header.signature, ACPI_SIG_XENV, 4);
+    xenv->header.length = tbl_add[TBL_XENV].size;
+    ACPI_MEMCPY(xenv->header.oem_id, "XenVMM", 6);
+    xenv->header.revision = 1;
+    xenv->gnt_start = 0x00000010000000;
+    xenv->gnt_size = 0x20000;
+    xenv->evt_intr = d->arch.evtchn_irq;
+    xenv->evt_intr_flag = ( 0xff & EVT_CHN_INTR_TRIG );
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, xenv), 
tbl_add[TBL_XENV].size);
+    xenv->header.checksum = xenv->header.checksum - checksum;
+    tbl_add[TBL_XENV].start = (u64)(tbl_virt);
+    offset += tbl_add[TBL_XENV].size;
+
+    /* add stao table */
+    tbl_add[TBL_STAO].start =(u64)(base_ptr+offset);
+    stao = (struct acpi_table_stao *)(tbl_add[TBL_STAO].start);
+    ACPI_MEMCPY((void *)stao, table, sizeof(struct acpi_table_header));
+    ACPI_MEMCPY(stao->header.signature,ACPI_SIG_STAO, 4);
+    stao->header.length = tbl_add[TBL_STAO].size;
+    stao->uart = 1;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, stao), 
tbl_add[TBL_STAO].size);
+    stao->header.checksum = stao->header.checksum - checksum;
+    tbl_add[TBL_STAO].start =(u64) (tbl_virt+offset);
+    offset += tbl_add[TBL_STAO].size;
+
+    /* fix xsdt table */
+    ACPI_MEMCPY(base_ptr+offset, table,table->length);
+    acpi_os_unmap_memory(table, table->length);
+
+    table = (struct acpi_table_header *)(base_ptr+offset);
+    table->length = tbl_add[TBL_XSDT].size;
+    table_entry = ACPI_CAST_PTR(u64,
+                                (base_ptr+offset + sizeof(struct 
acpi_table_header) ) );
+    table_entry +=
+        ( ( (table->length - sizeof(struct acpi_table_header) ) /
+            sizeof(acpi_native_uint) ) );
+
+    table_entry--;
+    *table_entry = tbl_add[TBL_XENV].start ;
+
+    table_entry--;
+    *table_entry = tbl_add[TBL_STAO].start;
+
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), table->length);
+    table->checksum =  table->checksum - checksum;
+    tbl_add[TBL_XSDT].start =(u64)(tbl_virt+offset);
+
+    res = raw_copy_to_guest_flush_dcache(tbl_virt, base_ptr, size);
+    if ( res != 0 )
+        panic("Unable to copy the stao to dom0 memory (left = %lu bytes)", 
res);
+    set_acpi_size(size);
+
+    xfree(base_ptr);
+
+    return 0;
+}
+
 static int prepare_acpi(struct domain *d, struct kernel_info *kinfo, struct 
membank tbl_add[])
 {
     unsigned long res;
     u64 addr, size;
     int i = 0;
+    struct acpi_table_rsdp *rsdp_tbl;
 
+    create_xen_acpi_tables(kinfo, d, tbl_add);
     addr = acpi_os_get_root_pointer();
     if( !addr )
         return -ENODEV;
 
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp) );
+    rsdp_tbl->xsdt_physical_address = tbl_add[TBL_XSDT].start;
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp) );
+
+    /* map rsdp table */
     size = sizeof(struct acpi_table_rsdp);
 
     res = map_regions(d,
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.