1/*
2 * Copyright 2021-2022 Haiku, Inc. All rights reserved.
3 * Released under the terms of the MIT License.
4 *
5 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
6 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
7 * Distributed under the terms of the NewOS License.
8 */
9
10// Relocatable. Before calling, smp_trampoline_args should point
11// to a struct trampoline_args (see smp.cpp). This pointer should
12// be 16-byte aligned, below 1MB and identity-mapped.
13.globl smp_trampoline
14.globl smp_trampoline_end
15.globl smp_trampoline_args
16
17#include <asm_defs.h>
18
19#include <arch/x86/descriptors.h>
20#include "mmu.h"
21
22.code16
23smp_trampoline:
24	cli
25
26//  movl 0xdeadbeef, esi
27	.byte 0x66
28	.byte 0xbe
29smp_trampoline_args:
30	.long 0xdeadbeef
31
32	// Set up the stack pointer for 16-bit mode
33	movl %esi, %eax
34	shrl $4, %eax
35	movw %ax, %ss
36	xorw %sp, %sp
37
38	popl %ebx		// trampoline
39
40	// Initialize GDT
41	popl %edx		// gdt
42	lgdt (%edx)
43
44	// Switch to protected mode
45	movl   %cr0, %eax
46	orl    $0x01, %eax
47	movl   %eax, %cr0
48
49	pushl  $KERNEL_CODE_SELECTOR
50	leal  (trampoline_32 - smp_trampoline)(%ebx), %eax
51	pushl  %eax
52.code32
53	.byte 0x66
54	lret
55
56trampoline_32:
57	// Set data segments.
58	movw   $KERNEL_DATA_SELECTOR, %ax
59	movw   %ax, %ds
60	movw   %ax, %es
61	movw   %ax, %fs
62	movw   %ax, %gs
63	movw   %ax, %ss
64
65	// Set up the stack pointer for 32-bit mode
66	movl	%esi, %esp
67	addl	$8, %esp
68
69	// Point CR3 to the kernel's page dir.
70	popl	%eax		// page_dir
71	movl	%eax, %cr3
72
73	popl	%ebx		// kernel_entry
74	popl	%ecx		// kernel_args
75	popl	%edx		// current_cpu
76
77	// Set the stack pointer, write to the sentinel and clear the stack frame
78	popl	%ebp		// stack_top
79	movl	$0, (%esp)	// sentinel
80	movl	%ebp, %esp
81	xorl	%ebp, %ebp
82
83	movl	$0x80010021, %eax
84	movl	%eax, %cr0
85
86	cli
87	cld
88	fninit
89
90	pushl	%edx		// currentCpu
91	pushl	%ecx		// kernelArgs
92	pushl	$0x0		// fake return address
93	pushl	$KERNEL_CODE_SELECTOR
94	pushl	%ebx		// kernelEntry
95	lret
96smp_trampoline_end:
97