linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: WANG Xuerui <kernel@xen0n.name>
To: Ard Biesheuvel <ardb@kernel.org>, Huacai Chen <chenhuacai@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>,
	Huacai Chen <chenhuacai@loongson.cn>,
	Andy Lutomirski <luto@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	David Airlie <airlied@linux.ie>, Jonathan Corbet <corbet@lwn.net>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-arch <linux-arch@vger.kernel.org>,
	"open list:DOCUMENTATION" <linux-doc@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Xuefeng Li <lixuefeng@loongson.cn>,
	Yanteng Si <siyanteng@loongson.cn>, Guo Ren <guoren@kernel.org>,
	Xuerui Wang <kernel@xen0n.name>,
	Jiaxun Yang <jiaxun.yang@flygoat.com>
Subject: Re: [PATCH V9 20/24] LoongArch: Add efistub booting support
Date: Fri, 6 May 2022 19:26:24 +0800	[thread overview]
Message-ID: <a6afaa3f-cb9f-2086-0e02-5ec21ba535d4@xen0n.name> (raw)
In-Reply-To: <CAMj1kXFD8_CuijJFgQbrxvY4MVBLmKQKFKmYhD1NBFLn3v=+FQ@mail.gmail.com>

Hi,

On 5/6/22 16:14, Ard Biesheuvel wrote:
> [snip]
>>>>> +
>>>>> +static efi_status_t mk_mmap(struct efi_boot_memmap *map, struct boot_params *p)
>>>>> +{
>>> Are you passing a different representation of the memory map to the
>>> 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.
>> Yes, this different representation is used by our "boot_params", the
>> interface between bootloader (including efistub) and the core kernel.
> So how does the core kernel consume the EFI memory map? Only through
> this mechanism?
>
>>>>> +       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)
>>> Why are you not using the generic EFI stub boot flow?
>> Hmmm, as I know, we define our own "boot_params", a interface between
>> 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.
>>
> OK, I understand. So using the generic stub is not possible for you.
>
> 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.

I'd like to add some relevant background: this "struct boot_params" 
thingy is actually a Loongson corporate standard. It is available at 
[1]; only in Chinese but should be minimally recognizable given much of 
it is C code, and you can see this struct and its friends barely changed 
since 2019.

The standard is in place long before inception of LoongArch (the 
earliest spec is dated back to 2014). Back when Loongson was still doing 
MIPS this is somewhat acceptable, due to fragmentation of the MIPS 
world, but they didn't take the chance to re-think most of this for 
LoongArch, instead simply porting everything over as-is. Hence the ship 
has more-or-less already sailed, and we indeed have to support this flow 
for keeping compatibility...

Or is there compatibility at all?

It turns out that this port is already incompatible with shipped 
systems, in other ways, at least since the March revision or so.

For one thing, the exact definition of this "struct boot_params" is 
already incompatibly revised; this version [2] is the one actually 
compatible with existing firmware, so people already have to write shims 
(not started yet) or flash their firmware (not open-sourced or provided 
by Loongson yet) to actually compile and run this port. (You haven't 
read that wrong; indeed no one outside Loongson is able to run this 
kernel so far.)

For another thing, the kernel ABI and the userland (mainly glibc) are 
also incompatible with the shipped systems with their pre-installed 
vendor systems. Things like different NSIG, sigcontext, and glibc symbol 
versions already ensured no binary can run in "the other world".

So, in effect, this port is starting from scratch, and taking the chance 
to fix early mistakes and oversights all over; hence my opinion is, 
better do the Right Thing (tm) and give the generic codepath a chance.

For the Loongson devs: at least, declare the struct boot_params flow 
deprecated from day one, then work to eliminate it from future products, 
if you really don't want to delay merging even further (it's already 
unlikely to land in 5.19, given the discussion happening in LKML [3]). 
It's not embarrassing to admit mistakes; we all make mistakes, and 
what's important is to learn from them so we don't collectively repeat 
ourselves.


[1]: 
https://web.archive.org/web/20190713081851/http://www.loongson.cn/uploadfile/devsysmanual/loongson_devsys_firmware_kernel_interface_specification.pdf
[2]: 
https://github.com/xen0n/linux/commit/a55739f8e748dc9164c12da504696161bb8b9911
[3]: https://lwn.net/ml/linux-kernel/87v8uk6kfa.wl-maz@kernel.org/


  reply	other threads:[~2022-05-06 11:26 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-30  9:04 [PATCH V9 00/22] arch: Add basic LoongArch support Huacai Chen
2022-04-30  9:04 ` [PATCH V9 01/24] Documentation: LoongArch: Add basic documentations Huacai Chen
2022-05-01  7:48   ` Bagas Sanjaya
2022-05-01  8:55     ` Huacai Chen
2022-05-01  9:32   ` WANG Xuerui
2022-05-01 10:17     ` Huacai Chen
2022-04-30  9:04 ` [PATCH V9 02/24] Documentation/zh_CN: Add basic LoongArch documentations Huacai Chen
2022-05-01  9:38   ` WANG Xuerui
2022-04-30  9:04 ` [PATCH V9 03/24] LoongArch: Add elf-related definitions Huacai Chen
2022-05-01  9:41   ` WANG Xuerui
2022-05-01 14:27     ` Huacai Chen
2022-04-30  9:04 ` [PATCH V9 04/24] LoongArch: Add writecombine support for drm Huacai Chen
2022-04-30  9:04 ` [PATCH V9 05/24] LoongArch: Add build infrastructure Huacai Chen
2022-05-01 10:09   ` WANG Xuerui
2022-05-01 12:41     ` Huacai Chen
2022-05-01 15:43     ` Xi Ruoyao
2022-04-30  9:05 ` [PATCH V9 06/24] LoongArch: Add CPU definition headers Huacai Chen
2022-05-01 11:05   ` WANG Xuerui
2022-04-30  9:05 ` [PATCH V9 07/24] LoongArch: Add atomic/locking headers Huacai Chen
2022-05-01 11:16   ` WANG Xuerui
2022-05-01 13:16     ` Huacai Chen
2022-04-30  9:05 ` [PATCH V9 08/24] LoongArch: Add other common headers Huacai Chen
2022-05-01 11:39   ` WANG Xuerui
2022-05-01 14:26     ` Huacai Chen
2022-04-30  9:05 ` [PATCH V9 09/24] LoongArch: Add boot and setup routines Huacai Chen
2022-04-30  9:05 ` [PATCH V9 10/24] LoongArch: Add exception/interrupt handling Huacai Chen
2022-05-01 16:27   ` Xi Ruoyao
2022-05-01 17:08     ` Xi Ruoyao
2022-05-02  0:01       ` Huacai Chen
2022-04-30  9:05 ` [PATCH V9 11/24] LoongArch: Add process management Huacai Chen
2022-04-30  9:05 ` [PATCH V9 12/24] LoongArch: Add memory management Huacai Chen
2022-04-30  9:05 ` [PATCH V9 13/24] LoongArch: Add system call support Huacai Chen
2022-04-30  9:44   ` Arnd Bergmann
2022-04-30 10:05     ` Huacai Chen
2022-04-30 10:34       ` Arnd Bergmann
2022-05-07 12:11         ` Christian Brauner
2022-05-09 10:00           ` Christian Brauner
2022-05-11  7:11             ` Arnd Bergmann
2022-05-11 21:12               ` [musl] " Rich Felker
2022-05-12  7:21                 ` Arnd Bergmann
2022-05-12 12:11                   ` Rich Felker
2022-05-11 16:17             ` Florian Weimer
2022-04-30  9:05 ` [PATCH V9 14/24] LoongArch: Add signal handling support Huacai Chen
2022-04-30  9:05 ` [PATCH V9 15/24] LoongArch: Add elf and module support Huacai Chen
2022-04-30  9:05 ` [PATCH V9 16/24] LoongArch: Add misc common routines Huacai Chen
2022-04-30  9:50   ` Arnd Bergmann
2022-04-30 10:00     ` Huacai Chen
2022-04-30 10:41       ` Arnd Bergmann
2022-04-30 13:22         ` Palmer Dabbelt
2022-05-01  5:12           ` Huacai Chen
2022-04-30  9:05 ` [PATCH V9 17/24] LoongArch: Add some library functions Huacai Chen
2022-05-01 10:55   ` Guo Ren
2022-05-01 12:18     ` Huacai Chen
2022-04-30  9:05 ` [PATCH V9 18/24] LoongArch: Add PCI controller support Huacai Chen
2022-04-30  9:05 ` [PATCH V9 19/24] LoongArch: Add VDSO and VSYSCALL support Huacai Chen
2022-04-30  9:05 ` [PATCH V9 20/24] LoongArch: Add efistub booting support Huacai Chen
2022-04-30  9:56   ` Arnd Bergmann
2022-04-30 10:02     ` Huacai Chen
2022-05-03  7:23     ` Ard Biesheuvel
2022-05-05  9:59       ` Huacai Chen
2022-05-06  8:14         ` Ard Biesheuvel
2022-05-06 11:26           ` WANG Xuerui [this message]
2022-05-06 11:41             ` Arnd Bergmann
2022-05-06 13:20               ` Huacai Chen
2022-05-13 19:32                 ` Arnd Bergmann
2022-05-14  2:27                   ` Huacai Chen
2022-04-30  9:05 ` [PATCH V9 21/24] LoongArch: Add zboot (compressed kernel) support Huacai Chen
2022-04-30 10:07   ` Arnd Bergmann
2022-05-01  5:22     ` Huacai Chen
2022-05-01  6:35       ` Russell King (Oracle)
2022-05-01  8:46         ` Huacai Chen
2022-05-01 11:28           ` Russell King (Oracle)
2022-05-01  8:33       ` Arnd Bergmann
2022-05-01 23:36     ` Ard Biesheuvel
2022-04-30  9:05 ` [PATCH V9 22/24] LoongArch: Add multi-processor (SMP) support Huacai Chen
2022-04-30  9:05 ` [PATCH V9 23/24] LoongArch: Add Non-Uniform Memory Access (NUMA) support Huacai Chen
2022-04-30  9:05 ` [PATCH V9 24/24] LoongArch: Add Loongson-3 default config file Huacai Chen
2022-05-01  8:19 ` [PATCH V9 00/22] arch: Add basic LoongArch support Bagas Sanjaya
2022-05-01  8:55   ` Huacai Chen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a6afaa3f-cb9f-2086-0e02-5ec21ba535d4@xen0n.name \
    --to=kernel@xen0n.name \
    --cc=airlied@linux.ie \
    --cc=akpm@linux-foundation.org \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=chenhuacai@gmail.com \
    --cc=chenhuacai@loongson.cn \
    --cc=corbet@lwn.net \
    --cc=guoren@kernel.org \
    --cc=jiaxun.yang@flygoat.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lixuefeng@loongson.cn \
    --cc=luto@kernel.org \
    --cc=peterz@infradead.org \
    --cc=siyanteng@loongson.cn \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).