locore.s revision 3117
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 373117Spst * $Id: locore.s,v 1.28 1994/09/15 07:26:31 sos 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 1052783Ssos 1062783Ssos .globl _video_mode_ptr 1072783Ssos 108757Sdg_cpu: .long 0 /* are we 386, 386sx, or 486 */ 1092216Sbde_cpu_id: .long 0 /* stepping ID */ 1102216Sbde_cpu_vendor: .space 20 /* CPU origin code */ 1112783Ssos_video_mode_ptr: .long 0 112757Sdg_cold: .long 1 /* cold till we are not */ 113757Sdg_atdevbase: .long 0 /* location of start of iomem in virtual */ 114757Sdg_atdevphys: .long 0 /* location of device mapping ptes (phys) */ 1154Srgrimes 116757Sdg .globl _KERNend 117757Sdg_KERNend: .long 0 /* phys addr end of kernel (just after bss) */ 118757Sdg 119592Srgrimes .globl _IdlePTD,_KPTphys 120757Sdg_IdlePTD: .long 0 /* phys addr of kernel PTD */ 121757Sdg_KPTphys: .long 0 /* phys addr of kernel page tables */ 1224Srgrimes 123757Sdg .globl _cyloffset 124757Sdg_cyloffset: .long 0 /* cylinder offset from boot blocks */ 125718Swollman 126757Sdg .globl _proc0paddr 127757Sdg_proc0paddr: .long 0 /* address of proc 0 address space */ 128134Sdg 129757Sdg#ifdef BDE_DEBUGGER 130757Sdg .globl _bdb_exists /* flag to indicate BDE debugger is available */ 1311321Sdg_bdb_exists: .long 0 132757Sdg#endif 133718Swollman 134757Sdg .globl tmpstk 135974Sdg .space 0x1000 1364Srgrimestmpstk: 137134Sdg 138134Sdg 139556Srgrimes/* 140556Srgrimes * System Initialization 141556Srgrimes */ 1424Srgrimes .text 143134Sdg 144134Sdg/* 145200Sdg * btext: beginning of text section. 146200Sdg * Also the entry point (jumped to directly from the boot blocks). 147134Sdg */ 1481321SdgNON_GPROF_ENTRY(btext) 149757Sdg movw $0x1234,0x472 /* warm boot */ 1504Srgrimes jmp 1f 1511321Sdg .org 0x500 /* space for BIOS variables */ 1524Srgrimes 1532486Sdg 1: 1542512Sbde /* Don't trust what the BIOS gives for eflags. */ 1552512Sbde pushl $PSL_MBO 1562486Sdg popfl 1572486Sdg 1584Srgrimes /* 159556Srgrimes * pass parameters on stack (howto, bootdev, unit, cyloffset, esym) 1604Srgrimes * note: (%esp) is return address of boot 1614Srgrimes * ( if we want to hold onto /boot, it's physical %esp up to _end) 1624Srgrimes */ 1632486Sdg movl 4(%esp),%eax 164570Srgrimes movl %eax,_boothowto-KERNBASE 1654Srgrimes movl 8(%esp),%eax 166570Srgrimes movl %eax,_bootdev-KERNBASE 1674Srgrimes movl 12(%esp),%eax 168570Srgrimes movl %eax,_cyloffset-KERNBASE 169556Srgrimes movl 16(%esp),%eax 170570Srgrimes addl $KERNBASE,%eax 171570Srgrimes movl %eax,_esym-KERNBASE 1722783Ssos 1732783Ssos /* get the BIOS video mode pointer */ 1742783Ssos movl $0x4a8, %ecx 1752783Ssos movl (%ecx), %eax 1762783Ssos movl %eax, %ecx 1772783Ssos shrl $12, %ecx 1782783Ssos andl $0xffff0000, %ecx 1792783Ssos andl $0x0000ffff, %eax 1802783Ssos orl %ecx, %eax 1812783Ssos movl (%eax), %eax 1822783Ssos movl %eax, %ecx 1832783Ssos shrl $12, %ecx 1842783Ssos andl $0xffff0000, %ecx 1852783Ssos andl $0x0000ffff, %eax 1862783Ssos orl %ecx, %eax 1872783Ssos addl $KERNBASE, %eax 1882783Ssos movl %eax, _video_mode_ptr-KERNBASE 1892783Ssos 190975Smartin#ifdef DISKLESS /* Copy diskless structure */ 191975Smartin movl _nfs_diskless_size-KERNBASE,%ecx 192975Smartin movl 20(%esp),%esi 193975Smartin movl $(_nfs_diskless-KERNBASE),%edi 1941688Sdg cld 195975Smartin rep 196975Smartin movsb 197975Smartin#endif 1984Srgrimes 1991998Swollman /* Find out our CPU type. */ 2001321Sdg 2011998Swollman /* Try to toggle alignment check flag; does not exist on 386. */ 2021998Swollman pushfl 2031998Swollman popl %eax 2041998Swollman movl %eax,%ecx 2051998Swollman orl $PSL_AC,%eax 2061998Swollman pushl %eax 2071998Swollman popfl 2081998Swollman pushfl 2091998Swollman popl %eax 2101998Swollman xorl %ecx,%eax 2111998Swollman andl $PSL_AC,%eax 2121998Swollman pushl %ecx 2131998Swollman popfl 2141998Swollman 2151998Swollman testl %eax,%eax 2161998Swollman jnz 1f 2171998Swollman movl $CPU_386,_cpu-KERNBASE 218556Srgrimes jmp 2f 2191998Swollman 2201998Swollman1: /* Try to toggle identification flag; does not exist on early 486s. */ 2211998Swollman pushfl 2221998Swollman popl %eax 2231998Swollman movl %eax,%ecx 2241998Swollman xorl $PSL_ID,%eax 2251998Swollman pushl %eax 2261998Swollman popfl 2271998Swollman pushfl 2281998Swollman popl %eax 2291998Swollman xorl %ecx,%eax 2301998Swollman andl $PSL_ID,%eax 2311998Swollman pushl %ecx 2321998Swollman popfl 2331998Swollman 2341998Swollman testl %eax,%eax 2351998Swollman jnz 1f 2361998Swollman movl $CPU_486,_cpu-KERNBASE 2372495Spst 2382495Spst /* check for Cyrix 486DLC -- based on check routine */ 2392495Spst /* documented in "Cx486SLC/e SMM Programmer's Guide" */ 2402495Spst xorw %dx,%dx 2412495Spst cmpw %dx,%dx # set flags to known state 2422495Spst pushfw 2432495Spst popw %cx # store flags in ecx 2442495Spst movw $0xffff,%ax 2452495Spst movw $0x0004,%bx 2462495Spst divw %bx 2472495Spst pushfw 2482495Spst popw %ax 2492495Spst andw $0x08d5,%ax # mask off important bits 2502495Spst andw $0x08d5,%cx 2512495Spst cmpw %ax,%cx 2522495Spst 2532495Spst jnz 2f # if flags changed, Intel chip 2542495Spst 2552495Spst movl $CPU_486DLC,_cpu-KERNBASE # set CPU value for Cyrix 2562495Spst movl $0x69727943,_cpu_vendor-KERNBASE # store vendor string 2572495Spst movw $0x0078,_cpu_vendor-KERNBASE+4 2582495Spst 2592495Spst invd # Start with guaranteed clean cache 2602495Spst /* Disable caching of the ISA hole only. */ 2612495Spst movb $CCR0,%al # Configuration Register index (CCR0) 2622495Spst outb %al,$0x22 2632495Spst inb $0x23,%al 2643117Spst orb $(CCR0_NC1|CCR0_BARB),%al 2652495Spst outb %al,$0x23 2662495Spst invd 2671998Swollman jmp 2f 2681998Swollman 2691998Swollman1: /* Use the `cpuid' instruction. */ 2701998Swollman xorl %eax,%eax 2711998Swollman .byte 0x0f,0xa2 # cpuid 0 2721998Swollman movl %ebx,_cpu_vendor-KERNBASE # store vendor string 2731998Swollman movl %edx,_cpu_vendor+4-KERNBASE 2741998Swollman movl %ecx,_cpu_vendor+8-KERNBASE 2751998Swollman movb $0,_cpu_vendor+12-KERNBASE 2761998Swollman 2771998Swollman movl $1,%eax 2781998Swollman .byte 0x0f,0xa2 # cpuid 1 2791998Swollman movl %eax,_cpu_id-KERNBASE # store cpu_id 2801998Swollman rorl $8,%eax # extract family type 2811998Swollman andl $15,%eax 2821998Swollman cmpl $5,%eax 2831998Swollman jae 1f 2841998Swollman 2851998Swollman /* less than Pentium; must be 486 */ 2861998Swollman movl $CPU_486,_cpu-KERNBASE 2871998Swollman jmp 2f 2881998Swollman 2891998Swollman1: movl $CPU_586,_cpu-KERNBASE 290556Srgrimes2: 291556Srgrimes 2924Srgrimes /* 2934Srgrimes * Finished with old stack; load new %esp now instead of later so 2944Srgrimes * we can trace this code without having to worry about the trace 2954Srgrimes * trap clobbering the memory test or the zeroing of the bss+bootstrap 2964Srgrimes * page tables. 2974Srgrimes * 2984Srgrimes * XXX - wdboot clears the bss after testing that this is safe. 2994Srgrimes * This is too wasteful - memory below 640K is scarce. The boot 3004Srgrimes * program should check: 3014Srgrimes * text+data <= &stack_variable - more_space_for_stack 3024Srgrimes * text+data+bss+pad+space_for_page_tables <= end_of_memory 3034Srgrimes * Oops, the gdt is in the carcass of the boot program so clearing 3044Srgrimes * the rest of memory is still not possible. 3054Srgrimes */ 306757Sdg movl $tmpstk-KERNBASE,%esp /* bootstrap stack end location */ 3074Srgrimes 308570Srgrimes/* 309570Srgrimes * Virtual address space of kernel: 310570Srgrimes * 311570Srgrimes * text | data | bss | [syms] | page dir | proc0 kernel stack | usr stk map | Sysmap 312974Sdg * pages: 1 UPAGES (2) 1 NKPT (7) 313570Srgrimes */ 314570Srgrimes 3154Srgrimes/* find end of kernel image */ 316570Srgrimes movl $_end-KERNBASE,%ecx 317757Sdg addl $NBPG-1,%ecx /* page align up */ 3184Srgrimes andl $~(NBPG-1),%ecx 3191321Sdg movl %ecx,%esi /* esi = start of free memory */ 320757Sdg movl %ecx,_KERNend-KERNBASE /* save end of kernel */ 3214Srgrimes 322757Sdg/* clear bss */ 323570Srgrimes movl $_edata-KERNBASE,%edi 324760Srgrimes subl %edi,%ecx /* get amount to clear */ 325757Sdg xorl %eax,%eax /* specify zero fill */ 3264Srgrimes cld 3274Srgrimes rep 3284Srgrimes stosb 3294Srgrimes 330608Srgrimes/* 331974Sdg * The value in esi is both the end of the kernel bss and a pointer to 332974Sdg * the kernel page directory, and is used by the rest of locore to build 333974Sdg * the tables. 334974Sdg * esi + 1(page dir) + 2(UPAGES) + 1(p0stack) + NKPT(number of kernel 335757Sdg * page table pages) is then passed on the stack to init386(first) as 336757Sdg * the value first. esi should ALWAYS be page aligned!! 337608Srgrimes */ 338757Sdg movl %esi,%ecx /* Get current first availiable address */ 339608Srgrimes 340757Sdg/* clear pagetables, page directory, stack, etc... */ 341757Sdg movl %esi,%edi /* base (page directory) */ 342974Sdg movl $((1+UPAGES+1+NKPT)*NBPG),%ecx /* amount to clear */ 343757Sdg xorl %eax,%eax /* specify zero fill */ 344757Sdg cld 345757Sdg rep 346757Sdg stosb 347757Sdg 348757Sdg/* physical address of Idle proc/kernel page directory */ 349570Srgrimes movl %esi,_IdlePTD-KERNBASE 3504Srgrimes 351592Srgrimes/* 352592Srgrimes * fillkpt 353592Srgrimes * eax = (page frame address | control | status) == pte 354592Srgrimes * ebx = address of page table 355592Srgrimes * ecx = how many pages to map 356592Srgrimes */ 3574Srgrimes#define fillkpt \ 3584Srgrimes1: movl %eax,(%ebx) ; \ 359570Srgrimes addl $NBPG,%eax ; /* increment physical address */ \ 3604Srgrimes addl $4,%ebx ; /* next pte */ \ 3614Srgrimes loop 1b ; 3624Srgrimes 3634Srgrimes/* 3644Srgrimes * Map Kernel 3654Srgrimes * 3664Srgrimes * First step - build page tables 3674Srgrimes */ 368757Sdg#if defined (KGDB) || defined (BDE_DEBUGGER) 369757Sdg movl _KERNend-KERNBASE,%ecx /* this much memory, */ 370757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 371757Sdg#ifdef BDE_DEBUGGER 372757Sdg cmpl $0xa0,%ecx /* XXX - cover debugger pages */ 373200Sdg jae 1f 374200Sdg movl $0xa0,%ecx 375200Sdg1: 376757Sdg#endif /* BDE_DEBUGGER */ 3772512Sbde movl $PG_V|PG_KW,%eax /* kernel R/W, valid */ 378757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 379757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 3804Srgrimes fillkpt 3814Srgrimes 382757Sdg#else /* !KGDB && !BDE_DEBUGGER */ 383757Sdg /* write protect kernel text (doesn't do a thing for 386's - only 486's) */ 384757Sdg movl $_etext-KERNBASE,%ecx /* get size of text */ 385757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 386757Sdg movl $PG_V|PG_KR,%eax /* specify read only */ 387757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 388757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 389757Sdg fillkpt 390757Sdg 391757Sdg /* data and bss are r/w */ 392757Sdg andl $PG_FRAME,%eax /* strip to just addr of bss */ 393757Sdg movl _KERNend-KERNBASE,%ecx /* calculate size */ 394757Sdg subl %eax,%ecx 395757Sdg shrl $PGSHIFT,%ecx 396757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 397757Sdg fillkpt 3981321Sdg#endif /* KGDB || BDE_DEBUGGER */ 399757Sdg 400757Sdg/* now initialize the page dir, upages, p0stack PT, and page tables */ 401757Sdg 402974Sdg movl $(1+UPAGES+1+NKPT),%ecx /* number of PTEs */ 403757Sdg movl %esi,%eax /* phys address of PTD */ 404757Sdg andl $PG_FRAME,%eax /* convert to PFN, should be a NOP */ 4052512Sbde orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 406757Sdg movl %esi,%ebx /* calculate pte offset to ptd */ 407757Sdg shrl $PGSHIFT-2,%ebx 408757Sdg addl %esi,%ebx /* address of page directory */ 409757Sdg addl $((1+UPAGES+1)*NBPG),%ebx /* offset to kernel page tables */ 410757Sdg fillkpt 4111321Sdg 4124Srgrimes/* map I/O memory map */ 4134Srgrimes 414757Sdg movl _KPTphys-KERNBASE,%ebx /* base of kernel page tables */ 415757Sdg lea (0xa0 * PTESIZE)(%ebx),%ebx /* hardwire ISA hole at KERNBASE + 0xa0000 */ 416757Sdg movl $0x100-0xa0,%ecx /* for this many pte s, */ 4171046Sdg movl $(0xa0000|PG_V|PG_KW|PG_N),%eax /* valid, kernel read/write, non-cacheable */ 418757Sdg movl %ebx,_atdevphys-KERNBASE /* save phys addr of ptes */ 4194Srgrimes fillkpt 4204Srgrimes 4214Srgrimes /* map proc 0's kernel stack into user page table page */ 4224Srgrimes 423757Sdg movl $UPAGES,%ecx /* for this many pte s, */ 424757Sdg lea (1*NBPG)(%esi),%eax /* physical address in proc 0 */ 425757Sdg lea (KERNBASE)(%eax),%edx /* change into virtual addr */ 426757Sdg movl %edx,_proc0paddr-KERNBASE /* save VA for proc 0 init */ 427757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 428757Sdg lea ((1+UPAGES)*NBPG)(%esi),%ebx /* addr of stack page table in proc 0 */ 429757Sdg addl $(KSTKPTEOFF * PTESIZE),%ebx /* offset to kernel stack PTE */ 4304Srgrimes fillkpt 4314Srgrimes 4324Srgrimes/* 433757Sdg * Initialize kernel page table directory 4344Srgrimes */ 4354Srgrimes /* install a pde for temporary double map of bottom of VA */ 436757Sdg movl _KPTphys-KERNBASE,%eax 437757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 438757Sdg movl %eax,(%esi) /* which is where temp maps! */ 4394Srgrimes 440757Sdg /* initialize kernel pde's */ 441974Sdg movl $(NKPT),%ecx /* for this many PDEs */ 442757Sdg lea (KPTDI*PDESIZE)(%esi),%ebx /* offset of pde for kernel */ 4434Srgrimes fillkpt 4444Srgrimes 4454Srgrimes /* install a pde recursively mapping page directory as a page table! */ 446757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 447757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 448757Sdg movl %eax,PTDPTDI*PDESIZE(%esi) /* which is where PTmap maps! */ 4494Srgrimes 4504Srgrimes /* install a pde to map kernel stack for proc 0 */ 451757Sdg lea ((1+UPAGES)*NBPG)(%esi),%eax /* physical address of pt in proc 0 */ 452757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 453757Sdg movl %eax,KSTKPTDI*PDESIZE(%esi) /* which is where kernel stack maps! */ 4544Srgrimes 455757Sdg#ifdef BDE_DEBUGGER 4564Srgrimes /* copy and convert stuff from old gdt and idt for debugger */ 4574Srgrimes 458757Sdg cmpl $0x0375c339,0x96104 /* XXX - debugger signature */ 4594Srgrimes jne 1f 460570Srgrimes movb $1,_bdb_exists-KERNBASE 4614Srgrimes1: 4624Srgrimes pushal 4634Srgrimes subl $2*6,%esp 4644Srgrimes 4654Srgrimes sgdt (%esp) 466757Sdg movl 2(%esp),%esi /* base address of current gdt */ 467570Srgrimes movl $_gdt-KERNBASE,%edi 4684Srgrimes movl %edi,2(%esp) 4694Srgrimes movl $8*18/4,%ecx 4701688Sdg cld 471757Sdg rep /* copy gdt */ 4724Srgrimes movsl 473570Srgrimes movl $_gdt-KERNBASE,-8+2(%edi) /* adjust gdt self-ptr */ 4744Srgrimes movb $0x92,-8+5(%edi) 4754Srgrimes 4764Srgrimes sidt 6(%esp) 477757Sdg movl 6+2(%esp),%esi /* base address of current idt */ 478757Sdg movl 8+4(%esi),%eax /* convert dbg descriptor to ... */ 4794Srgrimes movw 8(%esi),%ax 480570Srgrimes movl %eax,bdb_dbg_ljmp+1-KERNBASE /* ... immediate offset ... */ 4814Srgrimes movl 8+2(%esi),%eax 482570Srgrimes movw %ax,bdb_dbg_ljmp+5-KERNBASE /* ... and selector for ljmp */ 483757Sdg movl 24+4(%esi),%eax /* same for bpt descriptor */ 4844Srgrimes movw 24(%esi),%ax 485570Srgrimes movl %eax,bdb_bpt_ljmp+1-KERNBASE 4864Srgrimes movl 24+2(%esi),%eax 487570Srgrimes movw %ax,bdb_bpt_ljmp+5-KERNBASE 4884Srgrimes 489570Srgrimes movl $_idt-KERNBASE,%edi 4904Srgrimes movl %edi,6+2(%esp) 4914Srgrimes movl $8*4/4,%ecx 4921688Sdg cld 493757Sdg rep /* copy idt */ 4944Srgrimes movsl 4954Srgrimes 4964Srgrimes lgdt (%esp) 4974Srgrimes lidt 6(%esp) 4984Srgrimes 4994Srgrimes addl $2*6,%esp 5004Srgrimes popal 5011321Sdg#endif /* BDE_DEBUGGER */ 5024Srgrimes 503592Srgrimes /* load base of page directory and enable mapping */ 504757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 505757Sdg movl %eax,%cr3 /* load ptd addr into mmu */ 506757Sdg movl %cr0,%eax /* get control word */ 507757Sdg orl $CR0_PE|CR0_PG,%eax /* enable paging */ 508757Sdg movl %eax,%cr0 /* and let's page NOW! */ 5094Srgrimes 510757Sdg pushl $begin /* jump to high mem */ 5114Srgrimes ret 5124Srgrimes 513570Srgrimesbegin: /* now running relocated at KERNBASE where the system is linked to run */ 5144Srgrimes 515757Sdg .globl _Crtat /* XXX - locore should not know about */ 516757Sdg movl _Crtat,%eax /* variables of device drivers (pccons)! */ 517592Srgrimes subl $(KERNBASE+0xA0000),%eax 518757Sdg movl _atdevphys,%edx /* get pte PA */ 519757Sdg subl _KPTphys,%edx /* remove base of ptes, now have phys offset */ 520757Sdg shll $PGSHIFT-2,%edx /* corresponding to virt offset */ 521757Sdg addl $KERNBASE,%edx /* add virtual base */ 522570Srgrimes movl %edx,_atdevbase 5234Srgrimes addl %eax,%edx 5244Srgrimes movl %edx,_Crtat 5254Srgrimes 526757Sdg /* set up bootstrap stack - 48 bytes */ 527570Srgrimes movl $_kstack+UPAGES*NBPG-4*12,%esp /* bootstrap stack end location */ 528757Sdg xorl %eax,%eax /* mark end of frames */ 5294Srgrimes movl %eax,%ebp 530570Srgrimes movl _proc0paddr,%eax 531570Srgrimes movl %esi,PCB_CR3(%eax) 5324Srgrimes 533757Sdg#ifdef BDE_DEBUGGER 5344Srgrimes /* relocate debugger gdt entries */ 5354Srgrimes 536757Sdg movl $_gdt+8*9,%eax /* adjust slots 9-17 */ 5374Srgrimes movl $9,%ecx 5384Srgrimesreloc_gdt: 5391321Sdg movb $KERNBASE>>24,7(%eax) /* top byte of base addresses, was 0, */ 540757Sdg addl $8,%eax /* now KERNBASE>>24 */ 5414Srgrimes loop reloc_gdt 5424Srgrimes 5434Srgrimes cmpl $0,_bdb_exists 5444Srgrimes je 1f 5454Srgrimes int $3 5464Srgrimes1: 5471321Sdg#endif /* BDE_DEBUGGER */ 5484Srgrimes 549608Srgrimes /* 550608Srgrimes * Skip over the page tables and the kernel stack 551608Srgrimes */ 552974Sdg lea ((1+UPAGES+1+NKPT)*NBPG)(%esi),%esi 553608Srgrimes 554757Sdg pushl %esi /* value of first for init386(first) */ 555757Sdg call _init386 /* wire 386 chip for unix operation */ 5561549Srgrimes popl %esi 557200Sdg 5581549Srgrimes .globl __ucodesel,__udatasel 5591549Srgrimes 5601549Srgrimes pushl $0 /* unused */ 5611549Srgrimes pushl __udatasel /* ss */ 5621549Srgrimes pushl $0 /* esp - filled in by execve() */ 5632500Sdg pushl $PSL_USERSET /* eflags (ring 0, int enab) */ 5641549Srgrimes pushl __ucodesel /* cs */ 5651549Srgrimes pushl $0 /* eip - filled in by execve() */ 5661549Srgrimes subl $(12*4),%esp /* space for rest of registers */ 5671549Srgrimes 5681549Srgrimes pushl %esp /* call main with frame pointer */ 569757Sdg call _main /* autoconfiguration, mountroot etc */ 5704Srgrimes 5711549Srgrimes addl $(13*4),%esp /* back to a frame we can return with */ 5721549Srgrimes 573134Sdg /* 574570Srgrimes * now we've run main() and determined what cpu-type we are, we can 575570Srgrimes * enable WP mode on i486 cpus and above. 5761058Sdg */ 5771058Sdg#if defined(I486_CPU) || defined(I586_CPU) 5781058Sdg cmpl $CPUCLASS_386,_cpu_class 5791058Sdg je 1f 5801058Sdg movl %cr0,%eax /* get control word */ 5811058Sdg orl $CR0_WP,%eax /* enable write protect for all modes */ 5821058Sdg movl %eax,%cr0 /* and do it */ 5831058Sdg#endif 5841058Sdg /* 585134Sdg * on return from main(), we are process 1 586134Sdg * set up address space and stack so that we can 'return' to user mode 587134Sdg */ 5881058Sdg1: 5894Srgrimes movl __ucodesel,%eax 5904Srgrimes movl __udatasel,%ecx 5911549Srgrimes 5924Srgrimes movl %cx,%ds 5934Srgrimes movl %cx,%es 594757Sdg movl %ax,%fs /* double map cs to fs */ 595757Sdg movl %cx,%gs /* and ds to gs */ 5961549Srgrimes iret /* goto user! */ 5974Srgrimes 5981549Srgrimes#define LCALL(x,y) .byte 0x9a ; .long y ; .word x 5994Srgrimes 600200SdgNON_GPROF_ENTRY(sigcode) 601592Srgrimes call SIGF_HANDLER(%esp) 602757Sdg lea SIGF_SC(%esp),%eax /* scp (the call may have clobbered the */ 603757Sdg /* copy at 8(%esp)) */ 6044Srgrimes pushl %eax 605757Sdg pushl %eax /* junk to fake return address */ 606757Sdg movl $103,%eax /* XXX sigreturn() */ 607757Sdg LCALL(0x7,0) /* enter kernel with args on stack */ 608757Sdg hlt /* never gets here */ 6094Srgrimes 6104Srgrimes .globl _szsigcode 6114Srgrimes_szsigcode: 6124Srgrimes .long _szsigcode-_sigcode 613