[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: Sat, 22 Feb 2020 11:41:10 +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/+/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

Other related posts: