xref: /haiku/src/system/boot/platform/bios_ia32/smp_trampoline.S (revision 3fa048c0a641db7b58d69c9629cb714de60d221c)
15af32e75SAxel Dörfler/*
25af32e75SAxel Dörfler** Copyright 2001, Travis Geiselbrecht. All rights reserved.
35af32e75SAxel Dörfler** Distributed under the terms of the NewOS License.
45af32e75SAxel Dörfler*/
55af32e75SAxel Dörfler// expects a stack page like this:
65af32e75SAxel Dörfler// (stack has to be at (0x9e000)
75af32e75SAxel Dörfler//	0x9effc            : final esp
85af32e75SAxel Dörfler//  0x9eff8            : page dir
95af32e75SAxel Dörfler//
105af32e75SAxel Dörfler//  0x9e000 - 0x9e006  : gdt descriptor
115af32e75SAxel Dörfler//	0x9e008 - 0x9e020  : gdt
125af32e75SAxel Dörfler//
135af32e75SAxel Dörfler// smp_trampoline must be located at 0x9f000
145af32e75SAxel Dörfler.globl smp_trampoline
155af32e75SAxel Dörfler.globl smp_trampoline_end
165af32e75SAxel Dörfler.globl foo
175af32e75SAxel Dörfler
185af32e75SAxel Dörfler.code16
195af32e75SAxel Dörflersmp_trampoline:
205af32e75SAxel Dörfler	cli
215af32e75SAxel Dörfler
225af32e75SAxel Dörfler	mov    $0x9e00,%ax
235af32e75SAxel Dörfler	mov    %ax,%ds
245af32e75SAxel Dörfler
255af32e75SAxel Dörfler//	lgdt   0x9e000          # load the gdt
265af32e75SAxel Dörfler.byte 0x66, 0x0f, 0x01, 0x15, 0x00, 0xe0, 0x09, 0x00
275af32e75SAxel Dörfler
285af32e75SAxel Dörfler	movl   %cr0,%eax
295af32e75SAxel Dörfler	orl    $0x01,%eax
305af32e75SAxel Dörfler	movl   %eax,%cr0              # switch into protected mode
315af32e75SAxel Dörfler
325af32e75SAxel Dörfler.code32
335af32e75SAxel Dörfler_trampoline_32:
345af32e75SAxel Dörfler	.byte 0x66
355af32e75SAxel Dörfler	ljmp   $0x08,$(trampoline_32 - smp_trampoline + 0x9f000)
365af32e75SAxel Dörflertrampoline_32:
375af32e75SAxel Dörfler	mov    $0x10, %ax
385af32e75SAxel Dörfler	mov    %ax, %ds
395af32e75SAxel Dörfler	mov    %ax, %es
405af32e75SAxel Dörfler	mov    %ax, %fs
415af32e75SAxel Dörfler	mov    %ax, %gs
425af32e75SAxel Dörfler	mov    %ax, %ss
435af32e75SAxel Dörfler
445af32e75SAxel Dörfler	movl   $0x9eff8,%esp    # set up the stack pointer
455af32e75SAxel Dörfler
465af32e75SAxel Dörfler	popl   %eax             # get the page dir
475af32e75SAxel Dörfler	movl   %eax,%cr3        # set the page dir
485af32e75SAxel Dörfler
495af32e75SAxel Dörfler	popl   %eax             # get the final stack location
50*3fa048c0SMichael Lotz
51*3fa048c0SMichael Lotz	// Clear the final stack location to notify the startup code that
52*3fa048c0SMichael Lotz	// we loaded the address and it is now safe to be overwritten.
53*3fa048c0SMichael Lotz	pushl  $0x00000000
54*3fa048c0SMichael Lotz
555af32e75SAxel Dörfler	movl   %eax,%esp
565af32e75SAxel Dörfler
575af32e75SAxel Dörfler	// load an address for an indirect jump
585af32e75SAxel Dörfler	movl   $trampoline_after_paging,%ecx
595af32e75SAxel Dörfler
605af32e75SAxel Dörfler	movl   %cr0,%eax
615af32e75SAxel Dörfler	orl    $0x80000000,%eax
625af32e75SAxel Dörfler	movl   %eax,%cr0          # enable paging
635af32e75SAxel Dörfler
645af32e75SAxel Dörfler	// jump to the address previously loaded. NOTE:
655af32e75SAxel Dörfler	// this address is the address at which the code is originally linked,
665af32e75SAxel Dörfler	// which is > 1MB. We will be out of the low memory at this point.
675af32e75SAxel Dörfler	jmp    *%ecx
685af32e75SAxel Dörflertrampoline_after_paging:
695af32e75SAxel Dörfler	// just return, the bsp would have set the return address to the
705af32e75SAxel Dörfler	// target function at the top of the passed stack
715af32e75SAxel Dörfler	ret
725af32e75SAxel Dörfler
735af32e75SAxel Dörflersmp_trampoline_end:
745af32e75SAxel Dörfler
75