Message ID | 20240307164835.300412-7-gaosong@loongson.cn |
---|---|
State | New |
Headers | show |
Series | Add boot LoongArch elf kernel with FDT | expand |
On 2024/3/8 上午12:48, Song Gao wrote: > Signed-off-by: Song Gao <gaosong@loongson.cn> > Message-Id: <20240301093839.663947-7-gaosong@loongson.cn> > --- > hw/loongarch/boot.c | 39 +++++++++++++++++++++++++++++++++++++ > hw/loongarch/virt.c | 11 ++--------- > include/hw/loongarch/boot.h | 27 +++++++++++++++++++++++++ > include/hw/loongarch/virt.h | 10 ++++++++++ > 4 files changed, 78 insertions(+), 9 deletions(-) > > diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c > index 1e31e2a59f..2896c1ea40 100644 > --- a/hw/loongarch/boot.c > +++ b/hw/loongarch/boot.c > @@ -63,8 +63,40 @@ static const unsigned int slave_boot_code[] = { > 0x4c000020, /* jirl $r0,$r1,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 = memmap_table[i].address; > + map[i].num_pages = memmap_table[i].length >> 16; /* 64KB align*/ 64KB aligned or 64KB page size? In generic page size is 4K by EFI spec IIRC. Regards Bibo Mao > + 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 +112,13 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start) > p += ROUND_UP(sizeof(struct efi_system_table), 64); > > 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); > + > + 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 bbd5cc1d4d..8981b57b12 100644 > --- a/hw/loongarch/virt.c > +++ b/hw/loongarch/virt.c > @@ -377,15 +377,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) > { > diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h > index 65ad406f02..f71c693f43 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 __attribute__((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; >
在 2024/3/8 16:37, maobibo 写道: > > > On 2024/3/8 上午12:48, Song Gao wrote: >> Signed-off-by: Song Gao <gaosong@loongson.cn> >> Message-Id: <20240301093839.663947-7-gaosong@loongson.cn> >> --- >> hw/loongarch/boot.c | 39 +++++++++++++++++++++++++++++++++++++ >> hw/loongarch/virt.c | 11 ++--------- >> include/hw/loongarch/boot.h | 27 +++++++++++++++++++++++++ >> include/hw/loongarch/virt.h | 10 ++++++++++ >> 4 files changed, 78 insertions(+), 9 deletions(-) >> >> diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c >> index 1e31e2a59f..2896c1ea40 100644 >> --- a/hw/loongarch/boot.c >> +++ b/hw/loongarch/boot.c >> @@ -63,8 +63,40 @@ static const unsigned int slave_boot_code[] = { >> 0x4c000020, /* jirl $r0,$r1,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 = memmap_table[i].address; >> + map[i].num_pages = memmap_table[i].length >> 16; /* 64KB align*/ > 64KB aligned or 64KB page size? In generic page size is 4K by EFI spec > IIRC. > Thank you for pointing it out., I will correct it on v7. > Regards > Bibo Mao > >> + 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 +112,13 @@ static void init_systab(struct loongarch_boot_info >> *info, void *p, void *start) >> p += ROUND_UP(sizeof(struct efi_system_table), 64); >> 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); >> + >> + 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 bbd5cc1d4d..8981b57b12 100644 >> --- a/hw/loongarch/virt.c >> +++ b/hw/loongarch/virt.c >> @@ -377,15 +377,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) >> { >> diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h >> index 65ad406f02..f71c693f43 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 __attribute__((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 1e31e2a59f..2896c1ea40 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -63,8 +63,40 @@ static const unsigned int slave_boot_code[] = { 0x4c000020, /* jirl $r0,$r1,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 = memmap_table[i].address; + map[i].num_pages = memmap_table[i].length >> 16; /* 64KB align*/ + 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 +112,13 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start) p += ROUND_UP(sizeof(struct efi_system_table), 64); 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); + + 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 bbd5cc1d4d..8981b57b12 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -377,15 +377,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) { diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h index 65ad406f02..f71c693f43 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 __attribute__((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;
Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20240301093839.663947-7-gaosong@loongson.cn> --- hw/loongarch/boot.c | 39 +++++++++++++++++++++++++++++++++++++ hw/loongarch/virt.c | 11 ++--------- include/hw/loongarch/boot.h | 27 +++++++++++++++++++++++++ include/hw/loongarch/virt.h | 10 ++++++++++ 4 files changed, 78 insertions(+), 9 deletions(-)