test: debugsup.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# debugsup.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1989  Microsoft Corporation
    00004 Copyright (c) 1992  Digital Equipment Corporation
    00005
    00006 Module Name:
    00007
    00008    debugsup.c
    00009
    00010 Abstract:
    00011
    00012     This module contains routines which provide support for the
    00013     kernel debugger.
    00014
    00015 Author:
    00016
    00017     Lou Perazzoli (loup) 02-Aug-90
    00018     Joe Notarangelo  23-Apr-1992
    00019
    00020 Revision History:
    00021
    00022 --*/
    00023
    00024 #include "mi.h"
    00025
    00026 PVOID
    00027 MmDbgReadCheck (
    00028     IN PVOID VirtualAddress
    00029     )
    00030
    00031 /*++
    00032
    00033 Routine Description:
    00034
    00035
    00036     ALPHA implementation specific:
    00037
    00038     This routine returns the virtual address which is valid (mapped)
    00039     for read access.
    00040
    00041 Arguments:
    00042
    00043     VirtualAddress - Supplies the virtual address to check.
    00044
    00045 Return Value:
    00046
    00047     Returns NULL if the address is not valid or readable, otherwise
    00048     returns the virtual address.
    00049
    00050 Environment:
    00051
    00052     Kernel mode IRQL at DISPATCH_LEVEL or greater.
    00053
    00054 --*/
    00055
    00056 {
    00057     if ((VirtualAddress >= (PVOID)KSEG0_BASE) &&
    00058         (VirtualAddress < (PVOID)KSEG2_BASE)) {
    00059         return VirtualAddress;
    00060     }
    00061
    00062     if (!MmIsAddressValid (VirtualAddress)) {
    00063         return NULL;
    00064     }
    00065
    00066     return VirtualAddress;
    00067 }
    00068
    00069 PVOID
    00070 MmDbgWriteCheck (
    00071     IN PVOID VirtualAddress,
    00072     IN PHARDWARE_PTE Opaque
    00073     )
    00074
    00075 /*++
    00076
    00077 Routine Description:
    00078
    00079     ALPHA implementation specific:
    00080
    00081     This routine returns the physical address for a virtual address
    00082     which is valid (mapped) for write access.
    00083
    00084     If the address is valid and writable and not within KSEG0
    00085     the physical address within KSEG0 is returned.  If the address
    00086     is within KSEG0 then the called address is returned.
    00087
    00088     NOTE: The physical address must only be used while the interrupt
    00089     level on ALL processors is above DISPATCH_LEVEL, otherwise the
    00090     binding between the virtual address and the physical address can
    00091     change due to paging.
    00092
    00093 Arguments:
    00094
    00095     VirtualAddress - Supplies the virtual address to check.
    00096
    00097     Opaque - Supplies a pointer to fill with an opaque value.
    00098
    00099 Return Value:
    00100
    00101     Returns NULL if the address is not valid or readable, otherwise
    00102     returns the physical address of the corresponding virtual address.
    00103
    00104 Environment:
    00105
    00106     Kernel mode IRQL at DISPATCH_LEVEL or greater.
    00107
    00108 --*/
    00109
    00110 {
    00111     MMPTE PteContents;
    00112     PMMPTE PointerPte;
    00113     PMMPTE InputPte;
    00114
    00115     InputPte = (PMMPTE)Opaque;
    00116
    00117     InputPte->u.Long = 0;
    00118
    00119     if ((VirtualAddress >= (PVOID)KSEG0_BASE) &&
    00120         (VirtualAddress < (PVOID)KSEG2_BASE)) {
    00121         return VirtualAddress;
    00122     }
    00123
    00124     if (!MmIsAddressValid (VirtualAddress)) {
    00125         return NULL;
    00126     }
    00127
    00128     PointerPte = MiGetPteAddress (VirtualAddress);
    00129     if ((VirtualAddress <= MM_HIGHEST_USER_ADDRESS) &&
    00130          (PointerPte->u.Hard.PageFrameNumber < MM_PAGES_IN_KSEG0)) {
    00131
    00132         //
    00133         // User mode - return the physical address.  This prevents
    00134         // copy on write faults for breakpoints on user-mode pages.
    00135         // IGNORE write protection.
    00136         //
    00137         // N.B. - The physical address must be less than 1GB to allow this
    00138         //        short-cut mapping.
    00139         //
    00140         // N.B. - Any non-breakpoint modifications can get lost when the page
    00141         //        is paged out because the PTE is not marked modified when
    00142         //        the access is made through this alternate mapping.
    00143         //
    00144
    00145         return (PVOID)
    00146            ((ULONG)MmGetPhysicalAddress(VirtualAddress).LowPart + KSEG0_BASE);
    00147     }
    00148
    00149     if (PointerPte->u.Hard.Write == 0) {
    00150
    00151         //
    00152         // PTE is not writable, make it so.
    00153         //
    00154
    00155         PteContents = *PointerPte;
    00156
    00157         *InputPte = PteContents;
    00158
    00159         //
    00160         // Modify the PTE to ensure write permissions.
    00161         //
    00162
    00163         PteContents.u.Hard.Write = 1;
    00164
    00165         *PointerPte = PteContents;
    00166
    00167         //
    00168         // BUGBUG John Vert (jvert) 3/4/1999
    00169         //   KeFillEntryTb is liable to IPI the other processors. This is
    00170         //   definitely NOT what we want as the other processors are frozen
    00171         //   in the debugger and we will deadlock if we try and IPI them.
    00172         //   Just flush the the current processor instead.
    00173         //KeFillEntryTb ((PHARDWARE_PTE)PointerPte, VirtualAddress, TRUE);
    00174         KiFlushSingleTb(TRUE, VirtualAddress);
    00175
    00176     }
    00177
    00178     return VirtualAddress;
    00179 }
    00180
    00181 VOID
    00182 MmDbgReleaseAddress (
    00183     IN PVOID VirtualAddress,
    00184     IN PHARDWARE_PTE Opaque
    00185     )
    00186
    00187 /*++
    00188
    00189 Routine Description:
    00190
    00191     i386/486 implementation specific:
    00192
    00193     This routine resets the specified virtual address access permissions
    00194     to its original state.
    00195
    00196 Arguments:
    00197
    00198     VirtualAddress - Supplies the virtual address to check.
    00199
    00200     Opaque - Supplies an opaque pointer.
    00201
    00202 Return Value:
    00203
    00204     None.
    00205
    00206 Environment:
    00207
    00208     Kernel mode IRQL at DISPATCH_LEVEL or greater.
    00209
    00210 --*/
    00211
    00212 {
    00213     MMPTE TempPte;
    00214     PMMPTE PointerPte;
    00215     PMMPTE InputPte;
    00216
    00217     InputPte = (PMMPTE)Opaque;
    00218
    00219     ASSERT (MmIsAddressValid (VirtualAddress));
    00220
    00221     if (InputPte->u.Long != 0) {
    00222
    00223         PointerPte = MiGetPteAddress (VirtualAddress);
    00224
    00225         TempPte = *InputPte;
    00226
    00227         // LWFIX: Need to make the write go out to memory but can't
    00228         // make it dirty here ! TempPte.u.Hard.Dirty = MM_PTE_DIRTY;
    00229
    00230         *PointerPte = TempPte;
    00231
    00232         //
    00233         // BUGBUG John Vert (jvert) 3/4/1999
    00234         //   KeFillEntryTb is liable to IPI the other processors. This is
    00235         //   definitely NOT what we want as the other processors are frozen
    00236         //   in the debugger and we will deadlock if we try and IPI them.
    00237         //   Just flush the current processor instead.
    00238         //KeFillEntryTb ((PHARDWARE_PTE)PointerPte, VirtualAddress, TRUE);
    00239         KiFlushSingleTb(TRUE, VirtualAddress);
    00240     }
    00241
    00242     return;
    00243 }
    00244
    00245 PVOID64
    00246 MmDbgReadCheck64 (
    00247     IN PVOID64 VirtualAddress
    00248     )
    00249
    00250 /*++
    00251
    00252 Routine Description:
    00253
    00254
    00255     ALPHA implementation specific:
    00256
    00257     This routine returns the virtual address which is valid (mapped)
    00258     for read access.
    00259
    00260     If the address is valid and readable then the called address is returned.
    00261
    00262 Arguments:
    00263
    00264     VirtualAddress - Supplies the virtual address to check.
    00265
    00266 Return Value:
    00267
    00268     Returns NULL if the address is not valid or readable, otherwise
    00269     returns the virtual address.
    00270
    00271 Environment:
    00272
    00273     Kernel mode IRQL at DISPATCH_LEVEL or greater.
    00274
    00275 --*/
    00276
    00277 {
    00278 #ifdef VLM_SUPPORT
    00279
    00280     if (!MmIsAddressValid64 (VirtualAddress)) {
    00281         return NULL;
    00282     }
    00283
    00284     return VirtualAddress;
    00285 #else
    00286     return NULL;
    00287 #endif
    00288 }
    00289
    00290 PVOID64
    00291 MmDbgWriteCheck64 (
    00292     IN PVOID64 VirtualAddress
    00293     )
    00294
    00295 /*++
    00296
    00297 Routine Description:
    00298
    00299     ALPHA implementation specific:
    00300
    00301     This routine returns the physical address for a virtual address
    00302     which is valid (mapped) for write access.
    00303
    00304     If the address is valid and writable then the called address is returned.
    00305
    00306 Arguments:
    00307
    00308     VirtualAddress - Supplies the virtual address to check.
    00309
    00310 Return Value:
    00311
    00312     Returns NULL if the address is not valid or readable, otherwise
    00313     returns the virtual address.
    00314
    00315 Environment:
    00316
    00317     Kernel mode IRQL at DISPATCH_LEVEL or greater.
    00318
    00319 --*/
    00320
    00321 {
    00322 #ifdef VLM_SUPPORT
    00323     PMMPTE PointerPte;
    00324
    00325     if (!MmIsAddressValid64 (VirtualAddress)) {
    00326         return NULL;
    00327     }
    00328
    00329     PointerPte = MiGetPteAddress64 (VirtualAddress);
    00330
    00331     if (PointerPte->u.Hard.Write == 0) {
    00332         return NULL;
    00333     }
    00334
    00335     return VirtualAddress;
    00336 #else
    00337     return NULL;
    00338 #endif
    00339 }
    00340
    00341 PVOID64
    00342 MmDbgTranslatePhysicalAddress64 (
    00343     IN PHYSICAL_ADDRESS PhysicalAddress
    00344     )
    00345
    00346 /*++
    00347
    00348 Routine Description:
    00349
    00350     ALPHA implementation specific:
    00351
    00352     The Alpha processor provides a direct-mapped address space called
    00353     the superpage.  The entire physical address space can be
    00354     addressed via the superpage.  This routine translates a physical
    00355     address to its corresponding superpage address.  Unfortunately,
    00356     the base superpage address is processor-dependent.  Therefore, we
    00357     have to compute it based on the processor level.  As new processors are
    00358     released, this routine will need to be updated.
    00359
    00360     This routine does not use PTEs.
    00361
    00362 Arguments:
    00363
    00364     PhysicalAddress - Supplies the physical address to translate.
    00365
    00366 Return Value:
    00367
    00368     The virtual (superpage) address which corresponds to the physical address.
    00369
    00370 Environment:
    00371
    00372     Kernel mode IRQL at DISPATCH_LEVEL or greater.
    00373
    00374 --*/
    00375
    00376 {
    00377     switch (KeProcessorLevel) {
    00378
    00379     case PROCESSOR_ALPHA_21064:
    00380     case PROCESSOR_ALPHA_21066:
    00381     case PROCESSOR_ALPHA_21068:
    00382         PhysicalAddress.QuadPart &= 0x00000003ffffffff;
    00383         PhysicalAddress.QuadPart |= 0xfffffc0000000000;
    00384         break;
    00385
    00386     case PROCESSOR_ALPHA_21164:
    00387     case PROCESSOR_ALPHA_21164PC:
    00388         PhysicalAddress.QuadPart &= 0x000000ffffffffff;
    00389         PhysicalAddress.QuadPart |= 0xfffffc0000000000;
    00390         break;
    00391
    00392     case PROCESSOR_ALPHA_21264:
    00393         PhysicalAddress.QuadPart &= 0x00000fffffffffff;
    00394         PhysicalAddress.QuadPart |= 0xffff800000000000;
    00395         break;
    00396
    00397     default:
    00398         return NULL64;
    00399
    00400     }
    00401
    00402     return (PVOID64)PhysicalAddress.QuadPart;
    00403 }