ia64/xen-unstable

changeset 14161:b0f663e668d9

Accelerate IDE PIO on HVM/IA64 [1/3]

Add a bufferring mechanism for IDE PIO in qemu.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
author kfraser@localhost.localdomain
date Tue Feb 27 15:33:25 2007 +0000 (2007-02-27)
parents dd8c88744433
children e450a3b90aba
files tools/ioemu/hw/ide.c tools/ioemu/vl.c xen/include/public/hvm/ioreq.h
line diff
     1.1 --- a/tools/ioemu/hw/ide.c	Tue Feb 27 14:33:07 2007 +0000
     1.2 +++ b/tools/ioemu/hw/ide.c	Tue Feb 27 15:33:25 2007 +0000
     1.3 @@ -434,6 +434,121 @@ static void dma_create_thread(void)
     1.4  }
     1.5  #endif /* DMA_MULTI_THREAD */
     1.6  
     1.7 +#if defined(__ia64__)
     1.8 +#include <xen/hvm/ioreq.h>
     1.9 +
    1.10 +struct buffered_piopage *buffered_pio_page;
    1.11 +
    1.12 +static inline struct pio_buffer *
    1.13 +piobuf_by_addr(uint32_t addr)
    1.14 +{
    1.15 +    if (addr == 0x1F0)
    1.16 +        return &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
    1.17 +    if (addr == 0x170)
    1.18 +        return &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
    1.19 +    return NULL;
    1.20 +}
    1.21 +
    1.22 +static void
    1.23 +buffered_pio_init(void)
    1.24 +{
    1.25 +    struct pio_buffer *p1, *p2;
    1.26 +    uint32_t off1, off2;
    1.27 +
    1.28 +    if (!buffered_pio_page)
    1.29 +        return;
    1.30 +
    1.31 +    p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
    1.32 +    p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
    1.33 +    off1 = offsetof(struct buffered_piopage, buffer);
    1.34 +    off2 = (off1 + TARGET_PAGE_SIZE)/2;
    1.35 +
    1.36 +    p1->buf_size = off2 - off1;
    1.37 +    p1->page_offset = off1;
    1.38 +
    1.39 +    p2->buf_size = TARGET_PAGE_SIZE - off2;
    1.40 +    p2->page_offset = off2;
    1.41 +}
    1.42 +
    1.43 +static inline void
    1.44 +buffered_pio_flush(struct pio_buffer *piobuf)
    1.45 +{
    1.46 +    IDEState *s = piobuf->opaque;
    1.47 +    uint32_t pointer = piobuf->pointer;
    1.48 +
    1.49 +    if (s != NULL && pointer > 0) {
    1.50 +        uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
    1.51 +        memcpy(s->data_ptr, buf, pointer);
    1.52 +        s->data_ptr += pointer;
    1.53 +    }
    1.54 +}
    1.55 +
    1.56 +static inline void
    1.57 +buffered_pio_reset(IDEState *s)
    1.58 +{
    1.59 +    struct pio_buffer *piobuf;
    1.60 +
    1.61 +    if ((unsigned)s->drive_serial - 1 < 2)      /* 1,2 */
    1.62 +        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
    1.63 +    else if ((unsigned)s->drive_serial - 3 < 2) /* 3,4 */
    1.64 +        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
    1.65 +    else
    1.66 +        return;
    1.67 +    buffered_pio_flush(piobuf);
    1.68 +    piobuf->pointer = 0;
    1.69 +    piobuf->data_end = 0;
    1.70 +    piobuf->opaque = NULL;
    1.71 +}
    1.72 +
    1.73 +static inline void
    1.74 +buffered_pio_write(IDEState *s, uint32_t addr, int size)
    1.75 +{
    1.76 +    struct pio_buffer *piobuf = piobuf_by_addr(addr);
    1.77 +    uint32_t data_end;
    1.78 +
    1.79 +    if (!piobuf)
    1.80 +        return;
    1.81 +    buffered_pio_flush(piobuf);
    1.82 +    data_end = s->data_end - s->data_ptr - size;
    1.83 +    if (data_end <= 0)
    1.84 +        data_end = 0;
    1.85 +    else if (data_end > piobuf->buf_size)
    1.86 +        data_end = piobuf->buf_size;
    1.87 +    piobuf->pointer = 0;
    1.88 +    piobuf->data_end = data_end;
    1.89 +    piobuf->opaque = s;
    1.90 +}
    1.91 +
    1.92 +static inline void
    1.93 +buffered_pio_read(IDEState *s, uint32_t addr, int size)
    1.94 +{
    1.95 +    struct pio_buffer *piobuf = piobuf_by_addr(addr);
    1.96 +    uint32_t data_end;
    1.97 +
    1.98 +    if (!piobuf)
    1.99 +        return;
   1.100 +    s->data_ptr += piobuf->pointer;
   1.101 +    data_end = s->data_end - s->data_ptr - size;
   1.102 +    if (data_end <= 0) {
   1.103 +        data_end = 0;
   1.104 +    } else {
   1.105 +	uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
   1.106 +        if (data_end > piobuf->buf_size)
   1.107 +            data_end = piobuf->buf_size;
   1.108 +        memcpy(buf, s->data_ptr + size, data_end);
   1.109 +    }
   1.110 +    piobuf->pointer = 0;
   1.111 +    piobuf->data_end = data_end;
   1.112 +    piobuf->opaque = NULL;
   1.113 +}
   1.114 +
   1.115 +#else /* !__ia64__ */
   1.116 +#define buffered_pio_init()         do {} while (0)
   1.117 +#define buffered_pio_reset(I)       do {} while (0)
   1.118 +#define buffered_pio_write(I,A,S)   do {} while (0)
   1.119 +#define buffered_pio_read(I,A,S)    do {} while (0)
   1.120 +#endif
   1.121 +
   1.122  static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
   1.123  
   1.124  static void padstr(char *str, const char *src, int len)
   1.125 @@ -618,6 +733,7 @@ static void ide_transfer_start(IDEState 
   1.126      s->data_ptr = buf;
   1.127      s->data_end = buf + size;
   1.128      s->status |= DRQ_STAT;
   1.129 +    buffered_pio_reset(s);
   1.130  }
   1.131  
   1.132  static void ide_transfer_stop(IDEState *s)
   1.133 @@ -626,6 +742,7 @@ static void ide_transfer_stop(IDEState *
   1.134      s->data_ptr = s->io_buffer;
   1.135      s->data_end = s->io_buffer;
   1.136      s->status &= ~DRQ_STAT;
   1.137 +    buffered_pio_reset(s);
   1.138  }
   1.139  
   1.140  static int64_t ide_get_sector(IDEState *s)
   1.141 @@ -1562,6 +1679,7 @@ static void ide_ioport_write(void *opaqu
   1.142          ide_if[0].select = (val & ~0x10) | 0xa0;
   1.143          ide_if[1].select = (val | 0x10) | 0xa0;
   1.144          /* select drive */
   1.145 +        buffered_pio_reset(ide_if->cur_drive);
   1.146          unit = (val >> 4) & 1;
   1.147          s = ide_if + unit;
   1.148          ide_if->cur_drive = s;
   1.149 @@ -1928,6 +2046,7 @@ static void ide_data_writew(void *opaque
   1.150      IDEState *s = ((IDEState *)opaque)->cur_drive;
   1.151      uint8_t *p;
   1.152  
   1.153 +    buffered_pio_write(s, addr, 2);
   1.154      p = s->data_ptr;
   1.155      *(uint16_t *)p = le16_to_cpu(val);
   1.156      p += 2;
   1.157 @@ -1941,6 +2060,8 @@ static uint32_t ide_data_readw(void *opa
   1.158      IDEState *s = ((IDEState *)opaque)->cur_drive;
   1.159      uint8_t *p;
   1.160      int ret;
   1.161 +    
   1.162 +    buffered_pio_read(s, addr, 2);
   1.163      p = s->data_ptr;
   1.164      ret = cpu_to_le16(*(uint16_t *)p);
   1.165      p += 2;
   1.166 @@ -1955,6 +2076,7 @@ static void ide_data_writel(void *opaque
   1.167      IDEState *s = ((IDEState *)opaque)->cur_drive;
   1.168      uint8_t *p;
   1.169  
   1.170 +    buffered_pio_write(s, addr, 4);
   1.171      p = s->data_ptr;
   1.172      *(uint32_t *)p = le32_to_cpu(val);
   1.173      p += 4;
   1.174 @@ -1969,6 +2091,7 @@ static uint32_t ide_data_readl(void *opa
   1.175      uint8_t *p;
   1.176      int ret;
   1.177      
   1.178 +    buffered_pio_read(s, addr, 4);
   1.179      p = s->data_ptr;
   1.180      ret = cpu_to_le32(*(uint32_t *)p);
   1.181      p += 4;
   1.182 @@ -2517,6 +2640,8 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
   1.183      ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
   1.184      ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
   1.185  
   1.186 +    buffered_pio_init();
   1.187 +
   1.188      register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
   1.189  
   1.190  #ifdef DMA_MULTI_THREAD    
     2.1 --- a/tools/ioemu/vl.c	Tue Feb 27 14:33:07 2007 +0000
     2.2 +++ b/tools/ioemu/vl.c	Tue Feb 27 15:33:25 2007 +0000
     2.3 @@ -5972,6 +5972,7 @@ int main(int argc, char **argv)
     2.4      xen_pfn_t *page_array;
     2.5      extern void *shared_page;
     2.6      extern void *buffered_io_page;
     2.7 +    extern void *buffered_pio_page;
     2.8  
     2.9      char qemu_dm_logfilename[64];
    2.10  
    2.11 @@ -6576,6 +6577,10 @@ int main(int argc, char **argv)
    2.12                                         PROT_READ|PROT_WRITE,
    2.13                                         BUFFER_IO_PAGE_START >> PAGE_SHIFT);
    2.14  
    2.15 +    buffered_pio_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
    2.16 +                                       PROT_READ|PROT_WRITE,
    2.17 +                                       BUFFER_PIO_PAGE_START >> PAGE_SHIFT);
    2.18 +
    2.19      for (i = 0; i < tmp_nr_pages; i++)
    2.20          page_array[i] = i;
    2.21  	
     3.1 --- a/xen/include/public/hvm/ioreq.h	Tue Feb 27 14:33:07 2007 +0000
     3.2 +++ b/xen/include/public/hvm/ioreq.h	Tue Feb 27 15:33:25 2007 +0000
     3.3 @@ -81,9 +81,29 @@ struct buffered_iopage {
     3.4  };            /* sizeof this structure must be in one page */
     3.5  typedef struct buffered_iopage buffered_iopage_t;
     3.6  
     3.7 +#if defined(__ia64__)
     3.8 +struct pio_buffer {
     3.9 +    uint32_t page_offset;
    3.10 +    uint32_t pointer;
    3.11 +    uint32_t data_end;
    3.12 +    uint32_t buf_size;
    3.13 +    void *opaque;
    3.14 +};
    3.15 +
    3.16 +#define PIO_BUFFER_IDE_PRIMARY   0 /* I/O port = 0x1F0 */
    3.17 +#define PIO_BUFFER_IDE_SECONDARY 1 /* I/O port = 0x170 */
    3.18 +#define PIO_BUFFER_ENTRY_NUM     2
    3.19 +struct buffered_piopage {
    3.20 +    struct pio_buffer pio[PIO_BUFFER_ENTRY_NUM];
    3.21 +    uint8_t buffer[1];
    3.22 +};
    3.23 +#endif /* defined(__ia64__) */
    3.24 +
    3.25 +#if defined(__i386__) || defined(__x86_64__)
    3.26  #define ACPI_PM1A_EVT_BLK_ADDRESS           0x0000000000001f40
    3.27  #define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
    3.28  #define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
    3.29 +#endif /* defined(__i386__) || defined(__x86_64__) */
    3.30  
    3.31  #endif /* _IOREQ_H_ */
    3.32