diff -r 271ffb1c12eb tools/ioemu/hw/xen_platform.c --- a/tools/ioemu/hw/xen_platform.c Fri Jan 26 18:38:40 2007 +0000 +++ b/tools/ioemu/hw/xen_platform.c Sat Jan 27 19:24:37 2007 +0800 @@ -31,19 +31,18 @@ extern FILE *logfile; static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val) { +#if defined(__i386__) || defined(__x86_64__) + mapcache_lock(); + qemu_invalidate_map_cache(); + mapcache_unlock(); +#endif return; -} - -static uint32_t platform_ioport_read(void *opaque, uint32_t addr) -{ - return 0; } static void platform_ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type) { - register_ioport_write(addr, 16, 4, platform_ioport_write, NULL); - register_ioport_read(addr, 16, 1, platform_ioport_read, NULL); + register_ioport_write(addr, 1, 1, platform_ioport_write, NULL); } static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr) diff -r 271ffb1c12eb tools/ioemu/target-i386-dm/exec-dm.c --- a/tools/ioemu/target-i386-dm/exec-dm.c Fri Jan 26 18:38:40 2007 +0000 +++ b/tools/ioemu/target-i386-dm/exec-dm.c Sat Jan 27 19:24:37 2007 +0800 @@ -129,18 +129,8 @@ int loglevel; int loglevel; -#if defined(__i386__) || defined(__x86_64__) -#define MAPCACHE -#endif - #ifdef MAPCACHE -#include -static pthread_mutex_t mapcache_mutex; -#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex) -#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex) -#else -#define mapcache_lock() ( (void)0 ) -#define mapcache_unlock() ( (void)0 ) +pthread_mutex_t mapcache_mutex; #endif diff -r 271ffb1c12eb tools/ioemu/vl.c --- a/tools/ioemu/vl.c Fri Jan 26 18:38:40 2007 +0000 +++ b/tools/ioemu/vl.c Sat Jan 27 19:24:37 2007 +0800 @@ -285,7 +285,7 @@ int register_ioport_write(int start, int for(i = start; i < start + length; i += size) { ioport_write_table[bsize][i] = func; if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) - hw_error("register_ioport_read: invalid opaque"); + hw_error("register_ioport_write: invalid opaque"); ioport_opaque[i] = opaque; } return 0; @@ -5826,6 +5826,10 @@ static struct map_cache *mapcache_entry; static struct map_cache *mapcache_entry; static unsigned long nr_buckets; +/* For most cases (>99.9%), the page address is the same. */ +static unsigned long last_address_index = ~0UL; +static uint8_t *last_address_vaddr; + static int qemu_map_cache_init(unsigned long nr_pages) { unsigned long max_pages = MAX_MCACHE_SIZE >> PAGE_SHIFT; @@ -5862,10 +5866,6 @@ uint8_t *qemu_map_cache(target_phys_addr unsigned long address_index = phys_addr >> MCACHE_BUCKET_SHIFT; unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1); - /* For most cases (>99.9%), the page address is the same. */ - static unsigned long last_address_index = ~0UL; - static uint8_t *last_address_vaddr; - if (address_index == last_address_index) return last_address_vaddr + address_offset; @@ -5904,6 +5904,30 @@ uint8_t *qemu_map_cache(target_phys_addr last_address_vaddr = entry->vaddr_base; return last_address_vaddr + address_offset; +} + +void qemu_invalidate_map_cache(void) +{ + unsigned long i; + + for (i = 0; i < nr_buckets; i++) { + struct map_cache *entry = &mapcache_entry[i]; + + if (entry->vaddr_base == NULL) + continue; + + errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE); + if (errno) { + fprintf(logfile, "unmap fails %d\n", errno); + exit(-1); + } + + entry->paddr_index = 0; + entry->vaddr_base = NULL; + } + + last_address_index = ~0UL; + last_address_vaddr = NULL; } #endif diff -r 271ffb1c12eb tools/ioemu/vl.h --- a/tools/ioemu/vl.h Fri Jan 26 18:38:40 2007 +0000 +++ b/tools/ioemu/vl.h Sat Jan 27 19:24:37 2007 +0800 @@ -158,6 +158,7 @@ extern FILE *logfile; #if defined(__i386__) || defined(__x86_64__) +#define MAPCACHE #if defined(__i386__) #define MAX_MCACHE_SIZE 0x40000000 /* 1GB max for x86 */ #define MCACHE_BUCKET_SHIFT 16 @@ -174,6 +175,17 @@ struct map_cache { }; uint8_t *qemu_map_cache(target_phys_addr_t phys_addr); +void qemu_invalidate_map_cache(void); +#endif + +#ifdef MAPCACHE +#include +extern pthread_mutex_t mapcache_mutex; +#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex) +#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex) +#else +#define mapcache_lock() ((void)0) +#define mapcache_unlock() ((void)0) #endif extern int xc_handle; diff -r 271ffb1c12eb unmodified_drivers/linux-2.6/platform-pci/platform-pci.c --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Fri Jan 26 18:38:40 2007 +0000 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Sat Jan 27 19:24:52 2007 +0800 @@ -214,6 +214,18 @@ static uint64_t get_callback_via(struct #endif } +#if defined(__i386__) || defined(__x86_64__) +/* the port for invalidating Qemu mapcache */ +static uint16_t qemu_invl_mapcache_port; + +/* tell Qemu to invalidate its mapcache */ +void qemu_invalidate_map_cache(void) +{ + outb(0, qemu_invl_mapcache_port); +} +EXPORT_SYMBOL(qemu_invalidate_map_cache); +#endif + static int __devinit platform_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -238,6 +250,10 @@ static int __devinit platform_pci_init(s printk(KERN_WARNING DRV_NAME ":no resources found\n"); return -ENOENT; } + +#if defined(__i386__) || defined(__x86_64__) + qemu_invl_mapcache_port = ioaddr; +#endif if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) {