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