[snip]
So how does the core kernel consume the EFI memory map? Only throughYes, this different representation is used by our "boot_params", theAre you passing a different representation of the memory map to the+
+static efi_status_t mk_mmap(struct efi_boot_memmap *map, struct boot_params *p)
+{
core kernel? I think it would be easier just to pass the EFI memory
map like other EFI arches do, and reuse all of the code that we
already have.
interface between bootloader (including efistub) and the core kernel.
this mechanism?
OK, I understand. So using the generic stub is not possible for you.Hmmm, as I know, we define our own "boot_params", a interface betweenWhy are you not using the generic EFI stub boot flow?+ char checksum;
+ unsigned int i;
+ unsigned int nr_desc;
+ unsigned int mem_type;
+ unsigned long count;
+ efi_memory_desc_t *mem_desc;
+ struct loongsonlist_mem_map *mhp = NULL;
+
+ memset(map_entry, 0, sizeof(map_entry));
+ memset(mmap_array, 0, sizeof(mmap_array));
+
+ if (!strncmp((char *)p, "BPI", 3)) {
+ p->flags |= BPI_FLAGS_UEFI_SUPPORTED;
+ p->systemtable = (efi_system_table_t *)efi_system_table;
+ p->extlist_offset = sizeof(*p) + sizeof(unsigned long);
+ mhp = (struct loongsonlist_mem_map *)((char *)p + p->extlist_offset);
+
+ memcpy(&mhp->header.signature, "MEM", sizeof(unsigned long));
+ mhp->header.length = sizeof(*mhp);
+ mhp->desc_version = *map->desc_ver;
+ mhp->map_count = 0;
+ }
+ if (!(*(map->map_size)) || !(*(map->desc_size)) || !mhp) {
+ efi_err("get memory info error\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ nr_desc = *(map->map_size) / *(map->desc_size);
+
+ /*
+ * According to UEFI SPEC, mmap_buf is the accurate Memory Map
+ * mmap_array now we can fill platform specific memory structure.
+ */
+ for (i = 0; i < nr_desc; i++) {
+ mem_desc = (efi_memory_desc_t *)((void *)(*map->map) + (i * (*(map->desc_size))));
+ switch (mem_desc->type) {
+ case EFI_RESERVED_TYPE:
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_MEMORY_MAPPED_IO:
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ case EFI_UNUSABLE_MEMORY:
+ case EFI_PAL_CODE:
+ mem_type = ADDRESS_TYPE_RESERVED;
+ break;
+
+ case EFI_ACPI_MEMORY_NVS:
+ mem_type = ADDRESS_TYPE_NVS;
+ break;
+
+ case EFI_ACPI_RECLAIM_MEMORY:
+ mem_type = ADDRESS_TYPE_ACPI;
+ break;
+
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_PERSISTENT_MEMORY:
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_CONVENTIONAL_MEMORY:
+ mem_type = ADDRESS_TYPE_SYSRAM;
+ break;
+
+ default:
+ continue;
+ }
+
+ mmap_array[mem_type][map_entry[mem_type]].mem_type = mem_type;
+ mmap_array[mem_type][map_entry[mem_type]].mem_start =
+ mem_desc->phys_addr & TO_PHYS_MASK;
+ mmap_array[mem_type][map_entry[mem_type]].mem_size =
+ mem_desc->num_pages << EFI_PAGE_SHIFT;
+ mmap_array[mem_type][map_entry[mem_type]].attribute =
+ mem_desc->attribute;
+ map_entry[mem_type]++;
+ }
+
+ count = mhp->map_count;
+ /* Sort EFI memmap and add to BPI for kernel */
+ for (i = 0; i < LOONGSON3_BOOT_MEM_MAP_MAX; i++) {
+ if (!map_entry[i])
+ continue;
+ count = efi_memmap_sort(mhp, count, i);
+ }
+
+ mhp->map_count = count;
+ mhp->header.checksum = 0;
+
+ checksum = efi_crc8((char *)mhp, mhp->header.length);
+ mhp->header.checksum = checksum;
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
+{
+ efi_status_t status;
+ struct exit_boot_struct *p = priv;
+
+ status = mk_mmap(map, p->bp);
+ if (status != EFI_SUCCESS) {
+ efi_err("Make kernel memory map failed!\n");
+ return status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+static efi_status_t exit_boot_services(struct boot_params *boot_params, void *handle)
+{
+ unsigned int desc_version;
+ unsigned int runtime_entry_count = 0;
+ unsigned long map_size, key, desc_size, buff_size;
+ efi_status_t status;
+ efi_memory_desc_t *mem_map;
+ struct efi_boot_memmap map;
+ struct exit_boot_struct priv;
+
+ map.map = &mem_map;
+ map.map_size = &map_size;
+ map.desc_size = &desc_size;
+ map.desc_ver = &desc_version;
+ map.key_ptr = &key;
+ map.buff_size = &buff_size;
+ status = efi_get_memory_map(&map);
+ if (status != EFI_SUCCESS) {
+ efi_err("Unable to retrieve UEFI memory map.\n");
+ return status;
+ }
+
+ priv.bp = boot_params;
+ priv.runtime_entry_count = &runtime_entry_count;
+
+ /* Might as well exit boot services now */
+ status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ return EFI_SUCCESS;
+}
+
+/*
+ * EFI entry point for the LoongArch EFI stub.
+ */
+efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, efi_system_table_t *sys_table)
bootloader (including efistub) and the core kernel to pass memmap,
cmdline and initrd information, three years ago. This method looks
like the X86 way, while different from the generic stub (which is
called arm stub before 5.8). In these years, many products have
already use the "boot_params" interface (including UEFI, PMON, Grub,
Kernel, etc., but most of them haven't be upstream). Replace
boot_params with FDT (i.e., the generic stub way) is difficult for us,
because it means a big broken of compatibility.
So as long as you don't enable deprecated features such as initrd=, or
rely on special hacks like putting magic numbers at fixed offsets in
the image, I'm fine with this approach.