You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
4.9 KiB
213 lines
4.9 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
wake.c
|
|
|
|
Abstract:
|
|
|
|
This module contains architecture dependent support for hibernation
|
|
on IA-64.
|
|
|
|
Author:
|
|
|
|
Allen Kay ([email protected])
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <bldr.h>
|
|
|
|
|
|
#if defined (HIBER_DEBUG)
|
|
extern VOID HbPrint(PUCHAR);
|
|
extern VOID HbPrintNum(ULONG n);
|
|
extern VOID HbPrintHex(ULONG n);
|
|
extern VOID HbPause(VOID);
|
|
#define SHOWNUM(x) ((void) (HbPrint(#x " = "), HbPrintNum((ULONG) (x)), HbPrint("\r\n")))
|
|
#define SHOWHEX(x) ((void) (HbPrint(#x " = "), HbPrintHex((ULONG) (x)), HbPrint("\r\n")))
|
|
#endif
|
|
|
|
|
|
//
|
|
// When the hibernation image is read from disk each page must return to the
|
|
// same page frame it came from. Some of those page frames are currently in
|
|
// use by firmware or OS Loader, so the pages that belong there must be
|
|
// loaded temporarily somewhere else and copied into place just before the
|
|
// saved image is restarted.
|
|
//
|
|
// The hibernation file contains a list of pages that were not in use by
|
|
// the saved image, and were allocated from memory marked as MemoryFree by
|
|
// firmware. MapPage is initialized to point to this list; as pages are
|
|
// needed for relocation, they are chosen from this list. RemapPage is
|
|
// a corresponding array of where each relocated page actually belongs.
|
|
//
|
|
|
|
PPFN_NUMBER HiberMapPage;
|
|
PPFN_NUMBER HiberRemapPage;
|
|
|
|
ULONG HiberCurrentMapIndex;
|
|
|
|
|
|
VOID
|
|
HbInitRemap(
|
|
PPFN_NUMBER FreeList
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize memory allocation and remapping. Find a free page
|
|
in the FreeList, copy the FreeList into it, and point HiberMapPage
|
|
to it. Find another free page and and point HiberRemapPage to it.
|
|
Initialize HiberLastRemap.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
HiberMapPage = HiberRemapPage = FreeList; // so HbNextSharedPage will work
|
|
HiberMapPage = HbNextSharedPage(0, 0);
|
|
RtlCopyMemory(HiberMapPage, FreeList, PAGE_SIZE);
|
|
HiberRemapPage = HbNextSharedPage(0, 0);
|
|
}
|
|
|
|
|
|
PVOID
|
|
HbMapPte (
|
|
IN ULONG PteToMap,
|
|
IN PFN_NUMBER Page
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return a 32 superpage pointer to the specified physical page.
|
|
(On x86, this function maps the page and returns a virtual address.)
|
|
|
|
Arguments:
|
|
|
|
PteToMap - unused, present only for x86 compatibility
|
|
|
|
Page - the physical page (page frame number) to map,
|
|
must be below 1 GB.
|
|
|
|
Return Value:
|
|
|
|
32 bit superpage address of the page.
|
|
|
|
--*/
|
|
{
|
|
UNREFERENCED_PARAMETER( PteToMap );
|
|
|
|
ASSERT (Page < (1024L * 1024L * 1024L >> PAGE_SHIFT)) ;
|
|
return (PVOID) ((Page << PAGE_SHIFT) + KSEG0_BASE) ;
|
|
}
|
|
|
|
|
|
PVOID
|
|
HbNextSharedPage (
|
|
IN ULONG PteToMap,
|
|
IN PFN_NUMBER RealPage
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allocates the next available page in the free list and
|
|
maps the Hiber pte to the page. The allocated page
|
|
is put onto the remap list.
|
|
|
|
Arguments:
|
|
|
|
PteToMap - unused, present only for x86 compatibility
|
|
|
|
RealPage - The page to enter into the remap table for
|
|
this allocation
|
|
|
|
Return Value:
|
|
|
|
Virtual address of the mapping
|
|
|
|
--*/
|
|
|
|
{
|
|
PFN_NUMBER DestPage;
|
|
ULONG i;
|
|
|
|
#if defined (HIBER_DEBUG) && (HIBER_DEBUG & 2)
|
|
HbPrint("HbNextSharedPage("); HbPrintHex(RealPage); HbPrint(")\r\n");
|
|
SHOWNUM(HiberCurrentMapIndex);
|
|
SHOWNUM(HiberNoMappings);
|
|
#endif
|
|
|
|
//
|
|
// Loop until we find a free page which is not in
|
|
// use by the loader image, then map it
|
|
//
|
|
|
|
while (HiberCurrentMapIndex < HiberNoMappings) {
|
|
DestPage = HiberMapPage[HiberCurrentMapIndex];
|
|
HiberCurrentMapIndex += 1;
|
|
|
|
#if defined (HIBER_DEBUG) && (HIBER_DEBUG & 2)
|
|
SHOWHEX(DestPage);
|
|
#endif
|
|
|
|
i = HbPageDisposition (DestPage);
|
|
if (i == HbPageInvalid) {
|
|
#if defined (HIBER_DEBUG) && (HIBER_DEBUG & 2)
|
|
HbPrint("Invalid\n");
|
|
HbPause();
|
|
#endif
|
|
HiberIoError = TRUE;
|
|
return HiberBuffer;
|
|
}
|
|
|
|
if (i == HbPageNotInUse) {
|
|
#if defined (HIBER_DEBUG) && (HIBER_DEBUG & 2)
|
|
HbPrint("Not in use\r\n");
|
|
HbPause();
|
|
#endif
|
|
|
|
#if defined (HIBER_DEBUG) && (HIBER_DEBUG & 4)
|
|
HbPrint("\r\n"); HbPrintHex(RealPage); HbPrint(" at "); HbPrintHex(DestPage);
|
|
#endif
|
|
HiberMapPage[HiberLastRemap] = DestPage;
|
|
HiberRemapPage[HiberLastRemap] = RealPage;
|
|
HiberLastRemap += 1;
|
|
return HbMapPte(PteToMap, DestPage);
|
|
}
|
|
#if defined (HIBER_DEBUG)
|
|
SHOWNUM(i);
|
|
#endif
|
|
}
|
|
#if defined (HIBER_DEBUG)
|
|
HbPrint("Out of remap\r\n");
|
|
HbPause();
|
|
#endif
|
|
HiberOutOfRemap = TRUE;
|
|
return HiberBuffer;
|
|
}
|
|
|
|
|
|
VOID
|
|
HiberSetupForWakeDispatch (
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Make sure the I-cache is coherent with the wake dispatch code that was
|
|
// copied to a free page.
|
|
//
|
|
|
|
}
|