arch/x86: (Intel64) optimize and re-order startup assembly sequence
In some places the code was being overly pedantic; e.g., there is no need to load our own 32-bit descriptors because the loader's are fine for our purposes. We can defer loading our own segments until 64-bit. The sequence is re-ordered to faciliate code sharing between the BSP and APs when SMP is enabled (all BSP-specific operations occur before the per-CPU initialization). Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
17e135bc41
commit
90bf0da332
1 changed files with 23 additions and 26 deletions
|
@ -17,23 +17,20 @@
|
||||||
.globl __start
|
.globl __start
|
||||||
__start:
|
__start:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kernel execution begins here in 32-bit mode, with flat-mode
|
||||||
|
* descriptors in all segment registers, interrupts disabled.
|
||||||
|
* first, let common code do things like detect multiboot info.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "../common.S"
|
#include "../common.S"
|
||||||
|
|
||||||
/* switch to our own GDT/IDT and stack. */
|
|
||||||
|
|
||||||
lgdt gdt48
|
|
||||||
lidt idt48
|
|
||||||
jmpl $X86_KERNEL_CS_32, $1f
|
|
||||||
1: movw $X86_KERNEL_DS_32, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %ss
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clear the BSS. note that we do this in 32-bit mode, so
|
* N.B.: if multiboot info struct is present, "common.S"
|
||||||
* the BSS must fit entirely in the first 4GB of RAM.
|
* has left a pointer to it in EBX. do not clobber (yet).
|
||||||
|
*
|
||||||
|
* next, clear the BSS. note we're still in 32-bit mode,
|
||||||
|
* so the BSS must fit entirely in the first 4GB of RAM.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cld
|
cld
|
||||||
|
@ -42,9 +39,10 @@ __start:
|
||||||
movl $__bss_num_dwords, %ecx
|
movl $__bss_num_dwords, %ecx
|
||||||
rep stosl
|
rep stosl
|
||||||
|
|
||||||
movl $(_interrupt_stack + CONFIG_ISR_STACK_SIZE), %esp
|
/*
|
||||||
|
* transition to long mode, reload the segment registers,
|
||||||
/* transition to long mode. along the way, we enable SSE. */
|
* and configure per-CPU stuff: GS, task register, stack.
|
||||||
|
*/
|
||||||
|
|
||||||
movl %cr4, %eax /* enable PAE and SSE */
|
movl %cr4, %eax /* enable PAE and SSE */
|
||||||
orl $(CR4_PAE | CR4_OSFXSR), %eax
|
orl $(CR4_PAE | CR4_OSFXSR), %eax
|
||||||
|
@ -63,8 +61,8 @@ __start:
|
||||||
orl $CR0_PG, %eax
|
orl $CR0_PG, %eax
|
||||||
movl %eax, %cr0
|
movl %eax, %cr0
|
||||||
|
|
||||||
/* jump into long mode, reload the segment registers (again). */
|
lgdt gdt48
|
||||||
|
lidt idt48
|
||||||
jmpl $X86_KERNEL_CS_64, $1f
|
jmpl $X86_KERNEL_CS_64, $1f
|
||||||
.code64
|
.code64
|
||||||
1: movl $X86_KERNEL_DS_64, %eax
|
1: movl $X86_KERNEL_DS_64, %eax
|
||||||
|
@ -80,6 +78,12 @@ __start:
|
||||||
|
|
||||||
movl $(_interrupt_stack + CONFIG_ISR_STACK_SIZE), %esp
|
movl $(_interrupt_stack + CONFIG_ISR_STACK_SIZE), %esp
|
||||||
|
|
||||||
|
/*
|
||||||
|
* finally, complete environment for the C runtime and go.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cld /* GCC presumes a clear direction flag */
|
||||||
|
|
||||||
#ifdef CONFIG_INIT_STACKS
|
#ifdef CONFIG_INIT_STACKS
|
||||||
movq $0xAAAAAAAAAAAAAAAA, %rax
|
movq $0xAAAAAAAAAAAAAAAA, %rax
|
||||||
movq $_interrupt_stack, %rdi
|
movq $_interrupt_stack, %rdi
|
||||||
|
@ -87,11 +91,6 @@ __start:
|
||||||
rep stosq
|
rep stosq
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* set up SSE in case something uses the floating-point unit during
|
|
||||||
* early initialization (either directly, or if GCC gets clever)
|
|
||||||
*/
|
|
||||||
|
|
||||||
xorl %edi, %edi
|
xorl %edi, %edi
|
||||||
call x86_sse_init
|
call x86_sse_init
|
||||||
|
|
||||||
|
@ -104,8 +103,6 @@ __start:
|
||||||
movl %ebx, %edi /* multiboot pointer (or NULL) */
|
movl %ebx, %edi /* multiboot pointer (or NULL) */
|
||||||
call z_x86_prep_c /* enter kernel; never returns */
|
call z_x86_prep_c /* enter kernel; never returns */
|
||||||
|
|
||||||
stop: jmp stop
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void x86_sse_init(struct k_thread *thread);
|
* void x86_sse_init(struct k_thread *thread);
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue