locore.s revision 15403
1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 37 * $Id: locore.s,v 1.65 1996/04/26 13:47:37 phk Exp $ 38 * 39 * originally from: locore.s, by William F. Jolitz 40 * 41 * Substantially rewritten by David Greenman, Rod Grimes, 42 * Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp 43 * and many others. 44 */ 45 46#include "apm.h" 47#include "opt_ddb.h" 48 49#include <sys/errno.h> 50#include <sys/syscall.h> 51#include <sys/reboot.h> 52 53#include <machine/asmacros.h> 54#include <machine/cputypes.h> 55#include <machine/psl.h> 56#include <machine/pte.h> 57#include <machine/specialreg.h> 58 59#include "assym.s" 60 61/* 62 * XXX 63 * 64 * Note: This version greatly munged to avoid various assembler errors 65 * that may be fixed in newer versions of gas. Perhaps newer versions 66 * will have more pleasant appearance. 67 */ 68 69/* 70 * PTmap is recursive pagemap at top of virtual address space. 71 * Within PTmap, the page directory can be found (third indirection). 72 */ 73 .globl _PTmap,_PTD,_PTDpde 74 .set _PTmap,PTDPTDI << PDRSHIFT 75 .set _PTD,_PTmap + (PTDPTDI * NBPG) 76 .set _PTDpde,_PTD + (PTDPTDI * PDESIZE) 77 78/* 79 * Sysmap is the base address of the kernel page tables. 80 * It is a bogus interface for kgdb and isn't used by the kernel itself. 81 */ 82 .set _Sysmap,_PTmap + (KPTDI * NBPG) 83 84/* 85 * APTmap, APTD is the alternate recursive pagemap. 86 * It's used when modifying another process's page tables. 87 */ 88 .globl _APTmap,_APTD,_APTDpde 89 .set _APTmap,APTDPTDI << PDRSHIFT 90 .set _APTD,_APTmap + (APTDPTDI * NBPG) 91 .set _APTDpde,_PTD + (APTDPTDI * PDESIZE) 92 93/* 94 * Access to each processes kernel stack is via a region of 95 * per-process address space (at the beginning), immediatly above 96 * the user process stack. 97 */ 98 .set _kstack,USRSTACK 99 .globl _kstack 100 101/* 102 * Globals 103 */ 104 .data 105 ALIGN_DATA /* just to be sure */ 106 107 .globl tmpstk 108 .space 0x2000 /* space for tmpstk - temporary stack */ 109tmpstk: 110 111 .globl _boothowto,_bootdev 112 113 .globl _cpu,_atdevbase,_cpu_vendor,_cpu_id,_bootinfo 114 .globl _cpu_high, _cpu_feature 115 116_cpu: .long 0 /* are we 386, 386sx, or 486 */ 117_cpu_id: .long 0 /* stepping ID */ 118_cpu_high: .long 0 /* highest arg to CPUID */ 119_cpu_feature: .long 0 /* features */ 120_cpu_vendor: .space 20 /* CPU origin code */ 121_bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ 122_atdevbase: .long 0 /* location of start of iomem in virtual */ 123 124_KERNend: .long 0 /* phys addr end of kernel (just after bss) */ 125physfree: .long 0 /* phys addr end of kernel (just after bss) */ 126upa: .long 0 /* phys addr end of kernel (just after bss) */ 127p0s: .long 0 /* phys addr end of kernel (just after bss) */ 128 129 .globl _IdlePTD 130_IdlePTD: .long 0 /* phys addr of kernel PTD */ 131 132_KPTphys: .long 0 /* phys addr of kernel page tables */ 133 134 .globl _proc0paddr 135_proc0paddr: .long 0 /* address of proc 0 address space */ 136 137 138/********************************************************************** 139 * 140 * Some handy macros 141 * 142 */ 143 144#define R(foo) ((foo)-KERNBASE) 145 146#define ROUND2PAGE(foo) addl $NBPG-1, foo; andl $~(NBPG-1), foo 147 148#define ALLOCPAGES(foo) \ 149 movl R(physfree), %esi ; \ 150 movl $((foo)*NBPG), %eax ; \ 151 addl %esi, %eax ; \ 152 movl %eax, R(physfree) ; \ 153 movl %esi, %edi ; \ 154 movl $((foo)*NBPG),%ecx ; \ 155 xorl %eax,%eax ; \ 156 cld ; rep ; stosb 157 158/* 159 * fillkpt 160 * eax = (page frame address | control | status) == pte 161 * ebx = address of page table 162 * ecx = how many pages to map 163 */ 164#define fillkpt \ 1651: movl %eax,(%ebx) ; \ 166 addl $NBPG,%eax ; /* increment physical address */ \ 167 addl $4,%ebx ; /* next pte */ \ 168 loop 1b ; 169 170 .text 171/********************************************************************** 172 * 173 * This is where the bootblocks start us, set the ball rolling... 174 * 175 */ 176NON_GPROF_ENTRY(btext) 177 178/* Tell the bios to warmboot next time */ 179 movw $0x1234,0x472 180 181/* Set up a real frame, some day we may be doing returns */ 182 pushl %ebp 183 movl %esp, %ebp 184 185/* Don't trust what the BIOS gives for eflags. */ 186 pushl $PSL_KERNEL 187 popfl 188 mov %ds, %ax /* ... or segment registers */ 189 mov %ax, %es 190 mov %ax, %fs 191 mov %ax, %gs 192 193 call recover_bootinfo 194 195/* get onto a stack we know the size of */ 196 movl $R(tmpstk),%esp 197 mov %ds, %ax 198 mov %ax, %ss 199 200 call identify_cpu 201 202/* clear bss */ 203 movl $R(_end),%ecx 204 movl $R(_edata),%edi 205 subl %edi,%ecx 206 xorl %eax,%eax 207 cld ; rep ; stosb 208 209#if NAPM > 0 210 call _apm_setup /* ... in i386/apm/apm_setup.s */ 211#endif /* NAPM */ 212 213 call create_pagetables 214 215/* Now enable paging */ 216 movl R(_IdlePTD), %eax 217 movl %eax,%cr3 /* load ptd addr into mmu */ 218 movl %cr0,%eax /* get control word */ 219 orl $CR0_PE|CR0_PG,%eax /* enable paging */ 220 movl %eax,%cr0 /* and let's page NOW! */ 221 222 pushl $begin /* jump to high mem */ 223 ret 224 225/* now running relocated at KERNBASE where the system is linked to run */ 226begin: 227 /* set up bootstrap stack */ 228 movl $_kstack+UPAGES*NBPG,%esp /* bootstrap stack end location */ 229 xorl %eax,%eax /* mark end of frames */ 230 movl %eax,%ebp 231 movl _proc0paddr,%eax 232 movl _IdlePTD, %esi 233 movl %esi,PCB_CR3(%eax) 234 235 /* 236 * Prepare "first" - physical address of first available page 237 * after the kernel+pdir+upages+p0stack+page tables 238 */ 239 movl physfree, %esi 240 pushl %esi /* value of first for init386(first) */ 241 call _init386 /* wire 386 chip for unix operation */ 242 popl %esi 243 244 .globl __ucodesel,__udatasel 245 246 pushl $0 /* unused */ 247 pushl __udatasel /* ss */ 248 pushl $0 /* esp - filled in by execve() */ 249 pushl $PSL_USER /* eflags (IOPL 0, int enab) */ 250 pushl __ucodesel /* cs */ 251 pushl $0 /* eip - filled in by execve() */ 252 subl $(12*4),%esp /* space for rest of registers */ 253 254 pushl %esp /* call main with frame pointer */ 255 call _main /* autoconfiguration, mountroot etc */ 256 257 addl $(13*4),%esp /* back to a frame we can return with */ 258 259 /* 260 * now we've run main() and determined what cpu-type we are, we can 261 * enable write protection and alignment checking on i486 cpus and 262 * above. 263 */ 264#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) 265 cmpl $CPUCLASS_386,_cpu_class 266 je 1f 267 movl %cr0,%eax /* get control word */ 268 orl $CR0_WP|CR0_AM,%eax /* enable i486 features */ 269 movl %eax,%cr0 /* and do it */ 270#endif 271 /* 272 * on return from main(), we are process 1 273 * set up address space and stack so that we can 'return' to user mode 274 */ 2751: 276 movl __ucodesel,%eax 277 movl __udatasel,%ecx 278 279 movl %cx,%ds 280 movl %cx,%es 281 movl %ax,%fs /* double map cs to fs */ 282 movl %cx,%gs /* and ds to gs */ 283 iret /* goto user! */ 284 285#define LCALL(x,y) .byte 0x9a ; .long y ; .word x 286 287/* 288 * Signal trampoline, copied to top of user stack 289 */ 290NON_GPROF_ENTRY(sigcode) 291 call SIGF_HANDLER(%esp) 292 lea SIGF_SC(%esp),%eax /* scp (the call may have clobbered the */ 293 /* copy at 8(%esp)) */ 294 pushl %eax 295 pushl %eax /* junk to fake return address */ 296 movl $SYS_sigreturn,%eax /* sigreturn() */ 297 LCALL(0x7,0) /* enter kernel with args on stack */ 298 hlt /* never gets here */ 299 .align 2,0x90 /* long word text-align */ 300_esigcode: 301 302 .data 303 .globl _szsigcode 304_szsigcode: 305 .long _esigcode-_sigcode 306 307/********************************************************************** 308 * 309 * Recover the bootinfo passed to us from the boot program 310 * 311 */ 312recover_bootinfo: 313 /* 314 * This code is called in different ways depending on what loaded 315 * and started the kernel. This is used to detect how we get the 316 * arguments from the other code and what we do with them. 317 * 318 * Old disk boot blocks: 319 * (*btext)(howto, bootdev, cyloffset, esym); 320 * [return address == 0, and can NOT be returned to] 321 * [cyloffset was not supported by the FreeBSD boot code 322 * and always passed in as 0] 323 * [esym is also known as total in the boot code, and 324 * was never properly supported by the FreeBSD boot code] 325 * 326 * Old diskless netboot code: 327 * (*btext)(0,0,0,0,&nfsdiskless,0,0,0); 328 * [return address != 0, and can NOT be returned to] 329 * If we are being booted by this code it will NOT work, 330 * so we are just going to halt if we find this case. 331 * 332 * New uniform boot code: 333 * (*btext)(howto, bootdev, 0, 0, 0, &bootinfo) 334 * [return address != 0, and can be returned to] 335 * 336 * There may seem to be a lot of wasted arguments in here, but 337 * that is so the newer boot code can still load very old kernels 338 * and old boot code can load new kernels. 339 */ 340 341 /* 342 * The old style disk boot blocks fake a frame on the stack and 343 * did an lret to get here. The frame on the stack has a return 344 * address of 0. 345 */ 346 cmpl $0,4(%ebp) 347 je olddiskboot 348 349 /* 350 * We have some form of return address, so this is either the 351 * old diskless netboot code, or the new uniform code. That can 352 * be detected by looking at the 5th argument, it if is 0 we 353 * we are being booted by the new unifrom boot code. 354 */ 355 cmpl $0,24(%ebp) 356 je newboot 357 358 /* 359 * Seems we have been loaded by the old diskless boot code, we 360 * don't stand a chance of running as the diskless structure 361 * changed considerably between the two, so just halt. 362 */ 363 hlt 364 365 /* 366 * We have been loaded by the new uniform boot code. 367 * Lets check the bootinfo version, and if we do not understand 368 * it we return to the loader with a status of 1 to indicate this error 369 */ 370newboot: 371 movl 28(%ebp),%ebx /* &bootinfo.version */ 372 movl BI_VERSION(%ebx),%eax 373 cmpl $1,%eax /* We only understand version 1 */ 374 je 1f 375 movl $1,%eax /* Return status */ 376 add $4, %esp /* pop recover_bootinfo's retaddr */ 377 leave 378 ret 379 3801: 381 /* 382 * If we have a kernelname copy it in 383 */ 384 movl BI_KERNELNAME(%ebx),%esi 385 cmpl $0,%esi 386 je 2f /* No kernelname */ 387 movl $MAXPATHLEN,%ecx /* Brute force!!! */ 388 lea _kernelname-KERNBASE,%edi 389 cmpb $'/',(%esi) /* Make sure it starts with a slash */ 390 je 1f 391 movb $'/',(%edi) 392 incl %edi 393 decl %ecx 3941: 395 cld 396 rep 397 movsb 398 3992: 400 /* 401 * Determine the size of the boot loader's copy of the bootinfo 402 * struct. This is impossible to do properly because old versions 403 * of the struct don't contain a size field and there are 2 old 404 * versions with the same version number. 405 */ 406 movl $BI_ENDCOMMON,%ecx /* prepare for sizeless version */ 407 testl $RB_BOOTINFO,8(%ebp) /* bi_size (and bootinfo) valid? */ 408 je got_bi_size /* no, sizeless version */ 409 movl BI_SIZE(%ebx),%ecx 410got_bi_size: 411 412 /* 413 * Copy the common part of the bootinfo struct 414 */ 415 movl %ebx,%esi 416 movl $_bootinfo-KERNBASE,%edi 417 cmpl $BOOTINFO_SIZE,%ecx 418 jbe got_common_bi_size 419 movl $BOOTINFO_SIZE,%ecx 420got_common_bi_size: 421 cld 422 rep 423 movsb 424 425#ifdef NFS 426 /* 427 * If we have a nfs_diskless structure copy it in 428 */ 429 movl BI_NFS_DISKLESS(%ebx),%esi 430 cmpl $0,%esi 431 je 2f 432 lea _nfs_diskless-KERNBASE,%edi 433 movl $NFSDISKLESS_SIZE,%ecx 434 cld 435 rep 436 movsb 437 lea _nfs_diskless_valid-KERNBASE,%edi 438 movl $1,(%edi) 439#endif 440 441 /* 442 * The old style disk boot. 443 * (*btext)(howto, bootdev, cyloffset, esym); 444 * Note that the newer boot code just falls into here to pick 445 * up howto and bootdev, cyloffset and esym are no longer used 446 */ 447olddiskboot: 448 movl 8(%ebp),%eax 449 movl %eax,_boothowto-KERNBASE 450 movl 12(%ebp),%eax 451 movl %eax,_bootdev-KERNBASE 452 453 ret 454 455 456/********************************************************************** 457 * 458 * Identify the CPU and initialize anything special about it 459 * 460 */ 461identify_cpu: 462 463 /* Try to toggle alignment check flag; does not exist on 386. */ 464 pushfl 465 popl %eax 466 movl %eax,%ecx 467 orl $PSL_AC,%eax 468 pushl %eax 469 popfl 470 pushfl 471 popl %eax 472 xorl %ecx,%eax 473 andl $PSL_AC,%eax 474 pushl %ecx 475 popfl 476 477 testl %eax,%eax 478 jnz 1f 479 movl $CPU_386,_cpu-KERNBASE 480 jmp 3f 481 4821: /* Try to toggle identification flag; does not exist on early 486s. */ 483 pushfl 484 popl %eax 485 movl %eax,%ecx 486 xorl $PSL_ID,%eax 487 pushl %eax 488 popfl 489 pushfl 490 popl %eax 491 xorl %ecx,%eax 492 andl $PSL_ID,%eax 493 pushl %ecx 494 popfl 495 496 testl %eax,%eax 497 jnz 1f 498 movl $CPU_486,_cpu-KERNBASE 499 500 /* check for Cyrix 486DLC -- based on check routine */ 501 /* documented in "Cx486SLC/e SMM Programmer's Guide" */ 502 xorw %dx,%dx 503 cmpw %dx,%dx # set flags to known state 504 pushfw 505 popw %cx # store flags in ecx 506 movw $0xffff,%ax 507 movw $0x0004,%bx 508 divw %bx 509 pushfw 510 popw %ax 511 andw $0x08d5,%ax # mask off important bits 512 andw $0x08d5,%cx 513 cmpw %ax,%cx 514 515 jnz 3f # if flags changed, Intel chip 516 517 movl $CPU_486DLC,_cpu-KERNBASE # set CPU value for Cyrix 518 movl $0x69727943,_cpu_vendor-KERNBASE # store vendor string 519 movw $0x0078,_cpu_vendor-KERNBASE+4 520 521#ifndef CYRIX_CACHE_WORKS 522 /* Disable caching of the ISA hole only. */ 523 invd 524 movb $CCR0,%al # Configuration Register index (CCR0) 525 outb %al,$0x22 526 inb $0x23,%al 527 orb $(CCR0_NC1|CCR0_BARB),%al 528 movb %al,%ah 529 movb $CCR0,%al 530 outb %al,$0x22 531 movb %ah,%al 532 outb %al,$0x23 533 invd 534#else /* CYRIX_CACHE_WORKS */ 535 /* Set cache parameters */ 536 invd # Start with guaranteed clean cache 537 movb $CCR0,%al # Configuration Register index (CCR0) 538 outb %al,$0x22 539 inb $0x23,%al 540 andb $~CCR0_NC0,%al 541#ifndef CYRIX_CACHE_REALLY_WORKS 542 orb $(CCR0_NC1|CCR0_BARB),%al 543#else /* !CYRIX_CACHE_REALLY_WORKS */ 544 orb $CCR0_NC1,%al 545#endif /* CYRIX_CACHE_REALLY_WORKS */ 546 movb %al,%ah 547 movb $CCR0,%al 548 outb %al,$0x22 549 movb %ah,%al 550 outb %al,$0x23 551 /* clear non-cacheable region 1 */ 552 movb $(NCR1+2),%al 553 outb %al,$0x22 554 movb $NCR_SIZE_0K,%al 555 outb %al,$0x23 556 /* clear non-cacheable region 2 */ 557 movb $(NCR2+2),%al 558 outb %al,$0x22 559 movb $NCR_SIZE_0K,%al 560 outb %al,$0x23 561 /* clear non-cacheable region 3 */ 562 movb $(NCR3+2),%al 563 outb %al,$0x22 564 movb $NCR_SIZE_0K,%al 565 outb %al,$0x23 566 /* clear non-cacheable region 4 */ 567 movb $(NCR4+2),%al 568 outb %al,$0x22 569 movb $NCR_SIZE_0K,%al 570 outb %al,$0x23 571 /* enable caching in CR0 */ 572 movl %cr0,%eax 573 andl $~(CR0_CD|CR0_NW),%eax 574 movl %eax,%cr0 575 invd 576#endif /* CYRIX_CACHE_WORKS */ 577 jmp 3f 578 5791: /* Use the `cpuid' instruction. */ 580 xorl %eax,%eax 581 .byte 0x0f,0xa2 # cpuid 0 582 movl %eax,_cpu_high-KERNBASE # highest capability 583 movl %ebx,_cpu_vendor-KERNBASE # store vendor string 584 movl %edx,_cpu_vendor+4-KERNBASE 585 movl %ecx,_cpu_vendor+8-KERNBASE 586 movb $0,_cpu_vendor+12-KERNBASE 587 588 movl $1,%eax 589 .byte 0x0f,0xa2 # cpuid 1 590 movl %eax,_cpu_id-KERNBASE # store cpu_id 591 movl %edx,_cpu_feature-KERNBASE # store cpu_feature 592 rorl $8,%eax # extract family type 593 andl $15,%eax 594 cmpl $5,%eax 595 jae 1f 596 597 /* less than Pentium; must be 486 */ 598 movl $CPU_486,_cpu-KERNBASE 599 jmp 3f 6001: 601 /* a Pentium? */ 602 cmpl $5,%eax 603 jne 2f 604 movl $CPU_586,_cpu-KERNBASE 605 jmp 3f 6062: 607 /* Greater than Pentium...call it a Pentium Pro */ 608 movl $CPU_686,_cpu-KERNBASE 6093: 610 ret 611 612 613/********************************************************************** 614 * 615 * Create the first page directory and it's page tables 616 * 617 */ 618 619create_pagetables: 620 621/* find end of kernel image */ 622 movl $R(_end),%esi 623 624/* include symbols in "kernel image" if they are loaded and useful */ 625#ifdef DDB 626 movl R(_bootinfo+BI_ESYMTAB),%edi 627 testl %edi,%edi 628 je 1f 629 movl %edi,%esi 630 movl $KERNBASE,%edi 631 addl %edi,R(_bootinfo+BI_SYMTAB) 632 addl %edi,R(_bootinfo+BI_ESYMTAB) 6331: 634#endif 635 636 ROUND2PAGE(%esi) 637 movl %esi,R(_KERNend) /* save end of kernel */ 638 movl %esi,R(physfree) /* save end of kernel */ 639 640/* Allocate Kernel Page Tables */ 641 ALLOCPAGES(NKPT) 642 movl %esi,R(_KPTphys) 643 644/* Allocate Page Table Directory */ 645 ALLOCPAGES(1) 646 movl %esi,R(_IdlePTD) 647 648/* Allocate UPAGES */ 649 ALLOCPAGES(UPAGES) 650 movl %esi,R(upa); 651 addl $KERNBASE, %esi 652 movl %esi, R(_proc0paddr) 653 654/* Allocate P0 Stack */ 655 ALLOCPAGES(1) 656 movl %esi,R(p0s); 657 658/* Map read-only from zero to the end of the kernel text section */ 659 movl R(_KPTphys), %esi 660 movl $R(_etext),%ecx 661 addl $NBPG-1,%ecx 662 shrl $PGSHIFT,%ecx 663 movl $PG_V|PG_KR,%eax 664 movl %esi, %ebx 665 fillkpt 666 667/* Map read-write, data, bss and symbols */ 668 andl $PG_FRAME,%eax 669 movl R(_KERNend),%ecx 670 subl %eax,%ecx 671 shrl $PGSHIFT,%ecx 672 orl $PG_V|PG_KW,%eax 673 fillkpt 674 675/* Map PD */ 676 movl R(_IdlePTD), %eax 677 movl $1, %ecx 678 movl %eax, %ebx 679 shrl $PGSHIFT-2, %ebx 680 addl R(_KPTphys), %ebx 681 orl $PG_V|PG_KW, %eax 682 fillkpt 683 684/* Map Proc 0 kernel stack */ 685 movl R(p0s), %eax 686 movl $1, %ecx 687 movl %eax, %ebx 688 shrl $PGSHIFT-2, %ebx 689 addl R(_KPTphys), %ebx 690 orl $PG_V|PG_KW, %eax 691 fillkpt 692 693/* ... also in user page table page */ 694 movl R(p0s), %eax 695 movl $1, %ecx 696 orl $PG_V|PG_KW, %eax 697 movl R(_KPTphys), %ebx 698 addl $(KSTKPTEOFF * PTESIZE), %ebx 699 fillkpt 700 701/* Map UPAGES */ 702 movl R(upa), %eax 703 movl $UPAGES, %ecx 704 movl %eax, %ebx 705 shrl $PGSHIFT-2, %ebx 706 addl R(_KPTphys), %ebx 707 orl $PG_V|PG_KW, %eax 708 fillkpt 709 710/* ... also in user page table page */ 711 movl R(upa), %eax 712 movl $UPAGES, %ecx 713 orl $PG_V|PG_KW, %eax 714 movl R(p0s), %ebx 715 addl $(KSTKPTEOFF * PTESIZE), %ebx 716 fillkpt 717 718/* and a pde entry too */ 719 movl R(p0s), %eax 720 movl R(_IdlePTD), %esi 721 orl $PG_V|PG_KW,%eax 722 movl %eax,KSTKPTDI*PDESIZE(%esi) 723 724/* Map ISA hole */ 725#define ISA_HOLE_START 0xa0000 726#define ISA_HOLE_LENGTH (0x100000-ISA_HOLE_START) 727 movl $ISA_HOLE_LENGTH>>PGSHIFT, %ecx 728 movl $ISA_HOLE_START, %eax 729 movl %eax, %ebx 730 shrl $PGSHIFT-2, %ebx 731 addl R(_KPTphys), %ebx 732 orl $PG_V|PG_KW|PG_N, %eax 733 fillkpt 734 movl $ISA_HOLE_START, %eax 735 addl $KERNBASE, %eax 736 movl %eax, R(_atdevbase) 737 738/* install a pde for temporary double map of bottom of VA */ 739 movl R(_IdlePTD), %esi 740 movl R(_KPTphys), %eax 741 orl $PG_V|PG_KW, %eax 742 movl %eax, (%esi) 743 744/* install pde's for pt's */ 745 movl R(_IdlePTD), %esi 746 movl R(_KPTphys), %eax 747 orl $PG_V|PG_KW, %eax 748 movl $(NKPT), %ecx 749 lea (KPTDI*PDESIZE)(%esi), %ebx 750 fillkpt 751 752/* install a pde recursively mapping page directory as a page table */ 753 movl R(_IdlePTD), %esi 754 movl %esi,%eax 755 orl $PG_V|PG_KW,%eax 756 movl %eax,PTDPTDI*PDESIZE(%esi) 757 758 ret 759