xref: /dragonfly/stand/boot/pc32/libi386/x86_64_tramp.S (revision 479ab7f0492f2a51b48e8537e4f1dc686fc6014b)
1/*-
2 * Copyright (c) 2003  Peter Wemm <peter@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: src/sys/boot/i386/libi386/amd64_tramp.S,v 1.2 2003/05/17 00:30:51 peter Exp $
27 */
28
29#include "../bootasm.h"
30
31/*
32 * Quick and dirty trampoline to get into 64 bit (long) mode and running
33 * with paging enabled so that we enter the kernel at its linked address.
34 */
35#define MSR_EFER    0xc0000080
36#define EFER_LME    0x00000100
37#define CR4_PAE               0x00000020
38#define CR4_PSE               0x00000010
39#define CR0_PG                0x80000000
40
41/* GRRR. Deal with BTX that links us for a non-zero location */
42#define VTOP(x)     ((x) + MEM_BTX_USR)
43
44          .data
45
46          .p2align 12,0x40
47
48          .globl    PT4
49PT4:
50          .space    0x1000
51          .globl    PT3
52PT3:
53          .space    0x1000
54          .globl    PT2
55PT2:
56          .space    0x1000
57
58gdtdesc:
59          .word     gdtend - gdt
60          .long     VTOP(gdt)           # low
61          .long     0                             # high
62
63gdt:
64          .long     0                             # null descriptor
65          .long     0
66          .long     0x00000000                    # %cs
67          .long     0x00209800
68          .long     0x00000000                    # %ds
69          .long     0x00008000
70gdtend:
71
72          .text
73          .code32
74
75          .globl    x86_64_tramp
76x86_64_tramp:
77          /* Be sure that interrupts are disabled */
78          cli
79
80          /* Turn on EFER.LME */
81          movl      $MSR_EFER, %ecx
82          rdmsr
83          orl       $EFER_LME, %eax
84          wrmsr
85
86          /* Turn on PAE */
87          movl      %cr4, %eax
88          orl       $(CR4_PAE | CR4_PSE), %eax
89          movl      %eax, %cr4
90
91          /* Set %cr3 for PT4 */
92          movl      $VTOP(PT4), %eax
93          movl      %eax, %cr3
94
95          /* Turn on paging (implicitly sets EFER.LMA) */
96          movl      %cr0, %eax
97          orl       $CR0_PG, %eax
98          movl      %eax, %cr0
99
100          /* Now we're in compatibility mode. set %cs for long mode */
101          movl      $VTOP(gdtdesc), %eax
102          movl      VTOP(entry_hi), %esi
103          movl      VTOP(entry_lo), %edi
104          lgdt      (%eax)
105          ljmp      $0x8, $VTOP(longmode)
106
107          .code64
108longmode:
109          /* We're still running V=P, jump to entry point */
110          movl      %esi, %eax
111          salq      $32, %rax
112          orq       %rdi, %rax
113          pushq     %rax
114          ret
115