1/*
2** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3** Distributed under the terms of the NewOS License.
4*/
5// expects a stack page like this:
6// (stack has to be at (0x8c000)
7//	0x8cffc            : final esp
8//  0x8cff8            : page dir
9//
10//  0x8c000 - 0x8c006  : gdt descriptor
11//	0x8c008 - 0x8c020  : gdt
12//
13// smp_trampoline must be located at 0x8b000
14.globl smp_trampoline
15.globl smp_trampoline_end
16.globl foo
17
18.code16
19smp_trampoline:
20	cli
21
22	mov    $0x8c00,%ax
23	mov    %ax,%ds
24
25//	lgdt   0x8c000          # load the gdt
26.byte 0x66, 0x0f, 0x01, 0x15, 0x00, 0xc0, 0x08, 0x00
27
28	movl   %cr0,%eax
29	orl    $0x01,%eax
30	movl   %eax,%cr0              # switch into protected mode
31
32.code32
33_trampoline_32:
34	.byte 0x66
35	ljmp   $0x08,$(trampoline_32 - smp_trampoline + 0x8b000)
36trampoline_32:
37	mov    $0x10, %ax
38	mov    %ax, %ds
39	mov    %ax, %es
40	mov    %ax, %fs
41	mov    %ax, %gs
42	mov    %ax, %ss
43
44	movl   $0x8cff8,%esp    # set up the stack pointer
45
46	popl   %eax             # get the page dir
47	movl   %eax,%cr3        # set the page dir
48
49	popl   %eax             # get the final stack location
50
51	// Clear the final stack location to notify the startup code that
52	// we loaded the address and it is now safe to be overwritten.
53	pushl  $0x00000000
54
55	movl   %eax,%esp
56
57	// load an address for an indirect jump
58	movl   $trampoline_after_paging,%ecx
59
60	movl   %cr0,%eax
61	orl    $0x80000000,%eax
62	movl   %eax,%cr0          # enable paging
63
64	// jump to the address previously loaded. NOTE:
65	// this address is the address at which the code is originally linked,
66	// which is > 1MB. We will be out of the low memory at this point.
67	jmp    *%ecx
68trampoline_after_paging:
69	// just return, the bsp would have set the return address to the
70	// target function at the top of the passed stack
71	ret
72
73smp_trampoline_end:
74
75