Changeset 58903 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Nov 27, 2015 3:07:07 PM (9 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/DBGFAll.cpp
r58123 r58903 69 69 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[0]; 70 70 Assert(pBp->u.Reg.iReg == 0); 71 return pBp-> GCPtr;71 return pBp->u.Reg.GCPtr; 72 72 } 73 73 … … 83 83 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[1]; 84 84 Assert(pBp->u.Reg.iReg == 1); 85 return pBp-> GCPtr;85 return pBp->u.Reg.GCPtr; 86 86 } 87 87 … … 97 97 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[2]; 98 98 Assert(pBp->u.Reg.iReg == 2); 99 return pBp-> GCPtr;99 return pBp->u.Reg.GCPtr; 100 100 } 101 101 … … 111 111 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[3]; 112 112 Assert(pBp->u.Reg.iReg == 3); 113 return pBp-> GCPtr;113 return pBp->u.Reg.GCPtr; 114 114 } 115 115 … … 192 192 { 193 193 uint8_t cbReg = pVM->dbgf.s.aHwBreakpoints[iBp].u.Reg.cb; Assert(RT_IS_POWER_OF_TWO(cbReg)); 194 uint64_t uDrXFirst = pVM->dbgf.s.aHwBreakpoints[iBp]. GCPtr & ~(uint64_t)(cbReg - 1);194 uint64_t uDrXFirst = pVM->dbgf.s.aHwBreakpoints[iBp].u.Reg.GCPtr & ~(uint64_t)(cbReg - 1); 195 195 uint64_t uDrXLast = uDrXFirst + cbReg - 1; 196 196 if (uDrXFirst <= uIoPortLast && uDrXLast >= uIoPortFirst) -
trunk/src/VBox/VMM/VMMR3/DBGF.cpp
r58170 r58903 668 668 for (size_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); i++) 669 669 if ( pVM->dbgf.s.aBreakpoints[i].enmType == DBGFBPTYPE_REM 670 && pVM->dbgf.s.aBreakpoints[i]. GCPtr == eip)670 && pVM->dbgf.s.aBreakpoints[i].u.Rem.GCPtr == eip) 671 671 { 672 672 pVM->dbgf.s.DbgEvent.u.Bp.iBp = pVM->dbgf.s.aBreakpoints[i].iBp; -
trunk/src/VBox/VMM/VMMR3/DBGFBp.cpp
r58126 r58903 29 29 #endif 30 30 #include <VBox/vmm/mm.h> 31 #include <VBox/vmm/iom.h> 32 #include <VBox/vmm/hm.h> 31 33 #include "DBGFInternal.h" 32 34 #include <VBox/vmm/vm.h> … … 223 225 */ 224 226 for (unsigned iBp = 0; iBp < cBps; iBp++) 225 { 226 if ( paBps[iBp].enmType == enmType 227 && paBps[iBp].GCPtr == GCPtr) 227 if ( paBps[iBp].enmType == enmType 228 && paBps[iBp].u.GCPtr == GCPtr) 228 229 return &paBps[iBp]; 229 }230 230 231 231 return NULL; … … 320 320 if (!pBp) 321 321 return VERR_DBGF_NO_MORE_BP_SLOTS; 322 pBp->GCPtr = pAddress->FlatPtr; 323 pBp->iHitTrigger = *piHitTrigger; 324 pBp->iHitDisable = *piHitDisable; 325 pBp->fEnabled = true; 322 pBp->u.Int3.GCPtr = pAddress->FlatPtr; 323 pBp->iHitTrigger = *piHitTrigger; 324 pBp->iHitDisable = *piHitDisable; 325 ASMCompilerBarrier(); 326 pBp->fEnabled = true; 326 327 327 328 /* … … 386 387 */ 387 388 DBGFADDRESS Addr; 388 DBGFR3AddrFromFlat(pUVM, &Addr, pBp-> GCPtr);389 DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr); 389 390 int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1); 390 391 if (RT_SUCCESS(rc)) … … 415 416 */ 416 417 DBGFADDRESS Addr; 417 DBGFR3AddrFromFlat(pUVM, &Addr, pBp-> GCPtr);418 DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr); 418 419 uint8_t bCurrent; 419 420 int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &bCurrent, 1); … … 508 509 if (!pBp) 509 510 return VERR_DBGF_NO_MORE_BP_SLOTS; 510 pBp->GCPtr = pAddress->FlatPtr;511 511 pBp->iHitTrigger = *piHitTrigger; 512 512 pBp->iHitDisable = *piHitDisable; 513 pBp->fEnabled = true;514 513 Assert(pBp->iBp == pBp->u.Reg.iReg); 514 pBp->u.Reg.GCPtr = pAddress->FlatPtr; 515 515 pBp->u.Reg.fType = fType; 516 516 pBp->u.Reg.cb = cb; 517 ASMCompilerBarrier(); 518 pBp->fEnabled = true; 517 519 518 520 /* … … 642 644 if (!pBp->fEnabled) 643 645 #ifdef VBOX_WITH_REM 644 rc = REMR3BreakpointSet(pVM, pBp-> GCPtr);646 rc = REMR3BreakpointSet(pVM, pBp->u.Rem.GCPtr); 645 647 #else 646 rc = IEMBreakpointSet(pVM, pBp-> GCPtr);648 rc = IEMBreakpointSet(pVM, pBp->u.Rem.GCPtr); 647 649 #endif 648 650 if (RT_SUCCESS(rc)) … … 661 663 if (!pBp) 662 664 return VERR_DBGF_NO_MORE_BP_SLOTS; 663 pBp-> GCPtr= pAddress->FlatPtr;665 pBp->u.Rem.GCPtr = pAddress->FlatPtr; 664 666 pBp->iHitTrigger = *piHitTrigger; 665 667 pBp->iHitDisable = *piHitDisable; 668 ASMCompilerBarrier(); 666 669 pBp->fEnabled = true; 667 670 … … 711 714 712 715 716 717 /** 718 * Updates IOM on whether we've got any armed I/O port or MMIO breakpoints. 719 * 720 * @returns VINF_SUCCESS 721 * @param pVM The cross context VM structure. 722 */ 723 static int dbgfR3BpUpdateIom(PVM pVM) 724 { 725 unsigned cPortIo = 0; 726 unsigned cMmio = 0; 727 for (uint32_t iBp = 0; iBp < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); iBp++) 728 if (pVM->dbgf.s.aBreakpoints[iBp].fEnabled) 729 { 730 if (pVM->dbgf.s.aBreakpoints[iBp].enmType == DBGFBPTYPE_PORT_IO) 731 cPortIo++; 732 else if (pVM->dbgf.s.aBreakpoints[iBp].enmType == DBGFBPTYPE_MMIO) 733 cMmio++; 734 } 735 736 pVM->dbgf.s.fHasPortIoBps = cPortIo != 0; 737 pVM->dbgf.s.fHasMmioBps = cMmio != 0; 738 739 IOMR3NotifyBreakpointCountChange(pVM, cPortIo, cMmio); 740 return VINF_SUCCESS; 741 } 742 743 744 /** 745 * EMT worker for DBGFR3BpSetPortIo. 746 * 747 * @returns VBox status code. 748 * @param pUVM The user mode VM handle. 749 * @param uPort The first I/O port. 750 * @param cPorts The number of I/O ports. 751 * @param fAccess The access we want to break on. 752 * @param piHitTrigger The hit count at which the breakpoint start triggering. 753 * Use 0 (or 1) if it's gonna trigger at once. 754 * @param piHitDisable The hit count which disables the breakpoint. 755 * Use ~(uint64_t) if it's never gonna be disabled. 756 * @param piBp Where to store the breakpoint ID. 757 */ 758 static DECLCALLBACK(int) dbgfR3BpSetPortIo(PUVM pUVM, RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess, 759 uint64_t const *piHitTrigger, uint64_t const *piHitDisable, uint32_t *piBp) 760 { 761 /* 762 * Validate input. 763 */ 764 PVM pVM = pUVM->pVM; 765 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 766 *piBp = ~0; 767 768 /* 769 * Check if the breakpoint already exists. 770 */ 771 for (uint32_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); i++) 772 if ( pVM->dbgf.s.aBreakpoints[i].enmType == DBGFBPTYPE_PORT_IO 773 && pVM->dbgf.s.aBreakpoints[i].u.PortIo.uPort == uPort 774 && pVM->dbgf.s.aBreakpoints[i].u.PortIo.cPorts == cPorts 775 && pVM->dbgf.s.aBreakpoints[i].u.PortIo.fAccess == fAccess) 776 { 777 if (!pVM->dbgf.s.aBreakpoints[i].fEnabled) 778 { 779 pVM->dbgf.s.aBreakpoints[i].fEnabled = true; 780 dbgfR3BpUpdateIom(pVM); 781 } 782 *piBp = pVM->dbgf.s.aBreakpoints[i].iBp; 783 return VINF_DBGF_BP_ALREADY_EXIST; 784 } 785 786 /* 787 * Allocate and initialize the breakpoint. 788 */ 789 PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_PORT_IO); 790 if (!pBp) 791 return VERR_DBGF_NO_MORE_BP_SLOTS; 792 pBp->iHitTrigger = *piHitTrigger; 793 pBp->iHitDisable = *piHitDisable; 794 pBp->u.PortIo.uPort = uPort; 795 pBp->u.PortIo.cPorts = cPorts; 796 pBp->u.PortIo.fAccess = fAccess; 797 ASMCompilerBarrier(); 798 pBp->fEnabled = true; 799 800 /* 801 * Tell IOM. 802 */ 803 dbgfR3BpUpdateIom(pVM); 804 *piBp = pBp->iBp; 805 return VINF_SUCCESS; 806 } 807 808 809 /** 810 * Sets an I/O port breakpoint. 811 * 812 * @returns VBox status code. 813 * @param pUvm The user mode VM handle. 814 * @param uPort The first I/O port. 815 * @param cPorts The number of I/O ports, see DBGFBPIOACCESS_XXX. 816 * @param fAccess The access we want to break on. 817 * @param iHitTrigger The hit count at which the breakpoint start 818 * triggering. Use 0 (or 1) if it's gonna trigger at 819 * once. 820 * @param iHitDisable The hit count which disables the breakpoint. 821 * Use ~(uint64_t) if it's never gonna be disabled. 822 * @param piBp Where to store the breakpoint ID. Optional. 823 */ 824 VMMR3DECL(int) DBGFR3BpSetPortIo(PUVM pUVM, RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess, 825 uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp) 826 { 827 AssertReturn(!(fAccess & ~DBGFBPIOACCESS_VALID_MASK_PORT_IO), VERR_INVALID_FLAGS); 828 AssertReturn(fAccess, VERR_INVALID_FLAGS); 829 if (iHitTrigger > iHitDisable) 830 return VERR_INVALID_PARAMETER; 831 AssertPtrNullReturn(piBp, VERR_INVALID_POINTER); 832 AssertReturn(cPorts > 0, VERR_OUT_OF_RANGE); 833 AssertReturn((RTIOPORT)(uPort + cPorts) < uPort, VERR_OUT_OF_RANGE); 834 835 /* 836 * This must be done on EMT. 837 */ 838 uint32_t iBp = -1; 839 int rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)dbgfR3BpSetPortIo, 7, 840 pUVM, uPort, cPorts, fAccess, &iHitTrigger, &iHitDisable, piBp); 841 if (piBp) 842 *piBp = iBp; 843 LogFlow(("DBGFR3BpSetPortIo: returns %Rrc *piBp=%d\n", rc, iBp)); 844 return rc; 845 } 846 847 848 /** 849 * EMT worker for DBGFR3BpSetMmio. 850 * 851 * @returns VBox status code. 852 * @param pUVM The user mode VM handle. 853 * @param pGCPhys The start of the MMIO range to break on. 854 * @param cb The the size of the MMIO range. 855 * @param fAccess The access we want to break on. 856 * @param piHitTrigger The hit count at which the breakpoint start triggering. 857 * Use 0 (or 1) if it's gonna trigger at once. 858 * @param piHitDisable The hit count which disables the breakpoint. 859 * Use ~(uint64_t) if it's never gonna be disabled. 860 * @param piBp Where to store the breakpoint ID. 861 */ 862 static DECLCALLBACK(int) dbgfR3BpSetMmio(PUVM pUVM, PCRTGCPHYS pGCPhys, uint32_t cb, uint32_t fAccess, 863 uint64_t const *piHitTrigger, uint64_t const *piHitDisable, uint32_t *piBp) 864 { 865 RTGCPHYS const GCPhys = *pGCPhys; 866 867 /* 868 * Validate input. 869 */ 870 PVM pVM = pUVM->pVM; 871 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 872 *piBp = ~0; 873 874 /* 875 * Check if the breakpoint already exists. 876 */ 877 for (uint32_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); i++) 878 if ( pVM->dbgf.s.aBreakpoints[i].enmType == DBGFBPTYPE_MMIO 879 && pVM->dbgf.s.aBreakpoints[i].u.Mmio.PhysAddr == GCPhys 880 && pVM->dbgf.s.aBreakpoints[i].u.Mmio.cb == cb 881 && pVM->dbgf.s.aBreakpoints[i].u.Mmio.fAccess == fAccess) 882 { 883 if (!pVM->dbgf.s.aBreakpoints[i].fEnabled) 884 { 885 pVM->dbgf.s.aBreakpoints[i].fEnabled = true; 886 dbgfR3BpUpdateIom(pVM); 887 } 888 *piBp = pVM->dbgf.s.aBreakpoints[i].iBp; 889 return VINF_DBGF_BP_ALREADY_EXIST; 890 } 891 892 /* 893 * Allocate and initialize the breakpoint. 894 */ 895 PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_PORT_IO); 896 if (!pBp) 897 return VERR_DBGF_NO_MORE_BP_SLOTS; 898 pBp->iHitTrigger = *piHitTrigger; 899 pBp->iHitDisable = *piHitDisable; 900 pBp->u.Mmio.PhysAddr = GCPhys; 901 pBp->u.Mmio.cb = cb; 902 pBp->u.Mmio.fAccess = fAccess; 903 ASMCompilerBarrier(); 904 pBp->fEnabled = true; 905 906 /* 907 * Tell IOM. 908 */ 909 dbgfR3BpUpdateIom(pVM); 910 *piBp = pBp->iBp; 911 return VINF_SUCCESS; 912 } 913 914 915 /** 916 * Sets a memory mapped I/O breakpoint. 917 * 918 * @returns VBox status code. 919 * @param pUvm The user mode VM handle. 920 * @param GCPhys The first MMIO address. 921 * @param cb The size of the MMIO range to break on. 922 * @param fAccess The access we want to break on. 923 * @param iHitTrigger The hit count at which the breakpoint start 924 * triggering. Use 0 (or 1) if it's gonna trigger at 925 * once. 926 * @param iHitDisable The hit count which disables the breakpoint. 927 * Use ~(uint64_t) if it's never gonna be disabled. 928 * @param piBp Where to store the breakpoint ID. Optional. 929 */ 930 VMMR3DECL(int) DBGFR3BpSetMmio(PUVM pUVM, RTGCPHYS GCPhys, uint32_t cb, uint32_t fAccess, 931 uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp) 932 { 933 AssertReturn(!(fAccess & ~DBGFBPIOACCESS_VALID_MASK_MMIO), VERR_INVALID_FLAGS); 934 AssertReturn(fAccess, VERR_INVALID_FLAGS); 935 if (iHitTrigger > iHitDisable) 936 return VERR_INVALID_PARAMETER; 937 AssertPtrNullReturn(piBp, VERR_INVALID_POINTER); 938 AssertReturn(cb, VERR_OUT_OF_RANGE); 939 AssertReturn(GCPhys + cb < GCPhys, VERR_OUT_OF_RANGE); 940 941 /* 942 * This must be done on EMT. 943 */ 944 uint32_t iBp = -1; 945 int rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)dbgfR3BpSetMmio, 7, 946 pUVM, &GCPhys, cb, fAccess, &iHitTrigger, &iHitDisable, piBp); 947 if (piBp) 948 *piBp = iBp; 949 LogFlow(("DBGFR3BpSetMmio: returns %Rrc *piBp=%d\n", rc, iBp)); 950 return rc; 951 } 952 953 713 954 /** 714 955 * EMT worker for DBGFR3BpClear(). … … 750 991 case DBGFBPTYPE_REM: 751 992 #ifdef VBOX_WITH_REM 752 rc = REMR3BreakpointClear(pVM, pBp-> GCPtr);993 rc = REMR3BreakpointClear(pVM, pBp->u.Rem.GCPtr); 753 994 #else 754 rc = IEMBreakpointClear(pVM, pBp-> GCPtr);995 rc = IEMBreakpointClear(pVM, pBp->u.Rem.GCPtr); 755 996 #endif 997 break; 998 999 case DBGFBPTYPE_PORT_IO: 1000 case DBGFBPTYPE_MMIO: 1001 rc = dbgfR3BpUpdateIom(pVM); 756 1002 break; 757 1003 … … 832 1078 case DBGFBPTYPE_REM: 833 1079 #ifdef VBOX_WITH_REM 834 rc = REMR3BreakpointSet(pVM, pBp-> GCPtr);1080 rc = REMR3BreakpointSet(pVM, pBp->u.Rem.GCPtr); 835 1081 #else 836 rc = IEMBreakpointSet(pVM, pBp-> GCPtr);1082 rc = IEMBreakpointSet(pVM, pBp->u.Rem.GCPtr); 837 1083 #endif 1084 break; 1085 1086 case DBGFBPTYPE_PORT_IO: 1087 case DBGFBPTYPE_MMIO: 1088 rc = dbgfR3BpUpdateIom(pVM); 838 1089 break; 839 1090 … … 910 1161 case DBGFBPTYPE_REM: 911 1162 #ifdef VBOX_WITH_REM 912 rc = REMR3BreakpointClear(pVM, pBp-> GCPtr);1163 rc = REMR3BreakpointClear(pVM, pBp->u.Rem.GCPtr); 913 1164 #else 914 rc = IEMBreakpointClear(pVM, pBp-> GCPtr);1165 rc = IEMBreakpointClear(pVM, pBp->u.Rem.GCPtr); 915 1166 #endif 1167 break; 1168 1169 case DBGFBPTYPE_PORT_IO: 1170 case DBGFBPTYPE_MMIO: 1171 rc = dbgfR3BpUpdateIom(pVM); 916 1172 break; 917 1173 -
trunk/src/VBox/VMM/VMMR3/IOM.cpp
r58126 r58903 1646 1646 1647 1647 /** 1648 * Notification from DBGF that the number of active I/O port or MMIO 1649 * breakpoints has change. 1650 * 1651 * For performance reasons, IOM will only call DBGF before doing I/O and MMIO 1652 * accesses where there are armed breakpoints. 1653 * 1654 * @param pVM The cross context VM structure. 1655 * @param cPortIo Number of armed I/O port breakpoints. 1656 * @param cMmio Number of armed MMIO breakpoints. 1657 */ 1658 VMMR3_INT_DECL(void) IOMR3NotifyBreakpointCountChange(PVM pVM, unsigned cPortIo, unsigned cMmio) 1659 { 1660 /** @todo I/O breakpoints. */ 1661 } 1662 1663 1664 /** 1665 * Notification from DBGF that an event has been enabled or disabled. 1666 * 1667 * For performance reasons, IOM may cache the state of events it implements. 1668 * 1669 * @param pVM The cross context VM structure. 1670 * @param enmEvent The event. 1671 * @param fEnabled The new state. 1672 */ 1673 VMMR3_INT_DECL(void) IOMR3NotifyDebugEventChange(PVM pVM, DBGFEVENT enmEvent, bool fEnabled) 1674 { 1675 /** @todo IOM debug events. */ 1676 } 1677 1678 1679 /** 1648 1680 * Display a single MMIO range. 1649 1681 * -
trunk/src/VBox/VMM/VMMRZ/DBGFRZ.cpp
r58123 r58903 139 139 for (unsigned iBp = 0; iBp < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); iBp++) 140 140 { 141 if ( pVM->dbgf.s.aBreakpoints[iBp]. GCPtr == (RTGCUINTPTR)pPc141 if ( pVM->dbgf.s.aBreakpoints[iBp].u.GCPtr == (RTGCUINTPTR)pPc 142 142 && pVM->dbgf.s.aBreakpoints[iBp].enmType == DBGFBPTYPE_INT3) 143 143 { -
trunk/src/VBox/VMM/include/DBGFInternal.h
r56287 r58903 50 50 /** Single step execution - stepping into calls. */ 51 51 DBGFCMD_SINGLE_STEP, 52 /** Set a breakpoint. */53 DBGFCMD_BREAKPOINT_SET,54 /** Set a access breakpoint. */55 DBGFCMD_BREAKPOINT_SET_ACCESS,56 /** Set a REM breakpoint. */57 DBGFCMD_BREAKPOINT_SET_REM,58 /** Clear a breakpoint. */59 DBGFCMD_BREAKPOINT_CLEAR,60 /** Enable a breakpoint. */61 DBGFCMD_BREAKPOINT_ENABLE,62 /** Disable a breakpoint. */63 DBGFCMD_BREAKPOINT_DISABLE,64 /** List breakpoints. */65 DBGFCMD_BREAKPOINT_LIST,66 67 52 /** Detaches the debugger. 68 53 * Disabling all breakpoints, watch points and the like. */ 69 DBGFCMD_DETACH_DEBUGGER = 0x7ffffffe,54 DBGFCMD_DETACH_DEBUGGER, 70 55 /** Detached the debugger. 71 56 * The isn't a command as such, it's just that it's necessary for the 72 57 * detaching protocol to be racefree. */ 73 DBGFCMD_DETACHED_DEBUGGER = 0x7fffffff58 DBGFCMD_DETACHED_DEBUGGER 74 59 } DBGFCMD; 75 60 … … 202 187 int32_t offVM; 203 188 189 /** Set if we've got armed port I/O breakpoints. */ 190 bool fHasPortIoBps : 1; 191 /** Set if we've got armed memory mapped I/O breakpoints. */ 192 bool fHasMmioBps : 1; 193 204 194 /** Debugger Attached flag. 205 195 * Set if a debugger is attached, elsewise it's clear. … … 247 237 * @remark This is currently a fixed size array for reasons of simplicity. */ 248 238 DBGFBP aBreakpoints[32]; 239 249 240 } DBGF; 250 241 /** Pointer to DBGF Data. */
Note:
See TracChangeset
for help on using the changeset viewer.