1/* 2 * Memory and machine-specific definitions. Used in C and assembler. 3 */ 4 5/* 6 * Sizes 7 */ 8#define BI2BY 8 /* bits per byte */ 9#define BI2WD 32 /* bits per word */ 10#define BY2WD 4 /* bytes per word */ 11#define BY2PG 4096 /* bytes per page */ 12#define WD2PG (BY2PG/BY2WD) /* words per page */ 13#define PGSHIFT 12 /* log(BY2PG) */ 14#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) 15 16#define MAXMACH 1 /* max # cpus system can run */ 17 18/* 19 * Time 20 */ 21#define HZ (20) /* clock frequency */ 22#define MS2HZ (1000/HZ) /* millisec per clock tick */ 23#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ 24#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ 25#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ 26 27/* 28 * Fundamental addresses 29 */ 30 31/* 32 * Address spaces 33 * 34 * User is at 0-2GB 35 * Kernel is at 2GB-4GB 36 * 37 * To avoid an extra page map, both the user stack (USTKTOP) and 38 * the temporary user stack (TSTKTOP) should be in the the same 39 * 4 meg. 40 */ 41#define UZERO 0 /* base of user address space */ 42#define UTZERO (UZERO+BY2PG) /* first address in user text */ 43#define KZERO 0x80000000 /* base of kernel address space */ 44#define KTZERO KZERO /* first address in kernel text */ 45#define USERADDR 0xC0000000 /* struct User */ 46#define UREGADDR (USERADDR+BY2PG-4*19) 47#define TSTKTOP USERADDR /* end of new stack in sysexec */ 48#define TSTKSIZ 10 49#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */ 50#define USTKSIZE (16*1024*1024 - TSTKSIZ*BY2PG) /* size of user stack */ 51#define ROMBIOS (KZERO|0xF0000) 52 53#define MACHSIZE 4096 54 55#define isphys(x) (((ulong)x)&KZERO) 56 57/* 58 * known 80386 segments (in GDT) and their selectors 59 */ 60#define NULLSEG 0 /* null segment */ 61#define KDSEG 1 /* kernel data/stack */ 62#define KESEG 2 /* kernel executable */ 63#define UDSEG 3 /* user data/stack */ 64#define UESEG 4 /* user executable */ 65#define TSSSEG 5 /* task segment */ 66 67#define SELGDT (0<<3) /* selector is in gdt */ 68#define SELLDT (1<<3) /* selector is in ldt */ 69 70#define SELECTOR(i, t, p) (((i)<<3) | (t) | (p)) 71 72#define NULLSEL SELECTOR(NULLSEG, SELGDT, 0) 73#define KESEL SELECTOR(KESEG, SELGDT, 0) 74#define KDSEL SELECTOR(KDSEG, SELGDT, 0) 75#define UESEL SELECTOR(UESEG, SELGDT, 3) 76#define UDSEL SELECTOR(UDSEG, SELGDT, 3) 77#define TSSSEL SELECTOR(TSSSEG, SELGDT, 0) 78 79/* 80 * fields in segment descriptors 81 */ 82#define SEGDATA (0x10<<8) /* data/stack segment */ 83#define SEGEXEC (0x18<<8) /* executable segment */ 84#define SEGTSS (0x9<<8) /* TSS segment */ 85#define SEGCG (0x0C<<8) /* call gate */ 86#define SEGIG (0x0E<<8) /* interrupt gate */ 87#define SEGTG (0x0F<<8) /* task gate */ 88#define SEGTYPE (0x1F<<8) 89 90#define SEGP (1<<15) /* segment present */ 91#define SEGPL(x) ((x)<<13) /* priority level */ 92#define SEGB (1<<22) /* granularity 1==4k (for expand-down) */ 93#define SEGG (1<<23) /* granularity 1==4k (for other) */ 94#define SEGE (1<<10) /* expand down */ 95#define SEGW (1<<9) /* writable (for data/stack) */ 96#define SEGR (1<<9) /* readable (for code) */ 97#define SEGD (1<<22) /* default 1==32bit (for code) */ 98 99/* 100 * virtual MMU 101 */ 102#define PTEMAPMEM (1024*1024) /* ??? */ 103#define SEGMAPSIZE 16 /* ??? */ 104#define PTEPERTAB (PTEMAPMEM/BY2PG) /* ??? */ 105#define PPN(x) ((x)&~(BY2PG-1)) 106 107/* 108 * physical MMU 109 */ 110#define PTEVALID (1<<0) 111#define PTEUNCACHED 0 /* everything is uncached */ 112#define PTEWRITE (1<<1) 113#define PTERONLY (0<<1) 114#define PTEKERNEL (0<<2) 115#define PTEUSER (1<<2) 116 117/* 118 * flag register bits that we care about 119 */ 120#define IFLAG 0x200 121 122#define OP16 BYTE $0x66 123 124/* 125 * about to walk all over ms/dos - turn off interrupts 126 */ 127TEXT origin(SB),$0 128 129 CLI 130 131#ifdef BOOT 132/* 133 * This part of l.s is used only in the boot kernel. 134 * It assumes that we are in real address mode, i.e., 135 * that we look like an 8086. 136 */ 137/* 138 * relocate everything to a half meg and jump there 139 * - looks wierd because it is being assembled by a 32 bit 140 * assembler for a 16 bit world 141 */ 142 MOVL $0,BX 143 INCL BX 144 SHLL $15,BX 145 MOVL BX,CX 146 MOVW BX,ES 147 MOVL $0,SI 148 MOVL SI,DI 149 CLD; REP; MOVSL 150/* JMPFAR 0X8000:$lowcore(SB) /**/ 151 BYTE $0xEA 152 WORD $lowcore(SB) 153 WORD $0X8000 154 155TEXT lowcore(SB),$0 156 157/* 158 * now that we're in low core, update the DS 159 */ 160 161 MOVW BX,DS 162 163/* 164 * goto protected mode 165 */ 166/* MOVL tgdtptr(SB),GDTR /**/ 167 BYTE $0x0f 168 BYTE $0x01 169 BYTE $0x16 170 WORD $tgdtptr(SB) 171 MOVL CR0,AX 172 ORL $1,AX 173 MOVL AX,CR0 174 175/* 176 * clear prefetch queue (wierd code to avoid optimizations) 177 */ 178 CLC 179 JCC flush 180 MOVL AX,AX 181flush: 182 183/* 184 * set all segs 185 */ 186/* MOVW $SELECTOR(1, SELGDT, 0),AX /**/ 187 BYTE $0xc7 188 BYTE $0xc0 189 WORD $SELECTOR(1, SELGDT, 0) 190 MOVW AX,DS 191 MOVW AX,SS 192 MOVW AX,ES 193 MOVW AX,FS 194 MOVW AX,GS 195 196/* JMPFAR SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/ 197 BYTE $0x66 198 BYTE $0xEA 199 LONG $mode32bit-KZERO(SB) 200 WORD $SELECTOR(2, SELGDT, 0) 201 202TEXT mode32bit(SB),$0 203 204#endif BOOT 205 206 /* 207 * Clear BSS 208 */ 209 LEAL edata-KZERO(SB),SI 210 MOVL SI,DI 211 ADDL $4,DI 212 MOVL $0,AX 213 MOVL AX,(SI) 214 LEAL end-KZERO(SB),CX 215 SUBL DI,CX 216 SHRL $2,CX 217 CLD; REP; MOVSL 218 219 /* 220 * make a bottom level page table page that maps the first 221 * 16 meg of physical memory 222 */ 223 LEAL tpt-KZERO(SB),AX /* get phys addr of temporary page table */ 224 ADDL $(BY2PG-1),AX /* must be page aligned */ 225 ANDL $(~(BY2PG-1)),AX /* ... */ 226 MOVL $(4*1024),CX /* pte's per page */ 227 MOVL $((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX 228setpte: 229 MOVL BX,-4(AX)(CX*4) 230 SUBL $(1<<PGSHIFT),BX 231 LOOP setpte 232 233 /* 234 * make a top level page table page that maps the first 235 * 16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg 236 */ 237 MOVL AX,BX 238 ADDL $(4*BY2PG),AX 239 ADDL $(PTEVALID|PTEKERNEL|PTEWRITE),BX 240 MOVL BX,0(AX) 241 MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX) 242 ADDL $BY2PG,BX 243 MOVL BX,4(AX) 244 MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX) 245 ADDL $BY2PG,BX 246 MOVL BX,8(AX) 247 MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX) 248 ADDL $BY2PG,BX 249 MOVL BX,12(AX) 250 MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX) 251 252 /* 253 * point processor to top level page & turn on paging 254 */ 255 MOVL AX,CR3 256 MOVL CR0,AX 257 ORL $0X80000000,AX 258 ANDL $~(0x8|0x2),AX /* TS=0, MP=0 */ 259 MOVL AX,CR0 260 261 /* 262 * use a jump to an absolute location to get the PC into 263 * KZERO. 264 */ 265 LEAL tokzero(SB),AX 266 JMP* AX 267 268TEXT tokzero(SB),$0 269 270 /* 271 * stack and mach 272 */ 273 MOVL $mach0(SB),SP 274 MOVL SP,m(SB) 275 MOVL $0,0(SP) 276 ADDL $(MACHSIZE-4),SP /* start stack under machine struct */ 277 MOVL $0, u(SB) 278 279 /* 280 * clear flags 281 */ 282 MOVL $0,AX 283 PUSHL AX 284 POPFL 285 286 CALL main(SB) 287 288loop: 289 JMP loop 290 291GLOBL mach0+0(SB), $MACHSIZE 292GLOBL u(SB), $4 293GLOBL m(SB), $4 294GLOBL tpt(SB), $(BY2PG*6) 295 296/* 297 * gdt to get us to 32-bit/segmented/unpaged mode 298 */ 299TEXT tgdt(SB),$0 300 301 /* null descriptor */ 302 LONG $0 303 LONG $0 304 305 /* data segment descriptor for 4 gigabytes (PL 0) */ 306 LONG $(0xFFFF) 307 LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW) 308 309 /* exec segment descriptor for 4 gigabytes (PL 0) */ 310 LONG $(0xFFFF) 311 LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR) 312 313/* 314 * pointer to initial gdt 315 */ 316TEXT tgdtptr(SB),$0 317 318 WORD $(3*8) 319 LONG $tgdt-KZERO(SB) 320 321/* 322 * input a byte 323 */ 324TEXT inb(SB),$0 325 326 MOVL p+0(FP),DX 327 XORL AX,AX 328 INB 329 RET 330 331/* 332 * output a byte 333 */ 334TEXT outb(SB),$0 335 336 MOVL p+0(FP),DX 337 MOVL b+4(FP),AX 338 OUTB 339 RET 340 341/* 342 * input a string of shorts from a port 343 */ 344TEXT inss(SB),$0 345 MOVL p+0(FP),DX 346 MOVL a+4(FP),DI 347 MOVL c+8(FP),CX 348 CLD; REP; OP16; INSL 349 RET 350 351/* 352 * output a string of shorts to a port 353 */ 354TEXT outss(SB),$0 355 MOVL p+0(FP),DX 356 MOVL a+4(FP),SI 357 MOVL c+8(FP),CX 358 CLD; REP; OP16; OUTSL 359 RET 360 361/* 362 * test and set 363 */ 364TEXT tas(SB),$0 365 MOVL $0xdeadead,AX 366 MOVL l+0(FP),BX 367 XCHGL AX,(BX) 368 RET 369 370/* 371 * routines to load/read various system registers 372 */ 373GLOBL idtptr(SB),$6 374TEXT putidt(SB),$0 /* interrupt descriptor table */ 375 MOVL t+0(FP),AX 376 MOVL AX,idtptr+2(SB) 377 MOVL l+4(FP),AX 378 MOVW AX,idtptr(SB) 379 MOVL idtptr(SB),IDTR 380 RET 381 382GLOBL gdtptr(SB),$6 383TEXT putgdt(SB),$0 /* global descriptor table */ 384 MOVL t+0(FP),AX 385 MOVL AX,gdtptr+2(SB) 386 MOVL l+4(FP),AX 387 MOVW AX,gdtptr(SB) 388 MOVL gdtptr(SB),GDTR 389 RET 390 391TEXT putcr3(SB),$0 /* top level page table pointer */ 392 MOVL t+0(FP),AX 393 MOVL AX,CR3 394 RET 395 396TEXT puttr(SB),$0 /* task register */ 397 MOVL t+0(FP),AX 398 MOVW AX,TASK 399 RET 400 401TEXT getcr0(SB),$0 /* coprocessor bits */ 402 MOVL CR0,AX 403 RET 404 405TEXT getcr2(SB),$0 /* fault address */ 406 MOVL CR2,AX 407 RET 408 409#define FPOFF\ 410 WAIT;\ 411 MOVL CR0,AX;\ 412 ORL $0x4,AX /* EM=1 */;\ 413 MOVL AX,CR0 414 415#define FPON\ 416 MOVL CR0,AX;\ 417 ANDL $~0x4,AX /* EM=0 */;\ 418 MOVL AX,CR0 419 420TEXT fpoff(SB),$0 /* turn off floating point */ 421 FPOFF 422 RET 423 424TEXT fpinit(SB),$0 /* turn on & init the floating point */ 425 FPON 426 FINIT 427 WAIT 428 PUSHW $0x0330 429 FLDCW 0(SP) /* ignore underflow/precision, signal others */ 430 POPW AX 431 WAIT 432 RET 433 434TEXT fpsave(SB),$0 /* save floating point state and turn off */ 435 MOVL p+0(FP),AX 436 WAIT 437 FSAVE 0(AX) 438 FPOFF 439 RET 440 441TEXT fprestore(SB),$0 /* turn on floating point and restore regs */ 442 FPON 443 MOVL p+0(FP),AX 444 FRSTOR 0(AX) 445 WAIT 446 RET 447 448TEXT fpstatus(SB),$0 /* get floating point status */ 449 FSTSW AX 450 RET 451 452/* 453 * special traps 454 */ 455TEXT intr0(SB),$0 456 PUSHL $0 457 PUSHL $0 458 JMP intrcommon 459TEXT intr1(SB),$0 460 PUSHL $0 461 PUSHL $1 462 JMP intrcommon 463TEXT intr2(SB),$0 464 PUSHL $0 465 PUSHL $2 466 JMP intrcommon 467TEXT intr3(SB),$0 468 PUSHL $0 469 PUSHL $3 470 JMP intrcommon 471TEXT intr4(SB),$0 472 PUSHL $0 473 PUSHL $4 474 JMP intrcommon 475TEXT intr5(SB),$0 476 PUSHL $0 477 PUSHL $5 478 JMP intrcommon 479TEXT intr6(SB),$0 480 PUSHL $0 481 PUSHL $6 482 JMP intrcommon 483TEXT intr7(SB),$0 484 PUSHL $0 485 PUSHL $7 486 JMP intrcommon 487TEXT intr8(SB),$0 488 PUSHL $8 489 JMP intrscommon 490TEXT intr9(SB),$0 491 PUSHL $0 492 PUSHL $9 493 JMP intrcommon 494TEXT intr10(SB),$0 495 PUSHL $10 496 JMP intrscommon 497TEXT intr11(SB),$0 498 PUSHL $11 499 JMP intrscommon 500TEXT intr12(SB),$0 501 PUSHL $12 502 JMP intrscommon 503TEXT intr13(SB),$0 504 PUSHL $13 505 JMP intrscommon 506TEXT intr14(SB),$0 507 PUSHL $14 508 JMP intrscommon 509TEXT intr15(SB),$0 510 PUSHL $0 511 PUSHL $15 512 JMP intrcommon 513TEXT intr16(SB),$0 514 PUSHL $0 515 PUSHL $16 516 JMP intrcommon 517TEXT intr24(SB),$0 518 PUSHL $0 519 PUSHL $24 520 JMP intrcommon 521TEXT intr25(SB),$0 522 PUSHL $0 523 PUSHL $25 524 JMP intrcommon 525TEXT intr26(SB),$0 526 PUSHL $0 527 PUSHL $26 528 JMP intrcommon 529TEXT intr27(SB),$0 530 PUSHL $0 531 PUSHL $27 532 JMP intrcommon 533TEXT intr28(SB),$0 534 PUSHL $0 535 PUSHL $28 536 JMP intrcommon 537TEXT intr29(SB),$0 538 PUSHL $0 539 PUSHL $29 540 JMP intrcommon 541TEXT intr30(SB),$0 542 PUSHL $0 543 PUSHL $30 544 JMP intrcommon 545TEXT intr31(SB),$0 546 PUSHL $0 547 PUSHL $31 548 JMP intrcommon 549TEXT intr32(SB),$0 550 PUSHL $0 551 PUSHL $16 552 JMP intrcommon 553TEXT intr33(SB),$0 554 PUSHL $0 555 PUSHL $33 556 JMP intrcommon 557TEXT intr34(SB),$0 558 PUSHL $0 559 PUSHL $34 560 JMP intrcommon 561TEXT intr35(SB),$0 562 PUSHL $0 563 PUSHL $35 564 JMP intrcommon 565TEXT intr36(SB),$0 566 PUSHL $0 567 PUSHL $36 568 JMP intrcommon 569TEXT intr37(SB),$0 570 PUSHL $0 571 PUSHL $37 572 JMP intrcommon 573TEXT intr38(SB),$0 574 PUSHL $0 575 PUSHL $38 576 JMP intrcommon 577TEXT intr39(SB),$0 578 PUSHL $0 579 PUSHL $39 580 JMP intrcommon 581TEXT intr64(SB),$0 582 PUSHL $0 583 PUSHL $64 584 JMP intrcommon 585TEXT intrbad(SB),$0 586 PUSHL $0 587 PUSHL $0x1ff 588 JMP intrcommon 589 590intrcommon: 591 PUSHL DS 592 PUSHL ES 593 PUSHL FS 594 PUSHL GS 595 PUSHAL 596 MOVL $(KDSEL),AX 597 MOVW AX,DS 598 MOVW AX,ES 599 LEAL 0(SP),AX 600 PUSHL AX 601 CALL trap(SB) 602 POPL AX 603 POPAL 604 POPL GS 605 POPL FS 606 POPL ES 607 POPL DS 608 ADDL $8,SP /* error code and trap type */ 609 IRETL 610 611intrscommon: 612 PUSHL DS 613 PUSHL ES 614 PUSHL FS 615 PUSHL GS 616 PUSHAL 617 MOVL $(KDSEL),AX 618 MOVW AX,DS 619 MOVW AX,ES 620 LEAL 0(SP),AX 621 PUSHL AX 622 CALL trap(SB) 623 POPL AX 624 POPAL 625 POPL GS 626 POPL FS 627 POPL ES 628 POPL DS 629 ADDL $8,SP /* error code and trap type */ 630 IRETL 631 632/* 633 * interrupt level is interrupts on or off 634 */ 635TEXT spllo(SB),$0 636 PUSHFL 637 POPL AX 638 STI 639 RET 640 641TEXT splhi(SB),$0 642 PUSHFL 643 POPL AX 644 CLI 645 RET 646 647TEXT splx(SB),$0 648 MOVL s+0(FP),AX 649 PUSHL AX 650 POPFL 651 RET 652 653/* 654 * do nothing whatsoever till interrupt happens 655 */ 656TEXT idle(SB),$0 657 HLT 658 RET 659 660/* 661 * label consists of a stack pointer and a PC 662 */ 663TEXT gotolabel(SB),$0 664 MOVL l+0(FP),AX 665 MOVL 0(AX),SP /* restore sp */ 666 MOVL 4(AX),AX /* put return pc on the stack */ 667 MOVL AX,0(SP) 668 MOVL $1,AX /* return 1 */ 669 RET 670 671TEXT setlabel(SB),$0 672 MOVL l+0(FP),AX 673 MOVL SP,0(AX) /* store sp */ 674 MOVL 0(SP),BX /* store return pc */ 675 MOVL BX,4(AX) 676 MOVL $0,AX /* return 0 */ 677 RET 678 679/* 680 * Used to get to the first process. 681 * Set up an interrupt return frame and IRET to user level. 682 */ 683TEXT touser(SB),$0 684 PUSHL $(UDSEL) /* old ss */ 685 PUSHL $(USTKTOP) /* old sp */ 686 PUSHFL /* old flags */ 687 PUSHL $(UESEL) /* old cs */ 688 PUSHL $(UTZERO+32) /* old pc */ 689 MOVL $(UDSEL),AX 690 MOVW AX,DS 691 MOVW AX,ES 692 MOVW AX,GS 693 MOVW AX,FS 694 IRETL 695 696/* 697 * set configuration register 698 */ 699TEXT config(SB),$0 700 MOVL l+0(FP),AX 701 MOVL $0x3F3,DX 702 OUTB 703 OUTB 704 RET 705