WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-ia64-devel] [PATCH 1/3][IA64] Accelerate IDE PIO on HVM/IA64 : qemu

1/3 add a bufferring mechanism for IDE PIO in qemu.

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>

diff -r 2d3ceb082114 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c      Mon Feb 26 09:13:50 2007 +0000
+++ b/tools/ioemu/hw/ide.c      Tue Feb 27 13:27:24 2007 +0900
@@ -434,6 +434,121 @@ static void dma_create_thread(void)
 }
 #endif /* DMA_MULTI_THREAD */
 
+#if defined(__ia64__)
+#include <xen/hvm/ioreq.h>
+
+struct buffered_piopage *buffered_pio_page;
+
+static inline struct pio_buffer *
+piobuf_by_addr(uint32_t addr)
+{
+    if (addr == 0x1F0)
+        return &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
+    if (addr == 0x170)
+        return &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
+    return NULL;
+}
+
+static void
+buffered_pio_init(void)
+{
+    struct pio_buffer *p1, *p2;
+    uint32_t off1, off2;
+
+    if (!buffered_pio_page)
+        return;
+
+    p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
+    p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
+    off1 = offsetof(struct buffered_piopage, buffer);
+    off2 = (off1 + TARGET_PAGE_SIZE)/2;
+
+    p1->buf_size = off2 - off1;
+    p1->page_offset = off1;
+
+    p2->buf_size = TARGET_PAGE_SIZE - off2;
+    p2->page_offset = off2;
+}
+
+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;
+    }
+}
+
+static inline void
+buffered_pio_reset(IDEState *s)
+{
+    struct pio_buffer *piobuf;
+
+    if ((unsigned)s->drive_serial - 1 < 2)      /* 1,2 */
+        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
+    else if ((unsigned)s->drive_serial - 3 < 2) /* 3,4 */
+        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
+    else
+        return;
+    buffered_pio_flush(piobuf);
+    piobuf->pointer = 0;
+    piobuf->data_end = 0;
+    piobuf->opaque = NULL;
+}
+
+static inline void
+buffered_pio_write(IDEState *s, uint32_t addr, int size)
+{
+    struct pio_buffer *piobuf = piobuf_by_addr(addr);
+    uint32_t data_end;
+
+    if (!piobuf)
+        return;
+    buffered_pio_flush(piobuf);
+    data_end = s->data_end - s->data_ptr - size;
+    if (data_end <= 0)
+        data_end = 0;
+    else if (data_end > piobuf->buf_size)
+        data_end = piobuf->buf_size;
+    piobuf->pointer = 0;
+    piobuf->data_end = data_end;
+    piobuf->opaque = s;
+}
+
+static inline void
+buffered_pio_read(IDEState *s, uint32_t addr, int size)
+{
+    struct pio_buffer *piobuf = piobuf_by_addr(addr);
+    uint32_t data_end;
+
+    if (!piobuf)
+        return;
+    s->data_ptr += piobuf->pointer;
+    data_end = s->data_end - s->data_ptr - size;
+    if (data_end <= 0) {
+        data_end = 0;
+    } else {
+       uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
+        if (data_end > piobuf->buf_size)
+            data_end = piobuf->buf_size;
+        memcpy(buf, s->data_ptr + size, data_end);
+    }
+    piobuf->pointer = 0;
+    piobuf->data_end = data_end;
+    piobuf->opaque = NULL;
+}
+
+#else /* !__ia64__ */
+#define buffered_pio_init()         do {} while (0)
+#define buffered_pio_reset(I)       do {} while (0)
+#define buffered_pio_write(I,A,S)   do {} while (0)
+#define buffered_pio_read(I,A,S)    do {} while (0)
+#endif
+
 static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
 
 static void padstr(char *str, const char *src, int len)
@@ -618,6 +733,7 @@ static void ide_transfer_start(IDEState 
     s->data_ptr = buf;
     s->data_end = buf + size;
     s->status |= DRQ_STAT;
+    buffered_pio_reset(s);
 }
 
 static void ide_transfer_stop(IDEState *s)
@@ -626,6 +742,7 @@ static void ide_transfer_stop(IDEState *
     s->data_ptr = s->io_buffer;
     s->data_end = s->io_buffer;
     s->status &= ~DRQ_STAT;
+    buffered_pio_reset(s);
 }
 
 static int64_t ide_get_sector(IDEState *s)
@@ -1562,6 +1679,7 @@ static void ide_ioport_write(void *opaqu
         ide_if[0].select = (val & ~0x10) | 0xa0;
         ide_if[1].select = (val | 0x10) | 0xa0;
         /* select drive */
+        buffered_pio_reset(ide_if->cur_drive);
         unit = (val >> 4) & 1;
         s = ide_if + unit;
         ide_if->cur_drive = s;
@@ -1928,6 +2046,7 @@ static void ide_data_writew(void *opaque
     IDEState *s = ((IDEState *)opaque)->cur_drive;
     uint8_t *p;
 
+    buffered_pio_write(s, addr, 2);
     p = s->data_ptr;
     *(uint16_t *)p = le16_to_cpu(val);
     p += 2;
@@ -1941,6 +2060,8 @@ static uint32_t ide_data_readw(void *opa
     IDEState *s = ((IDEState *)opaque)->cur_drive;
     uint8_t *p;
     int ret;
+    
+    buffered_pio_read(s, addr, 2);
     p = s->data_ptr;
     ret = cpu_to_le16(*(uint16_t *)p);
     p += 2;
@@ -1955,6 +2076,7 @@ static void ide_data_writel(void *opaque
     IDEState *s = ((IDEState *)opaque)->cur_drive;
     uint8_t *p;
 
+    buffered_pio_write(s, addr, 4);
     p = s->data_ptr;
     *(uint32_t *)p = le32_to_cpu(val);
     p += 4;
@@ -1969,6 +2091,7 @@ static uint32_t ide_data_readl(void *opa
     uint8_t *p;
     int ret;
     
+    buffered_pio_read(s, addr, 4);
     p = s->data_ptr;
     ret = cpu_to_le32(*(uint32_t *)p);
     p += 4;
@@ -2517,6 +2640,8 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
     ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
     ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
 
+    buffered_pio_init();
+
     register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
 
 #ifdef DMA_MULTI_THREAD    
diff -r 2d3ceb082114 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Mon Feb 26 09:13:50 2007 +0000
+++ b/tools/ioemu/vl.c  Tue Feb 27 13:27:24 2007 +0900
@@ -5972,6 +5972,7 @@ int main(int argc, char **argv)
     xen_pfn_t *page_array;
     extern void *shared_page;
     extern void *buffered_io_page;
+    extern void *buffered_pio_page;
 
     char qemu_dm_logfilename[64];
 
@@ -6571,6 +6572,10 @@ int main(int argc, char **argv)
                                        PROT_READ|PROT_WRITE,
                                        BUFFER_IO_PAGE_START >> PAGE_SHIFT);
 
+    buffered_pio_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                       PROT_READ|PROT_WRITE,
+                                       BUFFER_PIO_PAGE_START >> PAGE_SHIFT);
+
     for (i = 0; i < tmp_nr_pages; i++)
         page_array[i] = i;
        
diff -r 2d3ceb082114 xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h    Mon Feb 26 09:13:50 2007 +0000
+++ b/xen/include/public/hvm/ioreq.h    Tue Feb 27 14:10:22 2007 +0900
@@ -81,6 +81,22 @@ struct buffered_iopage {
 };            /* sizeof this structure must be in one page */
 typedef struct buffered_iopage buffered_iopage_t;
 
+struct pio_buffer {
+    uint32_t page_offset;
+    uint32_t pointer;
+    uint32_t data_end;
+    uint32_t buf_size;
+    void *opaque;
+};
+
+#define PIO_BUFFER_IDE_PRIMARY   0 /* I/O port = 0x1F0 */
+#define PIO_BUFFER_IDE_SECONDARY 1 /* I/O port = 0x170 */
+#define PIO_BUFFER_ENTRY_NUM     2
+struct buffered_piopage {
+    struct pio_buffer pio[PIO_BUFFER_ENTRY_NUM];
+    uint8_t buffer[1];
+};
+
 #define ACPI_PM1A_EVT_BLK_ADDRESS           0x0000000000001f40
 #define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
 #define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel