Commit 988578886e0b9af507a7ef111f549c5dd47d93f3
1 parent
c4c7e3e6
fixed tlb invalidation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@555 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
19 additions
and
2 deletions
exec.c
| @@ -36,6 +36,7 @@ | @@ -36,6 +36,7 @@ | ||
| 36 | 36 | ||
| 37 | /* make various TB consistency checks */ | 37 | /* make various TB consistency checks */ |
| 38 | //#define DEBUG_TB_CHECK | 38 | //#define DEBUG_TB_CHECK |
| 39 | +//#define DEBUG_TLB_CHECK | ||
| 39 | 40 | ||
| 40 | /* threshold to flush the translated code buffer */ | 41 | /* threshold to flush the translated code buffer */ |
| 41 | #define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE) | 42 | #define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE) |
| @@ -766,12 +767,26 @@ void tb_link(TranslationBlock *tb) | @@ -766,12 +767,26 @@ void tb_link(TranslationBlock *tb) | ||
| 766 | /* save the code memory mappings (needed to invalidate the code) */ | 767 | /* save the code memory mappings (needed to invalidate the code) */ |
| 767 | addr = tb->pc & TARGET_PAGE_MASK; | 768 | addr = tb->pc & TARGET_PAGE_MASK; |
| 768 | vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS); | 769 | vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS); |
| 770 | +#ifdef DEBUG_TLB_CHECK | ||
| 771 | + if (vp->valid_tag == virt_valid_tag && | ||
| 772 | + vp->phys_addr != tb->page_addr[0]) { | ||
| 773 | + printf("Error tb addr=0x%x phys=0x%x vp->phys_addr=0x%x\n", | ||
| 774 | + addr, tb->page_addr[0], vp->phys_addr); | ||
| 775 | + } | ||
| 776 | +#endif | ||
| 769 | vp->phys_addr = tb->page_addr[0]; | 777 | vp->phys_addr = tb->page_addr[0]; |
| 770 | vp->valid_tag = virt_valid_tag; | 778 | vp->valid_tag = virt_valid_tag; |
| 771 | 779 | ||
| 772 | if (tb->page_addr[1] != -1) { | 780 | if (tb->page_addr[1] != -1) { |
| 773 | addr += TARGET_PAGE_SIZE; | 781 | addr += TARGET_PAGE_SIZE; |
| 774 | vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS); | 782 | vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS); |
| 783 | +#ifdef DEBUG_TLB_CHECK | ||
| 784 | + if (vp->valid_tag == virt_valid_tag && | ||
| 785 | + vp->phys_addr != tb->page_addr[1]) { | ||
| 786 | + printf("Error tb addr=0x%x phys=0x%x vp->phys_addr=0x%x\n", | ||
| 787 | + addr, tb->page_addr[1], vp->phys_addr); | ||
| 788 | + } | ||
| 789 | +#endif | ||
| 775 | vp->phys_addr = tb->page_addr[1]; | 790 | vp->phys_addr = tb->page_addr[1]; |
| 776 | vp->valid_tag = virt_valid_tag; | 791 | vp->valid_tag = virt_valid_tag; |
| 777 | } | 792 | } |
| @@ -1057,6 +1072,7 @@ void tlb_flush_page(CPUState *env, uint32_t addr) | @@ -1057,6 +1072,7 @@ void tlb_flush_page(CPUState *env, uint32_t addr) | ||
| 1057 | tb = tb->page_next[n]; | 1072 | tb = tb->page_next[n]; |
| 1058 | } | 1073 | } |
| 1059 | } | 1074 | } |
| 1075 | + vp->valid_tag = 0; | ||
| 1060 | } | 1076 | } |
| 1061 | 1077 | ||
| 1062 | #if !defined(CONFIG_SOFTMMU) | 1078 | #if !defined(CONFIG_SOFTMMU) |
| @@ -1069,7 +1085,8 @@ static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr) | @@ -1069,7 +1085,8 @@ static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr) | ||
| 1069 | { | 1085 | { |
| 1070 | if (addr == (tlb_entry->address & | 1086 | if (addr == (tlb_entry->address & |
| 1071 | (TARGET_PAGE_MASK | TLB_INVALID_MASK)) && | 1087 | (TARGET_PAGE_MASK | TLB_INVALID_MASK)) && |
| 1072 | - (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_CODE) { | 1088 | + (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_CODE && |
| 1089 | + (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_ROM) { | ||
| 1073 | tlb_entry->address |= IO_MEM_CODE; | 1090 | tlb_entry->address |= IO_MEM_CODE; |
| 1074 | tlb_entry->addend -= (unsigned long)phys_ram_base; | 1091 | tlb_entry->addend -= (unsigned long)phys_ram_base; |
| 1075 | } | 1092 | } |
| @@ -1139,7 +1156,7 @@ static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr) | @@ -1139,7 +1156,7 @@ static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr) | ||
| 1139 | tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr); | 1156 | tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr); |
| 1140 | } | 1157 | } |
| 1141 | 1158 | ||
| 1142 | -/* add a new TLB entry. At most a single entry for a given virtual | 1159 | +/* add a new TLB entry. At most one entry for a given virtual |
| 1143 | address is permitted. */ | 1160 | address is permitted. */ |
| 1144 | int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot, | 1161 | int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot, |
| 1145 | int is_user, int is_softmmu) | 1162 | int is_user, int is_softmmu) |