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