arch/x86: factor out common assembly startup code
The 32-bit and 64-bit assembly startup sequences share quite a bunch of common code, so it's factored out into one file to avoid repeating ourselves (and potentially falling out of sync). Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
25a7cc1136
commit
418e5c1b38
3 changed files with 70 additions and 114 deletions
67
arch/x86/core/common.S
Normal file
67
arch/x86/core/common.S
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Intel Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <arch/x86/multiboot.h>
|
||||
|
||||
/*
|
||||
* This is included by ia32/crt0.S and intel64/locore.S
|
||||
* at their 32-bit entry points to cover common ground.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT_INFO
|
||||
/*
|
||||
* If we were loaded by a multiboot-compliant loader, then EAX
|
||||
* contains MULTIBOOT_EAX_MAGIC and EBX points to a valid 'struct
|
||||
* multiboot_info'; otherwise EBX is just junk. Check EAX early
|
||||
* before it's clobbered and leave a sentinel (0) in EBX if invalid.
|
||||
* The valid in EBX will be the argument to z_x86_prep_c(), so the
|
||||
* subsequent code must, of course, be sure to preserve it meanwhile.
|
||||
*/
|
||||
|
||||
cmpl $MULTIBOOT_EAX_MAGIC, %eax
|
||||
je 1f
|
||||
xorl %ebx, %ebx
|
||||
1:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOT_TIME_MEASUREMENT
|
||||
/*
|
||||
* Boot time measurements use TSC as a datum; zero it.
|
||||
*/
|
||||
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
movl $X86_TIME_STAMP_COUNTER_MSR, %ecx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PIC_DISABLE
|
||||
/*
|
||||
* "Disable" legacy i8259 interrupt controllers. Note that we
|
||||
* can't actually disable them, but we mask all their interrupt
|
||||
* sources which is effectively the same thing (almost).
|
||||
*/
|
||||
|
||||
movb $0xff, %al
|
||||
outb %al, $0x21
|
||||
outb %al, $0xA1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT
|
||||
jmp 1f
|
||||
|
||||
.align 4
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
.long MULTIBOOT_HEADER_FLAGS
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||
#ifdef CONFIG_MULTIBOOT_FRAMEBUF
|
||||
.fill 5,4,0 /* (unused exec layout) */
|
||||
.long 0 /* linear graphics mode */
|
||||
.long CONFIG_MULTIBOOT_FRAMEBUF_X /* width */
|
||||
.long CONFIG_MULTIBOOT_FRAMEBUF_Y /* height */
|
||||
.long 32 /* depth */
|
||||
#endif /* CONFIG_MULTIBOOT_FRAMEBUF */
|
||||
1:
|
||||
#endif
|
|
@ -43,37 +43,7 @@
|
|||
|
||||
SECTION_FUNC(TEXT_START, __start)
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT_INFO
|
||||
/*
|
||||
* If we were loaded by a multiboot-compliant loader, then EAX
|
||||
* contains MULTIBOOT_EAX_MAGIC and EBX points to a 'struct
|
||||
* multiboot_info' somewhere in memory that the kernel load
|
||||
* image doesn't claim. Since the kernel will consider such memory
|
||||
* "free", we must copy the contents of the struct before the kernel
|
||||
* decides to use that RAM for something else. However, we can't
|
||||
* effect the copy until after the BSS is initialized.
|
||||
*
|
||||
* EBX isn't touched until the copy is made; even function calls will
|
||||
* preserve it (it's callee-save in the SysV ABI). But EAX will be
|
||||
* clobbered, so we check for the magic now and leave a sentinel in
|
||||
* EBX (0) if the multiboot data isn't valid.
|
||||
*/
|
||||
|
||||
cmpl $MULTIBOOT_EAX_MAGIC, %eax
|
||||
je 1f
|
||||
xorl %ebx, %ebx
|
||||
1:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOT_TIME_MEASUREMENT
|
||||
/*
|
||||
* Reset the TSC to 0, since that's the datum for boot metrics.
|
||||
*/
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
movl $X86_TIME_STAMP_COUNTER_MSR, %ecx
|
||||
wrmsr
|
||||
#endif
|
||||
#include "../common.S"
|
||||
|
||||
/* Enable write-back caching by clearing the NW and CD bits */
|
||||
movl %cr0, %eax
|
||||
|
@ -265,17 +235,6 @@ __csSet:
|
|||
#endif
|
||||
lidt z_x86_idt /* load 32-bit operand size IDT */
|
||||
|
||||
#if defined(CONFIG_PIC_DISABLE)
|
||||
/*
|
||||
* "Disable" legacy i8259 interrupt controllers. Note that we
|
||||
* can't actually disable them, but we mask all their interrupt
|
||||
* sources which is effectively the same thing (almost).
|
||||
*/
|
||||
movb $0xff, %al /* all bits set = mask all interrupts */
|
||||
outb %al, $0x21 /* set i8259 master mask (IRQs 0-7) */
|
||||
outb %al, $0xA1 /* set i8259 slave mask (IRQs 8-15) */
|
||||
#endif
|
||||
|
||||
pushl %ebx /* pointer to multiboot info, or NULL */
|
||||
call z_x86_prep_c /* enter kernel; never returns */
|
||||
|
||||
|
@ -390,29 +349,6 @@ z_x86_idt:
|
|||
.long _idt_base_address /* physical start address */
|
||||
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT
|
||||
/*
|
||||
* The multiboot header must be in the first 8 Kb of the kernel image
|
||||
* (not including the ELF section header(s)) and be aligned on a
|
||||
* 4 byte boundary. See include/arch/x86/multiboot.h for more info.
|
||||
*/
|
||||
|
||||
.balign 4,0x90
|
||||
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
.long MULTIBOOT_HEADER_FLAGS
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT_FRAMEBUF
|
||||
.fill 5,4,0 /* (unused exec layout) */
|
||||
.long 0 /* linear graphics mode */
|
||||
.long CONFIG_MULTIBOOT_FRAMEBUF_X /* width */
|
||||
.long CONFIG_MULTIBOOT_FRAMEBUF_Y /* height */
|
||||
.long 32 /* depth */
|
||||
#endif /* CONFIG_MULTIBOOT_FRAMEBUF */
|
||||
|
||||
#endif /* CONFIG_MULTIBOOT */
|
||||
|
||||
#ifdef CONFIG_SET_GDT
|
||||
|
||||
/* GDT should be aligned on 8-byte boundary for best processor
|
||||
|
|
|
@ -17,37 +17,9 @@
|
|||
.globl __start
|
||||
__start:
|
||||
|
||||
/*
|
||||
* multiboot starts us here in 32-bit flat mode with interrupts and
|
||||
* paging disabled. first, check to see if EAX has a valid multiboot
|
||||
* magic in it, and if not, zero EBX so we know it's bogus later.
|
||||
* Remember not to clobber EBX until we've copied the boot info struct!
|
||||
*/
|
||||
#include "../common.S"
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT_INFO
|
||||
cmpl $MULTIBOOT_EAX_MAGIC, %eax
|
||||
je 1f
|
||||
xorl %ebx, %ebx
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* FIXME: ...resetting TSC here is common to IA32 and Intel64... */
|
||||
/* FIXME: ...disabling the PICs is common to IA32 and Intel64... */
|
||||
|
||||
#ifdef CONFIG_BOOT_TIME_MEASUREMENT
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
movl $X86_TIME_STAMP_COUNTER_MSR, %ecx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PIC_DISABLE
|
||||
movb $0xff, %al
|
||||
outb %al, $0x21
|
||||
outb %al, $0xA1
|
||||
#endif
|
||||
|
||||
/* next, switch to our own GDT/IDT and stack. */
|
||||
/* switch to our own GDT/IDT and stack. */
|
||||
|
||||
lgdt gdt48
|
||||
lidt idt48
|
||||
|
@ -141,25 +113,6 @@ x86_sse_init:
|
|||
|
||||
mxcsr: .long X86_MXCSR_SANE
|
||||
|
||||
/*
|
||||
* FIXME: The multiboot header is identical (for obvious reasons) to the
|
||||
* version in ia32/crt0.S. They should be refactored into a common file.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT
|
||||
.align 4
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
.long MULTIBOOT_HEADER_FLAGS
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||
#ifdef CONFIG_MULTIBOOT_FRAMEBUF
|
||||
.fill 5,4,0 /* (unused exec layout) */
|
||||
.long 0 /* linear graphics mode */
|
||||
.long CONFIG_MULTIBOOT_FRAMEBUF_X /* width */
|
||||
.long CONFIG_MULTIBOOT_FRAMEBUF_Y /* height */
|
||||
.long 32 /* depth */
|
||||
#endif /* CONFIG_MULTIBOOT_FRAMEBUF */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* void z_arch_switch(void *switch_to, void **switched_from);
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue