148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen/* 248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 348927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * Trampoline.S Derived from Setup.S by Linus Torvalds 448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 4 Jan 1997 Michael Chastain: changed to gnu as. 648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 15 Sept 2005 Eric Biederman: 64bit PIC support 748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 848927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * Entry: CS:IP point to the start of our code, we are 948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * in real mode with no stack, but the rest of the 1048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * trampoline page to make our stack and everything else 1148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * is a mystery. 1248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 13f37240f16bec91f15ce564515f70a6ca9715ce96Jarkko Sakkinen * On entry to trampoline_start, the processor is in real mode 1448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * with 16-bit addressing and 16-bit data. CS has some value 1548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * and IP is zero. Thus, data addresses need to be absolute 1648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * (no relocation) and are taken with regard to r_base. 1748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 1848927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * With the addition of trampoline_level4_pgt this code can 1948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * now enter a 64bit kernel that lives at arbitrary 64bit 2048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * physical addresses. 2148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * 2248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * If you work on this file, check the object module with objdump 2348927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * --full-contents --reloc to make sure there are no relocation 2448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * entries. 2548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen */ 2648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 2748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen#include <linux/linkage.h> 2848927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen#include <asm/pgtable_types.h> 2948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen#include <asm/page_types.h> 3048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen#include <asm/msr.h> 3148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen#include <asm/segment.h> 3248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen#include <asm/processor-flags.h> 33e5684ec438a094bec0f7d5c52652c0901b48b613H. Peter Anvin#include "realmode.h" 3448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 3548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen .text 3648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen .code16 3748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 38cda846f101fb1396b6924f1d9b68ac3d42de5403Jarkko Sakkinen .balign PAGE_SIZE 39f37240f16bec91f15ce564515f70a6ca9715ce96Jarkko SakkinenENTRY(trampoline_start) 4048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen cli # We should be safe anyway 4148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen wbinvd 4248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 43e5684ec438a094bec0f7d5c52652c0901b48b613H. Peter Anvin LJMPW_RM(1f) 4448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen1: 4548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen mov %cs, %ax # Code and data in the same place 4648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen mov %ax, %ds 4748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen mov %ax, %es 4848927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen mov %ax, %ss 4948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 5048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen movl $0xA5A5A5A5, trampoline_status 5148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen # write marker for master knows we're running 5248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 5348927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen # Setup stack 548e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl $rm_stack_end, %esp 5548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 5648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen call verify_cpu # Verify the cpu supports long mode 5748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen testl %eax, %eax # Check for return code 5848927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen jnz no_longmode 5948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 6048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen /* 6148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * GDT tables in non default location kernel can be beyond 16MB and 6248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * lgdt will not be able to load the address as in real mode default 6348927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * operand size is 16bit. Use lgdtl instead to force operand size 6448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * to 32 bit. 6548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen */ 6648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 67cda846f101fb1396b6924f1d9b68ac3d42de5403Jarkko Sakkinen lidtl tr_idt # load idt with 0, 0 68cda846f101fb1396b6924f1d9b68ac3d42de5403Jarkko Sakkinen lgdtl tr_gdt # load gdt with whatever is appropriate 6948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 708e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movw $__KERNEL_DS, %dx # Data segment descriptor 718e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen 728e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen # Enable protected mode 738e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl $X86_CR0_PE, %eax # protected mode (PE) bit 748e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl %eax, %cr0 # into protected mode 7548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 7648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen # flush prefetch and jump to startup_32 77056a43a6d3ab903a798d8ee4435ad67d6fccc3e6H. Peter Anvin ljmpl $__KERNEL32_CS, $pa_startup_32 7848927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 7948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinenno_longmode: 8048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen hlt 8148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen jmp no_longmode 8248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen#include "../kernel/verify_cpu.S" 8348927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 84024742861124ef26dae4cfc620250f8f47ac934aH. Peter Anvin .section ".text32","ax" 8548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen .code32 8648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen .balign 4 8748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko SakkinenENTRY(startup_32) 888e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl %edx, %ss 898e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen addl $pa_real_mode_base, %esp 908e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl %edx, %ds 918e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl %edx, %es 928e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl %edx, %fs 938e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl %edx, %gs 9448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 95cda846f101fb1396b6924f1d9b68ac3d42de5403Jarkko Sakkinen movl pa_tr_cr4, %eax 9648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen movl %eax, %cr4 # Enable PAE mode 9748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 988e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen # Setup trampoline 4 level pagetables 99f37240f16bec91f15ce564515f70a6ca9715ce96Jarkko Sakkinen movl $pa_trampoline_pgd, %eax 10048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen movl %eax, %cr3 10148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 102cda846f101fb1396b6924f1d9b68ac3d42de5403Jarkko Sakkinen # Set up EFER 103cda846f101fb1396b6924f1d9b68ac3d42de5403Jarkko Sakkinen movl pa_tr_efer, %eax 104cda846f101fb1396b6924f1d9b68ac3d42de5403Jarkko Sakkinen movl pa_tr_efer + 4, %edx 10548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen movl $MSR_EFER, %ecx 10648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen wrmsr 10748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 10848927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen # Enable paging and in turn activate Long Mode 1098e029fcdd8702719c9179317cae9ef84ebe7027eJarkko Sakkinen movl $(X86_CR0_PG | X86_CR0_WP | X86_CR0_PE), %eax 11048927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen movl %eax, %cr0 11148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 11248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen /* 11348927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * At this point we're in long mode but in 32bit compatibility mode 11448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn 11548927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use 11648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen * the new gdt/idt that has __KERNEL_CS with CS.L = 1. 11748927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen */ 118056a43a6d3ab903a798d8ee4435ad67d6fccc3e6H. Peter Anvin ljmpl $__KERNEL_CS, $pa_startup_64 11948927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 120024742861124ef26dae4cfc620250f8f47ac934aH. Peter Anvin .section ".text64","ax" 12148927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen .code64 12248927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen .balign 4 12348927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko SakkinenENTRY(startup_64) 12448927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen # Now jump into the kernel using virtual addresses 125f37240f16bec91f15ce564515f70a6ca9715ce96Jarkko Sakkinen jmpq *tr_start(%rip) 12648927bbb97c7d4cf343c05827ab9ac30c60678cbJarkko Sakkinen 12751edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .section ".rodata","a" 12851edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin # Duplicate the global descriptor table 12951edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin # so the kernel can live anywhere 13051edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .balign 16 13151edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .globl tr_gdt 13251edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvintr_gdt: 13351edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .short tr_gdt_end - tr_gdt - 1 # gdt limit 13451edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .long pa_tr_gdt 13551edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .short 0 13651edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .quad 0x00cf9b000000ffff # __KERNEL32_CS 13751edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .quad 0x00af9b000000ffff # __KERNEL_CS 13851edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .quad 0x00cf93000000ffff # __KERNEL_DS 13951edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvintr_gdt_end: 14051edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin 14151edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .bss 14251edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .balign PAGE_SIZE 14351edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter AnvinGLOBAL(trampoline_pgd) .space PAGE_SIZE 14451edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin 14551edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin .balign 8 14651edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter AnvinGLOBAL(trampoline_header) 14751edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin tr_start: .space 8 14851edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin GLOBAL(tr_efer) .space 8 149638d957b51c88852de72f15f7cd588d125e97dabH. Peter Anvin GLOBAL(tr_cr4) .space 4 15051edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter AnvinEND(trampoline_header) 15151edbe6a2f47c78c6c6e529999ee0a044fe59a89H. Peter Anvin 152f37240f16bec91f15ce564515f70a6ca9715ce96Jarkko Sakkinen#include "trampoline_common.S" 153