/[qemu]/qemu/target-sparc/helper.c
ViewVC logotype

Diff of /qemu/target-sparc/helper.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.15 by bellard, Sun Apr 24 10:08:19 2005 UTC revision 1.16 by bellard, Sat Jul 2 14:31:34 2005 UTC
# Line 43  void cpu_unlock(void) Line 43  void cpu_unlock(void)
43  int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,  int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
44                                 int is_user, int is_softmmu)                                 int is_user, int is_softmmu)
45  {  {
     env->mmuregs[4] = address;  
46      if (rw & 2)      if (rw & 2)
47          env->exception_index = TT_TFAULT;          env->exception_index = TT_TFAULT;
48      else      else
# Line 102  void tlb_fill(target_ulong addr, int is_ Line 101  void tlb_fill(target_ulong addr, int is_
101      env = saved_env;      env = saved_env;
102  }  }
103    
104    #ifndef TARGET_SPARC64
105  static const int access_table[8][8] = {  static const int access_table[8][8] = {
106      { 0, 0, 0, 0, 2, 0, 3, 3 },      { 0, 0, 0, 0, 2, 0, 3, 3 },
107      { 0, 0, 0, 0, 2, 0, 0, 0 },      { 0, 0, 0, 0, 2, 0, 0, 0 },
# Line 268  int cpu_sparc_handle_mmu_fault (CPUState Line 268  int cpu_sparc_handle_mmu_fault (CPUState
268          return 1;          return 1;
269      }      }
270  }  }
271    #else
272    static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
273                              int *access_index, target_ulong address, int rw,
274                              int is_user)
275    {
276        target_ulong mask;
277        unsigned int i;
278    
279        if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
280            *physical = address & 0xffffffff;
281            *prot = PAGE_READ | PAGE_WRITE;
282            return 0;
283        }
284    
285        for (i = 0; i < 64; i++) {
286            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
287                switch (env->dtlb_tte[i] >> 60) {
288                default:
289                case 0x4: // 8k
290                    mask = 0xffffffffffffe000ULL;
291                    break;
292                case 0x5: // 64k
293                    mask = 0xffffffffffff0000ULL;
294                    break;
295                case 0x6: // 512k
296                    mask = 0xfffffffffff80000ULL;
297                    break;
298                case 0x7: // 4M
299                    mask = 0xffffffffffc00000ULL;
300                    break;
301                }
302                // ctx match, vaddr match?
303                if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
304                    (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
305                    // access ok?
306                    if (((env->dtlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) ||
307                        (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
308                        env->exception_index = TT_DFAULT;
309                        return 1;
310                    }
311                    *physical = env->dtlb_tte[i] & 0xffffe000;
312                    *prot = PAGE_READ;
313                    if (env->dtlb_tte[i] & 0x2)
314                        *prot |= PAGE_WRITE;
315                    return 0;
316                }
317            }
318        }
319        env->exception_index = TT_DFAULT;
320        return 1;
321    }
322    
323    static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
324                              int *access_index, target_ulong address, int rw,
325                              int is_user)
326    {
327        target_ulong mask;
328        unsigned int i;
329    
330        if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
331            *physical = address & 0xffffffff;
332            *prot = PAGE_READ;
333            return 0;
334        }
335        for (i = 0; i < 64; i++) {
336            if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
337                switch (env->itlb_tte[i] >> 60) {
338                default:
339                case 0x4: // 8k
340                    mask = 0xffffffffffffe000ULL;
341                    break;
342                case 0x5: // 64k
343                    mask = 0xffffffffffff0000ULL;
344                    break;
345                case 0x6: // 512k
346                    mask = 0xfffffffffff80000ULL;
347                    break;
348                case 0x7: // 4M
349                    mask = 0xffffffffffc00000ULL;
350                    break;
351                }
352                // ctx match, vaddr match?
353                if (env->immuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
354                    (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
355                    // access ok?
356                    if ((env->itlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) {
357                        env->exception_index = TT_TFAULT;
358                        return 1;
359                    }
360                    *physical = env->itlb_tte[i] & 0xffffe000;
361                    *prot = PAGE_READ;
362                    return 0;
363                }
364            }
365        }
366        env->exception_index = TT_TFAULT;
367        return 1;
368    }
369    
370    int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
371                              int *access_index, target_ulong address, int rw,
372                              int is_user)
373    {
374        if (rw == 2)
375            return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
376        else
377            return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
378    }
379    
380    /* Perform address translation */
381    int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
382                                  int is_user, int is_softmmu)
383    {
384        target_ulong virt_addr;
385        target_phys_addr_t paddr;
386        unsigned long vaddr;
387        int error_code = 0, prot, ret = 0, access_index;
388    
389        error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
390        if (error_code == 0) {
391            virt_addr = address & TARGET_PAGE_MASK;
392            vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
393            ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
394            return ret;
395        }
396        // XXX
397        return 1;
398    }
399    
400    #endif
401  #endif  #endif
402    
403  void memcpy32(target_ulong *dst, const target_ulong *src)  void memcpy32(target_ulong *dst, const target_ulong *src)
# Line 292  void set_cwp(int new_cwp) Line 422  void set_cwp(int new_cwp)
422      if (new_cwp == (NWINDOWS - 1))      if (new_cwp == (NWINDOWS - 1))
423          memcpy32(env->regbase + NWINDOWS * 16, env->regbase);          memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
424      env->regwptr = env->regbase + (new_cwp * 16);      env->regwptr = env->regbase + (new_cwp * 16);
425        REGWPTR = env->regwptr;
426  }  }
427    
428  void cpu_set_cwp(CPUState *env1, int new_cwp)  void cpu_set_cwp(CPUState *env1, int new_cwp)
429  {  {
430      CPUState *saved_env;      CPUState *saved_env;
431    #ifdef reg_REGWPTR
432        target_ulong *saved_regwptr;
433    #endif
434    
435      saved_env = env;      saved_env = env;
436    #ifdef reg_REGWPTR
437        saved_regwptr = REGWPTR;
438    #endif
439      env = env1;      env = env1;
440      set_cwp(new_cwp);      set_cwp(new_cwp);
441      env = saved_env;      env = saved_env;
442    #ifdef reg_REGWPTR
443        REGWPTR = saved_regwptr;
444    #endif
445  }  }
446    
447    #ifdef TARGET_SPARC64
448    void do_interrupt(int intno)
449    {
450    #ifdef DEBUG_PCALL
451        if (loglevel & CPU_LOG_INT) {
452            static int count;
453            fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
454                    count, intno,
455                    env->pc,
456                    env->npc, env->regwptr[6]);
457            cpu_dump_state(env, logfile, fprintf, 0);
458    #if 0
459            {
460                int i;
461                uint8_t *ptr;
462    
463                fprintf(logfile, "       code=");
464                ptr = (uint8_t *)env->pc;
465                for(i = 0; i < 16; i++) {
466                    fprintf(logfile, " %02x", ldub(ptr + i));
467                }
468                fprintf(logfile, "\n");
469            }
470    #endif
471            count++;
472        }
473    #endif
474    #if !defined(CONFIG_USER_ONLY)
475        if (env->pstate & PS_IE) {
476            cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
477            return;
478        }
479    #endif
480        env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
481            ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
482        env->tpc[env->tl] = env->pc;
483        env->tnpc[env->tl] = env->npc;
484        env->tt[env->tl] = intno;
485        env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4);
486        env->tl++;
487        env->pc = env->tbr;
488        env->npc = env->pc + 4;
489        env->exception_index = 0;
490    }
491    #else
492  void do_interrupt(int intno)  void do_interrupt(int intno)
493  {  {
494      int cwp;      int cwp;
# Line 448  void dump_mmu(void) Line 634  void dump_mmu(void)
634      printf("MMU dump ends\n");      printf("MMU dump ends\n");
635  }  }
636  #endif  #endif
637    #endif

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.16

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26