summaryrefslogtreecommitdiffstats
path: root/private/ntos/mm/mips/debugsup.c
blob: eb9ee3be3ed7cd23cf44e40e557fa87d66ca901c (plain) (blame)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

   debugsup.c

Abstract:

    This module contains routines which provide support for the
    kernel debugger.

Author:

    Lou Perazzoli (loup) 02-Aug-90

Revision History:

--*/

#include "mi.h"

PVOID
MmDbgReadCheck (
    IN PVOID VirtualAddress
    )

/*++

Routine Description:

    MIPS implementation specific:

    This routine returns the virtual address which is valid (mapped)
    for read access.

    If the address is valid and readable and not within KSEG0 or KSEG1
    the physical address within KSEG0 is returned.  If the adddress
    is within KSEG0 or KSEG1 then the called address is returned.

Arguments:

    VirtualAddress - Supplies the virtual address to check.

Return Value:

    Returns NULL if the address is not valid or readable, otherwise
    returns the physical address of the corresponding virtual address.

Environment:

    Kernel mode IRQL at DISPATCH_LEVEL or greater.

--*/

{
    if ((VirtualAddress >= (PVOID)KSEG0_BASE) &&
        (VirtualAddress < (PVOID)KSEG2_BASE)) {
        return VirtualAddress;
    }

    if (!MmIsAddressValid (VirtualAddress)) {
        if (KiProbeEntryTb(VirtualAddress)) {
            return VirtualAddress;
        }
        return NULL;
    }

    return VirtualAddress;
}

PVOID
MmDbgWriteCheck (
    IN PVOID VirtualAddress
    )

/*++

Routine Description:

    MIPS implementation specific:

    This routine returns the phyiscal address for a virtual address
    which is valid (mapped) for write access.

    If the address is valid and writable and not within KSEG0 or KSEG1
    the physical address within KSEG0 is returned.  If the adddress
    is within KSEG0 or KSEG1 then the called address is returned.

    NOTE: The physical address is must only be used while the interrupt
    level on ALL processors is above DISPATCH_LEVEL, otherwise the
    binding between the virtual address and the physical address can
    change due to paging.

Arguments:

    VirtualAddress - Supplies the virtual address to check.

Return Value:

    Returns NULL if the address is not valid or readable, otherwise
    returns the physical address of the corresponding virtual address.

Environment:

    Kernel mode IRQL at DISPATCH_LEVEL or greater.

--*/

{
    PMMPTE PointerPte;

    if ((VirtualAddress >= (PVOID)KSEG0_BASE) &&
        (VirtualAddress < (PVOID)KSEG2_BASE)) {
        return VirtualAddress;
    }

    if (!MmIsAddressValid (VirtualAddress)) {

        //
        // need to check write
        //

        if (KiProbeEntryTb(VirtualAddress)) {
            return VirtualAddress;
        }
        return NULL;
    }

    PointerPte = MiGetPteAddress (VirtualAddress);

    if ((ULONG) VirtualAddress < KSEG0_BASE && PointerPte->u.Hard.Dirty == 0) {
        return NULL;
    }

    return VirtualAddress;
}


PVOID
MmDbgTranslatePhysicalAddress (
    IN PHYSICAL_ADDRESS PhysicalAddress
    )

/*++

Routine Description:

    MIPS implementation specific:

    This routine maps the specified physical address and returns
    the virtual address which maps the physical address.

    The next call to MmDbgTranslatePhyiscalAddress removes the
    previous phyiscal address translation, hence on a single
    physical address can be examined at a time (can't cross page
    boundaries).

Arguments:

    PhysicalAddress - Supplies the phyiscal address to map and translate.

Return Value:

    The virtual address which corresponds to the phyiscal address.

    NULL if the physical address was bogus.

Environment:

    Kernel mode IRQL at DISPATCH_LEVEL or greater.

--*/

{
    PVOID BaseAddress;
    PMMPTE BasePte;
    PMMPFN Pfn1;
    ULONG Page;

    BasePte = MmDebugPte + (MM_NUMBER_OF_COLORS - 1);
    BasePte = (PMMPTE)((ULONG)BasePte & ~(MM_COLOR_MASK << PTE_SHIFT));

    Page = (ULONG)(PhysicalAddress.QuadPart >> PAGE_SHIFT);

    if ((Page > (LONGLONG)MmHighestPhysicalPage) ||
        (Page < (LONGLONG)MmLowestPhysicalPage)) {
        return NULL;
    }

    Pfn1 = MI_PFN_ELEMENT (Page);

    if (!MmIsAddressValid (Pfn1)) {
        return NULL;
    }

    BasePte = BasePte + Pfn1->u3.e1.PageColor;

    BaseAddress = MiGetVirtualAddressMappedByPte (BasePte);

    KiFlushSingleTb (TRUE, BaseAddress);

    *BasePte = ValidKernelPte;
    BasePte->u.Hard.PageFrameNumber = Page;
    return (PVOID)((ULONG)BaseAddress + BYTE_OFFSET(PhysicalAddress.LowPart));
}