ne2000 buffer fulness fix (Han Zhu)
[qemu] / exec.c
diff --git a/exec.c b/exec.c
index 2a13c59..f900e09 100644 (file)
--- a/exec.c
+++ b/exec.c
 //#define DEBUG_TB_CHECK 
 //#define DEBUG_TLB_CHECK 
 
+#if !defined(CONFIG_USER_ONLY)
+/* TB consistency checks only implemented for usermode emulation.  */
+#undef DEBUG_TB_CHECK
+#endif
+
 /* threshold to flush the translated code buffer */
 #define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
 
@@ -204,6 +209,7 @@ static inline PageDesc *page_find(unsigned int index)
 static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
 {
     void **lp, **p;
+    PhysPageDesc *pd;
 
     p = (void **)l1_phys_map;
 #if TARGET_PHYS_ADDR_SPACE_BITS > 32
@@ -223,16 +229,18 @@ static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
     }
 #endif
     lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
-    p = *lp;
-    if (!p) {
+    pd = *lp;
+    if (!pd) {
+        int i;
         /* allocate if not found */
         if (!alloc)
             return NULL;
-        p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
-        memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);
-        *lp = p;
+        pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
+        *lp = pd;
+        for (i = 0; i < L2_SIZE; i++)
+          pd[i].phys_offset = IO_MEM_UNASSIGNED;
     }
-    return ((PhysPageDesc *)p) + (index & (L2_SIZE - 1));
+    return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
 }
 
 static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
@@ -327,12 +335,12 @@ static void tb_invalidate_check(unsigned long address)
     TranslationBlock *tb;
     int i;
     address &= TARGET_PAGE_MASK;
-    for(i = 0;i < CODE_GEN_HASH_SIZE; i++) {
-        for(tb = tb_hash[i]; tb != NULL; tb = tb->hash_next) {
+    for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+        for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
             if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
                   address >= tb->pc + tb->size)) {
                 printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
-                       address, tb->pc, tb->size);
+                       address, (long)tb->pc, tb->size);
             }
         }
     }
@@ -344,13 +352,13 @@ static void tb_page_check(void)
     TranslationBlock *tb;
     int i, flags1, flags2;
     
-    for(i = 0;i < CODE_GEN_HASH_SIZE; i++) {
-        for(tb = tb_hash[i]; tb != NULL; tb = tb->hash_next) {
+    for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+        for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
             flags1 = page_get_flags(tb->pc);
             flags2 = page_get_flags(tb->pc + tb->size - 1);
             if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
                 printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
-                       tb->pc, tb->size, flags1, flags2);
+                       (long)tb->pc, tb->size, flags1, flags2);
             }
         }
     }
@@ -2072,6 +2080,45 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
     }
 }
 
+/* used for ROM loading : can write in RAM and ROM */
+void cpu_physical_memory_write_rom(target_phys_addr_t addr, 
+                                   const uint8_t *buf, int len)
+{
+    int l;
+    uint8_t *ptr;
+    target_phys_addr_t page;
+    unsigned long pd;
+    PhysPageDesc *p;
+    
+    while (len > 0) {
+        page = addr & TARGET_PAGE_MASK;
+        l = (page + TARGET_PAGE_SIZE) - addr;
+        if (l > len)
+            l = len;
+        p = phys_page_find(page >> TARGET_PAGE_BITS);
+        if (!p) {
+            pd = IO_MEM_UNASSIGNED;
+        } else {
+            pd = p->phys_offset;
+        }
+        
+        if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
+            (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM) {
+            /* do nothing */
+        } else {
+            unsigned long addr1;
+            addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
+            /* ROM/RAM case */
+            ptr = phys_ram_base + addr1;
+            memcpy(ptr, buf, l);
+        }
+        len -= l;
+        buf += l;
+        addr += l;
+    }
+}
+
+
 /* warning: addr must be aligned */
 uint32_t ldl_phys(target_phys_addr_t addr)
 {