summaryrefslogtreecommitdiffstats
path: root/src/VBox/VMM/include/DBGFInline.h
blob: 0737c6811fef97976e61208bf8c94e6779424f40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* $Id: DBGFInline.h $ */
/** @file
 * DBGF - Internal header file containing the inlined functions.
 */

/*
 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * SPDX-License-Identifier: GPL-3.0-only
 */

#ifndef VMM_INCLUDED_SRC_include_DBGFInline_h
#define VMM_INCLUDED_SRC_include_DBGFInline_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif


/**
 * Initializes the given L2 table entry with the given values.
 *
 * @param   pL2Entry            The L2 entry to intialize.
 * @param   hBp                 The breakpoint handle.
 * @param   GCPtr               The GC pointer used as the key (only the upper 6 bytes are used).
 * @param   idxL2Left           The left L2 table index.
 * @param   idxL2Right          The right L2 table index.
 * @param   iDepth              The depth of the node in the tree.
 */
DECLINLINE(void) dbgfBpL2TblEntryInit(PDBGFBPL2ENTRY pL2Entry, DBGFBP hBp, RTGCPTR GCPtr,
                                      uint32_t idxL2Left, uint32_t idxL2Right, uint8_t iDepth)
{
    uint64_t u64GCPtrKeyAndBpHnd1 =   ((uint64_t)hBp & DBGF_BP_L2_ENTRY_BP_1ST_MASK) << DBGF_BP_L2_ENTRY_BP_1ST_SHIFT
                                    | DBGF_BP_INT3_L2_KEY_EXTRACT_FROM_ADDR(GCPtr);
    uint64_t u64LeftRightIdxDepthBpHnd2 =   (((uint64_t)hBp & DBGF_BP_L2_ENTRY_BP_2ND_MASK) >> 16) << DBGF_BP_L2_ENTRY_BP_2ND_SHIFT
                                          | ((uint64_t)iDepth << DBGF_BP_L2_ENTRY_DEPTH_SHIFT)
                                          | ((uint64_t)idxL2Right << DBGF_BP_L2_ENTRY_RIGHT_IDX_SHIFT)
                                          | ((uint64_t)idxL2Left << DBGF_BP_L2_ENTRY_LEFT_IDX_SHIFT);

    ASMAtomicWriteU64(&pL2Entry->u64GCPtrKeyAndBpHnd1, u64GCPtrKeyAndBpHnd1);
    ASMAtomicWriteU64(&pL2Entry->u64LeftRightIdxDepthBpHnd2, u64LeftRightIdxDepthBpHnd2);
}


/**
 * Updates the given L2 table entry with the new pointers.
 *
 * @param   pL2Entry            The L2 entry to update.
 * @param   idxL2Left           The new left L2 table index.
 * @param   idxL2Right          The new right L2 table index.
 * @param   iDepth              The new depth of the tree.
 */
DECLINLINE(void) dbgfBpL2TblEntryUpdate(PDBGFBPL2ENTRY pL2Entry, uint32_t idxL2Left, uint32_t idxL2Right,
                                        uint8_t iDepth)
{
    uint64_t u64LeftRightIdxDepthBpHnd2 = ASMAtomicReadU64(&pL2Entry->u64LeftRightIdxDepthBpHnd2) & DBGF_BP_L2_ENTRY_BP_2ND_L2_ENTRY_MASK;
    u64LeftRightIdxDepthBpHnd2 |=   ((uint64_t)iDepth << DBGF_BP_L2_ENTRY_DEPTH_SHIFT)
                                  | ((uint64_t)idxL2Right << DBGF_BP_L2_ENTRY_RIGHT_IDX_SHIFT)
                                  | ((uint64_t)idxL2Left << DBGF_BP_L2_ENTRY_LEFT_IDX_SHIFT);

    ASMAtomicWriteU64(&pL2Entry->u64LeftRightIdxDepthBpHnd2, u64LeftRightIdxDepthBpHnd2);
}


/**
 * Updates the given L2 table entry with the left pointer.
 *
 * @param   pL2Entry            The L2 entry to update.
 * @param   idxL2Left           The new left L2 table index.
 * @param   iDepth              The new depth of the tree.
 */
DECLINLINE(void) dbgfBpL2TblEntryUpdateLeft(PDBGFBPL2ENTRY pL2Entry, uint32_t idxL2Left, uint8_t iDepth)
{
    uint64_t u64LeftRightIdxDepthBpHnd2 = ASMAtomicReadU64(&pL2Entry->u64LeftRightIdxDepthBpHnd2) & (  DBGF_BP_L2_ENTRY_BP_2ND_L2_ENTRY_MASK
                                                                                                     | DBGF_BP_L2_ENTRY_RIGHT_IDX_MASK);

    u64LeftRightIdxDepthBpHnd2 |=   ((uint64_t)iDepth << DBGF_BP_L2_ENTRY_DEPTH_SHIFT)
                                  | ((uint64_t)idxL2Left << DBGF_BP_L2_ENTRY_LEFT_IDX_SHIFT);

    ASMAtomicWriteU64(&pL2Entry->u64LeftRightIdxDepthBpHnd2, u64LeftRightIdxDepthBpHnd2);
}


/**
 * Updates the given L2 table entry with the right pointer.
 *
 * @param   pL2Entry            The L2 entry to update.
 * @param   idxL2Right          The new right L2 table index.
 * @param   iDepth              The new depth of the tree.
 */
DECLINLINE(void) dbgfBpL2TblEntryUpdateRight(PDBGFBPL2ENTRY pL2Entry, uint32_t idxL2Right, uint8_t iDepth)
{
    uint64_t u64LeftRightIdxDepthBpHnd2 = ASMAtomicReadU64(&pL2Entry->u64LeftRightIdxDepthBpHnd2) & (  DBGF_BP_L2_ENTRY_BP_2ND_L2_ENTRY_MASK
                                                                                                     | DBGF_BP_L2_ENTRY_LEFT_IDX_MASK);

    u64LeftRightIdxDepthBpHnd2 |=   ((uint64_t)iDepth << DBGF_BP_L2_ENTRY_DEPTH_SHIFT)
                                  | ((uint64_t)idxL2Right << DBGF_BP_L2_ENTRY_RIGHT_IDX_SHIFT);

    ASMAtomicWriteU64(&pL2Entry->u64LeftRightIdxDepthBpHnd2, u64LeftRightIdxDepthBpHnd2);
}

#ifdef IN_RING3
/**
 * Returns the internal breakpoint owner state for the given handle.
 *
 * @returns Pointer to the internal breakpoint owner state or NULL if the handle is invalid.
 * @param   pUVM                The user mode VM handle.
 * @param   hBpOwner            The breakpoint owner handle to resolve.
 */
DECLINLINE(PDBGFBPOWNERINT) dbgfR3BpOwnerGetByHnd(PUVM pUVM, DBGFBPOWNER hBpOwner)
{
    AssertReturn(hBpOwner < DBGF_BP_OWNER_COUNT_MAX, NULL);
    AssertPtrReturn(pUVM->dbgf.s.pbmBpOwnersAllocR3, NULL);

    AssertReturn(ASMBitTest(pUVM->dbgf.s.pbmBpOwnersAllocR3, hBpOwner), NULL);
    return &pUVM->dbgf.s.paBpOwnersR3[hBpOwner];
}
#endif

#endif /* !VMM_INCLUDED_SRC_include_DBGFInline_h */