test: hypermap.c Source File

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

# hypermap.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    hypermap.c
    00009
    00010 Abstract:
    00011
    00012     This module contains the routines which map physical pages into
    00013     reserved PTEs within hyper space for AXP64 systems.
    00014
    00015 Author:
    00016
    00017     Lou Perazzoli (loup) 5-Apr-1989
    00018     Joe Notarangelo 23-Apr-1992   ALPHA version from MIPS version
    00019
    00020 Revision History:
    00021
    00022     Chao Chen 21-Aug-1995 Fixed accessing pages above 1 gig problem through
    00023                           hyperspace.
    00024
    00025 --*/
    00026
    00027 #include "mi.h"
    00028
    00029 PVOID
    00030 MiMapPageInHyperSpace (
    00031     IN PFN_NUMBER PageFrameIndex,
    00032     IN PKIRQL OldIrql
    00033     )
    00034
    00035 /*++
    00036
    00037 Routine Description:
    00038
    00039     This routine returns the physical address of the page.
    00040
    00041     ************************************
    00042     *                                  *
    00043     * Returns with a spin lock held!!! *
    00044     *                                  *
    00045     ************************************
    00046
    00047 Arguments:
    00048
    00049     PageFrameIndex - Supplies the physical page number to map.
    00050
    00051 Return Value:
    00052
    00053     Returns the address where the requested page was mapped.
    00054
    00055     RETURNS WITH THE HYPERSPACE SPIN LOCK HELD!!!!
    00056
    00057     The routine MiUnmapHyperSpaceMap MUST be called to release the lock!!!!
    00058
    00059 Environment:
    00060
    00061     kernel mode.
    00062
    00063 --*/
    00064
    00065 {
    00066
    00067     //
    00068     // On AXP64 systems all pages can be mapped physically using the 43-bit
    00069     // super page address range.
    00070     //
    00071
    00072     ASSERT(PageFrameIndex != 0);
    00073
    00074     LOCK_HYPERSPACE(OldIrql);
    00075
    00076     return KSEG_ADDRESS(PageFrameIndex);
    00077 }
    00078
    00079 PVOID
    00080 MiMapImageHeaderInHyperSpace (
    00081     IN PFN_NUMBER PageFrameIndex
    00082     )
    00083
    00084 /*++
    00085
    00086 Routine Description:
    00087
    00088     The physical address of the specified page is returned.
    00089
    00090 Arguments:
    00091
    00092     PageFrameIndex - Supplies the physical page number to map.
    00093
    00094 Return Value:
    00095
    00096     Returns the virtual address where the specified physical page was
    00097     mapped.
    00098
    00099 Environment:
    00100
    00101     Kernel mode.
    00102
    00103 --*/
    00104
    00105 {
    00106     MMPTE TempPte;
    00107     PMMPTE PointerPte;
    00108     KIRQL OldIrql;
    00109
    00110 #if DBG
    00111
    00112     if (PageFrameIndex == 0) {
    00113         DbgPrint("attempt to map physical page 0 in hyper space\n");
    00114         KeBugCheck (MEMORY_MANAGEMENT);
    00115     }
    00116
    00117 #endif //DBG
    00118
    00119     PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE);
    00120
    00121     LOCK_PFN(OldIrql);
    00122
    00123     while (PointerPte->u.Long != 0) {
    00124
    00125         //
    00126         // If there is no event specified, set one up.
    00127         //
    00128
    00129         if (MmWorkingSetList->WaitingForImageMapping == (PKEVENT)NULL) {
    00130
    00131             //
    00132             // Set the global event into the field and wait for it.
    00133             //
    00134
    00135             MmWorkingSetList->WaitingForImageMapping = &MmImageMappingPteEvent;
    00136         }
    00137
    00138         //
    00139         // Release the PFN lock and wait on the event in an
    00140         // atomic operation.
    00141         //
    00142
    00143         KeEnterCriticalRegion();
    00144
    00145         UNLOCK_PFN_AND_THEN_WAIT(OldIrql);
    00146
    00147         KeWaitForSingleObject(MmWorkingSetList->WaitingForImageMapping,
    00148                               Executive,
    00149                               KernelMode,
    00150                               FALSE,
    00151                               (PLARGE_INTEGER)NULL);
    00152
    00153         KeLeaveCriticalRegion();
    00154
    00155         LOCK_PFN (OldIrql);
    00156     }
    00157
    00158     ASSERT (PointerPte->u.Long == 0);
    00159
    00160     TempPte = ValidPtePte;
    00161     TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
    00162
    00163     *PointerPte = TempPte;
    00164
    00165     UNLOCK_PFN (OldIrql);
    00166
    00167     return (PVOID)MiGetVirtualAddressMappedByPte (PointerPte);
    00168 }
    00169
    00170 VOID
    00171 MiUnmapImageHeaderInHyperSpace (
    00172     VOID
    00173     )
    00174
    00175 /*++
    00176
    00177 Routine Description:
    00178
    00179     This procedure unmaps the PTE reserved for mapping the image
    00180     header, flushes the TB, and, if the WaitingForImageMapping field
    00181     is not NULL, sets the specified event.
    00182
    00183     On ALPHA, no action is required as the super-page address of the page
    00184     was used.
    00185
    00186 Arguments:
    00187
    00188     None.
    00189
    00190 Return Value:
    00191
    00192     None.
    00193
    00194 Environment:
    00195
    00196     Kernel mode.
    00197
    00198 --*/
    00199
    00200 {
    00201
    00202     MMPTE TempPte;
    00203     PMMPTE PointerPte;
    00204     KIRQL OldIrql;
    00205     PKEVENT Event;
    00206
    00207     PointerPte = MiGetPteAddress(IMAGE_MAPPING_PTE);
    00208
    00209     TempPte.u.Long = 0;
    00210
    00211     LOCK_PFN (OldIrql);
    00212
    00213     //
    00214     // Capture the current state of the event field and clear it out.
    00215     //
    00216
    00217     Event = MmWorkingSetList->WaitingForImageMapping;
    00218
    00219     MmWorkingSetList->WaitingForImageMapping = (PKEVENT)NULL;
    00220
    00221     ASSERT (PointerPte->u.Long != 0);
    00222
    00223     KeFlushSingleTb (IMAGE_MAPPING_PTE, TRUE, FALSE,
    00224                      (PHARDWARE_PTE)PointerPte, TempPte.u.Hard);
    00225
    00226     UNLOCK_PFN (OldIrql);
    00227
    00228     if (Event != (PKEVENT)NULL) {
    00229
    00230         //
    00231         // If there was an event specified, set the event.
    00232         //
    00233
    00234         KePulseEvent (Event, 0, FALSE);
    00235     }
    00236
    00237     return;
    00238 }
    00239
    00240 PVOID
    00241 MiMapPageToZeroInHyperSpace (
    00242     IN PFN_NUMBER PageFrameIndex
    00243     )
    00244
    00245 /*++
    00246
    00247 Routine Description:
    00248
    00249     This procedure maps the specified page frame into the 43-bit super
    00250     page address range.
    00251
    00252 Arguments:
    00253
    00254     PageFrameIndex - Supplies the page frame to map.
    00255
    00256 Return Value:
    00257
    00258     The 43-bit super address of the respective page is returned as the
    00259     function value.
    00260
    00261 --*/
    00262
    00263 {
    00264
    00265     //
    00266     // On AXP64 systems all pages can be mapped physically using the 43-bit
    00267     // super page address range.
    00268     //
    00269
    00270     ASSERT(PageFrameIndex != 0);
    00271
    00272     MM_PFN_LOCK_ASSERT();
    00273
    00274     return KSEG_ADDRESS(PageFrameIndex);
    00275 }