locore.s revision 1998
14Srgrimes/*- 24Srgrimes * Copyright (c) 1990 The Regents of the University of California. 34Srgrimes * All rights reserved. 44Srgrimes * 54Srgrimes * This code is derived from software contributed to Berkeley by 64Srgrimes * William Jolitz. 74Srgrimes * 84Srgrimes * Redistribution and use in source and binary forms, with or without 94Srgrimes * modification, are permitted provided that the following conditions 104Srgrimes * are met: 114Srgrimes * 1. Redistributions of source code must retain the above copyright 124Srgrimes * notice, this list of conditions and the following disclaimer. 134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 144Srgrimes * notice, this list of conditions and the following disclaimer in the 154Srgrimes * documentation and/or other materials provided with the distribution. 164Srgrimes * 3. All advertising materials mentioning features or use of this software 174Srgrimes * must display the following acknowledgement: 184Srgrimes * This product includes software developed by the University of 194Srgrimes * California, Berkeley and its contributors. 204Srgrimes * 4. Neither the name of the University nor the names of its contributors 214Srgrimes * may be used to endorse or promote products derived from this software 224Srgrimes * without specific prior written permission. 234Srgrimes * 244Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 254Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 264Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 274Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 284Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 294Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 304Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 314Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 324Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 334Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 344Srgrimes * SUCH DAMAGE. 354Srgrimes * 36556Srgrimes * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 371998Swollman * $Id: locore.s,v 1.18 1994/06/06 14:12:48 davidg Exp $ 384Srgrimes */ 394Srgrimes 404Srgrimes/* 41757Sdg * locore.s: FreeBSD machine support for the Intel 386 42757Sdg * originally from: locore.s, by William F. Jolitz 43757Sdg * 44757Sdg * Substantially rewritten by David Greenman, Rod Grimes, 45757Sdg * Bruce Evans, Wolfgang Solfrank, and many others. 464Srgrimes */ 474Srgrimes 48757Sdg#include "npx.h" /* for NNPX */ 49757Sdg#include "assym.s" /* system definitions */ 50757Sdg#include "machine/psl.h" /* processor status longword defs */ 51757Sdg#include "machine/pte.h" /* page table entry definitions */ 52757Sdg#include "errno.h" /* error return codes */ 53757Sdg#include "machine/specialreg.h" /* x86 special registers */ 54757Sdg#include "machine/cputypes.h" /* x86 cpu type definitions */ 55757Sdg#include "syscall.h" /* system call numbers */ 56757Sdg#include "machine/asmacros.h" /* miscellaneous asm macros */ 574Srgrimes 584Srgrimes/* 59757Sdg * XXX 60757Sdg * 614Srgrimes * Note: This version greatly munged to avoid various assembler errors 624Srgrimes * that may be fixed in newer versions of gas. Perhaps newer versions 634Srgrimes * will have more pleasant appearance. 644Srgrimes */ 654Srgrimes 66200Sdg/* 674Srgrimes * PTmap is recursive pagemap at top of virtual address space. 684Srgrimes * Within PTmap, the page directory can be found (third indirection). 694Srgrimes */ 70592Srgrimes .globl _PTmap,_PTD,_PTDpde,_Sysmap 71592Srgrimes .set _PTmap,PTDPTDI << PDRSHIFT 72592Srgrimes .set _PTD,_PTmap + (PTDPTDI * NBPG) 73757Sdg .set _PTDpde,_PTD + (PTDPTDI * PDESIZE) 74592Srgrimes 75757Sdg/* Sysmap is the base address of the kernel page tables */ 76608Srgrimes .set _Sysmap,_PTmap + (KPTDI * NBPG) 774Srgrimes 784Srgrimes/* 794Srgrimes * APTmap, APTD is the alternate recursive pagemap. 804Srgrimes * It's used when modifying another process's page tables. 814Srgrimes */ 82592Srgrimes .globl _APTmap,_APTD,_APTDpde 83592Srgrimes .set _APTmap,APTDPTDI << PDRSHIFT 84592Srgrimes .set _APTD,_APTmap + (APTDPTDI * NBPG) 85757Sdg .set _APTDpde,_PTD + (APTDPTDI * PDESIZE) 864Srgrimes 874Srgrimes/* 884Srgrimes * Access to each processes kernel stack is via a region of 894Srgrimes * per-process address space (at the beginning), immediatly above 904Srgrimes * the user process stack. 914Srgrimes */ 92570Srgrimes .set _kstack,USRSTACK 93134Sdg .globl _kstack 944Srgrimes 95556Srgrimes/* 96556Srgrimes * Globals 97556Srgrimes */ 98556Srgrimes .data 99556Srgrimes .globl _esym 100757Sdg_esym: .long 0 /* ptr to end of syms */ 101134Sdg 102592Srgrimes .globl _boothowto,_bootdev,_curpcb 103134Sdg 1041998Swollman .globl _cpu,_cold,_atdevbase,_cpu_vendor,_cpu_id 105757Sdg_cpu: .long 0 /* are we 386, 386sx, or 486 */ 1061998Swollman_cpu_id: .long 0 /* stepping ID */ 1071998Swollman_cpu_vendor: .space 17 /* CPU origin code */ 108757Sdg_cold: .long 1 /* cold till we are not */ 109757Sdg_atdevbase: .long 0 /* location of start of iomem in virtual */ 110757Sdg_atdevphys: .long 0 /* location of device mapping ptes (phys) */ 1114Srgrimes 112757Sdg .globl _KERNend 113757Sdg_KERNend: .long 0 /* phys addr end of kernel (just after bss) */ 114757Sdg 115592Srgrimes .globl _IdlePTD,_KPTphys 116757Sdg_IdlePTD: .long 0 /* phys addr of kernel PTD */ 117757Sdg_KPTphys: .long 0 /* phys addr of kernel page tables */ 1184Srgrimes 119757Sdg .globl _cyloffset 120757Sdg_cyloffset: .long 0 /* cylinder offset from boot blocks */ 121718Swollman 122757Sdg .globl _proc0paddr 123757Sdg_proc0paddr: .long 0 /* address of proc 0 address space */ 124134Sdg 125757Sdg#ifdef BDE_DEBUGGER 126757Sdg .globl _bdb_exists /* flag to indicate BDE debugger is available */ 1271321Sdg_bdb_exists: .long 0 128757Sdg#endif 129718Swollman 130757Sdg .globl tmpstk 131974Sdg .space 0x1000 1324Srgrimestmpstk: 133134Sdg 134134Sdg 135556Srgrimes/* 136556Srgrimes * System Initialization 137556Srgrimes */ 1384Srgrimes .text 139134Sdg 140134Sdg/* 141200Sdg * btext: beginning of text section. 142200Sdg * Also the entry point (jumped to directly from the boot blocks). 143134Sdg */ 1441321SdgNON_GPROF_ENTRY(btext) 145757Sdg movw $0x1234,0x472 /* warm boot */ 1464Srgrimes jmp 1f 1471321Sdg .org 0x500 /* space for BIOS variables */ 1484Srgrimes 1494Srgrimes /* 150556Srgrimes * pass parameters on stack (howto, bootdev, unit, cyloffset, esym) 1514Srgrimes * note: (%esp) is return address of boot 1524Srgrimes * ( if we want to hold onto /boot, it's physical %esp up to _end) 1534Srgrimes */ 1544Srgrimes 1554Srgrimes 1: movl 4(%esp),%eax 156570Srgrimes movl %eax,_boothowto-KERNBASE 1574Srgrimes movl 8(%esp),%eax 158570Srgrimes movl %eax,_bootdev-KERNBASE 1594Srgrimes movl 12(%esp),%eax 160570Srgrimes movl %eax,_cyloffset-KERNBASE 161556Srgrimes movl 16(%esp),%eax 162570Srgrimes addl $KERNBASE,%eax 163570Srgrimes movl %eax,_esym-KERNBASE 164975Smartin#ifdef DISKLESS /* Copy diskless structure */ 165975Smartin movl _nfs_diskless_size-KERNBASE,%ecx 166975Smartin movl 20(%esp),%esi 167975Smartin movl $(_nfs_diskless-KERNBASE),%edi 1681688Sdg cld 169975Smartin rep 170975Smartin movsb 171975Smartin#endif 1724Srgrimes 1731998Swollman /* Find out our CPU type. */ 1741321Sdg 1751998Swollman /* Try to toggle alignment check flag; does not exist on 386. */ 1761998Swollman pushfl 1771998Swollman popl %eax 1781998Swollman movl %eax,%ecx 1791998Swollman orl $PSL_AC,%eax 1801998Swollman pushl %eax 1811998Swollman popfl 1821998Swollman pushfl 1831998Swollman popl %eax 1841998Swollman xorl %ecx,%eax 1851998Swollman andl $PSL_AC,%eax 1861998Swollman pushl %ecx 1871998Swollman popfl 1881998Swollman 1891998Swollman testl %eax,%eax 1901998Swollman jnz 1f 1911998Swollman movl $CPU_386,_cpu-KERNBASE 192556Srgrimes jmp 2f 1931998Swollman 1941998Swollman1: /* Try to toggle identification flag; does not exist on early 486s. */ 1951998Swollman pushfl 1961998Swollman popl %eax 1971998Swollman movl %eax,%ecx 1981998Swollman xorl $PSL_ID,%eax 1991998Swollman pushl %eax 2001998Swollman popfl 2011998Swollman pushfl 2021998Swollman popl %eax 2031998Swollman xorl %ecx,%eax 2041998Swollman andl $PSL_ID,%eax 2051998Swollman pushl %ecx 2061998Swollman popfl 2071998Swollman 2081998Swollman testl %eax,%eax 2091998Swollman jnz 1f 2101998Swollman movl $CPU_486,_cpu-KERNBASE 2111998Swollman jmp 2f 2121998Swollman 2131998Swollman1: /* Use the `cpuid' instruction. */ 2141998Swollman xorl %eax,%eax 2151998Swollman .byte 0x0f,0xa2 # cpuid 0 2161998Swollman movl %ebx,_cpu_vendor-KERNBASE # store vendor string 2171998Swollman movl %edx,_cpu_vendor+4-KERNBASE 2181998Swollman movl %ecx,_cpu_vendor+8-KERNBASE 2191998Swollman movb $0,_cpu_vendor+12-KERNBASE 2201998Swollman 2211998Swollman movl $1,%eax 2221998Swollman .byte 0x0f,0xa2 # cpuid 1 2231998Swollman movl %eax,_cpu_id-KERNBASE # store cpu_id 2241998Swollman rorl $8,%eax # extract family type 2251998Swollman andl $15,%eax 2261998Swollman cmpl $5,%eax 2271998Swollman jae 1f 2281998Swollman 2291998Swollman /* less than Pentium; must be 486 */ 2301998Swollman movl $CPU_486,_cpu-KERNBASE 2311998Swollman jmp 2f 2321998Swollman 2331998Swollman1: movl $CPU_586,_cpu-KERNBASE 234556Srgrimes2: 235556Srgrimes 2364Srgrimes /* 2374Srgrimes * Finished with old stack; load new %esp now instead of later so 2384Srgrimes * we can trace this code without having to worry about the trace 2394Srgrimes * trap clobbering the memory test or the zeroing of the bss+bootstrap 2404Srgrimes * page tables. 2414Srgrimes * 2424Srgrimes * XXX - wdboot clears the bss after testing that this is safe. 2434Srgrimes * This is too wasteful - memory below 640K is scarce. The boot 2444Srgrimes * program should check: 2454Srgrimes * text+data <= &stack_variable - more_space_for_stack 2464Srgrimes * text+data+bss+pad+space_for_page_tables <= end_of_memory 2474Srgrimes * Oops, the gdt is in the carcass of the boot program so clearing 2484Srgrimes * the rest of memory is still not possible. 2494Srgrimes */ 250757Sdg movl $tmpstk-KERNBASE,%esp /* bootstrap stack end location */ 2514Srgrimes 252570Srgrimes/* 253570Srgrimes * Virtual address space of kernel: 254570Srgrimes * 255570Srgrimes * text | data | bss | [syms] | page dir | proc0 kernel stack | usr stk map | Sysmap 256974Sdg * pages: 1 UPAGES (2) 1 NKPT (7) 257570Srgrimes */ 258570Srgrimes 2594Srgrimes/* find end of kernel image */ 260570Srgrimes movl $_end-KERNBASE,%ecx 261757Sdg addl $NBPG-1,%ecx /* page align up */ 2624Srgrimes andl $~(NBPG-1),%ecx 2631321Sdg movl %ecx,%esi /* esi = start of free memory */ 264757Sdg movl %ecx,_KERNend-KERNBASE /* save end of kernel */ 2654Srgrimes 266757Sdg/* clear bss */ 267570Srgrimes movl $_edata-KERNBASE,%edi 268760Srgrimes subl %edi,%ecx /* get amount to clear */ 269757Sdg xorl %eax,%eax /* specify zero fill */ 2704Srgrimes cld 2714Srgrimes rep 2724Srgrimes stosb 2734Srgrimes 274608Srgrimes/* 275974Sdg * The value in esi is both the end of the kernel bss and a pointer to 276974Sdg * the kernel page directory, and is used by the rest of locore to build 277974Sdg * the tables. 278974Sdg * esi + 1(page dir) + 2(UPAGES) + 1(p0stack) + NKPT(number of kernel 279757Sdg * page table pages) is then passed on the stack to init386(first) as 280757Sdg * the value first. esi should ALWAYS be page aligned!! 281608Srgrimes */ 282757Sdg movl %esi,%ecx /* Get current first availiable address */ 283608Srgrimes 284757Sdg/* clear pagetables, page directory, stack, etc... */ 285757Sdg movl %esi,%edi /* base (page directory) */ 286974Sdg movl $((1+UPAGES+1+NKPT)*NBPG),%ecx /* amount to clear */ 287757Sdg xorl %eax,%eax /* specify zero fill */ 288757Sdg cld 289757Sdg rep 290757Sdg stosb 291757Sdg 292757Sdg/* physical address of Idle proc/kernel page directory */ 293570Srgrimes movl %esi,_IdlePTD-KERNBASE 2944Srgrimes 295592Srgrimes/* 296592Srgrimes * fillkpt 297592Srgrimes * eax = (page frame address | control | status) == pte 298592Srgrimes * ebx = address of page table 299592Srgrimes * ecx = how many pages to map 300592Srgrimes */ 3014Srgrimes#define fillkpt \ 3024Srgrimes1: movl %eax,(%ebx) ; \ 303570Srgrimes addl $NBPG,%eax ; /* increment physical address */ \ 3044Srgrimes addl $4,%ebx ; /* next pte */ \ 3054Srgrimes loop 1b ; 3064Srgrimes 3074Srgrimes/* 3084Srgrimes * Map Kernel 3094Srgrimes * 3104Srgrimes * First step - build page tables 3114Srgrimes */ 312757Sdg#if defined (KGDB) || defined (BDE_DEBUGGER) 313757Sdg movl _KERNend-KERNBASE,%ecx /* this much memory, */ 314757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 315757Sdg#ifdef BDE_DEBUGGER 316757Sdg cmpl $0xa0,%ecx /* XXX - cover debugger pages */ 317200Sdg jae 1f 318200Sdg movl $0xa0,%ecx 319200Sdg1: 320757Sdg#endif /* BDE_DEBUGGER */ 3211549Srgrimes movl $PG_V|PG_KW|PG_NC_PWT,%eax /* kernel R/W, valid, cache write-through */ 322757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 323757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 3244Srgrimes fillkpt 3254Srgrimes 326757Sdg#else /* !KGDB && !BDE_DEBUGGER */ 327757Sdg /* write protect kernel text (doesn't do a thing for 386's - only 486's) */ 328757Sdg movl $_etext-KERNBASE,%ecx /* get size of text */ 329757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 330757Sdg movl $PG_V|PG_KR,%eax /* specify read only */ 331757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 332757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 333757Sdg fillkpt 334757Sdg 335757Sdg /* data and bss are r/w */ 336757Sdg andl $PG_FRAME,%eax /* strip to just addr of bss */ 337757Sdg movl _KERNend-KERNBASE,%ecx /* calculate size */ 338757Sdg subl %eax,%ecx 339757Sdg shrl $PGSHIFT,%ecx 340757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 341757Sdg fillkpt 3421321Sdg#endif /* KGDB || BDE_DEBUGGER */ 343757Sdg 344757Sdg/* now initialize the page dir, upages, p0stack PT, and page tables */ 345757Sdg 346974Sdg movl $(1+UPAGES+1+NKPT),%ecx /* number of PTEs */ 347757Sdg movl %esi,%eax /* phys address of PTD */ 348757Sdg andl $PG_FRAME,%eax /* convert to PFN, should be a NOP */ 3491549Srgrimes orl $PG_V|PG_KW|PG_NC_PWT,%eax /* valid, kernel read/write, cache write-though */ 350757Sdg movl %esi,%ebx /* calculate pte offset to ptd */ 351757Sdg shrl $PGSHIFT-2,%ebx 352757Sdg addl %esi,%ebx /* address of page directory */ 353757Sdg addl $((1+UPAGES+1)*NBPG),%ebx /* offset to kernel page tables */ 354757Sdg fillkpt 3551321Sdg 3564Srgrimes/* map I/O memory map */ 3574Srgrimes 358757Sdg movl _KPTphys-KERNBASE,%ebx /* base of kernel page tables */ 359757Sdg lea (0xa0 * PTESIZE)(%ebx),%ebx /* hardwire ISA hole at KERNBASE + 0xa0000 */ 360757Sdg movl $0x100-0xa0,%ecx /* for this many pte s, */ 3611046Sdg movl $(0xa0000|PG_V|PG_KW|PG_N),%eax /* valid, kernel read/write, non-cacheable */ 362757Sdg movl %ebx,_atdevphys-KERNBASE /* save phys addr of ptes */ 3634Srgrimes fillkpt 3644Srgrimes 3654Srgrimes /* map proc 0's kernel stack into user page table page */ 3664Srgrimes 367757Sdg movl $UPAGES,%ecx /* for this many pte s, */ 368757Sdg lea (1*NBPG)(%esi),%eax /* physical address in proc 0 */ 369757Sdg lea (KERNBASE)(%eax),%edx /* change into virtual addr */ 370757Sdg movl %edx,_proc0paddr-KERNBASE /* save VA for proc 0 init */ 371757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 372757Sdg lea ((1+UPAGES)*NBPG)(%esi),%ebx /* addr of stack page table in proc 0 */ 373757Sdg addl $(KSTKPTEOFF * PTESIZE),%ebx /* offset to kernel stack PTE */ 3744Srgrimes fillkpt 3754Srgrimes 3764Srgrimes/* 377757Sdg * Initialize kernel page table directory 3784Srgrimes */ 3794Srgrimes /* install a pde for temporary double map of bottom of VA */ 380757Sdg movl _KPTphys-KERNBASE,%eax 381757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 382757Sdg movl %eax,(%esi) /* which is where temp maps! */ 3834Srgrimes 384757Sdg /* initialize kernel pde's */ 385974Sdg movl $(NKPT),%ecx /* for this many PDEs */ 386757Sdg lea (KPTDI*PDESIZE)(%esi),%ebx /* offset of pde for kernel */ 3874Srgrimes fillkpt 3884Srgrimes 3894Srgrimes /* install a pde recursively mapping page directory as a page table! */ 390757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 391757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 392757Sdg movl %eax,PTDPTDI*PDESIZE(%esi) /* which is where PTmap maps! */ 3934Srgrimes 3944Srgrimes /* install a pde to map kernel stack for proc 0 */ 395757Sdg lea ((1+UPAGES)*NBPG)(%esi),%eax /* physical address of pt in proc 0 */ 396757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 397757Sdg movl %eax,KSTKPTDI*PDESIZE(%esi) /* which is where kernel stack maps! */ 3984Srgrimes 399757Sdg#ifdef BDE_DEBUGGER 4004Srgrimes /* copy and convert stuff from old gdt and idt for debugger */ 4014Srgrimes 402757Sdg cmpl $0x0375c339,0x96104 /* XXX - debugger signature */ 4034Srgrimes jne 1f 404570Srgrimes movb $1,_bdb_exists-KERNBASE 4054Srgrimes1: 4064Srgrimes pushal 4074Srgrimes subl $2*6,%esp 4084Srgrimes 4094Srgrimes sgdt (%esp) 410757Sdg movl 2(%esp),%esi /* base address of current gdt */ 411570Srgrimes movl $_gdt-KERNBASE,%edi 4124Srgrimes movl %edi,2(%esp) 4134Srgrimes movl $8*18/4,%ecx 4141688Sdg cld 415757Sdg rep /* copy gdt */ 4164Srgrimes movsl 417570Srgrimes movl $_gdt-KERNBASE,-8+2(%edi) /* adjust gdt self-ptr */ 4184Srgrimes movb $0x92,-8+5(%edi) 4194Srgrimes 4204Srgrimes sidt 6(%esp) 421757Sdg movl 6+2(%esp),%esi /* base address of current idt */ 422757Sdg movl 8+4(%esi),%eax /* convert dbg descriptor to ... */ 4234Srgrimes movw 8(%esi),%ax 424570Srgrimes movl %eax,bdb_dbg_ljmp+1-KERNBASE /* ... immediate offset ... */ 4254Srgrimes movl 8+2(%esi),%eax 426570Srgrimes movw %ax,bdb_dbg_ljmp+5-KERNBASE /* ... and selector for ljmp */ 427757Sdg movl 24+4(%esi),%eax /* same for bpt descriptor */ 4284Srgrimes movw 24(%esi),%ax 429570Srgrimes movl %eax,bdb_bpt_ljmp+1-KERNBASE 4304Srgrimes movl 24+2(%esi),%eax 431570Srgrimes movw %ax,bdb_bpt_ljmp+5-KERNBASE 4324Srgrimes 433570Srgrimes movl $_idt-KERNBASE,%edi 4344Srgrimes movl %edi,6+2(%esp) 4354Srgrimes movl $8*4/4,%ecx 4361688Sdg cld 437757Sdg rep /* copy idt */ 4384Srgrimes movsl 4394Srgrimes 4404Srgrimes lgdt (%esp) 4414Srgrimes lidt 6(%esp) 4424Srgrimes 4434Srgrimes addl $2*6,%esp 4444Srgrimes popal 4451321Sdg#endif /* BDE_DEBUGGER */ 4464Srgrimes 447592Srgrimes /* load base of page directory and enable mapping */ 448757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 449570Srgrimes orl $I386_CR3PAT,%eax 450757Sdg movl %eax,%cr3 /* load ptd addr into mmu */ 451757Sdg movl %cr0,%eax /* get control word */ 452757Sdg orl $CR0_PE|CR0_PG,%eax /* enable paging */ 453757Sdg movl %eax,%cr0 /* and let's page NOW! */ 4544Srgrimes 455757Sdg pushl $begin /* jump to high mem */ 4564Srgrimes ret 4574Srgrimes 458570Srgrimesbegin: /* now running relocated at KERNBASE where the system is linked to run */ 4594Srgrimes 460757Sdg .globl _Crtat /* XXX - locore should not know about */ 461757Sdg movl _Crtat,%eax /* variables of device drivers (pccons)! */ 462592Srgrimes subl $(KERNBASE+0xA0000),%eax 463757Sdg movl _atdevphys,%edx /* get pte PA */ 464757Sdg subl _KPTphys,%edx /* remove base of ptes, now have phys offset */ 465757Sdg shll $PGSHIFT-2,%edx /* corresponding to virt offset */ 466757Sdg addl $KERNBASE,%edx /* add virtual base */ 467570Srgrimes movl %edx,_atdevbase 4684Srgrimes addl %eax,%edx 4694Srgrimes movl %edx,_Crtat 4704Srgrimes 471757Sdg /* set up bootstrap stack - 48 bytes */ 472570Srgrimes movl $_kstack+UPAGES*NBPG-4*12,%esp /* bootstrap stack end location */ 473757Sdg xorl %eax,%eax /* mark end of frames */ 4744Srgrimes movl %eax,%ebp 475570Srgrimes movl _proc0paddr,%eax 476570Srgrimes movl %esi,PCB_CR3(%eax) 4774Srgrimes 478757Sdg#ifdef BDE_DEBUGGER 4794Srgrimes /* relocate debugger gdt entries */ 4804Srgrimes 481757Sdg movl $_gdt+8*9,%eax /* adjust slots 9-17 */ 4824Srgrimes movl $9,%ecx 4834Srgrimesreloc_gdt: 4841321Sdg movb $KERNBASE>>24,7(%eax) /* top byte of base addresses, was 0, */ 485757Sdg addl $8,%eax /* now KERNBASE>>24 */ 4864Srgrimes loop reloc_gdt 4874Srgrimes 4884Srgrimes cmpl $0,_bdb_exists 4894Srgrimes je 1f 4904Srgrimes int $3 4914Srgrimes1: 4921321Sdg#endif /* BDE_DEBUGGER */ 4934Srgrimes 494608Srgrimes /* 495608Srgrimes * Skip over the page tables and the kernel stack 496608Srgrimes */ 497974Sdg lea ((1+UPAGES+1+NKPT)*NBPG)(%esi),%esi 498608Srgrimes 499757Sdg pushl %esi /* value of first for init386(first) */ 500757Sdg call _init386 /* wire 386 chip for unix operation */ 5011549Srgrimes popl %esi 502200Sdg 5031549Srgrimes#if 0 5044Srgrimes movl $0,_PTD 5051549Srgrimes#endif 5061549Srgrimes 5071549Srgrimes .globl __ucodesel,__udatasel 5081549Srgrimes 5091549Srgrimes pushl $0 /* unused */ 5101549Srgrimes pushl __udatasel /* ss */ 5111549Srgrimes pushl $0 /* esp - filled in by execve() */ 5121549Srgrimes pushl $0x3200 /* eflags (ring 3, int enab) */ 5131549Srgrimes pushl __ucodesel /* cs */ 5141549Srgrimes pushl $0 /* eip - filled in by execve() */ 5151549Srgrimes subl $(12*4),%esp /* space for rest of registers */ 5161549Srgrimes 5171549Srgrimes pushl %esp /* call main with frame pointer */ 518757Sdg call _main /* autoconfiguration, mountroot etc */ 5194Srgrimes 5201549Srgrimes addl $(13*4),%esp /* back to a frame we can return with */ 5211549Srgrimes 522134Sdg /* 523570Srgrimes * now we've run main() and determined what cpu-type we are, we can 524570Srgrimes * enable WP mode on i486 cpus and above. 5251058Sdg */ 5261058Sdg#if defined(I486_CPU) || defined(I586_CPU) 5271058Sdg cmpl $CPUCLASS_386,_cpu_class 5281058Sdg je 1f 5291058Sdg movl %cr0,%eax /* get control word */ 5301058Sdg orl $CR0_WP,%eax /* enable write protect for all modes */ 5311058Sdg movl %eax,%cr0 /* and do it */ 5321058Sdg#endif 5331058Sdg /* 534134Sdg * on return from main(), we are process 1 535134Sdg * set up address space and stack so that we can 'return' to user mode 536134Sdg */ 5371058Sdg1: 5384Srgrimes movl __ucodesel,%eax 5394Srgrimes movl __udatasel,%ecx 5401549Srgrimes 5414Srgrimes movl %cx,%ds 5424Srgrimes movl %cx,%es 543757Sdg movl %ax,%fs /* double map cs to fs */ 544757Sdg movl %cx,%gs /* and ds to gs */ 5451549Srgrimes iret /* goto user! */ 5464Srgrimes 5471549Srgrimes#define LCALL(x,y) .byte 0x9a ; .long y ; .word x 5484Srgrimes 549200SdgNON_GPROF_ENTRY(sigcode) 550592Srgrimes call SIGF_HANDLER(%esp) 551757Sdg lea SIGF_SC(%esp),%eax /* scp (the call may have clobbered the */ 552757Sdg /* copy at 8(%esp)) */ 5534Srgrimes pushl %eax 554757Sdg pushl %eax /* junk to fake return address */ 555757Sdg movl $103,%eax /* XXX sigreturn() */ 556757Sdg LCALL(0x7,0) /* enter kernel with args on stack */ 557757Sdg hlt /* never gets here */ 5584Srgrimes 5594Srgrimes .globl _szsigcode 5604Srgrimes_szsigcode: 5614Srgrimes .long _szsigcode-_sigcode 562