hibernate_restore.c [plain text]
#include <i386/pmap.h>
#include <i386/proc_reg.h>
#include <IOKit/IOHibernatePrivate.h>
#include <i386/pal_hibernate.h>
extern pd_entry_t BootstrapPTD[2048];
#define TWO_MEG_MASK 0xFFFFFFFFFFE00000ULL
#define FOUR_K_MASK 0xFFFFFFFFFFFFF000ULL
uintptr_t
hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags)
{
(void)procFlags;
uint64_t * d;
uint64_t * s;
uint32_t idx;
if (src == 0)
return (uintptr_t)dst;
d = (uint64_t *)pal_hib_map(DEST_COPY_AREA, dst);
s = (uint64_t *) (uintptr_t)src;
for (idx = 0; idx < (len / (uint32_t)sizeof(uint64_t)); idx++)
d[idx] = s[idx];
return (uintptr_t)d;
}
#undef hibprintf
void hibprintf(const char *fmt, ...);
void
pal_hib_window_setup(ppnum_t page)
{
uint64_t *pp;
uint64_t phys = ptoa_64(page);
int i;
BootstrapPTD[2047] = (phys & ~((uint64_t)I386_LPGMASK)) | INTEL_PTE_PS | INTEL_PTE_VALID | INTEL_PTE_WRITE;
invlpg(HIB_PTES);
pp = (uint64_t *)(uintptr_t)(HIB_PTES + (phys & I386_LPGMASK));
for(i=0;i<512;i++)
*pp = 0;
pp[0] = phys | INTEL_PTE_VALID | INTEL_PTE_WRITE;
BootstrapPTD[2047] = phys | INTEL_PTE_VALID | INTEL_PTE_WRITE;
invlpg(HIB_PTES);
}
uintptr_t
pal_hib_map(uintptr_t v, uint64_t p)
{
int index;
switch(v) {
case DEST_COPY_AREA:
index = 1;
break;
case SRC_COPY_AREA:
index = 2;
break;
case COPY_PAGE_AREA:
index = 3;
break;
default:
index = -1;
asm("cli;hlt;");
}
uint64_t *ptes = (uint64_t *)HIB_PTES;
ptes[index] = (p & FOUR_K_MASK) | INTEL_PTE_VALID | INTEL_PTE_WRITE;
invlpg((uintptr_t)v);
return v;
}
void hibernateRestorePALState(uint32_t *arg)
{
(void)arg;
}
void
pal_hib_patchup(void)
{
}