> Date: Fri, 17 May 2019 17:56:52 -0400
> From: Patrick Wildt <[email protected]>
> 
> Hi,
> 
> claudio@ has a Kaby Lake that exceeds the 128 kB limit, being as big as
> 190 kB.  So, for him the ucode isn't being loaded.
> 
> On EFI systems we can simply ask EFI to allocate some memory for us.
> I'm not sure why this file is duplicated 4 times, but it looks like
> for efiboot this one is currently the file to patch.
> 
> This diff works for claudio@'s EFI booted system.  Since I don't know
> how much space is available on legacy systems I will not attempt to
> fix this for the legacy bootloader.  Someone that knows more than me
> about x86 can attempt that.
> 
> Feedback? ok?

In principle, ye, that is the right approach.

However, until Mike gets us to the point where we no longer care at
which physical address the kernel was loaded, efiboot will move the
kernel to a specific physical address after loading it and potentially
thrash all memory allocated through the EFI interfaces.  So there is a
change that we will overwrite the microcode at that point.

So it might actually be safer to just change the limit to 256k if
there is a good chance the the memory at the 1MB mark is unlikely to
be used by anything else.

> diff --git a/sys/arch/amd64/stand/efiboot/exec_i386.c 
> b/sys/arch/amd64/stand/efiboot/exec_i386.c
> index e4b39d6cd0c..ea1d301f1d8 100644
> --- a/sys/arch/amd64/stand/efiboot/exec_i386.c
> +++ b/sys/arch/amd64/stand/efiboot/exec_i386.c
> @@ -46,8 +46,13 @@
>  #include "softraid_amd64.h"
>  #endif
>  
> +#include <efi.h>
> +#include <efiapi.h>
> +#include "eficall.h"
>  #include "efiboot.h"
>  
> +extern EFI_BOOT_SERVICES     *BS;
> +
>  typedef void (*startfuncp)(int, int, int, int, int, int, int, int)
>      __attribute__ ((noreturn));
>  
> @@ -165,6 +170,7 @@ run_loadfile(uint64_t *marks, int howto)
>  void
>  ucode_load(void)
>  {
> +     EFI_PHYSICAL_ADDRESS addr;
>       uint32_t model, family, stepping;
>       uint32_t dummy, signature;
>       uint32_t vendor[4];
> @@ -200,12 +206,12 @@ ucode_load(void)
>               return;
>  
>       buflen = sb.st_size;
> -     if (buflen > 128*1024) {
> -             printf("ucode too large\n");
> +     if (EFI_CALL(BS->AllocatePages, AllocateAnyPages, EfiLoaderData,
> +         EFI_SIZE_TO_PAGES(buflen), &addr) != EFI_SUCCESS) {
> +             printf("cannot allocate memory for ucode\n");
>               return;
>       }
> -
> -     buf = (char *)(1*1024*1024);
> +     buf = (char *)((paddr_t)addr);
>  
>       if (read(fd, buf, buflen) != buflen) {
>               close(fd);
> 
> 

Reply via email to