#include <IOKit/IOHibernatePrivate.h>
#include <IOKit/IOLib.h>
#include <pexpert/boot.h>
-#include <crypto/aes.h>
#include <libkern/libkern.h>
-#include <libkern/WKdm.h>
+#include <vm/WKdm_new.h>
#include "IOHibernateInternal.h"
-#if defined(__i386__) || defined(__x86_64__)
-#include <i386/pal_hibernate.h>
-#endif
+#include <machine/pal_hibernate.h>
/*
This code is linked into the kernel but part of the "__HIB" section, which means
#if defined(__i386__) || defined(__x86_64__)
+#define rdtsc(lo,hi) \
+ __asm__ volatile("lfence; rdtsc; lfence" : "=a" (lo), "=d" (hi))
+
+static inline uint64_t rdtsc64(void)
+{
+ uint64_t lo, hi;
+ rdtsc(lo, hi);
+ return ((hi) << 32) | (lo);
+}
+
+#else
+
+static inline uint64_t rdtsc64(void)
+{
+ return (0);
+}
+
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+#if defined(__i386__) || defined(__x86_64__)
+
#define DBGLOG 1
#include <architecture/i386/pio.h>
uint32_t * buffer, uint32_t ppnum)
{
uint64_t dst = ptoa_64(ppnum);
+ uint8_t scratch[WKdm_SCRATCH_BUF_SIZE_INTERNAL] __attribute__ ((aligned (16)));
if (compressedSize != PAGE_SIZE)
{
dst = pal_hib_map(DEST_COPY_AREA, dst);
- WKdm_decompress((WK_word*) src, (WK_word*)(uintptr_t)dst, PAGE_SIZE >> 2);
+ if (compressedSize != 4) WKdm_decompress_new((WK_word*) src, (WK_word*)(uintptr_t)dst, (WK_word*) &scratch[0], compressedSize);
+ else
+ {
+ size_t i;
+ uint32_t s, *d;
+
+ s = *src;
+ d = (uint32_t *)(uintptr_t)dst;
+ if (!s) bzero((void *) dst, PAGE_SIZE);
+ else for (i = 0; i < (PAGE_SIZE / sizeof(int32_t)); i++) *d++ = s;
+ }
}
else
{
return hibernate_sum_page((uint8_t *)(uintptr_t)dst, ppnum);
}
-// used only for small struct copies
-static void
-bcopy_internal(const void *src, void *dst, uint32_t len)
-{
- const char *s = src;
- char *d = dst;
- uint32_t idx = 0;
-
- while (idx < len)
- {
- d[idx] = s[idx];
- idx++;
- }
-}
-
-#define C_ASSERT(e) typedef char __C_ASSERT__[(e) ? 1 : -1]
-
long
hibernate_kernel_entrypoint(uint32_t p1,
uint32_t p2, uint32_t p3, uint32_t p4)
uint64_t srcPhys;
uint64_t imageReadPhys;
uint64_t pageIndexPhys;
- uint32_t idx;
uint32_t * pageIndexSource;
hibernate_page_list_t * map;
uint32_t stage;
uint32_t handoffPages;
uint32_t handoffPageCount;
- C_ASSERT(sizeof(IOHibernateImageHeader) == 512);
+ uint64_t timeStart;
+ timeStart = rdtsc64();
+
+ static_assert(sizeof(IOHibernateImageHeader) == 512);
headerPhys = ptoa_64(p1);
debug_code(kIOHibernateRestoreCodeImageStart, headerPhys);
- bcopy_internal((void *) pal_hib_map(IMAGE_AREA, headerPhys),
- gIOHibernateCurrentHeader,
- sizeof(IOHibernateImageHeader));
+ memcpy(gIOHibernateCurrentHeader,
+ (void *) pal_hib_map(IMAGE_AREA, headerPhys),
+ sizeof(IOHibernateImageHeader));
debug_code(kIOHibernateRestoreCodeSignature, gIOHibernateCurrentHeader->signature);
sum = gIOHibernateCurrentHeader->actualRestore1Sum;
gIOHibernateCurrentHeader->diag[0] = atop_64(headerPhys);
gIOHibernateCurrentHeader->diag[1] = sum;
+ gIOHibernateCurrentHeader->trampolineTime = 0;
uncompressedPages = 0;
conflictCount = 0;
if (!conflicts)
{
-// if (compressedSize)
pageSum = store_one_page(gIOHibernateCurrentHeader->processorFlags,
src, compressedSize, 0, ppnum);
if (stage != 2)
}
else
{
- uint32_t bufferPage;
+ uint32_t bufferPage = 0;
uint32_t * dst;
// debug_code(kIOHibernateRestoreCodeConflictPage, ppnum);
// debug_code(kIOHibernateRestoreCodeConflictSource, (uintptr_t) src);
-
conflictCount++;
-
- // alloc new buffer page
- bufferPage = hibernate_page_list_grab(map, &nextFree);
-
+ if (compressedSize)
+ {
+ // alloc new buffer page
+ bufferPage = hibernate_page_list_grab(map, &nextFree);
+ dst = (uint32_t *)pal_hib_map(DEST_COPY_AREA, ptoa_64(bufferPage));
+ memcpy(dst, src, compressedSize);
+ }
if (copyPageIndex > ((PAGE_SIZE >> 2) - 3))
{
// alloc new copy list page
copyPageList[1] = 0;
copyPageIndex = 2;
}
-
copyPageList[copyPageIndex++] = ppnum;
copyPageList[copyPageIndex++] = bufferPage;
copyPageList[copyPageIndex++] = (compressedSize | (stage << 24));
copyPageList[0] = copyPageIndex;
-
- dst = (uint32_t *)pal_hib_map(DEST_COPY_AREA, ptoa_64(bufferPage));
- for (idx = 0; idx < ((compressedSize + 3) >> 2); idx++)
- dst[idx] = src[idx];
}
srcPhys += ((compressedSize + 3) & ~3);
src += ((compressedSize + 3) >> 2);
gIOHibernateState = kIOHibernateStateWakingFromHibernate;
+ gIOHibernateCurrentHeader->trampolineTime = (((rdtsc64() - timeStart)) >> 8);
+
+// debug_code('done', 0);
+
#if CONFIG_SLEEP
#if defined(__i386__) || defined(__x86_64__)
typedef void (*ResetProc)(void);