/[qemu]/qemu/target-i386/helper2.c
ViewVC logotype

Diff of /qemu/target-i386/helper2.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by bellard, Tue Sep 30 20:33:28 2003 UTC revision 1.2 by bellard, Mon Oct 27 21:22:23 2003 UTC
# Line 210  void cpu_x86_flush_tlb(CPUX86State *env, Line 210  void cpu_x86_flush_tlb(CPUX86State *env,
210      flags = page_get_flags(addr);      flags = page_get_flags(addr);
211      if (flags & PAGE_VALID) {      if (flags & PAGE_VALID) {
212          virt_addr = addr & ~0xfff;          virt_addr = addr & ~0xfff;
213    #if !defined(CONFIG_SOFTMMU)
214          munmap((void *)virt_addr, 4096);          munmap((void *)virt_addr, 4096);
215    #endif
216          page_set_flags(virt_addr, virt_addr + 4096, 0);          page_set_flags(virt_addr, virt_addr + 4096, 0);
217      }      }
218  }  }
# Line 221  void cpu_x86_flush_tlb(CPUX86State *env, Line 223  void cpu_x86_flush_tlb(CPUX86State *env,
223     1  = generate PF fault     1  = generate PF fault
224     2  = soft MMU activation required for this block     2  = soft MMU activation required for this block
225  */  */
226  int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)  int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
227                                 int is_write, int is_user, int is_softmmu)
228  {  {
229      uint8_t *pde_ptr, *pte_ptr;      uint8_t *pde_ptr, *pte_ptr;
230      uint32_t pde, pte, virt_addr;      uint32_t pde, pte, virt_addr;
231      int cpl, error_code, is_dirty, is_user, prot, page_size, ret;      int error_code, is_dirty, prot, page_size, ret;
232      unsigned long pd;      unsigned long pd;
233            
     cpl = env->hflags & HF_CPL_MASK;  
     is_user = (cpl == 3);  
       
234  #ifdef DEBUG_MMU  #ifdef DEBUG_MMU
235      printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n",      printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n",
236             addr, is_write, is_user, env->eip);             addr, is_write, is_user, env->eip);
# Line 252  int cpu_x86_handle_mmu_fault(CPUX86State Line 252  int cpu_x86_handle_mmu_fault(CPUX86State
252    
253      /* page directory entry */      /* page directory entry */
254      pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3));      pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3));
255      pde = ldl(pde_ptr);      pde = ldl_raw(pde_ptr);
256      if (!(pde & PG_PRESENT_MASK)) {      if (!(pde & PG_PRESENT_MASK)) {
257          error_code = 0;          error_code = 0;
258          goto do_fault;          goto do_fault;
# Line 274  int cpu_x86_handle_mmu_fault(CPUX86State Line 274  int cpu_x86_handle_mmu_fault(CPUX86State
274              pde |= PG_ACCESSED_MASK;              pde |= PG_ACCESSED_MASK;
275              if (is_dirty)              if (is_dirty)
276                  pde |= PG_DIRTY_MASK;                  pde |= PG_DIRTY_MASK;
277              stl(pde_ptr, pde);              stl_raw(pde_ptr, pde);
278          }          }
279                    
280          pte = pde & ~0x003ff000; /* align to 4MB */          pte = pde & ~0x003ff000; /* align to 4MB */
# Line 283  int cpu_x86_handle_mmu_fault(CPUX86State Line 283  int cpu_x86_handle_mmu_fault(CPUX86State
283      } else {      } else {
284          if (!(pde & PG_ACCESSED_MASK)) {          if (!(pde & PG_ACCESSED_MASK)) {
285              pde |= PG_ACCESSED_MASK;              pde |= PG_ACCESSED_MASK;
286              stl(pde_ptr, pde);              stl_raw(pde_ptr, pde);
287          }          }
288    
289          /* page directory entry */          /* page directory entry */
290          pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc));          pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc));
291          pte = ldl(pte_ptr);          pte = ldl_raw(pte_ptr);
292          if (!(pte & PG_PRESENT_MASK)) {          if (!(pte & PG_PRESENT_MASK)) {
293              error_code = 0;              error_code = 0;
294              goto do_fault;              goto do_fault;
# Line 308  int cpu_x86_handle_mmu_fault(CPUX86State Line 308  int cpu_x86_handle_mmu_fault(CPUX86State
308              pte |= PG_ACCESSED_MASK;              pte |= PG_ACCESSED_MASK;
309              if (is_dirty)              if (is_dirty)
310                  pte |= PG_DIRTY_MASK;                  pte |= PG_DIRTY_MASK;
311              stl(pte_ptr, pte);              stl_raw(pte_ptr, pte);
312          }          }
313          page_size = 4096;          page_size = 4096;
314          virt_addr = addr & ~0xfff;          virt_addr = addr & ~0xfff;
# Line 325  int cpu_x86_handle_mmu_fault(CPUX86State Line 325  int cpu_x86_handle_mmu_fault(CPUX86State
325      }      }
326            
327   do_mapping:   do_mapping:
328      if (env->hflags & HF_SOFTMMU_MASK) {  #if !defined(CONFIG_SOFTMMU)
329        if (is_softmmu)
330    #endif
331        {
332          unsigned long paddr, vaddr, address, addend, page_offset;          unsigned long paddr, vaddr, address, addend, page_offset;
333          int index;          int index;
334    
# Line 352  int cpu_x86_handle_mmu_fault(CPUX86State Line 355  int cpu_x86_handle_mmu_fault(CPUX86State
355              env->tlb_write[is_user][index].address = address;              env->tlb_write[is_user][index].address = address;
356              env->tlb_write[is_user][index].addend = addend;              env->tlb_write[is_user][index].addend = addend;
357          }          }
358            page_set_flags(vaddr, vaddr + TARGET_PAGE_SIZE,
359                           PAGE_VALID | PAGE_EXEC | prot);
360            ret = 0;
361      }      }
362      ret = 0;  #if !defined(CONFIG_SOFTMMU)
363      /* XXX: incorrect for 4MB pages */      else {
364      pd = physpage_find(pte & ~0xfff);          ret = 0;
365      if ((pd & 0xfff) != 0) {          /* XXX: incorrect for 4MB pages */
366          /* IO access: no mapping is done as it will be handled by the          pd = physpage_find(pte & ~0xfff);
367             soft MMU */          if ((pd & 0xfff) != 0) {
368          if (!(env->hflags & HF_SOFTMMU_MASK))              /* IO access: no mapping is done as it will be handled by the
369              ret = 2;                 soft MMU */
370      } else {              if (!(env->hflags & HF_SOFTMMU_MASK))
371          void *map_addr;                  ret = 2;
372          map_addr = mmap((void *)virt_addr, page_size, prot,          } else {
373                          MAP_SHARED | MAP_FIXED, phys_ram_fd, pd);              void *map_addr;
374          if (map_addr == MAP_FAILED) {              map_addr = mmap((void *)virt_addr, page_size, prot,
375              fprintf(stderr,                              MAP_SHARED | MAP_FIXED, phys_ram_fd, pd);
376                      "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",              if (map_addr == MAP_FAILED) {
377                      pte & ~0xfff, virt_addr);                  fprintf(stderr,
378              exit(1);                          "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
379          }                          pte & ~0xfff, virt_addr);
380                    exit(1);
381                }
382  #ifdef DEBUG_MMU  #ifdef DEBUG_MMU
383          printf("mmaping 0x%08x to virt 0x%08x pse=%d\n",              printf("mmaping 0x%08x to virt 0x%08x pse=%d\n",
384                 pte & ~0xfff, virt_addr, (page_size != 4096));                     pte & ~0xfff, virt_addr, (page_size != 4096));
385  #endif  #endif
386          page_set_flags(virt_addr, virt_addr + page_size,              page_set_flags(virt_addr, virt_addr + page_size,
387                         PAGE_VALID | PAGE_EXEC | prot);                             PAGE_VALID | PAGE_EXEC | prot);
388            }
389      }      }
390    #endif
391      return ret;      return ret;
392   do_fault_protect:   do_fault_protect:
393      error_code = PG_ERROR_P_MASK;      error_code = PG_ERROR_P_MASK;

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26