qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring
@ 2024-09-14 12:10 Jiaxun Yang
  2024-09-14 12:10 ` [PATCH 1/2] hw/loongarch/boot: Refactor EFI booting protocol generation Jiaxun Yang
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-09-14 12:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Song Gao, Jiaxun Yang

Hi all,

This series refactored booting protocol generation code
to better accommodate different host ABI / Alignment and
endianess.

It also enhanced LoongArch32 support.

Thanks

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
Jiaxun Yang (2):
      hw/loongarch/boot: Refactor EFI booting protocol generation
      hw/loongarch/boot: Rework boot code generation

 hw/loongarch/boot.c         | 321 ++++++++++++++++++++++++++++----------------
 include/hw/loongarch/boot.h | 106 ++++++++++++---
 2 files changed, 293 insertions(+), 134 deletions(-)
---
base-commit: 28ae3179fc52d2e4d870b635c4a412aab99759e7
change-id: 20240914-loongarch-booting-b5ae3f4976b7

Best regards,
-- 
Jiaxun Yang <jiaxun.yang@flygoat.com>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] hw/loongarch/boot: Refactor EFI booting protocol generation
  2024-09-14 12:10 [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
@ 2024-09-14 12:10 ` Jiaxun Yang
  2024-09-14 12:10 ` [PATCH 2/2] hw/loongarch/boot: Rework boot code generation Jiaxun Yang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-09-14 12:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Song Gao, Jiaxun Yang

Refector EFI style booting data structure generation to
support 32bit EFI variant on LoongArch32 CPU.

All data structs are filled with padding members if necessary
and marked as QEMU_PACKED to avoid host ABI alignment impact.

Host endian is being cared as well.

It also fixed various problems in old implementation such
as null pointer on empty string, memory desc map_size not set,
incorrect memory map definition and so on.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 hw/loongarch/boot.c         | 220 ++++++++++++++++++++++++++++++--------------
 include/hw/loongarch/boot.h | 106 +++++++++++++++++----
 2 files changed, 237 insertions(+), 89 deletions(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index cb668703bddd..4d01c01594e2 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2023 Loongson Technology Corporation Limited
  */
 
+#include <zlib.h>
 #include "qemu/osdep.h"
 #include "qemu/units.h"
 #include "target/loongarch/cpu.h"
@@ -31,7 +32,7 @@ static const unsigned int slave_boot_code[] = {
 
                   /* Clear mailbox.                            */
     0x1400002d,   /* lu12i.w    $t1, 1(0x1)                    */
-    0x038081ad,   /* ori        $t1, $t1, CORE_BUF_20  */
+    0x038081ad,   /* ori        $t1, $t1, CORE_BUF_20          */
     0x06481da0,   /* iocsrwr.d  $zero, $t1                     */
 
                   /* Enable IPI interrupt.                     */
@@ -74,88 +75,163 @@ static inline void *guidcpy(void *dst, const void *src)
     return memcpy(dst, src, sizeof(efi_guid_t));
 }
 
-static void init_efi_boot_memmap(struct efi_system_table *systab,
-                                 void *p, void *start)
+static void efi_hdr_crc32(efi_table_hdr_t *hdr)
 {
-    unsigned i;
-    struct efi_boot_memmap *boot_memmap = p;
-    efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
-
-    /* efi_configuration_table 1 */
-    guidcpy(&systab->tables[0].guid, &tbl_guid);
-    systab->tables[0].table = (struct efi_configuration_table *)(p - start);
-    systab->nr_tables = 1;
-
-    boot_memmap->desc_size = sizeof(efi_memory_desc_t);
-    boot_memmap->desc_ver = 1;
-    boot_memmap->map_size = 0;
+    uint32_t val;
 
-    efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap);
-    for (i = 0; i < memmap_entries; i++) {
-        map = (void *)boot_memmap + sizeof(*map);
-        map[i].type = memmap_table[i].type;
-        map[i].phys_addr = ROUND_UP(memmap_table[i].address, 64 * KiB);
-        map[i].num_pages = ROUND_DOWN(memmap_table[i].address +
-                        memmap_table[i].length - map[i].phys_addr, 64 * KiB);
-        p += sizeof(efi_memory_desc_t);
-    }
+    hdr->crc32 = 0;
+    val = crc32(0, (const unsigned char *)hdr, hdr->headersize);
+    hdr->crc32 = cpu_to_le32(val);
 }
 
-static void init_efi_initrd_table(struct efi_system_table *systab,
-                                  void *p, void *start)
+static void init_efi_vendor_string(void **p)
 {
-    efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;
-    struct efi_initrd *initrd_table  = p;
+    uint16_t *vendor_str = *p;
 
-    /* efi_configuration_table 2 */
-    guidcpy(&systab->tables[1].guid, &tbl_guid);
-    systab->tables[1].table = (struct efi_configuration_table *)(p - start);
-    systab->nr_tables = 2;
+    /* QEMU in UTF16-LE */
+    stw_le_p(vendor_str++, 0x0051); /* Q */
+    stw_le_p(vendor_str++, 0x0045); /* E */
+    stw_le_p(vendor_str++, 0x004D); /* M */
+    stw_le_p(vendor_str++, 0x0055); /* U */
+    stw_le_p(vendor_str++, 0x0000); /* \0 */
 
-    initrd_table->base = initrd_offset;
-    initrd_table->size = initrd_size;
+    *p = vendor_str;
+    *p = QEMU_ALIGN_PTR_UP(*p, sizeof(target_long));
 }
 
-static void init_efi_fdt_table(struct efi_system_table *systab)
+static void memmap_write_descs(efi_memory_desc_t *map)
 {
-    efi_guid_t tbl_guid = DEVICE_TREE_GUID;
-
-    /* efi_configuration_table 3 */
-    guidcpy(&systab->tables[2].guid, &tbl_guid);
-    systab->tables[2].table = (void *)FDT_BASE;
-    systab->nr_tables = 3;
-}
-
-static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
-{
-    void *bp_tables_start;
-    struct efi_system_table *systab = p;
+    int i;
 
-    info->a2 = p - start;
+    for (i = 0; i < memmap_entries; i++) {
+        uint32_t efi_type;
+        hwaddr start = memmap_table[i].address;
+        hwaddr end = memmap_table[i].address + memmap_table[i].length;
+
+        switch (memmap_table[i].type) {
+        case MEMMAP_TYPE_MEMORY:
+            efi_type = EFI_CONVENTIONAL_MEMORY;
+            break;
+        case MEMMAP_TYPE_RESERVED:
+            efi_type = EFI_RESERVED_TYPE;
+            break;
+        case MEMMAP_TYPE_ACPI:
+            efi_type = EFI_ACPI_RECLAIM_MEMORY;
+            break;
+        case MEMMAP_TYPE_NVS:
+            efi_type = EFI_ACPI_MEMORY_NVS;
+            break;
+        default:
+            efi_type = EFI_RESERVED_TYPE;
+            break;
+        }
 
-    systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
-    systab->hdr.revision = EFI_SPECIFICATION_VERSION;
-    systab->hdr.revision = sizeof(struct efi_system_table),
-    systab->fw_revision = FW_VERSION << 16 | FW_PATCHLEVEL << 8;
-    systab->runtime = 0;
-    systab->boottime = 0;
-    systab->nr_tables = 0;
+        if (memmap_table[i].reserved) {
+            start = QEMU_ALIGN_DOWN(start, EFI_PAGE_SIZE);
+            end = QEMU_ALIGN_UP(end, EFI_PAGE_SIZE);
+        } else {
+            start = QEMU_ALIGN_UP(start, EFI_PAGE_SIZE);
+            end = QEMU_ALIGN_DOWN(end, EFI_PAGE_SIZE);
+        }
 
-    p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB);
+        map[i].type = cpu_to_le32(efi_type);
+        map[i].phys_addr = cpu_to_le64(start);
+        map[i].virt_addr = cpu_to_le64(start);
+        map[i].num_pages = cpu_to_le64((end - start) >> EFI_PAGE_SHIFT);
+    }
+}
 
-    systab->tables = p;
-    bp_tables_start = p;
+#define EFI_BOOT_MEMMAP_TABLE_GEN(type)                                     \
+static void init_efi_boot_memmap_##type(void *guidp, void **p)              \
+{                                                                           \
+    struct efi_boot_memmap_##type *boot_memmap = *p;                        \
+    efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;                       \
+                                                                            \
+    /* efi_configuration_table 1 */                                         \
+    guidcpy(guidp, &tbl_guid);                                              \
+                                                                            \
+    boot_memmap->desc_size = cpu_to_le##type(sizeof(efi_memory_desc_t));    \
+    boot_memmap->desc_ver = cpu_to_le32(1);                                 \
+    boot_memmap->map_size = cpu_to_le##type(boot_memmap->desc_size *        \
+                                            memmap_entries);                \
+    memmap_write_descs(boot_memmap->map);                                   \
+    *p += sizeof(struct efi_boot_memmap_##type);                            \
+}
 
-    init_efi_boot_memmap(systab, p, start);
-    p += ROUND_UP(sizeof(struct efi_boot_memmap) +
-                  sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB);
-    init_efi_initrd_table(systab, p, start);
-    p += ROUND_UP(sizeof(struct efi_initrd), 64 * KiB);
-    init_efi_fdt_table(systab);
+#define EFI_INITRD_TABLE_GEN(type)                                          \
+static void init_efi_initrd_table_##type(void *guidp, void **p)             \
+{                                                                           \
+    efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;                      \
+    struct efi_initrd_##type *initrd_table = *p;                            \
+                                                                            \
+    /* efi_configuration_table  */                                          \
+    guidcpy(guidp, &tbl_guid);                                              \
+                                                                            \
+    initrd_table->base = cpu_to_le##type(initrd_offset);                    \
+    initrd_table->size = cpu_to_le##type(initrd_size);                      \
+    *p += sizeof(struct efi_initrd_##type);                                 \
+}
 
-    systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);
+#define BOOTP_ALIGN_PTR_UP(p, s, n)                                         \
+        ((typeof(p))((uintptr_t)(s) +                                       \
+            QEMU_ALIGN_UP((uintptr_t)(p) - (uintptr_t)(s), n)))
+
+#define EFI_INIT_SYSTAB_GEN(type)                                           \
+    EFI_BOOT_MEMMAP_TABLE_GEN(type)                                         \
+    EFI_INITRD_TABLE_GEN(type)                                              \
+static void init_systab_##type(struct loongarch_boot_info *info,            \
+                               void *p, void *start)                        \
+{                                                                           \
+    uint32_t nr_tables = 0;                                                 \
+    const efi_guid_t fdt_guid = DEVICE_TREE_GUID;                           \
+    struct efi_system_table_##type *systab;                                 \
+    struct efi_configuration_table_##type *cfg_tabs;                        \
+                                                                            \
+    p = BOOTP_ALIGN_PTR_UP(p, start, EFI_TABLE_ALIGN);                      \
+    systab = p;                                                             \
+    info->a2 = p - start;                                                   \
+                                                                            \
+    systab->hdr.signature = cpu_to_le64(EFI_SYSTEM_TABLE_SIGNATURE);        \
+    systab->hdr.revision = cpu_to_le32(EFI_SPECIFICATION_VERSION);          \
+    systab->hdr.headersize =                                                \
+            cpu_to_le32(sizeof(struct efi_system_table_##type));            \
+    systab->fw_revision =                                                   \
+            cpu_to_le32(FW_VERSION << 16 | FW_PATCHLEVEL << 8);             \
+    systab->runtime = 0;                                                    \
+    systab->boottime = 0;                                                   \
+    systab->nr_tables = 0;                                                  \
+                                                                            \
+    p += sizeof(struct efi_system_table_##type);                            \
+    systab->fw_vendor = cpu_to_le##type(p - start);                         \
+    init_efi_vendor_string(&p);                                             \
+                                                                            \
+    p = BOOTP_ALIGN_PTR_UP(p, start, EFI_TABLE_ALIGN);                      \
+    systab->tables = cpu_to_le##type(p - start);                            \
+    cfg_tabs = p;                                                           \
+    p += sizeof(struct efi_configuration_table_##type) * 3;                 \
+                                                                            \
+    p = BOOTP_ALIGN_PTR_UP(p, start, EFI_TABLE_ALIGN);                      \
+    cfg_tabs[nr_tables].table = cpu_to_le##type(p - start);                 \
+    init_efi_boot_memmap_##type(&cfg_tabs[nr_tables].guid, &p);             \
+    nr_tables++;                                                            \
+                                                                            \
+    if (initrd_size > 0) {                                                  \
+        cfg_tabs[nr_tables].table = cpu_to_le##type(p - start);             \
+        init_efi_initrd_table_##type(&cfg_tabs[nr_tables].guid, &p);        \
+        nr_tables++;                                                        \
+    }                                                                       \
+                                                                            \
+    guidcpy(&cfg_tabs[nr_tables].guid, &fdt_guid);                          \
+    cfg_tabs[nr_tables].table = cpu_to_le##type(FDT_BASE);                  \
+    nr_tables++;                                                            \
+                                                                            \
+    systab->nr_tables = cpu_to_le32(nr_tables);                             \
+    efi_hdr_crc32(&systab->hdr);                                            \
 }
 
+EFI_INIT_SYSTAB_GEN(32)
+EFI_INIT_SYSTAB_GEN(64)
+
 static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
 {
     hwaddr cmdline_addr = p - start;
@@ -223,7 +299,7 @@ static void reset_load_elf(void *opaque)
 
     cpu_reset(CPU(cpu));
     if (env->load_elf) {
-	if (cpu == LOONGARCH_CPU(first_cpu)) {
+        if (cpu == LOONGARCH_CPU(first_cpu)) {
             env->gpr[4] = env->boot_info->a0;
             env->gpr[5] = env->boot_info->a1;
             env->gpr[6] = env->boot_info->a2;
@@ -265,21 +341,25 @@ static void loongarch_firmware_boot(LoongArchVirtMachineState *lvms,
     fw_cfg_add_kernel_info(info, lvms->fw_cfg);
 }
 
-static void init_boot_rom(struct loongarch_boot_info *info, void *p)
+static void init_boot_rom(struct loongarch_boot_info *info, void *p,
+                          bool is_64bit)
 {
     void *start = p;
 
     init_cmdline(info, p, start);
     p += COMMAND_LINE_SIZE;
 
-    init_systab(info, p, start);
+    if (is_64bit)
+        init_systab_64(info, p, start);
+    else
+        init_systab_32(info, p, start);
 }
 
 static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
 {
     void *p, *bp;
     int64_t kernel_addr = 0;
-    LoongArchCPU *lacpu;
+    LoongArchCPU *lacpu = LOONGARCH_CPU(first_cpu);
     CPUState *cs;
 
     if (info->kernel_filename) {
@@ -294,7 +374,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
     /* Load cmdline and system tables at [0 - 1 MiB] */
     p = g_malloc0(1 * MiB);
     bp = p;
-    init_boot_rom(info, p);
+    init_boot_rom(info, p, is_la64(&lacpu->env));
     rom_add_blob_fixed_as("boot_info", bp, 1 * MiB, 0, &address_space_memory);
 
     /* Load slave boot code at pflash0 . */
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index b3b870df1f09..96ec15016a31 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -38,11 +38,35 @@ typedef struct {
         EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5,  0x83, 0x0b, \
                  0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
 
+/* Memory types: */
+#define EFI_RESERVED_TYPE           0
+#define EFI_LOADER_CODE             1
+#define EFI_LOADER_DATA             2
+#define EFI_BOOT_SERVICES_CODE      3
+#define EFI_BOOT_SERVICES_DATA      4
+#define EFI_RUNTIME_SERVICES_CODE   5
+#define EFI_RUNTIME_SERVICES_DATA   6
+#define EFI_CONVENTIONAL_MEMORY     7
+#define EFI_UNUSABLE_MEMORY         8
+#define EFI_ACPI_RECLAIM_MEMORY     9
+#define EFI_ACPI_MEMORY_NVS         10
+#define EFI_MEMORY_MAPPED_IO        11
+#define EFI_MEMORY_MAPPED_IO_PORT_SPACE 12
+#define EFI_PAL_CODE                13
+#define EFI_PERSISTENT_MEMORY       14
+#define EFI_UNACCEPTED_MEMORY       15
+#define EFI_MAX_MEMORY_TYPE         16
+
+#define EFI_PAGE_SHIFT      12
+#define EFI_PAGE_SIZE       (1UL << EFI_PAGE_SHIFT)
+
+#define EFI_TABLE_ALIGN     (64 * KiB)
+
 struct efi_config_table {
     efi_guid_t guid;
     uint64_t *ptr;
     const char name[16];
-};
+} QEMU_PACKED;
 
 typedef struct {
     uint64_t signature;
@@ -50,51 +74,90 @@ typedef struct {
     uint32_t headersize;
     uint32_t crc32;
     uint32_t reserved;
-} efi_table_hdr_t;
+} QEMU_PACKED efi_table_hdr_t;
 
-struct efi_configuration_table {
+struct efi_configuration_table_32 {
     efi_guid_t guid;
-    void *table;
-};
+    uint32_t table;
+} QEMU_PACKED;
 
-struct efi_system_table {
+struct efi_configuration_table_64 {
+    efi_guid_t guid;
+    uint64_t table;
+} QEMU_PACKED;
+
+struct efi_system_table_32 {
+    efi_table_hdr_t hdr;
+    uint32_t fw_vendor;        /* physical addr of CHAR16 vendor string */
+    uint32_t fw_revision;
+    uint32_t con_in_handle;
+    uint32_t con_in;
+    uint32_t con_out_handle;
+    uint32_t con_out;
+    uint32_t stderr_handle;
+    uint32_t stderr_placeholder;
+    uint32_t runtime;
+    uint32_t boottime;
+    uint32_t nr_tables;
+    uint32_t tables;
+} QEMU_PACKED;
+
+struct efi_system_table_64 {
     efi_table_hdr_t hdr;
     uint64_t fw_vendor;        /* physical addr of CHAR16 vendor string */
     uint32_t fw_revision;
+    uint32_t __pad1;
     uint64_t con_in_handle;
-    uint64_t *con_in;
+    uint64_t con_in;
     uint64_t con_out_handle;
-    uint64_t *con_out;
+    uint64_t con_out;
     uint64_t stderr_handle;
     uint64_t stderr_placeholder;
-    uint64_t *runtime;
-    uint64_t *boottime;
-    uint64_t nr_tables;
-    struct efi_configuration_table *tables;
-};
+    uint64_t runtime;
+    uint64_t boottime;
+    uint32_t nr_tables;
+    uint32_t __pad2;
+    uint64_t tables;
+} QEMU_PACKED;
 
 typedef struct {
     uint32_t type;
-    uint32_t pad;
+    uint32_t __pad;
     uint64_t phys_addr;
     uint64_t virt_addr;
     uint64_t num_pages;
     uint64_t attribute;
-} efi_memory_desc_t;
+} QEMU_PACKED efi_memory_desc_t;
+
+struct efi_boot_memmap_32 {
+    uint32_t map_size;
+    uint32_t desc_size;
+    uint32_t desc_ver;
+    uint32_t map_key;
+    uint32_t buff_size;
+    uint32_t __pad;
+    efi_memory_desc_t map[32];
+} QEMU_PACKED;
 
-struct efi_boot_memmap {
+struct efi_boot_memmap_64 {
     uint64_t map_size;
     uint64_t desc_size;
     uint32_t desc_ver;
+    uint32_t __pad;
     uint64_t map_key;
     uint64_t buff_size;
     efi_memory_desc_t map[32];
-};
+} QEMU_PACKED;
+
+struct efi_initrd_32 {
+    uint32_t base;
+    uint32_t size;
+} QEMU_PACKED;
 
-struct efi_initrd {
+struct efi_initrd_64 {
     uint64_t base;
     uint64_t size;
-};
+} QEMU_PACKED;
 
 struct loongarch_boot_info {
     uint64_t ram_size;
@@ -110,6 +173,11 @@ extern unsigned memmap_entries;
 struct memmap_entry {
     uint64_t address;
     uint64_t length;
+    /* E820 style type */
+#define MEMMAP_TYPE_MEMORY      1
+#define MEMMAP_TYPE_RESERVED    2
+#define MEMMAP_TYPE_ACPI        3
+#define MEMMAP_TYPE_NVS         4
     uint32_t type;
     uint32_t reserved;
 };

-- 
2.46.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] hw/loongarch/boot: Rework boot code generation
  2024-09-14 12:10 [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
  2024-09-14 12:10 ` [PATCH 1/2] hw/loongarch/boot: Refactor EFI booting protocol generation Jiaxun Yang
@ 2024-09-14 12:10 ` Jiaxun Yang
  2024-09-19 11:31 ` [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-09-14 12:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Song Gao, Jiaxun Yang

Use stl_p to write instructions so that host endian conversion
will be performed.

Replace mailbox read/write on LoongArch32 systems with 32bit IOCSR
instructions to prevent illegal instructions.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 hw/loongarch/boot.c | 107 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 59 insertions(+), 48 deletions(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 4d01c01594e2..5a1cc5b79b41 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -22,53 +22,64 @@ unsigned memmap_entries;
 ram_addr_t initrd_offset;
 uint64_t initrd_size;
 
-static const unsigned int slave_boot_code[] = {
-                  /* Configure reset ebase.                    */
-    0x0400302c,   /* csrwr      $t0, LOONGARCH_CSR_EENTRY      */
-
-                  /* Disable interrupt.                        */
-    0x0380100c,   /* ori        $t0, $zero,0x4                 */
-    0x04000180,   /* csrxchg    $zero, $t0, LOONGARCH_CSR_CRMD */
-
-                  /* Clear mailbox.                            */
-    0x1400002d,   /* lu12i.w    $t1, 1(0x1)                    */
-    0x038081ad,   /* ori        $t1, $t1, CORE_BUF_20          */
-    0x06481da0,   /* iocsrwr.d  $zero, $t1                     */
-
-                  /* Enable IPI interrupt.                     */
-    0x1400002c,   /* lu12i.w    $t0, 1(0x1)                    */
-    0x0400118c,   /* csrxchg    $t0, $t0, LOONGARCH_CSR_ECFG   */
-    0x02fffc0c,   /* addi.d     $t0, $r0,-1(0xfff)             */
-    0x1400002d,   /* lu12i.w    $t1, 1(0x1)                    */
-    0x038011ad,   /* ori        $t1, $t1, CORE_EN_OFF          */
-    0x064819ac,   /* iocsrwr.w  $t0, $t1                       */
-    0x1400002d,   /* lu12i.w    $t1, 1(0x1)                    */
-    0x038081ad,   /* ori        $t1, $t1, CORE_BUF_20          */
-
-                  /* Wait for wakeup  <.L11>:                  */
-    0x06488000,   /* idle       0x0                            */
-    0x03400000,   /* andi       $zero, $zero, 0x0              */
-    0x064809ac,   /* iocsrrd.w  $t0, $t1                       */
-    0x43fff59f,   /* beqz       $t0, -12(0x7ffff4) # 48 <.L11> */
-
-                  /* Read and clear IPI interrupt.             */
-    0x1400002d,   /* lu12i.w    $t1, 1(0x1)                    */
-    0x064809ac,   /* iocsrrd.w  $t0, $t1                       */
-    0x1400002d,   /* lu12i.w    $t1, 1(0x1)                    */
-    0x038031ad,   /* ori        $t1, $t1, CORE_CLEAR_OFF       */
-    0x064819ac,   /* iocsrwr.w  $t0, $t1                       */
-
-                  /* Disable  IPI interrupt.                   */
-    0x1400002c,   /* lu12i.w    $t0, 1(0x1)                    */
-    0x04001180,   /* csrxchg    $zero, $t0, LOONGARCH_CSR_ECFG */
-
-                  /* Read mail buf and jump to specified entry */
-    0x1400002d,   /* lu12i.w    $t1, 1(0x1)                    */
-    0x038081ad,   /* ori        $t1, $t1, CORE_BUF_20          */
-    0x06480dac,   /* iocsrrd.d  $t0, $t1                       */
-    0x00150181,   /* move       $ra, $t0                       */
-    0x4c000020,   /* jirl       $zero, $ra,0                   */
-};
+static void generate_secondary_boot_code(void *boot_code, bool is_64bit)
+{
+    uint32_t *p = boot_code;
+
+    /* Configure reset ebase. */
+    stl_p(p++, 0x0400302c); /* csrwr      $t0, LOONGARCH_CSR_EENTRY  */
+
+    /* Disable interrupt. */
+    stl_p(p++, 0x0380100c); /* ori        $t0, $zero,0x4             */
+    stl_p(p++, 0x04000180); /* csrxchg    $zero, $t0, LOONGARCH_CSR_CRMD */
+
+    /* Clear mailbox. */
+    stl_p(p++, 0x1400002d); /* lu12i.w    $t1, 1(0x1)                */
+    stl_p(p++, 0x038081ad); /* ori        $t1, $t1, CORE_BUF_20      */
+    if (is_64bit) {
+        stl_p(p++, 0x06481da0); /* iocsrwr.d  $zero, $t1             */
+    } else {
+        stl_p(p++, 0x064819a0); /* iocsrwr.w  $zero, $t1             */
+    }
+
+    /* Enable IPI interrupt. */
+    stl_p(p++, 0x1400002c); /* lu12i.w    $t0, 1(0x1)                */
+    stl_p(p++, 0x0400118c); /* csrxchg    $t0, $t0, LOONGARCH_CSR_ECFG */
+    stl_p(p++, 0x02fffc0c); /* addi.d     $t0, $r0, -1(0xfff)        */
+    stl_p(p++, 0x1400002d); /* lu12i.w    $t1, 1(0x1)                */
+    stl_p(p++, 0x038011ad); /* ori        $t1, $t1, CORE_EN_OFF      */
+    stl_p(p++, 0x064819ac); /* iocsrwr.w  $t0, $t1                   */
+    stl_p(p++, 0x1400002d); /* lu12i.w    $t1, 1(0x1)                */
+    stl_p(p++, 0x038081ad); /* ori        $t1, $t1, CORE_BUF_20      */
+
+    /* Wait for wakeup <.L11>: */
+    stl_p(p++, 0x06488000); /* idle       0x0                        */
+    stl_p(p++, 0x03400000); /* andi       $zero, $zero, 0x0          */
+    stl_p(p++, 0x064809ac); /* iocsrrd.w  $t0, $t1                   */
+    stl_p(p++, 0x43fff59f); /* beqz       $t0, -12(0x7ffff4) # 48 <.L11> */
+
+    /* Read and clear IPI interrupt. */
+    stl_p(p++, 0x1400002d); /* lu12i.w    $t1, 1(0x1)                */
+    stl_p(p++, 0x064809ac); /* iocsrrd.w  $t0, $t1                   */
+    stl_p(p++, 0x1400002d); /* lu12i.w    $t1, 1(0x1)                */
+    stl_p(p++, 0x038031ad); /* ori        $t1, $t1, CORE_CLEAR_OFF   */
+    stl_p(p++, 0x064819ac); /* iocsrwr.w  $t0, $t1                   */
+
+    /* Disable IPI interrupt. */
+    stl_p(p++, 0x1400002c); /* lu12i.w    $t0, 1(0x1)                */
+    stl_p(p++, 0x04001180); /* csrxchg    $zero, $t0, LOONGARCH_CSR_ECFG */
+
+    /* Read mail buf and jump to specified entry. */
+    stl_p(p++, 0x1400002d); /* lu12i.w    $t1, 1(0x1)                */
+    stl_p(p++, 0x038081ad); /* ori        $t1, $t1, CORE_BUF_20      */
+    if (is_64bit) {
+        stl_p(p++, 0x06480dac); /* iocsrrd.d  $t0, $t1               */
+    } else {
+        stl_p(p++, 0x064809ac); /* iocsrrd.w  $t0, $t1               */
+    }
+    stl_p(p++, 0x00150181); /* move       $ra, $t0                   */
+    stl_p(p++, 0x4c000020); /* jirl       $zero, $ra, 0              */
+}
 
 static inline void *guidcpy(void *dst, const void *src)
 {
@@ -379,7 +390,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
 
     /* Load slave boot code at pflash0 . */
     void *boot_code = g_malloc0(VIRT_FLASH0_SIZE);
-    memcpy(boot_code, &slave_boot_code, sizeof(slave_boot_code));
+    generate_secondary_boot_code(boot_code, is_la64(&lacpu->env));
     rom_add_blob_fixed("boot_code", boot_code, VIRT_FLASH0_SIZE, VIRT_FLASH0_BASE);
 
     CPU_FOREACH(cs) {

-- 
2.46.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring
  2024-09-14 12:10 [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
  2024-09-14 12:10 ` [PATCH 1/2] hw/loongarch/boot: Refactor EFI booting protocol generation Jiaxun Yang
  2024-09-14 12:10 ` [PATCH 2/2] hw/loongarch/boot: Rework boot code generation Jiaxun Yang
@ 2024-09-19 11:31 ` Jiaxun Yang
  2024-09-23 11:18   ` Jiaxun Yang
  2024-09-23 12:34 ` gaosong
  2024-09-29  7:51 ` gaosong
  4 siblings, 1 reply; 8+ messages in thread
From: Jiaxun Yang @ 2024-09-19 11:31 UTC (permalink / raw)
  To: QEMU devel; +Cc: Song Gao, Bibo Mao



在2024年9月14日九月 下午1:10,Jiaxun Yang写道:
> Hi all,
>
> This series refactored booting protocol generation code
> to better accommodate different host ABI / Alignment and
> endianess.

+ Bibo,

Ping for review.

Thanks

>
> It also enhanced LoongArch32 support.
>
> Thanks
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
> Jiaxun Yang (2):
>       hw/loongarch/boot: Refactor EFI booting protocol generation
>       hw/loongarch/boot: Rework boot code generation
>
>  hw/loongarch/boot.c         | 321 ++++++++++++++++++++++++++++----------------
>  include/hw/loongarch/boot.h | 106 ++++++++++++---
>  2 files changed, 293 insertions(+), 134 deletions(-)
> ---
> base-commit: 28ae3179fc52d2e4d870b635c4a412aab99759e7
> change-id: 20240914-loongarch-booting-b5ae3f4976b7
>
> Best regards,
> -- 
> Jiaxun Yang <jiaxun.yang@flygoat.com>

-- 
- Jiaxun


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring
  2024-09-19 11:31 ` [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
@ 2024-09-23 11:18   ` Jiaxun Yang
  0 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-09-23 11:18 UTC (permalink / raw)
  To: QEMU devel; +Cc: Song Gao, Bibo Mao



在2024年9月19日九月 下午12:31,Jiaxun Yang写道:
> 在2024年9月14日九月 下午1:10,Jiaxun Yang写道:
>> Hi all,
>>
>> This series refactored booting protocol generation code
>> to better accommodate different host ABI / Alignment and
>> endianess.
>
> + Bibo,
>
> Ping for review.

Ping?

Thanks


-- 
- Jiaxun


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring
  2024-09-14 12:10 [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
                   ` (2 preceding siblings ...)
  2024-09-19 11:31 ` [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
@ 2024-09-23 12:34 ` gaosong
  2024-09-23 14:43   ` Jiaxun Yang
  2024-09-29  7:51 ` gaosong
  4 siblings, 1 reply; 8+ messages in thread
From: gaosong @ 2024-09-23 12:34 UTC (permalink / raw)
  To: Jiaxun Yang, qemu-devel; +Cc: bibo mao

在 2024/9/14 下午8:10, Jiaxun Yang 写道:
> Hi all,
>
> This series refactored booting protocol generation code
> to better accommodate different host ABI / Alignment and
> endianess.
>
> It also enhanced LoongArch32 support.
Hi,

I tested LoongArch64 and it works well.

But how to test LoongArch32? Could you provide an example?

Thanks.
Song Gao
> Thanks
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
> Jiaxun Yang (2):
>        hw/loongarch/boot: Refactor EFI booting protocol generation
>        hw/loongarch/boot: Rework boot code generation
>
>   hw/loongarch/boot.c         | 321 ++++++++++++++++++++++++++++----------------
>   include/hw/loongarch/boot.h | 106 ++++++++++++---
>   2 files changed, 293 insertions(+), 134 deletions(-)
> ---
> base-commit: 28ae3179fc52d2e4d870b635c4a412aab99759e7
> change-id: 20240914-loongarch-booting-b5ae3f4976b7
>
> Best regards,



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring
  2024-09-23 12:34 ` gaosong
@ 2024-09-23 14:43   ` Jiaxun Yang
  0 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-09-23 14:43 UTC (permalink / raw)
  To: gaosong, QEMU devel; +Cc: Bibo Mao



在2024年9月23日九月 下午1:34,gaosong写道:
> 在 2024/9/14 下午8:10, Jiaxun Yang 写道:
>> Hi all,
>>
>> This series refactored booting protocol generation code
>> to better accommodate different host ABI / Alignment and
>> endianess.
>>
>> It also enhanced LoongArch32 support.
> Hi,
>
> I tested LoongArch64 and it works well.
>
> But how to test LoongArch32? Could you provide an example?

I have a W.I.P. LoonngArch 32 kernel tree[1] that can boot in QEMU,
but it still requires many other fixes in QEMU TCG.

32-bit stuff is just a bonus to this series and the main motivation
is to improve booting protocol quality.

Thanks

[1]: https://github.com/FlyGoat/linux/tree/b4/la32
>
> Thanks.
> Song Gao
>> Thanks
>>
>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> ---
>> Jiaxun Yang (2):
>>        hw/loongarch/boot: Refactor EFI booting protocol generation
>>        hw/loongarch/boot: Rework boot code generation
>>
>>   hw/loongarch/boot.c         | 321 ++++++++++++++++++++++++++++----------------
>>   include/hw/loongarch/boot.h | 106 ++++++++++++---
>>   2 files changed, 293 insertions(+), 134 deletions(-)
>> ---
>> base-commit: 28ae3179fc52d2e4d870b635c4a412aab99759e7
>> change-id: 20240914-loongarch-booting-b5ae3f4976b7
>>
>> Best regards,

-- 
- Jiaxun


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring
  2024-09-14 12:10 [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
                   ` (3 preceding siblings ...)
  2024-09-23 12:34 ` gaosong
@ 2024-09-29  7:51 ` gaosong
  4 siblings, 0 replies; 8+ messages in thread
From: gaosong @ 2024-09-29  7:51 UTC (permalink / raw)
  To: Jiaxun Yang, qemu-devel

在 2024/9/14 下午8:10, Jiaxun Yang 写道:
> Hi all,
>
> This series refactored booting protocol generation code
> to better accommodate different host ABI / Alignment and
> endianess.
>
> It also enhanced LoongArch32 support.
>
> Thanks
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
> Jiaxun Yang (2):
>        hw/loongarch/boot: Refactor EFI booting protocol generation
>        hw/loongarch/boot: Rework boot code generation
>
>   hw/loongarch/boot.c         | 321 ++++++++++++++++++++++++++++----------------
>   include/hw/loongarch/boot.h | 106 ++++++++++++---
>   2 files changed, 293 insertions(+), 134 deletions(-)
> ---
> base-commit: 28ae3179fc52d2e4d870b635c4a412aab99759e7
> change-id: 20240914-loongarch-booting-b5ae3f4976b7
>
> Best regards,
For this series,
Reviewed-by: Song Gao <gaosong@loongson.cn>

Applied to loongarch-next,

Thanks.
Song Gao



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-09-29  7:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-14 12:10 [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
2024-09-14 12:10 ` [PATCH 1/2] hw/loongarch/boot: Refactor EFI booting protocol generation Jiaxun Yang
2024-09-14 12:10 ` [PATCH 2/2] hw/loongarch/boot: Rework boot code generation Jiaxun Yang
2024-09-19 11:31 ` [PATCH 0/2] hw/loongarch/booting: Booting protocol refactoring Jiaxun Yang
2024-09-23 11:18   ` Jiaxun Yang
2024-09-23 12:34 ` gaosong
2024-09-23 14:43   ` Jiaxun Yang
2024-09-29  7:51 ` gaosong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).