1/* 2 * Copyright (c) 2003-2006 The Regents of The University of Michigan 3 * Copyright (c) 1992-1995 Hewlett-Packard Development Company 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Authors: Ali G. Saidi 30 * Nathan L. Binkert 31 */ 32 33// modified to use the Hudson style "impure.h" instead of ev5_impure.sdl 34// since we don't have a mechanism to expand the data structures.... pb Nov/95 35#include "ev5_defs.h" 36#include "ev5_impure.h" 37#include "ev5_alpha_defs.h" 38#include "ev5_paldef.h" 39#include "ev5_osfalpha_defs.h" 40#include "fromHudsonMacros.h" 41#include "fromHudsonOsf.h" 42#include "dc21164FromGasSources.h" 43 44#define DEBUGSTORE(c) nop 45 46#define DEBUG_EXC_ADDR()\ 47 bsr r25, put_exc_addr; \ 48 DEBUGSTORE(13) ; \ 49 DEBUGSTORE(10) 50 51// This is the fix for the user-mode super page references causing the 52// machine to crash. 53#define hw_rei_spe hw_rei 54 55#define vmaj 1 56#define vmin 18 57#define vms_pal 1 58#define osf_pal 2 59#define pal_type osf_pal 60#define osfpal_version_l ((pal_type<<16) | (vmaj<<8) | (vmin<<0)) 61 62 63/////////////////////////// 64// PALtemp register usage 65/////////////////////////// 66 67// The EV5 Ibox holds 24 PALtemp registers. This maps the OSF PAL usage 68// for these PALtemps: 69// 70// pt0 local scratch 71// pt1 local scratch 72// pt2 entUna pt_entUna 73// pt3 CPU specific impure area pointer pt_impure 74// pt4 memory management temp 75// pt5 memory management temp 76// pt6 memory management temp 77// pt7 entIF pt_entIF 78// pt8 intmask pt_intmask 79// pt9 entSys pt_entSys 80// pt10 81// pt11 entInt pt_entInt 82// pt12 entArith pt_entArith 83// pt13 reserved for system specific PAL 84// pt14 reserved for system specific PAL 85// pt15 reserved for system specific PAL 86// pt16 MISC: scratch ! WHAMI<7:0> ! 0 0 0 MCES<4:0> pt_misc, pt_whami, 87// pt_mces 88// pt17 sysval pt_sysval 89// pt18 usp pt_usp 90// pt19 ksp pt_ksp 91// pt20 PTBR pt_ptbr 92// pt21 entMM pt_entMM 93// pt22 kgp pt_kgp 94// pt23 PCBB pt_pcbb 95// 96// 97 98 99///////////////////////////// 100// PALshadow register usage 101///////////////////////////// 102 103// 104// EV5 shadows R8-R14 and R25 when in PALmode and ICSR<shadow_enable> = 1. 105// This maps the OSF PAL usage of R8 - R14 and R25: 106// 107// r8 ITBmiss/DTBmiss scratch 108// r9 ITBmiss/DTBmiss scratch 109// r10 ITBmiss/DTBmiss scratch 110// r11 PS 111// r12 local scratch 112// r13 local scratch 113// r14 local scratch 114// r25 local scratch 115// 116 117 118 119// .sbttl "PALcode configuration options" 120 121// There are a number of options that may be assembled into this version of 122// PALcode. They should be adjusted in a prefix assembly file (i.e. do not edit 123// the following). The options that can be adjusted cause the resultant PALcode 124// to reflect the desired target system. 125 126// multiprocessor support can be enabled for a max of n processors by 127// setting the following to the number of processors on the system. 128// Note that this is really the max cpuid. 129 130#define max_cpuid 1 131#ifndef max_cpuid 132#define max_cpuid 8 133#endif 134 135#define osf_svmin 1 136#define osfpal_version_h ((max_cpuid<<16) | (osf_svmin<<0)) 137 138// 139// RESET - Reset Trap Entry Point 140// 141// RESET - offset 0000 142// Entry: 143// Vectored into via hardware trap on reset, or branched to 144// on swppal. 145// 146// r0 = whami 147// r1 = pal_base 148// r2 = base of scratch area 149// r3 = halt code 150// 151// 152// Function: 153// 154// 155 156 .text 0 157 . = 0x0000 158 .globl _start 159 .globl Pal_Base 160_start: 161Pal_Base: 162 HDW_VECTOR(PAL_RESET_ENTRY) 163Trap_Reset: 164 nop 165 /* 166 * store into r1 167 */ 168 br r1,sys_reset 169 170 // Specify PAL version info as a constant 171 // at a known location (reset + 8). 172 173 .long osfpal_version_l // <pal_type@16> ! <vmaj@8> ! <vmin@0> 174 .long osfpal_version_h // <max_cpuid@16> ! <osf_svmin@0> 175 .long 0 176 .long 0 177pal_impure_start: 178 .quad 0 179pal_debug_ptr: 180 .quad 0 // reserved for debug pointer ; 20 181 182 183// 184// IACCVIO - Istream Access Violation Trap Entry Point 185// 186// IACCVIO - offset 0080 187// Entry: 188// Vectored into via hardware trap on Istream access violation or sign check error on PC. 189// 190// Function: 191// Build stack frame 192// a0 <- Faulting VA 193// a1 <- MMCSR (1 for ACV) 194// a2 <- -1 (for ifetch fault) 195// vector via entMM 196// 197 198 HDW_VECTOR(PAL_IACCVIO_ENTRY) 199Trap_Iaccvio: 200 DEBUGSTORE(0x42) 201 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 202 mtpr r31, ev5__ps // Set Ibox current mode to kernel 203 204 bis r11, r31, r12 // Save PS 205 bge r25, TRAP_IACCVIO_10_ // no stack swap needed if cm=kern 206 207 208 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 209 // no virt ref for next 2 cycles 210 mtpr r30, pt_usp // save user stack 211 212 bis r31, r31, r12 // Set new PS 213 mfpr r30, pt_ksp 214 215TRAP_IACCVIO_10_: 216 lda sp, 0-osfsf_c_size(sp)// allocate stack space 217 mfpr r14, exc_addr // get pc 218 219 stq r16, osfsf_a0(sp) // save regs 220 bic r14, 3, r16 // pass pc/va as a0 221 222 stq r17, osfsf_a1(sp) // a1 223 or r31, mmcsr_c_acv, r17 // pass mm_csr as a1 224 225 stq r18, osfsf_a2(sp) // a2 226 mfpr r13, pt_entmm // get entry point 227 228 stq r11, osfsf_ps(sp) // save old ps 229 bis r12, r31, r11 // update ps 230 231 stq r16, osfsf_pc(sp) // save pc 232 stq r29, osfsf_gp(sp) // save gp 233 234 mtpr r13, exc_addr // load exc_addr with entMM 235 // 1 cycle to hw_rei 236 mfpr r29, pt_kgp // get the kgp 237 238 subq r31, 1, r18 // pass flag of istream, as a2 239 hw_rei_spe 240 241 242// 243// INTERRUPT - Interrupt Trap Entry Point 244// 245// INTERRUPT - offset 0100 246// Entry: 247// Vectored into via trap on hardware interrupt 248// 249// Function: 250// check for halt interrupt 251// check for passive release (current ipl geq requestor) 252// if necessary, switch to kernel mode push stack frame, 253// update ps (including current mode and ipl copies), sp, and gp 254// pass the interrupt info to the system module 255// 256// 257 HDW_VECTOR(PAL_INTERRUPT_ENTRY) 258Trap_Interrupt: 259 mfpr r13, ev5__intid // Fetch level of interruptor 260 mfpr r25, ev5__isr // Fetch interrupt summary register 261 262 srl r25, isr_v_hlt, r9 // Get HLT bit 263 mfpr r14, ev5__ipl 264 265 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kern 266 blbs r9, sys_halt_interrupt // halt_interrupt if HLT bit set 267 268 cmple r13, r14, r8 // R8 = 1 if intid .less than or eql. ipl 269 bne r8, sys_passive_release // Passive release is current rupt is lt or eq ipl 270 271 and r11, osfps_m_mode, r10 // get mode bit 272 beq r10, TRAP_INTERRUPT_10_ // Skip stack swap in kernel 273 274 mtpr r30, pt_usp // save user stack 275 mfpr r30, pt_ksp // get kern stack 276 277TRAP_INTERRUPT_10_: 278 lda sp, (0-osfsf_c_size)(sp)// allocate stack space 279 mfpr r14, exc_addr // get pc 280 281 stq r11, osfsf_ps(sp) // save ps 282 stq r14, osfsf_pc(sp) // save pc 283 284 stq r29, osfsf_gp(sp) // push gp 285 stq r16, osfsf_a0(sp) // a0 286 287// pvc_violate 354 // ps is cleared anyway, if store to stack faults. 288 mtpr r31, ev5__ps // Set Ibox current mode to kernel 289 stq r17, osfsf_a1(sp) // a1 290 291 stq r18, osfsf_a2(sp) // a2 292 subq r13, 0x11, r12 // Start to translate from EV5IPL->OSFIPL 293 294 srl r12, 1, r8 // 1d, 1e: ipl 6. 1f: ipl 7. 295 subq r13, 0x1d, r9 // Check for 1d, 1e, 1f 296 297 cmovge r9, r8, r12 // if .ge. 1d, then take shifted value 298 bis r12, r31, r11 // set new ps 299 300 mfpr r12, pt_intmask 301 and r11, osfps_m_ipl, r14 // Isolate just new ipl (not really needed, since all non-ipl bits zeroed already) 302 303 /* 304 * Lance had space problems. We don't. 305 */ 306 extbl r12, r14, r14 // Translate new OSFIPL->EV5IPL 307 mfpr r29, pt_kgp // update gp 308 mtpr r14, ev5__ipl // load the new IPL into Ibox 309 br r31, sys_interrupt // Go handle interrupt 310 311 312 313// 314// ITBMISS - Istream TBmiss Trap Entry Point 315// 316// ITBMISS - offset 0180 317// Entry: 318// Vectored into via hardware trap on Istream translation buffer miss. 319// 320// Function: 321// Do a virtual fetch of the PTE, and fill the ITB if the PTE is valid. 322// Can trap into DTBMISS_DOUBLE. 323// This routine can use the PALshadow registers r8, r9, and r10 324// 325// 326 327 HDW_VECTOR(PAL_ITB_MISS_ENTRY) 328Trap_Itbmiss: 329 // Real MM mapping 330 nop 331 mfpr r8, ev5__ifault_va_form // Get virtual address of PTE. 332 333 nop 334 mfpr r10, exc_addr // Get PC of faulting instruction in case of DTBmiss. 335 336pal_itb_ldq: 337 ld_vpte r8, 0(r8) // Get PTE, traps to DTBMISS_DOUBLE in case of TBmiss 338 mtpr r10, exc_addr // Restore exc_address if there was a trap. 339 340 mfpr r31, ev5__va // Unlock VA in case there was a double miss 341 nop 342 343 and r8, osfpte_m_foe, r25 // Look for FOE set. 344 blbc r8, invalid_ipte_handler // PTE not valid. 345 346 nop 347 bne r25, foe_ipte_handler // FOE is set 348 349 nop 350 mtpr r8, ev5__itb_pte // Ibox remembers the VA, load the PTE into the ITB. 351 352 hw_rei_stall // 353 354 355// 356// DTBMISS_SINGLE - Dstream Single TBmiss Trap Entry Point 357// 358// DTBMISS_SINGLE - offset 0200 359// Entry: 360// Vectored into via hardware trap on Dstream single translation 361// buffer miss. 362// 363// Function: 364// Do a virtual fetch of the PTE, and fill the DTB if the PTE is valid. 365// Can trap into DTBMISS_DOUBLE. 366// This routine can use the PALshadow registers r8, r9, and r10 367// 368 369 HDW_VECTOR(PAL_DTB_MISS_ENTRY) 370Trap_Dtbmiss_Single: 371 mfpr r8, ev5__va_form // Get virtual address of PTE - 1 cycle delay. E0. 372 mfpr r10, exc_addr // Get PC of faulting instruction in case of error. E1. 373 374// DEBUGSTORE(0x45) 375// DEBUG_EXC_ADDR() 376 // Real MM mapping 377 mfpr r9, ev5__mm_stat // Get read/write bit. E0. 378 mtpr r10, pt6 // Stash exc_addr away 379 380pal_dtb_ldq: 381 ld_vpte r8, 0(r8) // Get PTE, traps to DTBMISS_DOUBLE in case of TBmiss 382 nop // Pad MF VA 383 384 mfpr r10, ev5__va // Get original faulting VA for TB load. E0. 385 nop 386 387 mtpr r8, ev5__dtb_pte // Write DTB PTE part. E0. 388 blbc r8, invalid_dpte_handler // Handle invalid PTE 389 390 mtpr r10, ev5__dtb_tag // Write DTB TAG part, completes DTB load. No virt ref for 3 cycles. 391 mfpr r10, pt6 392 393 // Following 2 instructions take 2 cycles 394 mtpr r10, exc_addr // Return linkage in case we trapped. E1. 395 mfpr r31, pt0 // Pad the write to dtb_tag 396 397 hw_rei // Done, return 398 399 400// 401// DTBMISS_DOUBLE - Dstream Double TBmiss Trap Entry Point 402// 403// 404// DTBMISS_DOUBLE - offset 0280 405// Entry: 406// Vectored into via hardware trap on Double TBmiss from single 407// miss flows. 408// 409// r8 - faulting VA 410// r9 - original MMstat 411// r10 - original exc_addr (both itb,dtb miss) 412// pt6 - original exc_addr (dtb miss flow only) 413// VA IPR - locked with original faulting VA 414// 415// Function: 416// Get PTE, if valid load TB and return. 417// If not valid then take TNV/ACV exception. 418// 419// pt4 and pt5 are reserved for this flow. 420// 421// 422// 423 424 HDW_VECTOR(PAL_DOUBLE_MISS_ENTRY) 425Trap_Dtbmiss_double: 426 mtpr r8, pt4 // save r8 to do exc_addr check 427 mfpr r8, exc_addr 428 blbc r8, Trap_Dtbmiss_Single //if not in palmode, should be in the single routine, dummy! 429 mfpr r8, pt4 // restore r8 430 nop 431 mtpr r22, pt5 // Get some scratch space. E1. 432 // Due to virtual scheme, we can skip the first lookup and go 433 // right to fetch of level 2 PTE 434 sll r8, (64-((2*page_seg_size_bits)+page_offset_size_bits)), r22 // Clean off upper bits of VA 435 mtpr r21, pt4 // Get some scratch space. E1. 436 437 srl r22, 61-page_seg_size_bits, r22 // Get Va<seg1>*8 438 mfpr r21, pt_ptbr // Get physical address of the page table. 439 440 nop 441 addq r21, r22, r21 // Index into page table for level 2 PTE. 442 443 sll r8, (64-((1*page_seg_size_bits)+page_offset_size_bits)), r22 // Clean off upper bits of VA 444 ldq_p r21, 0(r21) // Get level 2 PTE (addr<2:0> ignored) 445 446 srl r22, 61-page_seg_size_bits, r22 // Get Va<seg1>*8 447 blbc r21, double_pte_inv // Check for Invalid PTE. 448 449 srl r21, 32, r21 // extract PFN from PTE 450 sll r21, page_offset_size_bits, r21 // get PFN * 2^13 for add to <seg3>*8 451 452 addq r21, r22, r21 // Index into page table for level 3 PTE. 453 nop 454 455 ldq_p r21, 0(r21) // Get level 3 PTE (addr<2:0> ignored) 456 blbc r21, double_pte_inv // Check for invalid PTE. 457 458 mtpr r21, ev5__dtb_pte // Write the PTE. E0. 459 mfpr r22, pt5 // Restore scratch register 460 461 mtpr r8, ev5__dtb_tag // Write the TAG. E0. No virtual references in subsequent 3 cycles. 462 mfpr r21, pt4 // Restore scratch register 463 464 nop // Pad write to tag. 465 nop 466 467 nop // Pad write to tag. 468 nop 469 470 hw_rei 471 472 473 474// 475// UNALIGN -- Dstream unalign trap 476// 477// UNALIGN - offset 0300 478// Entry: 479// Vectored into via hardware trap on unaligned Dstream reference. 480// 481// Function: 482// Build stack frame 483// a0 <- Faulting VA 484// a1 <- Opcode 485// a2 <- src/dst register number 486// vector via entUna 487// 488 489 HDW_VECTOR(PAL_UNALIGN_ENTRY) 490Trap_Unalign: 491/* DEBUGSTORE(0x47)*/ 492 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 493 mtpr r31, ev5__ps // Set Ibox current mode to kernel 494 495 mfpr r8, ev5__mm_stat // Get mmstat --ok to use r8, no tbmiss 496 mfpr r14, exc_addr // get pc 497 498 srl r8, mm_stat_v_ra, r13 // Shift Ra field to ls bits 499 blbs r14, pal_pal_bug_check // Bugcheck if unaligned in PAL 500 501 blbs r8, UNALIGN_NO_DISMISS // lsb only set on store or fetch_m 502 // not set, must be a load 503 and r13, 0x1F, r8 // isolate ra 504 505 cmpeq r8, 0x1F, r8 // check for r31/F31 506 bne r8, dfault_fetch_ldr31_err // if its a load to r31 or f31 -- dismiss the fault 507 508UNALIGN_NO_DISMISS: 509 bis r11, r31, r12 // Save PS 510 bge r25, UNALIGN_NO_DISMISS_10_ // no stack swap needed if cm=kern 511 512 513 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 514 // no virt ref for next 2 cycles 515 mtpr r30, pt_usp // save user stack 516 517 bis r31, r31, r12 // Set new PS 518 mfpr r30, pt_ksp 519 520UNALIGN_NO_DISMISS_10_: 521 mfpr r25, ev5__va // Unlock VA 522 lda sp, 0-osfsf_c_size(sp)// allocate stack space 523 524 mtpr r25, pt0 // Stash VA 525 stq r18, osfsf_a2(sp) // a2 526 527 stq r11, osfsf_ps(sp) // save old ps 528 srl r13, mm_stat_v_opcode-mm_stat_v_ra, r25// Isolate opcode 529 530 stq r29, osfsf_gp(sp) // save gp 531 addq r14, 4, r14 // inc PC past the ld/st 532 533 stq r17, osfsf_a1(sp) // a1 534 and r25, mm_stat_m_opcode, r17// Clean opocde for a1 535 536 stq r16, osfsf_a0(sp) // save regs 537 mfpr r16, pt0 // a0 <- va/unlock 538 539 stq r14, osfsf_pc(sp) // save pc 540 mfpr r25, pt_entuna // get entry point 541 542 543 bis r12, r31, r11 // update ps 544 br r31, unalign_trap_cont 545 546 547// 548// DFAULT - Dstream Fault Trap Entry Point 549// 550// DFAULT - offset 0380 551// Entry: 552// Vectored into via hardware trap on dstream fault or sign check 553// error on DVA. 554// 555// Function: 556// Ignore faults on FETCH/FETCH_M 557// Check for DFAULT in PAL 558// Build stack frame 559// a0 <- Faulting VA 560// a1 <- MMCSR (1 for ACV, 2 for FOR, 4 for FOW) 561// a2 <- R/W 562// vector via entMM 563// 564// 565 HDW_VECTOR(PAL_D_FAULT_ENTRY) 566Trap_Dfault: 567// DEBUGSTORE(0x48) 568 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 569 mtpr r31, ev5__ps // Set Ibox current mode to kernel 570 571 mfpr r13, ev5__mm_stat // Get mmstat 572 mfpr r8, exc_addr // get pc, preserve r14 573 574 srl r13, mm_stat_v_opcode, r9 // Shift opcode field to ls bits 575 blbs r8, dfault_in_pal 576 577 bis r8, r31, r14 // move exc_addr to correct place 578 bis r11, r31, r12 // Save PS 579 580 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 581 // no virt ref for next 2 cycles 582 and r9, mm_stat_m_opcode, r9 // Clean all but opcode 583 584 cmpeq r9, evx_opc_sync, r9 // Is the opcode fetch/fetchm? 585 bne r9, dfault_fetch_ldr31_err // Yes, dismiss the fault 586 587 //dismiss exception if load to r31/f31 588 blbs r13, dfault_no_dismiss // mm_stat<0> set on store or fetchm 589 590 // not a store or fetch, must be a load 591 srl r13, mm_stat_v_ra, r9 // Shift rnum to low bits 592 593 and r9, 0x1F, r9 // isolate rnum 594 nop 595 596 cmpeq r9, 0x1F, r9 // Is the rnum r31 or f31? 597 bne r9, dfault_fetch_ldr31_err // Yes, dismiss the fault 598 599dfault_no_dismiss: 600 and r13, 0xf, r13 // Clean extra bits in mm_stat 601 bge r25, dfault_trap_cont // no stack swap needed if cm=kern 602 603 604 mtpr r30, pt_usp // save user stack 605 bis r31, r31, r12 // Set new PS 606 607 mfpr r30, pt_ksp 608 br r31, dfault_trap_cont 609 610 611// 612// MCHK - Machine Check Trap Entry Point 613// 614// MCHK - offset 0400 615// Entry: 616// Vectored into via hardware trap on machine check. 617// 618// Function: 619// 620// 621 622 HDW_VECTOR(PAL_MCHK_ENTRY) 623Trap_Mchk: 624 DEBUGSTORE(0x49) 625 mtpr r31, ic_flush_ctl // Flush the Icache 626 br r31, sys_machine_check 627 628 629// 630// OPCDEC - Illegal Opcode Trap Entry Point 631// 632// OPCDEC - offset 0480 633// Entry: 634// Vectored into via hardware trap on illegal opcode. 635// 636// Build stack frame 637// a0 <- code 638// a1 <- unpred 639// a2 <- unpred 640// vector via entIF 641// 642// 643 644 HDW_VECTOR(PAL_OPCDEC_ENTRY) 645Trap_Opcdec: 646 DEBUGSTORE(0x4a) 647//simos DEBUG_EXC_ADDR() 648 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 649 mtpr r31, ev5__ps // Set Ibox current mode to kernel 650 651 mfpr r14, exc_addr // get pc 652 blbs r14, pal_pal_bug_check // check opcdec in palmode 653 654 bis r11, r31, r12 // Save PS 655 bge r25, TRAP_OPCDEC_10_ // no stack swap needed if cm=kern 656 657 658 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 659 // no virt ref for next 2 cycles 660 mtpr r30, pt_usp // save user stack 661 662 bis r31, r31, r12 // Set new PS 663 mfpr r30, pt_ksp 664 665TRAP_OPCDEC_10_: 666 lda sp, 0-osfsf_c_size(sp)// allocate stack space 667 addq r14, 4, r14 // inc pc 668 669 stq r16, osfsf_a0(sp) // save regs 670 bis r31, osf_a0_opdec, r16 // set a0 671 672 stq r11, osfsf_ps(sp) // save old ps 673 mfpr r13, pt_entif // get entry point 674 675 stq r18, osfsf_a2(sp) // a2 676 stq r17, osfsf_a1(sp) // a1 677 678 stq r29, osfsf_gp(sp) // save gp 679 stq r14, osfsf_pc(sp) // save pc 680 681 bis r12, r31, r11 // update ps 682 mtpr r13, exc_addr // load exc_addr with entIF 683 // 1 cycle to hw_rei, E1 684 685 mfpr r29, pt_kgp // get the kgp, E1 686 687 hw_rei_spe // done, E1 688 689 690// 691// ARITH - Arithmetic Exception Trap Entry Point 692// 693// ARITH - offset 0500 694// Entry: 695// Vectored into via hardware trap on arithmetic excpetion. 696// 697// Function: 698// Build stack frame 699// a0 <- exc_sum 700// a1 <- exc_mask 701// a2 <- unpred 702// vector via entArith 703// 704// 705 HDW_VECTOR(PAL_ARITH_ENTRY) 706Trap_Arith: 707 DEBUGSTORE(0x4b) 708 and r11, osfps_m_mode, r12 // get mode bit 709 mfpr r31, ev5__va // unlock mbox 710 711 bis r11, r31, r25 // save ps 712 mfpr r14, exc_addr // get pc 713 714 nop 715 blbs r14, pal_pal_bug_check // arith trap from PAL 716 717 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 718 // no virt ref for next 2 cycles 719 beq r12, TRAP_ARITH_10_ // if zero we are in kern now 720 721 bis r31, r31, r25 // set the new ps 722 mtpr r30, pt_usp // save user stack 723 724 nop 725 mfpr r30, pt_ksp // get kern stack 726 727TRAP_ARITH_10_: lda sp, 0-osfsf_c_size(sp) // allocate stack space 728 mtpr r31, ev5__ps // Set Ibox current mode to kernel 729 730 nop // Pad current mode write and stq 731 mfpr r13, ev5__exc_sum // get the exc_sum 732 733 mfpr r12, pt_entarith 734 stq r14, osfsf_pc(sp) // save pc 735 736 stq r17, osfsf_a1(sp) 737 mfpr r17, ev5__exc_mask // Get exception register mask IPR - no mtpr exc_sum in next cycle 738 739 stq r11, osfsf_ps(sp) // save ps 740 bis r25, r31, r11 // set new ps 741 742 stq r16, osfsf_a0(sp) // save regs 743 srl r13, exc_sum_v_swc, r16 // shift data to correct position 744 745 stq r18, osfsf_a2(sp) 746// pvc_violate 354 // ok, but make sure reads of exc_mask/sum are not in same trap shadow 747 mtpr r31, ev5__exc_sum // Unlock exc_sum and exc_mask 748 749 stq r29, osfsf_gp(sp) 750 mtpr r12, exc_addr // Set new PC - 1 bubble to hw_rei - E1 751 752 mfpr r29, pt_kgp // get the kern gp - E1 753 hw_rei_spe // done - E1 754 755 756// 757// FEN - Illegal Floating Point Operation Trap Entry Point 758// 759// FEN - offset 0580 760// Entry: 761// Vectored into via hardware trap on illegal FP op. 762// 763// Function: 764// Build stack frame 765// a0 <- code 766// a1 <- unpred 767// a2 <- unpred 768// vector via entIF 769// 770// 771 772 HDW_VECTOR(PAL_FEN_ENTRY) 773Trap_Fen: 774 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 775 mtpr r31, ev5__ps // Set Ibox current mode to kernel 776 777 mfpr r14, exc_addr // get pc 778 blbs r14, pal_pal_bug_check // check opcdec in palmode 779 780 mfpr r13, ev5__icsr 781 nop 782 783 bis r11, r31, r12 // Save PS 784 bge r25, TRAP_FEN_10_ // no stack swap needed if cm=kern 785 786 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 787 // no virt ref for next 2 cycles 788 mtpr r30, pt_usp // save user stack 789 790 bis r31, r31, r12 // Set new PS 791 mfpr r30, pt_ksp 792 793TRAP_FEN_10_: 794 lda sp, 0-osfsf_c_size(sp)// allocate stack space 795 srl r13, icsr_v_fpe, r25 // Shift FP enable to bit 0 796 797 798 stq r16, osfsf_a0(sp) // save regs 799 mfpr r13, pt_entif // get entry point 800 801 stq r18, osfsf_a2(sp) // a2 802 stq r11, osfsf_ps(sp) // save old ps 803 804 stq r29, osfsf_gp(sp) // save gp 805 bis r12, r31, r11 // set new ps 806 807 stq r17, osfsf_a1(sp) // a1 808 blbs r25,fen_to_opcdec // If FP is enabled, this is really OPCDEC. 809 810 bis r31, osf_a0_fen, r16 // set a0 811 stq r14, osfsf_pc(sp) // save pc 812 813 mtpr r13, exc_addr // load exc_addr with entIF 814 // 1 cycle to hw_rei -E1 815 816 mfpr r29, pt_kgp // get the kgp -E1 817 818 hw_rei_spe // done -E1 819 820// FEN trap was taken, but the fault is really opcdec. 821 ALIGN_BRANCH 822fen_to_opcdec: 823 addq r14, 4, r14 // save PC+4 824 bis r31, osf_a0_opdec, r16 // set a0 825 826 stq r14, osfsf_pc(sp) // save pc 827 mtpr r13, exc_addr // load exc_addr with entIF 828 // 1 cycle to hw_rei 829 830 mfpr r29, pt_kgp // get the kgp 831 hw_rei_spe // done 832 833 834 835////////////////////////////////////////////////////////////////////////////// 836// Misc handlers - Start area for misc code. 837////////////////////////////////////////////////////////////////////////////// 838 839// 840// dfault_trap_cont 841// A dfault trap has been taken. The sp has been updated if necessary. 842// Push a stack frame a vector via entMM. 843// 844// Current state: 845// r12 - new PS 846// r13 - MMstat 847// VA - locked 848// 849// 850 ALIGN_BLOCK 851dfault_trap_cont: 852 lda sp, 0-osfsf_c_size(sp)// allocate stack space 853 mfpr r25, ev5__va // Fetch VA/unlock 854 855 stq r18, osfsf_a2(sp) // a2 856 and r13, 1, r18 // Clean r/w bit for a2 857 858 stq r16, osfsf_a0(sp) // save regs 859 bis r25, r31, r16 // a0 <- va 860 861 stq r17, osfsf_a1(sp) // a1 862 srl r13, 1, r17 // shift fault bits to right position 863 864 stq r11, osfsf_ps(sp) // save old ps 865 bis r12, r31, r11 // update ps 866 867 stq r14, osfsf_pc(sp) // save pc 868 mfpr r25, pt_entmm // get entry point 869 870 stq r29, osfsf_gp(sp) // save gp 871 cmovlbs r17, 1, r17 // a2. acv overrides fox. 872 873 mtpr r25, exc_addr // load exc_addr with entMM 874 // 1 cycle to hw_rei 875 mfpr r29, pt_kgp // get the kgp 876 877 hw_rei_spe // done 878 879// 880//unalign_trap_cont 881// An unalign trap has been taken. Just need to finish up a few things. 882// 883// Current state: 884// r25 - entUna 885// r13 - shifted MMstat 886// 887// 888 ALIGN_BLOCK 889unalign_trap_cont: 890 mtpr r25, exc_addr // load exc_addr with entUna 891 // 1 cycle to hw_rei 892 893 894 mfpr r29, pt_kgp // get the kgp 895 and r13, mm_stat_m_ra, r18 // Clean Ra for a2 896 897 hw_rei_spe // done 898 899 900 901// 902// dfault_in_pal 903// Dfault trap was taken, exc_addr points to a PAL PC. 904// r9 - mmstat<opcode> right justified 905// r8 - exception address 906// 907// These are the cases: 908// opcode was STQ -- from a stack builder, KSP not valid halt 909// r14 - original exc_addr 910// r11 - original PS 911// opcode was STL_C -- rti or retsys clear lock_flag by stack write, 912// KSP not valid halt 913// r11 - original PS 914// r14 - original exc_addr 915// opcode was LDQ -- retsys or rti stack read, KSP not valid halt 916// r11 - original PS 917// r14 - original exc_addr 918// opcode was HW_LD -- itbmiss or dtbmiss, bugcheck due to fault on page tables 919// r10 - original exc_addr 920// r11 - original PS 921// 922// 923// 924 ALIGN_BLOCK 925dfault_in_pal: 926 DEBUGSTORE(0x50) 927 bic r8, 3, r8 // Clean PC 928 mfpr r9, pal_base 929 930 mfpr r31, va // unlock VA 931 932 // if not real_mm, should never get here from miss flows 933 934 subq r9, r8, r8 // pal_base - offset 935 936 lda r9, pal_itb_ldq-pal_base(r8) 937 nop 938 939 beq r9, dfault_do_bugcheck 940 lda r9, pal_dtb_ldq-pal_base(r8) 941 942 beq r9, dfault_do_bugcheck 943 944// 945// KSP invalid halt case -- 946ksp_inval_halt: 947 DEBUGSTORE(76) 948 bic r11, osfps_m_mode, r11 // set ps to kernel mode 949 mtpr r0, pt0 950 951 mtpr r31, dtb_cm // Make sure that the CM IPRs are all kernel mode 952 mtpr r31, ips 953 954 mtpr r14, exc_addr // Set PC to instruction that caused trouble 955 bsr r0, pal_update_pcb // update the pcb 956 957 lda r0, hlt_c_ksp_inval(r31) // set halt code to hw halt 958 br r31, sys_enter_console // enter the console 959 960 ALIGN_BRANCH 961dfault_do_bugcheck: 962 bis r10, r31, r14 // bugcheck expects exc_addr in r14 963 br r31, pal_pal_bug_check 964 965 966// 967// dfault_fetch_ldr31_err - ignore faults on fetch(m) and loads to r31/f31 968// On entry - 969// r14 - exc_addr 970// VA is locked 971// 972// 973 ALIGN_BLOCK 974dfault_fetch_ldr31_err: 975 mtpr r11, ev5__dtb_cm 976 mtpr r11, ev5__ps // Make sure ps hasn't changed 977 978 mfpr r31, va // unlock the mbox 979 addq r14, 4, r14 // inc the pc to skip the fetch 980 981 mtpr r14, exc_addr // give ibox new PC 982 mfpr r31, pt0 // pad exc_addr write 983 984 hw_rei 985 986 987 988 ALIGN_BLOCK 989// 990// sys_from_kern 991// callsys from kernel mode - OS bugcheck machine check 992// 993// 994sys_from_kern: 995 mfpr r14, exc_addr // PC points to call_pal 996 subq r14, 4, r14 997 998 lda r25, mchk_c_os_bugcheck(r31) // fetch mchk code 999 br r31, pal_pal_mchk 1000 1001 1002// Continuation of long call_pal flows 1003// 1004// wrent_tbl 1005// Table to write *int in paltemps. 1006// 4 instructions/entry 1007// r16 has new value 1008// 1009// 1010 ALIGN_BLOCK 1011wrent_tbl: 1012//orig pvc_jsr wrent, dest=1 1013 nop 1014 mtpr r16, pt_entint 1015 1016 mfpr r31, pt0 // Pad for mt->mf paltemp rule 1017 hw_rei 1018 1019 1020//orig pvc_jsr wrent, dest=1 1021 nop 1022 mtpr r16, pt_entarith 1023 1024 mfpr r31, pt0 // Pad for mt->mf paltemp rule 1025 hw_rei 1026 1027 1028//orig pvc_jsr wrent, dest=1 1029 nop 1030 mtpr r16, pt_entmm 1031 1032 mfpr r31, pt0 // Pad for mt->mf paltemp rule 1033 hw_rei 1034 1035 1036//orig pvc_jsr wrent, dest=1 1037 nop 1038 mtpr r16, pt_entif 1039 1040 mfpr r31, pt0 // Pad for mt->mf paltemp rule 1041 hw_rei 1042 1043 1044//orig pvc_jsr wrent, dest=1 1045 nop 1046 mtpr r16, pt_entuna 1047 1048 mfpr r31, pt0 // Pad for mt->mf paltemp rule 1049 hw_rei 1050 1051 1052//orig pvc_jsr wrent, dest=1 1053 nop 1054 mtpr r16, pt_entsys 1055 1056 mfpr r31, pt0 // Pad for mt->mf paltemp rule 1057 hw_rei 1058 1059 ALIGN_BLOCK 1060// 1061// tbi_tbl 1062// Table to do tbi instructions 1063// 4 instructions per entry 1064// 1065tbi_tbl: 1066 // -2 tbia 1067//orig pvc_jsr tbi, dest=1 1068 mtpr r31, ev5__dtb_ia // Flush DTB 1069 mtpr r31, ev5__itb_ia // Flush ITB 1070 1071 hw_rei_stall 1072 1073 nop // Pad table 1074 1075 // -1 tbiap 1076//orig pvc_jsr tbi, dest=1 1077 mtpr r31, ev5__dtb_iap // Flush DTB 1078 mtpr r31, ev5__itb_iap // Flush ITB 1079 1080 hw_rei_stall 1081 1082 nop // Pad table 1083 1084 1085 // 0 unused 1086//orig pvc_jsr tbi, dest=1 1087 hw_rei // Pad table 1088 nop 1089 nop 1090 nop 1091 1092 1093 // 1 tbisi 1094//orig pvc_jsr tbi, dest=1 1095 1096 nop 1097 nop 1098 mtpr r17, ev5__itb_is // Flush ITB 1099 hw_rei_stall 1100 1101 // 2 tbisd 1102//orig pvc_jsr tbi, dest=1 1103 mtpr r17, ev5__dtb_is // Flush DTB. 1104 nop 1105 1106 nop 1107 hw_rei_stall 1108 1109 1110 // 3 tbis 1111//orig pvc_jsr tbi, dest=1 1112 mtpr r17, ev5__dtb_is // Flush DTB 1113 br r31, tbi_finish 1114 ALIGN_BRANCH 1115tbi_finish: 1116 mtpr r17, ev5__itb_is // Flush ITB 1117 hw_rei_stall 1118 1119 1120 1121 ALIGN_BLOCK 1122// 1123// bpt_bchk_common: 1124// Finish up the bpt/bchk instructions 1125// 1126bpt_bchk_common: 1127 stq r18, osfsf_a2(sp) // a2 1128 mfpr r13, pt_entif // get entry point 1129 1130 stq r12, osfsf_ps(sp) // save old ps 1131 stq r14, osfsf_pc(sp) // save pc 1132 1133 stq r29, osfsf_gp(sp) // save gp 1134 mtpr r13, exc_addr // load exc_addr with entIF 1135 // 1 cycle to hw_rei 1136 1137 mfpr r29, pt_kgp // get the kgp 1138 1139 1140 hw_rei_spe // done 1141 1142 1143 ALIGN_BLOCK 1144// 1145// rti_to_user 1146// Finish up the rti instruction 1147// 1148rti_to_user: 1149 mtpr r11, ev5__dtb_cm // set Mbox current mode - no virt ref for 2 cycles 1150 mtpr r11, ev5__ps // set Ibox current mode - 2 bubble to hw_rei 1151 1152 mtpr r31, ev5__ipl // set the ipl. No hw_rei for 2 cycles 1153 mtpr r25, pt_ksp // save off incase RTI to user 1154 1155 mfpr r30, pt_usp 1156 hw_rei_spe // and back 1157 1158 1159 ALIGN_BLOCK 1160// 1161// rti_to_kern 1162// Finish up the rti instruction 1163// 1164rti_to_kern: 1165 and r12, osfps_m_ipl, r11 // clean ps 1166 mfpr r12, pt_intmask // get int mask 1167 1168 extbl r12, r11, r12 // get mask for this ipl 1169 mtpr r25, pt_ksp // save off incase RTI to user 1170 1171 mtpr r12, ev5__ipl // set the new ipl. 1172 or r25, r31, sp // sp 1173 1174// pvc_violate 217 // possible hidden mt->mf ipl not a problem in callpals 1175 hw_rei 1176 1177 ALIGN_BLOCK 1178// 1179// swpctx_cont 1180// Finish up the swpctx instruction 1181// 1182 1183swpctx_cont: 1184 1185 bic r25, r24, r25 // clean icsr<FPE,PMP> 1186 sll r12, icsr_v_fpe, r12 // shift new fen to pos 1187 1188 ldq_p r14, osfpcb_q_mmptr(r16)// get new mmptr 1189 srl r22, osfpcb_v_pme, r22 // get pme down to bit 0 1190 1191 or r25, r12, r25 // icsr with new fen 1192 srl r23, 32, r24 // move asn to low asn pos 1193 1194 and r22, 1, r22 1195 sll r24, itb_asn_v_asn, r12 1196 1197 sll r22, icsr_v_pmp, r22 1198 nop 1199 1200 or r25, r22, r25 // icsr with new pme 1201 1202 sll r24, dtb_asn_v_asn, r24 1203 1204 subl r23, r13, r13 // gen new cc offset 1205 mtpr r12, itb_asn // no hw_rei_stall in 0,1,2,3,4 1206 1207 mtpr r24, dtb_asn // Load up new ASN 1208 mtpr r25, icsr // write the icsr 1209 1210 sll r14, page_offset_size_bits, r14 // Move PTBR into internal position. 1211 ldq_p r25, osfpcb_q_usp(r16) // get new usp 1212 1213 insll r13, 4, r13 // >> 32 1214// pvc_violate 379 // ldq_p can't trap except replay. only problem if mf same ipr in same shadow 1215 mtpr r14, pt_ptbr // load the new ptbr 1216 1217 mtpr r13, cc // set new offset 1218 ldq_p r30, osfpcb_q_ksp(r16) // get new ksp 1219 1220// pvc_violate 379 // ldq_p can't trap except replay. only problem if mf same ipr in same shadow 1221 mtpr r25, pt_usp // save usp 1222 1223no_pm_change_10_: hw_rei_stall // back we go 1224 1225 ALIGN_BLOCK 1226// 1227// swppal_cont - finish up the swppal call_pal 1228// 1229 1230swppal_cont: 1231 mfpr r2, pt_misc // get misc bits 1232 sll r0, pt_misc_v_switch, r0 // get the "I've switched" bit 1233 or r2, r0, r2 // set the bit 1234 mtpr r31, ev5__alt_mode // ensure alt_mode set to 0 (kernel) 1235 mtpr r2, pt_misc // update the chip 1236 1237 or r3, r31, r4 1238 mfpr r3, pt_impure // pass pointer to the impure area in r3 1239//orig fix_impure_ipr r3 // adjust impure pointer for ipr read 1240//orig restore_reg1 bc_ctl, r1, r3, ipr=1 // pass cns_bc_ctl in r1 1241//orig restore_reg1 bc_config, r2, r3, ipr=1 // pass cns_bc_config in r2 1242//orig unfix_impure_ipr r3 // restore impure pointer 1243 lda r3, CNS_Q_IPR(r3) 1244 RESTORE_SHADOW(r1,CNS_Q_BC_CTL,r3); 1245 RESTORE_SHADOW(r1,CNS_Q_BC_CFG,r3); 1246 lda r3, -CNS_Q_IPR(r3) 1247 1248 or r31, r31, r0 // set status to success 1249// pvc_violate 1007 1250 jmp r31, (r4) // and call our friend, it's her problem now 1251 1252 1253swppal_fail: 1254 addq r0, 1, r0 // set unknown pal or not loaded 1255 hw_rei // and return 1256 1257 1258// .sbttl "Memory management" 1259 1260 ALIGN_BLOCK 1261// 1262//foe_ipte_handler 1263// IFOE detected on level 3 pte, sort out FOE vs ACV 1264// 1265// on entry: 1266// with 1267// R8 = pte 1268// R10 = pc 1269// 1270// Function 1271// Determine TNV vs ACV vs FOE. Build stack and dispatch 1272// Will not be here if TNV. 1273// 1274 1275foe_ipte_handler: 1276 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 1277 mtpr r31, ev5__ps // Set Ibox current mode to kernel 1278 1279 bis r11, r31, r12 // Save PS for stack write 1280 bge r25, foe_ipte_handler_10_ // no stack swap needed if cm=kern 1281 1282 1283 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 1284 // no virt ref for next 2 cycles 1285 mtpr r30, pt_usp // save user stack 1286 1287 bis r31, r31, r11 // Set new PS 1288 mfpr r30, pt_ksp 1289 1290 srl r8, osfpte_v_ure-osfpte_v_kre, r8 // move pte user bits to kern 1291 nop 1292 1293foe_ipte_handler_10_: srl r8, osfpte_v_kre, r25 // get kre to <0> 1294 lda sp, 0-osfsf_c_size(sp)// allocate stack space 1295 1296 or r10, r31, r14 // Save pc/va in case TBmiss or fault on stack 1297 mfpr r13, pt_entmm // get entry point 1298 1299 stq r16, osfsf_a0(sp) // a0 1300 or r14, r31, r16 // pass pc/va as a0 1301 1302 stq r17, osfsf_a1(sp) // a1 1303 nop 1304 1305 stq r18, osfsf_a2(sp) // a2 1306 lda r17, mmcsr_c_acv(r31) // assume ACV 1307 1308 stq r16, osfsf_pc(sp) // save pc 1309 cmovlbs r25, mmcsr_c_foe, r17 // otherwise FOE 1310 1311 stq r12, osfsf_ps(sp) // save ps 1312 subq r31, 1, r18 // pass flag of istream as a2 1313 1314 stq r29, osfsf_gp(sp) 1315 mtpr r13, exc_addr // set vector address 1316 1317 mfpr r29, pt_kgp // load kgp 1318 hw_rei_spe // out to exec 1319 1320 ALIGN_BLOCK 1321// 1322//invalid_ipte_handler 1323// TNV detected on level 3 pte, sort out TNV vs ACV 1324// 1325// on entry: 1326// with 1327// R8 = pte 1328// R10 = pc 1329// 1330// Function 1331// Determine TNV vs ACV. Build stack and dispatch. 1332// 1333 1334invalid_ipte_handler: 1335 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 1336 mtpr r31, ev5__ps // Set Ibox current mode to kernel 1337 1338 bis r11, r31, r12 // Save PS for stack write 1339 bge r25, invalid_ipte_handler_10_ // no stack swap needed if cm=kern 1340 1341 1342 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 1343 // no virt ref for next 2 cycles 1344 mtpr r30, pt_usp // save user stack 1345 1346 bis r31, r31, r11 // Set new PS 1347 mfpr r30, pt_ksp 1348 1349 srl r8, osfpte_v_ure-osfpte_v_kre, r8 // move pte user bits to kern 1350 nop 1351 1352invalid_ipte_handler_10_: srl r8, osfpte_v_kre, r25 // get kre to <0> 1353 lda sp, 0-osfsf_c_size(sp)// allocate stack space 1354 1355 or r10, r31, r14 // Save pc/va in case TBmiss on stack 1356 mfpr r13, pt_entmm // get entry point 1357 1358 stq r16, osfsf_a0(sp) // a0 1359 or r14, r31, r16 // pass pc/va as a0 1360 1361 stq r17, osfsf_a1(sp) // a1 1362 nop 1363 1364 stq r18, osfsf_a2(sp) // a2 1365 and r25, 1, r17 // Isolate kre 1366 1367 stq r16, osfsf_pc(sp) // save pc 1368 xor r17, 1, r17 // map to acv/tnv as a1 1369 1370 stq r12, osfsf_ps(sp) // save ps 1371 subq r31, 1, r18 // pass flag of istream as a2 1372 1373 stq r29, osfsf_gp(sp) 1374 mtpr r13, exc_addr // set vector address 1375 1376 mfpr r29, pt_kgp // load kgp 1377 hw_rei_spe // out to exec 1378 1379 1380 1381 1382 ALIGN_BLOCK 1383// 1384//invalid_dpte_handler 1385// INVALID detected on level 3 pte, sort out TNV vs ACV 1386// 1387// on entry: 1388// with 1389// R10 = va 1390// R8 = pte 1391// R9 = mm_stat 1392// PT6 = pc 1393// 1394// Function 1395// Determine TNV vs ACV. Build stack and dispatch 1396// 1397 1398 1399invalid_dpte_handler: 1400 mfpr r12, pt6 1401 blbs r12, tnv_in_pal // Special handler if original faulting reference was in PALmode 1402 1403 bis r12, r31, r14 // save PC in case of tbmiss or fault 1404 srl r9, mm_stat_v_opcode, r25 // shift opc to <0> 1405 1406 mtpr r11, pt0 // Save PS for stack write 1407 and r25, mm_stat_m_opcode, r25 // isolate opcode 1408 1409 cmpeq r25, evx_opc_sync, r25 // is it FETCH/FETCH_M? 1410 blbs r25, nmiss_fetch_ldr31_err // yes 1411 1412 //dismiss exception if load to r31/f31 1413 blbs r9, invalid_dpte_no_dismiss // mm_stat<0> set on store or fetchm 1414 1415 // not a store or fetch, must be a load 1416 srl r9, mm_stat_v_ra, r25 // Shift rnum to low bits 1417 1418 and r25, 0x1F, r25 // isolate rnum 1419 nop 1420 1421 cmpeq r25, 0x1F, r25 // Is the rnum r31 or f31? 1422 bne r25, nmiss_fetch_ldr31_err // Yes, dismiss the fault 1423 1424invalid_dpte_no_dismiss: 1425 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 1426 mtpr r31, ev5__ps // Set Ibox current mode to kernel 1427 1428 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 1429 // no virt ref for next 2 cycles 1430 bge r25, invalid_dpte_no_dismiss_10_ // no stack swap needed if cm=kern 1431 1432 srl r8, osfpte_v_ure-osfpte_v_kre, r8 // move pte user bits to kern 1433 mtpr r30, pt_usp // save user stack 1434 1435 bis r31, r31, r11 // Set new PS 1436 mfpr r30, pt_ksp 1437 1438invalid_dpte_no_dismiss_10_: srl r8, osfpte_v_kre, r12 // get kre to <0> 1439 lda sp, 0-osfsf_c_size(sp)// allocate stack space 1440 1441 or r10, r31, r25 // Save va in case TBmiss on stack 1442 and r9, 1, r13 // save r/w flag 1443 1444 stq r16, osfsf_a0(sp) // a0 1445 or r25, r31, r16 // pass va as a0 1446 1447 stq r17, osfsf_a1(sp) // a1 1448 or r31, mmcsr_c_acv, r17 // assume acv 1449 1450 srl r12, osfpte_v_kwe-osfpte_v_kre, r25 // get write enable to <0> 1451 stq r29, osfsf_gp(sp) 1452 1453 stq r18, osfsf_a2(sp) // a2 1454 cmovlbs r13, r25, r12 // if write access move acv based on write enable 1455 1456 or r13, r31, r18 // pass flag of dstream access and read vs write 1457 mfpr r25, pt0 // get ps 1458 1459 stq r14, osfsf_pc(sp) // save pc 1460 mfpr r13, pt_entmm // get entry point 1461 1462 stq r25, osfsf_ps(sp) // save ps 1463 mtpr r13, exc_addr // set vector address 1464 1465 mfpr r29, pt_kgp // load kgp 1466 cmovlbs r12, mmcsr_c_tnv, r17 // make p2 be tnv if access ok else acv 1467 1468 hw_rei_spe // out to exec 1469 1470// 1471// 1472// We come here if we are erring on a dtb_miss, and the instr is a 1473// fetch, fetch_m, of load to r31/f31. 1474// The PC is incremented, and we return to the program. 1475// essentially ignoring the instruction and error. 1476// 1477// 1478 ALIGN_BLOCK 1479nmiss_fetch_ldr31_err: 1480 mfpr r12, pt6 1481 addq r12, 4, r12 // bump pc to pc+4 1482 1483 mtpr r12, exc_addr // and set entry point 1484 mfpr r31, pt0 // pad exc_addr write 1485 1486 hw_rei // 1487 1488 ALIGN_BLOCK 1489// 1490// double_pte_inv 1491// We had a single tbmiss which turned into a double tbmiss which found 1492// an invalid PTE. Return to single miss with a fake pte, and the invalid 1493// single miss flow will report the error. 1494// 1495// on entry: 1496// r21 PTE 1497// r22 available 1498// VA IPR locked with original fault VA 1499// pt4 saved r21 1500// pt5 saved r22 1501// pt6 original exc_addr 1502// 1503// on return to tbmiss flow: 1504// r8 fake PTE 1505// 1506// 1507// 1508double_pte_inv: 1509 srl r21, osfpte_v_kre, r21 // get the kre bit to <0> 1510 mfpr r22, exc_addr // get the pc 1511 1512 lda r22, 4(r22) // inc the pc 1513 lda r8, osfpte_m_prot(r31) // make a fake pte with xre and xwe set 1514 1515 cmovlbc r21, r31, r8 // set to all 0 for acv if pte<kre> is 0 1516 mtpr r22, exc_addr // set for rei 1517 1518 mfpr r21, pt4 // restore regs 1519 mfpr r22, pt5 // restore regs 1520 1521 hw_rei // back to tb miss 1522 1523 ALIGN_BLOCK 1524// 1525//tnv_in_pal 1526// The only places in pal that ld or store are the 1527// stack builders, rti or retsys. Any of these mean we 1528// need to take a ksp not valid halt. 1529// 1530// 1531tnv_in_pal: 1532 1533 1534 br r31, ksp_inval_halt 1535 1536 1537// .sbttl "Icache flush routines" 1538 1539 ALIGN_BLOCK 1540// 1541// Common Icache flush routine. 1542// 1543// 1544// 1545pal_ic_flush: 1546 nop 1547 mtpr r31, ev5__ic_flush_ctl // Icache flush - E1 1548 nop 1549 nop 1550 1551// Now, do 44 NOPs. 3RFB prefetches (24) + IC buffer,IB,slot,issue (20) 1552 nop 1553 nop 1554 nop 1555 nop 1556 1557 nop 1558 nop 1559 nop 1560 nop 1561 1562 nop 1563 nop // 10 1564 1565 nop 1566 nop 1567 nop 1568 nop 1569 1570 nop 1571 nop 1572 nop 1573 nop 1574 1575 nop 1576 nop // 20 1577 1578 nop 1579 nop 1580 nop 1581 nop 1582 1583 nop 1584 nop 1585 nop 1586 nop 1587 1588 nop 1589 nop // 30 1590 nop 1591 nop 1592 nop 1593 nop 1594 1595 nop 1596 nop 1597 nop 1598 nop 1599 1600 nop 1601 nop // 40 1602 1603 nop 1604 nop 1605 1606one_cycle_and_hw_rei: 1607 nop 1608 nop 1609 1610 hw_rei_stall 1611 1612 ALIGN_BLOCK 1613// 1614//osfpal_calpal_opcdec 1615// Here for all opcdec CALL_PALs 1616// 1617// Build stack frame 1618// a0 <- code 1619// a1 <- unpred 1620// a2 <- unpred 1621// vector via entIF 1622// 1623// 1624 1625osfpal_calpal_opcdec: 1626 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 1627 mtpr r31, ev5__ps // Set Ibox current mode to kernel 1628 1629 mfpr r14, exc_addr // get pc 1630 nop 1631 1632 bis r11, r31, r12 // Save PS for stack write 1633 bge r25, osfpal_calpal_opcdec_10_ // no stack swap needed if cm=kern 1634 1635 1636 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 1637 // no virt ref for next 2 cycles 1638 mtpr r30, pt_usp // save user stack 1639 1640 bis r31, r31, r11 // Set new PS 1641 mfpr r30, pt_ksp 1642 1643osfpal_calpal_opcdec_10_: 1644 lda sp, 0-osfsf_c_size(sp)// allocate stack space 1645 nop 1646 1647 stq r16, osfsf_a0(sp) // save regs 1648 bis r31, osf_a0_opdec, r16 // set a0 1649 1650 stq r18, osfsf_a2(sp) // a2 1651 mfpr r13, pt_entif // get entry point 1652 1653 stq r12, osfsf_ps(sp) // save old ps 1654 stq r17, osfsf_a1(sp) // a1 1655 1656 stq r14, osfsf_pc(sp) // save pc 1657 nop 1658 1659 stq r29, osfsf_gp(sp) // save gp 1660 mtpr r13, exc_addr // load exc_addr with entIF 1661 // 1 cycle to hw_rei 1662 1663 mfpr r29, pt_kgp // get the kgp 1664 1665 1666 hw_rei_spe // done 1667 1668 1669 1670 1671 1672// 1673//pal_update_pcb 1674// Update the PCB with the current SP, AST, and CC info 1675// 1676// r0 - return linkage 1677// 1678 ALIGN_BLOCK 1679 1680pal_update_pcb: 1681 mfpr r12, pt_pcbb // get pcbb 1682 and r11, osfps_m_mode, r25 // get mode 1683 beq r25, pal_update_pcb_10_ // in kern? no need to update user sp 1684 mtpr r30, pt_usp // save user stack 1685 stq_p r30, osfpcb_q_usp(r12) // store usp 1686 br r31, pal_update_pcb_20_ // join common 1687pal_update_pcb_10_: stq_p r30, osfpcb_q_ksp(r12) // store ksp 1688pal_update_pcb_20_: rpcc r13 // get cyccounter 1689 srl r13, 32, r14 // move offset 1690 addl r13, r14, r14 // merge for new time 1691 stl_p r14, osfpcb_l_cc(r12) // save time 1692 1693//orig pvc_jsr updpcb, bsr=1, dest=1 1694 ret r31, (r0) 1695 1696 1697// 1698// pal_save_state 1699// 1700// Function 1701// All chip state saved, all PT's, SR's FR's, IPR's 1702// 1703// 1704// Regs' on entry... 1705// 1706// R0 = halt code 1707// pt0 = r0 1708// R1 = pointer to impure 1709// pt4 = r1 1710// R3 = return addr 1711// pt5 = r3 1712// 1713// register usage: 1714// r0 = halt_code 1715// r1 = addr of impure area 1716// r3 = return_address 1717// r4 = scratch 1718// 1719// 1720 1721 ALIGN_BLOCK 1722 .globl pal_save_state 1723pal_save_state: 1724// 1725// 1726// start of implementation independent save routine 1727// 1728// the impure area is larger than the addressibility of hw_ld and hw_st 1729// therefore, we need to play some games: The impure area 1730// is informally divided into the "machine independent" part and the 1731// "machine dependent" part. The state that will be saved in the 1732// "machine independent" part are gpr's, fpr's, hlt, flag, mchkflag (use (un)fix_impure_gpr macros). 1733// All others will be in the "machine dependent" part (use (un)fix_impure_ipr macros). 1734// The impure pointer will need to be adjusted by a different offset for each. The store/restore_reg 1735// macros will automagically adjust the offset correctly. 1736// 1737 1738// The distributed code is commented out and followed by corresponding SRC code. 1739// Beware: SAVE_IPR and RESTORE_IPR blow away r0(v0) 1740 1741//orig fix_impure_gpr r1 // adjust impure area pointer for stores to "gpr" part of impure area 1742 lda r1, 0x200(r1) // Point to center of CPU segment 1743//orig store_reg1 flag, r31, r1, ipr=1 // clear dump area flag 1744 SAVE_GPR(r31,CNS_Q_FLAG,r1) // Clear the valid flag 1745//orig store_reg1 hlt, r0, r1, ipr=1 1746 SAVE_GPR(r0,CNS_Q_HALT,r1) // Save the halt code 1747 1748 mfpr r0, pt0 // get r0 back //orig 1749//orig store_reg1 0, r0, r1 // save r0 1750 SAVE_GPR(r0,CNS_Q_GPR+0x00,r1) // Save r0 1751 1752 mfpr r0, pt4 // get r1 back //orig 1753//orig store_reg1 1, r0, r1 // save r1 1754 SAVE_GPR(r0,CNS_Q_GPR+0x08,r1) // Save r1 1755 1756//orig store_reg 2 // save r2 1757 SAVE_GPR(r2,CNS_Q_GPR+0x10,r1) // Save r2 1758 1759 mfpr r0, pt5 // get r3 back //orig 1760//orig store_reg1 3, r0, r1 // save r3 1761 SAVE_GPR(r0,CNS_Q_GPR+0x18,r1) // Save r3 1762 1763 // reason code has been saved 1764 // r0 has been saved 1765 // r1 has been saved 1766 // r2 has been saved 1767 // r3 has been saved 1768 // pt0, pt4, pt5 have been lost 1769 1770 // 1771 // Get out of shadow mode 1772 // 1773 1774 mfpr r2, icsr // Get icsr 1775 ldah r0, (1<<(icsr_v_sde-16))(r31) 1776 bic r2, r0, r0 // ICSR with SDE clear 1777 mtpr r0, icsr // Turn off SDE 1778 1779 mfpr r31, pt0 // SDE bubble cycle 1 1780 mfpr r31, pt0 // SDE bubble cycle 2 1781 mfpr r31, pt0 // SDE bubble cycle 3 1782 nop 1783 1784 1785 // save integer regs R4-r31 1786 SAVE_GPR(r4,CNS_Q_GPR+0x20,r1) 1787 SAVE_GPR(r5,CNS_Q_GPR+0x28,r1) 1788 SAVE_GPR(r6,CNS_Q_GPR+0x30,r1) 1789 SAVE_GPR(r7,CNS_Q_GPR+0x38,r1) 1790 SAVE_GPR(r8,CNS_Q_GPR+0x40,r1) 1791 SAVE_GPR(r9,CNS_Q_GPR+0x48,r1) 1792 SAVE_GPR(r10,CNS_Q_GPR+0x50,r1) 1793 SAVE_GPR(r11,CNS_Q_GPR+0x58,r1) 1794 SAVE_GPR(r12,CNS_Q_GPR+0x60,r1) 1795 SAVE_GPR(r13,CNS_Q_GPR+0x68,r1) 1796 SAVE_GPR(r14,CNS_Q_GPR+0x70,r1) 1797 SAVE_GPR(r15,CNS_Q_GPR+0x78,r1) 1798 SAVE_GPR(r16,CNS_Q_GPR+0x80,r1) 1799 SAVE_GPR(r17,CNS_Q_GPR+0x88,r1) 1800 SAVE_GPR(r18,CNS_Q_GPR+0x90,r1) 1801 SAVE_GPR(r19,CNS_Q_GPR+0x98,r1) 1802 SAVE_GPR(r20,CNS_Q_GPR+0xA0,r1) 1803 SAVE_GPR(r21,CNS_Q_GPR+0xA8,r1) 1804 SAVE_GPR(r22,CNS_Q_GPR+0xB0,r1) 1805 SAVE_GPR(r23,CNS_Q_GPR+0xB8,r1) 1806 SAVE_GPR(r24,CNS_Q_GPR+0xC0,r1) 1807 SAVE_GPR(r25,CNS_Q_GPR+0xC8,r1) 1808 SAVE_GPR(r26,CNS_Q_GPR+0xD0,r1) 1809 SAVE_GPR(r27,CNS_Q_GPR+0xD8,r1) 1810 SAVE_GPR(r28,CNS_Q_GPR+0xE0,r1) 1811 SAVE_GPR(r29,CNS_Q_GPR+0xE8,r1) 1812 SAVE_GPR(r30,CNS_Q_GPR+0xF0,r1) 1813 SAVE_GPR(r31,CNS_Q_GPR+0xF8,r1) 1814 1815 // save all paltemp regs except pt0 1816 1817//orig unfix_impure_gpr r1 // adjust impure area pointer for gpr stores 1818//orig fix_impure_ipr r1 // adjust impure area pointer for pt stores 1819 1820 lda r1, -0x200(r1) // Restore the impure base address. 1821 lda r1, CNS_Q_IPR(r1) // Point to the base of IPR area. 1822 SAVE_IPR(pt0,CNS_Q_PT+0x00,r1) // the osf code didn't save/restore palTemp 0 ?? pboyle 1823 SAVE_IPR(pt1,CNS_Q_PT+0x08,r1) 1824 SAVE_IPR(pt2,CNS_Q_PT+0x10,r1) 1825 SAVE_IPR(pt3,CNS_Q_PT+0x18,r1) 1826 SAVE_IPR(pt4,CNS_Q_PT+0x20,r1) 1827 SAVE_IPR(pt5,CNS_Q_PT+0x28,r1) 1828 SAVE_IPR(pt6,CNS_Q_PT+0x30,r1) 1829 SAVE_IPR(pt7,CNS_Q_PT+0x38,r1) 1830 SAVE_IPR(pt8,CNS_Q_PT+0x40,r1) 1831 SAVE_IPR(pt9,CNS_Q_PT+0x48,r1) 1832 SAVE_IPR(pt10,CNS_Q_PT+0x50,r1) 1833 SAVE_IPR(pt11,CNS_Q_PT+0x58,r1) 1834 SAVE_IPR(pt12,CNS_Q_PT+0x60,r1) 1835 SAVE_IPR(pt13,CNS_Q_PT+0x68,r1) 1836 SAVE_IPR(pt14,CNS_Q_PT+0x70,r1) 1837 SAVE_IPR(pt15,CNS_Q_PT+0x78,r1) 1838 SAVE_IPR(pt16,CNS_Q_PT+0x80,r1) 1839 SAVE_IPR(pt17,CNS_Q_PT+0x88,r1) 1840 SAVE_IPR(pt18,CNS_Q_PT+0x90,r1) 1841 SAVE_IPR(pt19,CNS_Q_PT+0x98,r1) 1842 SAVE_IPR(pt20,CNS_Q_PT+0xA0,r1) 1843 SAVE_IPR(pt21,CNS_Q_PT+0xA8,r1) 1844 SAVE_IPR(pt22,CNS_Q_PT+0xB0,r1) 1845 SAVE_IPR(pt23,CNS_Q_PT+0xB8,r1) 1846 1847 // Restore shadow mode 1848 mfpr r31, pt0 // pad write to icsr out of shadow of store (trap does not abort write) 1849 mfpr r31, pt0 1850 mtpr r2, icsr // Restore original ICSR 1851 1852 mfpr r31, pt0 // SDE bubble cycle 1 1853 mfpr r31, pt0 // SDE bubble cycle 2 1854 mfpr r31, pt0 // SDE bubble cycle 3 1855 nop 1856 1857 // save all integer shadow regs 1858 SAVE_SHADOW( r8,CNS_Q_SHADOW+0x00,r1) // also called p0...p7 in the Hudson code 1859 SAVE_SHADOW( r9,CNS_Q_SHADOW+0x08,r1) 1860 SAVE_SHADOW(r10,CNS_Q_SHADOW+0x10,r1) 1861 SAVE_SHADOW(r11,CNS_Q_SHADOW+0x18,r1) 1862 SAVE_SHADOW(r12,CNS_Q_SHADOW+0x20,r1) 1863 SAVE_SHADOW(r13,CNS_Q_SHADOW+0x28,r1) 1864 SAVE_SHADOW(r14,CNS_Q_SHADOW+0x30,r1) 1865 SAVE_SHADOW(r25,CNS_Q_SHADOW+0x38,r1) 1866 1867 SAVE_IPR(excAddr,CNS_Q_EXC_ADDR,r1) 1868 SAVE_IPR(palBase,CNS_Q_PAL_BASE,r1) 1869 SAVE_IPR(mmStat,CNS_Q_MM_STAT,r1) 1870 SAVE_IPR(va,CNS_Q_VA,r1) 1871 SAVE_IPR(icsr,CNS_Q_ICSR,r1) 1872 SAVE_IPR(ipl,CNS_Q_IPL,r1) 1873 SAVE_IPR(ips,CNS_Q_IPS,r1) 1874 SAVE_IPR(itbAsn,CNS_Q_ITB_ASN,r1) 1875 SAVE_IPR(aster,CNS_Q_ASTER,r1) 1876 SAVE_IPR(astrr,CNS_Q_ASTRR,r1) 1877 SAVE_IPR(sirr,CNS_Q_SIRR,r1) 1878 SAVE_IPR(isr,CNS_Q_ISR,r1) 1879 SAVE_IPR(iVptBr,CNS_Q_IVPTBR,r1) 1880 SAVE_IPR(mcsr,CNS_Q_MCSR,r1) 1881 SAVE_IPR(dcMode,CNS_Q_DC_MODE,r1) 1882 1883//orig pvc_violate 379 // mf maf_mode after a store ok (pvc doesn't distinguish ld from st) 1884//orig store_reg maf_mode, ipr=1 // save ipr -- no mbox instructions for 1885//orig // PVC violation applies only to 1886pvc$osf35$379: // loads. HW_ST ok here, so ignore 1887 SAVE_IPR(mafMode,CNS_Q_MAF_MODE,r1) // MBOX INST->MF MAF_MODE IN 0,1,2 1888 1889 1890 //the following iprs are informational only -- will not be restored 1891 1892 SAVE_IPR(icPerr,CNS_Q_ICPERR_STAT,r1) 1893 SAVE_IPR(PmCtr,CNS_Q_PM_CTR,r1) 1894 SAVE_IPR(intId,CNS_Q_INT_ID,r1) 1895 SAVE_IPR(excSum,CNS_Q_EXC_SUM,r1) 1896 SAVE_IPR(excMask,CNS_Q_EXC_MASK,r1) 1897 ldah r14, 0xFFF0(zero) 1898 zap r14, 0xE0, r14 // Get base address of CBOX IPRs 1899 NOP // Pad mfpr dcPerr out of shadow of 1900 NOP // last store 1901 NOP 1902 SAVE_IPR(dcPerr,CNS_Q_DCPERR_STAT,r1) 1903 1904 // read cbox ipr state 1905 1906 mb 1907 ldq_p r2, scCtl(r14) 1908 ldq_p r13, ldLock(r14) 1909 ldq_p r4, scAddr(r14) 1910 ldq_p r5, eiAddr(r14) 1911 ldq_p r6, bcTagAddr(r14) 1912 ldq_p r7, fillSyn(r14) 1913 bis r5, r4, zero // Make sure all loads complete before 1914 bis r7, r6, zero // reading registers that unlock them. 1915 ldq_p r8, scStat(r14) // Unlocks scAddr. 1916 ldq_p r9, eiStat(r14) // Unlocks eiAddr, bcTagAddr, fillSyn. 1917 ldq_p zero, eiStat(r14) // Make sure it is really unlocked. 1918 mb 1919 1920 // save cbox ipr state 1921 SAVE_SHADOW(r2,CNS_Q_SC_CTL,r1); 1922 SAVE_SHADOW(r13,CNS_Q_LD_LOCK,r1); 1923 SAVE_SHADOW(r4,CNS_Q_SC_ADDR,r1); 1924 SAVE_SHADOW(r5,CNS_Q_EI_ADDR,r1); 1925 SAVE_SHADOW(r6,CNS_Q_BC_TAG_ADDR,r1); 1926 SAVE_SHADOW(r7,CNS_Q_FILL_SYN,r1); 1927 SAVE_SHADOW(r8,CNS_Q_SC_STAT,r1); 1928 SAVE_SHADOW(r9,CNS_Q_EI_STAT,r1); 1929 //bc_config? sl_rcv? 1930 1931// restore impure base 1932//orig unfix_impure_ipr r1 1933 lda r1, -CNS_Q_IPR(r1) 1934 1935// save all floating regs 1936 mfpr r0, icsr // get icsr 1937 or r31, 1, r2 // get a one 1938 sll r2, icsr_v_fpe, r2 // Shift it into ICSR<FPE> position 1939 or r2, r0, r0 // set FEN on 1940 mtpr r0, icsr // write to icsr, enabling FEN 1941 1942// map the save area virtually 1943 mtpr r31, dtbIa // Clear all DTB entries 1944 srl r1, va_s_off, r0 // Clean off byte-within-page offset 1945 sll r0, pte_v_pfn, r0 // Shift to form PFN 1946 lda r0, pte_m_prot(r0) // Set all read/write enable bits 1947 mtpr r0, dtbPte // Load the PTE and set valid 1948 mtpr r1, dtbTag // Write the PTE and tag into the DTB 1949 1950 1951// map the next page too - in case the impure area crosses a page boundary 1952 lda r4, (1<<va_s_off)(r1) // Generate address for next page 1953 srl r4, va_s_off, r0 // Clean off byte-within-page offset 1954 sll r0, pte_v_pfn, r0 // Shift to form PFN 1955 lda r0, pte_m_prot(r0) // Set all read/write enable bits 1956 mtpr r0, dtbPte // Load the PTE and set valid 1957 mtpr r4, dtbTag // Write the PTE and tag into the DTB 1958 1959 sll r31, 0, r31 // stall cycle 1 1960 sll r31, 0, r31 // stall cycle 2 1961 sll r31, 0, r31 // stall cycle 3 1962 nop 1963 1964// add offset for saving fpr regs 1965//orig fix_impure_gpr r1 1966 lda r1, 0x200(r1) // Point to center of CPU segment 1967 1968// now save the regs - F0-F31 1969 mf_fpcr f0 // original 1970 1971 SAVE_FPR(f0,CNS_Q_FPR+0x00,r1) 1972 SAVE_FPR(f1,CNS_Q_FPR+0x08,r1) 1973 SAVE_FPR(f2,CNS_Q_FPR+0x10,r1) 1974 SAVE_FPR(f3,CNS_Q_FPR+0x18,r1) 1975 SAVE_FPR(f4,CNS_Q_FPR+0x20,r1) 1976 SAVE_FPR(f5,CNS_Q_FPR+0x28,r1) 1977 SAVE_FPR(f6,CNS_Q_FPR+0x30,r1) 1978 SAVE_FPR(f7,CNS_Q_FPR+0x38,r1) 1979 SAVE_FPR(f8,CNS_Q_FPR+0x40,r1) 1980 SAVE_FPR(f9,CNS_Q_FPR+0x48,r1) 1981 SAVE_FPR(f10,CNS_Q_FPR+0x50,r1) 1982 SAVE_FPR(f11,CNS_Q_FPR+0x58,r1) 1983 SAVE_FPR(f12,CNS_Q_FPR+0x60,r1) 1984 SAVE_FPR(f13,CNS_Q_FPR+0x68,r1) 1985 SAVE_FPR(f14,CNS_Q_FPR+0x70,r1) 1986 SAVE_FPR(f15,CNS_Q_FPR+0x78,r1) 1987 SAVE_FPR(f16,CNS_Q_FPR+0x80,r1) 1988 SAVE_FPR(f17,CNS_Q_FPR+0x88,r1) 1989 SAVE_FPR(f18,CNS_Q_FPR+0x90,r1) 1990 SAVE_FPR(f19,CNS_Q_FPR+0x98,r1) 1991 SAVE_FPR(f20,CNS_Q_FPR+0xA0,r1) 1992 SAVE_FPR(f21,CNS_Q_FPR+0xA8,r1) 1993 SAVE_FPR(f22,CNS_Q_FPR+0xB0,r1) 1994 SAVE_FPR(f23,CNS_Q_FPR+0xB8,r1) 1995 SAVE_FPR(f24,CNS_Q_FPR+0xC0,r1) 1996 SAVE_FPR(f25,CNS_Q_FPR+0xC8,r1) 1997 SAVE_FPR(f26,CNS_Q_FPR+0xD0,r1) 1998 SAVE_FPR(f27,CNS_Q_FPR+0xD8,r1) 1999 SAVE_FPR(f28,CNS_Q_FPR+0xE0,r1) 2000 SAVE_FPR(f29,CNS_Q_FPR+0xE8,r1) 2001 SAVE_FPR(f30,CNS_Q_FPR+0xF0,r1) 2002 SAVE_FPR(f31,CNS_Q_FPR+0xF8,r1) 2003 2004//switch impure offset from gpr to ipr--- 2005//orig unfix_impure_gpr r1 2006//orig fix_impure_ipr r1 2007//orig store_reg1 fpcsr, f0, r1, fpcsr=1 2008 2009 SAVE_FPR(f0,CNS_Q_FPCSR,r1) // fpcsr loaded above into f0 -- can it reach 2010 lda r1, -0x200(r1) // Restore the impure base address 2011 2012// and back to gpr --- 2013//orig unfix_impure_ipr r1 2014//orig fix_impure_gpr r1 2015 2016//orig lda r0, cns_mchksize(r31) // get size of mchk area 2017//orig store_reg1 mchkflag, r0, r1, ipr=1 2018//orig mb 2019 2020 lda r1, CNS_Q_IPR(r1) // Point to base of IPR area again 2021 // save this using the IPR base (it is closer) not the GRP base as they used...pb 2022 lda r0, MACHINE_CHECK_SIZE(r31) // get size of mchk area 2023 SAVE_SHADOW(r0,CNS_Q_MCHK,r1); 2024 mb 2025 2026//orig or r31, 1, r0 // get a one 2027//orig store_reg1 flag, r0, r1, ipr=1 // set dump area flag 2028//orig mb 2029 2030 lda r1, -CNS_Q_IPR(r1) // back to the base 2031 lda r1, 0x200(r1) // Point to center of CPU segment 2032 or r31, 1, r0 // get a one 2033 SAVE_GPR(r0,CNS_Q_FLAG,r1) // // set dump area valid flag 2034 mb 2035 2036 // restore impure area base 2037//orig unfix_impure_gpr r1 2038 lda r1, -0x200(r1) // Point to center of CPU segment 2039 2040 mtpr r31, dtb_ia // clear the dtb 2041 mtpr r31, itb_ia // clear the itb 2042 2043//orig pvc_jsr savsta, bsr=1, dest=1 2044 ret r31, (r3) // and back we go 2045 2046 2047 2048// .sbttl "PAL_RESTORE_STATE" 2049// 2050// 2051// Pal_restore_state 2052// 2053// 2054// register usage: 2055// r1 = addr of impure area 2056// r3 = return_address 2057// all other regs are scratchable, as they are about to 2058// be reloaded from ram. 2059// 2060// Function: 2061// All chip state restored, all SRs, FRs, PTs, IPRs 2062// *** except R1, R3, PT0, PT4, PT5 *** 2063// 2064// 2065 ALIGN_BLOCK 2066pal_restore_state: 2067 2068//need to restore sc_ctl,bc_ctl,bc_config??? if so, need to figure out a safe way to do so. 2069 2070// map the console io area virtually 2071 mtpr r31, dtbIa // Clear all DTB entries 2072 srl r1, va_s_off, r0 // Clean off byte-within-page offset 2073 sll r0, pte_v_pfn, r0 // Shift to form PFN 2074 lda r0, pte_m_prot(r0) // Set all read/write enable bits 2075 mtpr r0, dtbPte // Load the PTE and set valid 2076 mtpr r1, dtbTag // Write the PTE and tag into the DTB 2077 2078 2079// map the next page too, in case impure area crosses page boundary 2080 lda r4, (1<<VA_S_OFF)(r1) // Generate address for next page 2081 srl r4, va_s_off, r0 // Clean off byte-within-page offset 2082 sll r0, pte_v_pfn, r0 // Shift to form PFN 2083 lda r0, pte_m_prot(r0) // Set all read/write enable bits 2084 mtpr r0, dtbPte // Load the PTE and set valid 2085 mtpr r4, dtbTag // Write the PTE and tag into the DTB 2086 2087// save all floating regs 2088 mfpr r0, icsr // Get current ICSR 2089 bis zero, 1, r2 // Get a '1' 2090 or r2, (1<<(icsr_v_sde-icsr_v_fpe)), r2 2091 sll r2, icsr_v_fpe, r2 // Shift bits into position 2092 bis r2, r2, r0 // Set ICSR<SDE> and ICSR<FPE> 2093 mtpr r0, icsr // Update the chip 2094 2095 mfpr r31, pt0 // FPE bubble cycle 1 //orig 2096 mfpr r31, pt0 // FPE bubble cycle 2 //orig 2097 mfpr r31, pt0 // FPE bubble cycle 3 //orig 2098 2099//orig fix_impure_ipr r1 2100//orig restore_reg1 fpcsr, f0, r1, fpcsr=1 2101//orig mt_fpcr f0 2102//orig 2103//orig unfix_impure_ipr r1 2104//orig fix_impure_gpr r1 // adjust impure pointer offset for gpr access 2105 lda r1, 200(r1) // Point to base of IPR area again 2106 RESTORE_FPR(f0,CNS_Q_FPCSR,r1) // can it reach?? pb 2107 mt_fpcr f0 // original 2108 2109 lda r1, 0x200(r1) // point to center of CPU segment 2110 2111// restore all floating regs 2112 RESTORE_FPR(f0,CNS_Q_FPR+0x00,r1) 2113 RESTORE_FPR(f1,CNS_Q_FPR+0x08,r1) 2114 RESTORE_FPR(f2,CNS_Q_FPR+0x10,r1) 2115 RESTORE_FPR(f3,CNS_Q_FPR+0x18,r1) 2116 RESTORE_FPR(f4,CNS_Q_FPR+0x20,r1) 2117 RESTORE_FPR(f5,CNS_Q_FPR+0x28,r1) 2118 RESTORE_FPR(f6,CNS_Q_FPR+0x30,r1) 2119 RESTORE_FPR(f7,CNS_Q_FPR+0x38,r1) 2120 RESTORE_FPR(f8,CNS_Q_FPR+0x40,r1) 2121 RESTORE_FPR(f9,CNS_Q_FPR+0x48,r1) 2122 RESTORE_FPR(f10,CNS_Q_FPR+0x50,r1) 2123 RESTORE_FPR(f11,CNS_Q_FPR+0x58,r1) 2124 RESTORE_FPR(f12,CNS_Q_FPR+0x60,r1) 2125 RESTORE_FPR(f13,CNS_Q_FPR+0x68,r1) 2126 RESTORE_FPR(f14,CNS_Q_FPR+0x70,r1) 2127 RESTORE_FPR(f15,CNS_Q_FPR+0x78,r1) 2128 RESTORE_FPR(f16,CNS_Q_FPR+0x80,r1) 2129 RESTORE_FPR(f17,CNS_Q_FPR+0x88,r1) 2130 RESTORE_FPR(f18,CNS_Q_FPR+0x90,r1) 2131 RESTORE_FPR(f19,CNS_Q_FPR+0x98,r1) 2132 RESTORE_FPR(f20,CNS_Q_FPR+0xA0,r1) 2133 RESTORE_FPR(f21,CNS_Q_FPR+0xA8,r1) 2134 RESTORE_FPR(f22,CNS_Q_FPR+0xB0,r1) 2135 RESTORE_FPR(f23,CNS_Q_FPR+0xB8,r1) 2136 RESTORE_FPR(f24,CNS_Q_FPR+0xC0,r1) 2137 RESTORE_FPR(f25,CNS_Q_FPR+0xC8,r1) 2138 RESTORE_FPR(f26,CNS_Q_FPR+0xD0,r1) 2139 RESTORE_FPR(f27,CNS_Q_FPR+0xD8,r1) 2140 RESTORE_FPR(f28,CNS_Q_FPR+0xE0,r1) 2141 RESTORE_FPR(f29,CNS_Q_FPR+0xE8,r1) 2142 RESTORE_FPR(f30,CNS_Q_FPR+0xF0,r1) 2143 RESTORE_FPR(f31,CNS_Q_FPR+0xF8,r1) 2144 2145// switch impure pointer from gpr to ipr area -- 2146//orig unfix_impure_gpr r1 2147//orig fix_impure_ipr r1 2148 lda r1, -0x200(r1) // Restore base address of impure area. 2149 lda r1, CNS_Q_IPR(r1) // Point to base of IPR area. 2150 2151// restore all pal regs 2152 RESTORE_IPR(pt0,CNS_Q_PT+0x00,r1) // the osf code didn't save/restore palTemp 0 ?? pboyle 2153 RESTORE_IPR(pt1,CNS_Q_PT+0x08,r1) 2154 RESTORE_IPR(pt2,CNS_Q_PT+0x10,r1) 2155 RESTORE_IPR(pt3,CNS_Q_PT+0x18,r1) 2156 RESTORE_IPR(pt4,CNS_Q_PT+0x20,r1) 2157 RESTORE_IPR(pt5,CNS_Q_PT+0x28,r1) 2158 RESTORE_IPR(pt6,CNS_Q_PT+0x30,r1) 2159 RESTORE_IPR(pt7,CNS_Q_PT+0x38,r1) 2160 RESTORE_IPR(pt8,CNS_Q_PT+0x40,r1) 2161 RESTORE_IPR(pt9,CNS_Q_PT+0x48,r1) 2162 RESTORE_IPR(pt10,CNS_Q_PT+0x50,r1) 2163 RESTORE_IPR(pt11,CNS_Q_PT+0x58,r1) 2164 RESTORE_IPR(pt12,CNS_Q_PT+0x60,r1) 2165 RESTORE_IPR(pt13,CNS_Q_PT+0x68,r1) 2166 RESTORE_IPR(pt14,CNS_Q_PT+0x70,r1) 2167 RESTORE_IPR(pt15,CNS_Q_PT+0x78,r1) 2168 RESTORE_IPR(pt16,CNS_Q_PT+0x80,r1) 2169 RESTORE_IPR(pt17,CNS_Q_PT+0x88,r1) 2170 RESTORE_IPR(pt18,CNS_Q_PT+0x90,r1) 2171 RESTORE_IPR(pt19,CNS_Q_PT+0x98,r1) 2172 RESTORE_IPR(pt20,CNS_Q_PT+0xA0,r1) 2173 RESTORE_IPR(pt21,CNS_Q_PT+0xA8,r1) 2174 RESTORE_IPR(pt22,CNS_Q_PT+0xB0,r1) 2175 RESTORE_IPR(pt23,CNS_Q_PT+0xB8,r1) 2176 2177 2178//orig restore_reg exc_addr, ipr=1 // restore ipr 2179//orig restore_reg pal_base, ipr=1 // restore ipr 2180//orig restore_reg ipl, ipr=1 // restore ipr 2181//orig restore_reg ps, ipr=1 // restore ipr 2182//orig mtpr r0, dtb_cm // set current mode in mbox too 2183//orig restore_reg itb_asn, ipr=1 2184//orig srl r0, itb_asn_v_asn, r0 2185//orig sll r0, dtb_asn_v_asn, r0 2186//orig mtpr r0, dtb_asn // set ASN in Mbox too 2187//orig restore_reg ivptbr, ipr=1 2188//orig mtpr r0, mvptbr // use ivptbr value to restore mvptbr 2189//orig restore_reg mcsr, ipr=1 2190//orig restore_reg aster, ipr=1 2191//orig restore_reg astrr, ipr=1 2192//orig restore_reg sirr, ipr=1 2193//orig restore_reg maf_mode, ipr=1 // no mbox instruction for 3 cycles 2194//orig mfpr r31, pt0 // (may issue with mt maf_mode) 2195//orig mfpr r31, pt0 // bubble cycle 1 2196//orig mfpr r31, pt0 // bubble cycle 2 2197//orig mfpr r31, pt0 // bubble cycle 3 2198//orig mfpr r31, pt0 // (may issue with following ld) 2199 2200 // r0 gets the value of RESTORE_IPR in the macro and this code uses this side effect (gag) 2201 RESTORE_IPR(excAddr,CNS_Q_EXC_ADDR,r1) 2202 RESTORE_IPR(palBase,CNS_Q_PAL_BASE,r1) 2203 RESTORE_IPR(ipl,CNS_Q_IPL,r1) 2204 RESTORE_IPR(ips,CNS_Q_IPS,r1) 2205 mtpr r0, dtbCm // Set Mbox current mode too. 2206 RESTORE_IPR(itbAsn,CNS_Q_ITB_ASN,r1) 2207 srl r0, 4, r0 2208 sll r0, 57, r0 2209 mtpr r0, dtbAsn // Set Mbox ASN too 2210 RESTORE_IPR(iVptBr,CNS_Q_IVPTBR,r1) 2211 mtpr r0, mVptBr // Set Mbox VptBr too 2212 RESTORE_IPR(mcsr,CNS_Q_MCSR,r1) 2213 RESTORE_IPR(aster,CNS_Q_ASTER,r1) 2214 RESTORE_IPR(astrr,CNS_Q_ASTRR,r1) 2215 RESTORE_IPR(sirr,CNS_Q_SIRR,r1) 2216 RESTORE_IPR(mafMode,CNS_Q_MAF_MODE,r1) 2217 STALL 2218 STALL 2219 STALL 2220 STALL 2221 STALL 2222 2223 2224 // restore all integer shadow regs 2225 RESTORE_SHADOW( r8,CNS_Q_SHADOW+0x00,r1) // also called p0...p7 in the Hudson code 2226 RESTORE_SHADOW( r9,CNS_Q_SHADOW+0x08,r1) 2227 RESTORE_SHADOW(r10,CNS_Q_SHADOW+0x10,r1) 2228 RESTORE_SHADOW(r11,CNS_Q_SHADOW+0x18,r1) 2229 RESTORE_SHADOW(r12,CNS_Q_SHADOW+0x20,r1) 2230 RESTORE_SHADOW(r13,CNS_Q_SHADOW+0x28,r1) 2231 RESTORE_SHADOW(r14,CNS_Q_SHADOW+0x30,r1) 2232 RESTORE_SHADOW(r25,CNS_Q_SHADOW+0x38,r1) 2233 RESTORE_IPR(dcMode,CNS_Q_DC_MODE,r1) 2234 2235 // 2236 // Get out of shadow mode 2237 // 2238 2239 mfpr r31, pt0 // pad last load to icsr write (in case of replay, icsr will be written anyway) 2240 mfpr r31, pt0 // "" 2241 mfpr r0, icsr // Get icsr 2242 ldah r2, (1<<(ICSR_V_SDE-16))(r31) // Get a one in SHADOW_ENABLE bit location 2243 bic r0, r2, r2 // ICSR with SDE clear 2244 mtpr r2, icsr // Turn off SDE - no palshadow rd/wr for 3 bubble cycles 2245 2246 mfpr r31, pt0 // SDE bubble cycle 1 2247 mfpr r31, pt0 // SDE bubble cycle 2 2248 mfpr r31, pt0 // SDE bubble cycle 3 2249 nop 2250 2251// switch impure pointer from ipr to gpr area -- 2252//orig unfix_impure_ipr r1 2253//orig fix_impure_gpr r1 2254 2255// Restore GPRs (r0, r2 are restored later, r1 and r3 are trashed) ... 2256 2257 lda r1, -CNS_Q_IPR(r1) // Restore base address of impure area 2258 lda r1, 0x200(r1) // Point to center of CPU segment 2259 2260 // restore all integer regs 2261 RESTORE_GPR(r4,CNS_Q_GPR+0x20,r1) 2262 RESTORE_GPR(r5,CNS_Q_GPR+0x28,r1) 2263 RESTORE_GPR(r6,CNS_Q_GPR+0x30,r1) 2264 RESTORE_GPR(r7,CNS_Q_GPR+0x38,r1) 2265 RESTORE_GPR(r8,CNS_Q_GPR+0x40,r1) 2266 RESTORE_GPR(r9,CNS_Q_GPR+0x48,r1) 2267 RESTORE_GPR(r10,CNS_Q_GPR+0x50,r1) 2268 RESTORE_GPR(r11,CNS_Q_GPR+0x58,r1) 2269 RESTORE_GPR(r12,CNS_Q_GPR+0x60,r1) 2270 RESTORE_GPR(r13,CNS_Q_GPR+0x68,r1) 2271 RESTORE_GPR(r14,CNS_Q_GPR+0x70,r1) 2272 RESTORE_GPR(r15,CNS_Q_GPR+0x78,r1) 2273 RESTORE_GPR(r16,CNS_Q_GPR+0x80,r1) 2274 RESTORE_GPR(r17,CNS_Q_GPR+0x88,r1) 2275 RESTORE_GPR(r18,CNS_Q_GPR+0x90,r1) 2276 RESTORE_GPR(r19,CNS_Q_GPR+0x98,r1) 2277 RESTORE_GPR(r20,CNS_Q_GPR+0xA0,r1) 2278 RESTORE_GPR(r21,CNS_Q_GPR+0xA8,r1) 2279 RESTORE_GPR(r22,CNS_Q_GPR+0xB0,r1) 2280 RESTORE_GPR(r23,CNS_Q_GPR+0xB8,r1) 2281 RESTORE_GPR(r24,CNS_Q_GPR+0xC0,r1) 2282 RESTORE_GPR(r25,CNS_Q_GPR+0xC8,r1) 2283 RESTORE_GPR(r26,CNS_Q_GPR+0xD0,r1) 2284 RESTORE_GPR(r27,CNS_Q_GPR+0xD8,r1) 2285 RESTORE_GPR(r28,CNS_Q_GPR+0xE0,r1) 2286 RESTORE_GPR(r29,CNS_Q_GPR+0xE8,r1) 2287 RESTORE_GPR(r30,CNS_Q_GPR+0xF0,r1) 2288 RESTORE_GPR(r31,CNS_Q_GPR+0xF8,r1) 2289 2290//orig // switch impure pointer from gpr to ipr area -- 2291//orig unfix_impure_gpr r1 2292//orig fix_impure_ipr r1 2293//orig restore_reg icsr, ipr=1 // restore original icsr- 4 bubbles to hw_rei 2294 2295 lda t0, -0x200(t0) // Restore base address of impure area. 2296 lda t0, CNS_Q_IPR(t0) // Point to base of IPR area again. 2297 RESTORE_IPR(icsr,CNS_Q_ICSR,r1) 2298 2299//orig // and back again -- 2300//orig unfix_impure_ipr r1 2301//orig fix_impure_gpr r1 2302//orig store_reg1 flag, r31, r1, ipr=1 // clear dump area valid flag 2303//orig mb 2304 2305 lda t0, -CNS_Q_IPR(t0) // Back to base of impure area again, 2306 lda t0, 0x200(t0) // and back to center of CPU segment 2307 SAVE_GPR(r31,CNS_Q_FLAG,r1) // Clear the dump area valid flag 2308 mb 2309 2310//orig // and back we go 2311//orig// restore_reg 3 2312//orig restore_reg 2 2313//orig// restore_reg 1 2314//orig restore_reg 0 2315//orig // restore impure area base 2316//orig unfix_impure_gpr r1 2317 2318 RESTORE_GPR(r2,CNS_Q_GPR+0x10,r1) 2319 RESTORE_GPR(r0,CNS_Q_GPR+0x00,r1) 2320 lda r1, -0x200(r1) // Restore impure base address 2321 2322 mfpr r31, pt0 // stall for ldq_p above //orig 2323 2324 mtpr r31, dtb_ia // clear the tb //orig 2325 mtpr r31, itb_ia // clear the itb //orig 2326 2327//orig pvc_jsr rststa, bsr=1, dest=1 2328 ret r31, (r3) // back we go //orig 2329 2330 2331// 2332// pal_pal_bug_check -- code has found a bugcheck situation. 2333// Set things up and join common machine check flow. 2334// 2335// Input: 2336// r14 - exc_addr 2337// 2338// On exit: 2339// pt0 - saved r0 2340// pt1 - saved r1 2341// pt4 - saved r4 2342// pt5 - saved r5 2343// pt6 - saved r6 2344// pt10 - saved exc_addr 2345// pt_misc<47:32> - mchk code 2346// pt_misc<31:16> - scb vector 2347// r14 - base of Cbox IPRs in IO space 2348// MCES<mchk> is set 2349// 2350 2351 ALIGN_BLOCK 2352 .globl pal_pal_bug_check_from_int 2353pal_pal_bug_check_from_int: 2354 DEBUGSTORE(0x79) 2355//simos DEBUG_EXC_ADDR() 2356 DEBUGSTORE(0x20) 2357//simos bsr r25, put_hex 2358 lda r25, mchk_c_bugcheck(r31) 2359 addq r25, 1, r25 // set flag indicating we came from interrupt and stack is already pushed 2360 br r31, pal_pal_mchk 2361 nop 2362 2363pal_pal_bug_check: 2364 lda r25, mchk_c_bugcheck(r31) 2365 2366pal_pal_mchk: 2367 sll r25, 32, r25 // Move mchk code to position 2368 2369 mtpr r14, pt10 // Stash exc_addr 2370 mtpr r14, exc_addr 2371 2372 mfpr r12, pt_misc // Get MCES and scratch 2373 zap r12, 0x3c, r12 2374 2375 or r12, r25, r12 // Combine mchk code 2376 lda r25, scb_v_procmchk(r31) // Get SCB vector 2377 2378 sll r25, 16, r25 // Move SCBv to position 2379 or r12, r25, r25 // Combine SCBv 2380 2381 mtpr r0, pt0 // Stash for scratch 2382 bis r25, mces_m_mchk, r25 // Set MCES<MCHK> bit 2383 2384 mtpr r25, pt_misc // Save mchk code!scbv!whami!mces 2385 ldah r14, 0xfff0(r31) 2386 2387 mtpr r1, pt1 // Stash for scratch 2388 zap r14, 0xE0, r14 // Get Cbox IPR base 2389 2390 mtpr r4, pt4 2391 mtpr r5, pt5 2392 2393 mtpr r6, pt6 2394 blbs r12, sys_double_machine_check // MCHK halt if double machine check 2395 2396 br r31, sys_mchk_collect_iprs // Join common machine check flow 2397 2398 2399 2400// align_to_call_pal_section 2401// Align to address of first call_pal entry point - 2000 2402 2403// 2404// HALT - PALcode for HALT instruction 2405// 2406// Entry: 2407// Vectored into via hardware PALcode instruction dispatch. 2408// 2409// Function: 2410// GO to console code 2411// 2412// 2413 2414 .text 1 2415// . = 0x2000 2416 CALL_PAL_PRIV(PAL_HALT_ENTRY) 2417call_pal_halt: 2418 mfpr r31, pt0 // Pad exc_addr read 2419 mfpr r31, pt0 2420 2421 mfpr r12, exc_addr // get PC 2422 subq r12, 4, r12 // Point to the HALT 2423 2424 mtpr r12, exc_addr 2425 mtpr r0, pt0 2426 2427//orig pvc_jsr updpcb, bsr=1 2428 bsr r0, pal_update_pcb // update the pcb 2429 lda r0, hlt_c_sw_halt(r31) // set halt code to sw halt 2430 br r31, sys_enter_console // enter the console 2431 2432// 2433// CFLUSH - PALcode for CFLUSH instruction 2434// 2435// Entry: 2436// Vectored into via hardware PALcode instruction dispatch. 2437// 2438// R16 - contains the PFN of the page to be flushed 2439// 2440// Function: 2441// Flush all Dstream caches of 1 entire page 2442// The CFLUSH routine is in the system specific module. 2443// 2444// 2445 2446 CALL_PAL_PRIV(PAL_CFLUSH_ENTRY) 2447Call_Pal_Cflush: 2448 br r31, sys_cflush 2449 2450// 2451// DRAINA - PALcode for DRAINA instruction 2452// 2453// Entry: 2454// Vectored into via hardware PALcode instruction dispatch. 2455// Implicit TRAPB performed by hardware. 2456// 2457// Function: 2458// Stall instruction issue until all prior instructions are guaranteed to 2459// complete without incurring aborts. For the EV5 implementation, this 2460// means waiting until all pending DREADS are returned. 2461// 2462// 2463 2464 CALL_PAL_PRIV(PAL_DRAINA_ENTRY) 2465Call_Pal_Draina: 2466 ldah r14, 0x100(r31) // Init counter. Value? 2467 nop 2468 2469DRAINA_LOOP: 2470 subq r14, 1, r14 // Decrement counter 2471 mfpr r13, ev5__maf_mode // Fetch status bit 2472 2473 srl r13, maf_mode_v_dread_pending, r13 2474 ble r14, DRAINA_LOOP_TOO_LONG 2475 2476 nop 2477 blbs r13, DRAINA_LOOP // Wait until all DREADS clear 2478 2479 hw_rei 2480 2481DRAINA_LOOP_TOO_LONG: 2482 br r31, call_pal_halt 2483 2484// CALL_PAL OPCDECs 2485 2486 CALL_PAL_PRIV(0x0003) 2487CallPal_OpcDec03: 2488 br r31, osfpal_calpal_opcdec 2489 2490 CALL_PAL_PRIV(0x0004) 2491CallPal_OpcDec04: 2492 br r31, osfpal_calpal_opcdec 2493 2494 CALL_PAL_PRIV(0x0005) 2495CallPal_OpcDec05: 2496 br r31, osfpal_calpal_opcdec 2497 2498 CALL_PAL_PRIV(0x0006) 2499CallPal_OpcDec06: 2500 br r31, osfpal_calpal_opcdec 2501 2502 CALL_PAL_PRIV(0x0007) 2503CallPal_OpcDec07: 2504 br r31, osfpal_calpal_opcdec 2505 2506 CALL_PAL_PRIV(0x0008) 2507CallPal_OpcDec08: 2508 br r31, osfpal_calpal_opcdec 2509 2510// 2511// CSERVE - PALcode for CSERVE instruction 2512// 2513// Entry: 2514// Vectored into via hardware PALcode instruction dispatch. 2515// 2516// Function: 2517// Various functions for private use of console software 2518// 2519// option selector in r0 2520// arguments in r16.... 2521// The CSERVE routine is in the system specific module. 2522// 2523// 2524 2525 CALL_PAL_PRIV(PAL_CSERVE_ENTRY) 2526Call_Pal_Cserve: 2527 br r31, sys_cserve 2528 2529// 2530// swppal - PALcode for swppal instruction 2531// 2532// Entry: 2533// Vectored into via hardware PALcode instruction dispatch. 2534// Vectored into via hardware PALcode instruction dispatch. 2535// R16 contains the new PAL identifier 2536// R17:R21 contain implementation-specific entry parameters 2537// 2538// R0 receives status: 2539// 0 success (PAL was switched) 2540// 1 unknown PAL variant 2541// 2 known PAL variant, but PAL not loaded 2542// 2543// 2544// Function: 2545// Swap control to another PAL. 2546// 2547 2548 CALL_PAL_PRIV(PAL_SWPPAL_ENTRY) 2549Call_Pal_Swppal: 2550 cmpule r16, 255, r0 // see if a kibble was passed 2551 cmoveq r16, r16, r0 // if r16=0 then a valid address (ECO 59) 2552 2553 or r16, r31, r3 // set r3 incase this is a address 2554 blbc r0, swppal_cont // nope, try it as an address 2555 2556 cmpeq r16, 2, r0 // is it our friend OSF? 2557 blbc r0, swppal_fail // nope, don't know this fellow 2558 2559 br r2, CALL_PAL_SWPPAL_10_ // tis our buddy OSF 2560 2561// .global osfpal_hw_entry_reset 2562// .weak osfpal_hw_entry_reset 2563// .long <osfpal_hw_entry_reset-pal_start> 2564//orig halt // don't know how to get the address here - kludge ok, load pal at 0 2565 .long 0 // ?? hack upon hack...pb 2566 2567CALL_PAL_SWPPAL_10_: ldl_p r3, 0(r2) // fetch target addr 2568// ble r3, swppal_fail ; if OSF not linked in say not loaded. 2569 mfpr r2, pal_base // fetch pal base 2570 2571 addq r2, r3, r3 // add pal base 2572 lda r2, 0x3FFF(r31) // get pal base checker mask 2573 2574 and r3, r2, r2 // any funky bits set? 2575 cmpeq r2, 0, r0 // 2576 2577 blbc r0, swppal_fail // return unknown if bad bit set. 2578 br r31, swppal_cont 2579 2580// .sbttl "CALL_PAL OPCDECs" 2581 2582 CALL_PAL_PRIV(0x000B) 2583CallPal_OpcDec0B: 2584 br r31, osfpal_calpal_opcdec 2585 2586 CALL_PAL_PRIV(0x000C) 2587CallPal_OpcDec0C: 2588 br r31, osfpal_calpal_opcdec 2589 2590// 2591// wripir - PALcode for wripir instruction 2592// 2593// Entry: 2594// Vectored into via hardware PALcode instruction dispatch. 2595// r16 = processor number to interrupt 2596// 2597// Function: 2598// IPIR <- R16 2599// Handled in system-specific code 2600// 2601// Exit: 2602// interprocessor interrupt is recorded on the target processor 2603// and is initiated when the proper enabling conditions are present. 2604// 2605 2606 CALL_PAL_PRIV(PAL_WRIPIR_ENTRY) 2607Call_Pal_Wrpir: 2608 br r31, sys_wripir 2609 2610// .sbttl "CALL_PAL OPCDECs" 2611 2612 CALL_PAL_PRIV(0x000E) 2613CallPal_OpcDec0E: 2614 br r31, osfpal_calpal_opcdec 2615 2616 CALL_PAL_PRIV(0x000F) 2617CallPal_OpcDec0F: 2618 br r31, osfpal_calpal_opcdec 2619 2620// 2621// rdmces - PALcode for rdmces instruction 2622// 2623// Entry: 2624// Vectored into via hardware PALcode instruction dispatch. 2625// 2626// Function: 2627// R0 <- ZEXT(MCES) 2628// 2629 2630 CALL_PAL_PRIV(PAL_RDMCES_ENTRY) 2631Call_Pal_Rdmces: 2632 mfpr r0, pt_mces // Read from PALtemp 2633 and r0, mces_m_all, r0 // Clear other bits 2634 2635 hw_rei 2636 2637// 2638// wrmces - PALcode for wrmces instruction 2639// 2640// Entry: 2641// Vectored into via hardware PALcode instruction dispatch. 2642// 2643// Function: 2644// If {R16<0> EQ 1} then MCES<0> <- 0 (MCHK) 2645// If {R16<1> EQ 1} then MCES<1> <- 0 (SCE) 2646// If {R16<2> EQ 1} then MCES<2> <- 0 (PCE) 2647// MCES<3> <- R16<3> (DPC) 2648// MCES<4> <- R16<4> (DSC) 2649// 2650// 2651 2652 CALL_PAL_PRIV(PAL_WRMCES_ENTRY) 2653Call_Pal_Wrmces: 2654 and r16, ((1<<mces_v_mchk) | (1<<mces_v_sce) | (1<<mces_v_pce)), r13 // Isolate MCHK, SCE, PCE 2655 mfpr r14, pt_mces // Get current value 2656 2657 ornot r31, r13, r13 // Flip all the bits 2658 and r16, ((1<<mces_v_dpc) | (1<<mces_v_dsc)), r17 2659 2660 and r14, r13, r1 // Update MCHK, SCE, PCE 2661 bic r1, ((1<<mces_v_dpc) | (1<<mces_v_dsc)), r1 // Clear old DPC, DSC 2662 2663 or r1, r17, r1 // Update DPC and DSC 2664 mtpr r1, pt_mces // Write MCES back 2665 2666 nop // Pad to fix PT write->read restriction 2667 2668 nop 2669 hw_rei 2670 2671 2672 2673// CALL_PAL OPCDECs 2674 2675 CALL_PAL_PRIV(0x0012) 2676CallPal_OpcDec12: 2677 br r31, osfpal_calpal_opcdec 2678 2679 CALL_PAL_PRIV(0x0013) 2680CallPal_OpcDec13: 2681 br r31, osfpal_calpal_opcdec 2682 2683 CALL_PAL_PRIV(0x0014) 2684CallPal_OpcDec14: 2685 br r31, osfpal_calpal_opcdec 2686 2687 CALL_PAL_PRIV(0x0015) 2688CallPal_OpcDec15: 2689 br r31, osfpal_calpal_opcdec 2690 2691 CALL_PAL_PRIV(0x0016) 2692CallPal_OpcDec16: 2693 br r31, osfpal_calpal_opcdec 2694 2695 CALL_PAL_PRIV(0x0017) 2696CallPal_OpcDec17: 2697 br r31, osfpal_calpal_opcdec 2698 2699 CALL_PAL_PRIV(0x0018) 2700CallPal_OpcDec18: 2701 br r31, osfpal_calpal_opcdec 2702 2703 CALL_PAL_PRIV(0x0019) 2704CallPal_OpcDec19: 2705 br r31, osfpal_calpal_opcdec 2706 2707 CALL_PAL_PRIV(0x001A) 2708CallPal_OpcDec1A: 2709 br r31, osfpal_calpal_opcdec 2710 2711 CALL_PAL_PRIV(0x001B) 2712CallPal_OpcDec1B: 2713 br r31, osfpal_calpal_opcdec 2714 2715 CALL_PAL_PRIV(0x001C) 2716CallPal_OpcDec1C: 2717 br r31, osfpal_calpal_opcdec 2718 2719 CALL_PAL_PRIV(0x001D) 2720CallPal_OpcDec1D: 2721 br r31, osfpal_calpal_opcdec 2722 2723 CALL_PAL_PRIV(0x001E) 2724CallPal_OpcDec1E: 2725 br r31, osfpal_calpal_opcdec 2726 2727 CALL_PAL_PRIV(0x001F) 2728CallPal_OpcDec1F: 2729 br r31, osfpal_calpal_opcdec 2730 2731 CALL_PAL_PRIV(0x0020) 2732CallPal_OpcDec20: 2733 br r31, osfpal_calpal_opcdec 2734 2735 CALL_PAL_PRIV(0x0021) 2736CallPal_OpcDec21: 2737 br r31, osfpal_calpal_opcdec 2738 2739 CALL_PAL_PRIV(0x0022) 2740CallPal_OpcDec22: 2741 br r31, osfpal_calpal_opcdec 2742 2743 CALL_PAL_PRIV(0x0023) 2744CallPal_OpcDec23: 2745 br r31, osfpal_calpal_opcdec 2746 2747 CALL_PAL_PRIV(0x0024) 2748CallPal_OpcDec24: 2749 br r31, osfpal_calpal_opcdec 2750 2751 CALL_PAL_PRIV(0x0025) 2752CallPal_OpcDec25: 2753 br r31, osfpal_calpal_opcdec 2754 2755 CALL_PAL_PRIV(0x0026) 2756CallPal_OpcDec26: 2757 br r31, osfpal_calpal_opcdec 2758 2759 CALL_PAL_PRIV(0x0027) 2760CallPal_OpcDec27: 2761 br r31, osfpal_calpal_opcdec 2762 2763 CALL_PAL_PRIV(0x0028) 2764CallPal_OpcDec28: 2765 br r31, osfpal_calpal_opcdec 2766 2767 CALL_PAL_PRIV(0x0029) 2768CallPal_OpcDec29: 2769 br r31, osfpal_calpal_opcdec 2770 2771 CALL_PAL_PRIV(0x002A) 2772CallPal_OpcDec2A: 2773 br r31, osfpal_calpal_opcdec 2774 2775// 2776// wrfen - PALcode for wrfen instruction 2777// 2778// Entry: 2779// Vectored into via hardware PALcode instruction dispatch. 2780// 2781// Function: 2782// a0<0> -> ICSR<FPE> 2783// Store new FEN in PCB 2784// Final value of t0 (r1), t8..t10 (r22..r24) and a0 (r16) 2785// are UNPREDICTABLE 2786// 2787// Issue: What about pending FP loads when FEN goes from on->off???? 2788// 2789 2790 CALL_PAL_PRIV(PAL_WRFEN_ENTRY) 2791Call_Pal_Wrfen: 2792 or r31, 1, r13 // Get a one 2793 mfpr r1, ev5__icsr // Get current FPE 2794 2795 sll r13, icsr_v_fpe, r13 // shift 1 to icsr<fpe> spot, e0 2796 and r16, 1, r16 // clean new fen 2797 2798 sll r16, icsr_v_fpe, r12 // shift new fen to correct bit position 2799 bic r1, r13, r1 // zero icsr<fpe> 2800 2801 or r1, r12, r1 // Or new FEN into ICSR 2802 mfpr r12, pt_pcbb // Get PCBB - E1 2803 2804 mtpr r1, ev5__icsr // write new ICSR. 3 Bubble cycles to HW_REI 2805 stl_p r16, osfpcb_q_fen(r12) // Store FEN in PCB. 2806 2807 mfpr r31, pt0 // Pad ICSR<FPE> write. 2808 mfpr r31, pt0 2809 2810 mfpr r31, pt0 2811// pvc_violate 225 // cuz PVC can't distinguish which bits changed 2812 hw_rei 2813 2814 2815 CALL_PAL_PRIV(0x002C) 2816CallPal_OpcDec2C: 2817 br r31, osfpal_calpal_opcdec 2818 2819// 2820// wrvptpr - PALcode for wrvptpr instruction 2821// 2822// Entry: 2823// Vectored into via hardware PALcode instruction dispatch. 2824// 2825// Function: 2826// vptptr <- a0 (r16) 2827// 2828 2829 CALL_PAL_PRIV(PAL_WRVPTPTR_ENTRY) 2830Call_Pal_Wrvptptr: 2831 mtpr r16, ev5__mvptbr // Load Mbox copy 2832 mtpr r16, ev5__ivptbr // Load Ibox copy 2833 nop // Pad IPR write 2834 nop 2835 hw_rei 2836 2837 CALL_PAL_PRIV(0x002E) 2838CallPal_OpcDec2E: 2839 br r31, osfpal_calpal_opcdec 2840 2841 CALL_PAL_PRIV(0x002F) 2842CallPal_OpcDec2F: 2843 br r31, osfpal_calpal_opcdec 2844 2845 2846// 2847// swpctx - PALcode for swpctx instruction 2848// 2849// Entry: 2850// hardware dispatch via callPal instruction 2851// R16 -> new pcb 2852// 2853// Function: 2854// dynamic state moved to old pcb 2855// new state loaded from new pcb 2856// pcbb pointer set 2857// old pcbb returned in R0 2858// 2859// Note: need to add perf monitor stuff 2860// 2861 2862 CALL_PAL_PRIV(PAL_SWPCTX_ENTRY) 2863Call_Pal_Swpctx: 2864 rpcc r13 // get cyccounter 2865 mfpr r0, pt_pcbb // get pcbb 2866 2867 ldq_p r22, osfpcb_q_fen(r16) // get new fen/pme 2868 ldq_p r23, osfpcb_l_cc(r16) // get new asn 2869 2870 srl r13, 32, r25 // move offset 2871 mfpr r24, pt_usp // get usp 2872 2873 stq_p r30, osfpcb_q_ksp(r0) // store old ksp 2874// pvc_violate 379 // stq_p can't trap except replay. only problem if mf same ipr in same shadow. 2875 mtpr r16, pt_pcbb // set new pcbb 2876 2877 stq_p r24, osfpcb_q_usp(r0) // store usp 2878 addl r13, r25, r25 // merge for new time 2879 2880 stl_p r25, osfpcb_l_cc(r0) // save time 2881 ldah r24, (1<<(icsr_v_fpe-16))(r31) 2882 2883 and r22, 1, r12 // isolate fen 2884 mfpr r25, icsr // get current icsr 2885 2886 lda r24, (1<<icsr_v_pmp)(r24) 2887 br r31, swpctx_cont 2888 2889// 2890// wrval - PALcode for wrval instruction 2891// 2892// Entry: 2893// Vectored into via hardware PALcode instruction dispatch. 2894// 2895// Function: 2896// sysvalue <- a0 (r16) 2897// 2898 2899 CALL_PAL_PRIV(PAL_WRVAL_ENTRY) 2900Call_Pal_Wrval: 2901 nop 2902 mtpr r16, pt_sysval // Pad paltemp write 2903 nop 2904 nop 2905 hw_rei 2906 2907// 2908// rdval - PALcode for rdval instruction 2909// 2910// Entry: 2911// Vectored into via hardware PALcode instruction dispatch. 2912// 2913// Function: 2914// v0 (r0) <- sysvalue 2915// 2916 2917 CALL_PAL_PRIV(PAL_RDVAL_ENTRY) 2918Call_Pal_Rdval: 2919 nop 2920 mfpr r0, pt_sysval 2921 nop 2922 hw_rei 2923 2924// 2925// tbi - PALcode for tbi instruction 2926// 2927// Entry: 2928// Vectored into via hardware PALcode instruction dispatch. 2929// 2930// Function: 2931// TB invalidate 2932// r16/a0 = TBI type 2933// r17/a1 = Va for TBISx instructions 2934// 2935 2936 CALL_PAL_PRIV(PAL_TBI_ENTRY) 2937Call_Pal_Tbi: 2938 addq r16, 2, r16 // change range to 0-2 2939 br r23, CALL_PAL_tbi_10_ // get our address 2940 2941CALL_PAL_tbi_10_: cmpult r16, 6, r22 // see if in range 2942 lda r23, tbi_tbl-CALL_PAL_tbi_10_(r23) // set base to start of table 2943 sll r16, 4, r16 // * 16 2944 blbc r22, CALL_PAL_tbi_30_ // go rei, if not 2945 2946 addq r23, r16, r23 // addr of our code 2947//orig pvc_jsr tbi 2948 jmp r31, (r23) // and go do it 2949 2950CALL_PAL_tbi_30_: 2951 hw_rei 2952 nop 2953 2954// 2955// wrent - PALcode for wrent instruction 2956// 2957// Entry: 2958// Vectored into via hardware PALcode instruction dispatch. 2959// 2960// Function: 2961// Update ent* in paltemps 2962// r16/a0 = Address of entry routine 2963// r17/a1 = Entry Number 0..5 2964// 2965// r22, r23 trashed 2966// 2967 2968 CALL_PAL_PRIV(PAL_WRENT_ENTRY) 2969Call_Pal_Wrent: 2970 cmpult r17, 6, r22 // see if in range 2971 br r23, CALL_PAL_wrent_10_ // get our address 2972 2973CALL_PAL_wrent_10_: bic r16, 3, r16 // clean pc 2974 blbc r22, CALL_PAL_wrent_30_ // go rei, if not in range 2975 2976 lda r23, wrent_tbl-CALL_PAL_wrent_10_(r23) // set base to start of table 2977 sll r17, 4, r17 // *16 2978 2979 addq r17, r23, r23 // Get address in table 2980//orig pvc_jsr wrent 2981 jmp r31, (r23) // and go do it 2982 2983CALL_PAL_wrent_30_: 2984 hw_rei // out of range, just return 2985 2986// 2987// swpipl - PALcode for swpipl instruction 2988// 2989// Entry: 2990// Vectored into via hardware PALcode instruction dispatch. 2991// 2992// Function: 2993// v0 (r0) <- PS<IPL> 2994// PS<IPL> <- a0<2:0> (r16) 2995// 2996// t8 (r22) is scratch 2997// 2998 2999 CALL_PAL_PRIV(PAL_SWPIPL_ENTRY) 3000Call_Pal_Swpipl: 3001 and r16, osfps_m_ipl, r16 // clean New ipl 3002 mfpr r22, pt_intmask // get int mask 3003 3004 extbl r22, r16, r22 // get mask for this ipl 3005 bis r11, r31, r0 // return old ipl 3006 3007 bis r16, r31, r11 // set new ps 3008 mtpr r22, ev5__ipl // set new mask 3009 3010 mfpr r31, pt0 // pad ipl write 3011 mfpr r31, pt0 // pad ipl write 3012 3013 hw_rei // back 3014 3015// 3016// rdps - PALcode for rdps instruction 3017// 3018// Entry: 3019// Vectored into via hardware PALcode instruction dispatch. 3020// 3021// Function: 3022// v0 (r0) <- ps 3023// 3024 3025 CALL_PAL_PRIV(PAL_RDPS_ENTRY) 3026Call_Pal_Rdps: 3027 bis r11, r31, r0 // Fetch PALshadow PS 3028 nop // Must be 2 cycles long 3029 hw_rei 3030 3031// 3032// wrkgp - PALcode for wrkgp instruction 3033// 3034// Entry: 3035// Vectored into via hardware PALcode instruction dispatch. 3036// 3037// Function: 3038// kgp <- a0 (r16) 3039// 3040 3041 CALL_PAL_PRIV(PAL_WRKGP_ENTRY) 3042Call_Pal_Wrkgp: 3043 nop 3044 mtpr r16, pt_kgp 3045 nop // Pad for pt write->read restriction 3046 nop 3047 hw_rei 3048 3049// 3050// wrusp - PALcode for wrusp instruction 3051// 3052// Entry: 3053// Vectored into via hardware PALcode instruction dispatch. 3054// 3055// Function: 3056// usp <- a0 (r16) 3057// 3058 3059 CALL_PAL_PRIV(PAL_WRUSP_ENTRY) 3060Call_Pal_Wrusp: 3061 nop 3062 mtpr r16, pt_usp 3063 nop // Pad possible pt write->read restriction 3064 nop 3065 hw_rei 3066 3067// 3068// wrperfmon - PALcode for wrperfmon instruction 3069// 3070// Entry: 3071// Vectored into via hardware PALcode instruction dispatch. 3072// 3073// 3074// Function: 3075// Various control functions for the onchip performance counters 3076// 3077// option selector in r16 3078// option argument in r17 3079// returned status in r0 3080// 3081// 3082// r16 = 0 Disable performance monitoring for one or more cpu's 3083// r17 = 0 disable no counters 3084// r17 = bitmask disable counters specified in bit mask (1=disable) 3085// 3086// r16 = 1 Enable performance monitoring for one or more cpu's 3087// r17 = 0 enable no counters 3088// r17 = bitmask enable counters specified in bit mask (1=enable) 3089// 3090// r16 = 2 Mux select for one or more cpu's 3091// r17 = Mux selection (cpu specific) 3092// <24:19> bc_ctl<pm_mux_sel> field (see spec) 3093// <31>,<7:4>,<3:0> pmctr <sel0>,<sel1>,<sel2> fields (see spec) 3094// 3095// r16 = 3 Options 3096// r17 = (cpu specific) 3097// <0> = 0 log all processes 3098// <0> = 1 log only selected processes 3099// <30,9,8> mode select - ku,kp,kk 3100// 3101// r16 = 4 Interrupt frequency select 3102// r17 = (cpu specific) indicates interrupt frequencies desired for each 3103// counter, with "zero interrupts" being an option 3104// frequency info in r17 bits as defined by PMCTR_CTL<FRQx> below 3105// 3106// r16 = 5 Read Counters 3107// r17 = na 3108// r0 = value (same format as ev5 pmctr) 3109// <0> = 0 Read failed 3110// <0> = 1 Read succeeded 3111// 3112// r16 = 6 Write Counters 3113// r17 = value (same format as ev5 pmctr; all counters written simultaneously) 3114// 3115// r16 = 7 Enable performance monitoring for one or more cpu's and reset counter to 0 3116// r17 = 0 enable no counters 3117// r17 = bitmask enable & clear counters specified in bit mask (1=enable & clear) 3118// 3119//============================================================================= 3120//Assumptions: 3121//PMCTR_CTL: 3122// 3123// <15:14> CTL0 -- encoded frequency select and enable - CTR0 3124// <13:12> CTL1 -- " - CTR1 3125// <11:10> CTL2 -- " - CTR2 3126// 3127// <9:8> FRQ0 -- frequency select for CTR0 (no enable info) 3128// <7:6> FRQ1 -- frequency select for CTR1 3129// <5:4> FRQ2 -- frequency select for CTR2 3130// 3131// <0> all vs. select processes (0=all,1=select) 3132// 3133// where 3134// FRQx<1:0> 3135// 0 1 disable interrupt 3136// 1 0 frequency = 65536 (16384 for ctr2) 3137// 1 1 frequency = 256 3138// note: FRQx<1:0> = 00 will keep counters from ever being enabled. 3139// 3140//============================================================================= 3141// 3142 CALL_PAL_PRIV(0x0039) 3143// unsupported in Hudson code .. pboyle Nov/95 3144CALL_PAL_Wrperfmon: 3145 // "real" performance monitoring code 3146 cmpeq r16, 1, r0 // check for enable 3147 bne r0, perfmon_en // br if requested to enable 3148 3149 cmpeq r16, 2, r0 // check for mux ctl 3150 bne r0, perfmon_muxctl // br if request to set mux controls 3151 3152 cmpeq r16, 3, r0 // check for options 3153 bne r0, perfmon_ctl // br if request to set options 3154 3155 cmpeq r16, 4, r0 // check for interrupt frequency select 3156 bne r0, perfmon_freq // br if request to change frequency select 3157 3158 cmpeq r16, 5, r0 // check for counter read request 3159 bne r0, perfmon_rd // br if request to read counters 3160 3161 cmpeq r16, 6, r0 // check for counter write request 3162 bne r0, perfmon_wr // br if request to write counters 3163 3164 cmpeq r16, 7, r0 // check for counter clear/enable request 3165 bne r0, perfmon_enclr // br if request to clear/enable counters 3166 3167 beq r16, perfmon_dis // br if requested to disable (r16=0) 3168 br r31, perfmon_unknown // br if unknown request 3169 3170// 3171// rdusp - PALcode for rdusp instruction 3172// 3173// Entry: 3174// Vectored into via hardware PALcode instruction dispatch. 3175// 3176// Function: 3177// v0 (r0) <- usp 3178// 3179 3180 CALL_PAL_PRIV(PAL_RDUSP_ENTRY) 3181Call_Pal_Rdusp: 3182 nop 3183 mfpr r0, pt_usp 3184 hw_rei 3185 3186 3187 CALL_PAL_PRIV(0x003B) 3188CallPal_OpcDec3B: 3189 br r31, osfpal_calpal_opcdec 3190 3191// 3192// whami - PALcode for whami instruction 3193// 3194// Entry: 3195// Vectored into via hardware PALcode instruction dispatch. 3196// 3197// Function: 3198// v0 (r0) <- whami 3199// 3200 CALL_PAL_PRIV(PAL_WHAMI_ENTRY) 3201Call_Pal_Whami: 3202 nop 3203 mfpr r0, pt_whami // Get Whami 3204 extbl r0, 1, r0 // Isolate just whami bits 3205 hw_rei 3206 3207// 3208// retsys - PALcode for retsys instruction 3209// 3210// Entry: 3211// Vectored into via hardware PALcode instruction dispatch. 3212// 00(sp) contains return pc 3213// 08(sp) contains r29 3214// 3215// Function: 3216// Return from system call. 3217// mode switched from kern to user. 3218// stacks swapped, ugp, upc restored. 3219// r23, r25 junked 3220// 3221 3222 CALL_PAL_PRIV(PAL_RETSYS_ENTRY) 3223Call_Pal_Retsys: 3224 lda r25, osfsf_c_size(sp) // pop stack 3225 bis r25, r31, r14 // touch r25 & r14 to stall mf exc_addr 3226 3227 mfpr r14, exc_addr // save exc_addr in case of fault 3228 ldq r23, osfsf_pc(sp) // get pc 3229 3230 ldq r29, osfsf_gp(sp) // get gp 3231 stl_c r31, -4(sp) // clear lock_flag 3232 3233 lda r11, 1<<osfps_v_mode(r31)// new PS:mode=user 3234 mfpr r30, pt_usp // get users stack 3235 3236 bic r23, 3, r23 // clean return pc 3237 mtpr r31, ev5__ipl // zero ibox IPL - 2 bubbles to hw_rei 3238 3239 mtpr r11, ev5__dtb_cm // set Mbox current mode - no virt ref for 2 cycles 3240 mtpr r11, ev5__ps // set Ibox current mode - 2 bubble to hw_rei 3241 3242 mtpr r23, exc_addr // set return address - 1 bubble to hw_rei 3243 mtpr r25, pt_ksp // save kern stack 3244 3245 rc r31 // clear inter_flag 3246// pvc_violate 248 // possible hidden mt->mf pt violation ok in callpal 3247 hw_rei_spe // and back 3248 3249 3250 CALL_PAL_PRIV(0x003E) 3251CallPal_OpcDec3E: 3252 br r31, osfpal_calpal_opcdec 3253 3254// 3255// rti - PALcode for rti instruction 3256// 3257// Entry: 3258// Vectored into via hardware PALcode instruction dispatch. 3259// 3260// Function: 3261// 00(sp) -> ps 3262// 08(sp) -> pc 3263// 16(sp) -> r29 (gp) 3264// 24(sp) -> r16 (a0) 3265// 32(sp) -> r17 (a1) 3266// 40(sp) -> r18 (a3) 3267// 3268 3269 CALL_PAL_PRIV(PAL_RTI_ENTRY) 3270 /* called once by platform_tlaser */ 3271 .globl Call_Pal_Rti 3272Call_Pal_Rti: 3273 lda r25, osfsf_c_size(sp) // get updated sp 3274 bis r25, r31, r14 // touch r14,r25 to stall mf exc_addr 3275 3276 mfpr r14, exc_addr // save PC in case of fault 3277 rc r31 // clear intr_flag 3278 3279 ldq r12, -6*8(r25) // get ps 3280 ldq r13, -5*8(r25) // pc 3281 3282 ldq r18, -1*8(r25) // a2 3283 ldq r17, -2*8(r25) // a1 3284 3285 ldq r16, -3*8(r25) // a0 3286 ldq r29, -4*8(r25) // gp 3287 3288 bic r13, 3, r13 // clean return pc 3289 stl_c r31, -4(r25) // clear lock_flag 3290 3291 and r12, osfps_m_mode, r11 // get mode 3292 mtpr r13, exc_addr // set return address 3293 3294 beq r11, rti_to_kern // br if rti to Kern 3295 br r31, rti_to_user // out of call_pal space 3296 3297 3298/////////////////////////////////////////////////// 3299// Start the Unprivileged CALL_PAL Entry Points 3300/////////////////////////////////////////////////// 3301 3302// 3303// bpt - PALcode for bpt instruction 3304// 3305// Entry: 3306// Vectored into via hardware PALcode instruction dispatch. 3307// 3308// Function: 3309// Build stack frame 3310// a0 <- code 3311// a1 <- unpred 3312// a2 <- unpred 3313// vector via entIF 3314// 3315// 3316// 3317 .text 1 3318// . = 0x3000 3319 CALL_PAL_UNPRIV(PAL_BPT_ENTRY) 3320Call_Pal_Bpt: 3321 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 3322 mtpr r31, ev5__ps // Set Ibox current mode to kernel 3323 3324 bis r11, r31, r12 // Save PS for stack write 3325 bge r25, CALL_PAL_bpt_10_ // no stack swap needed if cm=kern 3326 3327 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 3328 // no virt ref for next 2 cycles 3329 mtpr r30, pt_usp // save user stack 3330 3331 bis r31, r31, r11 // Set new PS 3332 mfpr r30, pt_ksp 3333 3334CALL_PAL_bpt_10_: 3335 lda sp, 0-osfsf_c_size(sp)// allocate stack space 3336 mfpr r14, exc_addr // get pc 3337 3338 stq r16, osfsf_a0(sp) // save regs 3339 bis r31, osf_a0_bpt, r16 // set a0 3340 3341 stq r17, osfsf_a1(sp) // a1 3342 br r31, bpt_bchk_common // out of call_pal space 3343 3344 3345// 3346// bugchk - PALcode for bugchk instruction 3347// 3348// Entry: 3349// Vectored into via hardware PALcode instruction dispatch. 3350// 3351// Function: 3352// Build stack frame 3353// a0 <- code 3354// a1 <- unpred 3355// a2 <- unpred 3356// vector via entIF 3357// 3358// 3359// 3360 CALL_PAL_UNPRIV(PAL_BUGCHK_ENTRY) 3361Call_Pal_Bugchk: 3362 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 3363 mtpr r31, ev5__ps // Set Ibox current mode to kernel 3364 3365 bis r11, r31, r12 // Save PS for stack write 3366 bge r25, CALL_PAL_bugchk_10_ // no stack swap needed if cm=kern 3367 3368 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 3369 // no virt ref for next 2 cycles 3370 mtpr r30, pt_usp // save user stack 3371 3372 bis r31, r31, r11 // Set new PS 3373 mfpr r30, pt_ksp 3374 3375CALL_PAL_bugchk_10_: 3376 lda sp, 0-osfsf_c_size(sp)// allocate stack space 3377 mfpr r14, exc_addr // get pc 3378 3379 stq r16, osfsf_a0(sp) // save regs 3380 bis r31, osf_a0_bugchk, r16 // set a0 3381 3382 stq r17, osfsf_a1(sp) // a1 3383 br r31, bpt_bchk_common // out of call_pal space 3384 3385 3386 CALL_PAL_UNPRIV(0x0082) 3387CallPal_OpcDec82: 3388 br r31, osfpal_calpal_opcdec 3389 3390// 3391// callsys - PALcode for callsys instruction 3392// 3393// Entry: 3394// Vectored into via hardware PALcode instruction dispatch. 3395// 3396// Function: 3397// Switch mode to kernel and build a callsys stack frame. 3398// sp = ksp 3399// gp = kgp 3400// t8 - t10 (r22-r24) trashed 3401// 3402// 3403// 3404 CALL_PAL_UNPRIV(PAL_CALLSYS_ENTRY) 3405Call_Pal_Callsys: 3406 3407 and r11, osfps_m_mode, r24 // get mode 3408 mfpr r22, pt_ksp // get ksp 3409 3410 beq r24, sys_from_kern // sysCall from kern is not allowed 3411 mfpr r12, pt_entsys // get address of callSys routine 3412 3413// 3414// from here on we know we are in user going to Kern 3415// 3416 mtpr r31, ev5__dtb_cm // set Mbox current mode - no virt ref for 2 cycles 3417 mtpr r31, ev5__ps // set Ibox current mode - 2 bubble to hw_rei 3418 3419 bis r31, r31, r11 // PS=0 (mode=kern) 3420 mfpr r23, exc_addr // get pc 3421 3422 mtpr r30, pt_usp // save usp 3423 lda sp, 0-osfsf_c_size(r22)// set new sp 3424 3425 stq r29, osfsf_gp(sp) // save user gp/r29 3426 stq r24, osfsf_ps(sp) // save ps 3427 3428 stq r23, osfsf_pc(sp) // save pc 3429 mtpr r12, exc_addr // set address 3430 // 1 cycle to hw_rei 3431 3432 mfpr r29, pt_kgp // get the kern gp/r29 3433 3434 hw_rei_spe // and off we go! 3435 3436 3437 CALL_PAL_UNPRIV(0x0084) 3438CallPal_OpcDec84: 3439 br r31, osfpal_calpal_opcdec 3440 3441 CALL_PAL_UNPRIV(0x0085) 3442CallPal_OpcDec85: 3443 br r31, osfpal_calpal_opcdec 3444 3445// 3446// imb - PALcode for imb instruction 3447// 3448// Entry: 3449// Vectored into via hardware PALcode instruction dispatch. 3450// 3451// Function: 3452// Flush the writebuffer and flush the Icache 3453// 3454// 3455// 3456 CALL_PAL_UNPRIV(PAL_IMB_ENTRY) 3457Call_Pal_Imb: 3458 mb // Clear the writebuffer 3459 mfpr r31, ev5__mcsr // Sync with clear 3460 nop 3461 nop 3462 br r31, pal_ic_flush // Flush Icache 3463 3464 3465// CALL_PAL OPCDECs 3466 3467 CALL_PAL_UNPRIV(0x0087) 3468CallPal_OpcDec87: 3469 br r31, osfpal_calpal_opcdec 3470 3471 CALL_PAL_UNPRIV(0x0088) 3472CallPal_OpcDec88: 3473 br r31, osfpal_calpal_opcdec 3474 3475 CALL_PAL_UNPRIV(0x0089) 3476CallPal_OpcDec89: 3477 br r31, osfpal_calpal_opcdec 3478 3479 CALL_PAL_UNPRIV(0x008A) 3480CallPal_OpcDec8A: 3481 br r31, osfpal_calpal_opcdec 3482 3483 CALL_PAL_UNPRIV(0x008B) 3484CallPal_OpcDec8B: 3485 br r31, osfpal_calpal_opcdec 3486 3487 CALL_PAL_UNPRIV(0x008C) 3488CallPal_OpcDec8C: 3489 br r31, osfpal_calpal_opcdec 3490 3491 CALL_PAL_UNPRIV(0x008D) 3492CallPal_OpcDec8D: 3493 br r31, osfpal_calpal_opcdec 3494 3495 CALL_PAL_UNPRIV(0x008E) 3496CallPal_OpcDec8E: 3497 br r31, osfpal_calpal_opcdec 3498 3499 CALL_PAL_UNPRIV(0x008F) 3500CallPal_OpcDec8F: 3501 br r31, osfpal_calpal_opcdec 3502 3503 CALL_PAL_UNPRIV(0x0090) 3504CallPal_OpcDec90: 3505 br r31, osfpal_calpal_opcdec 3506 3507 CALL_PAL_UNPRIV(0x0091) 3508CallPal_OpcDec91: 3509 br r31, osfpal_calpal_opcdec 3510 3511 CALL_PAL_UNPRIV(0x0092) 3512CallPal_OpcDec92: 3513 br r31, osfpal_calpal_opcdec 3514 3515 CALL_PAL_UNPRIV(0x0093) 3516CallPal_OpcDec93: 3517 br r31, osfpal_calpal_opcdec 3518 3519 CALL_PAL_UNPRIV(0x0094) 3520CallPal_OpcDec94: 3521 br r31, osfpal_calpal_opcdec 3522 3523 CALL_PAL_UNPRIV(0x0095) 3524CallPal_OpcDec95: 3525 br r31, osfpal_calpal_opcdec 3526 3527 CALL_PAL_UNPRIV(0x0096) 3528CallPal_OpcDec96: 3529 br r31, osfpal_calpal_opcdec 3530 3531 CALL_PAL_UNPRIV(0x0097) 3532CallPal_OpcDec97: 3533 br r31, osfpal_calpal_opcdec 3534 3535 CALL_PAL_UNPRIV(0x0098) 3536CallPal_OpcDec98: 3537 br r31, osfpal_calpal_opcdec 3538 3539 CALL_PAL_UNPRIV(0x0099) 3540CallPal_OpcDec99: 3541 br r31, osfpal_calpal_opcdec 3542 3543 CALL_PAL_UNPRIV(0x009A) 3544CallPal_OpcDec9A: 3545 br r31, osfpal_calpal_opcdec 3546 3547 CALL_PAL_UNPRIV(0x009B) 3548CallPal_OpcDec9B: 3549 br r31, osfpal_calpal_opcdec 3550 3551 CALL_PAL_UNPRIV(0x009C) 3552CallPal_OpcDec9C: 3553 br r31, osfpal_calpal_opcdec 3554 3555 CALL_PAL_UNPRIV(0x009D) 3556CallPal_OpcDec9D: 3557 br r31, osfpal_calpal_opcdec 3558 3559// 3560// rdunique - PALcode for rdunique instruction 3561// 3562// Entry: 3563// Vectored into via hardware PALcode instruction dispatch. 3564// 3565// Function: 3566// v0 (r0) <- unique 3567// 3568// 3569// 3570 CALL_PAL_UNPRIV(PAL_RDUNIQUE_ENTRY) 3571CALL_PALrdunique_: 3572 mfpr r0, pt_pcbb // get pcb pointer 3573 ldq_p r0, osfpcb_q_unique(r0) // get new value 3574 3575 hw_rei 3576 3577// 3578// wrunique - PALcode for wrunique instruction 3579// 3580// Entry: 3581// Vectored into via hardware PALcode instruction dispatch. 3582// 3583// Function: 3584// unique <- a0 (r16) 3585// 3586// 3587// 3588CALL_PAL_UNPRIV(PAL_WRUNIQUE_ENTRY) 3589CALL_PAL_Wrunique: 3590 nop 3591 mfpr r12, pt_pcbb // get pcb pointer 3592 stq_p r16, osfpcb_q_unique(r12)// get new value 3593 nop // Pad palshadow write 3594 hw_rei // back 3595 3596// CALL_PAL OPCDECs 3597 3598 CALL_PAL_UNPRIV(0x00A0) 3599CallPal_OpcDecA0: 3600 br r31, osfpal_calpal_opcdec 3601 3602 CALL_PAL_UNPRIV(0x00A1) 3603CallPal_OpcDecA1: 3604 br r31, osfpal_calpal_opcdec 3605 3606 CALL_PAL_UNPRIV(0x00A2) 3607CallPal_OpcDecA2: 3608 br r31, osfpal_calpal_opcdec 3609 3610 CALL_PAL_UNPRIV(0x00A3) 3611CallPal_OpcDecA3: 3612 br r31, osfpal_calpal_opcdec 3613 3614 CALL_PAL_UNPRIV(0x00A4) 3615CallPal_OpcDecA4: 3616 br r31, osfpal_calpal_opcdec 3617 3618 CALL_PAL_UNPRIV(0x00A5) 3619CallPal_OpcDecA5: 3620 br r31, osfpal_calpal_opcdec 3621 3622 CALL_PAL_UNPRIV(0x00A6) 3623CallPal_OpcDecA6: 3624 br r31, osfpal_calpal_opcdec 3625 3626 CALL_PAL_UNPRIV(0x00A7) 3627CallPal_OpcDecA7: 3628 br r31, osfpal_calpal_opcdec 3629 3630 CALL_PAL_UNPRIV(0x00A8) 3631CallPal_OpcDecA8: 3632 br r31, osfpal_calpal_opcdec 3633 3634 CALL_PAL_UNPRIV(0x00A9) 3635CallPal_OpcDecA9: 3636 br r31, osfpal_calpal_opcdec 3637 3638 3639// 3640// gentrap - PALcode for gentrap instruction 3641// 3642// CALL_PAL_gentrap: 3643// Entry: 3644// Vectored into via hardware PALcode instruction dispatch. 3645// 3646// Function: 3647// Build stack frame 3648// a0 <- code 3649// a1 <- unpred 3650// a2 <- unpred 3651// vector via entIF 3652// 3653// 3654 3655 CALL_PAL_UNPRIV(0x00AA) 3656// unsupported in Hudson code .. pboyle Nov/95 3657CALL_PAL_gentrap: 3658 sll r11, 63-osfps_v_mode, r25 // Shift mode up to MS bit 3659 mtpr r31, ev5__ps // Set Ibox current mode to kernel 3660 3661 bis r11, r31, r12 // Save PS for stack write 3662 bge r25, CALL_PAL_gentrap_10_ // no stack swap needed if cm=kern 3663 3664 mtpr r31, ev5__dtb_cm // Set Mbox current mode to kernel - 3665 // no virt ref for next 2 cycles 3666 mtpr r30, pt_usp // save user stack 3667 3668 bis r31, r31, r11 // Set new PS 3669 mfpr r30, pt_ksp 3670 3671CALL_PAL_gentrap_10_: 3672 lda sp, 0-osfsf_c_size(sp)// allocate stack space 3673 mfpr r14, exc_addr // get pc 3674 3675 stq r16, osfsf_a0(sp) // save regs 3676 bis r31, osf_a0_gentrap, r16// set a0 3677 3678 stq r17, osfsf_a1(sp) // a1 3679 br r31, bpt_bchk_common // out of call_pal space 3680 3681 3682// CALL_PAL OPCDECs 3683 3684 CALL_PAL_UNPRIV(0x00AB) 3685CallPal_OpcDecAB: 3686 br r31, osfpal_calpal_opcdec 3687 3688 CALL_PAL_UNPRIV(0x00AC) 3689CallPal_OpcDecAC: 3690 br r31, osfpal_calpal_opcdec 3691 3692 CALL_PAL_UNPRIV(0x00AD) 3693CallPal_OpcDecAD: 3694 br r31, osfpal_calpal_opcdec 3695 3696 CALL_PAL_UNPRIV(0x00AE) 3697CallPal_OpcDecAE: 3698 br r31, osfpal_calpal_opcdec 3699 3700 CALL_PAL_UNPRIV(0x00AF) 3701CallPal_OpcDecAF: 3702 br r31, osfpal_calpal_opcdec 3703 3704 CALL_PAL_UNPRIV(0x00B0) 3705CallPal_OpcDecB0: 3706 br r31, osfpal_calpal_opcdec 3707 3708 CALL_PAL_UNPRIV(0x00B1) 3709CallPal_OpcDecB1: 3710 br r31, osfpal_calpal_opcdec 3711 3712 CALL_PAL_UNPRIV(0x00B2) 3713CallPal_OpcDecB2: 3714 br r31, osfpal_calpal_opcdec 3715 3716 CALL_PAL_UNPRIV(0x00B3) 3717CallPal_OpcDecB3: 3718 br r31, osfpal_calpal_opcdec 3719 3720 CALL_PAL_UNPRIV(0x00B4) 3721CallPal_OpcDecB4: 3722 br r31, osfpal_calpal_opcdec 3723 3724 CALL_PAL_UNPRIV(0x00B5) 3725CallPal_OpcDecB5: 3726 br r31, osfpal_calpal_opcdec 3727 3728 CALL_PAL_UNPRIV(0x00B6) 3729CallPal_OpcDecB6: 3730 br r31, osfpal_calpal_opcdec 3731 3732 CALL_PAL_UNPRIV(0x00B7) 3733CallPal_OpcDecB7: 3734 br r31, osfpal_calpal_opcdec 3735 3736 CALL_PAL_UNPRIV(0x00B8) 3737CallPal_OpcDecB8: 3738 br r31, osfpal_calpal_opcdec 3739 3740 CALL_PAL_UNPRIV(0x00B9) 3741CallPal_OpcDecB9: 3742 br r31, osfpal_calpal_opcdec 3743 3744 CALL_PAL_UNPRIV(0x00BA) 3745CallPal_OpcDecBA: 3746 br r31, osfpal_calpal_opcdec 3747 3748 CALL_PAL_UNPRIV(0x00BB) 3749CallPal_OpcDecBB: 3750 br r31, osfpal_calpal_opcdec 3751 3752 CALL_PAL_UNPRIV(0x00BC) 3753CallPal_OpcDecBC: 3754 br r31, osfpal_calpal_opcdec 3755 3756 CALL_PAL_UNPRIV(0x00BD) 3757CallPal_OpcDecBD: 3758 br r31, osfpal_calpal_opcdec 3759 3760 CALL_PAL_UNPRIV(0x00BE) 3761CallPal_OpcDecBE: 3762 br r31, osfpal_calpal_opcdec 3763 3764 CALL_PAL_UNPRIV(0x00BF) 3765CallPal_OpcDecBF: 3766 // MODIFIED BY EGH 2/25/04 3767 br r31, copypal_impl 3768 3769 3770/*======================================================================*/ 3771/* OSF/1 CALL_PAL CONTINUATION AREA */ 3772/*======================================================================*/ 3773 3774 .text 2 3775 3776 . = 0x4000 3777 3778 3779// Continuation of MTPR_PERFMON 3780 ALIGN_BLOCK 3781 // "real" performance monitoring code 3782// mux ctl 3783perfmon_muxctl: 3784 lda r8, 1(r31) // get a 1 3785 sll r8, pmctr_v_sel0, r8 // move to sel0 position 3786 or r8, ((0xf<<pmctr_v_sel1) | (0xf<<pmctr_v_sel2)), r8 // build mux select mask 3787 and r17, r8, r25 // isolate pmctr mux select bits 3788 mfpr r0, ev5__pmctr 3789 bic r0, r8, r0 // clear old mux select bits 3790 or r0,r25, r25 // or in new mux select bits 3791 mtpr r25, ev5__pmctr 3792 3793 // ok, now tackle cbox mux selects 3794 ldah r14, 0xfff0(r31) 3795 zap r14, 0xE0, r14 // Get Cbox IPR base 3796//orig get_bc_ctl_shadow r16 // bc_ctl returned in lower longword 3797// adapted from ev5_pal_macros.mar 3798 mfpr r16, pt_impure 3799 lda r16, CNS_Q_IPR(r16) 3800 RESTORE_SHADOW(r16,CNS_Q_BC_CTL,r16); 3801 3802 lda r8, 0x3F(r31) // build mux select mask 3803 sll r8, bc_ctl_v_pm_mux_sel, r8 3804 3805 and r17, r8, r25 // isolate bc_ctl mux select bits 3806 bic r16, r8, r16 // isolate old mux select bits 3807 or r16, r25, r25 // create new bc_ctl 3808 mb // clear out cbox for future ipr write 3809 stq_p r25, ev5__bc_ctl(r14) // store to cbox ipr 3810 mb // clear out cbox for future ipr write 3811 3812//orig update_bc_ctl_shadow r25, r16 // r25=value, r16-overwritten with adjusted impure ptr 3813// adapted from ev5_pal_macros.mar 3814 mfpr r16, pt_impure 3815 lda r16, CNS_Q_IPR(r16) 3816 SAVE_SHADOW(r25,CNS_Q_BC_CTL,r16); 3817 3818 br r31, perfmon_success 3819 3820 3821// requested to disable perf monitoring 3822perfmon_dis: 3823 mfpr r14, ev5__pmctr // read ibox pmctr ipr 3824perfmon_dis_ctr0: // and begin with ctr0 3825 blbc r17, perfmon_dis_ctr1 // do not disable ctr0 3826 lda r8, 3(r31) 3827 sll r8, pmctr_v_ctl0, r8 3828 bic r14, r8, r14 // disable ctr0 3829perfmon_dis_ctr1: 3830 srl r17, 1, r17 3831 blbc r17, perfmon_dis_ctr2 // do not disable ctr1 3832 lda r8, 3(r31) 3833 sll r8, pmctr_v_ctl1, r8 3834 bic r14, r8, r14 // disable ctr1 3835perfmon_dis_ctr2: 3836 srl r17, 1, r17 3837 blbc r17, perfmon_dis_update // do not disable ctr2 3838 lda r8, 3(r31) 3839 sll r8, pmctr_v_ctl2, r8 3840 bic r14, r8, r14 // disable ctr2 3841perfmon_dis_update: 3842 mtpr r14, ev5__pmctr // update pmctr ipr 3843//;the following code is not needed for ev5 pass2 and later, but doesn't hurt anything to leave in 3844// adapted from ev5_pal_macros.mar 3845//orig get_pmctr_ctl r8, r25 // pmctr_ctl bit in r8. adjusted impure pointer in r25 3846 mfpr r25, pt_impure 3847 lda r25, CNS_Q_IPR(r25) 3848 RESTORE_SHADOW(r8,CNS_Q_PM_CTL,r25); 3849 3850 lda r17, 0x3F(r31) // build mask 3851 sll r17, pmctr_v_ctl2, r17 // shift mask to correct position 3852 and r14, r17, r14 // isolate ctl bits 3853 bic r8, r17, r8 // clear out old ctl bits 3854 or r14, r8, r14 // create shadow ctl bits 3855//orig store_reg1 pmctr_ctl, r14, r25, ipr=1 // update pmctr_ctl register 3856//adjusted impure pointer still in r25 3857 SAVE_SHADOW(r14,CNS_Q_PM_CTL,r25); 3858 3859 br r31, perfmon_success 3860 3861 3862// requested to enable perf monitoring 3863//;the following code can be greatly simplified for pass2, but should work fine as is. 3864 3865 3866perfmon_enclr: 3867 lda r9, 1(r31) // set enclr flag 3868 br perfmon_en_cont 3869 3870perfmon_en: 3871 bis r31, r31, r9 // clear enclr flag 3872 3873perfmon_en_cont: 3874 mfpr r8, pt_pcbb // get PCB base 3875//orig get_pmctr_ctl r25, r25 3876 mfpr r25, pt_impure 3877 lda r25, CNS_Q_IPR(r25) 3878 RESTORE_SHADOW(r25,CNS_Q_PM_CTL,r25); 3879 3880 ldq_p r16, osfpcb_q_fen(r8) // read DAT/PME/FEN quadword 3881 mfpr r14, ev5__pmctr // read ibox pmctr ipr 3882 srl r16, osfpcb_v_pme, r16 // get pme bit 3883 mfpr r13, icsr 3884 and r16, 1, r16 // isolate pme bit 3885 3886 // this code only needed in pass2 and later 3887 lda r12, 1<<icsr_v_pmp(r31) // pb 3888 bic r13, r12, r13 // clear pmp bit 3889 sll r16, icsr_v_pmp, r12 // move pme bit to icsr<pmp> position 3890 or r12, r13, r13 // new icsr with icsr<pmp> bit set/clear 3891 mtpr r13, icsr // update icsr 3892 3893 bis r31, 1, r16 // set r16<0> on pass2 to update pmctr always (icsr provides real enable) 3894 3895 sll r25, 6, r25 // shift frequency bits into pmctr_v_ctl positions 3896 bis r14, r31, r13 // copy pmctr 3897 3898perfmon_en_ctr0: // and begin with ctr0 3899 blbc r17, perfmon_en_ctr1 // do not enable ctr0 3900 3901 blbc r9, perfmon_en_noclr0 // enclr flag set, clear ctr0 field 3902 lda r8, 0xffff(r31) 3903 zapnot r8, 3, r8 // ctr0<15:0> mask 3904 sll r8, pmctr_v_ctr0, r8 3905 bic r14, r8, r14 // clear ctr bits 3906 bic r13, r8, r13 // clear ctr bits 3907 3908perfmon_en_noclr0: 3909//orig get_addr r8, 3<<pmctr_v_ctl0, r31 3910 LDLI(r8, (3<<pmctr_v_ctl0)) 3911 and r25, r8, r12 //isolate frequency select bits for ctr0 3912 bic r14, r8, r14 // clear ctl0 bits in preparation for enabling 3913 or r14,r12,r14 // or in new ctl0 bits 3914 3915perfmon_en_ctr1: // enable ctr1 3916 srl r17, 1, r17 // get ctr1 enable 3917 blbc r17, perfmon_en_ctr2 // do not enable ctr1 3918 3919 blbc r9, perfmon_en_noclr1 // if enclr flag set, clear ctr1 field 3920 lda r8, 0xffff(r31) 3921 zapnot r8, 3, r8 // ctr1<15:0> mask 3922 sll r8, pmctr_v_ctr1, r8 3923 bic r14, r8, r14 // clear ctr bits 3924 bic r13, r8, r13 // clear ctr bits 3925 3926perfmon_en_noclr1: 3927//orig get_addr r8, 3<<pmctr_v_ctl1, r31 3928 LDLI(r8, (3<<pmctr_v_ctl1)) 3929 and r25, r8, r12 //isolate frequency select bits for ctr1 3930 bic r14, r8, r14 // clear ctl1 bits in preparation for enabling 3931 or r14,r12,r14 // or in new ctl1 bits 3932 3933perfmon_en_ctr2: // enable ctr2 3934 srl r17, 1, r17 // get ctr2 enable 3935 blbc r17, perfmon_en_return // do not enable ctr2 - return 3936 3937 blbc r9, perfmon_en_noclr2 // if enclr flag set, clear ctr2 field 3938 lda r8, 0x3FFF(r31) // ctr2<13:0> mask 3939 sll r8, pmctr_v_ctr2, r8 3940 bic r14, r8, r14 // clear ctr bits 3941 bic r13, r8, r13 // clear ctr bits 3942 3943perfmon_en_noclr2: 3944//orig get_addr r8, 3<<pmctr_v_ctl2, r31 3945 LDLI(r8, (3<<pmctr_v_ctl2)) 3946 and r25, r8, r12 //isolate frequency select bits for ctr2 3947 bic r14, r8, r14 // clear ctl2 bits in preparation for enabling 3948 or r14,r12,r14 // or in new ctl2 bits 3949 3950perfmon_en_return: 3951 cmovlbs r16, r14, r13 // if pme enabled, move enables into pmctr 3952 // else only do the counter clears 3953 mtpr r13, ev5__pmctr // update pmctr ipr 3954 3955//;this code not needed for pass2 and later, but does not hurt to leave it in 3956 lda r8, 0x3F(r31) 3957//orig get_pmctr_ctl r25, r12 // read pmctr ctl; r12=adjusted impure pointer 3958 mfpr r12, pt_impure 3959 lda r12, CNS_Q_IPR(r12) 3960 RESTORE_SHADOW(r25,CNS_Q_PM_CTL,r12); 3961 3962 sll r8, pmctr_v_ctl2, r8 // build ctl mask 3963 and r8, r14, r14 // isolate new ctl bits 3964 bic r25, r8, r25 // clear out old ctl value 3965 or r25, r14, r14 // create new pmctr_ctl 3966//orig store_reg1 pmctr_ctl, r14, r12, ipr=1 3967 SAVE_SHADOW(r14,CNS_Q_PM_CTL,r12); // r12 still has the adjusted impure ptr 3968 3969 br r31, perfmon_success 3970 3971 3972// options... 3973perfmon_ctl: 3974 3975// set mode 3976//orig get_pmctr_ctl r14, r12 // read shadow pmctr ctl; r12=adjusted impure pointer 3977 mfpr r12, pt_impure 3978 lda r12, CNS_Q_IPR(r12) 3979 RESTORE_SHADOW(r14,CNS_Q_PM_CTL,r12); 3980 3981 // build mode mask for pmctr register 3982 LDLI(r8, ((1<<pmctr_v_killu) | (1<<pmctr_v_killp) | (1<<pmctr_v_killk))) 3983 mfpr r0, ev5__pmctr 3984 and r17, r8, r25 // isolate pmctr mode bits 3985 bic r0, r8, r0 // clear old mode bits 3986 or r0, r25, r25 // or in new mode bits 3987 mtpr r25, ev5__pmctr 3988 3989 // the following code will only be used in pass2, but should 3990 // not hurt anything if run in pass1. 3991 mfpr r8, icsr 3992 lda r25, 1<<icsr_v_pma(r31) // set icsr<pma> if r17<0>=0 3993 bic r8, r25, r8 // clear old pma bit 3994 cmovlbs r17, r31, r25 // and clear icsr<pma> if r17<0>=1 3995 or r8, r25, r8 3996 mtpr r8, icsr // 4 bubbles to hw_rei 3997 mfpr r31, pt0 // pad icsr write 3998 mfpr r31, pt0 // pad icsr write 3999 4000 // the following code not needed for pass2 and later, but 4001 // should work anyway. 4002 bis r14, 1, r14 // set for select processes 4003 blbs r17, perfmon_sp // branch if select processes 4004 bic r14, 1, r14 // all processes 4005perfmon_sp: 4006//orig store_reg1 pmctr_ctl, r14, r12, ipr=1 // update pmctr_ctl register 4007 SAVE_SHADOW(r14,CNS_Q_PM_CTL,r12); // r12 still has the adjusted impure ptr 4008 br r31, perfmon_success 4009 4010// counter frequency select 4011perfmon_freq: 4012//orig get_pmctr_ctl r14, r12 // read shadow pmctr ctl; r12=adjusted impure pointer 4013 mfpr r12, pt_impure 4014 lda r12, CNS_Q_IPR(r12) 4015 RESTORE_SHADOW(r14,CNS_Q_PM_CTL,r12); 4016 4017 lda r8, 0x3F(r31) 4018//orig sll r8, pmctr_ctl_v_frq2, r8 // build mask for frequency select field 4019// I guess this should be a shift of 4 bits from the above control register structure 4020#define pmctr_ctl_v_frq2_SHIFT 4 4021 sll r8, pmctr_ctl_v_frq2_SHIFT, r8 // build mask for frequency select field 4022 4023 and r8, r17, r17 4024 bic r14, r8, r14 // clear out old frequency select bits 4025 4026 or r17, r14, r14 // or in new frequency select info 4027//orig store_reg1 pmctr_ctl, r14, r12, ipr=1 // update pmctr_ctl register 4028 SAVE_SHADOW(r14,CNS_Q_PM_CTL,r12); // r12 still has the adjusted impure ptr 4029 4030 br r31, perfmon_success 4031 4032// read counters 4033perfmon_rd: 4034 mfpr r0, ev5__pmctr 4035 or r0, 1, r0 // or in return status 4036 hw_rei // back to user 4037 4038// write counters 4039perfmon_wr: 4040 mfpr r14, ev5__pmctr 4041 lda r8, 0x3FFF(r31) // ctr2<13:0> mask 4042 sll r8, pmctr_v_ctr2, r8 4043 4044 LDLI(r9, (0xFFFFFFFF)) // ctr2<15:0>,ctr1<15:0> mask 4045 sll r9, pmctr_v_ctr1, r9 4046 or r8, r9, r8 // or ctr2, ctr1, ctr0 mask 4047 bic r14, r8, r14 // clear ctr fields 4048 and r17, r8, r25 // clear all but ctr fields 4049 or r25, r14, r14 // write ctr fields 4050 mtpr r14, ev5__pmctr // update pmctr ipr 4051 4052 mfpr r31, pt0 // pad pmctr write (needed only to keep PVC happy) 4053 4054perfmon_success: 4055 or r31, 1, r0 // set success 4056 hw_rei // back to user 4057 4058perfmon_unknown: 4059 or r31, r31, r0 // set fail 4060 hw_rei // back to user 4061 4062 4063////////////////////////////////////////////////////////// 4064// Copy code 4065////////////////////////////////////////////////////////// 4066 4067copypal_impl: 4068 mov r16, r0 4069#ifdef CACHE_COPY 4070#ifndef CACHE_COPY_UNALIGNED 4071 and r16, 63, r8 4072 and r17, 63, r9 4073 bis r8, r9, r8 4074 bne r8, cache_copy_done 4075#endif 4076 bic r18, 63, r8 4077 and r18, 63, r18 4078 beq r8, cache_copy_done 4079cache_loop: 4080 ldf f17, 0(r16) 4081 stf f17, 0(r16) 4082 addq r17, 64, r17 4083 addq r16, 64, r16 4084 subq r8, 64, r8 4085 bne r8, cache_loop 4086cache_copy_done: 4087#endif 4088 ble r18, finished // if len <=0 we are finished 4089 ldq_u r8, 0(r17) 4090 xor r17, r16, r9 4091 and r9, 7, r9 4092 and r16, 7, r10 4093 bne r9, unaligned 4094 beq r10, aligned 4095 ldq_u r9, 0(r16) 4096 addq r18, r10, r18 4097 mskqh r8, r17, r8 4098 mskql r9, r17, r9 4099 bis r8, r9, r8 4100aligned: 4101 subq r18, 1, r10 4102 bic r10, 7, r10 4103 and r18, 7, r18 4104 beq r10, aligned_done 4105loop: 4106 stq_u r8, 0(r16) 4107 ldq_u r8, 8(r17) 4108 subq r10, 8, r10 4109 lda r16,8(r16) 4110 lda r17,8(r17) 4111 bne r10, loop 4112aligned_done: 4113 bne r18, few_left 4114 stq_u r8, 0(r16) 4115 br r31, finished 4116 few_left: 4117 mskql r8, r18, r10 4118 ldq_u r9, 0(r16) 4119 mskqh r9, r18, r9 4120 bis r10, r9, r10 4121 stq_u r10, 0(r16) 4122 br r31, finished 4123unaligned: 4124 addq r17, r18, r25 4125 cmpule r18, 8, r9 4126 bne r9, unaligned_few_left 4127 beq r10, unaligned_dest_aligned 4128 and r16, 7, r10 4129 subq r31, r10, r10 4130 addq r10, 8, r10 4131 ldq_u r9, 7(r17) 4132 extql r8, r17, r8 4133 extqh r9, r17, r9 4134 bis r8, r9, r12 4135 insql r12, r16, r12 4136 ldq_u r13, 0(r16) 4137 mskql r13, r16, r13 4138 bis r12, r13, r12 4139 stq_u r12, 0(r16) 4140 addq r16, r10, r16 4141 addq r17, r10, r17 4142 subq r18, r10, r18 4143 ldq_u r8, 0(r17) 4144unaligned_dest_aligned: 4145 subq r18, 1, r10 4146 bic r10, 7, r10 4147 and r18, 7, r18 4148 beq r10, unaligned_partial_left 4149unaligned_loop: 4150 ldq_u r9, 7(r17) 4151 lda r17, 8(r17) 4152 extql r8, r17, r12 4153 extqh r9, r17, r13 4154 subq r10, 8, r10 4155 bis r12, r13, r13 4156 stq r13, 0(r16) 4157 lda r16, 8(r16) 4158 beq r10, unaligned_second_partial_left 4159 ldq_u r8, 7(r17) 4160 lda r17, 8(r17) 4161 extql r9, r17, r12 4162 extqh r8, r17, r13 4163 bis r12, r13, r13 4164 subq r10, 8, r10 4165 stq r13, 0(r16) 4166 lda r16, 8(r16) 4167 bne r10, unaligned_loop 4168unaligned_partial_left: 4169 mov r8, r9 4170unaligned_second_partial_left: 4171 ldq_u r8, -1(r25) 4172 extql r9, r17, r9 4173 extqh r8, r17, r8 4174 bis r8, r9, r8 4175 bne r18, few_left 4176 stq_u r8, 0(r16) 4177 br r31, finished 4178unaligned_few_left: 4179 ldq_u r9, -1(r25) 4180 extql r8, r17, r8 4181 extqh r9, r17, r9 4182 bis r8, r9, r8 4183 insqh r8, r16, r9 4184 insql r8, r16, r8 4185 lda r12, -1(r31) 4186 mskql r12, r18, r13 4187 cmovne r13, r13, r12 4188 insqh r12, r16, r13 4189 insql r12, r16, r12 4190 addq r16, r18, r10 4191 ldq_u r14, 0(r16) 4192 ldq_u r25, -1(r10) 4193 bic r14, r12, r14 4194 bic r25, r13, r25 4195 and r8, r12, r8 4196 and r9, r13, r9 4197 bis r8, r14, r8 4198 bis r9, r25, r9 4199 stq_u r9, -1(r10) 4200 stq_u r8, 0(r16) 4201finished: 4202 hw_rei 4203