Commit d094807b9bfe39401e82dce6b7e97a70eb5931be
1 parent
6d506e6d
MMU fix - temporary osi_call support - xec_bc mask fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1437 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
35 additions
and
36 deletions
target-ppc/helper.c
... | ... | @@ -22,6 +22,8 @@ |
22 | 22 | //#define DEBUG_MMU |
23 | 23 | //#define DEBUG_BATS |
24 | 24 | //#define DEBUG_EXCEPTIONS |
25 | +/* accurate but slower TLB flush in exceptions */ | |
26 | +//#define ACCURATE_TLB_FLUSH | |
25 | 27 | |
26 | 28 | /*****************************************************************************/ |
27 | 29 | /* PPC MMU emulation */ |
... | ... | @@ -128,7 +130,7 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, |
128 | 130 | pte0 = ldl_phys(base + (i * 8)); |
129 | 131 | pte1 = ldl_phys(base + (i * 8) + 4); |
130 | 132 | #if defined (DEBUG_MMU) |
131 | - if (loglevel > 0) { | |
133 | + if (loglevel > 0) { | |
132 | 134 | fprintf(logfile, "Load pte from 0x%08x => 0x%08x 0x%08x " |
133 | 135 | "%d %d %d 0x%08x\n", base + (i * 8), pte0, pte1, |
134 | 136 | pte0 >> 31, h, (pte0 >> 6) & 1, va); |
... | ... | @@ -175,17 +177,17 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, |
175 | 177 | if (loglevel > 0) |
176 | 178 | fprintf(logfile, "PTE access granted !\n"); |
177 | 179 | #endif |
178 | - good = i; | |
179 | - keep = pte1; | |
180 | - ret = 0; | |
180 | + good = i; | |
181 | + keep = pte1; | |
182 | + ret = 0; | |
181 | 183 | } else { |
182 | 184 | /* Access right violation */ |
183 | - ret = -2; | |
185 | + ret = -2; | |
184 | 186 | #if defined (DEBUG_MMU) |
185 | 187 | if (loglevel > 0) |
186 | 188 | fprintf(logfile, "PTE access rejected\n"); |
187 | 189 | #endif |
188 | - } | |
190 | + } | |
189 | 191 | *prot = access; |
190 | 192 | } |
191 | 193 | } |
... | ... | @@ -194,7 +196,7 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, |
194 | 196 | if (good != -1) { |
195 | 197 | *RPN = keep & 0xFFFFF000; |
196 | 198 | #if defined (DEBUG_MMU) |
197 | - if (loglevel > 0) { | |
199 | + if (loglevel > 0) { | |
198 | 200 | fprintf(logfile, "found PTE at addr 0x%08x prot=0x%01x ret=%d\n", |
199 | 201 | *RPN, *prot, ret); |
200 | 202 | } |
... | ... | @@ -205,7 +207,7 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, |
205 | 207 | keep |= 0x00000100; |
206 | 208 | store = 1; |
207 | 209 | } |
208 | - if (!(keep & 0x00000080)) { | |
210 | + if (!(keep & 0x00000080)) { | |
209 | 211 | if (rw && ret == 0) { |
210 | 212 | /* Change flag */ |
211 | 213 | keep |= 0x00000080; |
... | ... | @@ -251,7 +253,7 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, |
251 | 253 | ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0; |
252 | 254 | if ((sr & 0x80000000) == 0) { |
253 | 255 | #if defined (DEBUG_MMU) |
254 | - if (loglevel > 0) | |
256 | + if (loglevel > 0) | |
255 | 257 | fprintf(logfile, "pte segment: key=%d n=0x%08x\n", |
256 | 258 | key, sr & 0x10000000); |
257 | 259 | #endif |
... | ... | @@ -604,7 +606,7 @@ void _store_xer (CPUState *env, uint32_t value) |
604 | 606 | xer_so = (value >> XER_SO) & 0x01; |
605 | 607 | xer_ov = (value >> XER_OV) & 0x01; |
606 | 608 | xer_ca = (value >> XER_CA) & 0x01; |
607 | - xer_bc = (value >> XER_BC) & 0x1f; | |
609 | + xer_bc = (value >> XER_BC) & 0x3f; | |
608 | 610 | } |
609 | 611 | |
610 | 612 | uint32_t _load_msr (CPUState *env) |
... | ... | @@ -628,12 +630,12 @@ uint32_t _load_msr (CPUState *env) |
628 | 630 | |
629 | 631 | void _store_msr (CPUState *env, uint32_t value) |
630 | 632 | { |
631 | -#if 0 // TRY | |
633 | +#ifdef ACCURATE_TLB_FLUSH | |
632 | 634 | if (((value >> MSR_IR) & 0x01) != msr_ir || |
633 | 635 | ((value >> MSR_DR) & 0x01) != msr_dr) |
634 | 636 | { |
635 | 637 | /* Flush all tlb when changing translation mode or privilege level */ |
636 | - tlb_flush(env, 1); | |
638 | + tlb_flush(env, 1); | |
637 | 639 | } |
638 | 640 | #endif |
639 | 641 | msr_pow = (value >> MSR_POW) & 0x03; |
... | ... | @@ -660,6 +662,13 @@ void do_interrupt (CPUState *env) |
660 | 662 | env->exception_index = -1; |
661 | 663 | } |
662 | 664 | #else |
665 | +static void dump_syscall(CPUState *env) | |
666 | +{ | |
667 | + fprintf(logfile, "syscall r0=0x%08x r3=0x%08x r4=0x%08x r5=0x%08x r6=0x%08x nip=0x%08x\n", | |
668 | + env->gpr[0], env->gpr[3], env->gpr[4], | |
669 | + env->gpr[5], env->gpr[6], env->nip); | |
670 | +} | |
671 | + | |
663 | 672 | void do_interrupt (CPUState *env) |
664 | 673 | { |
665 | 674 | uint32_t msr; |
... | ... | @@ -707,11 +716,11 @@ void do_interrupt (CPUState *env) |
707 | 716 | */ |
708 | 717 | msr &= ~0xFFFF0000; |
709 | 718 | env->spr[DSISR] = 0; |
710 | - if (env->error_code & EXCP_DSI_TRANSLATE) | |
719 | + if ((env->error_code & 0x0f) == EXCP_DSI_TRANSLATE) | |
711 | 720 | env->spr[DSISR] |= 0x40000000; |
712 | - else if (env->error_code & EXCP_DSI_PROT) | |
721 | + else if ((env->error_code & 0x0f) == EXCP_DSI_PROT) | |
713 | 722 | env->spr[DSISR] |= 0x08000000; |
714 | - else if (env->error_code & EXCP_DSI_NOTSUP) { | |
723 | + else if ((env->error_code & 0x0f) == EXCP_DSI_NOTSUP) { | |
715 | 724 | env->spr[DSISR] |= 0x80000000; |
716 | 725 | if (env->error_code & EXCP_DSI_DIRECT) |
717 | 726 | env->spr[DSISR] |= 0x04000000; |
... | ... | @@ -819,28 +828,15 @@ void do_interrupt (CPUState *env) |
819 | 828 | } |
820 | 829 | goto store_next; |
821 | 830 | case EXCP_SYSCALL: |
831 | + /* NOTE: this is a temporary hack to support graphics OSI | |
832 | + calls from the MOL driver */ | |
833 | + if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b && | |
834 | + env->osi_call) { | |
835 | + if (env->osi_call(env) != 0) | |
836 | + return; | |
837 | + } | |
822 | 838 | if (loglevel & CPU_LOG_INT) { |
823 | - fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", | |
824 | - env->gpr[0], env->gpr[3], env->gpr[4], | |
825 | - env->gpr[5], env->gpr[6]); | |
826 | - if (env->gpr[0] == 4 && env->gpr[3] == 1) { | |
827 | - int len, addr, i; | |
828 | - uint8_t c; | |
829 | - | |
830 | - fprintf(logfile, "write: "); | |
831 | - addr = env->gpr[4]; | |
832 | - len = env->gpr[5]; | |
833 | - if (len > 64) | |
834 | - len = 64; | |
835 | - for(i = 0; i < len; i++) { | |
836 | - c = 0; | |
837 | - cpu_memory_rw_debug(env, addr + i, &c, 1, 0); | |
838 | - if (c < 32 || c > 126) | |
839 | - c = '.'; | |
840 | - fprintf(logfile, "%c", c); | |
841 | - } | |
842 | - fprintf(logfile, "\n"); | |
843 | - } | |
839 | + dump_syscall(env); | |
844 | 840 | } |
845 | 841 | goto store_next; |
846 | 842 | case EXCP_TRACE: |
... | ... | @@ -887,6 +883,9 @@ void do_interrupt (CPUState *env) |
887 | 883 | env->nip = excp << 8; |
888 | 884 | env->exception_index = EXCP_NONE; |
889 | 885 | /* Invalidate all TLB as we may have changed translation mode */ |
886 | +#ifdef ACCURATE_TLB_FLUSH | |
887 | + tlb_flush(env, 1); | |
888 | +#endif | |
890 | 889 | /* ensure that no TB jump will be modified as |
891 | 890 | the program flow was changed */ |
892 | 891 | #ifdef __sparc__ | ... | ... |