diff options
author | Keir Fraser <keir@xensource.com> | 2007-10-22 09:42:49 +0100 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-10-22 09:42:49 +0100 |
commit | 808c9bd4900abb20da1b7d8da725766d97de2d3f (patch) | |
tree | c8a65baffa7b05eb89dc1ed7687993bf957d5cc4 /tools | |
parent | 1934a762f0ebd5b4f36b946815d36e2d6b5bd2bd (diff) | |
download | xen-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.c | 63 | ||||
-rw-r--r-- | tools/ioemu/target-i386-dm/helper2.c | 1 | ||||
-rw-r--r-- | tools/ioemu/vl.h | 3 |
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 */ |