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