> Date: Sat, 18 May 2019 05:58:39 +0200 (CEST)
> From: Mark Kettenis <[email protected]>
> 
> > 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.

Actually, since we always move the kernel to 16MB, we can use
AllocateMaxAddress to allocate a large enough block of memory below
that.  So the diff below should work (and does on my Skylake system
that uses a 100k firmware).

ok?


Index: arch/amd64/stand/efiboot/exec_i386.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/exec_i386.c,v
retrieving revision 1.1
diff -u -p -r1.1 exec_i386.c
--- arch/amd64/stand/efiboot/exec_i386.c        10 May 2019 21:20:42 -0000      
1.1
+++ arch/amd64/stand/efiboot/exec_i386.c        20 May 2019 22:25:38 -0000
@@ -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,13 @@ ucode_load(void)
                return;
 
        buflen = sb.st_size;
-       if (buflen > 128*1024) {
-               printf("ucode too large\n");
+       addr = 16 * 1024 * 1024;
+       if (EFI_CALL(BS->AllocatePages, AllocateMaxAddress, 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