test: ia64/hypermap.c File Reference

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

# hypermap.c File Reference

`#include "mi.h"`

Go to the source code of this file.

## Functions

PVOID | MiMapPageInHyperSpace (IN PFN_NUMBER PageFrameIndex, IN PKIRQL OldIrql)
PVOID | MiMapImageHeaderInHyperSpace (IN PFN_NUMBER PageFrameIndex)
VOID | MiUnmapImageHeaderInHyperSpace (VOID)
PVOID | MiMapPageToZeroInHyperSpace (IN PFN_NUMBER PageFrameIndex)

## Function Documentation

PVOID MiMapImageHeaderInHyperSpace | ( | IN PFN_NUMBER | PageFrameIndex | ) |

Definition at line 149 of file ia64/hypermap.c.

References ASSERT, DbgPrint, Executive, FALSE, IMAGE_MAPPING_PTE, KeBugCheck(), KernelMode, KeWaitForSingleObject(), LOCK_PFN, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MmImageMappingPteEvent, MmWorkingSetList, NULL, _MMPTE::u, UNLOCK_PFN, UNLOCK_PFN_AND_THEN_WAIT, ValidPtePte, and _MMWSL::WaitingForImageMapping.

    00155                    :
    00156
    00157     This procedure maps the specified physical page into the
    00158     PTE within hyper space reserved explicitly for image page
    00159     header mapping.  By reserving an explicit PTE for mapping
    00160     the PTE, page faults can occur while the PTE is mapped within
    00161     hyperspace and no other hyperspace maps will affect this PTE.
    00162
    00163     Note that if another thread attempts to map an image at the
    00164     same time, it will be forced into a wait state until the
    00165     header is "unmapped".
    00166
    00167 Arguments:
    00168
    00169     PageFrameIndex - Supplies the physical page number to map.
    00170
    00171 Return Value:
    00172
    00173     Returns the virtual address where the specified physical page was
    00174     mapped.
    00175
    00176 Environment:
    00177
    00178     Kernel mode.
    00179
    00180 --*/
    00181
    00182 {
    00183     MMPTE TempPte;
    00184     PMMPTE PointerPte;
    00185     KIRQL OldIrql;
    00186
    00187 #if DBG
    00188     if (PageFrameIndex == 0) {
    00189         DbgPrint("attempt to map physical page 0 in hyper space\n");
    00190         KeBugCheck (MEMORY_MANAGEMENT);
    00191     }
    00192 #endif //DBG
    00193
    00194 #if HYPERMAP
    00195
    00196     PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE);
    00197
    00198     LOCK_PFN (OldIrql);
    00199
    00200     while (PointerPte->u.Long != 0) {
    00201
    00202         //
    00203         // If there is no event specified, set one up.
    00204         //
    00205
    00206         if (MmWorkingSetList->WaitingForImageMapping == (PKEVENT)NULL) {
    00207
    00208             //
    00209             // Set the global event into the field and wait for it.
    00210             //
    00211
    00212             MmWorkingSetList->WaitingForImageMapping = &MmImageMappingPteEvent;
    00213         }
    00214
    00215         //
    00216         // Release the PFN lock and wait on the event in an
    00217         // atomic operation.
    00218         //
    00219
    00220         UNLOCK_PFN_AND_THEN_WAIT(OldIrql);
    00221
    00222         KeWaitForSingleObject(MmWorkingSetList->WaitingForImageMapping,
    00223                               Executive,
    00224                               KernelMode,
    00225                               FALSE,
    00226                               (PLARGE_INTEGER)NULL);
    00227
    00228         LOCK_PFN (OldIrql);
    00229     }
    00230
    00231     ASSERT (PointerPte->u.Long == 0);
    00232
    00233     TempPte = ValidPtePte;
    00234     TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
    00235
    00236     *PointerPte = TempPte;
    00237
    00238     UNLOCK_PFN (OldIrql);
    00239
    00240     return (PVOID)MiGetVirtualAddressMappedByPte (PointerPte);
    00241
    00242 #else
    00243
    00244     return KSEG_ADDRESS(PageFrameIndex);
    00245
    00246 #endif
    00247 }

PVOID MiMapPageInHyperSpace | ( | IN PFN_NUMBER | PageFrameIndex,
|  | IN PKIRQL | OldIrql
| ) |

Definition at line 26 of file ia64/hypermap.c.

References ASSERT, DbgPrint, FALSE, KeBugCheck(), KeFlushEntireTb(), KSEG0_BASE, LOCK_HYPERSPACE, MI_MAKING_MULTIPLE_PTES_INVALID, MiGetVirtualAddressMappedByPte, MmFirstReservedMappingPte, MmKseg2Frame, NUMBER_OF_MAPPING_PTES, PAGE_SHIFT, TRUE, _MMPTE::u, and ValidPtePte.

    00033                    :
    00034
    00035     This procedure maps the specified physical page into hyper space
    00036     and returns the virtual address which maps the page.
    00037
    00038     ************************************
    00039     *                                  *
    00040     * Returns with a spin lock held!!! *
    00041     *                                  *
    00042     ************************************
    00043
    00044 Arguments:
    00045
    00046     PageFrameIndex - Supplies the physical page number to map.
    00047
    00048
    00049 Return Value:
    00050
    00051     Returns the address where the requested page was mapped.
    00052
    00053     RETURNS WITH THE HYPERSPACE SPIN LOCK HELD!!!!
    00054
    00055     The routine MiUnmapHyperSpaceMap MUST be called to release the lock!!!!
    00056
    00057 Environment:
    00058
    00059     Kernel mode.
    00060
    00061 --*/
    00062
    00063 {
    00064
    00065     MMPTE TempPte;
    00066     PMMPTE PointerPte;
    00067     PFN_NUMBER offset;
    00068
    00069 #if DBG
    00070     if (PageFrameIndex == 0) {
    00071         DbgPrint("attempt to map physical page 0 in hyper space\n");
    00072         KeBugCheck (MEMORY_MANAGEMENT);
    00073     }
    00074 #endif //DBG
    00075
    00076     LOCK_HYPERSPACE(OldIrql);
    00077
    00078 #if HYPERMAP
    00079
    00080     if( PageFrameIndex < MmKseg2Frame){
    00081         return (PVOID)(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT));
    00082     }
    00083
    00084     PointerPte = MmFirstReservedMappingPte;
    00085     if (PointerPte->u.Hard.Valid == 1) {
    00086
    00087         //
    00088         // All the reserved PTEs have been used, make
    00089         // them all invalid.
    00090         //
    00091
    00092         MI_MAKING_MULTIPLE_PTES_INVALID (FALSE);
    00093
    00094         RtlZeroMemory (MmFirstReservedMappingPte,
    00095                        (NUMBER_OF_MAPPING_PTES + 1) * sizeof(MMPTE));
    00096
    00097         //
    00098         // Use the page frame number field of the first PTE as an
    00099         // offset into the available mapping PTEs.
    00100         //
    00101
    00102         PointerPte->u.Hard.PageFrameNumber = NUMBER_OF_MAPPING_PTES;
    00103
    00104         //
    00105         // Flush entire TB only on this processor.
    00106         //
    00107
    00108         KeFlushEntireTb (TRUE, FALSE);
    00109     }
    00110
    00111     //
    00112     // Get offset to first free PTE.
    00113     //
    00114
    00115     offset = (PFN_NUMBER)PointerPte->u.Hard.PageFrameNumber;
    00116
    00117     //
    00118     // Change offset for next time through.
    00119     //
    00120
    00121     PointerPte->u.Hard.PageFrameNumber = offset - 1;
    00122
    00123     //
    00124     // Point to free entry and make it valid.
    00125     //
    00126
    00127     PointerPte += offset;
    00128     ASSERT (PointerPte->u.Hard.Valid == 0);
    00129
    00130
    00131     TempPte = ValidPtePte;
    00132     TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
    00133     *PointerPte = TempPte;
    00134
    00135     //
    00136     // Return the VA that map the page.
    00137     //
    00138
    00139     return MiGetVirtualAddressMappedByPte (PointerPte);
    00140
    00141 #else
    00142
    00143     return KSEG_ADDRESS(PageFrameIndex);
    00144
    00145 #endif
    00146 }

PVOID MiMapPageToZeroInHyperSpace | ( | IN PFN_NUMBER | PageFrameIndex | ) |

Definition at line 320 of file ia64/hypermap.c.

References DbgPrint, FALSE, KeBugCheck(), KeFlushSingleTb(), KSEG0_BASE, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MM_PFN_LOCK_ASSERT, MmKseg2Frame, PAGE_SHIFT, TRUE, _MMPTE::u, ValidPtePte, and ZEROING_PAGE_PTE.

    00326                    :
    00327
    00328     This procedure maps the specified physical page into hyper space
    00329     and returns the virtual address which maps the page.
    00330
    00331     NOTE: it maps it into the same location reserved for zeroing operations.
    00332     This is only to be used by the zeroing page thread.
    00333
    00334 Arguments:
    00335
    00336     PageFrameIndex - Supplies the physical page number to map.
    00337
    00338 Return Value:
    00339
    00340     Returns the virtual address where the specified physical page was
    00341     mapped.
    00342
    00343 Environment:
    00344
    00345     Must be holding the PFN lock.
    00346
    00347 --*/
    00348
    00349 {
    00350     MMPTE TempPte;
    00351     PMMPTE PointerPte;
    00352     PVOID MappedAddress;
    00353
    00354 #if DBG
    00355     if (PageFrameIndex == 0) {
    00356         DbgPrint("attempt to map physical page 0 in hyper space\n");
    00357         KeBugCheck (MEMORY_MANAGEMENT);
    00358     }
    00359 #endif
    00360
    00361     MM_PFN_LOCK_ASSERT();
    00362
    00363 #if HYPERMAP
    00364
    00365     if( PageFrameIndex < MmKseg2Frame){
    00366         return (PVOID)(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT));
    00367     }
    00368
    00369     PointerPte = MiGetPteAddress (ZEROING_PAGE_PTE);
    00370
    00371     MappedAddress = MiGetVirtualAddressMappedByPte (PointerPte);
    00372
    00373     TempPte.u.Long = 0;
    00374
    00375     KeFlushSingleTb (MappedAddress, TRUE, FALSE,
    00376                      (PHARDWARE_PTE)PointerPte, TempPte.u.Flush);
    00377
    00378     TempPte = ValidPtePte;
    00379     TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
    00380
    00381     *PointerPte = TempPte;
    00382
    00383     return MappedAddress;
    00384
    00385 #else
    00386
    00387     return KSEG_ADDRESS(PageFrameIndex);
    00388
    00389 #endif
    00390 }
    }

VOID MiUnmapImageHeaderInHyperSpace | ( | VOID |  | ) |

Definition at line 250 of file ia64/hypermap.c.

References ASSERT, Event(), FALSE, IMAGE_MAPPING_PTE, KeFlushSingleTb(), KePulseEvent(), LOCK_PFN, MiGetPteAddress, MmWorkingSetList, NULL, TRUE, _MMPTE::u, UNLOCK_PFN, and _MMWSL::WaitingForImageMapping.

    00256                    :
    00257
    00258     This procedure unmaps the PTE reserved for mapping the image
    00259     header, flushes the TB, and, if the WaitingForImageMapping field
    00260     is not NULL, sets the specified event.
    00261
    00262 Arguments:
    00263
    00264     None.
    00265
    00266 Return Value:
    00267
    00268     None.
    00269
    00270 Environment:
    00271
    00272     Kernel mode.
    00273
    00274 --*/
    00275
    00276 {
    00277 #if HYPERMAP
    00278
    00279     MMPTE TempPte;
    00280     PMMPTE PointerPte;
    00281     KIRQL OldIrql;
    00282     PKEVENT Event;
    00283
    00284     PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE);
    00285
    00286     TempPte.u.Long = 0;
    00287
    00288     LOCK_PFN (OldIrql);
    00289
    00290     //
    00291     // Capture the current state of the event field and clear it out.
    00292     //
    00293
    00294     Event = MmWorkingSetList->WaitingForImageMapping;
    00295
    00296     MmWorkingSetList->WaitingForImageMapping = (PKEVENT)NULL;
    00297
    00298     ASSERT (PointerPte->u.Long != 0);
    00299
    00300     KeFlushSingleTb (IMAGE_MAPPING_PTE, TRUE, FALSE,
    00301                      (PHARDWARE_PTE)PointerPte, TempPte.u.Flush);
    00302
    00303     UNLOCK_PFN (OldIrql);
    00304
    00305     if (Event != (PKEVENT)NULL) {
    00306
    00307         //
    00308         // If there was an event specified, set the event.
    00309         //
    00310
    00311         KePulseEvent (Event, 0, FALSE);
    00312     }
    00313
    00314 #endif
    00315
    00316     return;
    00317 }