Re: [PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table
在 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 Message-Id: <20240307164835.300412-7-gaos...@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[] = { 0x4c20, /* 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 + 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/loonga
Re: [PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table
On 2024/4/26 下午5:15, Song Gao wrote: Message test is also missing there :( Signed-off-by: Song Gao Message-Id: <20240307164835.300412-7-gaos...@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[] = { 0x4c20, /* 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 + 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 memm
[PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table
Signed-off-by: Song Gao Message-Id: <20240307164835.300412-7-gaos...@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[] = { 0x4c20, /* 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(ui