Commit d094807b9bfe39401e82dce6b7e97a70eb5931be

Authored by bellard
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__