/* SPDX-License-Identifier: GPL-2.0-only */ #include #include .text .globl _secondary_start, _secondary_start_end, _secondary_gdt_addr .balign 4096 _secondary_start: .code16 cli xorl %eax, %eax movl %eax, %cr3 /* Invalidate TLB*/ /* On hyper threaded cpus, invalidating the cache here is * very very bad. Don't. */ /* setup the data segment */ movw %cs, %ax movw %ax, %ds lgdtl gdtaddr - _secondary_start movl %cr0, %eax andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */ orl $0x60000001, %eax /* CD, NW, PE = 1 */ movl %eax, %cr0 ljmpl $RAM_CODE_SEG, $__ap_protected_start /* This will get filled in by C code. */ _secondary_gdt_addr: gdtaddr: .word 0 /* the table limit */ #if ENV_X86_64 .quad 0 #else .long 0 /* we know the offset */ #endif _secondary_start_end: ap_protected_start: .code32 lgdt gdtaddr ljmpl $RAM_CODE_SEG, $__ap_protected_start __ap_protected_start: movw $RAM_DATA_SEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss movw %ax, %fs movw %ax, %gs /* Load the Interrupt descriptor table */ lidt idtarg #if ENV_X86_64 /* entry64.inc preserves ebx. */ #include movabs secondary_stack, %rax mov %rax, %rsp andl $0xfffffff0, %esp movabs secondary_cpu_index, %rax mov %rax, %rdi #else /* Set the stack pointer, and flag that we are done */ xorl %eax, %eax movl secondary_stack, %esp andl $0xfffffff0, %esp sub $12, %esp /* maintain 16-byte alignment for the call below */ movl secondary_cpu_index, %edi pushl %edi movl %eax, secondary_stack #endif call secondary_cpu_init 1: hlt jmp 1b .code32