]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/amd64/amd64/xen-locore.S
amd64: use register macros for gdb_cpu_getreg()
[FreeBSD/FreeBSD.git] / sys / amd64 / amd64 / xen-locore.S
1 /*-
2  * Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
3  * Copyright (c) 2011-2012 Spectra Logic Corporation
4  * Copyright (c) 2013 Roger Pau Monne <royger@FreeBSD.org>
5  * All rights reserved.
6  *
7  * This software was developed by Cherry G. Mathew <cherry@zyx.in>
8  * under sponsorship from Spectra Logic Corporation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33
34 #include <machine/asmacros.h>
35 #include <machine/psl.h>
36 #include <machine/pmap.h>
37 #include <machine/specialreg.h>
38
39 #include <xen/xen-os.h>
40 #define __ASSEMBLY__
41 #include <xen/interface/elfnote.h>
42
43 #include "assym.inc"
44
45 #define VTOP(x)         ((x) - KERNBASE)
46 #define ENTRY_SIZE      8 /* sizeof(uint64_t) */
47
48 #define GDT_CODE        0x08
49 #define GDT_DATA        0x10
50
51 .section __xen_guest
52         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "FreeBSD")
53         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, __XSTRING(__FreeBSD_version))
54         ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
55         ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .quad,  KERNBASE)
56         ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  0)
57         ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  xen_start)
58         ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,  hypercall_page)
59         ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .quad,  HYPERVISOR_VIRT_START)
60         ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector")
61         ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
62         ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PG_V, PG_V)
63         ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
64         ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long,  0)
65         ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB,     .asciz, "yes")
66         /* For PVHv2 support. */
67         ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,   .long,  VTOP(xen_start32))
68
69         .text
70 .p2align PAGE_SHIFT, 0x90       /* Hypercall_page needs to be PAGE aligned */
71
72 NON_GPROF_ENTRY(hypercall_page)
73         .skip   0x1000, 0x90    /* Fill with "nop"s */
74
75 /* Legacy PVH entry point, to be removed. */
76 NON_GPROF_ENTRY(xen_start)
77         /* Don't trust what the loader gives for rflags. */
78         pushq   $PSL_KERNEL
79         popfq
80
81         /* Parameters for the xen init function */
82         movq    %rsi, %rdi              /* shared_info (arg 1) */
83         movq    %rsp, %rsi              /* xenstack    (arg 2) */
84
85         /* Use our own stack */
86         movq    $bootstack,%rsp
87         xorl    %ebp, %ebp
88
89         /* u_int64_t hammer_time_xen(start_info_t *si, u_int64_t xenstack); */
90         call    hammer_time_xen_legacy
91         movq    %rax, %rsp              /* set up kstack for mi_startup() */
92         call    mi_startup              /* autoconfiguration, mountroot etc */
93
94         /* NOTREACHED */
95 0:      hlt
96         jmp     0b
97
98 /* PVH entry point. */
99         .code32
100 NON_GPROF_ENTRY(xen_start32)
101
102         /* Load flat GDT */
103         movl    $VTOP(gdtdesc32), %eax
104         lgdt    (%eax)
105         jmp     $GDT_CODE, $VTOP(reload_cs)
106
107 reload_cs:
108         movw    $GDT_DATA, %ax
109         movw    %ax, %ds
110         movw    %ax, %es
111         movw    %ax, %ss
112
113         movl    $VTOP(bootstack), %esp
114
115         /* Don't trust what the loader gives for eflags. */
116         pushl   $PSL_KERNEL
117         popfl
118
119         /*
120          * Create the page tables.
121          * The first 1GB is mapped using 2MB entries.
122          */
123         movl    $0, %eax
124 pgbuild:
125         cmp     $(PAGE_SIZE/ENTRY_SIZE), %eax
126         jae     pgbuild_done
127
128         /* PT4[i] = VTOP(&PT3[0]) | PG_V | PG_RW | PG_U */
129         movl    $VTOP(PT4), %ecx
130         movl    $VTOP(PT3), %edx
131         orl     $(PG_V | PG_RW | PG_U), %edx
132         movl    %edx, (%ecx,%eax,ENTRY_SIZE)
133
134         /* PT3[i] = VTOP(&PT2[0]) | PG_V | PG_RW | PG_U */
135         movl    $VTOP(PT3), %ecx
136         movl    $VTOP(PT2), %edx
137         orl     $(PG_V | PG_RW | PG_U), %edx
138         movl    %edx, (%ecx,%eax,ENTRY_SIZE)
139
140         /* PT2[i] = i * 2MiB | PG_V | PG_RW | PG_PS | PG_U */
141         movl    $VTOP(PT2), %ecx
142         movl    %eax, %edx
143         shll    $PDRSHIFT, %edx
144         orl     $(PG_V | PG_RW | PG_PS | PG_U), %edx
145         movl    %edx, (%ecx,%eax,ENTRY_SIZE)
146
147         inc     %eax
148         jmp     pgbuild
149
150 pgbuild_done:
151         /* Turn on EFER.LME */
152         movl    $MSR_EFER, %ecx
153         rdmsr
154         orl     $EFER_LME, %eax
155         wrmsr
156
157         /* Turn on PAE */
158         movl    %cr4, %eax
159         orl     $CR4_PAE, %eax
160         movl    %eax, %cr4
161
162         /* Set %cr3 for PT4 */
163         movl    $VTOP(PT4), %eax
164         movl    %eax, %cr3
165
166         /* Turn on paging (implicitly sets EFER.LMA) */
167         movl    %cr0, %eax
168         orl     $CR0_PG, %eax
169         movl    %eax, %cr0
170
171         /* Now we're in compatibility mode. Set %cs for long mode */
172         movl    $VTOP(gdtdesc), %eax
173         lgdt    (%eax)
174         ljmp    $GDT_CODE, $VTOP(longmode)
175
176         .code64
177 longmode:
178         /* We're still running V=P, jump to entry point */
179         movq    $bootstack, %rsp
180         movq    $start_kernel, %rax
181         pushq   %rax
182         ret
183
184 start_kernel:
185         /*
186          * Pass %ebx as the argument to hammer_time_xen, it contains
187          * the startup info.
188          */
189         movq    %rbx, %rdi
190         call    hammer_time_xen
191         movq    %rax, %rsp
192         call    mi_startup
193
194         /* NOTREACHED */
195 0:      hlt
196         jmp     0b
197
198 /* Space for initial page tables */
199         .data
200         .p2align 12,0x40
201 PT4:
202         .space  0x1000
203 PT3:
204         .space  0x1000
205 PT2:
206         .space  0x1000
207
208 /* 64bit GDT */
209 gdtdesc:
210         .word   gdtend - gdt - 1
211         .long   VTOP(gdt)               # low
212         .long   0                       # high
213 gdt:
214         .long   0                       # null descriptor
215         .long   0
216         .long   0x00000000              # %cs
217         .long   0x00209800
218         .long   0x00000000              # %ds
219         .long   0x00008000
220 gdtend:
221
222 /* 32bit GDT */
223 gdtdesc32:
224         .word   gdt32end - gdt32 - 1
225         .long   VTOP(gdt32)
226         .long   0
227 gdt32:
228         .long   0                       # null descriptor
229         .long   0
230         .long   0x0000ffff              # %cs
231         .long   0x00cf9a00
232         .long   0x0000ffff              # %ds, %es, %ss
233         .long   0x00cf9200
234 gdt32end: