ia64/xen-unstable

changeset 9583:8d08ad8256df

HVM patch to add pio IOREQ_WRITE OVERLAP/REPZ support in hvm io.c
hvm_pio_assist(). Also, cleaned up a bit of duplicate code in the
functions. Simple guest tests (ide pio) pass now for overlapped/rep
write operations.

Signed-off-by: Tom Woller <thomas.woller@amd.com>
Signed-off-by: Mats Petersson <mats.petersson@amd.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Apr 04 15:05:17 2006 +0100 (2006-04-04)
parents 887ff2d1e382
children 7086a4e96ce0
files xen/arch/x86/hvm/io.c
line diff
     1.1 --- a/xen/arch/x86/hvm/io.c	Tue Apr 04 15:00:41 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/io.c	Tue Apr 04 15:05:17 2006 +0100
     1.3 @@ -365,29 +365,42 @@ static void hvm_pio_assist(struct cpu_us
     1.4      unsigned long old_eax;
     1.5      int sign = p->df ? -1 : 1;
     1.6  
     1.7 -    if (p->dir == IOREQ_WRITE) {
     1.8 -        if (p->pdata_valid) {
     1.9 -            regs->esi += sign * p->count * p->size;
    1.10 -            if (mmio_opp->flags & REPZ)
    1.11 -                regs->ecx -= p->count;
    1.12 -        }
    1.13 -    } else {
    1.14 -        if (mmio_opp->flags & OVERLAP) {
    1.15 -            unsigned long addr;
    1.16 -
    1.17 +    if (p->pdata_valid || (mmio_opp->flags & OVERLAP)) {
    1.18 +        if (mmio_opp->flags & REPZ)
    1.19 +            regs->ecx -= p->count;
    1.20 +        if (p->dir == IOREQ_READ) {
    1.21              regs->edi += sign * p->count * p->size;
    1.22 -            if (mmio_opp->flags & REPZ)
    1.23 -                regs->ecx -= p->count;
    1.24  
    1.25 -            addr = regs->edi;
    1.26 -            if (sign > 0)
    1.27 -                addr -= p->size;
    1.28 -            hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
    1.29 -        } else if (p->pdata_valid) {
    1.30 -            regs->edi += sign * p->count * p->size;
    1.31 -            if (mmio_opp->flags & REPZ)
    1.32 -                regs->ecx -= p->count;
    1.33 -        } else {
    1.34 +            if (mmio_opp->flags & OVERLAP) {
    1.35 +                /* 
    1.36 +                 * If we are doing in IN and it's overlapping a page boundary, 
    1.37 +                 * we need to copy the data back to user's page with hvm_copy. 
    1.38 +                 * Note that overlap * can only be set with paging enabled, so 
    1.39 +                 * we don't need to worry about * real-mode stuff.  
    1.40 +                 */
    1.41 +                unsigned long addr;
    1.42 +                {
    1.43 +                    /* 
    1.44 +		     * We completely ignore segment registers here - 
    1.45 +                     * it's not a good idea. We also may use upper bits
    1.46 +                     * in edi when in 16-bit real/protected mode.
    1.47 +                     * We really need to get the actual address back from
    1.48 +                     * the arch-dependant HVM portion.
    1.49 +                     */
    1.50 +                    struct vcpu *v = current;
    1.51 +                    if (hvm_realmode(v))
    1.52 +                        __hvm_bug(regs);
    1.53 +                }
    1.54 +                addr = regs->edi;
    1.55 +                if (sign > 0)
    1.56 +                    addr -= p->size;
    1.57 +                hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
    1.58 +            }
    1.59 +        } else
    1.60 +            regs->esi += sign * p->count * p->size;
    1.61 +
    1.62 +    } else {
    1.63 +        if (p->dir == IOREQ_READ) {
    1.64              old_eax = regs->eax;
    1.65              switch (p->size) {
    1.66              case 1: