Commit b769d8fef6c06ddb39ef0337882a4f8872b9c2bc
1 parent
32ff25bf
removed access_type hack
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1095 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
9 changed files
with
89 additions
and
86 deletions
exec-all.h
... | ... | @@ -592,13 +592,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) |
592 | 592 | #endif |
593 | 593 | if (__builtin_expect(env->tlb_read[is_user][index].address != |
594 | 594 | (addr & TARGET_PAGE_MASK), 0)) { |
595 | -#if defined (TARGET_PPC) | |
596 | - env->access_type = ACCESS_CODE; | |
597 | - ldub_code((void *)addr); | |
598 | - env->access_type = ACCESS_INT; | |
599 | -#else | |
600 | 595 | ldub_code((void *)addr); |
601 | -#endif | |
602 | 596 | } |
603 | 597 | return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base; |
604 | 598 | } | ... | ... |
exec.c
... | ... | @@ -2115,6 +2115,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, |
2115 | 2115 | #define MMUSUFFIX _cmmu |
2116 | 2116 | #define GETPC() NULL |
2117 | 2117 | #define env cpu_single_env |
2118 | +#define SOFTMMU_CODE_ACCESS | |
2118 | 2119 | |
2119 | 2120 | #define SHIFT 0 |
2120 | 2121 | #include "softmmu_template.h" | ... | ... |
softmmu_template.h
... | ... | @@ -39,14 +39,15 @@ |
39 | 39 | #error unsupported data size |
40 | 40 | #endif |
41 | 41 | |
42 | +#ifdef SOFTMMU_CODE_ACCESS | |
43 | +#define READ_ACCESS_TYPE 2 | |
44 | +#else | |
45 | +#define READ_ACCESS_TYPE 0 | |
46 | +#endif | |
47 | + | |
42 | 48 | static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
43 | 49 | int is_user, |
44 | 50 | void *retaddr); |
45 | -static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, | |
46 | - DATA_TYPE val, | |
47 | - int is_user, | |
48 | - void *retaddr); | |
49 | - | |
50 | 51 | static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, |
51 | 52 | unsigned long tlb_addr) |
52 | 53 | { |
... | ... | @@ -68,29 +69,6 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, |
68 | 69 | return res; |
69 | 70 | } |
70 | 71 | |
71 | -static inline void glue(io_write, SUFFIX)(unsigned long physaddr, | |
72 | - DATA_TYPE val, | |
73 | - unsigned long tlb_addr, | |
74 | - void *retaddr) | |
75 | -{ | |
76 | - int index; | |
77 | - | |
78 | - index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); | |
79 | - env->mem_write_vaddr = tlb_addr; | |
80 | - env->mem_write_pc = (unsigned long)retaddr; | |
81 | -#if SHIFT <= 2 | |
82 | - io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val); | |
83 | -#else | |
84 | -#ifdef TARGET_WORDS_BIGENDIAN | |
85 | - io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32); | |
86 | - io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val); | |
87 | -#else | |
88 | - io_mem_write[index][2](io_mem_opaque[index], physaddr, val); | |
89 | - io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32); | |
90 | -#endif | |
91 | -#endif /* SHIFT > 2 */ | |
92 | -} | |
93 | - | |
94 | 72 | /* handle all cases except unaligned access which span two pages */ |
95 | 73 | DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
96 | 74 | int is_user) |
... | ... | @@ -125,7 +103,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
125 | 103 | } else { |
126 | 104 | /* the page is not in the TLB : fill it */ |
127 | 105 | retaddr = GETPC(); |
128 | - tlb_fill(addr, 0, is_user, retaddr); | |
106 | + tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); | |
129 | 107 | goto redo; |
130 | 108 | } |
131 | 109 | return res; |
... | ... | @@ -172,12 +150,41 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
172 | 150 | } |
173 | 151 | } else { |
174 | 152 | /* the page is not in the TLB : fill it */ |
175 | - tlb_fill(addr, 0, is_user, retaddr); | |
153 | + tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); | |
176 | 154 | goto redo; |
177 | 155 | } |
178 | 156 | return res; |
179 | 157 | } |
180 | 158 | |
159 | +#ifndef SOFTMMU_CODE_ACCESS | |
160 | + | |
161 | +static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, | |
162 | + DATA_TYPE val, | |
163 | + int is_user, | |
164 | + void *retaddr); | |
165 | + | |
166 | +static inline void glue(io_write, SUFFIX)(unsigned long physaddr, | |
167 | + DATA_TYPE val, | |
168 | + unsigned long tlb_addr, | |
169 | + void *retaddr) | |
170 | +{ | |
171 | + int index; | |
172 | + | |
173 | + index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); | |
174 | + env->mem_write_vaddr = tlb_addr; | |
175 | + env->mem_write_pc = (unsigned long)retaddr; | |
176 | +#if SHIFT <= 2 | |
177 | + io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val); | |
178 | +#else | |
179 | +#ifdef TARGET_WORDS_BIGENDIAN | |
180 | + io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32); | |
181 | + io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val); | |
182 | +#else | |
183 | + io_mem_write[index][2](io_mem_opaque[index], physaddr, val); | |
184 | + io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32); | |
185 | +#endif | |
186 | +#endif /* SHIFT > 2 */ | |
187 | +} | |
181 | 188 | |
182 | 189 | void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, |
183 | 190 | DATA_TYPE val, |
... | ... | @@ -257,6 +264,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, |
257 | 264 | } |
258 | 265 | } |
259 | 266 | |
267 | +#endif /* !defined(SOFTMMU_CODE_ACCESS) */ | |
268 | + | |
269 | +#undef READ_ACCESS_TYPE | |
260 | 270 | #undef SHIFT |
261 | 271 | #undef DATA_TYPE |
262 | 272 | #undef SUFFIX | ... | ... |
target-i386/helper2.c
... | ... | @@ -331,7 +331,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, |
331 | 331 | printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", |
332 | 332 | addr, is_write, is_user, env->eip); |
333 | 333 | #endif |
334 | - | |
334 | + is_write &= 1; | |
335 | + | |
335 | 336 | if (env->user_mode_only) { |
336 | 337 | /* user mode only emulation */ |
337 | 338 | error_code = 0; | ... | ... |
target-ppc/helper.c
... | ... | @@ -432,13 +432,13 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) |
432 | 432 | generated code */ |
433 | 433 | saved_env = env; |
434 | 434 | env = cpu_single_env; |
435 | +#if 0 | |
435 | 436 | { |
436 | 437 | unsigned long tlb_addrr, tlb_addrw; |
437 | 438 | int index; |
438 | 439 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
439 | 440 | tlb_addrr = env->tlb_read[is_user][index].address; |
440 | 441 | tlb_addrw = env->tlb_write[is_user][index].address; |
441 | -#if 0 | |
442 | 442 | if (loglevel) { |
443 | 443 | fprintf(logfile, |
444 | 444 | "%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " |
... | ... | @@ -447,8 +447,8 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) |
447 | 447 | tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK, |
448 | 448 | tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); |
449 | 449 | } |
450 | -#endif | |
451 | 450 | } |
451 | +#endif | |
452 | 452 | ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); |
453 | 453 | if (ret) { |
454 | 454 | if (retaddr) { |
... | ... | @@ -463,20 +463,20 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) |
463 | 463 | } |
464 | 464 | do_raise_exception_err(env->exception_index, env->error_code); |
465 | 465 | } |
466 | +#if 0 | |
466 | 467 | { |
467 | 468 | unsigned long tlb_addrr, tlb_addrw; |
468 | 469 | int index; |
469 | 470 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
470 | 471 | tlb_addrr = env->tlb_read[is_user][index].address; |
471 | 472 | tlb_addrw = env->tlb_write[is_user][index].address; |
472 | -#if 0 | |
473 | 473 | printf("%s 2 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " |
474 | 474 | "(0x%08lx 0x%08lx)\n", __func__, env, |
475 | 475 | &env->tlb_read[is_user][index], index, addr, |
476 | 476 | tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK, |
477 | 477 | tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); |
478 | -#endif | |
479 | 478 | } |
479 | +#endif | |
480 | 480 | env = saved_env; |
481 | 481 | } |
482 | 482 | |
... | ... | @@ -496,18 +496,22 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
496 | 496 | int access_type; |
497 | 497 | int ret = 0; |
498 | 498 | |
499 | -// printf("%s 0\n", __func__); | |
500 | - access_type = env->access_type; | |
499 | + if (rw == 2) { | |
500 | + /* code access */ | |
501 | + rw = 0; | |
502 | + access_type = ACCESS_CODE; | |
503 | + } else { | |
504 | + /* data access */ | |
505 | + /* XXX: put correct access by using cpu_restore_state() | |
506 | + correctly */ | |
507 | + access_type = ACCESS_INT; | |
508 | + // access_type = env->access_type; | |
509 | + } | |
501 | 510 | if (env->user_mode_only) { |
502 | 511 | /* user mode only emulation */ |
503 | 512 | ret = -2; |
504 | 513 | goto do_fault; |
505 | 514 | } |
506 | - /* NASTY BUG workaround */ | |
507 | - if (access_type == ACCESS_CODE && rw) { | |
508 | - printf("%s: ERROR WRITE CODE ACCESS\n", __func__); | |
509 | - access_type = ACCESS_INT; | |
510 | - } | |
511 | 515 | ret = get_physical_address(env, &physical, &prot, |
512 | 516 | address, rw, access_type); |
513 | 517 | if (ret == 0) { |
... | ... | @@ -590,7 +594,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
590 | 594 | env->error_code = error_code; |
591 | 595 | ret = 1; |
592 | 596 | } |
593 | - | |
594 | 597 | return ret; |
595 | 598 | } |
596 | 599 | |
... | ... | @@ -671,11 +674,15 @@ void do_interrupt (CPUState *env) |
671 | 674 | if (loglevel > 0) { |
672 | 675 | fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n", |
673 | 676 | env->nip, excp << 8, env->error_code); |
674 | - } | |
677 | + } | |
675 | 678 | if (loglevel > 0) |
676 | 679 | cpu_ppc_dump_state(env, logfile, 0); |
677 | 680 | } |
678 | 681 | #endif |
682 | + if (loglevel & CPU_LOG_INT) { | |
683 | + fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n", | |
684 | + env->nip, excp << 8, env->error_code); | |
685 | + } | |
679 | 686 | /* Generate informations in save/restore registers */ |
680 | 687 | switch (excp) { |
681 | 688 | case EXCP_OFCALL: |
... | ... | @@ -824,19 +831,29 @@ void do_interrupt (CPUState *env) |
824 | 831 | } |
825 | 832 | goto store_next; |
826 | 833 | case EXCP_SYSCALL: |
827 | -#if defined (DEBUG_EXCEPTIONS) | |
828 | - if (msr_pr) { | |
829 | - if (loglevel) { | |
830 | - fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", | |
831 | - env->gpr[0], env->gpr[3], env->gpr[4], | |
832 | - env->gpr[5], env->gpr[6]); | |
833 | - } else { | |
834 | - printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", | |
835 | - env->gpr[0], env->nip, env->gpr[3], env->gpr[4], | |
836 | - env->gpr[5], env->gpr[6]); | |
837 | - } | |
838 | - } | |
839 | -#endif | |
834 | + if (loglevel & CPU_LOG_INT) { | |
835 | + fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", | |
836 | + env->gpr[0], env->gpr[3], env->gpr[4], | |
837 | + env->gpr[5], env->gpr[6]); | |
838 | + if (env->gpr[0] == 4 && env->gpr[3] == 1) { | |
839 | + int len, addr, i; | |
840 | + uint8_t c; | |
841 | + | |
842 | + fprintf(logfile, "write: "); | |
843 | + addr = env->gpr[4]; | |
844 | + len = env->gpr[5]; | |
845 | + if (len > 64) | |
846 | + len = 64; | |
847 | + for(i = 0; i < len; i++) { | |
848 | + c = 0; | |
849 | + cpu_memory_rw_debug(env, addr + i, &c, 1, 0); | |
850 | + if (c < 32 || c > 126) | |
851 | + c = '.'; | |
852 | + fprintf(logfile, "%c", c); | |
853 | + } | |
854 | + fprintf(logfile, "\n"); | |
855 | + } | |
856 | + } | |
840 | 857 | goto store_next; |
841 | 858 | case EXCP_TRACE: |
842 | 859 | goto store_next; | ... | ... |
target-ppc/translate.c
... | ... | @@ -3002,7 +3002,6 @@ CPUPPCState *cpu_ppc_init(void) |
3002 | 3002 | #else |
3003 | 3003 | env->nip = 0xFFFFFFFC; |
3004 | 3004 | #endif |
3005 | - env->access_type = ACCESS_INT; | |
3006 | 3005 | cpu_single_env = env; |
3007 | 3006 | return env; |
3008 | 3007 | } |
... | ... | @@ -3050,12 +3049,9 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
3050 | 3049 | /* Single step trace mode */ |
3051 | 3050 | msr_se = 1; |
3052 | 3051 | #endif |
3053 | - env->access_type = ACCESS_CODE; | |
3054 | 3052 | /* Set env in case of segfault during code fetch */ |
3055 | 3053 | while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) { |
3056 | 3054 | if (search_pc) { |
3057 | - if (loglevel > 0) | |
3058 | - fprintf(logfile, "Search PC...\n"); | |
3059 | 3055 | j = gen_opc_ptr - gen_opc_buf; |
3060 | 3056 | if (lj < j) { |
3061 | 3057 | lj++; |
... | ... | @@ -3187,8 +3183,6 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
3187 | 3183 | fprintf(logfile, "\n"); |
3188 | 3184 | } |
3189 | 3185 | #endif |
3190 | - env->access_type = ACCESS_INT; | |
3191 | - | |
3192 | 3186 | return 0; |
3193 | 3187 | } |
3194 | 3188 | ... | ... |
target-sparc/cpu.h
... | ... | @@ -86,10 +86,6 @@ |
86 | 86 | #define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT) |
87 | 87 | #define PG_CACHE_MASK (1 << PG_CACHE_BIT) |
88 | 88 | |
89 | -#define ACCESS_DATA 0 | |
90 | -#define ACCESS_CODE 1 | |
91 | -#define ACCESS_MMU 2 | |
92 | - | |
93 | 89 | #define NWINDOWS 32 |
94 | 90 | |
95 | 91 | typedef struct CPUSPARCState { |
... | ... | @@ -131,7 +127,6 @@ typedef struct CPUSPARCState { |
131 | 127 | CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; |
132 | 128 | CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; |
133 | 129 | int error_code; |
134 | - int access_type; | |
135 | 130 | /* MMU regs */ |
136 | 131 | uint32_t mmuregs[16]; |
137 | 132 | /* temporary float registers */ | ... | ... |
target-sparc/helper.c
... | ... | @@ -132,13 +132,12 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
132 | 132 | int is_user, int is_softmmu) |
133 | 133 | { |
134 | 134 | int exception = 0; |
135 | - int access_type, access_perms = 0, access_index = 0; | |
135 | + int access_perms = 0, access_index = 0; | |
136 | 136 | uint8_t *pde_ptr; |
137 | 137 | uint32_t pde, virt_addr; |
138 | 138 | int error_code = 0, is_dirty, prot, ret = 0; |
139 | 139 | unsigned long paddr, vaddr, page_offset; |
140 | 140 | |
141 | - access_type = env->access_type; | |
142 | 141 | if (env->user_mode_only) { |
143 | 142 | /* user mode only emulation */ |
144 | 143 | ret = -2; |
... | ... | @@ -156,7 +155,6 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
156 | 155 | /* SPARC reference MMU table walk: Context table->L1->L2->PTE */ |
157 | 156 | /* Context base + context number */ |
158 | 157 | pde_ptr = phys_ram_base + (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4); |
159 | - env->access_type = ACCESS_MMU; | |
160 | 158 | pde = ldl_raw(pde_ptr); |
161 | 159 | |
162 | 160 | /* Ctx pde */ |
... | ... | @@ -219,7 +217,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
219 | 217 | } |
220 | 218 | |
221 | 219 | /* update page modified and dirty bits */ |
222 | - is_dirty = rw && !(pde & PG_MODIFIED_MASK); | |
220 | + is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK); | |
223 | 221 | if (!(pde & PG_ACCESSED_MASK) || is_dirty) { |
224 | 222 | pde |= PG_ACCESSED_MASK; |
225 | 223 | if (is_dirty) |
... | ... | @@ -228,7 +226,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
228 | 226 | } |
229 | 227 | |
230 | 228 | /* check access */ |
231 | - access_index = (rw << 2) | ((access_type == ACCESS_CODE)? 2 : 0) | (is_user? 0 : 1); | |
229 | + access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1); | |
232 | 230 | access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT; |
233 | 231 | error_code = access_table[access_index][access_perms]; |
234 | 232 | if (error_code) |
... | ... | @@ -249,14 +247,12 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
249 | 247 | paddr = ((pde & PTE_ADDR_MASK) << 4) + page_offset; |
250 | 248 | |
251 | 249 | do_mapping: |
252 | - env->access_type = access_type; | |
253 | 250 | vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1)); |
254 | 251 | |
255 | 252 | ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); |
256 | 253 | return ret; |
257 | 254 | |
258 | 255 | do_fault: |
259 | - env->access_type = access_type; | |
260 | 256 | if (env->mmuregs[3]) /* Fault status register */ |
261 | 257 | env->mmuregs[3] = 1; /* overflow (not read before another fault) */ |
262 | 258 | env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; | ... | ... |
target-sparc/translate.c
... | ... | @@ -1278,8 +1278,6 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, |
1278 | 1278 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
1279 | 1279 | gen_opparam_ptr = gen_opparam_buf; |
1280 | 1280 | |
1281 | - env->access_type = ACCESS_CODE; | |
1282 | - | |
1283 | 1281 | do { |
1284 | 1282 | if (env->nb_breakpoints > 0) { |
1285 | 1283 | for(j = 0; j < env->nb_breakpoints; j++) { |
... | ... | @@ -1352,8 +1350,6 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, |
1352 | 1350 | } |
1353 | 1351 | } |
1354 | 1352 | #endif |
1355 | - | |
1356 | - env->access_type = ACCESS_DATA; | |
1357 | 1353 | return 0; |
1358 | 1354 | } |
1359 | 1355 | |
... | ... | @@ -1379,7 +1375,6 @@ CPUSPARCState *cpu_sparc_init(void) |
1379 | 1375 | env->cwp = 0; |
1380 | 1376 | env->wim = 1; |
1381 | 1377 | env->regwptr = env->regbase + (env->cwp * 16); |
1382 | - env->access_type = ACCESS_DATA; | |
1383 | 1378 | #if defined(CONFIG_USER_ONLY) |
1384 | 1379 | env->user_mode_only = 1; |
1385 | 1380 | #else | ... | ... |