boot_loader: load intel microcode update data file
Change-Id: I323a57cc0b1f05ad7b60b6a141d068a3e618ee4d Reviewed-on: https://review.haiku-os.org/c/haiku/+/2263 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
@@ -21,4 +21,9 @@ void calculate_cpu_conversion_factor(uint8 channel);
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boot/vfs.h>
|
||||||
|
|
||||||
|
void ucode_load(BootVolume& volume);
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOT_ARCH_CPU_H */
|
#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_switch_to_text_mode(void);
|
||||||
extern void platform_start_kernel(void);
|
extern void platform_start_kernel(void);
|
||||||
extern void platform_exit(void);
|
extern void platform_exit(void);
|
||||||
|
extern void platform_load_ucode(BootVolume& volume);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <boot/stdio.h>
|
#include <boot/stdio.h>
|
||||||
|
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
#include <arch/x86/arch_cpu.h>
|
||||||
#include <arch_kernel.h>
|
#include <arch_kernel.h>
|
||||||
#include <arch_system_info.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
|
extern "C" bigtime_t
|
||||||
system_time()
|
system_time()
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ static const char *sAddonPaths[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int
|
int
|
||||||
open_maybe_packaged(BootVolume& volume, const char* path, int openMode)
|
open_maybe_packaged(BootVolume& volume, const char* path, int openMode)
|
||||||
{
|
{
|
||||||
if (strncmp(path, kSystemDirectoryPrefix, strlen(kSystemDirectoryPrefix))
|
if (strncmp(path, kSystemDirectoryPrefix, strlen(kSystemDirectoryPrefix))
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ main(stage2_args *args)
|
|||||||
|
|
||||||
gKernelArgs.ucode_data = NULL;
|
gKernelArgs.ucode_data = NULL;
|
||||||
gKernelArgs.ucode_data_size = 0;
|
gKernelArgs.ucode_data_size = 0;
|
||||||
|
platform_load_ucode(bootVolume);
|
||||||
|
|
||||||
// apply boot settings
|
// apply boot settings
|
||||||
apply_boot_settings();
|
apply_boot_settings();
|
||||||
|
|||||||
@@ -70,3 +70,10 @@ cpu_init()
|
|||||||
gKernelArgs.num_cpus = 1;
|
gKernelArgs.num_cpus = 1;
|
||||||
// this will eventually be corrected later on
|
// 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.debug_output);
|
||||||
fix_address(gKernelArgs.previous_debug_output);
|
fix_address(gKernelArgs.previous_debug_output);
|
||||||
fix_address(gKernelArgs.boot_splash);
|
fix_address(gKernelArgs.boot_splash);
|
||||||
|
fix_address(gKernelArgs.ucode_data);
|
||||||
fix_address(gKernelArgs.arch_args.apic);
|
fix_address(gKernelArgs.arch_args.apic);
|
||||||
fix_address(gKernelArgs.arch_args.hpet);
|
fix_address(gKernelArgs.arch_args.hpet);
|
||||||
|
|
||||||
|
|||||||
@@ -16,3 +16,10 @@ cpu_init()
|
|||||||
gKernelArgs.num_cpus = 1;
|
gKernelArgs.num_cpus = 1;
|
||||||
// this will eventually be corrected later on
|
// this will eventually be corrected later on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
platform_load_ucode(BootVolume& volume)
|
||||||
|
{
|
||||||
|
ucode_load(volume);
|
||||||
|
}
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ convert_kernel_args()
|
|||||||
fix_address(gKernelArgs.debug_output);
|
fix_address(gKernelArgs.debug_output);
|
||||||
fix_address(gKernelArgs.boot_splash);
|
fix_address(gKernelArgs.boot_splash);
|
||||||
#if defined(__x86_64__) || defined(__x86__)
|
#if defined(__x86_64__) || defined(__x86__)
|
||||||
|
fix_address(gKernelArgs.ucode_data);
|
||||||
fix_address(gKernelArgs.arch_args.apic);
|
fix_address(gKernelArgs.arch_args.apic);
|
||||||
fix_address(gKernelArgs.arch_args.hpet);
|
fix_address(gKernelArgs.arch_args.hpet);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user