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,
