[haiku-commits] Change in haiku[master]: boot_loader: load intel microcode update data file

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 23 Mar 2020 15:32:01 +0000

From Jérôme Duval <jerome.duval@xxxxxxxxx>:

Jérôme Duval has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/2409 ;)


Change subject: boot_loader: load intel microcode update data file
......................................................................

boot_loader: load intel microcode update data file

Previous version of the patch was broken by the EFI refactoring.
---
M headers/private/kernel/boot/arch/x86/arch_cpu.h
M headers/private/kernel/boot/platform.h
M src/system/boot/arch/x86/cpu.cpp
M src/system/boot/loader/loader.cpp
M src/system/boot/loader/main.cpp
M src/system/boot/platform/bios_ia32/cpu.cpp
M src/system/boot/platform/bios_ia32/long.cpp
M src/system/boot/platform/efi/cpu.cpp
M src/system/boot/platform/efi/start.cpp
9 files changed, 87 insertions(+), 1 deletion(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/09/2409/1

diff --git a/headers/private/kernel/boot/arch/x86/arch_cpu.h 
b/headers/private/kernel/boot/arch/x86/arch_cpu.h
index 9c697ce..59608e3 100644
--- a/headers/private/kernel/boot/arch/x86/arch_cpu.h
+++ b/headers/private/kernel/boot/arch/x86/arch_cpu.h
@@ -21,4 +21,9 @@
 }
 #endif

+#include <boot/vfs.h>
+
+void ucode_load(BootVolume& volume);
+
+
 #endif /* BOOT_ARCH_CPU_H */
diff --git a/headers/private/kernel/boot/platform.h 
b/headers/private/kernel/boot/platform.h
index 8cbae60..3c28b73 100644
--- a/headers/private/kernel/boot/platform.h
+++ b/headers/private/kernel/boot/platform.h
@@ -43,6 +43,7 @@
 extern void platform_switch_to_text_mode(void);
 extern void platform_start_kernel(void);
 extern void platform_exit(void);
+extern void platform_load_ucode(BootVolume& volume);

 #ifdef __cplusplus
 }
diff --git a/src/system/boot/arch/x86/cpu.cpp b/src/system/boot/arch/x86/cpu.cpp
index 1890f81..664baec 100644
--- a/src/system/boot/arch/x86/cpu.cpp
+++ b/src/system/boot/arch/x86/cpu.cpp
@@ -17,6 +17,7 @@
 #include <boot/stdio.h>

 #include <arch/cpu.h>
+#include <arch/x86/arch_cpu.h>
 #include <arch_kernel.h>
 #include <arch_system_info.h>

@@ -311,6 +312,62 @@
        }
 }

+extern int open_maybe_packaged(BootVolume& volume, const char* path,
+       int openMode);
+
+void
+ucode_load(BootVolume& volume)
+{
+       cpuid_info info;
+       if (get_current_cpuid(&info, 0, 0) != B_OK
+               || strncmp(info.eax_0.vendor_id, "GenuineIntel", 12) != 0)
+               return;
+
+       if (get_current_cpuid(&info, 1, 0) != B_OK)
+               return;
+
+       char path[128];
+       int family = info.eax_1.family;
+       int model = info.eax_1.model;
+       if (family == 0x6 || family == 0xf) {
+               family += info.eax_1.extended_family;
+               model += (info.eax_1.extended_model << 4);
+       }
+       snprintf(path, sizeof(path), "system/data/firmware/intel-ucode/"
+               "%02x-%02x-%02x", family, model, info.eax_1.stepping);
+       dprintf("ucode_load: %s\n", path);
+
+       int fd = open_maybe_packaged(volume, path, O_RDONLY);
+       if (fd < B_OK) {
+               dprintf("ucode_load: couldn't find microcode\n");
+               return;
+       }
+       struct stat stat;
+       if (fstat(fd, &stat) < 0) {
+               dprintf("ucode_load: couldn't stat microcode file\n");
+               close(fd);
+               return;
+       }
+
+       ssize_t length = stat.st_size;
+       const uint32 alignment = 16;
+#define ALIGN(size, align)     (((size) + align - 1) & ~(align - 1))
+       void *buffer = kernel_args_malloc(length + alignment - 1);
+       if (buffer != NULL) {
+               buffer = (void*)ALIGN((addr_t)buffer, alignment);
+               if (read(fd, buffer, length) != length) {
+                       dprintf("ucode_load: couldn't read microcode file\n");
+                       kernel_args_free(buffer);
+               } else {
+                       gKernelArgs.ucode_data = buffer;
+                       gKernelArgs.ucode_data_size = length;
+                       dprintf("ucode_load: microcode file read in memory\n");
+               }
+       }
+
+       close(fd);
+}
+

 extern "C" bigtime_t
 system_time()
diff --git a/src/system/boot/loader/loader.cpp 
b/src/system/boot/loader/loader.cpp
index e192344..32e1a06 100644
--- a/src/system/boot/loader/loader.cpp
+++ b/src/system/boot/loader/loader.cpp
@@ -55,7 +55,7 @@
 };


-static int
+int
 open_maybe_packaged(BootVolume& volume, const char* path, int openMode)
 {
        if (strncmp(path, kSystemDirectoryPrefix, 
strlen(kSystemDirectoryPrefix))
diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp
index 73b66da..d4a41c5 100644
--- a/src/system/boot/loader/main.cpp
+++ b/src/system/boot/loader/main.cpp
@@ -128,6 +128,7 @@

                        gKernelArgs.ucode_data = NULL;
                        gKernelArgs.ucode_data_size = 0;
+                       platform_load_ucode(bootVolume);

                        // apply boot settings
                        apply_boot_settings();
diff --git a/src/system/boot/platform/bios_ia32/cpu.cpp 
b/src/system/boot/platform/bios_ia32/cpu.cpp
index 2d177f7..93a782f 100644
--- a/src/system/boot/platform/bios_ia32/cpu.cpp
+++ b/src/system/boot/platform/bios_ia32/cpu.cpp
@@ -70,3 +70,10 @@
        gKernelArgs.num_cpus = 1;
                // this will eventually be corrected later on
 }
+
+
+extern "C" void
+platform_load_ucode(BootVolume& volume)
+{
+       ucode_load(volume);
+}
diff --git a/src/system/boot/platform/bios_ia32/long.cpp 
b/src/system/boot/platform/bios_ia32/long.cpp
index 2152f99..c784422 100644
--- a/src/system/boot/platform/bios_ia32/long.cpp
+++ b/src/system/boot/platform/bios_ia32/long.cpp
@@ -244,6 +244,7 @@
        fix_address(gKernelArgs.debug_output);
        fix_address(gKernelArgs.previous_debug_output);
        fix_address(gKernelArgs.boot_splash);
+       fix_address(gKernelArgs.ucode_data);
        fix_address(gKernelArgs.arch_args.apic);
        fix_address(gKernelArgs.arch_args.hpet);

diff --git a/src/system/boot/platform/efi/cpu.cpp 
b/src/system/boot/platform/efi/cpu.cpp
index 88a3fc5..aab6ad0 100644
--- a/src/system/boot/platform/efi/cpu.cpp
+++ b/src/system/boot/platform/efi/cpu.cpp
@@ -6,8 +6,12 @@


 #include <boot/kernel_args.h>
+#include <boot/platform.h>
 #include <boot/stage2.h>
 #include <arch/cpu.h>
+#ifdef __x86_64__
+#  include <boot/arch/x86/arch_cpu.h>
+#endif


 void
@@ -16,3 +20,12 @@
        gKernelArgs.num_cpus = 1;
                // this will eventually be corrected later on
 }
+
+
+extern "C" void
+platform_load_ucode(BootVolume& volume)
+{
+#ifdef __x86_64__
+       ucode_load(volume);
+#endif
+}
diff --git a/src/system/boot/platform/efi/start.cpp 
b/src/system/boot/platform/efi/start.cpp
index 9d485b8..c0e535c 100644
--- a/src/system/boot/platform/efi/start.cpp
+++ b/src/system/boot/platform/efi/start.cpp
@@ -90,6 +90,7 @@
        fix_address(gKernelArgs.debug_output);
        fix_address(gKernelArgs.boot_splash);
        #if defined(__x86_64__) || defined(__x86__)
+       fix_address(gKernelArgs.ucode_data);
        fix_address(gKernelArgs.arch_args.apic);
        fix_address(gKernelArgs.arch_args.hpet);
        #endif

--
To view, visit https://review.haiku-os.org/c/haiku/+/2409
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I6dd125100b22b2461c531bfd8f81b3dd28e2b751
Gerrit-Change-Number: 2409
Gerrit-PatchSet: 1
Gerrit-Owner: Jérôme Duval <jerome.duval@xxxxxxxxx>
Gerrit-MessageType: newchange

Other related posts: