locore.s revision 2500
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 372500Sdg * $Id: locore.s,v 1.24 1994/09/04 19:59:13 pst 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 482056Swollman#include "npx.h" /* for NNPX */ 492056Swollman#include "assym.s" /* system definitions */ 502056Swollman#include <machine/psl.h> /* processor status longword defs */ 512056Swollman#include <machine/pte.h> /* page table entry definitions */ 522056Swollman#include <sys/errno.h> /* error return codes */ 532056Swollman#include <machine/specialreg.h> /* x86 special registers */ 542056Swollman#include <machine/cputypes.h> /* x86 cpu type definitions */ 552056Swollman#include <sys/syscall.h> /* system call numbers */ 562056Swollman#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 */ 1062216Sbde_cpu_id: .long 0 /* stepping ID */ 1072216Sbde_cpu_vendor: .space 20 /* 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 1492486Sdg 1: 1502486Sdg /* don't trust what the BIOS gives for eflags */ 1512486Sdg pushl $PSL_MBO 1522486Sdg popfl 1532486Sdg 1544Srgrimes /* 155556Srgrimes * pass parameters on stack (howto, bootdev, unit, cyloffset, esym) 1564Srgrimes * note: (%esp) is return address of boot 1574Srgrimes * ( if we want to hold onto /boot, it's physical %esp up to _end) 1584Srgrimes */ 1594Srgrimes 1602486Sdg movl 4(%esp),%eax 161570Srgrimes movl %eax,_boothowto-KERNBASE 1624Srgrimes movl 8(%esp),%eax 163570Srgrimes movl %eax,_bootdev-KERNBASE 1644Srgrimes movl 12(%esp),%eax 165570Srgrimes movl %eax,_cyloffset-KERNBASE 166556Srgrimes movl 16(%esp),%eax 167570Srgrimes addl $KERNBASE,%eax 168570Srgrimes movl %eax,_esym-KERNBASE 169975Smartin#ifdef DISKLESS /* Copy diskless structure */ 170975Smartin movl _nfs_diskless_size-KERNBASE,%ecx 171975Smartin movl 20(%esp),%esi 172975Smartin movl $(_nfs_diskless-KERNBASE),%edi 1731688Sdg cld 174975Smartin rep 175975Smartin movsb 176975Smartin#endif 1774Srgrimes 1781998Swollman /* Find out our CPU type. */ 1791321Sdg 1801998Swollman /* Try to toggle alignment check flag; does not exist on 386. */ 1811998Swollman pushfl 1821998Swollman popl %eax 1831998Swollman movl %eax,%ecx 1841998Swollman orl $PSL_AC,%eax 1851998Swollman pushl %eax 1861998Swollman popfl 1871998Swollman pushfl 1881998Swollman popl %eax 1891998Swollman xorl %ecx,%eax 1901998Swollman andl $PSL_AC,%eax 1911998Swollman pushl %ecx 1921998Swollman popfl 1931998Swollman 1941998Swollman testl %eax,%eax 1951998Swollman jnz 1f 1961998Swollman movl $CPU_386,_cpu-KERNBASE 197556Srgrimes jmp 2f 1981998Swollman 1991998Swollman1: /* Try to toggle identification flag; does not exist on early 486s. */ 2001998Swollman pushfl 2011998Swollman popl %eax 2021998Swollman movl %eax,%ecx 2031998Swollman xorl $PSL_ID,%eax 2041998Swollman pushl %eax 2051998Swollman popfl 2061998Swollman pushfl 2071998Swollman popl %eax 2081998Swollman xorl %ecx,%eax 2091998Swollman andl $PSL_ID,%eax 2101998Swollman pushl %ecx 2111998Swollman popfl 2121998Swollman 2131998Swollman testl %eax,%eax 2141998Swollman jnz 1f 2151998Swollman movl $CPU_486,_cpu-KERNBASE 2162495Spst 2172495Spst /* check for Cyrix 486DLC -- based on check routine */ 2182495Spst /* documented in "Cx486SLC/e SMM Programmer's Guide" */ 2192495Spst xorw %dx,%dx 2202495Spst cmpw %dx,%dx # set flags to known state 2212495Spst pushfw 2222495Spst popw %cx # store flags in ecx 2232495Spst movw $0xffff,%ax 2242495Spst movw $0x0004,%bx 2252495Spst divw %bx 2262495Spst pushfw 2272495Spst popw %ax 2282495Spst andw $0x08d5,%ax # mask off important bits 2292495Spst andw $0x08d5,%cx 2302495Spst cmpw %ax,%cx 2312495Spst 2322495Spst jnz 2f # if flags changed, Intel chip 2332495Spst 2342495Spst movl $CPU_486DLC,_cpu-KERNBASE # set CPU value for Cyrix 2352495Spst movl $0x69727943,_cpu_vendor-KERNBASE # store vendor string 2362495Spst movw $0x0078,_cpu_vendor-KERNBASE+4 2372495Spst 2382495Spst invd # Start with guaranteed clean cache 2392495Spst /* Disable caching of the ISA hole only. */ 2402495Spst movb $CCR0,%al # Configuration Register index (CCR0) 2412495Spst outb %al,$0x22 2422495Spst inb $0x23,%al 2432495Spst orb $CCR0_NC1,%al 2442495Spst outb %al,$0x23 2452495Spst invd 2461998Swollman jmp 2f 2471998Swollman 2481998Swollman1: /* Use the `cpuid' instruction. */ 2491998Swollman xorl %eax,%eax 2501998Swollman .byte 0x0f,0xa2 # cpuid 0 2511998Swollman movl %ebx,_cpu_vendor-KERNBASE # store vendor string 2521998Swollman movl %edx,_cpu_vendor+4-KERNBASE 2531998Swollman movl %ecx,_cpu_vendor+8-KERNBASE 2541998Swollman movb $0,_cpu_vendor+12-KERNBASE 2551998Swollman 2561998Swollman movl $1,%eax 2571998Swollman .byte 0x0f,0xa2 # cpuid 1 2581998Swollman movl %eax,_cpu_id-KERNBASE # store cpu_id 2591998Swollman rorl $8,%eax # extract family type 2601998Swollman andl $15,%eax 2611998Swollman cmpl $5,%eax 2621998Swollman jae 1f 2631998Swollman 2641998Swollman /* less than Pentium; must be 486 */ 2651998Swollman movl $CPU_486,_cpu-KERNBASE 2661998Swollman jmp 2f 2671998Swollman 2681998Swollman1: movl $CPU_586,_cpu-KERNBASE 269556Srgrimes2: 270556Srgrimes 2714Srgrimes /* 2724Srgrimes * Finished with old stack; load new %esp now instead of later so 2734Srgrimes * we can trace this code without having to worry about the trace 2744Srgrimes * trap clobbering the memory test or the zeroing of the bss+bootstrap 2754Srgrimes * page tables. 2764Srgrimes * 2774Srgrimes * XXX - wdboot clears the bss after testing that this is safe. 2784Srgrimes * This is too wasteful - memory below 640K is scarce. The boot 2794Srgrimes * program should check: 2804Srgrimes * text+data <= &stack_variable - more_space_for_stack 2814Srgrimes * text+data+bss+pad+space_for_page_tables <= end_of_memory 2824Srgrimes * Oops, the gdt is in the carcass of the boot program so clearing 2834Srgrimes * the rest of memory is still not possible. 2844Srgrimes */ 285757Sdg movl $tmpstk-KERNBASE,%esp /* bootstrap stack end location */ 2864Srgrimes 287570Srgrimes/* 288570Srgrimes * Virtual address space of kernel: 289570Srgrimes * 290570Srgrimes * text | data | bss | [syms] | page dir | proc0 kernel stack | usr stk map | Sysmap 291974Sdg * pages: 1 UPAGES (2) 1 NKPT (7) 292570Srgrimes */ 293570Srgrimes 2944Srgrimes/* find end of kernel image */ 295570Srgrimes movl $_end-KERNBASE,%ecx 296757Sdg addl $NBPG-1,%ecx /* page align up */ 2974Srgrimes andl $~(NBPG-1),%ecx 2981321Sdg movl %ecx,%esi /* esi = start of free memory */ 299757Sdg movl %ecx,_KERNend-KERNBASE /* save end of kernel */ 3004Srgrimes 301757Sdg/* clear bss */ 302570Srgrimes movl $_edata-KERNBASE,%edi 303760Srgrimes subl %edi,%ecx /* get amount to clear */ 304757Sdg xorl %eax,%eax /* specify zero fill */ 3054Srgrimes cld 3064Srgrimes rep 3074Srgrimes stosb 3084Srgrimes 309608Srgrimes/* 310974Sdg * The value in esi is both the end of the kernel bss and a pointer to 311974Sdg * the kernel page directory, and is used by the rest of locore to build 312974Sdg * the tables. 313974Sdg * esi + 1(page dir) + 2(UPAGES) + 1(p0stack) + NKPT(number of kernel 314757Sdg * page table pages) is then passed on the stack to init386(first) as 315757Sdg * the value first. esi should ALWAYS be page aligned!! 316608Srgrimes */ 317757Sdg movl %esi,%ecx /* Get current first availiable address */ 318608Srgrimes 319757Sdg/* clear pagetables, page directory, stack, etc... */ 320757Sdg movl %esi,%edi /* base (page directory) */ 321974Sdg movl $((1+UPAGES+1+NKPT)*NBPG),%ecx /* amount to clear */ 322757Sdg xorl %eax,%eax /* specify zero fill */ 323757Sdg cld 324757Sdg rep 325757Sdg stosb 326757Sdg 327757Sdg/* physical address of Idle proc/kernel page directory */ 328570Srgrimes movl %esi,_IdlePTD-KERNBASE 3294Srgrimes 330592Srgrimes/* 331592Srgrimes * fillkpt 332592Srgrimes * eax = (page frame address | control | status) == pte 333592Srgrimes * ebx = address of page table 334592Srgrimes * ecx = how many pages to map 335592Srgrimes */ 3364Srgrimes#define fillkpt \ 3374Srgrimes1: movl %eax,(%ebx) ; \ 338570Srgrimes addl $NBPG,%eax ; /* increment physical address */ \ 3394Srgrimes addl $4,%ebx ; /* next pte */ \ 3404Srgrimes loop 1b ; 3414Srgrimes 3424Srgrimes/* 3434Srgrimes * Map Kernel 3444Srgrimes * 3454Srgrimes * First step - build page tables 3464Srgrimes */ 347757Sdg#if defined (KGDB) || defined (BDE_DEBUGGER) 348757Sdg movl _KERNend-KERNBASE,%ecx /* this much memory, */ 349757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 350757Sdg#ifdef BDE_DEBUGGER 351757Sdg cmpl $0xa0,%ecx /* XXX - cover debugger pages */ 352200Sdg jae 1f 353200Sdg movl $0xa0,%ecx 354200Sdg1: 355757Sdg#endif /* BDE_DEBUGGER */ 3562452Sdg movl $PG_V|PG_KW,%eax /* kernel R/W, valid, cache write-through */ 357757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 358757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 3594Srgrimes fillkpt 3604Srgrimes 361757Sdg#else /* !KGDB && !BDE_DEBUGGER */ 362757Sdg /* write protect kernel text (doesn't do a thing for 386's - only 486's) */ 363757Sdg movl $_etext-KERNBASE,%ecx /* get size of text */ 364757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 365757Sdg movl $PG_V|PG_KR,%eax /* specify read only */ 366757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 367757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 368757Sdg fillkpt 369757Sdg 370757Sdg /* data and bss are r/w */ 371757Sdg andl $PG_FRAME,%eax /* strip to just addr of bss */ 372757Sdg movl _KERNend-KERNBASE,%ecx /* calculate size */ 373757Sdg subl %eax,%ecx 374757Sdg shrl $PGSHIFT,%ecx 375757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 376757Sdg fillkpt 3771321Sdg#endif /* KGDB || BDE_DEBUGGER */ 378757Sdg 379757Sdg/* now initialize the page dir, upages, p0stack PT, and page tables */ 380757Sdg 381974Sdg movl $(1+UPAGES+1+NKPT),%ecx /* number of PTEs */ 382757Sdg movl %esi,%eax /* phys address of PTD */ 383757Sdg andl $PG_FRAME,%eax /* convert to PFN, should be a NOP */ 3842452Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write, cache write-though */ 385757Sdg movl %esi,%ebx /* calculate pte offset to ptd */ 386757Sdg shrl $PGSHIFT-2,%ebx 387757Sdg addl %esi,%ebx /* address of page directory */ 388757Sdg addl $((1+UPAGES+1)*NBPG),%ebx /* offset to kernel page tables */ 389757Sdg fillkpt 3901321Sdg 3914Srgrimes/* map I/O memory map */ 3924Srgrimes 393757Sdg movl _KPTphys-KERNBASE,%ebx /* base of kernel page tables */ 394757Sdg lea (0xa0 * PTESIZE)(%ebx),%ebx /* hardwire ISA hole at KERNBASE + 0xa0000 */ 395757Sdg movl $0x100-0xa0,%ecx /* for this many pte s, */ 3961046Sdg movl $(0xa0000|PG_V|PG_KW|PG_N),%eax /* valid, kernel read/write, non-cacheable */ 397757Sdg movl %ebx,_atdevphys-KERNBASE /* save phys addr of ptes */ 3984Srgrimes fillkpt 3994Srgrimes 4004Srgrimes /* map proc 0's kernel stack into user page table page */ 4014Srgrimes 402757Sdg movl $UPAGES,%ecx /* for this many pte s, */ 403757Sdg lea (1*NBPG)(%esi),%eax /* physical address in proc 0 */ 404757Sdg lea (KERNBASE)(%eax),%edx /* change into virtual addr */ 405757Sdg movl %edx,_proc0paddr-KERNBASE /* save VA for proc 0 init */ 406757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 407757Sdg lea ((1+UPAGES)*NBPG)(%esi),%ebx /* addr of stack page table in proc 0 */ 408757Sdg addl $(KSTKPTEOFF * PTESIZE),%ebx /* offset to kernel stack PTE */ 4094Srgrimes fillkpt 4104Srgrimes 4114Srgrimes/* 412757Sdg * Initialize kernel page table directory 4134Srgrimes */ 4144Srgrimes /* install a pde for temporary double map of bottom of VA */ 415757Sdg movl _KPTphys-KERNBASE,%eax 416757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 417757Sdg movl %eax,(%esi) /* which is where temp maps! */ 4184Srgrimes 419757Sdg /* initialize kernel pde's */ 420974Sdg movl $(NKPT),%ecx /* for this many PDEs */ 421757Sdg lea (KPTDI*PDESIZE)(%esi),%ebx /* offset of pde for kernel */ 4224Srgrimes fillkpt 4234Srgrimes 4244Srgrimes /* install a pde recursively mapping page directory as a page table! */ 425757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 426757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 427757Sdg movl %eax,PTDPTDI*PDESIZE(%esi) /* which is where PTmap maps! */ 4284Srgrimes 4294Srgrimes /* install a pde to map kernel stack for proc 0 */ 430757Sdg lea ((1+UPAGES)*NBPG)(%esi),%eax /* physical address of pt in proc 0 */ 431757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 432757Sdg movl %eax,KSTKPTDI*PDESIZE(%esi) /* which is where kernel stack maps! */ 4334Srgrimes 434757Sdg#ifdef BDE_DEBUGGER 4354Srgrimes /* copy and convert stuff from old gdt and idt for debugger */ 4364Srgrimes 437757Sdg cmpl $0x0375c339,0x96104 /* XXX - debugger signature */ 4384Srgrimes jne 1f 439570Srgrimes movb $1,_bdb_exists-KERNBASE 4404Srgrimes1: 4414Srgrimes pushal 4424Srgrimes subl $2*6,%esp 4434Srgrimes 4444Srgrimes sgdt (%esp) 445757Sdg movl 2(%esp),%esi /* base address of current gdt */ 446570Srgrimes movl $_gdt-KERNBASE,%edi 4474Srgrimes movl %edi,2(%esp) 4484Srgrimes movl $8*18/4,%ecx 4491688Sdg cld 450757Sdg rep /* copy gdt */ 4514Srgrimes movsl 452570Srgrimes movl $_gdt-KERNBASE,-8+2(%edi) /* adjust gdt self-ptr */ 4534Srgrimes movb $0x92,-8+5(%edi) 4544Srgrimes 4554Srgrimes sidt 6(%esp) 456757Sdg movl 6+2(%esp),%esi /* base address of current idt */ 457757Sdg movl 8+4(%esi),%eax /* convert dbg descriptor to ... */ 4584Srgrimes movw 8(%esi),%ax 459570Srgrimes movl %eax,bdb_dbg_ljmp+1-KERNBASE /* ... immediate offset ... */ 4604Srgrimes movl 8+2(%esi),%eax 461570Srgrimes movw %ax,bdb_dbg_ljmp+5-KERNBASE /* ... and selector for ljmp */ 462757Sdg movl 24+4(%esi),%eax /* same for bpt descriptor */ 4634Srgrimes movw 24(%esi),%ax 464570Srgrimes movl %eax,bdb_bpt_ljmp+1-KERNBASE 4654Srgrimes movl 24+2(%esi),%eax 466570Srgrimes movw %ax,bdb_bpt_ljmp+5-KERNBASE 4674Srgrimes 468570Srgrimes movl $_idt-KERNBASE,%edi 4694Srgrimes movl %edi,6+2(%esp) 4704Srgrimes movl $8*4/4,%ecx 4711688Sdg cld 472757Sdg rep /* copy idt */ 4734Srgrimes movsl 4744Srgrimes 4754Srgrimes lgdt (%esp) 4764Srgrimes lidt 6(%esp) 4774Srgrimes 4784Srgrimes addl $2*6,%esp 4794Srgrimes popal 4801321Sdg#endif /* BDE_DEBUGGER */ 4814Srgrimes 482592Srgrimes /* load base of page directory and enable mapping */ 483757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 484570Srgrimes orl $I386_CR3PAT,%eax 485757Sdg movl %eax,%cr3 /* load ptd addr into mmu */ 486757Sdg movl %cr0,%eax /* get control word */ 487757Sdg orl $CR0_PE|CR0_PG,%eax /* enable paging */ 488757Sdg movl %eax,%cr0 /* and let's page NOW! */ 4894Srgrimes 490757Sdg pushl $begin /* jump to high mem */ 4914Srgrimes ret 4924Srgrimes 493570Srgrimesbegin: /* now running relocated at KERNBASE where the system is linked to run */ 4944Srgrimes 495757Sdg .globl _Crtat /* XXX - locore should not know about */ 496757Sdg movl _Crtat,%eax /* variables of device drivers (pccons)! */ 497592Srgrimes subl $(KERNBASE+0xA0000),%eax 498757Sdg movl _atdevphys,%edx /* get pte PA */ 499757Sdg subl _KPTphys,%edx /* remove base of ptes, now have phys offset */ 500757Sdg shll $PGSHIFT-2,%edx /* corresponding to virt offset */ 501757Sdg addl $KERNBASE,%edx /* add virtual base */ 502570Srgrimes movl %edx,_atdevbase 5034Srgrimes addl %eax,%edx 5044Srgrimes movl %edx,_Crtat 5054Srgrimes 506757Sdg /* set up bootstrap stack - 48 bytes */ 507570Srgrimes movl $_kstack+UPAGES*NBPG-4*12,%esp /* bootstrap stack end location */ 508757Sdg xorl %eax,%eax /* mark end of frames */ 5094Srgrimes movl %eax,%ebp 510570Srgrimes movl _proc0paddr,%eax 511570Srgrimes movl %esi,PCB_CR3(%eax) 5124Srgrimes 513757Sdg#ifdef BDE_DEBUGGER 5144Srgrimes /* relocate debugger gdt entries */ 5154Srgrimes 516757Sdg movl $_gdt+8*9,%eax /* adjust slots 9-17 */ 5174Srgrimes movl $9,%ecx 5184Srgrimesreloc_gdt: 5191321Sdg movb $KERNBASE>>24,7(%eax) /* top byte of base addresses, was 0, */ 520757Sdg addl $8,%eax /* now KERNBASE>>24 */ 5214Srgrimes loop reloc_gdt 5224Srgrimes 5234Srgrimes cmpl $0,_bdb_exists 5244Srgrimes je 1f 5254Srgrimes int $3 5264Srgrimes1: 5271321Sdg#endif /* BDE_DEBUGGER */ 5284Srgrimes 529608Srgrimes /* 530608Srgrimes * Skip over the page tables and the kernel stack 531608Srgrimes */ 532974Sdg lea ((1+UPAGES+1+NKPT)*NBPG)(%esi),%esi 533608Srgrimes 534757Sdg pushl %esi /* value of first for init386(first) */ 535757Sdg call _init386 /* wire 386 chip for unix operation */ 5361549Srgrimes popl %esi 537200Sdg 5381549Srgrimes .globl __ucodesel,__udatasel 5391549Srgrimes 5401549Srgrimes pushl $0 /* unused */ 5411549Srgrimes pushl __udatasel /* ss */ 5421549Srgrimes pushl $0 /* esp - filled in by execve() */ 5432500Sdg pushl $PSL_USERSET /* eflags (ring 0, int enab) */ 5441549Srgrimes pushl __ucodesel /* cs */ 5451549Srgrimes pushl $0 /* eip - filled in by execve() */ 5461549Srgrimes subl $(12*4),%esp /* space for rest of registers */ 5471549Srgrimes 5481549Srgrimes pushl %esp /* call main with frame pointer */ 549757Sdg call _main /* autoconfiguration, mountroot etc */ 5504Srgrimes 5511549Srgrimes addl $(13*4),%esp /* back to a frame we can return with */ 5521549Srgrimes 553134Sdg /* 554570Srgrimes * now we've run main() and determined what cpu-type we are, we can 555570Srgrimes * enable WP mode on i486 cpus and above. 5561058Sdg */ 5571058Sdg#if defined(I486_CPU) || defined(I586_CPU) 5581058Sdg cmpl $CPUCLASS_386,_cpu_class 5591058Sdg je 1f 5601058Sdg movl %cr0,%eax /* get control word */ 5611058Sdg orl $CR0_WP,%eax /* enable write protect for all modes */ 5621058Sdg movl %eax,%cr0 /* and do it */ 5631058Sdg#endif 5641058Sdg /* 565134Sdg * on return from main(), we are process 1 566134Sdg * set up address space and stack so that we can 'return' to user mode 567134Sdg */ 5681058Sdg1: 5694Srgrimes movl __ucodesel,%eax 5704Srgrimes movl __udatasel,%ecx 5711549Srgrimes 5724Srgrimes movl %cx,%ds 5734Srgrimes movl %cx,%es 574757Sdg movl %ax,%fs /* double map cs to fs */ 575757Sdg movl %cx,%gs /* and ds to gs */ 5761549Srgrimes iret /* goto user! */ 5774Srgrimes 5781549Srgrimes#define LCALL(x,y) .byte 0x9a ; .long y ; .word x 5794Srgrimes 580200SdgNON_GPROF_ENTRY(sigcode) 581592Srgrimes call SIGF_HANDLER(%esp) 582757Sdg lea SIGF_SC(%esp),%eax /* scp (the call may have clobbered the */ 583757Sdg /* copy at 8(%esp)) */ 5844Srgrimes pushl %eax 585757Sdg pushl %eax /* junk to fake return address */ 586757Sdg movl $103,%eax /* XXX sigreturn() */ 587757Sdg LCALL(0x7,0) /* enter kernel with args on stack */ 588757Sdg hlt /* never gets here */ 5894Srgrimes 5904Srgrimes .globl _szsigcode 5914Srgrimes_szsigcode: 5924Srgrimes .long _szsigcode-_sigcode 593