18368e25fSAaron LI/* 28368e25fSAaron LI * Copyright (c) 1998, 2000, 2007, 2008, 2016, 2017 The NetBSD Foundation, Inc. 38368e25fSAaron LI * All rights reserved. 48368e25fSAaron LI * 58368e25fSAaron LI * This code is derived from software contributed to The NetBSD Foundation 68368e25fSAaron LI * by Charles M. Hannum and by Maxime Villard. 78368e25fSAaron LI * 88368e25fSAaron LI * Redistribution and use in source and binary forms, with or without 98368e25fSAaron LI * modification, are permitted provided that the following conditions 108368e25fSAaron LI * are met: 118368e25fSAaron LI * 1. Redistributions of source code must retain the above copyright 128368e25fSAaron LI * notice, this list of conditions and the following disclaimer. 138368e25fSAaron LI * 2. Redistributions in binary form must reproduce the above copyright 148368e25fSAaron LI * notice, this list of conditions and the following disclaimer in the 158368e25fSAaron LI * documentation and/or other materials provided with the distribution. 168368e25fSAaron LI * 178368e25fSAaron LI * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 188368e25fSAaron LI * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 198368e25fSAaron LI * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 208368e25fSAaron LI * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 218368e25fSAaron LI * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 228368e25fSAaron LI * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 238368e25fSAaron LI * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 248368e25fSAaron LI * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 258368e25fSAaron LI * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 268368e25fSAaron LI * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 278368e25fSAaron LI * POSSIBILITY OF SUCH DAMAGE. 288368e25fSAaron LI */ 298368e25fSAaron LI 308368e25fSAaron LI#define _LOCORE 31*20b815aaSAaron LI#define LOCORE /* DragonFly */ 328368e25fSAaron LI 333bac6f2aSAaron LI#include "asm.h" 343bac6f2aSAaron LI#include "pdir.h" 358368e25fSAaron LI 368368e25fSAaron LI#include <machine/param.h> 378368e25fSAaron LI#include <machine/segments.h> 388368e25fSAaron LI#include <machine/specialreg.h> 398368e25fSAaron LI 403bac6f2aSAaron LI#define PSL_MBO 0x00000002 /* must be zero bits */ 418368e25fSAaron LI 423bac6f2aSAaron LI#define PTE_P 0x001 /* P: Valid */ 433bac6f2aSAaron LI#define PTE_W 0x002 /* R/W: Read/Write */ 443bac6f2aSAaron LI#define PTE_PCD 0x010 /* PCD: Cache disable */ 458368e25fSAaron LI 468368e25fSAaron LI/* 32bit version of PG_NX */ 478368e25fSAaron LI#define PG_NX32 0x80000000 488368e25fSAaron LI 498368e25fSAaron LI#define TABLE_L2_ENTRIES (NKL2_KIMG_ENTRIES + 1) 508368e25fSAaron LI#define TABLE_L3_ENTRIES NKL3_KIMG_ENTRIES 518368e25fSAaron LI 528368e25fSAaron LI#define PROC0_PML4_OFF 0 538368e25fSAaron LI#define PROC0_STK_OFF (PROC0_PML4_OFF + 1 * PAGE_SIZE) 548368e25fSAaron LI#define PROC0_PTP3_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) 558368e25fSAaron LI#define PROC0_PTP2_OFF (PROC0_PTP3_OFF + NKL4_KIMG_ENTRIES * PAGE_SIZE) 568368e25fSAaron LI#define PROC0_PTP1_OFF (PROC0_PTP2_OFF + TABLE_L3_ENTRIES * PAGE_SIZE) 578368e25fSAaron LI#define TABLESIZE \ 588368e25fSAaron LI ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1 + UPAGES) \ 598368e25fSAaron LI * PAGE_SIZE) 608368e25fSAaron LI 618368e25fSAaron LI/* 628368e25fSAaron LI * fillkpt - Fill in a kernel page table 638368e25fSAaron LI * eax = pte (page frame | control | status) 648368e25fSAaron LI * ebx = page table address 658368e25fSAaron LI * ecx = number of pages to map 668368e25fSAaron LI * 678368e25fSAaron LI * Each entry is 8 (PDE_SIZE) bytes long: we must set the 4 upper bytes to 0. 688368e25fSAaron LI */ 698368e25fSAaron LI#define fillkpt \ 708368e25fSAaron LI cmpl $0,%ecx ; /* zero-sized? */ \ 718368e25fSAaron LI je 2f ; \ 728368e25fSAaron LI1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \ 738368e25fSAaron LI movl %eax,(%ebx) ; /* store phys addr */ \ 748368e25fSAaron LI addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ 758368e25fSAaron LI addl $PAGE_SIZE,%eax ; /* next phys page */ \ 768368e25fSAaron LI loop 1b ; \ 778368e25fSAaron LI2: ; 788368e25fSAaron LI 798368e25fSAaron LI/* 808368e25fSAaron LI * fillkpt_nox - Same as fillkpt, but sets the NX/XD bit. 818368e25fSAaron LI */ 828368e25fSAaron LI#define fillkpt_nox \ 838368e25fSAaron LI cmpl $0,%ecx ; /* zero-sized? */ \ 848368e25fSAaron LI je 2f ; \ 858368e25fSAaron LI pushl %ebp ; \ 868368e25fSAaron LI movl _C_LABEL(nox_flag),%ebp ; \ 878368e25fSAaron LI1: movl %ebp,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: NX */ \ 888368e25fSAaron LI movl %eax,(%ebx) ; /* store phys addr */ \ 898368e25fSAaron LI addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ 908368e25fSAaron LI addl $PAGE_SIZE,%eax ; /* next phys page */ \ 918368e25fSAaron LI loop 1b ; \ 928368e25fSAaron LI popl %ebp ; \ 938368e25fSAaron LI2: ; 948368e25fSAaron LI 958368e25fSAaron LI/* 968368e25fSAaron LI * fillkpt_blank - Fill in a kernel page table with blank entries 978368e25fSAaron LI * ebx = page table address 988368e25fSAaron LI * ecx = number of pages to map 998368e25fSAaron LI */ 1008368e25fSAaron LI#define fillkpt_blank \ 1018368e25fSAaron LI cmpl $0,%ecx ; /* zero-sized? */ \ 1028368e25fSAaron LI je 2f ; \ 1038368e25fSAaron LI1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \ 1048368e25fSAaron LI movl $0,(%ebx) ; /* lower 32 bits: 0 */ \ 1058368e25fSAaron LI addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \ 1068368e25fSAaron LI loop 1b ; \ 1078368e25fSAaron LI2: ; 1088368e25fSAaron LI 1098368e25fSAaron LI/* 1108368e25fSAaron LI * Initialization 1118368e25fSAaron LI */ 1128368e25fSAaron LI .data 1138368e25fSAaron LI 1148368e25fSAaron LI .globl _C_LABEL(tablesize) 1158368e25fSAaron LI .globl _C_LABEL(nox_flag) 1168368e25fSAaron LI .globl _C_LABEL(cpuid_level) 1178368e25fSAaron LI .globl _C_LABEL(PDPpaddr) 1188368e25fSAaron LI .globl _C_LABEL(atdevbase) 119aaa1e810SAaron LI .globl _C_LABEL(lapicbase) 1208368e25fSAaron LI .globl _C_LABEL(stkpa) 1218368e25fSAaron LI .globl _C_LABEL(stkva) 1228368e25fSAaron LI 1238368e25fSAaron LI .type _C_LABEL(tablesize), @object 1248368e25fSAaron LI_C_LABEL(tablesize): .long TABLESIZE 1258368e25fSAaron LIEND(tablesize) 1268368e25fSAaron LI .type _C_LABEL(nox_flag), @object 1278368e25fSAaron LILABEL(nox_flag) .long 0 /* 32bit NOX flag, set if supported */ 1288368e25fSAaron LIEND(nox_flag) 1298368e25fSAaron LI .type _C_LABEL(cpuid_level), @object 1308368e25fSAaron LILABEL(cpuid_level) .long -1 /* max. level accepted by cpuid instr */ 1318368e25fSAaron LIEND(cpuid_level) 1328368e25fSAaron LI .type _C_LABEL(PDPpaddr), @object 1338368e25fSAaron LILABEL(PDPpaddr) .quad 0 1348368e25fSAaron LIEND(PDPpaddr) 1358368e25fSAaron LI .type _C_LABEL(atdevbase), @object 1368368e25fSAaron LILABEL(atdevbase) .quad 0 /* location of start of iomem in virt */ 1378368e25fSAaron LIEND(atdevbase) 1388368e25fSAaron LI .type _C_LABEL(lapicbase), @object 1398368e25fSAaron LILABEL(lapicbase) .quad 0 /* location of start of lapic in virt */ 1408368e25fSAaron LIEND(lapicbase) 1418368e25fSAaron LI .type _C_LABEL(stkpa), @object 1428368e25fSAaron LILABEL(stkpa) .quad 0 1438368e25fSAaron LIEND(stkpa) 1448368e25fSAaron LI .type _C_LABEL(stkva), @object 1458368e25fSAaron LILABEL(stkva) .quad 0 1468368e25fSAaron LIEND(stkva) 1478368e25fSAaron LI 1488368e25fSAaron LI .globl gdt64_lo 1498368e25fSAaron LI .globl gdt64_start 1508368e25fSAaron LI 1518368e25fSAaron LI#define GDT64_LIMIT gdt64_end-gdt64_start-1 1528368e25fSAaron LI/* Temporary gdt64, with base address in low memory */ 1538368e25fSAaron LI .type _C_LABEL(gdt64_lo), @object 1548368e25fSAaron LILABEL(gdt64_lo) 1558368e25fSAaron LI .word GDT64_LIMIT 1568368e25fSAaron LI .quad gdt64_start 1578368e25fSAaron LIEND(gdt64_lo) 1588368e25fSAaron LI.align 64 1598368e25fSAaron LI#undef GDT64_LIMIT 1608368e25fSAaron LI 1618368e25fSAaron LI .type _C_LABEL(gdt64_start), @object 1628368e25fSAaron LILABEL(gdt64_start) 1638368e25fSAaron LI .quad 0x0000000000000000 /* always empty */ 1648368e25fSAaron LI .quad 0x00af9a000000ffff /* kernel CS */ 1658368e25fSAaron LI .quad 0x00cf92000000ffff /* kernel DS */ 1668368e25fSAaron LI .quad 0x0000000000000000 /* kernel TSS [1/2] */ 1678368e25fSAaron LI .quad 0x0000000000000000 /* kernel TSS [2/2] */ 1688368e25fSAaron LIEND(gdt64_start) 1698368e25fSAaron LIgdt64_end: 1708368e25fSAaron LI 1718368e25fSAaron LI .type _C_LABEL(farjmp64), @object 1728368e25fSAaron LI_C_LABEL(farjmp64): 1738368e25fSAaron LI .long longmode 1748368e25fSAaron LI .word GSEL(GCODE_SEL, SEL_KPL) 1758368e25fSAaron LIEND(farjmp64) 1768368e25fSAaron LI 1778368e25fSAaron LI /* Space for the temporary stack */ 1788368e25fSAaron LI .size tmpstk, tmpstk - . 1798368e25fSAaron LI .space 512 1808368e25fSAaron LItmpstk: 1818368e25fSAaron LI 1828368e25fSAaron LI .text 1838368e25fSAaron LI 1848368e25fSAaron LIENTRY(start) 1858368e25fSAaron LI .code32 1868368e25fSAaron LI 1878368e25fSAaron LI xorl %eax,%eax 1888368e25fSAaron LI 1898368e25fSAaron LI /* Switch to new stack now. */ 1908368e25fSAaron LI movl $_C_LABEL(tmpstk),%esp 1918368e25fSAaron LI 1928368e25fSAaron LI /* First, reset the PSL. */ 1938368e25fSAaron LI pushl $PSL_MBO 1948368e25fSAaron LI popfl 1958368e25fSAaron LI 1968368e25fSAaron LI xorl %eax,%eax 1978368e25fSAaron LI cpuid 1988368e25fSAaron LI movl %eax,_C_LABEL(cpuid_level) 1998368e25fSAaron LI 2008368e25fSAaron LI /* 2018368e25fSAaron LI * Retrieve the NX/XD flag. We use the 32bit version of PG_NX. 2028368e25fSAaron LI */ 2038368e25fSAaron LI movl $0x80000001,%eax 2048368e25fSAaron LI cpuid 2058368e25fSAaron LI andl $CPUID_NOX,%edx 2068368e25fSAaron LI jz .Lno_NOX 2078368e25fSAaron LI movl $PG_NX32,_C_LABEL(nox_flag) 2088368e25fSAaron LI.Lno_NOX: 2098368e25fSAaron LI 2108368e25fSAaron LI/* 2118368e25fSAaron LI * There are four levels of pages in amd64: PML4 -> PDP -> PD -> PT. They will 2128368e25fSAaron LI * be referred to as: L4 -> L3 -> L2 -> L1. 2138368e25fSAaron LI * 2148368e25fSAaron LI * Physical address space: 2158368e25fSAaron LI * +-----------------+------------------+ 2168368e25fSAaron LI * | SMALLKERN IMAGE | BOOTSTRAP TABLES | 2178368e25fSAaron LI * +-----------------+------------------+ 2188368e25fSAaron LI * (1) 2198368e25fSAaron LI * 2208368e25fSAaron LI * Virtual address space of the smallkern: 2218368e25fSAaron LI * +-----------------+------------------+ 2228368e25fSAaron LI * | SMALLKERN IMAGE | BOOTSTRAP TABLES | 2238368e25fSAaron LI * +-----------------+------------------+ 2248368e25fSAaron LI * 2258368e25fSAaron LI * PROC0 STK is obviously not linked as a page level. It just happens to be 2268368e25fSAaron LI * caught between L4 and L3. 2278368e25fSAaron LI * 2288368e25fSAaron LI * (PROC0 STK + L4 + L3 + L2 + L1) is later referred to as BOOTSTRAP TABLES. 2298368e25fSAaron LI * 2308368e25fSAaron LI * Important note: the kernel segments are properly 4k-aligned 2318368e25fSAaron LI * (see kern.ldscript), so there's no need to enforce alignment. 2328368e25fSAaron LI */ 2338368e25fSAaron LI 2348368e25fSAaron LI /* Find end of the kernel image; brings us on (1). */ 2358368e25fSAaron LI movl $_C_LABEL(__smallkern_end),%edi 2368368e25fSAaron LI 2378368e25fSAaron LI /* We are on (1). Align up for LAPIC PAGE. */ 2388368e25fSAaron LI movl %edi,%esi 2398368e25fSAaron LI addl $PGOFSET,%esi 2408368e25fSAaron LI andl $~PGOFSET,%esi 2418368e25fSAaron LI 2428368e25fSAaron LI /* We are on the BOOTSTRAP TABLES. Save L4's physical address. */ 2438368e25fSAaron LI movl $_C_LABEL(PDPpaddr),%ebp 2448368e25fSAaron LI movl %esi,(%ebp) 2458368e25fSAaron LI movl $0,4(%ebp) 2468368e25fSAaron LI 2478368e25fSAaron LI /* Now, zero out the BOOTSTRAP TABLES (before filling them in). */ 2488368e25fSAaron LI movl %esi,%edi 2498368e25fSAaron LI xorl %eax,%eax 2508368e25fSAaron LI cld 2518368e25fSAaron LI movl $TABLESIZE,%ecx 2528368e25fSAaron LI shrl $2,%ecx 2538368e25fSAaron LI rep 2548368e25fSAaron LI stosl /* copy eax -> edi */ 2558368e25fSAaron LI 2568368e25fSAaron LI/* 2578368e25fSAaron LI * Build the page tables and levels. We go from L1 to L4, and link the levels 2588368e25fSAaron LI * together. 2598368e25fSAaron LI */ 2608368e25fSAaron LI /* 2618368e25fSAaron LI * Build L1. 2628368e25fSAaron LI */ 2638368e25fSAaron LI leal (PROC0_PTP1_OFF)(%esi),%ebx 2648368e25fSAaron LI 2658368e25fSAaron LI /* Skip the area below the smallkern text. */ 2668368e25fSAaron LI movl $(SMALLKERNTEXTOFF - SMALLKERNBASE),%ecx 2678368e25fSAaron LI shrl $PGSHIFT,%ecx 2688368e25fSAaron LI fillkpt_blank 2698368e25fSAaron LI 2708368e25fSAaron LI /* Map the smallkern text RX. */ 2718368e25fSAaron LI movl $(SMALLKERNTEXTOFF - SMALLKERNBASE),%eax /* start of TEXT */ 2728368e25fSAaron LI movl $_C_LABEL(__rodata_start),%ecx 2738368e25fSAaron LI subl %eax,%ecx 2748368e25fSAaron LI shrl $PGSHIFT,%ecx 2758368e25fSAaron LI orl $(PTE_P),%eax 2768368e25fSAaron LI fillkpt 2778368e25fSAaron LI 2788368e25fSAaron LI /* Map the smallkern rodata R. */ 2798368e25fSAaron LI movl $_C_LABEL(__rodata_start),%eax 2808368e25fSAaron LI movl $_C_LABEL(__data_start),%ecx 2818368e25fSAaron LI subl %eax,%ecx 2828368e25fSAaron LI shrl $PGSHIFT,%ecx 2838368e25fSAaron LI orl $(PTE_P),%eax 2848368e25fSAaron LI fillkpt_nox 2858368e25fSAaron LI 2868368e25fSAaron LI /* Map the smallkern data+bss RW. */ 2878368e25fSAaron LI movl $_C_LABEL(__data_start),%eax 2888368e25fSAaron LI movl $_C_LABEL(__smallkern_end),%ecx 2898368e25fSAaron LI subl %eax,%ecx 2908368e25fSAaron LI shrl $PGSHIFT,%ecx 2918368e25fSAaron LI orl $(PTE_P|PTE_W),%eax 2928368e25fSAaron LI fillkpt_nox 2938368e25fSAaron LI 2948368e25fSAaron LI /* Map some blank space, to keep pa = va. */ 2958368e25fSAaron LI movl $_C_LABEL(__smallkern_end),%eax 2968368e25fSAaron LI movl %esi,%ecx /* start of BOOTSTRAP TABLES */ 2978368e25fSAaron LI subl %eax,%ecx 2988368e25fSAaron LI shrl $PGSHIFT,%ecx 2998368e25fSAaron LI fillkpt_blank 3008368e25fSAaron LI 3018368e25fSAaron LI /* Map the BOOTSTRAP TABLES RW. */ 3028368e25fSAaron LI movl %esi,%eax /* start of BOOTSTRAP TABLES */ 3038368e25fSAaron LI movl $TABLESIZE,%ecx /* length of BOOTSTRAP TABLES */ 3048368e25fSAaron LI shrl $PGSHIFT,%ecx 3058368e25fSAaron LI orl $(PTE_P|PTE_W),%eax 3068368e25fSAaron LI fillkpt_nox 3078368e25fSAaron LI 3088368e25fSAaron LI /* Map the LAPIC PAGE RW. */ 3098368e25fSAaron LI movl $0xfee00000,%eax 3108368e25fSAaron LI movl $PAGE_SIZE,%ecx /* size of the LAPIC PAGE */ 3118368e25fSAaron LI shrl $PGSHIFT,%ecx 3128368e25fSAaron LI orl $(PTE_P|PTE_W/*|PTE_PCD*/),%eax 3138368e25fSAaron LI fillkpt_nox 3148368e25fSAaron LI 3158368e25fSAaron LI /* Map the ISA I/O MEM RW. */ 3168368e25fSAaron LI movl $IOM_BEGIN,%eax 3178368e25fSAaron LI movl $IOM_SIZE,%ecx /* size of ISA I/O MEM */ 3188368e25fSAaron LI shrl $PGSHIFT,%ecx 3198368e25fSAaron LI orl $(PTE_P|PTE_W/*|PTE_PCD*/),%eax 3208368e25fSAaron LI fillkpt_nox 3218368e25fSAaron LI 3228368e25fSAaron LI /* 3238368e25fSAaron LI * Build L2. Linked to L1. 3248368e25fSAaron LI */ 3258368e25fSAaron LI leal (PROC0_PTP2_OFF)(%esi),%ebx 3268368e25fSAaron LI leal (PROC0_PTP1_OFF)(%esi),%eax 3278368e25fSAaron LI orl $(PTE_P|PTE_W),%eax 3288368e25fSAaron LI movl $(NKL2_KIMG_ENTRIES+1),%ecx 3298368e25fSAaron LI fillkpt 3308368e25fSAaron LI 3318368e25fSAaron LI /* 3328368e25fSAaron LI * Build L3. Linked to L2. 3338368e25fSAaron LI */ 3348368e25fSAaron LI leal (PROC0_PTP3_OFF)(%esi),%ebx 3358368e25fSAaron LI leal (PROC0_PTP2_OFF)(%esi),%eax 3368368e25fSAaron LI orl $(PTE_P|PTE_W),%eax 3378368e25fSAaron LI movl $NKL3_KIMG_ENTRIES,%ecx 3388368e25fSAaron LI fillkpt 3398368e25fSAaron LI 3408368e25fSAaron LI /* 3418368e25fSAaron LI * Build L4. Linked to L3. 3428368e25fSAaron LI */ 3438368e25fSAaron LI leal (PROC0_PML4_OFF)(%esi),%ebx 3448368e25fSAaron LI leal (PROC0_PTP3_OFF)(%esi),%eax 3458368e25fSAaron LI orl $(PTE_P|PTE_W),%eax 3468368e25fSAaron LI movl $NKL4_KIMG_ENTRIES,%ecx 3478368e25fSAaron LI fillkpt 3488368e25fSAaron LI 3498368e25fSAaron LI /* Install recursive top level PDE (one entry) */ 3508368e25fSAaron LI leal (PROC0_PML4_OFF + PDIR_SLOT_PTE * PDE_SIZE)(%esi),%ebx 3518368e25fSAaron LI leal (PROC0_PML4_OFF)(%esi),%eax 3528368e25fSAaron LI orl $(PTE_P|PTE_W),%eax 3538368e25fSAaron LI movl $1,%ecx 3548368e25fSAaron LI fillkpt_nox 3558368e25fSAaron LI 3568368e25fSAaron LI /* 3578368e25fSAaron LI * Startup checklist: 3588368e25fSAaron LI * 1. Enable PAE (and SSE while here). 3598368e25fSAaron LI */ 3608368e25fSAaron LI movl %cr4,%eax 3618368e25fSAaron LI orl $(CR4_PAE|CR4_OSFXSR|CR4_OSXMMEXCPT),%eax 3628368e25fSAaron LI movl %eax,%cr4 3638368e25fSAaron LI 3648368e25fSAaron LI /* 3658368e25fSAaron LI * 2. Set Long Mode Enable in EFER. Also enable the syscall extensions, 3668368e25fSAaron LI * and NOX if available. 3678368e25fSAaron LI */ 3688368e25fSAaron LI movl $MSR_EFER,%ecx 3698368e25fSAaron LI rdmsr 3708368e25fSAaron LI xorl %eax,%eax 3718368e25fSAaron LI orl $(EFER_LME|EFER_SCE),%eax 3728368e25fSAaron LI movl _C_LABEL(nox_flag),%ebx 3738368e25fSAaron LI cmpl $0,%ebx 3748368e25fSAaron LI je .Lskip_NOX 3758368e25fSAaron LI orl $(EFER_NXE),%eax 3768368e25fSAaron LI.Lskip_NOX: 3778368e25fSAaron LI wrmsr 3788368e25fSAaron LI 3798368e25fSAaron LI /* 3808368e25fSAaron LI * 3. Load %cr3 with pointer to PML4. 3818368e25fSAaron LI */ 3828368e25fSAaron LI movl %esi,%eax 3838368e25fSAaron LI movl %eax,%cr3 3848368e25fSAaron LI 3858368e25fSAaron LI /* 3868368e25fSAaron LI * 4. Enable paging and the rest of it. 3878368e25fSAaron LI */ 3888368e25fSAaron LI movl %cr0,%eax 3898368e25fSAaron LI orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_MP|CR0_WP|CR0_AM),%eax 3908368e25fSAaron LI movl %eax,%cr0 3918368e25fSAaron LI jmp compat 3928368e25fSAaron LIcompat: 3938368e25fSAaron LI 3948368e25fSAaron LI /* 3958368e25fSAaron LI * 5. Not quite done yet, we're now in a compatibility segment, in 3968368e25fSAaron LI * legacy mode. We must jump to a long mode segment. Need to set up 3978368e25fSAaron LI * a GDT with a long mode segment in it to do that. 3988368e25fSAaron LI */ 3998368e25fSAaron LI movl $_C_LABEL(gdt64_lo),%eax 4008368e25fSAaron LI lgdt (%eax) 4018368e25fSAaron LI movl $_C_LABEL(farjmp64),%eax 4028368e25fSAaron LI ljmp *(%eax) 4038368e25fSAaron LI 4048368e25fSAaron LI .code64 4058368e25fSAaron LIlongmode: 4068368e25fSAaron LI 4078368e25fSAaron LI /* 4088368e25fSAaron LI * We have arrived. Everything is identity-mapped. 4098368e25fSAaron LI */ 4108368e25fSAaron LI 4118368e25fSAaron LI /* Store lapicbase. */ 4128368e25fSAaron LI movq $TABLESIZE,%rdx 4138368e25fSAaron LI addq %rsi,%rdx 4148368e25fSAaron LI movq %rdx,_C_LABEL(lapicbase)(%rip) 4158368e25fSAaron LI 4168368e25fSAaron LI /* Store atdevbase. */ 4178368e25fSAaron LI addq $PAGE_SIZE,%rdx 4188368e25fSAaron LI movq %rdx,_C_LABEL(atdevbase)(%rip) 4198368e25fSAaron LI 4208368e25fSAaron LI /* Set up bootstrap stack. */ 4218368e25fSAaron LI leaq (PROC0_STK_OFF)(%rsi),%rax 4228368e25fSAaron LI movq %rax,_C_LABEL(stkpa)(%rip) 4238368e25fSAaron LI leaq (USPACE-FRAMESIZE)(%rax),%rsp 4248368e25fSAaron LI xorq %rbp,%rbp /* mark end of frames */ 4258368e25fSAaron LI 4268368e25fSAaron LI xorw %ax,%ax 4278368e25fSAaron LI movw %ax,%gs 4288368e25fSAaron LI movw %ax,%fs 4298368e25fSAaron LI 4308368e25fSAaron LI /* The first physical page available. */ 4318368e25fSAaron LI leaq (TABLESIZE)(%rsi),%rdi 4328368e25fSAaron LI 4338368e25fSAaron LI /* 4348368e25fSAaron LI * Continue execution in C. 4358368e25fSAaron LI */ 4368368e25fSAaron LI call _C_LABEL(main) 4378368e25fSAaron LI 4388368e25fSAaron LI ret 4398368e25fSAaron LIEND(start) 4408368e25fSAaron LI 4418368e25fSAaron LI/* -------------------------------------------------------------------------- */ 4428368e25fSAaron LI 4438368e25fSAaron LIENTRY(lidt) 4448368e25fSAaron LI lidt (%rdi) 4458368e25fSAaron LI ret 4468368e25fSAaron LIEND(lidt) 4478368e25fSAaron LI 4488368e25fSAaron LIENTRY(vmmcall) 4498368e25fSAaron LI vmmcall 4508368e25fSAaron LIEND(vmmcall) 4518368e25fSAaron LI 4528368e25fSAaron LIENTRY(outsb) 4538368e25fSAaron LI movl %edx,%ecx 4548368e25fSAaron LI movl %edi,%edx 4558368e25fSAaron LI rep 4568368e25fSAaron LI outsb 4578368e25fSAaron LI ret 4588368e25fSAaron LIEND(outsb) 4598368e25fSAaron LI 4608368e25fSAaron LIENTRY(clts) 4618368e25fSAaron LI clts 4628368e25fSAaron LI ret 4638368e25fSAaron LIEND(clts) 4648368e25fSAaron LI 4658368e25fSAaron LIENTRY(sti) 4668368e25fSAaron LI sti 4678368e25fSAaron LI ret 4688368e25fSAaron LIEND(sti) 4698368e25fSAaron LI 4708368e25fSAaron LIENTRY(lcr8) 4718368e25fSAaron LI movq %rdi, %cr8 4728368e25fSAaron LI ret 4738368e25fSAaron LIEND(lcr8) 4748368e25fSAaron LI 4758368e25fSAaron LIENTRY(rdmsr) 4768368e25fSAaron LI movq %rdi, %rcx 4778368e25fSAaron LI xorq %rax, %rax 4788368e25fSAaron LI rdmsr 4798368e25fSAaron LI shlq $32, %rdx 4808368e25fSAaron LI orq %rdx, %rax 4818368e25fSAaron LI ret 4828368e25fSAaron LIEND(rdmsr) 4838368e25fSAaron LI 4848368e25fSAaron LIENTRY(cpuid) 4858368e25fSAaron LI movq %rbx,%r8 4868368e25fSAaron LI movq %rdi,%rax 4878368e25fSAaron LI movq %rsi,%rcx 4888368e25fSAaron LI movq %rdx,%rsi 4898368e25fSAaron LI cpuid 4908368e25fSAaron LI movl %eax,0(%rsi) 4918368e25fSAaron LI movl %ebx,4(%rsi) 4928368e25fSAaron LI movl %ecx,8(%rsi) 4938368e25fSAaron LI movl %edx,12(%rsi) 4948368e25fSAaron LI movq %r8,%rbx 4958368e25fSAaron LI ret 4968368e25fSAaron LIEND(cpuid) 497