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

[Xen-devel] [PATCH v2 36/41] arm : acpi pass rsdp and memory via efi table



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.dixit@xxxxxxxxxx>
---
 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@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®.