|
|
1.1 ! root 1: /* QEMU Emulation PALcode. ! 2: ! 3: Copyright (C) 2011 Richard Henderson ! 4: ! 5: This file is part of QEMU PALcode. ! 6: ! 7: This program is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2 of the License or ! 10: (at your option) any later version. ! 11: ! 12: This program is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the text ! 15: of the GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with this program; see the file COPYING. If not see ! 19: <http://www.gnu.org/licenses/>. */ ! 20: ! 21: .set noat ! 22: .set nomacro ! 23: .text ! 24: ! 25: #include "pal.h" ! 26: #include "osf.h" ! 27: #include SYSTEM_H ! 28: ! 29: /* ! 30: * Create a standard kernel entry stack frame. ! 31: */ ! 32: ! 33: .macro STACK_FRAME save_ps, save_pc, temp, do_ps ! 34: // Test if we're currently in user mode ! 35: and \save_ps, PS_M_CM, \temp ! 36: beq \temp, 0f ! 37: // Switch to kernel mode ! 38: .ifne \do_ps ! 39: mtpr $31, qemu_ps ! 40: .endif ! 41: mtpr $sp, qemu_usp ! 42: mfpr $sp, ptKsp ! 43: // Allocate the stack frame ! 44: 0: lda $sp, -FRM_K_SIZE($sp) ! 45: stq \save_ps, FRM_Q_PS($sp) ! 46: stq \save_pc, FRM_Q_PC($sp) ! 47: stq $gp, FRM_Q_GP($sp) ! 48: stq a0, FRM_Q_A0($sp) ! 49: stq a1, FRM_Q_A1($sp) ! 50: stq a2, FRM_Q_A2($sp) ! 51: .endm ! 52: ! 53: /* ! 54: * Allocate a 1 page stack for use by the console. ! 55: */ ! 56: #define STACK_SIZE 8192 ! 57: ! 58: /* ! 59: * QEMU emulator "hardware" entry points. ! 60: */ ! 61: ! 62: /* ! 63: * Reset ! 64: * ! 65: * INPUT PARAMETERS: ! 66: * ! 67: * trap_arg0 = Memory size ! 68: * trap_arg1 = Kernel entry (if loaded) ! 69: */ ! 70: .org 0x0000 ! 71: .globl __start ! 72: __start: ! 73: // Initialize GP. ! 74: br $gp, .+4 ! 75: ldah $gp, 0($gp) !gpdisp!1 ! 76: lda $gp, 0($gp) !gpdisp!1 ! 77: mtpr $gp, ptPgp ! 78: ! 79: // Disable interrupts; kernel mode ! 80: lda t0, IPL_K_HIGH ! 81: mtpr t0, qemu_ps ! 82: ! 83: // Initialize Stack. ! 84: SYS_WHAMI a0 ! 85: lda t0, STACK_SIZE ! 86: addq a0, 1, t1 ! 87: mull t0, t1, t0 ! 88: ldah t1, stack($gp) !gprelhigh ! 89: lda t1, stack(t1) !gprellow ! 90: addq t0, t1, $sp ! 91: ! 92: // Do any necessary system setup required for PALmode, ! 93: // e.g. setting up ptSys[01]. ! 94: bsr $26, Sys_Setup ! 95: ! 96: // Non-boot CPUs can go wait now. ! 97: bne a0, 1f ! 98: ! 99: // Load boot arguments ! 100: mfpr a0, qemu_trap_arg0 ! 101: mfpr a1, qemu_trap_arg1 ! 102: mfpr a2, qemu_trap_arg2 ! 103: ! 104: // Continue in do_start, outside PALmode. ! 105: ldah $27, do_start($gp) !gprelhigh ! 106: lda $27, do_start($27) !gprellow ! 107: hw_ret ($27) ! 108: ! 109: 1: ldah $27, do_start_wait($gp) !gprelhigh ! 110: lda $27, do_start_wait($27) !gprellow ! 111: hw_ret ($27) ! 112: ENDFN __start ! 113: ! 114: /* ! 115: * Machine Check ! 116: * ! 117: * INPUT PARAMETERS: ! 118: * ! 119: * trap_arg0 = ! 120: * trap_arg1 = ! 121: * trap_arg2 = ! 122: */ ! 123: .org 0x0080 ! 124: Pal_Mchk: ! 125: halt ! 126: ENDFN Pal_Mchk ! 127: ! 128: /* ! 129: * Interprocessor Interrupt ! 130: * ! 131: * INPUT PARAMETERS: ! 132: * ! 133: * trap_arg0 = ! 134: * trap_arg1 = ! 135: * trap_arg2 = ! 136: * ! 137: * The interprocessor interrupt is special, in that PALcode is supposed ! 138: * to clear the interupt and not wait for the OS to do it. ! 139: */ ! 140: .org 0x0100 ! 141: Pal_Smp_Interrupt: ! 142: mfpr p6, qemu_exc_addr ! 143: ! 144: SYS_ACK_SMP p0, p1, p2 ! 145: ! 146: mfpr p0, qemu_ps ! 147: ! 148: STACK_FRAME p0, p6, p2, 0 ! 149: ! 150: mov IPL_K_IP, p0 // Raise IPL ! 151: mtpr p0, qemu_ps ! 152: ! 153: mfpr p6, ptEntInt ! 154: mfpr $gp, ptKgp ! 155: lda a0, INT_K_IP ! 156: lda a1, 0 ! 157: lda a2, 0 ! 158: ! 159: hw_ret (p6) ! 160: ENDFN Pal_Smp_Interrupt ! 161: ! 162: /* ! 163: * Clock Interrupt ! 164: * ! 165: * INPUT PARAMETERS: ! 166: * ! 167: * trap_arg0 = ! 168: * trap_arg1 = ! 169: * trap_arg2 = ! 170: * ! 171: * The clock interrupt is special, in that PALcode is supposed ! 172: * to clear the interupt and not wait for the OS to do it. ! 173: */ ! 174: .org 0x0180 ! 175: Pal_Clk_Interrupt: ! 176: mfpr p6, qemu_exc_addr ! 177: ! 178: SYS_ACK_CLK p0, p1, p2 ! 179: ! 180: mfpr p0, qemu_ps ! 181: ! 182: STACK_FRAME p0, p6, p2, 0 ! 183: ! 184: mov IPL_K_CLK, p0 // Raise IPL ! 185: mtpr p0, qemu_ps ! 186: ! 187: mfpr p6, ptEntInt ! 188: mfpr $gp, ptKgp ! 189: lda a0, INT_K_CLK ! 190: lda a1, 0 ! 191: lda a2, 0 ! 192: ! 193: 9: hw_ret (p6) ! 194: ENDFN Pal_Clk_Interrupt ! 195: ! 196: /* ! 197: * Device Interrupt ! 198: * ! 199: * INPUT PARAMETERS: ! 200: * ! 201: * trap_arg0 = ! 202: * trap_arg1 = ! 203: * trap_arg2 = ! 204: */ ! 205: .org 0x0200 ! 206: Pal_Dev_Interrupt: ! 207: mfpr p6, qemu_exc_addr ! 208: mfpr p0, qemu_ps ! 209: ! 210: STACK_FRAME p0, p6, p2, 0 ! 211: ! 212: mov IPL_K_DEV1, p0 // Raise IPL ! 213: mtpr p0, qemu_ps ! 214: ! 215: bsr p7, Sys_Dev_Vector ! 216: ! 217: mfpr p7, ptEntInt ! 218: mfpr $gp, ptKgp ! 219: lda a0, INT_K_DEV ! 220: lda a2, 0 ! 221: hw_ret (p7) ! 222: ENDFN Pal_Dev_Interrupt ! 223: ! 224: /* ! 225: * Memory Fault ! 226: * ! 227: * INPUT PARAMETERS: ! 228: * ! 229: * trap_arg0 = faulting address ! 230: * trap_arg1 = fault type (TNV, ACV, FOR, FOW, FOE) ! 231: * trap_arg2 = access type (exec=-1, read=0, write=1) ! 232: */ ! 233: .org 0x0280 ! 234: Pal_MMFault: ! 235: mfpr p0, qemu_ps ! 236: mfpr p6, qemu_exc_addr ! 237: blbs p6, MchkBugCheck ! 238: ! 239: STACK_FRAME p0, p6, p2, 1 ! 240: ! 241: mfpr p0, ptEntMM ! 242: mfpr $gp, ptKgp ! 243: mfpr a0, qemu_trap_arg0 ! 244: mfpr a1, qemu_trap_arg1 ! 245: mfpr a2, qemu_trap_arg2 ! 246: hw_ret (p0) ! 247: ENDFN Pal_MMFault ! 248: ! 249: /* ! 250: * Unaligned Data ! 251: * ! 252: * INPUT PARAMETERS: ! 253: * ! 254: * trap_arg0 = faulting address ! 255: * trap_arg1 = opcode of faulting insn ! 256: * trap_arg2 = src/dst register number ! 257: */ ! 258: .org 0x0300 ! 259: Pal_Unalign: ! 260: mfpr p0, qemu_ps ! 261: mfpr p6, qemu_exc_addr ! 262: addq p6, 4, p1 // increment past the faulting insn ! 263: blbs p6, MchkBugCheck ! 264: ! 265: STACK_FRAME p0, p1, p2, 1 ! 266: ! 267: mfpr p0, ptEntUna ! 268: mfpr $gp, ptKgp ! 269: mfpr a0, qemu_trap_arg0 ! 270: mfpr a1, qemu_trap_arg1 ! 271: mfpr a2, qemu_trap_arg2 ! 272: hw_ret (p0) ! 273: ENDFN Pal_Unalign ! 274: ! 275: /* ! 276: * Illegal Opcode ! 277: * ! 278: * INPUT PARAMETERS: ! 279: * ! 280: * trap_arg0 = UNDEFINED ! 281: * trap_arg1 = UNDEFINED ! 282: * trap_arg2 = UNDEFINED ! 283: * ! 284: * OUTPUT PARAMETERS: ! 285: * ! 286: * r16 (a0) = Instruction fault code ! 287: * r17 (a1) = UNPREDICTABLE ! 288: * r18 (a2) = UNPREDICTABLE ! 289: */ ! 290: .org 0x0380 ! 291: Pal_OpcDec: ! 292: mfpr p0, qemu_ps ! 293: mfpr p6, qemu_exc_addr ! 294: addq p6, 4, p1 // increment past the faulting insn ! 295: blbs p6, MchkBugCheck ! 296: ! 297: STACK_FRAME p0, p1, p2, 1 ! 298: ! 299: mfpr p0, ptEntIF ! 300: mfpr $gp, ptKgp ! 301: mov IF_K_OPCDEC, a0 ! 302: hw_ret (p0) ! 303: ENDFN Pal_OpcDec ! 304: ! 305: /* ! 306: * Arithmetic Trap ! 307: * ! 308: * INPUT PARAMETERS: ! 309: * ! 310: * trap_arg0 = exception type ! 311: * trap_arg1 = register modification mask ! 312: * trap_arg2 = UNDEFINED ! 313: */ ! 314: .org 0x0400 ! 315: Pal_Arith: ! 316: mfpr p0, qemu_ps ! 317: mfpr p6, qemu_exc_addr ! 318: blbs p6, MchkBugCheck ! 319: ! 320: STACK_FRAME p0, p6, p2, 1 ! 321: ! 322: mfpr p0, ptEntArith ! 323: mfpr $gp, ptKgp ! 324: mfpr a0, qemu_trap_arg0 ! 325: mfpr a1, qemu_trap_arg1 ! 326: hw_ret (p0) ! 327: ENDFN Pal_Arith ! 328: ! 329: /* ! 330: * Floating Point Disabled ! 331: * ! 332: * INPUT PARAMETERS: ! 333: * ! 334: * trap_arg0 = UNDEFINED ! 335: * trap_arg1 = UNDEFINED ! 336: * trap_arg2 = UNDEFINED ! 337: * ! 338: * OUTPUT PARAMETERS: ! 339: * ! 340: * r16 (a0) = Instruction fault code ! 341: * r17 (a1) = UNPREDICTABLE ! 342: * r18 (a2) = UNPREDICTABLE ! 343: */ ! 344: .org 0x0480 ! 345: Pal_Fen: ! 346: mfpr p0, qemu_ps ! 347: mfpr p6, qemu_exc_addr ! 348: blbs p6, MchkBugCheck ! 349: ! 350: STACK_FRAME p0, p6, p2, 1 ! 351: ! 352: mfpr p0, ptEntIF ! 353: mfpr $gp, ptKgp ! 354: mov IF_K_FEN, a0 ! 355: hw_ret (p0) ! 356: ENDFN Pal_Fen ! 357: ! 358: /* ! 359: * OSF/1 Privileged CALL_PAL Entry Points ! 360: */ ! 361: ! 362: #define ORG_CALL_PAL_PRIV(X) .org 0x1000+64*X ! 363: ! 364: /* ! 365: * Halt ! 366: * ! 367: * SIDE EFFECTS: ! 368: * ! 369: * We either power down the system or re-enter the console. ! 370: * But given that we're not returning to the kernel, there's ! 371: * no reason to continue processing in assembler. Go to C. ! 372: */ ! 373: ORG_CALL_PAL_PRIV(0x00) ! 374: CallPal_Halt: ! 375: bsr p7, UpdatePCB // Save kernel data ! 376: lda v0, HLT_K_SW_HALT // FIXME store this somewhere. ! 377: ! 378: mtpr $31, qemu_halt ! 379: ! 380: br Sys_EnterConsole ! 381: ENDFN CallPal_Halt ! 382: ! 383: /* ! 384: * Cache Flush ! 385: * ! 386: * For QEMU, this is of course a no-op. ! 387: */ ! 388: ORG_CALL_PAL_PRIV(0x01) ! 389: CallPal_Cflush: ! 390: hw_rei ! 391: ENDFN CallPal_Cflush ! 392: ! 393: /* ! 394: * Drain Aborts ! 395: * ! 396: * For QEMU, this is of course a no-op. ! 397: */ ! 398: ORG_CALL_PAL_PRIV(0x02) ! 399: CallPal_Draina: ! 400: hw_rei ! 401: ENDFN CallPal_Draina ! 402: ! 403: ORG_CALL_PAL_PRIV(0x03) ! 404: CallPal_OpcDec03: ! 405: br CallPal_OpcDec ! 406: ENDFN CallPal_OpcDec03 ! 407: ! 408: ORG_CALL_PAL_PRIV(0x04) ! 409: CallPal_OpcDec04: ! 410: br CallPal_OpcDec ! 411: ENDFN CallPal_OpcDec04 ! 412: ! 413: ORG_CALL_PAL_PRIV(0x05) ! 414: CallPal_OpcDec05: ! 415: br CallPal_OpcDec ! 416: ENDFN CallPal_OpcDec05 ! 417: ! 418: ORG_CALL_PAL_PRIV(0x06) ! 419: CallPal_OpcDec06: ! 420: br CallPal_OpcDec ! 421: ENDFN CallPal_OpcDec06 ! 422: ! 423: ORG_CALL_PAL_PRIV(0x07) ! 424: CallPal_OpcDec07: ! 425: br CallPal_OpcDec ! 426: ENDFN CallPal_OpcDec07 ! 427: ! 428: ORG_CALL_PAL_PRIV(0x08) ! 429: CallPal_OpcDec08: ! 430: br CallPal_OpcDec ! 431: ENDFN CallPal_OpcDec08 ! 432: ! 433: /* ! 434: * Console Service ! 435: * ! 436: * INPUT PARAMETERS: ! 437: * ! 438: * r16 (a0) = Option selector ! 439: * r17..r21 (a1..a5) = Implementation specific entry parameters ! 440: * ! 441: * SIDE EFFECTS: ! 442: * ! 443: * Registers a0..a5, and v0 are UNPREDICTABLE upon return. ! 444: */ ! 445: ORG_CALL_PAL_PRIV(0x09) ! 446: CallPal_Cserve: ! 447: // Most of the entries are densely clustered around 0. ! 448: mov 0, v0 ! 449: cmpule a0, 6, p0 ! 450: cmovne p0, a0, v0 ! 451: br p0, 1f ! 452: 1: lda p0, Cserve_Table-1b(p0) ! 453: s8addq v0, p0, p0 ! 454: jmp $31, (p0), 0 ! 455: ENDFN CallPal_Cserve ! 456: ! 457: .text 1 ! 458: .align 3 ! 459: /* Note that the entries in the following table are all 2 insns. ! 460: The first entry is unused, and is also where all out-of-range ! 461: commands are vectored. */ ! 462: Cserve_Table: ! 463: br CallPal_Cserve_Cont ! 464: nop ! 465: Cserve_Ldqp: ! 466: ldq_p v0, 0(a1) ! 467: hw_rei ! 468: ENDFN Cserve_Ldqp ! 469: Cserve_Stqp: ! 470: stq_p a2, 0(a1) ! 471: hw_rei ! 472: ENDFN Cserve_Stqp ! 473: Cserve_Get_Wall_Time: ! 474: mfpr v0, qemu_walltime ! 475: hw_rei ! 476: ENDFN Cserve_Get_Wall_Time ! 477: Cserve_Get_Alarm: ! 478: mfpr v0, qemu_alarm ! 479: hw_rei ! 480: ENDFN Cserve_Get_Alarm ! 481: Cserve_Set_Alarm_Rel: ! 482: // Cheating here: create the absolute time and fall thru. ! 483: mfpr p0, qemu_walltime ! 484: addq p0, a1, a1 ! 485: ENDFN Cserve_Set_Alarm_Rel ! 486: Cserve_Set_Alarm_Abs: ! 487: mtpr a1, qemu_alarm ! 488: hw_rei ! 489: ENDFN Cserve_Set_Alarm_Abs ! 490: ! 491: CallPal_Cserve_Cont: ! 492: // ??? For SRM compatibility and their use within Linux, use 52/53 ! 493: // for these. Anyone know what other "standard" SRM Cserve entry ! 494: // points are? Certainly we don't want to be compatible with MILO, ! 495: // which puts the selector at A2. ! 496: cmpeq a0, 52, v0 ! 497: bne v0, Cserve_Ena ! 498: cmpeq a0, 53, v0 ! 499: bne v0, Cserve_Dis ! 500: hw_rei ! 501: ENDFN CallPal_Cserve_Cont ! 502: .previous ! 503: ! 504: /* ! 505: * Swap PALcode ! 506: * ! 507: * FUNCTIONAL DESCRIPTION: ! 508: * ! 509: * The swap PALcode (swppal) function replaces the current ! 510: * (active) PALcode by the specified new PALcode image. ! 511: * This function is intended for use by operating systems ! 512: * only during bootstraps and restarts, or during transitions ! 513: * to console I/O mode. ! 514: * ! 515: * The PALcode descriptor passed in a0 is interpreted as ! 516: * either a PALcode variant or the base physical address ! 517: * of the new PALcode image. If a variant, the PALcode ! 518: * image must have been previously loaded. No PALcode ! 519: * loading occurs as a result of this function. ! 520: * ! 521: * NOTE: ! 522: * This implementation of SWPPAL does not support PALcode ! 523: * variants. If a variant is specified in a0, a check is ! 524: * performed to determine whether the variant is OSF/1 or ! 525: * not and the returned status is either unknown variant ! 526: * (if not OSF/1) or variant not loaded. ! 527: * ! 528: * INPUT PARAMETERS: ! 529: * ! 530: * r16 (a0) = New PALcode variant or base physical address ! 531: * r17 (a1) = New PC ! 532: * r18 (a2) = New PCB ! 533: * r19 (a3) = New VptPtr ! 534: * ! 535: * OUTPUT PARAMETERS: ! 536: * ! 537: * r0 (v0) = Returned status indicating: ! 538: * 0 - Success (PALcode was switched) ! 539: * 1 - Unknown PALcode variant ! 540: * 2 - Known PALcode variant, but PALcode not loaded ! 541: * ! 542: * r26 (ra) = r27 (pv) = New PC ! 543: * Note that this is non-architected, but is relied on by ! 544: * the usage of SwpPal within our own console code in order ! 545: * to simplify its use within C code. ! 546: * ! 547: */ ! 548: ORG_CALL_PAL_PRIV(0x0A) ! 549: CallPal_SwpPal: ! 550: // Save a copy of the return address in case of machine check. ! 551: mfpr p6, qemu_exc_addr ! 552: ! 553: // Accept swapping to OSF PALcode. The side effect here is to ! 554: // load the other parameters for the kernel. ! 555: cmpeq a0, 2, v0 ! 556: bne v0, CallPal_SwpPal_Cont ! 557: ! 558: // Return as an unknown PALcode variant ! 559: mov 1, v0 ! 560: hw_rei ! 561: ENDFN CallPal_SwpPal ! 562: ! 563: .text 1 ! 564: CallPal_SwpPal_Cont: ! 565: rpcc p0 ! 566: mtpr a2, ptPcbb ! 567: mtpr a3, qemu_vptptr ! 568: ! 569: ldq_p $sp, PCB_Q_KSP(a2) ! 570: ldq_p t0, PCB_Q_USP(a2) ! 571: ldq_p t1, PCB_Q_PTBR(a2) ! 572: ldl_p t2, PCB_L_PCC(a2) ! 573: ldq_p t3, PCB_Q_UNIQUE(a2) ! 574: ldq_p t4, PCB_Q_FEN(a2) ! 575: ! 576: mtpr t0, qemu_usp ! 577: ! 578: sll t1, VA_S_OFF, t1 ! 579: mtpr t1, qemu_ptbr ! 580: ! 581: subl t2, p0, t2 ! 582: mtpr t2, qemu_pcc_ofs ! 583: ! 584: mtpr t3, qemu_unique ! 585: ! 586: and t4, 1, t4 ! 587: mtpr t4, qemu_fen ! 588: ! 589: mtpr $31, qemu_tbia // Flush TLB for new PTBR ! 590: ! 591: mov a1, $26 ! 592: mov a1, $27 ! 593: hw_ret (a1) ! 594: ENDFN CallPal_SwpPal_Cont ! 595: .previous ! 596: ! 597: ORG_CALL_PAL_PRIV(0x0B) ! 598: CallPal_OpcDec0B: ! 599: br CallPal_OpcDec ! 600: ENDFN CallPal_OpcDec0B ! 601: ! 602: ORG_CALL_PAL_PRIV(0x0C) ! 603: CallPal_OpcDec0C: ! 604: br CallPal_OpcDec ! 605: ENDFN CallPal_OpcDec0C ! 606: ! 607: /* ! 608: * Write Interprocessor Interrupt Request ! 609: * ! 610: * INPUT PARAMETERS: ! 611: * ! 612: * r16 (a0) = target processor number ! 613: * ! 614: * OUTPUT PARAMETERS: ! 615: * ! 616: * SIDE EFFECTS: ! 617: * ! 618: */ ! 619: ORG_CALL_PAL_PRIV(0x0D) ! 620: CallPal_WrIpir: ! 621: // Save a copy of the return address in case of machine check. ! 622: mfpr p6, qemu_exc_addr ! 623: ! 624: SYS_WRIPIR a0, p0, p1, p2 ! 625: ! 626: hw_rei ! 627: ENDFN CallPal_WrIpir ! 628: ! 629: ORG_CALL_PAL_PRIV(0x0E) ! 630: CallPal_OpcDec0E: ! 631: br CallPal_OpcDec ! 632: ENDFN CallPal_OpcDec0E ! 633: ! 634: ORG_CALL_PAL_PRIV(0x0F) ! 635: CallPal_OpcDec0F: ! 636: br CallPal_OpcDec ! 637: ENDFN CallPal_OpcDec0F ! 638: ! 639: /* ! 640: * Read Machine Check Error Summary ! 641: * ! 642: * INPUT PARAMETERS: ! 643: * ! 644: * OUTPUT PARAMETERS: ! 645: * ! 646: * r0 (v0) = returned MCES value ! 647: * ! 648: * SIDE EFFECTS: ! 649: * ! 650: */ ! 651: ORG_CALL_PAL_PRIV(0x10) ! 652: CallPal_RdMces: ! 653: mfpr v0, ptMces // Get current MCES value ! 654: and v0, MCES_M_ALL, v0 // Clear all other bits ! 655: hw_rei ! 656: ENDFN CallPal_RdMces ! 657: ! 658: /* ! 659: * Write Machine Check Error Summary ! 660: * ! 661: * INPUT PARAMETERS: ! 662: * ! 663: * r16 (a0) = MCES<DPC> <- a0<3>, MCES<DSC> <- a0<4> ! 664: * ! 665: * OUTPUT PARAMETERS: ! 666: * ! 667: * SIDE EFFECTS: ! 668: * ! 669: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 670: */ ! 671: ORG_CALL_PAL_PRIV(0x11) ! 672: CallPal_WrMces: ! 673: // Clear MIP, SCE, PCE ! 674: and a0, (MCES_M_MIP | MCES_M_SCE | MCES_M_PCE), p0 ! 675: mfpr p1, ptMces ! 676: bic p1, p0, p1 ! 677: ! 678: // Copy DPC and DSC ! 679: and a0, (MCES_M_DPC | MCES_M_DSC), p0 ! 680: bic p1, (MCES_M_DPC | MCES_M_DSC), p1 ! 681: or p1, p0, p1 ! 682: ! 683: mtpr p1, ptMces ! 684: hw_rei ! 685: ENDFN CallPal_WrMces ! 686: ! 687: ORG_CALL_PAL_PRIV(0x12) ! 688: CallPal_OpcDec12: ! 689: br CallPal_OpcDec ! 690: ENDFN CallPal_OpcDec12 ! 691: ! 692: ORG_CALL_PAL_PRIV(0x13) ! 693: CallPal_OpcDec13: ! 694: br CallPal_OpcDec ! 695: ENDFN CallPal_OpcDec13 ! 696: ! 697: ORG_CALL_PAL_PRIV(0x14) ! 698: CallPal_OpcDec14: ! 699: br CallPal_OpcDec ! 700: ENDFN CallPal_OpcDec14 ! 701: ! 702: ORG_CALL_PAL_PRIV(0x15) ! 703: CallPal_OpcDec15: ! 704: br CallPal_OpcDec ! 705: ENDFN CallPal_OpcDec15 ! 706: ! 707: ORG_CALL_PAL_PRIV(0x16) ! 708: CallPal_OpcDec16: ! 709: br CallPal_OpcDec ! 710: ENDFN CallPal_OpcDec16 ! 711: ! 712: ORG_CALL_PAL_PRIV(0x17) ! 713: CallPal_OpcDec17: ! 714: br CallPal_OpcDec ! 715: ENDFN CallPal_OpcDec17 ! 716: ! 717: ORG_CALL_PAL_PRIV(0x18) ! 718: CallPal_OpcDec18: ! 719: br CallPal_OpcDec ! 720: ENDFN CallPal_OpcDec18 ! 721: ! 722: ORG_CALL_PAL_PRIV(0x19) ! 723: CallPal_OpcDec19: ! 724: br CallPal_OpcDec ! 725: ENDFN CallPal_OpcDec19 ! 726: ! 727: ORG_CALL_PAL_PRIV(0x1A) ! 728: CallPal_OpcDec1A: ! 729: br CallPal_OpcDec ! 730: ENDFN CallPal_OpcDec1A ! 731: ! 732: ORG_CALL_PAL_PRIV(0x1B) ! 733: CallPal_OpcDec1B: ! 734: br CallPal_OpcDec ! 735: ENDFN CallPal_OpcDec1B ! 736: ! 737: ORG_CALL_PAL_PRIV(0x1C) ! 738: CallPal_OpcDec1C: ! 739: br CallPal_OpcDec ! 740: ENDFN CallPal_OpcDec1C ! 741: ! 742: ORG_CALL_PAL_PRIV(0x1D) ! 743: CallPal_OpcDec1D: ! 744: br CallPal_OpcDec ! 745: ENDFN CallPal_OpcDec1D ! 746: ! 747: ORG_CALL_PAL_PRIV(0x1E) ! 748: CallPal_OpcDec1E: ! 749: br CallPal_OpcDec ! 750: ENDFN CallPal_OpcDec1E ! 751: ! 752: ORG_CALL_PAL_PRIV(0x1F) ! 753: CallPal_OpcDec1F: ! 754: br CallPal_OpcDec ! 755: ENDFN CallPal_OpcDec1F ! 756: ! 757: ORG_CALL_PAL_PRIV(0x20) ! 758: CallPal_OpcDec20: ! 759: br CallPal_OpcDec ! 760: ENDFN CallPal_OpcDec20 ! 761: ! 762: ORG_CALL_PAL_PRIV(0x21) ! 763: CallPal_OpcDec21: ! 764: br CallPal_OpcDec ! 765: ENDFN CallPal_OpcDec21 ! 766: ! 767: ORG_CALL_PAL_PRIV(0x22) ! 768: CallPal_OpcDec22: ! 769: br CallPal_OpcDec ! 770: ENDFN CallPal_OpcDec22 ! 771: ! 772: ORG_CALL_PAL_PRIV(0x23) ! 773: CallPal_OpcDec23: ! 774: br CallPal_OpcDec ! 775: ENDFN CallPal_OpcDec23 ! 776: ! 777: ORG_CALL_PAL_PRIV(0x24) ! 778: CallPal_OpcDec24: ! 779: br CallPal_OpcDec ! 780: ENDFN CallPal_OpcDec24 ! 781: ! 782: ORG_CALL_PAL_PRIV(0x25) ! 783: CallPal_OpcDec25: ! 784: br CallPal_OpcDec ! 785: ENDFN CallPal_OpcDec25 ! 786: ! 787: ORG_CALL_PAL_PRIV(0x26) ! 788: CallPal_OpcDec26: ! 789: br CallPal_OpcDec ! 790: ENDFN CallPal_OpcDec26 ! 791: ! 792: ORG_CALL_PAL_PRIV(0x27) ! 793: CallPal_OpcDec27: ! 794: br CallPal_OpcDec ! 795: ENDFN CallPal_OpcDec27 ! 796: ! 797: ORG_CALL_PAL_PRIV(0x28) ! 798: CallPal_OpcDec28: ! 799: br CallPal_OpcDec ! 800: ENDFN CallPal_OpcDec28 ! 801: ! 802: ORG_CALL_PAL_PRIV(0x29) ! 803: CallPal_OpcDec29: ! 804: br CallPal_OpcDec ! 805: ENDFN CallPal_OpcDec29 ! 806: ! 807: ORG_CALL_PAL_PRIV(0x2A) ! 808: CallPal_OpcDec2A: ! 809: br CallPal_OpcDec ! 810: ENDFN CallPal_OpcDec2A ! 811: ! 812: /* ! 813: * Write Floating Point Enable ! 814: * ! 815: * INPUT PARAMETERS: ! 816: * ! 817: * r16 (a0) = ICSR<FPE> <- a0<0> ! 818: * ! 819: * SIDE EFFECTS: ! 820: * ! 821: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 822: */ ! 823: ORG_CALL_PAL_PRIV(0x2B) ! 824: CallPal_WrFen: ! 825: mfpr p0, ptPcbb // Get PCBB ! 826: and a0, 1, a0 // Clean new FEN value to single bit ! 827: mtpr a0, qemu_fen ! 828: stl_p a0, PCB_Q_FEN(p0) // Write new PCB<FEN> ! 829: hw_rei ! 830: ENDFN CallPal_WrFen ! 831: ! 832: ORG_CALL_PAL_PRIV(0x2C) ! 833: CallPal_OpcDec2C: ! 834: br CallPal_OpcDec ! 835: ENDFN CallPal_OpcDec2C ! 836: ! 837: /* ! 838: * Write Virtual Page Table Pointer ! 839: * ! 840: * INPUT PARAMETERS: ! 841: * ! 842: * r16 (a0) = New virtual page table pointer ! 843: * ! 844: * SIDE EFFECTS: ! 845: * ! 846: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 847: */ ! 848: ORG_CALL_PAL_PRIV(0x2D) ! 849: CallPal_WrVptPtr: ! 850: mtpr a0, qemu_vptptr ! 851: hw_rei ! 852: ENDFN CallPal_WrVptPtr ! 853: ! 854: ORG_CALL_PAL_PRIV(0x2E) ! 855: CallPal_OpcDec2E: ! 856: br CallPal_OpcDec ! 857: ENDFN CallPal_OpcDec2E ! 858: ! 859: ORG_CALL_PAL_PRIV(0x2F) ! 860: CallPal_OpcDec2F: ! 861: br CallPal_OpcDec ! 862: ENDFN CallPal_OpcDec2F ! 863: ! 864: /* ! 865: * Swap Process Context ! 866: * ! 867: * FUNCTIONAL DESCRIPTION: ! 868: * ! 869: * The swap process context (swpctx) function saves ! 870: * the current process data in the current PCB, then ! 871: * switches to the PCB passed in a0 and loads the ! 872: * new process context. The old PCB is returned in v0. ! 873: * ! 874: * INPUT PARAMETERS: ! 875: * ! 876: * r16 (a0) = New PCBB ! 877: * ! 878: * OUTPUT PARAMETERS: ! 879: * ! 880: * r0 (v0) = Old PCBB ! 881: * ! 882: * SIDE EFFECTS: ! 883: * ! 884: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 885: */ ! 886: ORG_CALL_PAL_PRIV(0x30) ! 887: CallPal_SwpCtx: ! 888: rpcc p5 // Get cycle counter ! 889: mfpr p6, qemu_exc_addr // Save exc_addr for machine check ! 890: ! 891: mfpr v0, ptPcbb // Get current PCBB ! 892: mtpr a0, ptPcbb // Save new PCBB ! 893: srl p5, 32, p7 // Move CC<OFFSET> to low longword ! 894: ! 895: addl p5, p7, p7 // Accumulate time for old pcb ! 896: stl_p p7, PCB_L_PCC(v0) ! 897: ! 898: ldl_p t9, PCB_L_PCC(a0) // Get new PCC ! 899: subl t9, p5, p5 // Generate and ... ! 900: mtpr p5, qemu_pcc_ofs // .. set new CC<OFFSET> bits ! 901: ! 902: stq_p $sp, PCB_Q_KSP(v0) // Store old kernel stack pointer ! 903: mfpr t10, qemu_usp // Save old user stack pointer ! 904: stq_p t10, PCB_Q_USP(v0) ! 905: ! 906: br CallPal_SwpCtx_Cont ! 907: ENDFN CallPal_SwpCtx ! 908: ! 909: .text 1 ! 910: CallPal_SwpCtx_Cont: ! 911: ldq_p $sp, PCB_Q_KSP(a0) // Install new stack pointers ! 912: ldq_p t10, PCB_Q_USP(a0) ! 913: mtpr t10, qemu_usp ! 914: ! 915: mfpr t10, qemu_unique // Save old unique value ! 916: stq_p t10, PCB_Q_UNIQUE(v0) ! 917: ldq_p t10, PCB_Q_UNIQUE(a0) // Install new unique value ! 918: mtpr t10, qemu_unique ! 919: ! 920: ldq_p t8, PCB_Q_FEN(a0) // Install new FEN ! 921: and t8, 1, t8 ! 922: mtpr t8, qemu_fen ! 923: ! 924: // QEMU does not implement an ASN; skip that. ! 925: ! 926: ldq_p t10, PCB_Q_PTBR(a0) // Install new page tables ! 927: sll t10, VA_S_OFF, t10 ! 928: mtpr t10, qemu_ptbr ! 929: mtpr $31, qemu_tbia // Flush TLB, since we don't do ASNs ! 930: ! 931: hw_rei ! 932: ENDFN CallPal_SwpCtx_Cont ! 933: .previous ! 934: ! 935: /* ! 936: * Write System Value ! 937: * ! 938: * INPUT PARAMETERS: ! 939: * ! 940: * r16 (a0) = New system value ! 941: * ! 942: * SIDE EFFECTS: ! 943: * ! 944: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 945: */ ! 946: ORG_CALL_PAL_PRIV(0x31) ! 947: CallPal_WrVal: ! 948: mtpr a0, qemu_sysval ! 949: hw_rei ! 950: ENDFN CallPal_WrVal ! 951: ! 952: /* ! 953: * Read System Value ! 954: * ! 955: * OUTPUT PARAMETERS: ! 956: * ! 957: * r0 (v0) = Returned system value ! 958: * ! 959: * SIDE EFFECTS: ! 960: * ! 961: * Registers t0 and t8..t11 are UNPREDICTABLE upon return. ! 962: */ ! 963: ORG_CALL_PAL_PRIV(0x32) ! 964: CallPal_RdVal: ! 965: mfpr v0, qemu_sysval ! 966: hw_rei ! 967: ENDFN CallPal_RdVal ! 968: ! 969: /* ! 970: * Translation Buffer Invalidate ! 971: * ! 972: * INPUT PARAMETERS: ! 973: * ! 974: * r16 (a0) = tbi selector type: ! 975: * ! 976: * -2 - Flush all TB entries (tbia) ! 977: * -1 - Invalidate all TB entries with ASM=0 (tbiap) ! 978: * 1 - Invalidate ITB entry for va=a1 (tbisi) ! 979: * 2 - Invalidate DTB entry for va=a1 (tbisd) ! 980: * 3 - Invalidate both ITB and DTB entry for va=a1 (tbis) ! 981: * ! 982: * r17 (a1) = VA for TBISx types ! 983: * ! 984: * Qemu does not implement ASNs or split I/D tlbs. Therefore these ! 985: * collapse to tbia and tbis. ! 986: * ! 987: * SIDE EFFECTS: ! 988: * ! 989: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 990: */ ! 991: ORG_CALL_PAL_PRIV(0x33) ! 992: CallPal_Tbi: ! 993: bge a0, 1f ! 994: ! 995: mtpr $31, qemu_tbia ! 996: hw_rei ! 997: ! 998: 1: mtpr a1, qemu_tbis ! 999: hw_rei ! 1000: ENDFN CallPal_Tbi ! 1001: ! 1002: /* ! 1003: * Write System Entry Address ! 1004: * ! 1005: * INPUT PARAMETERS: ! 1006: * ! 1007: * r16 (a0) = VA of system entry point ! 1008: * r17 (a1) = System entry point selector ! 1009: * ! 1010: * SIDE EFFECTS: ! 1011: * ! 1012: * Registers t0, t8..t11, and a0..a1 are UNPREDICTABLE ! 1013: * upon return. ! 1014: */ ! 1015: ORG_CALL_PAL_PRIV(0x34) ! 1016: CallPal_WrEnt: ! 1017: andnot a0, 3, a0 // Clean PC<1:0> ! 1018: ! 1019: cmpult a1, 6, t8 // Bound the input ! 1020: cmoveq t8, 6, a1 ! 1021: ! 1022: br t0, 1f ! 1023: 1: lda t0, WrEnt_Table-1b(t0) ! 1024: s8addq a1, t0, t0 ! 1025: jmp $31, (t0), 0 ! 1026: ENDFN CallPal_WrEnt ! 1027: ! 1028: .text 1 ! 1029: WrEnt_Table: ! 1030: 0: mtpr a0, ptEntInt ! 1031: hw_rei ! 1032: 1: mtpr a0, ptEntArith ! 1033: hw_rei ! 1034: 2: mtpr a0, ptEntMM ! 1035: hw_rei ! 1036: 3: mtpr a0, ptEntIF ! 1037: hw_rei ! 1038: 4: mtpr a0, ptEntUna ! 1039: hw_rei ! 1040: 5: mtpr a0, ptEntSys ! 1041: hw_rei ! 1042: 6: nop ! 1043: hw_rei ! 1044: ENDFN WrEnt_Table ! 1045: .previous ! 1046: ! 1047: /* ! 1048: * Swap Interrupt Priority Level ! 1049: * ! 1050: * INPUT PARAMETERS: ! 1051: * ! 1052: * r16 (a0) = New IPL ! 1053: * ! 1054: * OUTPUT PARAMETERS: ! 1055: * ! 1056: * r0 (v0) = Old IPL ! 1057: * ! 1058: * SIDE EFFECTS: ! 1059: * ! 1060: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 1061: */ ! 1062: ORG_CALL_PAL_PRIV(0x35) ! 1063: CallPal_SwpIpl: ! 1064: mfpr v0, qemu_ps ! 1065: and a0, PS_M_IPL, a0 ! 1066: and v0, PS_M_IPL, v0 ! 1067: mtpr a0, qemu_ps ! 1068: hw_rei ! 1069: ENDFN CallPal_SwpIpl ! 1070: ! 1071: /* ! 1072: * Read Processor Status ! 1073: * ! 1074: * OUTPUT PARAMETERS: ! 1075: * ! 1076: * r0 (v0) = Current PS ! 1077: * ! 1078: * SIDE EFFECTS: ! 1079: * ! 1080: * Registers t0, t8..t11 are UNPREDICTABLE upon return. ! 1081: */ ! 1082: ORG_CALL_PAL_PRIV(0x36) ! 1083: CallPal_RdPs: ! 1084: mfpr v0, qemu_ps ! 1085: hw_rei ! 1086: ENDFN CallPal_RdPs ! 1087: ! 1088: /* ! 1089: * Write Kernel Global Pointer ! 1090: * ! 1091: * INPUT PARAMETERS: ! 1092: * ! 1093: * r16 (a0) = New KGP value ! 1094: * ! 1095: * SIDE EFFECTS: ! 1096: * ! 1097: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 1098: */ ! 1099: ORG_CALL_PAL_PRIV(0x37) ! 1100: CallPal_WrKgp: ! 1101: mtpr a0, ptKgp ! 1102: hw_rei ! 1103: ENDFN CallPal_WrKgp ! 1104: ! 1105: /* ! 1106: * Write User Stack Pointer ! 1107: * ! 1108: * INPUT PARAMETERS: ! 1109: * ! 1110: * r16 (a0) = New user stack pointer value ! 1111: * ! 1112: * SIDE EFFECTS: ! 1113: * ! 1114: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 1115: */ ! 1116: ORG_CALL_PAL_PRIV(0x38) ! 1117: CallPal_WrUsp: ! 1118: mtpr a0, qemu_usp ! 1119: hw_rei ! 1120: ENDFN CallPal_WrUsp ! 1121: ! 1122: /* ! 1123: * Write Performance Monitor ! 1124: * ! 1125: * INPUT PARAMETERS: ! 1126: * ! 1127: * r16 (a0) = New user stack pointer value ! 1128: * ! 1129: * SIDE EFFECTS: ! 1130: * ! 1131: * Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return. ! 1132: */ ! 1133: ORG_CALL_PAL_PRIV(0x39) ! 1134: CallPal_WrPerfMon: ! 1135: // Not implemented ! 1136: hw_rei ! 1137: ENDFN CallPal_WrPerfMon ! 1138: ! 1139: /* ! 1140: * Read User Stack Pointer ! 1141: * ! 1142: * OUTPUT PARAMETERS: ! 1143: * ! 1144: * r0 (v0) = User stack pointer value ! 1145: * ! 1146: * SIDE EFFECTS: ! 1147: * ! 1148: * Registers t0, and t8..t11 are UNPREDICTABLE upon return. ! 1149: */ ! 1150: ORG_CALL_PAL_PRIV(0x3A) ! 1151: CallPal_RdUsp: ! 1152: mfpr v0, qemu_usp ! 1153: hw_rei ! 1154: ENDFN CallPal_RdUsp ! 1155: ! 1156: ORG_CALL_PAL_PRIV(0x3B) ! 1157: CallPal_OpcDec3B: ! 1158: br CallPal_OpcDec ! 1159: ENDFN CallPal_OpcDec3B ! 1160: ! 1161: /* ! 1162: * Who Am I ! 1163: * ! 1164: * OUTPUT PARAMETERS: ! 1165: * ! 1166: * r0 (v0) = Current processor number ! 1167: * ! 1168: * SIDE EFFECTS: ! 1169: * ! 1170: * Registers t0 and t8..t11 are UNPREDICTABLE upon return. ! 1171: */ ! 1172: ORG_CALL_PAL_PRIV(0x3C) ! 1173: CallPal_Whami: ! 1174: SYS_WHAMI v0 ! 1175: hw_rei ! 1176: ENDFN CallPal_Whami ! 1177: ! 1178: /* ! 1179: * Return From System Call ! 1180: * ! 1181: * INPUT PARAMETERS: ! 1182: * ! 1183: * r30 (sp) = Pointer to the top of the kernel stack ! 1184: * ! 1185: * OUTPUT PARAMETERS: ! 1186: * ! 1187: * r29 (gp) = Restored user mode global pointer ! 1188: * r30 (sp) = User stack pointer ! 1189: * ! 1190: * SIDE EFFECTS: ! 1191: * ! 1192: * Registers t0 and t8..t11 are UNPREDICTABLE upon return. ! 1193: */ ! 1194: ORG_CALL_PAL_PRIV(0x3D) ! 1195: CallPal_RetSys: ! 1196: ldq t9, FRM_Q_PC($sp) // Pop the return address ! 1197: ldq $gp, FRM_Q_GP($sp) // Get the user mode global pointer ! 1198: lda t8, FRM_K_SIZE($sp) ! 1199: mtpr t8, ptKsp ! 1200: ! 1201: mov PS_K_USER, t8 // Set new mode to user ! 1202: mtpr t8, qemu_ps ! 1203: ! 1204: mfpr $sp, qemu_usp // Get the user stack pointer ! 1205: ! 1206: andnot t9, 3, t9 // Clean return PC<1:0> ! 1207: hw_ret (t9) ! 1208: ENDFN CallPal_RetSys ! 1209: ! 1210: /* ! 1211: * Wait For Interrupt ! 1212: * ! 1213: * FUNCTIONAL DESCRIPTION: ! 1214: * ! 1215: * If possible, wait for the first of either of the following ! 1216: * conditions before returning: any interrupt other than a clock ! 1217: * tick; or the first clock tick after a specified number of clock ! 1218: * ticks have bbeen skipped. ! 1219: * ! 1220: * INPUT PARAMETERS: ! 1221: * ! 1222: * r16 (a0) = Maximum number of clock ticks to skip ! 1223: * ! 1224: * OUTPUT PARAMETERS: ! 1225: * ! 1226: * r0 (v0) = Number of clock ticks actually skipped. ! 1227: */ ! 1228: ORG_CALL_PAL_PRIV(0x3E) ! 1229: CallPal_WtInt: ! 1230: mtpr $31, qemu_wait ! 1231: mov 0, v0 ! 1232: hw_rei ! 1233: ENDFN CallPal_WtInt ! 1234: ! 1235: /* ! 1236: * Return From Trap, Fault, or Interrupt ! 1237: * ! 1238: * INPUT PARAMETERS: ! 1239: * ! 1240: * r30 (sp) = Pointer to the top of the kernel stack ! 1241: * ! 1242: * OUTPUT PARAMETERS: ! 1243: * ! 1244: * ps <- (sp+00) ! 1245: * pc <- (sp+08) ! 1246: * r29 (gp) <- (sp+16) ! 1247: * r16 (a0) <- (sp+24) ! 1248: * r17 (a1) <- (sp+32) ! 1249: * r18 (a2) <- (sp+40) ! 1250: */ ! 1251: ORG_CALL_PAL_PRIV(0x3F) ! 1252: .globl CallPal_Rti ! 1253: CallPal_Rti: ! 1254: mfpr p6, qemu_exc_addr // Save exc_addr for machine check ! 1255: ! 1256: ldq p4, FRM_Q_PS($sp) // Get the PS ! 1257: ldq p5, FRM_Q_PC($sp) // Get the return PC ! 1258: ldq $gp, FRM_Q_GP($sp) // Get gp ! 1259: ldq a0, FRM_Q_A0($sp) // Get a0 ! 1260: ldq a1, FRM_Q_A1($sp) // Get a1 ! 1261: ldq a2, FRM_Q_A2($sp) // Get a2 ! 1262: lda $sp, FRM_K_SIZE($sp) // Pop the stack ! 1263: ! 1264: andnot p5, 3, p5 // Clean return PC<1:0> ! 1265: ! 1266: and p4, PS_M_CM, p3 ! 1267: bne p3, CallPal_Rti_ToUser ! 1268: ! 1269: and p4, PS_M_IPL, p4 ! 1270: mtpr p4, qemu_ps ! 1271: hw_ret (p5) ! 1272: ENDFN CallPal_Rti ! 1273: ! 1274: .text 1 ! 1275: CallPal_Rti_ToUser: ! 1276: mtpr p3, qemu_ps ! 1277: mtpr $sp, ptKsp ! 1278: mfpr $sp, qemu_usp ! 1279: hw_ret (p5) ! 1280: ENDFN CallPal_Rti_ToUser ! 1281: .previous ! 1282: ! 1283: /* ! 1284: * OSF/1 Unprivileged CALL_PAL Entry Points ! 1285: */ ! 1286: ! 1287: #define ORG_CALL_PAL_UNPRIV(X) .org 0x2000+64*(X-0x80) ! 1288: ! 1289: /* ! 1290: * A helper routine for the unprivaledged kernel entry points, since the ! 1291: * actual stack frame setup code is just a tad too large to fit inline. ! 1292: * ! 1293: * INPUT PARAMETERS: ! 1294: * ! 1295: * p5 = ps ! 1296: * p6 = exc_addr ! 1297: * p7 = return address ! 1298: * ! 1299: * SIDE EFFECTS: ! 1300: * ! 1301: * p0 is clobbered ! 1302: * ! 1303: */ ! 1304: .text 1 ! 1305: CallPal_Stack_Frame: ! 1306: // Test if we're currently in user mode ! 1307: and p5, PS_M_CM, p0 ! 1308: beq p0, 0f ! 1309: CallPal_Stack_Frame_FromUser: ! 1310: // Switch to kernel mode ! 1311: mtpr $31, qemu_ps ! 1312: mtpr $sp, qemu_usp ! 1313: mfpr $sp, ptKsp ! 1314: 0: ! 1315: // Allocate the stack frame ! 1316: lda $sp, -FRM_K_SIZE($sp) ! 1317: stq p5, FRM_Q_PS($sp) ! 1318: stq p6, FRM_Q_PC($sp) ! 1319: stq $gp, FRM_Q_GP($sp) ! 1320: stq a0, FRM_Q_A0($sp) ! 1321: stq a1, FRM_Q_A1($sp) ! 1322: stq a2, FRM_Q_A2($sp) ! 1323: ret $31, (p7), 0 ! 1324: ENDFN CallPal_Stack_Frame ! 1325: .previous ! 1326: ! 1327: /* ! 1328: * Breakpoint Trap ! 1329: * ! 1330: * OUTPUT PARAMETERS: ! 1331: * ! 1332: * r16 (a0) = Code for bpt (0) ! 1333: * r17 (a1) = UNPREDICTABLE ! 1334: * r18 (a2) = UNPREDICTABLE ! 1335: */ ! 1336: ORG_CALL_PAL_UNPRIV(0x80) ! 1337: CallPal_Bpt: ! 1338: mfpr p5, qemu_ps ! 1339: mfpr p6, qemu_exc_addr ! 1340: bsr p7, CallPal_Stack_Frame ! 1341: ! 1342: mfpr p0, ptEntIF ! 1343: mfpr $gp, ptKgp ! 1344: mov IF_K_BPT, a0 ! 1345: hw_ret (p0) ! 1346: ENDFN CallPal_Bpt ! 1347: ! 1348: /* ! 1349: * Bugcheck Trap ! 1350: * ! 1351: * OUTPUT PARAMETERS: ! 1352: * ! 1353: * r16 (a0) = Code for bugchk (1) ! 1354: * r17 (a1) = UNPREDICTABLE ! 1355: * r18 (a2) = UNPREDICTABLE ! 1356: */ ! 1357: ORG_CALL_PAL_UNPRIV(0x81) ! 1358: CallPal_BugChk: ! 1359: mfpr p5, qemu_ps ! 1360: mfpr p6, qemu_exc_addr ! 1361: bsr p7, CallPal_Stack_Frame ! 1362: ! 1363: mfpr p0, ptEntIF ! 1364: mfpr $gp, ptKgp ! 1365: mov IF_K_BUGCHK, a0 ! 1366: hw_ret (p0) ! 1367: ENDFN CallPal_BugChk ! 1368: ! 1369: ! 1370: ORG_CALL_PAL_UNPRIV(0x82) ! 1371: CallPal_OpcDec82: ! 1372: br CallPal_OpcDec ! 1373: ENDFN CallPal_OpcDec82 ! 1374: ! 1375: /* ! 1376: * System Call ! 1377: */ ! 1378: ORG_CALL_PAL_UNPRIV(0x83) ! 1379: CallPal_CallSys: ! 1380: mfpr p5, qemu_ps ! 1381: mfpr p6, qemu_exc_addr ! 1382: ! 1383: and p5, PS_M_CM, p0 ! 1384: beq p0, 0f ! 1385: ! 1386: bsr p7, CallPal_Stack_Frame_FromUser ! 1387: ! 1388: mfpr p0, ptEntSys ! 1389: mfpr $gp, ptKgp ! 1390: hw_ret (p0) ! 1391: ! 1392: 0: subq p6, 4, p6 // Get PC of CALL_PAL insn ! 1393: br MchkOSBugCheck ! 1394: ENDFN CallPal_CallSys ! 1395: ! 1396: ORG_CALL_PAL_UNPRIV(0x84) ! 1397: CallPal_OpcDec84: ! 1398: br CallPal_OpcDec ! 1399: ENDFN CallPal_OpcDec84 ! 1400: ! 1401: ORG_CALL_PAL_UNPRIV(0x85) ! 1402: CallPal_OpcDec85: ! 1403: br CallPal_OpcDec ! 1404: ENDFN CallPal_OpcDec85 ! 1405: ! 1406: ! 1407: /* ! 1408: * I-Stream Memory Barrier ! 1409: * ! 1410: * For QEMU, this is of course a no-op. ! 1411: */ ! 1412: ORG_CALL_PAL_UNPRIV(0x86) ! 1413: CallPal_Imb: ! 1414: hw_rei ! 1415: ENDFN CallPal_Imb ! 1416: ! 1417: ! 1418: ORG_CALL_PAL_UNPRIV(0x87) ! 1419: CallPal_OpcDec87: ! 1420: br CallPal_OpcDec ! 1421: ENDFN CallPal_OpcDec87 ! 1422: ! 1423: ORG_CALL_PAL_UNPRIV(0x88) ! 1424: CallPal_OpcDec88: ! 1425: br CallPal_OpcDec ! 1426: ENDFN CallPal_OpcDec88 ! 1427: ! 1428: ORG_CALL_PAL_UNPRIV(0x89) ! 1429: CallPal_OpcDec89: ! 1430: br CallPal_OpcDec ! 1431: ENDFN CallPal_OpcDec89 ! 1432: ! 1433: ORG_CALL_PAL_UNPRIV(0x8A) ! 1434: CallPal_OpcDec8A: ! 1435: br CallPal_OpcDec ! 1436: ENDFN CallPal_OpcDec8A ! 1437: ! 1438: ORG_CALL_PAL_UNPRIV(0x8B) ! 1439: CallPal_OpcDec8B: ! 1440: br CallPal_OpcDec ! 1441: ENDFN CallPal_OpcDec8B ! 1442: ! 1443: ORG_CALL_PAL_UNPRIV(0x8C) ! 1444: CallPal_OpcDec8C: ! 1445: br CallPal_OpcDec ! 1446: ENDFN CallPal_OpcDec8C ! 1447: ! 1448: ORG_CALL_PAL_UNPRIV(0x8D) ! 1449: CallPal_OpcDec8D: ! 1450: br CallPal_OpcDec ! 1451: ENDFN CallPal_OpcDec8D ! 1452: ! 1453: ORG_CALL_PAL_UNPRIV(0x8E) ! 1454: CallPal_OpcDec8E: ! 1455: br CallPal_OpcDec ! 1456: ENDFN CallPal_OpcDec8E ! 1457: ! 1458: ORG_CALL_PAL_UNPRIV(0x8F) ! 1459: CallPal_OpcDec8F: ! 1460: br CallPal_OpcDec ! 1461: ENDFN CallPal_OpcDec8F ! 1462: ! 1463: ORG_CALL_PAL_UNPRIV(0x90) ! 1464: CallPal_OpcDec90: ! 1465: br CallPal_OpcDec ! 1466: ENDFN CallPal_OpcDec90 ! 1467: ! 1468: ORG_CALL_PAL_UNPRIV(0x91) ! 1469: CallPal_OpcDec91: ! 1470: br CallPal_OpcDec ! 1471: ENDFN CallPal_OpcDec91 ! 1472: ! 1473: ORG_CALL_PAL_UNPRIV(0x92) ! 1474: CallPal_OpcDec92: ! 1475: br CallPal_OpcDec ! 1476: ENDFN CallPal_OpcDec92 ! 1477: ! 1478: ORG_CALL_PAL_UNPRIV(0x93) ! 1479: CallPal_OpcDec93: ! 1480: br CallPal_OpcDec ! 1481: ENDFN CallPal_OpcDec93 ! 1482: ! 1483: ORG_CALL_PAL_UNPRIV(0x94) ! 1484: CallPal_OpcDec94: ! 1485: br CallPal_OpcDec ! 1486: ENDFN CallPal_OpcDec94 ! 1487: ! 1488: ORG_CALL_PAL_UNPRIV(0x95) ! 1489: CallPal_OpcDec95: ! 1490: br CallPal_OpcDec ! 1491: ENDFN CallPal_OpcDec95 ! 1492: ! 1493: ORG_CALL_PAL_UNPRIV(0x96) ! 1494: CallPal_OpcDec96: ! 1495: br CallPal_OpcDec ! 1496: ENDFN CallPal_OpcDec96 ! 1497: ! 1498: ORG_CALL_PAL_UNPRIV(0x97) ! 1499: CallPal_OpcDec97: ! 1500: br CallPal_OpcDec ! 1501: ENDFN CallPal_OpcDec97 ! 1502: ! 1503: ORG_CALL_PAL_UNPRIV(0x98) ! 1504: CallPal_OpcDec98: ! 1505: br CallPal_OpcDec ! 1506: ENDFN CallPal_OpcDec98 ! 1507: ! 1508: ORG_CALL_PAL_UNPRIV(0x99) ! 1509: CallPal_OpcDec99: ! 1510: br CallPal_OpcDec ! 1511: ENDFN CallPal_OpcDec99 ! 1512: ! 1513: ORG_CALL_PAL_UNPRIV(0x9A) ! 1514: CallPal_OpcDec9A: ! 1515: br CallPal_OpcDec ! 1516: ENDFN CallPal_OpcDec9A ! 1517: ! 1518: ORG_CALL_PAL_UNPRIV(0x9B) ! 1519: CallPal_OpcDec9B: ! 1520: br CallPal_OpcDec ! 1521: ENDFN CallPal_OpcDec9B ! 1522: ! 1523: ORG_CALL_PAL_UNPRIV(0x9C) ! 1524: CallPal_OpcDec9C: ! 1525: br CallPal_OpcDec ! 1526: ENDFN CallPal_OpcDec9C ! 1527: ! 1528: ORG_CALL_PAL_UNPRIV(0x9D) ! 1529: CallPal_OpcDec9D: ! 1530: br CallPal_OpcDec ! 1531: ENDFN CallPal_OpcDec9D ! 1532: ! 1533: /* ! 1534: * Read Unique Value ! 1535: * ! 1536: * OUTPUT PARAMETERS: ! 1537: * ! 1538: * r0 (v0) = Returned process unique value ! 1539: */ ! 1540: ORG_CALL_PAL_UNPRIV(0x9E) ! 1541: CallPal_RdUnique: ! 1542: mfpr v0, qemu_unique ! 1543: hw_rei ! 1544: ENDFN CallPal_RdUnique ! 1545: ! 1546: /* ! 1547: * Write Unique Value ! 1548: * ! 1549: * INPUT PARAMETERS: ! 1550: * ! 1551: * r16 (a0) = New process unique value ! 1552: */ ! 1553: ORG_CALL_PAL_UNPRIV(0x9F) ! 1554: CallPal_WrUnique: ! 1555: mtpr a0, qemu_unique ! 1556: hw_rei ! 1557: ENDFN CallPal_WrUnique ! 1558: ! 1559: ORG_CALL_PAL_UNPRIV(0xA0) ! 1560: CallPal_OpcDecA0: ! 1561: br CallPal_OpcDec ! 1562: ENDFN CallPal_OpcDecA0 ! 1563: ! 1564: ORG_CALL_PAL_UNPRIV(0xA1) ! 1565: CallPal_OpcDecA1: ! 1566: br CallPal_OpcDec ! 1567: ENDFN CallPal_OpcDecA1 ! 1568: ! 1569: ORG_CALL_PAL_UNPRIV(0xA2) ! 1570: CallPal_OpcDecA2: ! 1571: br CallPal_OpcDec ! 1572: ENDFN CallPal_OpcDecA2 ! 1573: ! 1574: ORG_CALL_PAL_UNPRIV(0xA3) ! 1575: CallPal_OpcDecA3: ! 1576: br CallPal_OpcDec ! 1577: ENDFN CallPal_OpcDecA3 ! 1578: ! 1579: ORG_CALL_PAL_UNPRIV(0xA4) ! 1580: CallPal_OpcDecA4: ! 1581: br CallPal_OpcDec ! 1582: ENDFN CallPal_OpcDecA4 ! 1583: ! 1584: ORG_CALL_PAL_UNPRIV(0xA5) ! 1585: CallPal_OpcDecA5: ! 1586: br CallPal_OpcDec ! 1587: ENDFN CallPal_OpcDecA5 ! 1588: ! 1589: ORG_CALL_PAL_UNPRIV(0xA6) ! 1590: CallPal_OpcDecA6: ! 1591: br CallPal_OpcDec ! 1592: ENDFN CallPal_OpcDecA6 ! 1593: ! 1594: ORG_CALL_PAL_UNPRIV(0xA7) ! 1595: CallPal_OpcDecA7: ! 1596: br CallPal_OpcDec ! 1597: ENDFN CallPal_OpcDecA7 ! 1598: ! 1599: ORG_CALL_PAL_UNPRIV(0xA8) ! 1600: CallPal_OpcDecA8: ! 1601: br CallPal_OpcDec ! 1602: ENDFN CallPal_OpcDecA8 ! 1603: ! 1604: ORG_CALL_PAL_UNPRIV(0xA9) ! 1605: CallPal_OpcDecA9: ! 1606: br CallPal_OpcDec ! 1607: ENDFN CallPal_OpcDecA9 ! 1608: ! 1609: /* ! 1610: * Generate Trap ! 1611: * ! 1612: * OUTPUT PARAMETERS: ! 1613: * ! 1614: * r16 (a0) = Code for gentrap (2) ! 1615: * r17 (a1) = UNPREDICTABLE ! 1616: * r18 (a2) = UNPREDICTABLE ! 1617: */ ! 1618: ORG_CALL_PAL_UNPRIV(0xAA) ! 1619: CallPal_GenTrap: ! 1620: mfpr p5, qemu_ps ! 1621: mfpr p6, qemu_exc_addr ! 1622: bsr p7, CallPal_Stack_Frame ! 1623: ! 1624: mfpr p0, ptEntIF ! 1625: mfpr $gp, ptKgp ! 1626: mov IF_K_GENTRAP, a0 ! 1627: hw_ret (p0) ! 1628: ENDFN CallPal_GenTrap ! 1629: ! 1630: ORG_CALL_PAL_UNPRIV(0xAB) ! 1631: CallPal_OpcDecAB: ! 1632: br CallPal_OpcDec ! 1633: ENDFN CallPal_OpcDecAB ! 1634: ! 1635: ORG_CALL_PAL_UNPRIV(0xAC) ! 1636: CallPal_OpcDecAC: ! 1637: br CallPal_OpcDec ! 1638: ENDFN CallPal_OpcDecAC ! 1639: ! 1640: ORG_CALL_PAL_UNPRIV(0xAD) ! 1641: CallPal_OpcDecAD: ! 1642: br CallPal_OpcDec ! 1643: ENDFN CallPal_OpcDecAD ! 1644: ! 1645: ORG_CALL_PAL_UNPRIV(0xAE) ! 1646: CallPal_OpcDecAE: ! 1647: br CallPal_OpcDec ! 1648: ENDFN CallPal_OpcDecAE ! 1649: ! 1650: ORG_CALL_PAL_UNPRIV(0xAF) ! 1651: CallPal_OpcDecAF: ! 1652: br CallPal_OpcDec ! 1653: ENDFN CallPal_OpcDecAF ! 1654: ! 1655: ORG_CALL_PAL_UNPRIV(0xB0) ! 1656: CallPal_OpcDecB0: ! 1657: br CallPal_OpcDec ! 1658: ENDFN CallPal_OpcDecB0 ! 1659: ! 1660: ORG_CALL_PAL_UNPRIV(0xB1) ! 1661: CallPal_OpcDecB1: ! 1662: br CallPal_OpcDec ! 1663: ENDFN CallPal_OpcDecB1 ! 1664: ! 1665: ORG_CALL_PAL_UNPRIV(0xB2) ! 1666: CallPal_OpcDecB2: ! 1667: br CallPal_OpcDec ! 1668: ENDFN CallPal_OpcDecB2 ! 1669: ! 1670: ORG_CALL_PAL_UNPRIV(0xB3) ! 1671: CallPal_OpcDecB3: ! 1672: br CallPal_OpcDec ! 1673: ENDFN CallPal_OpcDecB3 ! 1674: ! 1675: ORG_CALL_PAL_UNPRIV(0xB4) ! 1676: CallPal_OpcDecB4: ! 1677: br CallPal_OpcDec ! 1678: ENDFN CallPal_OpcDecB4 ! 1679: ! 1680: ORG_CALL_PAL_UNPRIV(0xB5) ! 1681: CallPal_OpcDecB5: ! 1682: br CallPal_OpcDec ! 1683: ENDFN CallPal_OpcDecB5 ! 1684: ! 1685: ORG_CALL_PAL_UNPRIV(0xB6) ! 1686: CallPal_OpcDecB6: ! 1687: br CallPal_OpcDec ! 1688: ENDFN CallPal_OpcDecB6 ! 1689: ! 1690: ORG_CALL_PAL_UNPRIV(0xB7) ! 1691: CallPal_OpcDecB7: ! 1692: br CallPal_OpcDec ! 1693: ENDFN CallPal_OpcDecB7 ! 1694: ! 1695: ORG_CALL_PAL_UNPRIV(0xB8) ! 1696: CallPal_OpcDecB8: ! 1697: br CallPal_OpcDec ! 1698: ENDFN CallPal_OpcDecB8 ! 1699: ! 1700: ORG_CALL_PAL_UNPRIV(0xB9) ! 1701: CallPal_OpcDecB9: ! 1702: br CallPal_OpcDec ! 1703: ENDFN CallPal_OpcDecB9 ! 1704: ! 1705: ORG_CALL_PAL_UNPRIV(0xBA) ! 1706: CallPal_OpcDecBA: ! 1707: br CallPal_OpcDec ! 1708: ENDFN CallPal_OpcDecBA ! 1709: ! 1710: ORG_CALL_PAL_UNPRIV(0xBB) ! 1711: CallPal_OpcDecBB: ! 1712: br CallPal_OpcDec ! 1713: ENDFN CallPal_OpcDecBB ! 1714: ! 1715: ORG_CALL_PAL_UNPRIV(0xBC) ! 1716: CallPal_OpcDecBC: ! 1717: br CallPal_OpcDec ! 1718: ENDFN CallPal_OpcDecBC ! 1719: ! 1720: ORG_CALL_PAL_UNPRIV(0xBD) ! 1721: CallPal_OpcDecBD: ! 1722: br CallPal_OpcDec ! 1723: ENDFN CallPal_OpcDecBD ! 1724: ! 1725: ORG_CALL_PAL_UNPRIV(0xBE) ! 1726: CallPal_OpcDecBE: ! 1727: br CallPal_OpcDec ! 1728: ENDFN CallPal_OpcDecBE ! 1729: ! 1730: ORG_CALL_PAL_UNPRIV(0xBF) ! 1731: CallPal_OpcDec: ! 1732: mfpr p5, qemu_ps ! 1733: mfpr p6, qemu_exc_addr ! 1734: bsr p7, CallPal_Stack_Frame ! 1735: ! 1736: mfpr p0, ptEntIF ! 1737: mfpr $gp, ptKgp ! 1738: mov IF_K_OPCDEC, a0 ! 1739: hw_ret (p0) ! 1740: ENDFN CallPal_OpcDec ! 1741: ! 1742: .org 0x3000 ! 1743: .text 1 ! 1744: /* ! 1745: * PALcode detected processor machine check handler. ! 1746: * ! 1747: * The PALcode-detected machine check handler loads a code ! 1748: * indicating the type of machine check error, loads ! 1749: * the System Control Block (SCB) vector for the ! 1750: * processor machine check service routine, sets the ! 1751: * Machine-Check-In-Progress (MIP) flag in the Machine ! 1752: * Check Error Summary register (MCES), and merges ! 1753: * with the common machine check flow. ! 1754: * ! 1755: * If a second processor machine check error condition ! 1756: * is detected while the MIP flag is set, the processor ! 1757: * is forced into console I/O mode indicating "double ! 1758: * error abort encountered" as the reason for the halt. ! 1759: * ! 1760: * CALLING SEQUENCE: ! 1761: * ! 1762: * Called when an internal processor error is detected ! 1763: * that cannot be successfully corrected by hardware or ! 1764: * PALcode. ! 1765: * ! 1766: * INPUT PARAMETERS: ! 1767: * ! 1768: * r14 (p6) = Exception address ! 1769: * ! 1770: * OUTPUT PARAMETERS: ! 1771: * ! 1772: * ptMchk0 = saved v0 ! 1773: * ptMchk1 = saved t0 ! 1774: * ptMchk2 = saved t3 ! 1775: * ptMchk3 = saved t4 ! 1776: * ptMchk4 = saved t5 ! 1777: * ptMchk5 = saved exc_addr ! 1778: * ptMisc<47:32> = MCHK code ! 1779: * ptMisc<31:16> = SCB vector ! 1780: * ptMces<MIP> = Set ! 1781: * ! 1782: * SIDE EFFECTS: ! 1783: * ! 1784: * r0 (v0), r1 (t0), and r4..r6 (t3..t5) are saved in ! 1785: * PAL temporaries and are available for use as scratch ! 1786: * registers by the system specific machine check ! 1787: * handler. ! 1788: */ ! 1789: ! 1790: MchkBugCheck: ! 1791: MchkOSBugCheck: ! 1792: halt ! 1793: ENDFN MchkBugCheck ! 1794: ! 1795: /* ! 1796: * Common Machine Check Handler ! 1797: * ! 1798: * INPUT STATE: ! 1799: * ! 1800: * ptMchk0 Saved v0 ! 1801: * ptMchk1 Saved t0 ! 1802: * ptMchk2 Saved t3 ! 1803: * ptMchk3 Saved t4 ! 1804: * ptMchk4 Saved t5 ! 1805: * ptMchk5 Saved exc_addr ! 1806: * ptMisc<47:32> MCHK code ! 1807: * ptMisc<31:16> SCB vector ! 1808: * ptMces<MIP> Set ! 1809: * ! 1810: * Registers v0, t0, and t3 .. t5 are available for use, in ! 1811: * addition to the shadow registers. ! 1812: */ ! 1813: ! 1814: MchkCommon: ! 1815: halt ! 1816: ENDFN MchkCommon ! 1817: ! 1818: /* ! 1819: * Build Machine Check Logout Frame ! 1820: * ! 1821: * This portion of the machine check handler builds a logout frame ! 1822: * in the PAL impure scratch area, builds a stack frame on the kernel ! 1823: * stack (already built if there was an interrupt machine check), ! 1824: * loads the GP with the KGP, loads the machine check entry ! 1825: * code in a0, loads a platform-specific interrupt vector ! 1826: * (typically the same value as the SCB offset) in a1, loads ! 1827: * the kseg address of the logout area in a2, and dispatches ! 1828: * to the kernel interrupt handler pointed to by the entInt ! 1829: * operating system entry point. ! 1830: * ! 1831: * OUTPUT PARAMETERS: ! 1832: * ! 1833: * a0 (r16) = Machine check entry type ! 1834: * a1 (r17) = Platform-specific interrupt vector ! 1835: * a2 (r18) = Pointer to logout area ! 1836: */ ! 1837: ! 1838: .macro STORE_IPR which, offset, base ! 1839: mfpr v0, \which ! 1840: stq_p v0, \offset(\base) ! 1841: .endm ! 1842: ! 1843: MchkLogOut: ! 1844: halt ! 1845: ENDFN MchkLogOut ! 1846: ! 1847: MchkDouble: ! 1848: bsr p7, UpdatePCB ! 1849: lda v0, HLT_K_DBL_MCHK ! 1850: br Sys_EnterConsole ! 1851: ENDFN MchkDouble ! 1852: ! 1853: MchkFromPal: ! 1854: bsr p7, UpdatePCB ! 1855: lda v0, HLT_K_MCHK_FROM_PAL ! 1856: br Sys_EnterConsole ! 1857: ENDFN MchkFromPal ! 1858: ! 1859: MchkKspInvalid: ! 1860: bsr p7, UpdatePCB ! 1861: lda v0, HLT_K_KSP_INVAL ! 1862: br Sys_EnterConsole ! 1863: ENDFN MchkKspInvalid ! 1864: ! 1865: /* ! 1866: * Update the current PCB with new SP and CC info. ! 1867: * ! 1868: * INPUT PARAMETERS: ! 1869: * ! 1870: * p7 = return linkage ! 1871: */ ! 1872: ! 1873: UpdatePCB: ! 1874: rpcc p5 ! 1875: mfpr p4, ptPcbb ! 1876: ! 1877: mfpr p3, qemu_ps // Check current mode ! 1878: and p3, PS_M_CM, p3 ! 1879: beq p3, 1f ! 1880: ! 1881: mtpr $sp, qemu_usp // Save user stack pointer ! 1882: stq_p $sp, PCB_Q_USP(p4) ! 1883: br 2f ! 1884: ! 1885: 1: mtpr $sp, ptKsp // Save kernel stack pointer ! 1886: stq_p $sp, PCB_Q_KSP(p4) ! 1887: ! 1888: 2: srl p5, 32, p3 // Merge for new time ! 1889: addl p5, p3, p3 ! 1890: stl_p p3, PCB_L_PCC(p4) // Store new time ! 1891: ! 1892: mfpr p5, qemu_unique // Save unique ! 1893: stq_p p5, PCB_Q_UNIQUE(p4) ! 1894: ! 1895: ret $31, (p7), 0 ! 1896: ENDFN UpdatePCB ! 1897: ! 1898: /* ! 1899: * FIXME ! 1900: */ ! 1901: Sys_EnterConsole: ! 1902: halt ! 1903: ! 1904: /* ! 1905: * Allocate the initial bootup stack. ! 1906: */ ! 1907: ! 1908: .section .bss ! 1909: .align 3 ! 1910: .globl stack ! 1911: .type stack,@object ! 1912: .size stack,STACK_SIZE ! 1913: stack: .skip STACK_SIZE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.