[PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table

Song Gao posted 17 patches 6 months, 3 weeks ago
Maintainers: Song Gao <gaosong@loongson.cn>
[PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table
Posted by Song Gao 6 months, 3 weeks ago
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-Id: <20240307164835.300412-7-gaosong@loongson.cn>
---
 include/hw/loongarch/boot.h | 27 +++++++++++++++++++++++++
 include/hw/loongarch/virt.h | 10 ++++++++++
 hw/loongarch/boot.c         | 40 +++++++++++++++++++++++++++++++++++++
 hw/loongarch/virt.c         | 11 ++--------
 4 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index cf0e4d4f91..76622af2e2 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -21,6 +21,15 @@ typedef struct {
     uint8_t b[16];
 } efi_guid_t QEMU_ALIGNED(8);
 
+#define EFI_GUID(a, b, c, d...) (efi_guid_t){ {                                \
+        (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+        (b) & 0xff, ((b) >> 8) & 0xff,                                         \
+        (c) & 0xff, ((c) >> 8) & 0xff, d } }
+
+#define LINUX_EFI_BOOT_MEMMAP_GUID \
+        EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, \
+                 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
+
 struct efi_config_table {
     efi_guid_t guid;
     uint64_t *ptr;
@@ -56,6 +65,24 @@ struct efi_system_table {
     struct efi_configuration_table *tables;
 };
 
+typedef struct {
+    uint32_t type;
+    uint32_t pad;
+    uint64_t phys_addr;
+    uint64_t virt_addr;
+    uint64_t num_pages;
+    uint64_t attribute;
+} efi_memory_desc_t;
+
+struct efi_boot_memmap {
+    uint64_t map_size;
+    uint64_t desc_size;
+    uint32_t desc_ver;
+    uint64_t map_key;
+    uint64_t buff_size;
+    efi_memory_desc_t map[32];
+};
+
 struct loongarch_boot_info {
     uint64_t ram_size;
     const char *kernel_filename;
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index d7a074d69f..8a9fe4053d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -35,6 +35,16 @@
 
 #define COMMAND_LINE_SIZE       512
 
+extern struct memmap_entry *memmap_table;
+extern unsigned memmap_entries;
+
+struct memmap_entry {
+    uint64_t address;
+    uint64_t length;
+    uint32_t type;
+    uint32_t reserved;
+};
+
 struct LoongArchMachineState {
     /*< private >*/
     MachineState parent_obj;
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 46a241a04c..18aae3434d 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -63,8 +63,41 @@ static const unsigned int slave_boot_code[] = {
     0x4c000020,   /* jirl       $zero, $ra,0                   */
 };
 
+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)
+{
+    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;
+
+    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);
+    }
+}
+
 static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
 {
+    void *bp_tables_start;
     struct efi_system_table *systab = p;
 
     info->a2 = (uint64_t)p - (uint64_t)start;
@@ -80,6 +113,13 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
     p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB);
 
     systab->tables = p;
+    bp_tables_start = p;
+
+    init_efi_boot_memmap(systab, p, start);
+    p += ROUND_UP(sizeof(struct efi_boot_memmap) +
+                  sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB);
+
+    systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);
 }
 
 static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index bfb88aedab..708aa8bc60 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -378,15 +378,8 @@ static void virt_powerdown_req(Notifier *notifier, void *opaque)
     acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
 }
 
-struct memmap_entry {
-    uint64_t address;
-    uint64_t length;
-    uint32_t type;
-    uint32_t reserved;
-};
-
-static struct memmap_entry *memmap_table;
-static unsigned memmap_entries;
+struct memmap_entry *memmap_table;
+unsigned memmap_entries;
 
 static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
 {
-- 
2.25.1
Re: [PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table
Posted by maobibo 6 months, 2 weeks ago

On 2024/4/26 下午5:15, Song Gao wrote:

Message test is also missing there :(

> Signed-off-by: Song Gao <gaosong@loongson.cn>
> Message-Id: <20240307164835.300412-7-gaosong@loongson.cn>
> ---
>   include/hw/loongarch/boot.h | 27 +++++++++++++++++++++++++
>   include/hw/loongarch/virt.h | 10 ++++++++++
>   hw/loongarch/boot.c         | 40 +++++++++++++++++++++++++++++++++++++
>   hw/loongarch/virt.c         | 11 ++--------
>   4 files changed, 79 insertions(+), 9 deletions(-)
> 
> diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
> index cf0e4d4f91..76622af2e2 100644
> --- a/include/hw/loongarch/boot.h
> +++ b/include/hw/loongarch/boot.h
> @@ -21,6 +21,15 @@ typedef struct {
>       uint8_t b[16];
>   } efi_guid_t QEMU_ALIGNED(8);
>   
> +#define EFI_GUID(a, b, c, d...) (efi_guid_t){ {                                \
> +        (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
> +        (b) & 0xff, ((b) >> 8) & 0xff,                                         \
> +        (c) & 0xff, ((c) >> 8) & 0xff, d } }
> +
> +#define LINUX_EFI_BOOT_MEMMAP_GUID \
> +        EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, \
> +                 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
> +
>   struct efi_config_table {
>       efi_guid_t guid;
>       uint64_t *ptr;
> @@ -56,6 +65,24 @@ struct efi_system_table {
>       struct efi_configuration_table *tables;
>   };
>   
> +typedef struct {
> +    uint32_t type;
> +    uint32_t pad;
> +    uint64_t phys_addr;
> +    uint64_t virt_addr;
> +    uint64_t num_pages;
> +    uint64_t attribute;
> +} efi_memory_desc_t;
> +
> +struct efi_boot_memmap {
> +    uint64_t map_size;
> +    uint64_t desc_size;
> +    uint32_t desc_ver;
> +    uint64_t map_key;
> +    uint64_t buff_size;
> +    efi_memory_desc_t map[32];
> +};
> +
>   struct loongarch_boot_info {
>       uint64_t ram_size;
>       const char *kernel_filename;
> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
> index d7a074d69f..8a9fe4053d 100644
> --- a/include/hw/loongarch/virt.h
> +++ b/include/hw/loongarch/virt.h
> @@ -35,6 +35,16 @@
>   
>   #define COMMAND_LINE_SIZE       512
>   
> +extern struct memmap_entry *memmap_table;
> +extern unsigned memmap_entries;
> +
> +struct memmap_entry {
> +    uint64_t address;
> +    uint64_t length;
> +    uint32_t type;
> +    uint32_t reserved;
> +};
> +
>   struct LoongArchMachineState {
>       /*< private >*/
>       MachineState parent_obj;
> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
> index 46a241a04c..18aae3434d 100644
> --- a/hw/loongarch/boot.c
> +++ b/hw/loongarch/boot.c
> @@ -63,8 +63,41 @@ static const unsigned int slave_boot_code[] = {
>       0x4c000020,   /* jirl       $zero, $ra,0                   */
>   };
>   
> +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)
> +{
> +    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;
> +
> +    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);
> +    }
> +}

Do you verify that memory size of VM is the same with qemu command line 
setting? I am ok if the test result is the same.

Reviewed-by: Bibo Mao <maobibo@loongson.cn>
> +
>   static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
>   {
> +    void *bp_tables_start;
>       struct efi_system_table *systab = p;
>   
>       info->a2 = (uint64_t)p - (uint64_t)start;
> @@ -80,6 +113,13 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
>       p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB);
>   
>       systab->tables = p;
> +    bp_tables_start = p;
> +
> +    init_efi_boot_memmap(systab, p, start);
> +    p += ROUND_UP(sizeof(struct efi_boot_memmap) +
> +                  sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB);
> +
> +    systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);
>   }
>   
>   static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index bfb88aedab..708aa8bc60 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -378,15 +378,8 @@ static void virt_powerdown_req(Notifier *notifier, void *opaque)
>       acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
>   }
>   
> -struct memmap_entry {
> -    uint64_t address;
> -    uint64_t length;
> -    uint32_t type;
> -    uint32_t reserved;
> -};
> -
> -static struct memmap_entry *memmap_table;
> -static unsigned memmap_entries;
> +struct memmap_entry *memmap_table;
> +unsigned memmap_entries;
>   
>   static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
>   {
> 


Re: [PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table
Posted by gaosong 6 months, 2 weeks ago
在 2024/4/28 上午9:34, maobibo 写道:
>
>
> On 2024/4/26 下午5:15, Song Gao wrote:
>
> Message test is also missing there :(
>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> Message-Id: <20240307164835.300412-7-gaosong@loongson.cn>
>> ---
>>   include/hw/loongarch/boot.h | 27 +++++++++++++++++++++++++
>>   include/hw/loongarch/virt.h | 10 ++++++++++
>>   hw/loongarch/boot.c         | 40 +++++++++++++++++++++++++++++++++++++
>>   hw/loongarch/virt.c         | 11 ++--------
>>   4 files changed, 79 insertions(+), 9 deletions(-)
>>
>> diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
>> index cf0e4d4f91..76622af2e2 100644
>> --- a/include/hw/loongarch/boot.h
>> +++ b/include/hw/loongarch/boot.h
>> @@ -21,6 +21,15 @@ typedef struct {
>>       uint8_t b[16];
>>   } efi_guid_t QEMU_ALIGNED(8);
>>   +#define EFI_GUID(a, b, c, d...) (efi_guid_t){ 
>> {                                \
>> +        (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 
>> 24) & 0xff, \
>> +        (b) & 0xff, ((b) >> 8) & 
>> 0xff,                                         \
>> +        (c) & 0xff, ((c) >> 8) & 0xff, d } }
>> +
>> +#define LINUX_EFI_BOOT_MEMMAP_GUID \
>> +        EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, \
>> +                 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
>> +
>>   struct efi_config_table {
>>       efi_guid_t guid;
>>       uint64_t *ptr;
>> @@ -56,6 +65,24 @@ struct efi_system_table {
>>       struct efi_configuration_table *tables;
>>   };
>>   +typedef struct {
>> +    uint32_t type;
>> +    uint32_t pad;
>> +    uint64_t phys_addr;
>> +    uint64_t virt_addr;
>> +    uint64_t num_pages;
>> +    uint64_t attribute;
>> +} efi_memory_desc_t;
>> +
>> +struct efi_boot_memmap {
>> +    uint64_t map_size;
>> +    uint64_t desc_size;
>> +    uint32_t desc_ver;
>> +    uint64_t map_key;
>> +    uint64_t buff_size;
>> +    efi_memory_desc_t map[32];
>> +};
>> +
>>   struct loongarch_boot_info {
>>       uint64_t ram_size;
>>       const char *kernel_filename;
>> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
>> index d7a074d69f..8a9fe4053d 100644
>> --- a/include/hw/loongarch/virt.h
>> +++ b/include/hw/loongarch/virt.h
>> @@ -35,6 +35,16 @@
>>     #define COMMAND_LINE_SIZE       512
>>   +extern struct memmap_entry *memmap_table;
>> +extern unsigned memmap_entries;
>> +
>> +struct memmap_entry {
>> +    uint64_t address;
>> +    uint64_t length;
>> +    uint32_t type;
>> +    uint32_t reserved;
>> +};
>> +
>>   struct LoongArchMachineState {
>>       /*< private >*/
>>       MachineState parent_obj;
>> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
>> index 46a241a04c..18aae3434d 100644
>> --- a/hw/loongarch/boot.c
>> +++ b/hw/loongarch/boot.c
>> @@ -63,8 +63,41 @@ static const unsigned int slave_boot_code[] = {
>>       0x4c000020,   /* jirl       $zero, $ra,0 */
>>   };
>>   +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)
>> +{
>> +    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;
>> +
>> +    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);
>> +    }
>> +}
>
> Do you verify that memory size of VM is the same with qemu command 
> line setting? I am ok if the test result is the same.
>
Yes.   e.g 4G

[    4.061717] Run /sbin/init as init process
/ # free -h
               total        used        free      shared buff/cache   
available
Mem:           3.9G       61.3M        3.8G           0 11.4M        3.5G
Swap:             0           0           0

> Reviewed-by: Bibo Mao <maobibo@loongson.cn>
>> +
>>   static void init_systab(struct loongarch_boot_info *info, void *p, 
>> void *start)
>>   {
>> +    void *bp_tables_start;
>>       struct efi_system_table *systab = p;
>>         info->a2 = (uint64_t)p - (uint64_t)start;
>> @@ -80,6 +113,13 @@ static void init_systab(struct 
>> loongarch_boot_info *info, void *p, void *start)
>>       p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB);
>>         systab->tables = p;
>> +    bp_tables_start = p;
>> +
>> +    init_efi_boot_memmap(systab, p, start);
>> +    p += ROUND_UP(sizeof(struct efi_boot_memmap) +
>> +                  sizeof(efi_memory_desc_t) * memmap_entries, 64 * 
>> KiB);
>> +
>> +    systab->tables = (struct efi_configuration_table 
>> *)(bp_tables_start - start);
>>   }
>>     static void init_cmdline(struct loongarch_boot_info *info, void 
>> *p, void *start)
>> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
>> index bfb88aedab..708aa8bc60 100644
>> --- a/hw/loongarch/virt.c
>> +++ b/hw/loongarch/virt.c
>> @@ -378,15 +378,8 @@ static void virt_powerdown_req(Notifier 
>> *notifier, void *opaque)
>>       acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
>>   }
>>   -struct memmap_entry {
>> -    uint64_t address;
>> -    uint64_t length;
>> -    uint32_t type;
>> -    uint32_t reserved;
>> -};
>> -
>> -static struct memmap_entry *memmap_table;
>> -static unsigned memmap_entries;
>> +struct memmap_entry *memmap_table;
>> +unsigned memmap_entries;
>>     static void memmap_add_entry(uint64_t address, uint64_t length, 
>> uint32_t type)
>>   {
>>