1/* 2 * Memory and machine-specific definitions. Used in C and assembler. 3 */ 4 5/* 6 * Sizes 7 */ 8 9#define BI2BY 8 /* bits per byte */ 10#define BI2WD 32 /* bits per word */ 11#define BY2WD 4 /* bytes per word */ 12#define BY2PG 4096 /* bytes per page */ 13#define WD2PG (BY2PG/BY2WD) /* words per page */ 14#define PGSHIFT 12 /* log(BY2PG) */ 15 16#define MAXMACH 4 /* max # cpus system can run */ 17 18/* 19 * Time 20 */ 21#define MS2HZ 50 /* millisec per clock tick */ 22#define TK2SEC(t) ((t)/20) /* ticks to seconds */ 23#define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */ 24#define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */ 25 26/* 27 * CP0 registers 28 */ 29 30#define INDEX 0 31#define RANDOM 1 32#define TLBPHYS 2 33#define CONTEXT 4 34#define BADVADDR 8 35#define TLBVIRT 10 36#define STATUS 12 37#define CAUSE 13 38#define EPC 14 39#define PRID 15 40 41/* 42 * M(STATUS) bits 43 */ 44#define IEC 0x00000001 45#define KUC 0x00000002 46#define IEP 0x00000004 47#define KUP 0x00000008 48#define INTMASK 0x0000ff00 49#define SW0 0x00000100 50#define SW1 0x00000200 51#define INTR0 0x00000400 52#define INTR1 0x00000800 53#define INTR2 0x00001000 54#define INTR3 0x00002000 55#define INTR4 0x00004000 56#define INTR5 0x00008000 57#define ISC 0x00010000 58#define SWC 0x00020000 59#define CU1 0x20000000 60 61/* 62 * Traps 63 */ 64 65#define UTLBMISS (KSEG0+0x00) 66#define EXCEPTION (KSEG0+0x80) 67 68/* 69 * Magic registers 70 */ 71 72#define MACH 25 /* R25 is m-> */ 73#define USER 24 /* R24 is u-> */ 74#define MPID 0xBF000000 /* long; low 3 bits identify mp bus slot */ 75#define WBFLUSH 0xBC000000 /* D-CACHE data; used for write buffer flush */ 76 77/* 78 * Fundamental addresses 79 */ 80 81#define MACHADDR 0x80014000 82#define USERADDR 0xC0000000 83#define UREGADDR (USERADDR+BY2PG-4-0xA0) 84/* 85 * MMU 86 */ 87 88#define KUSEG 0x00000000 89#define KSEG0 0x80000000 90#define KSEG1 0xA0000000 91#define KSEG2 0xC0000000 92#define KSEGM 0xE0000000 /* mask to check which seg */ 93 94#define PTEGLOBL (1<<8) 95#define PTEVALID (1<<9) 96#define PTEWRITE (1<<10) 97#define PTEPID(n) ((n)<<6) 98 99#define NTLBPID 64 /* number of pids */ 100#define NTLB 64 /* number of entries */ 101#define TLBROFF 8 /* offset of first randomly indexed entry */ 102 103/* 104 * Address spaces 105 */ 106 107#define UZERO KUSEG /* base of user address space */ 108#define UTZERO (UZERO+BY2PG) /* first address in user text */ 109#define USTKTOP KZERO /* byte just beyond user stack */ 110#define TSTKTOP (USERADDR+100*BY2PG) /* top of temporary stack */ 111#define KZERO KSEG0 /* base of kernel address space */ 112#define KTZERO (KSEG0+0x20000) /* first address in kernel text */ 113#define USTACKSIZE (4*1024*1024) /* size of user stack */ 114/* 115 * Exception codes 116 */ 117#define CINT 0 /* external interrupt */ 118#define CTLBM 1 /* TLB modification */ 119#define CTLBL 2 /* TLB miss (load or fetch) */ 120#define CTLBS 3 /* TLB miss (store) */ 121#define CADREL 4 /* address error (load or fetch) */ 122#define CADRES 5 /* address error (store) */ 123#define CBUSI 6 /* bus error (fetch) */ 124#define CBUSD 7 /* bus error (data load or store) */ 125#define CSYS 8 /* system call */ 126#define CBRK 9 /* breakpoint */ 127#define CRES 10 /* reserved instruction */ 128#define CCPU 11 /* coprocessor unusable */ 129#define COVF 12 /* arithmetic overflow */ 130#define CUNK13 13 /* undefined 13 */ 131#define CUNK14 14 /* undefined 14 */ 132#define CUNK15 15 /* undefined 15 */ 133 134#define NSEG 5 135 136#define SP R29 137 138#define PROM (KSEG1+0x1FC00000) 139#define NOOP NOR R0,R0 140#define WAIT NOOP; NOOP 141 142/* 143 * Boot first processor 144 * - why is the processor number loaded from R0 ????? 145 */ 146TEXT start(SB), $-4 147 148 MOVW $setR30(SB), R30 149 MOVW $(CU1|INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1 150 MOVW R1, M(STATUS) 151 WAIT 152 153 MOVW $(0x1C<<7), R1 154 MOVW R1, FCR31 /* permit only inexact and underflow */ 155 NOOP 156 MOVD $0.5, F26 157 SUBD F26, F26, F24 158 ADDD F26, F26, F28 159 ADDD F28, F28, F30 160 161 MOVD F24, F0 162 MOVD F24, F2 163 MOVD F24, F4 164 MOVD F24, F6 165 MOVD F24, F8 166 MOVD F24, F10 167 MOVD F24, F12 168 MOVD F24, F14 169 MOVD F24, F16 170 MOVD F24, F18 171 MOVD F24, F20 172 MOVD F24, F22 173 174 MOVW $MACHADDR, R(MACH) 175 ADDU $(BY2PG-4), R(MACH), SP 176 MOVW $0, R(USER) 177 MOVW R0, 0(R(MACH)) 178 179 MOVW $edata(SB), R1 180 MOVW $end(SB), R2 181 182clrbss: 183 MOVB $0, (R1) 184 ADDU $1, R1 185 BNE R1, R2, clrbss 186 187 MOVW R4, _argc(SB) 188 MOVW R5, _argv(SB) 189 MOVW R6, _env(SB) 190 JAL main(SB) 191 JMP (R0) 192 193/* 194 * Take first processor into user mode 195 * - argument is stack pointer to user 196 */ 197 198TEXT touser(SB), $-4 199 200 MOVW M(STATUS), R1 201 OR $(KUP|IEP), R1 202 MOVW R1, M(STATUS) 203 NOOP 204 MOVW 0(FP), SP 205 MOVW $(UTZERO+32), R26 /* header appears in text */ 206 RFE (R26) 207 208/* 209 * Bring subsequent processors on line 210 */ 211TEXT newstart(SB), $0 212 213 MOVW $setR30(SB), R30 214 MOVW $(INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1 215 MOVW R1, M(STATUS) 216 NOOP 217 MOVW $MACHADDR, R(MACH) 218 MOVB (MPID+3), R1 219 AND $7, R1 220 SLL $PGSHIFT, R1, R2 221 ADDU R2, R(MACH) 222 ADDU $(BY2PG-4), R(MACH), SP 223 MOVW $0, R(USER) 224 MOVW R1, 0(R(MACH)) 225 JAL online(SB) 226 JMP (R0) 227 228TEXT firmware(SB), $0 229 230 MOVW $(PROM+0x18), R1 /**/ 231/* MOVW $(PROM+0x00), R1 /**/ 232 JMP (R1) 233 234TEXT splhi(SB), $0 235 236 MOVW M(STATUS), R1 237 AND $~IEC, R1, R2 238 MOVW R2, M(STATUS) 239 NOOP 240 RET 241 242TEXT spllo(SB), $0 243 244 MOVW M(STATUS), R1 245 OR $IEC, R1, R2 246 MOVW R2, M(STATUS) 247 NOOP 248 RET 249 250TEXT splx(SB), $0 251 252 MOVW 0(FP), R1 253 MOVW M(STATUS), R2 254 AND $IEC, R1 255 AND $~IEC, R2 256 OR R2, R1 257 MOVW R1, M(STATUS) 258 NOOP 259 RET 260 261TEXT wbflush(SB), $-4 262 263 MOVW $WBFLUSH, R1 264 MOVW 0(R1), R1 265 RET 266 267TEXT setlabel(SB), $0 268 269 MOVW 0(FP), R2 270 MOVW $0, R1 271 MOVW R31, 0(R2) 272 MOVW R29, 4(R2) 273 RET 274 275TEXT gotolabel(SB), $0 276 277 MOVW 0(FP), R2 278 MOVW $1, R1 279 MOVW 0(R2), R31 280 MOVW 4(R2), R29 281 RET 282 283TEXT gotopc(SB), $8 284 285 MOVW 0(FP), R7 /* save arguments for later */ 286 MOVW _argc(SB), R4 287 MOVW _argv(SB), R5 288 MOVW _env(SB), R6 289 MOVW R0, 4(SP) 290 MOVW $(64*1024), R1 291 MOVW R1, 8(SP) 292 JAL icflush(SB) 293 JMP (R7) 294 295TEXT puttlb(SB), $4 296 297 JAL splhi(SB) 298 MOVW 0(FP), R2 299 MOVW 4(FP), R3 300 MOVW R1, 4(SP) 301 MOVW R2, M(TLBVIRT) 302 MOVW R3, M(TLBPHYS) 303 NOOP 304 TLBP 305 NOOP 306 MOVW M(INDEX), R4 307 BGEZ R4, index 308 TLBWR 309 NOOP 310 JAL splx(SB) 311 RET 312index: 313 TLBWI 314 NOOP 315 JAL splx(SB) 316 RET 317 318TEXT puttlbx(SB), $0 319 320 MOVW 0(FP), R4 321 MOVW 4(FP), R2 322 MOVW 8(FP), R3 323 SLL $8, R4 324 MOVW R2, M(TLBVIRT) 325 MOVW R3, M(TLBPHYS) 326 MOVW R4, M(INDEX) 327 NOOP 328 TLBWI 329 NOOP 330 RET 331 332TEXT tlbp(SB), $0 333 TLBP 334 NOOP 335 MOVW M(INDEX), R1 336 RET 337 338TEXT tlbvirt(SB), $0 339 TLBP 340 NOOP 341 MOVW M(TLBVIRT), R1 342 RET 343 344 345TEXT gettlb(SB), $0 346 347 MOVW 0(FP), R3 348 MOVW 4(FP), R4 349 SLL $8, R3 350 MOVW R3, M(INDEX) 351 NOOP 352 TLBR 353 NOOP 354 MOVW M(TLBVIRT), R1 355 MOVW M(TLBPHYS), R2 356 NOOP 357 MOVW R1, 0(R4) 358 MOVW R2, 4(R4) 359 RET 360 361TEXT gettlbvirt(SB), $0 362 363 MOVW 0(FP), R3 364 SLL $8, R3 365 MOVW R3, M(INDEX) 366 NOOP 367 TLBR 368 NOOP 369 MOVW M(TLBVIRT), R1 370 NOOP 371 RET 372 373TEXT vector80(SB), $-4 374 375 MOVW $exception(SB), R26 376 JMP (R26) 377 378TEXT exception(SB), $-4 379 380 MOVW M(STATUS), R26 381 AND $KUP, R26 382 BEQ R26, waskernel 383 384wasuser: 385 MOVW SP, R26 386 /* 387 * set kernel sp: ureg - ureg* - pc 388 * done in 2 steps because R30 is not set 389 * and the loader will make a literal 390 */ 391 MOVW $((UREGADDR-2*BY2WD) & 0xffff0000), SP 392 OR $((UREGADDR-2*BY2WD) & 0xffff), SP 393 MOVW R26, 0x10(SP) /* user SP */ 394 MOVW R31, 0x28(SP) 395 MOVW R30, 0x2C(SP) 396 MOVW M(CAUSE), R26 397 MOVW R(MACH), 0x3C(SP) 398 MOVW R(USER), 0x40(SP) 399 AND $(0xF<<2), R26 400 SUB $(CSYS<<2), R26 401 402 JAL saveregs(SB) 403 404 MOVW $setR30(SB), R30 405 SUBU $(UREGADDR-2*BY2WD-USERADDR), SP, R(USER) 406 MOVW $MPID, R1 407 MOVB 3(R1), R1 408 MOVW $MACHADDR, R(MACH) /* locn of mach 0 */ 409 AND $7, R1 410 SLL $PGSHIFT, R1 411 ADDU R1, R(MACH) /* add offset for mach # */ 412 413 BNE R26, notsys 414 415 JAL syscall(SB) 416 417 MOVW 0x28(SP), R31 418 MOVW 0x08(SP), R26 419 MOVW 0x2C(SP), R30 420 MOVW R26, M(STATUS) 421 NOOP 422 MOVW 0x0C(SP), R26 /* old pc */ 423 MOVW 0x10(SP), SP 424 RFE (R26) 425 426notsys: 427 JAL trap(SB) 428 429restore: 430 JAL restregs(SB) 431 MOVW 0x28(SP), R31 432 MOVW 0x2C(SP), R30 433 MOVW 0x3C(SP), R(MACH) 434 MOVW 0x40(SP), R(USER) 435 MOVW 0x10(SP), SP 436 RFE (R26) 437 438waskernel: 439 MOVW $1, R26 /* not sys call */ 440 MOVW SP, -0x90(SP) /* drop this if possible */ 441 SUB $0xA0, SP 442 MOVW R31, 0x28(SP) 443 JAL saveregs(SB) 444 JAL trap(SB) 445 JAL restregs(SB) 446 MOVW 0x28(SP), R31 447 ADD $0xA0, SP 448 RFE (R26) 449 450TEXT saveregs(SB), $-4 451 MOVW R1, 0x9C(SP) 452 MOVW R2, 0x98(SP) 453 ADDU $8, SP, R1 454 MOVW R1, 0x04(SP) /* arg to base of regs */ 455 MOVW M(STATUS), R1 456 MOVW M(EPC), R2 457 MOVW R1, 0x08(SP) 458 MOVW R2, 0x0C(SP) 459 460 BEQ R26, return /* sys call, don't save */ 461 462 MOVW M(CAUSE), R1 463 MOVW M(BADVADDR), R2 464 MOVW R1, 0x14(SP) 465 MOVW M(TLBVIRT), R1 466 MOVW R2, 0x18(SP) 467 MOVW R1, 0x1C(SP) 468 MOVW HI, R1 469 MOVW LO, R2 470 MOVW R1, 0x20(SP) 471 MOVW R2, 0x24(SP) 472 /* LINK,SB,SP missing */ 473 MOVW R28, 0x30(SP) 474 /* R27, R26 not saved */ 475 /* R25, R24 missing */ 476 MOVW R23, 0x44(SP) 477 MOVW R22, 0x48(SP) 478 MOVW R21, 0x4C(SP) 479 MOVW R20, 0x50(SP) 480 MOVW R19, 0x54(SP) 481 MOVW R18, 0x58(SP) 482 MOVW R17, 0x5C(SP) 483 MOVW R16, 0x60(SP) 484 MOVW R15, 0x64(SP) 485 MOVW R14, 0x68(SP) 486 MOVW R13, 0x6C(SP) 487 MOVW R12, 0x70(SP) 488 MOVW R11, 0x74(SP) 489 MOVW R10, 0x78(SP) 490 MOVW R9, 0x7C(SP) 491 MOVW R8, 0x80(SP) 492 MOVW R7, 0x84(SP) 493 MOVW R6, 0x88(SP) 494 MOVW R5, 0x8C(SP) 495 MOVW R4, 0x90(SP) 496 MOVW R3, 0x94(SP) 497return: 498 RET 499 500TEXT restregs(SB), $-4 501 /* LINK,SB,SP missing */ 502 MOVW 0x30(SP), R28 503 /* R27, R26 not saved */ 504 /* R25, R24 missing */ 505 MOVW 0x44(SP), R23 506 MOVW 0x48(SP), R22 507 MOVW 0x4C(SP), R21 508 MOVW 0x50(SP), R20 509 MOVW 0x54(SP), R19 510 MOVW 0x58(SP), R18 511 MOVW 0x5C(SP), R17 512 MOVW 0x60(SP), R16 513 MOVW 0x64(SP), R15 514 MOVW 0x68(SP), R14 515 MOVW 0x6C(SP), R13 516 MOVW 0x70(SP), R12 517 MOVW 0x74(SP), R11 518 MOVW 0x78(SP), R10 519 MOVW 0x7C(SP), R9 520 MOVW 0x80(SP), R8 521 MOVW 0x84(SP), R7 522 MOVW 0x88(SP), R6 523 MOVW 0x8C(SP), R5 524 MOVW 0x90(SP), R4 525 MOVW 0x94(SP), R3 526 MOVW 0x24(SP), R2 527 MOVW 0x20(SP), R1 528 MOVW R2, LO 529 MOVW R1, HI 530 MOVW 0x08(SP), R1 531 MOVW 0x98(SP), R2 532 MOVW R1, M(STATUS) 533 NOOP 534 MOVW 0x9C(SP), R1 535 MOVW 0x0C(SP), R26 /* old pc */ 536 RET 537 538TEXT rfnote(SB), $0 539 MOVW 0(FP), R26 /* 1st arg is &uregpointer */ 540 SUBU $(BY2WD), R26, SP /* pc hole */ 541 BNE R26, restore 542 543 544TEXT clrfpintr(SB), $0 545 MOVW FCR31, R1 546 MOVW R1, R2 547 AND $~(0x3F<<12), R2 548 MOVW R2, FCR31 549 RET 550 551TEXT savefpregs(SB), $0 552 MOVW M(STATUS), R3 553 MOVW 0(FP), R1 554 MOVW FCR31, R2 555 556 MOVD F0, 0x00(R1) 557 MOVD F2, 0x08(R1) 558 MOVD F4, 0x10(R1) 559 MOVD F6, 0x18(R1) 560 MOVD F8, 0x20(R1) 561 MOVD F10, 0x28(R1) 562 MOVD F12, 0x30(R1) 563 MOVD F14, 0x38(R1) 564 MOVD F16, 0x40(R1) 565 MOVD F18, 0x48(R1) 566 MOVD F20, 0x50(R1) 567 MOVD F22, 0x58(R1) 568 MOVD F24, 0x60(R1) 569 MOVD F26, 0x68(R1) 570 MOVD F28, 0x70(R1) 571 MOVD F30, 0x78(R1) 572 573 MOVW R2, 0x80(R1) 574 AND $~CU1, R3 575 MOVW R3, M(STATUS) 576 RET 577 578TEXT restfpregs(SB), $0 579 580 MOVW M(STATUS), R3 581 MOVW 0(FP), R1 582 OR $CU1, R3 583 MOVW R3, M(STATUS) 584 MOVW 0x80(R1), R2 585 586 MOVD 0x00(R1), F0 587 MOVD 0x08(R1), F2 588 MOVD 0x10(R1), F4 589 MOVD 0x18(R1), F6 590 MOVD 0x20(R1), F8 591 MOVD 0x28(R1), F10 592 MOVD 0x30(R1), F12 593 MOVD 0x38(R1), F14 594 MOVD 0x40(R1), F16 595 MOVD 0x48(R1), F18 596 MOVD 0x50(R1), F20 597 MOVD 0x58(R1), F22 598 MOVD 0x60(R1), F24 599 MOVD 0x68(R1), F26 600 MOVD 0x70(R1), F28 601 MOVD 0x78(R1), F30 602 603 MOVW R2, FCR31 604 AND $~CU1, R3 605 MOVW R3, M(STATUS) 606 RET 607 608/* 609 * we avoid using R4, R5, R6, and R7 so gotopc can call us without saving them 610 */ 611TEXT icflush(SB), $-4 /* icflush(physaddr, nbytes) */ 612 613 MOVW M(STATUS), R10 614 MOVW 0(FP), R8 615 MOVW 4(FP), R9 616 MOVW $KSEG0, R3 617 OR R3, R8 618 MOVW $0, M(STATUS) 619 MOVW $WBFLUSH, R1 /* wbflush */ 620 MOVW 0(R1), R1 621 NOOP 622 MOVW $KSEG1, R3 623 MOVW $icflush0(SB), R2 /* make sure PC is in uncached address space */ 624 MOVW $(SWC|ISC), R1 625 OR R3, R2 626 JMP (R2) 627 628TEXT icflush0(SB), $-4 629 630 MOVW R1, M(STATUS) /* swap and isolate cache, splhi */ 631 MOVW $icflush1(SB), R2 632 JMP (R2) 633 634TEXT icflush1(SB), $-4 635 636_icflush1: 637 MOVBU R0, 0x00(R8) 638 MOVBU R0, 0x04(R8) 639 MOVBU R0, 0x08(R8) 640 MOVBU R0, 0x0C(R8) 641 MOVBU R0, 0x10(R8) 642 MOVBU R0, 0x14(R8) 643 MOVBU R0, 0x18(R8) 644 MOVBU R0, 0x1C(R8) 645 MOVBU R0, 0x20(R8) 646 MOVBU R0, 0x24(R8) 647 MOVBU R0, 0x28(R8) 648 MOVBU R0, 0x2C(R8) 649 MOVBU R0, 0x30(R8) 650 MOVBU R0, 0x34(R8) 651 MOVBU R0, 0x38(R8) 652 MOVBU R0, 0x3C(R8) 653 SUB $0x40, R9 654 ADD $0x40, R8 655 BGTZ R9, _icflush1 656 MOVW $icflush2(SB), R2 /* make sure PC is in uncached address space */ 657 OR R3, R2 658 JMP (R2) 659 660TEXT icflush2(SB), $-4 661 662 MOVW $0, M(STATUS) /* swap back caches, de-isolate them, and stay splhi */ 663 NOOP /* +++ */ 664 MOVW R10, M(STATUS) 665 RET 666 667TEXT dcflush(SB), $-4 /* dcflush(physaddr, nbytes) */ 668 669 MOVW M(STATUS), R6 670 MOVW 0(FP), R4 671 MOVW 4(FP), R5 672 MOVW $KSEG0, R3 673 OR R3, R4 674 MOVW $0, M(STATUS) 675 MOVW $WBFLUSH, R1 676 MOVW 0(R1), R1 677 NOOP 678 MOVW $ISC, R1 679 MOVW R1, M(STATUS) 680_dcflush0: 681 MOVBU R0, 0x00(R4) 682 MOVBU R0, 0x04(R4) 683 MOVBU R0, 0x08(R4) 684 MOVBU R0, 0x0C(R4) 685 MOVBU R0, 0x10(R4) 686 MOVBU R0, 0x14(R4) 687 MOVBU R0, 0x18(R4) 688 MOVBU R0, 0x1C(R4) 689 MOVBU R0, 0x20(R4) 690 MOVBU R0, 0x24(R4) 691 MOVBU R0, 0x28(R4) 692 MOVBU R0, 0x2C(R4) 693 MOVBU R0, 0x30(R4) 694 MOVBU R0, 0x34(R4) 695 MOVBU R0, 0x38(R4) 696 MOVBU R0, 0x3C(R4) 697 SUB $0x40, R5 698 ADD $0x40, R4 699 BGTZ R5, _dcflush0 700 MOVW $0, M(STATUS) 701 NOOP /* +++ */ 702 MOVW R6, M(STATUS) 703 RET 704