diff mbox

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

Message ID 1431893048-5214-37-git-send-email-parth.dixit@linaro.org
State New
Headers show

Commit Message

Parth Dixit May 17, 2015, 8:04 p.m. UTC
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@linaro.org>
---
 xen/arch/arm/domain_build.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

Comments

Parth Dixit July 5, 2015, 1:34 p.m. UTC | #1
+shannon

On 18 May 2015 at 01:34, Parth Dixit <parth.dixit@linaro.org> wrote:
> 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@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
>
diff mbox

Patch

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);