Diff for /qemu/exec.c between versions 1.1.1.13 and 1.1.1.14

version 1.1.1.13, 2018/04/24 18:24:13 version 1.1.1.14, 2018/04/24 18:34:06
Line 23 Line 23
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/mman.h>  #include <sys/mman.h>
 #endif  #endif
 #include <stdlib.h>  
 #include <stdio.h>  
 #include <stdarg.h>  
 #include <string.h>  
 #include <errno.h>  
 #include <unistd.h>  
 #include <inttypes.h>  
   
   #include "qemu-common.h"
 #include "cpu.h"  #include "cpu.h"
 #include "exec-all.h"  #include "exec-all.h"
 #include "qemu-common.h"  
 #include "tcg.h"  #include "tcg.h"
 #include "hw/hw.h"  #include "hw/hw.h"
 #include "hw/qdev.h"  #include "hw/qdev.h"
Line 524  static void code_gen_alloc(unsigned long Line 517  static void code_gen_alloc(unsigned long
             exit(1);              exit(1);
         }          }
     }      }
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)  #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
       || defined(__DragonFly__) || defined(__OpenBSD__)
     {      {
         int flags;          int flags;
         void *addr = NULL;          void *addr = NULL;
Line 537  static void code_gen_alloc(unsigned long Line 531  static void code_gen_alloc(unsigned long
         /* Cannot map more than that */          /* Cannot map more than that */
         if (code_gen_buffer_size > (800 * 1024 * 1024))          if (code_gen_buffer_size > (800 * 1024 * 1024))
             code_gen_buffer_size = (800 * 1024 * 1024);              code_gen_buffer_size = (800 * 1024 * 1024);
   #elif defined(__sparc_v9__)
           // Map the buffer below 2G, so we can use direct calls and branches
           flags |= MAP_FIXED;
           addr = (void *) 0x60000000UL;
           if (code_gen_buffer_size > (512 * 1024 * 1024)) {
               code_gen_buffer_size = (512 * 1024 * 1024);
           }
 #endif  #endif
         code_gen_buffer = mmap(addr, code_gen_buffer_size,          code_gen_buffer = mmap(addr, code_gen_buffer_size,
                                PROT_WRITE | PROT_READ | PROT_EXEC,                                  PROT_WRITE | PROT_READ | PROT_EXEC, 
Line 1706  static QLIST_HEAD(memory_client_list, CP Line 1707  static QLIST_HEAD(memory_client_list, CP
     = QLIST_HEAD_INITIALIZER(memory_client_list);      = QLIST_HEAD_INITIALIZER(memory_client_list);
   
 static void cpu_notify_set_memory(target_phys_addr_t start_addr,  static void cpu_notify_set_memory(target_phys_addr_t start_addr,
                                   ram_addr_t size,                                    ram_addr_t size,
                                   ram_addr_t phys_offset)                                    ram_addr_t phys_offset)
 {  {
     CPUPhysMemoryClient *client;      CPUPhysMemoryClient *client;
     QLIST_FOREACH(client, &memory_client_list, list) {      QLIST_FOREACH(client, &memory_client_list, list) {
Line 1716  static void cpu_notify_set_memory(target Line 1717  static void cpu_notify_set_memory(target
 }  }
   
 static int cpu_notify_sync_dirty_bitmap(target_phys_addr_t start,  static int cpu_notify_sync_dirty_bitmap(target_phys_addr_t start,
                                         target_phys_addr_t end)                                          target_phys_addr_t end)
 {  {
     CPUPhysMemoryClient *client;      CPUPhysMemoryClient *client;
     QLIST_FOREACH(client, &memory_client_list, list) {      QLIST_FOREACH(client, &memory_client_list, list) {
Line 1803  int cpu_str_to_log_mask(const char *str) Line 1804  int cpu_str_to_log_mask(const char *str)
         p1 = strchr(p, ',');          p1 = strchr(p, ',');
         if (!p1)          if (!p1)
             p1 = p + strlen(p);              p1 = p + strlen(p);
         if(cmp1(p,p1-p,"all")) {          if(cmp1(p,p1-p,"all")) {
                 for(item = cpu_log_items; item->mask != 0; item++) {              for(item = cpu_log_items; item->mask != 0; item++) {
                         mask |= item->mask;                  mask |= item->mask;
                 }              }
         } else {          } else {
         for(item = cpu_log_items; item->mask != 0; item++) {              for(item = cpu_log_items; item->mask != 0; item++) {
             if (cmp1(p, p1 - p, item->name))                  if (cmp1(p, p1 - p, item->name))
                 goto found;                      goto found;
               }
               return 0;
         }          }
         return 0;  
         }  
     found:      found:
         mask |= item->mask;          mask |= item->mask;
         if (*p1 != ',')          if (*p1 != ',')
Line 1907  static inline void tlb_flush_jmp_cache(C Line 1908  static inline void tlb_flush_jmp_cache(C
        overlap the flushed page.  */         overlap the flushed page.  */
     i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);      i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
     memset (&env->tb_jmp_cache[i], 0,       memset (&env->tb_jmp_cache[i], 0, 
             TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));              TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
   
     i = tb_jmp_cache_hash_page(addr);      i = tb_jmp_cache_hash_page(addr);
     memset (&env->tb_jmp_cache[i], 0,       memset (&env->tb_jmp_cache[i], 0, 
             TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));              TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
 }  }
   
 static CPUTLBEntry s_cputlb_empty_entry = {  static CPUTLBEntry s_cputlb_empty_entry = {
Line 2037  void cpu_physical_memory_reset_dirty(ram Line 2038  void cpu_physical_memory_reset_dirty(ram
   
     /* we modify the TLB cache so that the dirty bit will be set again      /* we modify the TLB cache so that the dirty bit will be set again
        when accessing the range */         when accessing the range */
     start1 = (unsigned long)qemu_get_ram_ptr(start);      start1 = (unsigned long)qemu_safe_ram_ptr(start);
     /* Chek that we don't span multiple blocks - this breaks the      /* Chek that we don't span multiple blocks - this breaks the
        address comparisons below.  */         address comparisons below.  */
     if ((unsigned long)qemu_get_ram_ptr(end - 1) - start1      if ((unsigned long)qemu_safe_ram_ptr(end - 1) - start1
             != (end - 1) - start) {              != (end - 1) - start) {
         abort();          abort();
     }      }
Line 2085  static inline void tlb_update_dirty(CPUT Line 2086  static inline void tlb_update_dirty(CPUT
     if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {      if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
         p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)          p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
             + tlb_entry->addend);              + tlb_entry->addend);
         ram_addr = qemu_ram_addr_from_host(p);          ram_addr = qemu_ram_addr_from_host_nofail(p);
         if (!cpu_physical_memory_is_dirty(ram_addr)) {          if (!cpu_physical_memory_is_dirty(ram_addr)) {
             tlb_entry->addr_write |= TLB_NOTDIRTY;              tlb_entry->addr_write |= TLB_NOTDIRTY;
         }          }
Line 2173  void tlb_set_page(CPUState *env, target_ Line 2174  void tlb_set_page(CPUState *env, target_
         pd = p->phys_offset;          pd = p->phys_offset;
     }      }
 #if defined(DEBUG_TLB)  #if defined(DEBUG_TLB)
     printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",      printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
            vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);             " prot=%x idx=%d pd=0x%08lx\n",
              vaddr, paddr, prot, mmu_idx, pd);
 #endif  #endif
   
     address = vaddr;      address = vaddr;
Line 2687  static long gethugepagesize(const char * Line 2689  static long gethugepagesize(const char *
     int ret;      int ret;
   
     do {      do {
             ret = statfs(path, &fs);          ret = statfs(path, &fs);
     } while (ret != 0 && errno == EINTR);      } while (ret != 0 && errno == EINTR);
   
     if (ret != 0) {      if (ret != 0) {
             perror(path);          perror(path);
             return 0;          return 0;
     }      }
   
     if (fs.f_type != HUGETLBFS_MAGIC)      if (fs.f_type != HUGETLBFS_MAGIC)
             fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);          fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
   
     return fs.f_bsize;      return fs.f_bsize;
 }  }
Line 2715  static void *file_ram_alloc(RAMBlock *bl Line 2717  static void *file_ram_alloc(RAMBlock *bl
   
     hpagesize = gethugepagesize(path);      hpagesize = gethugepagesize(path);
     if (!hpagesize) {      if (!hpagesize) {
         return NULL;          return NULL;
     }      }
   
     if (memory < hpagesize) {      if (memory < hpagesize) {
Line 2728  static void *file_ram_alloc(RAMBlock *bl Line 2730  static void *file_ram_alloc(RAMBlock *bl
     }      }
   
     if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {      if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
         return NULL;          return NULL;
     }      }
   
     fd = mkstemp(filename);      fd = mkstemp(filename);
     if (fd < 0) {      if (fd < 0) {
         perror("unable to create backing store for hugepages");          perror("unable to create backing store for hugepages");
         free(filename);          free(filename);
         return NULL;          return NULL;
     }      }
     unlink(filename);      unlink(filename);
     free(filename);      free(filename);
Line 2749  static void *file_ram_alloc(RAMBlock *bl Line 2751  static void *file_ram_alloc(RAMBlock *bl
      * mmap will fail.       * mmap will fail.
      */       */
     if (ftruncate(fd, memory))      if (ftruncate(fd, memory))
         perror("ftruncate");          perror("ftruncate");
   
 #ifdef MAP_POPULATE  #ifdef MAP_POPULATE
     /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case      /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
Line 2762  static void *file_ram_alloc(RAMBlock *bl Line 2764  static void *file_ram_alloc(RAMBlock *bl
     area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);      area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 #endif  #endif
     if (area == MAP_FAILED) {      if (area == MAP_FAILED) {
         perror("file_ram_alloc: can't mmap RAM pages");          perror("file_ram_alloc: can't mmap RAM pages");
         close(fd);          close(fd);
         return (NULL);          return (NULL);
     }      }
     block->fd = fd;      block->fd = fd;
     return area;      return area;
Line 2809  static ram_addr_t last_ram_offset(void) Line 2811  static ram_addr_t last_ram_offset(void)
 }  }
   
 ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,  ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
                         ram_addr_t size, void *host)                                     ram_addr_t size, void *host)
 {  {
     RAMBlock *new_block, *block;      RAMBlock *new_block, *block;
   
Line 2833  ram_addr_t qemu_ram_alloc_from_ptr(Devic Line 2835  ram_addr_t qemu_ram_alloc_from_ptr(Devic
         }          }
     }      }
   
     new_block->host = host;      if (host) {
           new_block->host = host;
     new_block->offset = find_ram_offset(size);      } else {
     new_block->length = size;          if (mem_path) {
   
     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);  
   
     ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,  
                                        last_ram_offset() >> TARGET_PAGE_BITS);  
     memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),  
            0xff, size >> TARGET_PAGE_BITS);  
   
     if (kvm_enabled())  
         kvm_setup_guest_memory(new_block->host, size);  
   
     return new_block->offset;  
 }  
   
 ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size)  
 {  
     RAMBlock *new_block, *block;  
   
     size = TARGET_PAGE_ALIGN(size);  
     new_block = qemu_mallocz(sizeof(*new_block));  
   
     if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {  
         char *id = dev->parent_bus->info->get_dev_path(dev);  
         if (id) {  
             snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);  
             qemu_free(id);  
         }  
     }  
     pstrcat(new_block->idstr, sizeof(new_block->idstr), name);  
   
     QLIST_FOREACH(block, &ram_list.blocks, next) {  
         if (!strcmp(block->idstr, new_block->idstr)) {  
             fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",  
                     new_block->idstr);  
             abort();  
         }  
     }  
   
     if (mem_path) {  
 #if defined (__linux__) && !defined(TARGET_S390X)  #if defined (__linux__) && !defined(TARGET_S390X)
         new_block->host = file_ram_alloc(new_block, size, mem_path);              new_block->host = file_ram_alloc(new_block, size, mem_path);
         if (!new_block->host) {              if (!new_block->host) {
             new_block->host = qemu_vmalloc(size);                  new_block->host = qemu_vmalloc(size);
 #ifdef MADV_MERGEABLE                  qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
             madvise(new_block->host, size, MADV_MERGEABLE);              }
 #endif  
         }  
 #else  #else
         fprintf(stderr, "-mem-path option unsupported\n");              fprintf(stderr, "-mem-path option unsupported\n");
         exit(1);              exit(1);
 #endif  #endif
     } else {          } else {
 #if defined(TARGET_S390X) && defined(CONFIG_KVM)  #if defined(TARGET_S390X) && defined(CONFIG_KVM)
         /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */              /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */
         new_block->host = mmap((void*)0x1000000, size,              new_block->host = mmap((void*)0x1000000, size,
                                 PROT_EXEC|PROT_READ|PROT_WRITE,                                     PROT_EXEC|PROT_READ|PROT_WRITE,
                                 MAP_SHARED | MAP_ANONYMOUS, -1, 0);                                     MAP_SHARED | MAP_ANONYMOUS, -1, 0);
 #else  #else
         new_block->host = qemu_vmalloc(size);              new_block->host = qemu_vmalloc(size);
 #endif  
 #ifdef MADV_MERGEABLE  
         madvise(new_block->host, size, MADV_MERGEABLE);  
 #endif  #endif
               qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
           }
     }      }
   
     new_block->offset = find_ram_offset(size);      new_block->offset = find_ram_offset(size);
     new_block->length = size;      new_block->length = size;
   
Line 2917  ram_addr_t qemu_ram_alloc(DeviceState *d Line 2878  ram_addr_t qemu_ram_alloc(DeviceState *d
     return new_block->offset;      return new_block->offset;
 }  }
   
   ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size)
   {
       return qemu_ram_alloc_from_ptr(dev, name, size, NULL);
   }
   
 void qemu_ram_free(ram_addr_t addr)  void qemu_ram_free(ram_addr_t addr)
 {  {
     RAMBlock *block;      RAMBlock *block;
Line 2973  void *qemu_get_ram_ptr(ram_addr_t addr) Line 2939  void *qemu_get_ram_ptr(ram_addr_t addr)
     return NULL;      return NULL;
 }  }
   
 /* Some of the softmmu routines need to translate from a host pointer  /* Return a host pointer to ram allocated with qemu_ram_alloc.
    (typically a TLB entry) back to a ram offset.  */   * Same as qemu_get_ram_ptr but avoid reordering ramblocks.
 ram_addr_t qemu_ram_addr_from_host(void *ptr)   */
   void *qemu_safe_ram_ptr(ram_addr_t addr)
   {
       RAMBlock *block;
   
       QLIST_FOREACH(block, &ram_list.blocks, next) {
           if (addr - block->offset < block->length) {
               return block->host + (addr - block->offset);
           }
       }
   
       fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
       abort();
   
       return NULL;
   }
   
   int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {  {
     RAMBlock *block;      RAMBlock *block;
     uint8_t *host = ptr;      uint8_t *host = ptr;
   
     QLIST_FOREACH(block, &ram_list.blocks, next) {      QLIST_FOREACH(block, &ram_list.blocks, next) {
         if (host - block->host < block->length) {          if (host - block->host < block->length) {
             return block->offset + (host - block->host);              *ram_addr = block->offset + (host - block->host);
               return 0;
         }          }
     }      }
       return -1;
   }
   
     fprintf(stderr, "Bad ram pointer %p\n", ptr);  /* Some of the softmmu routines need to translate from a host pointer
     abort();     (typically a TLB entry) back to a ram offset.  */
   ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
   {
       ram_addr_t ram_addr;
   
     return 0;      if (qemu_ram_addr_from_host(ptr, &ram_addr)) {
           fprintf(stderr, "Bad ram pointer %p\n", ptr);
           abort();
       }
       return ram_addr;
 }  }
   
 static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)  static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
Line 3325  static int subpage_register (subpage_t * Line 3318  static int subpage_register (subpage_t *
     printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,      printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
            mmio, start, end, idx, eidx, memory);             mmio, start, end, idx, eidx, memory);
 #endif  #endif
       if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
           memory = IO_MEM_UNASSIGNED;
     memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);      memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     for (; idx <= eidx; idx++) {      for (; idx <= eidx; idx++) {
         mmio->sub_io_index[idx] = memory;          mmio->sub_io_index[idx] = memory;
Line 3344  static subpage_t *subpage_init (target_p Line 3339  static subpage_t *subpage_init (target_p
     mmio = qemu_mallocz(sizeof(subpage_t));      mmio = qemu_mallocz(sizeof(subpage_t));
   
     mmio->base = base;      mmio->base = base;
     subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio);      subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio,
                                               DEVICE_NATIVE_ENDIAN);
 #if defined(DEBUG_SUBPAGE)  #if defined(DEBUG_SUBPAGE)
     printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,      printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
            mmio, base, TARGET_PAGE_SIZE, subpage_memory);             mmio, base, TARGET_PAGE_SIZE, subpage_memory);
Line 3368  static int get_free_io_mem_idx(void) Line 3364  static int get_free_io_mem_idx(void)
     return -1;      return -1;
 }  }
   
   /*
    * Usually, devices operate in little endian mode. There are devices out
    * there that operate in big endian too. Each device gets byte swapped
    * mmio if plugged onto a CPU that does the other endianness.
    *
    * CPU          Device           swap?
    *
    * little       little           no
    * little       big              yes
    * big          little           yes
    * big          big              no
    */
   
   typedef struct SwapEndianContainer {
       CPUReadMemoryFunc *read[3];
       CPUWriteMemoryFunc *write[3];
       void *opaque;
   } SwapEndianContainer;
   
   static uint32_t swapendian_mem_readb (void *opaque, target_phys_addr_t addr)
   {
       uint32_t val;
       SwapEndianContainer *c = opaque;
       val = c->read[0](c->opaque, addr);
       return val;
   }
   
   static uint32_t swapendian_mem_readw(void *opaque, target_phys_addr_t addr)
   {
       uint32_t val;
       SwapEndianContainer *c = opaque;
       val = bswap16(c->read[1](c->opaque, addr));
       return val;
   }
   
   static uint32_t swapendian_mem_readl(void *opaque, target_phys_addr_t addr)
   {
       uint32_t val;
       SwapEndianContainer *c = opaque;
       val = bswap32(c->read[2](c->opaque, addr));
       return val;
   }
   
   static CPUReadMemoryFunc * const swapendian_readfn[3]={
       swapendian_mem_readb,
       swapendian_mem_readw,
       swapendian_mem_readl
   };
   
   static void swapendian_mem_writeb(void *opaque, target_phys_addr_t addr,
                                     uint32_t val)
   {
       SwapEndianContainer *c = opaque;
       c->write[0](c->opaque, addr, val);
   }
   
   static void swapendian_mem_writew(void *opaque, target_phys_addr_t addr,
                                     uint32_t val)
   {
       SwapEndianContainer *c = opaque;
       c->write[1](c->opaque, addr, bswap16(val));
   }
   
   static void swapendian_mem_writel(void *opaque, target_phys_addr_t addr,
                                     uint32_t val)
   {
       SwapEndianContainer *c = opaque;
       c->write[2](c->opaque, addr, bswap32(val));
   }
   
   static CPUWriteMemoryFunc * const swapendian_writefn[3]={
       swapendian_mem_writeb,
       swapendian_mem_writew,
       swapendian_mem_writel
   };
   
   static void swapendian_init(int io_index)
   {
       SwapEndianContainer *c = qemu_malloc(sizeof(SwapEndianContainer));
       int i;
   
       /* Swap mmio for big endian targets */
       c->opaque = io_mem_opaque[io_index];
       for (i = 0; i < 3; i++) {
           c->read[i] = io_mem_read[io_index][i];
           c->write[i] = io_mem_write[io_index][i];
   
           io_mem_read[io_index][i] = swapendian_readfn[i];
           io_mem_write[io_index][i] = swapendian_writefn[i];
       }
       io_mem_opaque[io_index] = c;
   }
   
   static void swapendian_del(int io_index)
   {
       if (io_mem_read[io_index][0] == swapendian_readfn[0]) {
           qemu_free(io_mem_opaque[io_index]);
       }
   }
   
 /* mem_read and mem_write are arrays of functions containing the  /* mem_read and mem_write are arrays of functions containing the
    function to access byte (index 0), word (index 1) and dword (index     function to access byte (index 0), word (index 1) and dword (index
    2). Functions can be omitted with a NULL function pointer.     2). Functions can be omitted with a NULL function pointer.
Line 3378  static int get_free_io_mem_idx(void) Line 3474  static int get_free_io_mem_idx(void)
 static int cpu_register_io_memory_fixed(int io_index,  static int cpu_register_io_memory_fixed(int io_index,
                                         CPUReadMemoryFunc * const *mem_read,                                          CPUReadMemoryFunc * const *mem_read,
                                         CPUWriteMemoryFunc * const *mem_write,                                          CPUWriteMemoryFunc * const *mem_write,
                                         void *opaque)                                          void *opaque, enum device_endian endian)
 {  {
     int i;      int i;
   
Line 3402  static int cpu_register_io_memory_fixed( Line 3498  static int cpu_register_io_memory_fixed(
     }      }
     io_mem_opaque[io_index] = opaque;      io_mem_opaque[io_index] = opaque;
   
       switch (endian) {
       case DEVICE_BIG_ENDIAN:
   #ifndef TARGET_WORDS_BIGENDIAN
           swapendian_init(io_index);
   #endif
           break;
       case DEVICE_LITTLE_ENDIAN:
   #ifdef TARGET_WORDS_BIGENDIAN
           swapendian_init(io_index);
   #endif
           break;
       case DEVICE_NATIVE_ENDIAN:
       default:
           break;
       }
   
     return (io_index << IO_MEM_SHIFT);      return (io_index << IO_MEM_SHIFT);
 }  }
   
 int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,  int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
                            CPUWriteMemoryFunc * const *mem_write,                             CPUWriteMemoryFunc * const *mem_write,
                            void *opaque)                             void *opaque, enum device_endian endian)
 {  {
     return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque);      return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque, endian);
 }  }
   
 void cpu_unregister_io_memory(int io_table_address)  void cpu_unregister_io_memory(int io_table_address)
Line 3417  void cpu_unregister_io_memory(int io_tab Line 3529  void cpu_unregister_io_memory(int io_tab
     int i;      int i;
     int io_index = io_table_address >> IO_MEM_SHIFT;      int io_index = io_table_address >> IO_MEM_SHIFT;
   
       swapendian_del(io_index);
   
     for (i=0;i < 3; i++) {      for (i=0;i < 3; i++) {
         io_mem_read[io_index][i] = unassigned_mem_read[i];          io_mem_read[io_index][i] = unassigned_mem_read[i];
         io_mem_write[io_index][i] = unassigned_mem_write[i];          io_mem_write[io_index][i] = unassigned_mem_write[i];
Line 3429  static void io_mem_init(void) Line 3543  static void io_mem_init(void)
 {  {
     int i;      int i;
   
     cpu_register_io_memory_fixed(IO_MEM_ROM, error_mem_read, unassigned_mem_write, NULL);      cpu_register_io_memory_fixed(IO_MEM_ROM, error_mem_read,
     cpu_register_io_memory_fixed(IO_MEM_UNASSIGNED, unassigned_mem_read, unassigned_mem_write, NULL);                                   unassigned_mem_write, NULL,
     cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read, notdirty_mem_write, NULL);                                   DEVICE_NATIVE_ENDIAN);
       cpu_register_io_memory_fixed(IO_MEM_UNASSIGNED, unassigned_mem_read,
                                    unassigned_mem_write, NULL,
                                    DEVICE_NATIVE_ENDIAN);
       cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read,
                                    notdirty_mem_write, NULL,
                                    DEVICE_NATIVE_ENDIAN);
     for (i=0; i<5; i++)      for (i=0; i<5; i++)
         io_mem_used[i] = 1;          io_mem_used[i] = 1;
   
     io_mem_watch = cpu_register_io_memory(watch_mem_read,      io_mem_watch = cpu_register_io_memory(watch_mem_read,
                                           watch_mem_write, NULL);                                            watch_mem_write, NULL,
                                             DEVICE_NATIVE_ENDIAN);
 }  }
   
 #endif /* !defined(CONFIG_USER_ONLY) */  #endif /* !defined(CONFIG_USER_ONLY) */
Line 3736  void cpu_physical_memory_unmap(void *buf Line 3857  void cpu_physical_memory_unmap(void *buf
 {  {
     if (buffer != bounce.buffer) {      if (buffer != bounce.buffer) {
         if (is_write) {          if (is_write) {
             ram_addr_t addr1 = qemu_ram_addr_from_host(buffer);              ram_addr_t addr1 = qemu_ram_addr_from_host_nofail(buffer);
             while (access_len) {              while (access_len) {
                 unsigned l;                  unsigned l;
                 l = TARGET_PAGE_SIZE;                  l = TARGET_PAGE_SIZE;
Line 4121  void cpu_io_recompile(CPUState *env, voi Line 4242  void cpu_io_recompile(CPUState *env, voi
   
 #if !defined(CONFIG_USER_ONLY)  #if !defined(CONFIG_USER_ONLY)
   
 void dump_exec_info(FILE *f,  void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...))  
 {  {
     int i, target_code_size, max_target_code_size;      int i, target_code_size, max_target_code_size;
     int direct_jmp_count, direct_jmp2_count, cross_page;      int direct_jmp_count, direct_jmp2_count, cross_page;
Line 4149  void dump_exec_info(FILE *f, Line 4269  void dump_exec_info(FILE *f,
     }      }
     /* XXX: avoid using doubles ? */      /* XXX: avoid using doubles ? */
     cpu_fprintf(f, "Translation buffer state:\n");      cpu_fprintf(f, "Translation buffer state:\n");
     cpu_fprintf(f, "gen code size       %ld/%ld\n",      cpu_fprintf(f, "gen code size       %td/%ld\n",
                 code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);                  code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);
     cpu_fprintf(f, "TB count            %d/%d\n",       cpu_fprintf(f, "TB count            %d/%d\n", 
                 nb_tbs, code_gen_max_blocks);                  nb_tbs, code_gen_max_blocks);
     cpu_fprintf(f, "TB avg target size  %d max=%d bytes\n",      cpu_fprintf(f, "TB avg target size  %d max=%d bytes\n",
                 nb_tbs ? target_code_size / nb_tbs : 0,                  nb_tbs ? target_code_size / nb_tbs : 0,
                 max_target_code_size);                  max_target_code_size);
     cpu_fprintf(f, "TB avg host size    %d bytes (expansion ratio: %0.1f)\n",      cpu_fprintf(f, "TB avg host size    %td bytes (expansion ratio: %0.1f)\n",
                 nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,                  nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
                 target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);                  target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
     cpu_fprintf(f, "cross page TB count %d (%d%%)\n",      cpu_fprintf(f, "cross page TB count %d (%d%%)\n",

Removed from v.1.1.1.13  
changed lines
  Added in v.1.1.1.14


unix.superglobalmegacorp.com