]> Git Repo - qemu.git/blobdiff - arch_init.c
Merge branch 'for-upstream' of git://repo.or.cz/qemu/agraf
[qemu.git] / arch_init.c
index 5df84048a29b0bb475c562c3dcd4e57e42553008..2366511a6f698cb214e170af13882cb3be8bc463 100644 (file)
@@ -95,14 +95,30 @@ const uint32_t arch_type = QEMU_ARCH;
 #define RAM_SAVE_FLAG_EOS      0x10
 #define RAM_SAVE_FLAG_CONTINUE 0x20
 
-static int is_dup_page(uint8_t *page, uint8_t ch)
+#ifdef __ALTIVEC__
+#include <altivec.h>
+#define VECTYPE        vector unsigned char
+#define SPLAT(p)       vec_splat(vec_ld(0, p), 0)
+#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
+#elif defined __SSE2__
+#include <emmintrin.h>
+#define VECTYPE        __m128i
+#define SPLAT(p)       _mm_set1_epi8(*(p))
+#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
+#else
+#define VECTYPE        unsigned long
+#define SPLAT(p)       (*(p) * (~0UL / 255))
+#define ALL_EQ(v1, v2) ((v1) == (v2))
+#endif
+
+static int is_dup_page(uint8_t *page)
 {
-    uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
-    uint32_t *array = (uint32_t *)page;
+    VECTYPE *p = (VECTYPE *)page;
+    VECTYPE val = SPLAT(page);
     int i;
 
-    for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
-        if (array[i] != val) {
+    for (i = 0; i < TARGET_PAGE_SIZE / sizeof(VECTYPE); i++) {
+        if (!ALL_EQ(val, p[i])) {
             return 0;
         }
     }
@@ -134,7 +150,7 @@ static int ram_save_block(QEMUFile *f)
 
             p = memory_region_get_ram_ptr(mr) + offset;
 
-            if (is_dup_page(p, *p)) {
+            if (is_dup_page(p)) {
                 qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
                 if (!cont) {
                     qemu_put_byte(f, strlen(block->idstr));
@@ -251,7 +267,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
     int ret;
 
     if (stage < 0) {
-        cpu_physical_memory_set_dirty_tracking(0);
+        memory_global_dirty_log_stop();
         return 0;
     }
 
@@ -269,13 +285,12 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
             for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
                 if (!memory_region_get_dirty(block->mr, addr,
                                              DIRTY_MEMORY_MIGRATION)) {
-                    memory_region_set_dirty(block->mr, addr);
+                    memory_region_set_dirty(block->mr, addr, TARGET_PAGE_SIZE);
                 }
             }
         }
 
-        /* Enable dirty memory tracking */
-        cpu_physical_memory_set_dirty_tracking(1);
+        memory_global_dirty_log_start();
 
         qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
 
@@ -320,7 +335,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
         while ((bytes_sent = ram_save_block(f)) != 0) {
             bytes_transferred += bytes_sent;
         }
-        cpu_physical_memory_set_dirty_tracking(0);
+        memory_global_dirty_log_stop();
     }
 
     qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
@@ -344,7 +359,7 @@ static inline void *host_from_stream_offset(QEMUFile *f,
             return NULL;
         }
 
-        return block->host + offset;
+        return memory_region_get_ram_ptr(block->mr) + offset;
     }
 
     len = qemu_get_byte(f);
@@ -353,7 +368,7 @@ static inline void *host_from_stream_offset(QEMUFile *f,
 
     QLIST_FOREACH(block, &ram_list.blocks, next) {
         if (!strncmp(id, block->idstr, sizeof(id)))
-            return block->host + offset;
+            return memory_region_get_ram_ptr(block->mr) + offset;
     }
 
     fprintf(stderr, "Can't find block %s!\n", id);
@@ -366,7 +381,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
     int flags;
     int error;
 
-    if (version_id < 3 || version_id > 4) {
+    if (version_id < 4 || version_id > 4) {
         return -EINVAL;
     }
 
@@ -377,11 +392,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
         addr &= TARGET_PAGE_MASK;
 
         if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
-            if (version_id == 3) {
-                if (addr != ram_bytes_total()) {
-                    return -EINVAL;
-                }
-            } else {
+            if (version_id == 4) {
                 /* Synchronize RAM block list */
                 char id[256];
                 ram_addr_t length;
@@ -419,10 +430,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
             void *host;
             uint8_t ch;
 
-            if (version_id == 3)
-                host = qemu_get_ram_ptr(addr);
-            else
-                host = host_from_stream_offset(f, addr, flags);
+            host = host_from_stream_offset(f, addr, flags);
             if (!host) {
                 return -EINVAL;
             }
@@ -438,10 +446,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
         } else if (flags & RAM_SAVE_FLAG_PAGE) {
             void *host;
 
-            if (version_id == 3)
-                host = qemu_get_ram_ptr(addr);
-            else
-                host = host_from_stream_offset(f, addr, flags);
+            host = host_from_stream_offset(f, addr, flags);
 
             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
         }
This page took 0.029426 seconds and 4 git commands to generate.