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 | 36 | |
37 | 37 | /* make various TB consistency checks */ |
38 | 38 | //#define DEBUG_TB_CHECK |
39 | +//#define DEBUG_TLB_CHECK | |
39 | 40 | |
40 | 41 | /* threshold to flush the translated code buffer */ |
41 | 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 | 767 | /* save the code memory mappings (needed to invalidate the code) */ |
767 | 768 | addr = tb->pc & TARGET_PAGE_MASK; |
768 | 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 | 777 | vp->phys_addr = tb->page_addr[0]; |
770 | 778 | vp->valid_tag = virt_valid_tag; |
771 | 779 | |
772 | 780 | if (tb->page_addr[1] != -1) { |
773 | 781 | addr += TARGET_PAGE_SIZE; |
774 | 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 | 790 | vp->phys_addr = tb->page_addr[1]; |
776 | 791 | vp->valid_tag = virt_valid_tag; |
777 | 792 | } |
... | ... | @@ -1057,6 +1072,7 @@ void tlb_flush_page(CPUState *env, uint32_t addr) |
1057 | 1072 | tb = tb->page_next[n]; |
1058 | 1073 | } |
1059 | 1074 | } |
1075 | + vp->valid_tag = 0; | |
1060 | 1076 | } |
1061 | 1077 | |
1062 | 1078 | #if !defined(CONFIG_SOFTMMU) |
... | ... | @@ -1069,7 +1085,8 @@ static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr) |
1069 | 1085 | { |
1070 | 1086 | if (addr == (tlb_entry->address & |
1071 | 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 | 1090 | tlb_entry->address |= IO_MEM_CODE; |
1074 | 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 | 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 | 1160 | address is permitted. */ |
1144 | 1161 | int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot, |
1145 | 1162 | int is_user, int is_softmmu) | ... | ... |