//++ // // Copyright (c) 1989 Microsoft Corporation // // Module Name: // // procstat.asm // // Abstract: // // This module implements procedures for saving and restoring // processor control state. // // These procedures support debugging of UP and MP systems. // // Author: // // Chuck Bauman (v-cbaum@microsoft.com) 7-Nov-1994 // // Environment: // // Kernel mode only. // // Revision History: // //-- #include "ksppc.h" // Supported PPC versions .set PV601, 1 .set PV603, 3 .set PV604, 4 .set PV603p, 6 .set PV603pp, 7 .set PV613, 8 .set PV604p, 9 // 601 special purpose register names .set hid1, 1009 // special purpose register names (601, 603 and 604) .set iabr, 1010 // special purpose register names (601, 604) .set dabr, 1013 .extern KiBreakPoints //++ // // KiSaveProcessorControlState( // PKPROCESSOR_STATE ProcessorState // ); // // Routine Description: // // This routine saves the control subset of the processor state. // Called by the debug subsystem, and KiSaveProcessorState() // // N.B. This procedure will save the debug registers and then turn off // the appropriate debug registers at the hardware. This prevents // recursive hardware trace breakpoints and allows debuggers // to work. // // Arguments: // // ProcessorState (r.3) // // Return Value: // // None. // //-- LEAF_ENTRY(KiSaveProcessorControlState) lwz r.5, [toc]KiBreakPoints(r.2) // Available Breakpoints Addr addi r.3, r.3, PsSpecialRegisters lwz r.5, 0(r.5) // # available breakpoints lwz r.7, SrKernelDr7(r.3) // Get Dr state lwz r.6, SrKernelDr6(r.3) rlwinm. r.7, r.7, 0, 0xff // KD set Drs? or r.5, r.5, r.6 // Return # DRs in Dr6 stw r.5, SrKernelDr6(r.3) // return allowed Drs beq getsregs // Leave if no DR set mfpvr r.4 li r.9, 0 // Initialize Dr7 li r.8, 0 // Turn off Drs rlwinm r.4, r.4, 16, 0xffff // isolate processor type cmpwi r.4, PV604 beq ss.604 // jif 604 cmpwi r.4, PV603p beq ss.603 // jif Stretch (603+) cmpwi r.4, PV604p beq ss.604 // jif Sirocco (604+) cmpwi r.4, PV603 beq ss.603 // jif 603 cmpwi r.4, PV603pp beq ss.603 // jif 603++ cmpwi r.4, PV613 beq ss.604 // jif 613 cmpwi r.4, PV601 li r.10, 0x0080 // Normal, run mode (601) beq ss.601 // jif 601 stw r.9, SrKernelDr7(r.3) // Drs not supported b getsregs // return // No DRs supported ss.601: // 601 SPECIFIC mtspr hid1, r.10 // turn off trace mode ss.604: // 601/604 SPECIFIC mfspr r.4, iabr // Load the IABR (Dr0) rlwinm. r.4, r.4, 0, 0xfffffffc // IABR(DR0) set? stw r.4, SrKernelDr0(r.3) mfspr r.4, dabr // Load the DABR (Dr1) beq ssnoiabr.1 // jiff Dr0 not set li r.9, 0x2 // Set GE0 in Dr7 ssnoiabr.1: rlwimi r.9, r.4, 19, 11, 11 // Interchange R/W1 bits rlwimi r.9, r.4, 21, 10, 10 // and move to Dr7 rlwinm. r.4, r.4, 0, 0xfffffff8 // Sanitize Dr1 stw r.4, SrKernelDr1(r.3) // Store Dr1 in trap frame beq ssnodabr.1 // jiff Dr1 not set ori r.9, r.9, 0x8 // Set GE1 in Dr7 ssnodabr.1: stw r.9, SrKernelDr7(r.3) // Initialize if no DRs set rlwinm. r.5, r.9, 0, 0xf // Any DRs set? mtspr dabr, r.8 mtspr iabr, r.8 // Turn off DRs isync ori r.9, r.9, 0x200 // Set GE bit in Dr7 beq getsregs // exit if not set stw r.9, SrKernelDr7(r.3) b getsregs ss.603: // 603 SPECIFIC mfspr r.4, iabr // Load the IABR (Dr0) rlwinm. r.4, r.4, 0, 0xfffffffc // Sanitize Dr0 beq ssnoiabr.3 // jiff Dr0 not set li r.9, 0x202 // Initialize Dr7 ssnoiabr.3: stw r.4, SrKernelDr0(r.3) // Store Dr0 stw r.9, SrKernelDr7(r.3) mtspr iabr, r.8 // Turn off DRs getsregs: mfsr r.4, 0 mfsr r.5, 1 mfsr r.6, 2 mfsr r.7, 3 stw r.4, SrSr0(r.3) mfsr r.4, 4 stw r.5, SrSr1(r.3) mfsr r.5, 5 stw r.6, SrSr2(r.3) mfsr r.6, 6 stw r.7, SrSr3(r.3) mfsr r.7, 7 stw r.4, SrSr4(r.3) mfsr r.4, 8 stw r.5, SrSr5(r.3) mfsr r.5, 9 stw r.6, SrSr6(r.3) mfsr r.6, 10 stw r.7, SrSr7(r.3) mfsr r.7, 11 stw r.4, SrSr8(r.3) mfsr r.4, 12 stw r.5, SrSr9(r.3) mfsr r.5, 13 stw r.6, SrSr10(r.3) mfsr r.6, 14 stw r.7, SrSr11(r.3) mfsr r.7, 15 stw r.4, SrSr12(r.3) stw r.5, SrSr13(r.3) stw r.6, SrSr14(r.3) stw r.7, SrSr15(r.3) mfsdr1 r.0 stw r.0, SrSdr1(r.3) mfibatl r.4, 0 mfibatu r.5, 0 mfibatl r.6, 1 mfibatu r.7, 1 stw r.4, SrIBAT0L(r.3) mfibatl r.4, 2 stw r.5, SrIBAT0U(r.3) mfibatu r.5, 2 stw r.6, SrIBAT1L(r.3) mfibatl r.6, 3 stw r.7, SrIBAT1U(r.3) mfibatu r.7, 3 stw r.4, SrIBAT2L(r.3) stw r.5, SrIBAT2U(r.3) stw r.6, SrIBAT3L(r.3) stw r.7, SrIBAT3U(r.3) mfpvr r.4 cmpwi r.4, PV601 beqlr // exit if 601 (no DBATs) mfdbatl r.4, 0 mfdbatu r.5, 0 mfdbatl r.6, 1 mfdbatu r.7, 1 stw r.4, SrDBAT0L(r.3) mfdbatl r.4, 2 stw r.5, SrDBAT0U(r.3) mfdbatu r.5, 2 stw r.6, SrDBAT1L(r.3) mfdbatl r.6, 3 stw r.7, SrDBAT1U(r.3) mfdbatu r.7, 3 stw r.4, SrDBAT2L(r.3) stw r.5, SrDBAT2U(r.3) stw r.6, SrDBAT3L(r.3) stw r.7, SrDBAT3U(r.3) LEAF_EXIT(KiSaveProcessorControlState) //++ // // KiRestoreProcessorControlState( // ); // // Routine Description: // // This routine restores the control subset of the processor state. // (Restores the same information as KiRestoreProcessorState EXCEPT that // data in TrapFrame/ExceptionFrame=Context record is NOT restored.) // Called by the debug subsystem, and KiRestoreProcessorState() // // Arguments: // // Return Value: // // None. // //-- LEAF_ENTRY(KiRestoreProcessorControlState) addi r.3, r.3, PsSpecialRegisters lwz r.4, SrKernelDr7(r.3) // Active DRs mfpvr r.7 rlwinm. r.6, r.4, 0, 0xff // Drs Set? bne DRon // jif DRs active blr // exit No DRs set DRon: rlwinm r.7, r.7, 16, 0xffff // isolate processor type lwz r.5, SrKernelDr1 (r.3) // Get kernel DABR (Dr1) lwz r.6, SrKernelDr0 (r.3) // Get kernel IABR (Dr0) ori r.5, r.5, 0x4 // Sanitize DABR (Dr1) 604 ori r.6, r.6, 0x3 // Sanitize IABR (Dr0) 604 cmpwi r.7, PV604 beq rs.604 // jif 604 cmpwi r.7, PV603p beq rs.603 // jif 603+ cmpwi r.7, PV604p beq rs.604 // jif 604+ cmpwi r.7, PV603 beq rs.603 // jif 603 cmpwi r.7, PV603pp beq rs.603 // jif 603++ cmpwi r.7, PV613 beq rs.604 // jif 613 cmpwi r.7, PV601 lis r.10, 0x6080 // Full cmp. trace mode (601) beq rs.601 // jif 601 blr // return // No DRs supported rs.601: // 601 SPECIFIC rlwinm r.6, r.6, 0, 0xfffffffc // Sanitze IABR (Dr0) undo 604 rlwinm r.5, r.5, 0, 0xfffffff8 // Sanitze DABR (Dr0) undo 604 mtspr hid1, r.10 // turn on full cmp rs.604: rlwinm. r.9, r.4, 0, 0x0000000c // LE1/GE1 set? beq rsnodabr.1 // jiff Dr1 not set rlwimi r.5, r.4, 13, 30, 30 // Interchange R/W1 bits rlwimi r.5, r.4, 11, 31, 31 mtspr dabr, r.5 rsnodabr.1: rlwinm. r.4, r.4, 0, 0x00000003 // LE0/GE0 set? beqlr mtspr iabr, r.6 isync blr rs.603: // 603 SPECIFIC rlwinm r.6, r.6, 0, 0xfffffffc // Sanitize IABR ori r.6, r.6, 0x2 mtspr iabr, r.6 LEAF_EXIT(KiRestoreProcessorControlState)