/[qemu]/qemu/exec.c
ViewVC logotype

Diff of /qemu/exec.c

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

revision 1.60 by bellard, Sun Apr 24 18:02:38 2005 UTC revision 1.61 by bellard, Sun Jul 24 10:17:31 2005 UTC
# Line 83  typedef struct PhysPageDesc { Line 83  typedef struct PhysPageDesc {
83      uint32_t phys_offset;      uint32_t phys_offset;
84  } PhysPageDesc;  } PhysPageDesc;
85    
86    /* Note: the VirtPage handling is absolete and will be suppressed
87       ASAP */
88  typedef struct VirtPageDesc {  typedef struct VirtPageDesc {
89      /* physical address of code page. It is valid only if 'valid_tag'      /* physical address of code page. It is valid only if 'valid_tag'
90         matches 'virt_valid_tag' */         matches 'virt_valid_tag' */
# Line 113  static PageDesc *l1_map[L1_SIZE]; Line 115  static PageDesc *l1_map[L1_SIZE];
115  PhysPageDesc **l1_phys_map;  PhysPageDesc **l1_phys_map;
116    
117  #if !defined(CONFIG_USER_ONLY)  #if !defined(CONFIG_USER_ONLY)
118    #if TARGET_LONG_BITS > 32
119    #define VIRT_L_BITS 9
120    #define VIRT_L_SIZE (1 << VIRT_L_BITS)
121    static void *l1_virt_map[VIRT_L_SIZE];
122    #else
123  static VirtPageDesc *l1_virt_map[L1_SIZE];  static VirtPageDesc *l1_virt_map[L1_SIZE];
124    #endif
125  static unsigned int virt_valid_tag;  static unsigned int virt_valid_tag;
126  #endif  #endif
127    
# Line 234  static inline PhysPageDesc *phys_page_fi Line 242  static inline PhysPageDesc *phys_page_fi
242  static void tlb_protect_code(CPUState *env, target_ulong addr);  static void tlb_protect_code(CPUState *env, target_ulong addr);
243  static void tlb_unprotect_code_phys(CPUState *env, unsigned long phys_addr, target_ulong vaddr);  static void tlb_unprotect_code_phys(CPUState *env, unsigned long phys_addr, target_ulong vaddr);
244    
245  static inline VirtPageDesc *virt_page_find_alloc(unsigned int index)  static VirtPageDesc *virt_page_find_alloc(target_ulong index, int alloc)
246  {  {
     VirtPageDesc **lp, *p;  
   
     /* XXX: should not truncate for 64 bit addresses */  
247  #if TARGET_LONG_BITS > 32  #if TARGET_LONG_BITS > 32
248      index &= (L1_SIZE - 1);      void **p, **lp;
249  #endif  
250        p = l1_virt_map;
251        lp = p + ((index >> (5 * VIRT_L_BITS)) & (VIRT_L_SIZE - 1));
252        p = *lp;
253        if (!p) {
254            if (!alloc)
255                return NULL;
256            p = qemu_mallocz(sizeof(void *) * VIRT_L_SIZE);
257            *lp = p;
258        }
259        lp = p + ((index >> (4 * VIRT_L_BITS)) & (VIRT_L_SIZE - 1));
260        p = *lp;
261        if (!p) {
262            if (!alloc)
263                return NULL;
264            p = qemu_mallocz(sizeof(void *) * VIRT_L_SIZE);
265            *lp = p;
266        }
267        lp = p + ((index >> (3 * VIRT_L_BITS)) & (VIRT_L_SIZE - 1));
268        p = *lp;
269        if (!p) {
270            if (!alloc)
271                return NULL;
272            p = qemu_mallocz(sizeof(void *) * VIRT_L_SIZE);
273            *lp = p;
274        }
275        lp = p + ((index >> (2 * VIRT_L_BITS)) & (VIRT_L_SIZE - 1));
276        p = *lp;
277        if (!p) {
278            if (!alloc)
279                return NULL;
280            p = qemu_mallocz(sizeof(void *) * VIRT_L_SIZE);
281            *lp = p;
282        }
283        lp = p + ((index >> (1 * VIRT_L_BITS)) & (VIRT_L_SIZE - 1));
284        p = *lp;
285        if (!p) {
286            if (!alloc)
287                return NULL;
288            p = qemu_mallocz(sizeof(VirtPageDesc) * VIRT_L_SIZE);
289            *lp = p;
290        }
291        return ((VirtPageDesc *)p) + (index & (VIRT_L_SIZE - 1));
292    #else
293        VirtPageDesc *p, **lp;
294    
295      lp = &l1_virt_map[index >> L2_BITS];      lp = &l1_virt_map[index >> L2_BITS];
296      p = *lp;      p = *lp;
297      if (!p) {      if (!p) {
298          /* allocate if not found */          /* allocate if not found */
299          p = qemu_malloc(sizeof(VirtPageDesc) * L2_SIZE);          if (!alloc)
300          memset(p, 0, sizeof(VirtPageDesc) * L2_SIZE);              return NULL;
301            p = qemu_mallocz(sizeof(VirtPageDesc) * L2_SIZE);
302          *lp = p;          *lp = p;
303      }      }
304      return p + (index & (L2_SIZE - 1));      return p + (index & (L2_SIZE - 1));
305    #endif
306  }  }
307    
308  static inline VirtPageDesc *virt_page_find(unsigned int index)  static inline VirtPageDesc *virt_page_find(target_ulong index)
309  {  {
310      VirtPageDesc *p;      return virt_page_find_alloc(index, 0);
311    }
312    
313      p = l1_virt_map[index >> L2_BITS];  #if TARGET_LONG_BITS > 32
314      if (!p)  static void virt_page_flush_internal(void **p, int level)
315          return 0;  {
316      return p + (index & (L2_SIZE - 1));      int i;
317        if (level == 0) {
318            VirtPageDesc *q = (VirtPageDesc *)p;
319            for(i = 0; i < VIRT_L_SIZE; i++)
320                q[i].valid_tag = 0;
321        } else {
322            level--;
323            for(i = 0; i < VIRT_L_SIZE; i++) {
324                if (p[i])
325                    virt_page_flush_internal(p[i], level);
326            }
327        }
328  }  }
329    #endif
330    
331  static void virt_page_flush(void)  static void virt_page_flush(void)
332  {  {
     int i, j;  
     VirtPageDesc *p;  
       
333      virt_valid_tag++;      virt_valid_tag++;
334    
335      if (virt_valid_tag == 0) {      if (virt_valid_tag == 0) {
336          virt_valid_tag = 1;          virt_valid_tag = 1;
337          for(i = 0; i < L1_SIZE; i++) {  #if TARGET_LONG_BITS > 32
338              p = l1_virt_map[i];          virt_page_flush_internal(l1_virt_map, 5);
339              if (p) {  #else
340                  for(j = 0; j < L2_SIZE; j++)          {
341                      p[j].valid_tag = 0;              int i, j;
342                VirtPageDesc *p;
343                for(i = 0; i < L1_SIZE; i++) {
344                    p = l1_virt_map[i];
345                    if (p) {
346                        for(j = 0; j < L2_SIZE; j++)
347                            p[j].valid_tag = 0;
348                    }
349              }              }
350          }          }
351    #endif
352      }      }
353  }  }
354  #else  #else
# Line 945  void tb_link(TranslationBlock *tb) Line 1015  void tb_link(TranslationBlock *tb)
1015                    
1016          /* save the code memory mappings (needed to invalidate the code) */          /* save the code memory mappings (needed to invalidate the code) */
1017          addr = tb->pc & TARGET_PAGE_MASK;          addr = tb->pc & TARGET_PAGE_MASK;
1018          vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS);          vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
1019  #ifdef DEBUG_TLB_CHECK  #ifdef DEBUG_TLB_CHECK
1020          if (vp->valid_tag == virt_valid_tag &&          if (vp->valid_tag == virt_valid_tag &&
1021              vp->phys_addr != tb->page_addr[0]) {              vp->phys_addr != tb->page_addr[0]) {
# Line 963  void tb_link(TranslationBlock *tb) Line 1033  void tb_link(TranslationBlock *tb)
1033                    
1034          if (tb->page_addr[1] != -1) {          if (tb->page_addr[1] != -1) {
1035              addr += TARGET_PAGE_SIZE;              addr += TARGET_PAGE_SIZE;
1036              vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS);              vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
1037  #ifdef DEBUG_TLB_CHECK  #ifdef DEBUG_TLB_CHECK
1038              if (vp->valid_tag == virt_valid_tag &&              if (vp->valid_tag == virt_valid_tag &&
1039                  vp->phys_addr != tb->page_addr[1]) {                  vp->phys_addr != tb->page_addr[1]) {
# Line 1572  int tlb_set_page(CPUState *env, target_u Line 1642  int tlb_set_page(CPUState *env, target_u
1642              addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);              addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
1643          }          }
1644                    
1645          index = (vaddr >> 12) & (CPU_TLB_SIZE - 1);          index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1646          addend -= vaddr;          addend -= vaddr;
1647          if (prot & PAGE_READ) {          if (prot & PAGE_READ) {
1648              env->tlb_read[is_user][index].address = address;              env->tlb_read[is_user][index].address = address;
# Line 1635  int tlb_set_page(CPUState *env, target_u Line 1705  int tlb_set_page(CPUState *env, target_u
1705                             original mapping */                             original mapping */
1706                          VirtPageDesc *vp;                          VirtPageDesc *vp;
1707                                                    
1708                          vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS);                          vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1);
1709                          vp->phys_addr = pd;                          vp->phys_addr = pd;
1710                          vp->prot = prot;                          vp->prot = prot;
1711                          vp->valid_tag = virt_valid_tag;                          vp->valid_tag = virt_valid_tag;

Legend:
Removed from v.1.60  
changed lines
  Added in v.1.61

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