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
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) > { >
在 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) >> { >>
© 2016 - 2024 Red Hat, Inc.