3/3 add a bufferring mechanism for IDE PIO in a hypervisor.
Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
diff -r 2d3ceb082114 xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c Mon Feb 26 09:13:50 2007 +0000
+++ b/xen/arch/ia64/vmx/mmio.c Tue Feb 27 13:27:24 2007 +0900
@@ -136,6 +136,56 @@ static void low_mmio_access(VCPU *vcpu,
}
return;
}
+
+int vmx_ide_pio_intercept(ioreq_t *p, u64 *val)
+{
+ struct buffered_piopage *pio_page =
+ (void *)(current->domain->arch.hvm_domain.buffered_pio_va);
+ struct pio_buffer *piobuf;
+ uint32_t pointer, page_offset;
+
+ if (p->addr == 0x1F0)
+ piobuf = &pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
+ else if (p->addr == 0x170)
+ piobuf = &pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
+ else
+ return 0;
+
+ if (p->size != 2 && p->size != 4)
+ return 0;
+
+ pointer = piobuf->pointer;
+ page_offset = piobuf->page_offset;
+
+ /* sanity check */
+ if (page_offset + pointer < offsetof(struct buffered_piopage, buffer))
+ return 0;
+ if (page_offset + piobuf->data_end > PAGE_SIZE)
+ return 0;
+
+ if (pointer + p->size < piobuf->data_end) {
+ uint8_t *bufp = (uint8_t *)pio_page + page_offset + pointer;
+ if (p->dir == IOREQ_WRITE) {
+ if (likely(p->size == 4 && (((long)bufp & 3) == 0)))
+ *(uint32_t *)bufp = *val;
+ else
+ memcpy(bufp, val, p->size);
+ } else {
+ if (likely(p->size == 4 && (((long)bufp & 3) == 0))) {
+ *val = *(uint32_t *)bufp;
+ } else {
+ *val = 0;
+ memcpy(val, bufp, p->size);
+ }
+ }
+ piobuf->pointer += p->size;
+ p->state = STATE_IORESP_READY;
+ vmx_io_assist(current);
+ return 1;
+ }
+ return 0;
+}
+
#define TO_LEGACY_IO(pa) (((pa)>>12<<2)|((pa)&0x3))
static void legacy_io_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir)
@@ -160,6 +210,9 @@ static void legacy_io_access(VCPU *vcpu,
p->df = 0;
p->io_count++;
+
+ if (vmx_ide_pio_intercept(p, val))
+ return;
vmx_send_assist_req(v);
if(dir==IOREQ_READ){ //read
diff -r 2d3ceb082114 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Mon Feb 26 09:13:50 2007 +0000
+++ b/xen/arch/ia64/vmx/vmx_init.c Tue Feb 27 13:27:24 2007 +0900
@@ -390,6 +390,8 @@ void vmx_setup_platform(struct domain *d
spin_lock_init(&d->arch.hvm_domain.buffered_io_lock);
d->arch.hvm_domain.buffered_io_va =
(unsigned long)__va(__gpa_to_mpa(d, BUFFER_IO_PAGE_START));
+ d->arch.hvm_domain.buffered_pio_va =
+ (unsigned long)__va(__gpa_to_mpa(d, BUFFER_PIO_PAGE_START));
/* TEMP */
d->arch.vmx_platform.pib_base = 0xfee00000UL;
diff -r 2d3ceb082114 xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h Mon Feb 26 09:13:50 2007 +0000
+++ b/xen/include/asm-ia64/vmx_platform.h Tue Feb 27 13:27:24 2007 +0900
@@ -24,8 +24,9 @@
#include <asm/viosapic.h>
struct mmio_list;
typedef struct virtual_platform_def {
- unsigned long buffered_io_va;
- spinlock_t buffered_io_lock;
+ unsigned long buffered_io_va;
+ spinlock_t buffered_io_lock;
+ unsigned long buffered_pio_va;
unsigned long shared_page_va;
unsigned long pib_base;
unsigned long params[HVM_NR_PARAMS];
diff -r 2d3ceb082114 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h Mon Feb 26 09:13:50 2007 +0000
+++ b/xen/include/public/arch-ia64.h Tue Feb 27 13:27:24 2007 +0900
@@ -91,10 +91,13 @@ typedef unsigned long xen_ulong_t;
#define IO_PAGE_SIZE PAGE_SIZE
#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
-#define STORE_PAGE_SIZE PAGE_SIZE
-
-#define BUFFER_IO_PAGE_START (STORE_PAGE_START+PAGE_SIZE)
+#define STORE_PAGE_SIZE PAGE_SIZE
+
+#define BUFFER_IO_PAGE_START (STORE_PAGE_START+STORE_PAGE_SIZE)
#define BUFFER_IO_PAGE_SIZE PAGE_SIZE
+
+#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START+BUFFER_IO_PAGE_SIZE)
+#define BUFFER_PIO_PAGE_SIZE PAGE_SIZE
#define IO_SAPIC_START 0xfec00000UL
#define IO_SAPIC_SIZE 0x100000
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|