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 - 2026 Red Hat, Inc.