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,6 +22,8 @@ | ||
22 | //#define DEBUG_MMU | 22 | //#define DEBUG_MMU |
23 | //#define DEBUG_BATS | 23 | //#define DEBUG_BATS |
24 | //#define DEBUG_EXCEPTIONS | 24 | //#define DEBUG_EXCEPTIONS |
25 | +/* accurate but slower TLB flush in exceptions */ | ||
26 | +//#define ACCURATE_TLB_FLUSH | ||
25 | 27 | ||
26 | /*****************************************************************************/ | 28 | /*****************************************************************************/ |
27 | /* PPC MMU emulation */ | 29 | /* PPC MMU emulation */ |
@@ -128,7 +130,7 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, | @@ -128,7 +130,7 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, | ||
128 | pte0 = ldl_phys(base + (i * 8)); | 130 | pte0 = ldl_phys(base + (i * 8)); |
129 | pte1 = ldl_phys(base + (i * 8) + 4); | 131 | pte1 = ldl_phys(base + (i * 8) + 4); |
130 | #if defined (DEBUG_MMU) | 132 | #if defined (DEBUG_MMU) |
131 | - if (loglevel > 0) { | 133 | + if (loglevel > 0) { |
132 | fprintf(logfile, "Load pte from 0x%08x => 0x%08x 0x%08x " | 134 | fprintf(logfile, "Load pte from 0x%08x => 0x%08x 0x%08x " |
133 | "%d %d %d 0x%08x\n", base + (i * 8), pte0, pte1, | 135 | "%d %d %d 0x%08x\n", base + (i * 8), pte0, pte1, |
134 | pte0 >> 31, h, (pte0 >> 6) & 1, va); | 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,17 +177,17 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, | ||
175 | if (loglevel > 0) | 177 | if (loglevel > 0) |
176 | fprintf(logfile, "PTE access granted !\n"); | 178 | fprintf(logfile, "PTE access granted !\n"); |
177 | #endif | 179 | #endif |
178 | - good = i; | ||
179 | - keep = pte1; | ||
180 | - ret = 0; | 180 | + good = i; |
181 | + keep = pte1; | ||
182 | + ret = 0; | ||
181 | } else { | 183 | } else { |
182 | /* Access right violation */ | 184 | /* Access right violation */ |
183 | - ret = -2; | 185 | + ret = -2; |
184 | #if defined (DEBUG_MMU) | 186 | #if defined (DEBUG_MMU) |
185 | if (loglevel > 0) | 187 | if (loglevel > 0) |
186 | fprintf(logfile, "PTE access rejected\n"); | 188 | fprintf(logfile, "PTE access rejected\n"); |
187 | #endif | 189 | #endif |
188 | - } | 190 | + } |
189 | *prot = access; | 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,7 +196,7 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, | ||
194 | if (good != -1) { | 196 | if (good != -1) { |
195 | *RPN = keep & 0xFFFFF000; | 197 | *RPN = keep & 0xFFFFF000; |
196 | #if defined (DEBUG_MMU) | 198 | #if defined (DEBUG_MMU) |
197 | - if (loglevel > 0) { | 199 | + if (loglevel > 0) { |
198 | fprintf(logfile, "found PTE at addr 0x%08x prot=0x%01x ret=%d\n", | 200 | fprintf(logfile, "found PTE at addr 0x%08x prot=0x%01x ret=%d\n", |
199 | *RPN, *prot, ret); | 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,7 +207,7 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, | ||
205 | keep |= 0x00000100; | 207 | keep |= 0x00000100; |
206 | store = 1; | 208 | store = 1; |
207 | } | 209 | } |
208 | - if (!(keep & 0x00000080)) { | 210 | + if (!(keep & 0x00000080)) { |
209 | if (rw && ret == 0) { | 211 | if (rw && ret == 0) { |
210 | /* Change flag */ | 212 | /* Change flag */ |
211 | keep |= 0x00000080; | 213 | keep |= 0x00000080; |
@@ -251,7 +253,7 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, | @@ -251,7 +253,7 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, | ||
251 | ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0; | 253 | ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0; |
252 | if ((sr & 0x80000000) == 0) { | 254 | if ((sr & 0x80000000) == 0) { |
253 | #if defined (DEBUG_MMU) | 255 | #if defined (DEBUG_MMU) |
254 | - if (loglevel > 0) | 256 | + if (loglevel > 0) |
255 | fprintf(logfile, "pte segment: key=%d n=0x%08x\n", | 257 | fprintf(logfile, "pte segment: key=%d n=0x%08x\n", |
256 | key, sr & 0x10000000); | 258 | key, sr & 0x10000000); |
257 | #endif | 259 | #endif |
@@ -604,7 +606,7 @@ void _store_xer (CPUState *env, uint32_t value) | @@ -604,7 +606,7 @@ void _store_xer (CPUState *env, uint32_t value) | ||
604 | xer_so = (value >> XER_SO) & 0x01; | 606 | xer_so = (value >> XER_SO) & 0x01; |
605 | xer_ov = (value >> XER_OV) & 0x01; | 607 | xer_ov = (value >> XER_OV) & 0x01; |
606 | xer_ca = (value >> XER_CA) & 0x01; | 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 | uint32_t _load_msr (CPUState *env) | 612 | uint32_t _load_msr (CPUState *env) |
@@ -628,12 +630,12 @@ uint32_t _load_msr (CPUState *env) | @@ -628,12 +630,12 @@ uint32_t _load_msr (CPUState *env) | ||
628 | 630 | ||
629 | void _store_msr (CPUState *env, uint32_t value) | 631 | void _store_msr (CPUState *env, uint32_t value) |
630 | { | 632 | { |
631 | -#if 0 // TRY | 633 | +#ifdef ACCURATE_TLB_FLUSH |
632 | if (((value >> MSR_IR) & 0x01) != msr_ir || | 634 | if (((value >> MSR_IR) & 0x01) != msr_ir || |
633 | ((value >> MSR_DR) & 0x01) != msr_dr) | 635 | ((value >> MSR_DR) & 0x01) != msr_dr) |
634 | { | 636 | { |
635 | /* Flush all tlb when changing translation mode or privilege level */ | 637 | /* Flush all tlb when changing translation mode or privilege level */ |
636 | - tlb_flush(env, 1); | 638 | + tlb_flush(env, 1); |
637 | } | 639 | } |
638 | #endif | 640 | #endif |
639 | msr_pow = (value >> MSR_POW) & 0x03; | 641 | msr_pow = (value >> MSR_POW) & 0x03; |
@@ -660,6 +662,13 @@ void do_interrupt (CPUState *env) | @@ -660,6 +662,13 @@ void do_interrupt (CPUState *env) | ||
660 | env->exception_index = -1; | 662 | env->exception_index = -1; |
661 | } | 663 | } |
662 | #else | 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 | void do_interrupt (CPUState *env) | 672 | void do_interrupt (CPUState *env) |
664 | { | 673 | { |
665 | uint32_t msr; | 674 | uint32_t msr; |
@@ -707,11 +716,11 @@ void do_interrupt (CPUState *env) | @@ -707,11 +716,11 @@ void do_interrupt (CPUState *env) | ||
707 | */ | 716 | */ |
708 | msr &= ~0xFFFF0000; | 717 | msr &= ~0xFFFF0000; |
709 | env->spr[DSISR] = 0; | 718 | env->spr[DSISR] = 0; |
710 | - if (env->error_code & EXCP_DSI_TRANSLATE) | 719 | + if ((env->error_code & 0x0f) == EXCP_DSI_TRANSLATE) |
711 | env->spr[DSISR] |= 0x40000000; | 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 | env->spr[DSISR] |= 0x08000000; | 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 | env->spr[DSISR] |= 0x80000000; | 724 | env->spr[DSISR] |= 0x80000000; |
716 | if (env->error_code & EXCP_DSI_DIRECT) | 725 | if (env->error_code & EXCP_DSI_DIRECT) |
717 | env->spr[DSISR] |= 0x04000000; | 726 | env->spr[DSISR] |= 0x04000000; |
@@ -819,28 +828,15 @@ void do_interrupt (CPUState *env) | @@ -819,28 +828,15 @@ void do_interrupt (CPUState *env) | ||
819 | } | 828 | } |
820 | goto store_next; | 829 | goto store_next; |
821 | case EXCP_SYSCALL: | 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 | if (loglevel & CPU_LOG_INT) { | 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 | goto store_next; | 841 | goto store_next; |
846 | case EXCP_TRACE: | 842 | case EXCP_TRACE: |
@@ -887,6 +883,9 @@ void do_interrupt (CPUState *env) | @@ -887,6 +883,9 @@ void do_interrupt (CPUState *env) | ||
887 | env->nip = excp << 8; | 883 | env->nip = excp << 8; |
888 | env->exception_index = EXCP_NONE; | 884 | env->exception_index = EXCP_NONE; |
889 | /* Invalidate all TLB as we may have changed translation mode */ | 885 | /* Invalidate all TLB as we may have changed translation mode */ |
886 | +#ifdef ACCURATE_TLB_FLUSH | ||
887 | + tlb_flush(env, 1); | ||
888 | +#endif | ||
890 | /* ensure that no TB jump will be modified as | 889 | /* ensure that no TB jump will be modified as |
891 | the program flow was changed */ | 890 | the program flow was changed */ |
892 | #ifdef __sparc__ | 891 | #ifdef __sparc__ |