aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-10-22 09:42:49 +0100
committerKeir Fraser <keir@xensource.com>2007-10-22 09:42:49 +0100
commit808c9bd4900abb20da1b7d8da725766d97de2d3f (patch)
treec8a65baffa7b05eb89dc1ed7687993bf957d5cc4 /tools
parent1934a762f0ebd5b4f36b946815d36e2d6b5bd2bd (diff)
downloadxen-808c9bd4900abb20da1b7d8da725766d97de2d3f.tar.gz
xen-808c9bd4900abb20da1b7d8da725766d97de2d3f.tar.bz2
xen-808c9bd4900abb20da1b7d8da725766d97de2d3f.zip
ia64: make buffered pio aware of save/restore.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Diffstat (limited to 'tools')
-rw-r--r--tools/ioemu/hw/ide.c63
-rw-r--r--tools/ioemu/target-i386-dm/helper2.c1
-rw-r--r--tools/ioemu/vl.h3
3 files changed, 62 insertions, 5 deletions
diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c
index f5e796171f..6faeb4dfce 100644
--- a/tools/ioemu/hw/ide.c
+++ b/tools/ioemu/hw/ide.c
@@ -431,16 +431,21 @@ buffered_pio_init(void)
}
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)
diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c
index 070109a6cd..cc37867de6 100644
--- a/tools/ioemu/target-i386-dm/helper2.c
+++ b/tools/ioemu/target-i386-dm/helper2.c
@@ -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 */
diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h
index b087e20c00..fd80d023c7 100644
--- a/tools/ioemu/vl.h
+++ b/tools/ioemu/vl.h
@@ -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 */