.globl long_smp_trampoline
.globl long_smp_trampoline_end
.globl long_smp_trampoline_args
#include <asm_defs.h>
#include <arch/x86/descriptors.h>
#include "mmu.h"
.code16
long_smp_trampoline:
cli
.byte 0x66
.byte 0xbe
long_smp_trampoline_args:
.long 0xdeadbeef
movl %esi, %eax
shrl $4, %eax
movw %ax, %ss
xorw %sp, %sp
popl %ebx
popl %edx
lgdt (%edx)
movl %cr0,%eax
orl $0x01,%eax
movl %eax,%cr0
pushl $8
leal (long_trampoline_32 - long_smp_trampoline)(%ebx), %eax
pushl %eax
.byte 0x66
.code32
lret
long_trampoline_32:
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
movl %esi, %esp
addl $8, %esp
movl %cr4, %eax
orl $(1 << 5) | (1 << 7), %eax
movl %eax, %cr4
popl %eax
movl %eax, %cr3
popl %eax
movl $0xc0000080, %ecx
rdmsr
orl $(1 << 8), %eax
wrmsr
movl %cr0, %ecx
orl $(1 << 31), %ecx
movl %ecx, %cr0
pushl $0x18
leal (.Llmode_tmp - long_smp_trampoline)(%ebx), %eax
pushl %eax
lret
.align 8
.code64
.Llmode_tmp:
popq %rax
lgdtq (%rax)
pushq $KERNEL_CODE_SELECTOR
leaq (.Llmode - long_smp_trampoline)(%ebx), %rax
pushq %rax
lretq
.align 8
.Llmode:
mov $KERNEL_DATA_SELECTOR, %ax
mov %ax, %ss
xor %ax, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
movq %cr0, %rax
orq $0x10000, %rax
andq $(~6), %rax
movq %rax, %cr0
fninit
movq %cr4, %rax
orq $0x600, %rax
movq %rax, %cr4
popq %rax
popq %rdi
popq %rsi
popq %rbp
movq $0, (%rsp)
movq %rbp, %rsp
xorq %rbp, %rbp
push $0
popf
call *%rax
long_smp_trampoline_end: