Create EFI table and populate it with DOM0 memory and address
of RSDP. Fix device tree with correct addresses of EFI table
and start of memory descriptor address.

Signed-off-by: Parth Dixit <parth.di...@linaro.org>
---
 xen/arch/arm/domain_build.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 0ad70c1..2ce30bf 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1260,6 +1260,111 @@ static uint32_t xz_crc32(uint8_t *buf, size_t size, 
uint32_t crc)
        return ~crc;
 }
 
+static int prepare_efi_table(struct domain *d,
+                          const struct kernel_info *kinfo,
+                           struct membank tbl_add[])
+{
+    u64 fdt_val64;
+    u32 fdt_val32;
+    int size;
+    int i,offset;
+    unsigned long res;
+    int node;
+    u16 *fw_vendor;
+    u8 *base_ptr;
+    struct efi_memory_desc *memory_map;
+    struct efi_config_table *acpi_ect;
+    struct efi_system_table *sys_tbl;
+    void * __user tbl_virt = (void * __user)(register_t)kinfo->acpi_paddr;
+    struct efi_system_table *efi_sys_tbl = ( struct efi_system_table *)
+        maddr_to_virt(efi.est);
+
+    xz_crc32_init();
+    /* Fix up linux,uefi-system-table and linux,mmap-size in /chosen */
+    node = fdt_path_offset(kinfo->fdt, "/chosen");
+    if ( node < 0 )
+        panic("Cannot find the /chosen node");
+
+    size = tbl_add[TBL_EFIT].size
+        +  tbl_add[TBL_MMAP].size;
+
+    tbl_virt += get_acpi_size();
+    base_ptr = xzalloc_bytes(size);
+    sys_tbl = (struct efi_system_table *)base_ptr;
+    memcpy( (struct efi_table_hdr*)&(sys_tbl->hdr),
+            (struct efi_table_hdr*)&(efi_sys_tbl->hdr),
+            sizeof(struct efi_table_hdr) );
+    sys_tbl->hdr.headersize = tbl_add[TBL_EFIT].size;
+
+    sys_tbl->fw_revision = efi_sys_tbl->fw_revision;
+    sys_tbl->nr_tables = 1;
+    fdt_val64 = cpu_to_fdt64((u64)(uintptr_t)tbl_virt);
+    res = fdt_setprop_inplace(kinfo->fdt, node, "linux,uefi-system-table",
+                              &fdt_val64, sizeof(fdt_val64));
+    if ( res )
+        return res;
+    offset = sizeof(struct efi_system_table);
+
+    size = sizeof(XEN_EFI_FW_VENDOR);
+    fw_vendor = (u16 *)(base_ptr+offset);
+    memcpy(fw_vendor, XEN_EFI_FW_VENDOR, size);
+    sys_tbl->fw_vendor = (u64)(tbl_virt+offset);
+    offset+=size;
+
+    size = sizeof(struct efi_config_table);
+    acpi_ect = (struct efi_config_table *)(base_ptr+offset);
+    acpi_ect->guid = ACPI_20_TBL_GUID;
+    acpi_ect->table = efi.acpi20;
+    sys_tbl->tables = (u64)(tbl_virt+offset);
+    offset += size;
+    sys_tbl->hdr.crc32 = xz_crc32((uint8_t *)sys_tbl, sys_tbl->hdr.headersize, 
0);
+
+    size = tbl_add[TBL_MMAP].size;
+    memory_map = (struct efi_memory_desc *)(base_ptr+offset);
+    fdt_val64 = cpu_to_fdt64((u64)(uintptr_t)(tbl_virt+offset));
+    res = fdt_setprop_inplace(kinfo->fdt, node, "linux,uefi-mmap-start",
+                              &fdt_val64,  sizeof(fdt_val64));
+    if ( res )
+        return res;
+
+    fdt_val32 = cpu_to_fdt32(size);
+    res = fdt_setprop_inplace(kinfo->fdt, node, "linux,uefi-mmap-size",
+                              &fdt_val32,  sizeof(fdt_val32));
+    size += offset;
+
+    for( i=0; i < kinfo->mem.nr_banks ; i++)
+    {
+        memory_map[i].type = EFI_CONVENTIONAL_MEMORY;
+        memory_map[i].phys_addr = kinfo->mem.bank[i].start;
+        memory_map[i].num_pages = kinfo->mem.bank[i].size/PAGE_SIZE;
+        memory_map[i].attribute |= EFI_MEMORY_ATT_WB;
+    }
+    offset = kinfo->mem.nr_banks;
+    for( i=0; i < acpi_mem.nr_banks ; i++,offset++)
+    {
+        memory_map[offset].type = EFI_ACPI_RECLAIM_MEMORY;
+        memory_map[offset].phys_addr = acpi_mem.bank[i].start;
+        memory_map[offset].num_pages = acpi_mem.bank[i].size/PAGE_SIZE;
+    }
+
+    for( i=0; i < TBL_MMAX; i++, offset++ )
+    {
+        memory_map[offset].type = EFI_ACPI_RECLAIM_MEMORY;
+        memory_map[offset].phys_addr = tbl_add[i].start;
+        memory_map[offset].num_pages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[i].attribute |= EFI_MEMORY_ATT_WB;
+    }
+
+    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);
+    size += get_acpi_size();
+    set_acpi_size(size);
+
+    xfree(base_ptr);
+    return res;
+}
+
 static int create_xen_acpi_tables(struct kernel_info *kinfo, struct domain *d,
                                   struct membank tbl_add[])
 {
@@ -1375,6 +1480,7 @@ static int prepare_acpi(struct domain *d, struct 
kernel_info *kinfo, struct memb
     rsdp_tbl->xsdt_physical_address = tbl_add[TBL_XSDT].start;
     acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp) );
 
+    prepare_efi_table(d, kinfo, tbl_add);
     /* map rsdp table */
     size = sizeof(struct acpi_table_rsdp);
 
-- 
1.9.1


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

Reply via email to