]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOHibernateRestoreKernel.c
xnu-3789.60.24.tar.gz
[apple/xnu.git] / iokit / Kernel / IOHibernateRestoreKernel.c
index b45b2acd3bf14cf80c22a55d575c654dc3d97e74..017d4d4f87bc9a3a2a59ab9a8008cd2352df16eb 100644 (file)
@@ -34,7 +34,7 @@
 #include <pexpert/boot.h>
 #include <libkern/libkern.h>
 
-#include <libkern/WKdm.h>
+#include <vm/WKdm_new.h>
 #include "IOHibernateInternal.h"
 
 #include <machine/pal_hibernate.h>
@@ -396,11 +396,22 @@ store_one_page(uint32_t procFlags, uint32_t * src, uint32_t compressedSize,
                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
        {
@@ -410,23 +421,6 @@ store_one_page(uint32_t procFlags, uint32_t * src, uint32_t compressedSize,
        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)
@@ -436,7 +430,6 @@ hibernate_kernel_entrypoint(uint32_t p1,
     uint64_t srcPhys;
     uint64_t imageReadPhys;
     uint64_t pageIndexPhys;
-    uint32_t idx;
     uint32_t * pageIndexSource;
     hibernate_page_list_t * map;
     uint32_t stage;
@@ -460,10 +453,10 @@ hibernate_kernel_entrypoint(uint32_t p1,
     uint32_t handoffPages;
     uint32_t handoffPageCount;
 
-    uint64_t timeStart, time;
+    uint64_t timeStart;
     timeStart = rdtsc64();
 
-    C_ASSERT(sizeof(IOHibernateImageHeader) == 512);
+    static_assert(sizeof(IOHibernateImageHeader) == 512);
 
     headerPhys = ptoa_64(p1);
 
@@ -472,9 +465,9 @@ hibernate_kernel_entrypoint(uint32_t 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);
 
@@ -517,6 +510,7 @@ hibernate_kernel_entrypoint(uint32_t p1,
     sum = gIOHibernateCurrentHeader->actualRestore1Sum;
     gIOHibernateCurrentHeader->diag[0] = atop_64(headerPhys);
     gIOHibernateCurrentHeader->diag[1] = sum;
+    gIOHibernateCurrentHeader->trampolineTime = 0;
 
     uncompressedPages    = 0;
     conflictCount        = 0;
@@ -625,28 +619,27 @@ hibernate_kernel_entrypoint(uint32_t p1,
 
            if (!conflicts)
            {
-//              if (compressedSize)
-               time = rdtsc64();
                pageSum = store_one_page(gIOHibernateCurrentHeader->processorFlags,
                                         src, compressedSize, 0, ppnum);
-                gIOHibernateCurrentHeader->restoreTime2 += (rdtsc64() - time);
                if (stage != 2)
                    sum += pageSum;
                uncompressedPages++;
            }
            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
@@ -662,15 +655,10 @@ hibernate_kernel_entrypoint(uint32_t p1,
                    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);
@@ -682,8 +670,6 @@ hibernate_kernel_entrypoint(uint32_t p1,
 
     // -- copy back conflicts
 
-    time = rdtsc64();
-
     pageListPage = copyPageListHeadPage;
     while (pageListPage)
     {
@@ -707,8 +693,6 @@ hibernate_kernel_entrypoint(uint32_t p1,
 
     pal_hib_patchup();
 
-    gIOHibernateCurrentHeader->restoreTime3 = (rdtsc64() - time);
-
     // -- image has been destroyed...
 
     gIOHibernateCurrentHeader->actualImage1Sum         = sum;
@@ -718,7 +702,9 @@ hibernate_kernel_entrypoint(uint32_t p1,
 
     gIOHibernateState = kIOHibernateStateWakingFromHibernate;
 
-    gIOHibernateCurrentHeader->restoreTime1 = (rdtsc64() - timeStart);
+    gIOHibernateCurrentHeader->trampolineTime = (((rdtsc64() - timeStart)) >> 8);
+
+//  debug_code('done', 0);
 
 #if CONFIG_SLEEP
 #if defined(__i386__) || defined(__x86_64__)