ia64: make buffered pio aware of save/restore.
authorKeir Fraser <keir@xensource.com>
Mon, 22 Oct 2007 08:42:49 +0000 (09:42 +0100)
committerKeir Fraser <keir@xensource.com>
Mon, 22 Oct 2007 08:42:49 +0000 (09:42 +0100)
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
tools/ioemu/hw/ide.c
tools/ioemu/target-i386-dm/helper2.c
tools/ioemu/vl.h

index f5e796171ff146c5465696fdc82814354308d1e2..6faeb4dfce2c2e207e05cc1422b05ddc6fcb02b2 100644 (file)
@@ -430,17 +430,22 @@ buffered_pio_init(void)
     p2->page_offset = off2;
 }
 
+static inline void
+__buffered_pio_flush(struct pio_buffer *piobuf, IDEState *s, uint32_t pointer)
+{
+    uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
+    memcpy(s->data_ptr, buf, pointer);
+    s->data_ptr += pointer;
+}
+
 static inline void
 buffered_pio_flush(struct pio_buffer *piobuf)
 {
     IDEState *s = piobuf->opaque;
     uint32_t pointer = piobuf->pointer;
 
-    if (s != NULL && pointer > 0) {
-        uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
-        memcpy(s->data_ptr, buf, pointer);
-        s->data_ptr += pointer;
-    }
+    if (s != NULL && pointer > 0)
+        __buffered_pio_flush(piobuf, s, pointer);
 }
 
 static inline void
@@ -502,6 +507,54 @@ buffered_pio_read(IDEState *s, uint32_t addr, int size)
     piobuf->opaque = NULL;
 }
 
+/*
+ * buffered pio reads are undone. It results in normal pio when the domain
+ * is restored.
+ * buffered pio writes are handled before saving domain.
+ * However currently pci_ide_save/load() just discards a pending transfer. XXX
+ */
+static void
+__handle_buffered_pio(struct pio_buffer *piobuf)
+{
+    IDEState *s = piobuf->opaque;
+    uint32_t pointer = piobuf->pointer;
+
+    
+    if (pointer == 0)
+        return;/* no buffered pio */
+
+    if (s != NULL) {
+        /* written data are pending in pio_buffer. process it */
+        __buffered_pio_flush(piobuf, s, pointer);
+    } else {
+        /* data are buffered for pio read in pio_buffer.
+         * undone buffering by buffered_pio_read()
+         */
+        if (pointer > s->data_ptr - s->io_buffer)
+            pointer = s->data_ptr - s->io_buffer;
+        s->data_ptr -= pointer;
+    }
+       
+    piobuf->pointer = 0;
+    piobuf->data_end = 0;
+    piobuf->opaque = NULL;
+}
+
+void
+handle_buffered_pio(void)
+{
+    struct pio_buffer *p1, *p2;
+
+    if (!buffered_pio_page)
+        return;
+
+    p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
+    p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
+
+    __handle_buffered_pio(p1);
+    __handle_buffered_pio(p2);
+}
+
 #else /* !__ia64__ */
 #define buffered_pio_init()         do {} while (0)
 #define buffered_pio_reset(I)       do {} while (0)
index 070109a6cdce0ea99ec3cc833e9c7b25937abfdf..cc37867de64e694a8ce4429caa20c87ab1a974e4 100644 (file)
@@ -635,6 +635,7 @@ int main_loop(void)
         fprintf(logfile, "device model saving state\n");
 
         /* Pull all outstanding ioreqs through the system */
+        handle_buffered_pio();
         handle_buffered_io(env);
         main_loop_wait(1); /* For the select() on events */
 
index b087e20c0075d6f821787baa4f4a3f5b3d55caca..fd80d023c73b93c0e3c015f5e17d1f0158d5b0c6 100644 (file)
@@ -1494,8 +1494,11 @@ static inline void xc_domain_shutdown_hook(int xc_handle, uint32_t domid)
 {
        xc_ia64_save_to_nvram(xc_handle, domid);
 }
+
+void handle_buffered_pio(void);
 #else
 #define xc_domain_shutdown_hook(xc_handle, domid)      do {} while (0)
+#define handle_buffered_pio()                          do {} while (0)
 #endif
 
 #endif /* VL_H */