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:
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user