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/+/2263 ;)
Change subject: boot_loader: load intel microcode update data file.
......................................................................
boot_loader: load intel microcode update data file.
---
M headers/private/kernel/arch/x86/arch_kernel_args.h
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/loader/vfs.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
11 files changed, 99 insertions(+), 1 deletion(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/63/2263/1
diff --git a/headers/private/kernel/arch/x86/arch_kernel_args.h
b/headers/private/kernel/arch/x86/arch_kernel_args.h
index 011bdf0..7d87016 100644
--- a/headers/private/kernel/arch/x86/arch_kernel_args.h
+++ b/headers/private/kernel/arch/x86/arch_kernel_args.h
@@ -40,6 +40,9 @@
FixedWidthPointer<void> hpet;
// needed for UEFI, otherwise kernel acpi support can't find ACPI root
FixedWidthPointer<void> acpi_root;
+ // microcode
+ FixedWidthPointer<void> ucode_data;
+ uint32 ucode_data_size;
} _PACKED arch_kernel_args;
#endif /* KERNEL_ARCH_x86_KERNEL_ARGS_H */
diff --git a/headers/private/kernel/boot/arch/x86/arch_cpu.h
b/headers/private/kernel/boot/arch/x86/arch_cpu.h
index 771f11a..61ee31d 100644
--- a/headers/private/kernel/boot/arch/x86/arch_cpu.h
+++ b/headers/private/kernel/boot/arch/x86/arch_cpu.h
@@ -22,4 +22,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..e881920 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,57 @@
}
}
+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, 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.arch_args.ucode_data = buffer;
+ gKernelArgs.arch_args.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 8b02173..701a238 100644
--- a/src/system/boot/loader/main.cpp
+++ b/src/system/boot/loader/main.cpp
@@ -126,6 +126,8 @@
load_modules(args, bootVolume);
+ platform_load_ucode(bootVolume);
+
// apply boot settings
apply_boot_settings();
diff --git a/src/system/boot/loader/vfs.cpp b/src/system/boot/loader/vfs.cpp
index 2a57686..01d0205 100644
--- a/src/system/boot/loader/vfs.cpp
+++ b/src/system/boot/loader/vfs.cpp
@@ -39,6 +39,9 @@
#endif
+int debug_uload = false;
+
+
struct __DIR {
Directory* directory;
void* cookie;
@@ -773,6 +776,8 @@
static status_t
get_node_for_path(Directory *directory, char *path, Node **_node)
{
+ if (debug_uload == 1) TRACE(("get_node_for_path: 1\n"));
+
directory->Acquire();
// balance Acquire()/Release() calls
@@ -784,6 +789,8 @@
// path component), and filter out multiple slashes
for (nextPath = path + 1; nextPath[0] != '\0' && nextPath[0] !=
'/'; nextPath++);
+ if (debug_uload == 1) TRACE(("get_node_for_path: 2 %s\n", path));
+
if (*nextPath == '/') {
*nextPath = '\0';
do
@@ -791,25 +798,31 @@
while (*nextPath == '/');
}
+ if (debug_uload == 1) TRACE(("get_node_for_path: 3 %s\n", path));
nextNode = directory->Lookup(path, true);
directory->Release();
if (nextNode == NULL)
return B_ENTRY_NOT_FOUND;
+ if (debug_uload == 1) TRACE(("get_node_for_path: 4\n"));
path = nextPath;
if (S_ISDIR(nextNode->Type()))
directory = (Directory *)nextNode;
else if (path[0])
return B_NOT_ALLOWED;
+ if (debug_uload == 1) TRACE(("get_node_for_path: 5\n"));
// are we done?
if (path[0] == '\0') {
*_node = nextNode;
+ if (debug_uload == 1) TRACE(("get_node_for_path: 6\n"));
return B_OK;
}
}
+ if (debug_uload == 1) TRACE(("get_node_for_path: 7\n"));
+
return B_ENTRY_NOT_FOUND;
}
@@ -1036,7 +1049,10 @@
return B_NAME_TOO_LONG;
Node *node;
+ if (debug_uload == 1) TRACE(("open_from: %s\n", name));
status_t error = get_node_for_path(directory, path, &node);
+ if (debug_uload == 1) TRACE(("open_from: %s\n", strerror(error)));
+
if (error != B_OK) {
if (error != B_ENTRY_NOT_FOUND)
return error;
@@ -1044,6 +1060,8 @@
if ((mode & O_CREAT) == 0)
return B_ENTRY_NOT_FOUND;
+ if (debug_uload == 1) TRACE(("open_from: 2\n"));
+
// try to resolve the parent directory
strlcpy(path, name, sizeof(path));
if (char* lastSlash = strrchr(path, '/')) {
@@ -1077,6 +1095,7 @@
return B_FILE_EXISTS;
}
+ if (debug_uload == 1) TRACE(("open_from: 3\n"));
int fd = open_node(node, mode);
node->Release();
diff --git a/src/system/boot/platform/bios_ia32/cpu.cpp
b/src/system/boot/platform/bios_ia32/cpu.cpp
index 2d9e00f..8363adf 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..8e5b911 100644
--- a/src/system/boot/platform/bios_ia32/long.cpp
+++ b/src/system/boot/platform/bios_ia32/long.cpp
@@ -246,6 +246,7 @@
fix_address(gKernelArgs.boot_splash);
fix_address(gKernelArgs.arch_args.apic);
fix_address(gKernelArgs.arch_args.hpet);
+ fix_address(gKernelArgs.arch_args.ucode_data);
convert_preloaded_image(static_cast<preloaded_elf64_image*>(
gKernelArgs.kernel_image.Pointer()));
diff --git a/src/system/boot/platform/efi/cpu.cpp
b/src/system/boot/platform/efi/cpu.cpp
index 5093cfe..0d07566 100644
--- a/src/system/boot/platform/efi/cpu.cpp
+++ b/src/system/boot/platform/efi/cpu.cpp
@@ -19,3 +19,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/efi/start.cpp
b/src/system/boot/platform/efi/start.cpp
index 9c3bf43..dc87c7f 100644
--- a/src/system/boot/platform/efi/start.cpp
+++ b/src/system/boot/platform/efi/start.cpp
@@ -93,6 +93,7 @@
#if defined(__x86_64__) || defined(__x86__)
fix_address(gKernelArgs.arch_args.apic);
fix_address(gKernelArgs.arch_args.hpet);
+ fix_address(gKernelArgs.arch_args.ucode_data);
#endif
convert_preloaded_image(static_cast<preloaded_elf64_image*>(
--
To view, visit https://review.haiku-os.org/c/haiku/+/2263
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I323a57cc0b1f05ad7b60b6a141d068a3e618ee4d
Gerrit-Change-Number: 2263
Gerrit-PatchSet: 1
Gerrit-Owner: Jérôme Duval <jerome.duval@xxxxxxxxx>
Gerrit-MessageType: newchange