arch/x86: Expand cpu boot argument

In order to mitigate at runtime whether it booted on multiboot or EFI,
let's introduce a dedicated x86 cpu argument structure which holds the
type and the actual pointer delivered by the method (multiboot_info, or
efi_system_table)

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2020-09-18 09:05:50 +02:00 committed by Anas Nashif
parent 9fb80d04b4
commit f19f9db8df
8 changed files with 56 additions and 9 deletions

View file

@ -44,6 +44,8 @@
GDATA(_sse_mxcsr_default_value)
#endif
GDATA(x86_cpu_boot_arg)
.macro install_page_tables
#ifdef CONFIG_X86_MMU
/* Enable paging. If virtual memory is enabled, the instruction pointer
@ -269,7 +271,13 @@ __csSet:
/* load 32-bit operand size IDT */
lidt z_x86_idt
pushl %ebx /* pointer to multiboot info, or NULL */
movl $x86_cpu_boot_arg, %ebp
/* Boot type to multiboot, ebx content will help to mitigate */
movl $MULTIBOOT_BOOT_TYPE, \
__x86_boot_arg_t_boot_type_OFFSET(%ebp)
/* pointer to multiboot info, or NULL */
movl %ebx, __x86_boot_arg_t_arg_OFFSET(%ebp)
pushl $x86_cpu_boot_arg
call z_x86_prep_c /* enter kernel; never returns */
#if defined(CONFIG_X86_SSE)

View file

@ -90,6 +90,14 @@ struct x86_tss64 tss3 = {
};
#endif
/* We must put this in a dedicated section, or else it will land into .bss:
* in this case, though locore.S initalizes it relevantly, all will be
* lost when calling z_bss_zero() in z_x86_cpu_init prior to using it.
*/
Z_GENERIC_SECTION(.boot_arg)
x86_boot_arg_t x86_cpu_boot_arg;
struct x86_cpuboot x86_cpuboot[] = {
{
.tr = X86_KERNEL_CPU0_TR,
@ -99,6 +107,7 @@ struct x86_cpuboot x86_cpuboot[] = {
.stack_size =
Z_KERNEL_STACK_SIZE_ADJUST(CONFIG_ISR_STACK_SIZE),
.fn = z_x86_prep_c,
.arg = &x86_cpu_boot_arg,
},
#if CONFIG_MP_NUM_CPUS > 1
{

View file

@ -190,9 +190,14 @@ __start32:
* has left a pointer to it in EBX.
*/
movl $x86_cpuboot, %ebp /* BSP is always logical CPU id 0 */
movl %ebx, __x86_cpuboot_t_arg_OFFSET(%ebp) /* multiboot info */
movl $x86_cpu_boot_arg, %ebp
/* Inserting boot type */
movl $MULTIBOOT_BOOT_TYPE, __x86_boot_arg_t_boot_type_OFFSET(%ebp)
/* and multiboot info */
movl %ebx, __x86_boot_arg_t_arg_OFFSET(%ebp)
movl $x86_cpuboot, %ebp /* BSP is always logical CPU id 0 */
go64: /* Install page tables and transition to long mode */
install_pagetables_32

View file

@ -14,6 +14,9 @@
#include "ia32_offsets.c"
#endif
GEN_OFFSET_SYM(x86_boot_arg_t, boot_type);
GEN_OFFSET_SYM(x86_boot_arg_t, arg);
GEN_OFFSET_SYM(_thread_arch_t, flags);
GEN_ABS_SYM_END

View file

@ -13,13 +13,17 @@
extern FUNC_NORETURN void z_cstart(void);
extern void x86_64_irq_init(void);
#if !defined(CONFIG_X86_64)
x86_boot_arg_t x86_cpu_boot_arg;
#endif
/* Early global initialization functions, C domain. This runs only on the first
* CPU for SMP systems.
*/
__boot_func
FUNC_NORETURN void z_x86_prep_c(void *arg)
{
struct multiboot_info *info = arg;
x86_boot_arg_t *cpu_arg = arg;
_kernel.cpus[0].nested = 0;
@ -39,11 +43,13 @@ FUNC_NORETURN void z_x86_prep_c(void *arg)
x86_64_irq_init();
#endif
#if defined(CONFIG_MULTIBOOT_INFO) && !defined(CONFIG_BUILD_OUTPUT_EFI)
z_multiboot_init(info);
#else
ARG_UNUSED(info);
#endif
if (IS_ENABLED(CONFIG_MULTIBOOT_INFO) &&
cpu_arg->boot_type == MULTIBOOT_BOOT_TYPE) {
z_multiboot_init((struct multiboot_info *)cpu_arg->arg);
} else {
ARG_UNUSED(cpu_arg);
}
#if CONFIG_X86_STACK_PROTECTION
for (int i = 0; i < CONFIG_MP_NUM_CPUS; i++) {

View file

@ -57,6 +57,18 @@
#define CR4_PAE BIT(5) /* enable PAE */
#define CR4_OSFXSR BIT(9) /* enable SSE (OS FXSAVE/RSTOR) */
#ifndef _ASMLANGUAGE
/* x86 boot argument (see prep_c.c) */
struct x86_boot_arg {
int boot_type;
void *arg;
};
typedef struct x86_boot_arg x86_boot_arg_t;
#endif /* _ASMLANGUAGE */
#ifdef CONFIG_X86_64
#include <intel64/kernel_arch_data.h>
#else

View file

@ -60,6 +60,7 @@ SECTIONS
z_shared_kernel_page_start = .;
#endif /* CONFIG_X86_KPTI */
*(.boot_arg)
*(.tss)
*(.gdt)

View file

@ -62,6 +62,9 @@ struct multiboot_mmap {
#endif /* _ASMLANGUAGE */
/* Boot type value (see prep_c.c) */
#define MULTIBOOT_BOOT_TYPE 1
/*
* Possible values for multiboot_mmap.type field.
* Other values should be assumed to be unusable ranges.