boot_loader: load intel microcode update data file

Previous version of the patch was broken by the EFI refactoring.

Change-Id: I6dd125100b22b2461c531bfd8f81b3dd28e2b751
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2409
Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
Jérôme Duval
2020-03-23 15:33:34 +00:00
parent 6f857fa9fb
commit 11f8b65a79
9 changed files with 87 additions and 1 deletions
@@ -21,4 +21,9 @@ void calculate_cpu_conversion_factor(uint8 channel);
}
#endif
#include <boot/vfs.h>
void ucode_load(BootVolume& volume);
#endif /* BOOT_ARCH_CPU_H */
+1
View File
@@ -43,6 +43,7 @@ extern void platform_switch_to_logo(void);
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
}
+57
View File
@@ -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 @@ slower_sample:
}
}
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()
+1 -1
View File
@@ -55,7 +55,7 @@ static const char *sAddonPaths[] = {
};
static int
int
open_maybe_packaged(BootVolume& volume, const char* path, int openMode)
{
if (strncmp(path, kSystemDirectoryPrefix, strlen(kSystemDirectoryPrefix))
+1
View File
@@ -128,6 +128,7 @@ main(stage2_args *args)
gKernelArgs.ucode_data = NULL;
gKernelArgs.ucode_data_size = 0;
platform_load_ucode(bootVolume);
// apply boot settings
apply_boot_settings();
@@ -70,3 +70,10 @@ cpu_init()
gKernelArgs.num_cpus = 1;
// this will eventually be corrected later on
}
extern "C" void
platform_load_ucode(BootVolume& volume)
{
ucode_load(volume);
}
@@ -244,6 +244,7 @@ convert_kernel_args()
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);
+13
View File
@@ -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 @@ cpu_init()
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
}
+1
View File
@@ -90,6 +90,7 @@ convert_kernel_args()
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