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:
Charles E. Youse 2019-09-28 16:16:19 -04:00 committed by Anas Nashif
commit 418e5c1b38
3 changed files with 70 additions and 114 deletions

67
arch/x86/core/common.S Normal file
View 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

View file

@ -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

View file

@ -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);
*