> 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);