diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-01-12 11:13:57 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-01-12 11:13:57 +0000 |
commit | bc6c5510dbaa5b3be862d28ee62e3acf6c35f0bb (patch) | |
tree | 7ebd131f56422eaf67302fcad0dfe2e46f843883 /xen/arch/x86/hvm/vpic.c | |
parent | 3790d2ab9b967c9c3dfdedb56c22bc01b07ffbc2 (diff) | |
download | xen-bc6c5510dbaa5b3be862d28ee62e3acf6c35f0bb.tar.gz xen-bc6c5510dbaa5b3be862d28ee62e3acf6c35f0bb.tar.bz2 xen-bc6c5510dbaa5b3be862d28ee62e3acf6c35f0bb.zip |
hvm: Improve in-Xen PIO emulation to better handle string PIO
instructions.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch/x86/hvm/vpic.c')
-rw-r--r-- | xen/arch/x86/hvm/vpic.c | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c index ab57cda5fb..3af6888e01 100644 --- a/xen/arch/x86/hvm/vpic.c +++ b/xen/arch/x86/hvm/vpic.c @@ -316,61 +316,45 @@ static uint32_t vpic_ioport_read(struct hvm_hw_vpic *vpic, uint32_t addr) return vpic->imr; } -static int vpic_intercept_pic_io(ioreq_t *p) +static int vpic_intercept_pic_io( + int dir, uint32_t port, uint32_t bytes, uint32_t *val) { struct hvm_hw_vpic *vpic; - uint32_t data; - if ( (p->size != 1) || (p->count != 1) ) + if ( bytes != 1 ) { - gdprintk(XENLOG_WARNING, "PIC_IO bad access size %d\n", (int)p->size); + gdprintk(XENLOG_WARNING, "PIC_IO bad access size %d\n", bytes); return 1; } - vpic = ¤t->domain->arch.hvm_domain.vpic[p->addr >> 7]; + vpic = ¤t->domain->arch.hvm_domain.vpic[port >> 7]; - if ( p->dir == IOREQ_WRITE ) - { - if ( p->data_is_ptr ) - (void)hvm_copy_from_guest_phys(&data, p->data, p->size); - else - data = p->data; - vpic_ioport_write(vpic, (uint32_t)p->addr, (uint8_t)data); - } + if ( dir == IOREQ_WRITE ) + vpic_ioport_write(vpic, port, (uint8_t)*val); else - { - data = vpic_ioport_read(vpic, (uint32_t)p->addr); - if ( p->data_is_ptr ) - (void)hvm_copy_to_guest_phys(p->data, &data, p->size); - else - p->data = (u64)data; - } + *val = (uint8_t)vpic_ioport_read(vpic, port); return 1; } -static int vpic_intercept_elcr_io(ioreq_t *p) +static int vpic_intercept_elcr_io( + int dir, uint32_t port, uint32_t bytes, uint32_t *val) { struct hvm_hw_vpic *vpic; uint32_t data; - if ( (p->size != 1) || (p->count != 1) ) + if ( bytes != 1 ) { - gdprintk(XENLOG_WARNING, "PIC_IO bad access size %d\n", (int)p->size); + gdprintk(XENLOG_WARNING, "PIC_IO bad access size %d\n", bytes); return 1; } - vpic = ¤t->domain->arch.hvm_domain.vpic[p->addr & 1]; + vpic = ¤t->domain->arch.hvm_domain.vpic[port & 1]; - if ( p->dir == IOREQ_WRITE ) + if ( dir == IOREQ_WRITE ) { - if ( p->data_is_ptr ) - (void)hvm_copy_from_guest_phys(&data, p->data, p->size); - else - data = p->data; - /* Some IRs are always edge trig. Slave IR is always level trig. */ - data &= vpic_elcr_mask(vpic); + data = *val & vpic_elcr_mask(vpic); if ( vpic->is_master ) data |= 1 << 2; vpic->elcr = data; @@ -378,12 +362,7 @@ static int vpic_intercept_elcr_io(ioreq_t *p) else { /* Reader should not see hardcoded level-triggered slave IR. */ - data = vpic->elcr & vpic_elcr_mask(vpic); - - if ( p->data_is_ptr ) - (void)hvm_copy_to_guest_phys(p->data, &data, p->size); - else - p->data = data; + *val = vpic->elcr & vpic_elcr_mask(vpic); } return 1; |