?? op_helper.c
字號:
case 0x83: // Secondary no-fault case 0x89: // Secondary LE case 0x8b: // Secondary no-fault LE // XXX break; case 0x45: // LSU ret = env->lsu; break; case 0x50: // I-MMU regs { int reg = (T0 >> 3) & 0xf; ret = env->immuregs[reg]; break; } case 0x51: // I-MMU 8k TSB pointer case 0x52: // I-MMU 64k TSB pointer case 0x55: // I-MMU data access // XXX break; case 0x56: // I-MMU tag read { unsigned int i; for (i = 0; i < 64; i++) { // Valid, ctx match, vaddr match if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 && env->itlb_tag[i] == T0) { ret = env->itlb_tag[i]; break; } } break; } case 0x58: // D-MMU regs { int reg = (T0 >> 3) & 0xf; ret = env->dmmuregs[reg]; break; } case 0x5e: // D-MMU tag read { unsigned int i; for (i = 0; i < 64; i++) { // Valid, ctx match, vaddr match if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 && env->dtlb_tag[i] == T0) { ret = env->dtlb_tag[i]; break; } } break; } case 0x59: // D-MMU 8k TSB pointer case 0x5a: // D-MMU 64k TSB pointer case 0x5b: // D-MMU data pointer case 0x5d: // D-MMU data access case 0x48: // Interrupt dispatch, RO case 0x49: // Interrupt data receive case 0x7f: // Incoming interrupt vector, RO // XXX break; case 0x54: // I-MMU data in, WO case 0x57: // I-MMU demap, WO case 0x5c: // D-MMU data in, WO case 0x5f: // D-MMU demap, WO case 0x77: // Interrupt vector, WO default: do_unassigned_access(T0, 0, 0, 1); ret = 0; break; } /* Convert from little endian */ switch (asi) { case 0x0c: // Nucleus Little Endian (LE) case 0x18: // As if user primary LE case 0x19: // As if user secondary LE case 0x1c: // Bypass LE case 0x1d: // Bypass, non-cacheable LE case 0x88: // Primary LE case 0x89: // Secondary LE case 0x8a: // Primary no-fault LE case 0x8b: // Secondary no-fault LE switch(size) { case 2: ret = bswap16(ret); break; case 4: ret = bswap32(ret); break; case 8: ret = bswap64(ret); break; default: break; } default: break; } /* Convert to signed number */ if (sign) { switch(size) { case 1: ret = (int8_t) ret; break; case 2: ret = (int16_t) ret; break; case 4: ret = (int32_t) ret; break; default: break; } } T1 = ret;}void helper_st_asi(int asi, int size){ if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) raise_exception(TT_PRIV_ACT); /* Convert to little endian */ switch (asi) { case 0x0c: // Nucleus Little Endian (LE) case 0x18: // As if user primary LE case 0x19: // As if user secondary LE case 0x1c: // Bypass LE case 0x1d: // Bypass, non-cacheable LE case 0x88: // Primary LE case 0x89: // Secondary LE switch(size) { case 2: T0 = bswap16(T0); break; case 4: T0 = bswap32(T0); break; case 8: T0 = bswap64(T0); break; default: break; } default: break; } switch(asi) { case 0x10: // As if user primary case 0x18: // As if user primary LE case 0x80: // Primary case 0x88: // Primary LE if ((asi & 0x80) && (env->pstate & PS_PRIV)) { if (env->hpstate & HS_PRIV) { switch(size) { case 1: stb_hypv(T0, T1); break; case 2: stw_hypv(T0 & ~1, T1); break; case 4: stl_hypv(T0 & ~3, T1); break; case 8: default: stq_hypv(T0 & ~7, T1); break; } } else { switch(size) { case 1: stb_kernel(T0, T1); break; case 2: stw_kernel(T0 & ~1, T1); break; case 4: stl_kernel(T0 & ~3, T1); break; case 8: default: stq_kernel(T0 & ~7, T1); break; } } } else { switch(size) { case 1: stb_user(T0, T1); break; case 2: stw_user(T0 & ~1, T1); break; case 4: stl_user(T0 & ~3, T1); break; case 8: default: stq_user(T0 & ~7, T1); break; } } break; case 0x14: // Bypass case 0x15: // Bypass, non-cacheable case 0x1c: // Bypass LE case 0x1d: // Bypass, non-cacheable LE { switch(size) { case 1: stb_phys(T0, T1); break; case 2: stw_phys(T0 & ~1, T1); break; case 4: stl_phys(T0 & ~3, T1); break; case 8: default: stq_phys(T0 & ~7, T1); break; } } return; case 0x04: // Nucleus case 0x0c: // Nucleus Little Endian (LE) case 0x11: // As if user secondary case 0x19: // As if user secondary LE case 0x24: // Nucleus quad LDD 128 bit atomic case 0x2c: // Nucleus quad LDD 128 bit atomic case 0x4a: // UPA config case 0x81: // Secondary case 0x89: // Secondary LE // XXX return; case 0x45: // LSU { uint64_t oldreg; oldreg = env->lsu; env->lsu = T1 & (DMMU_E | IMMU_E); // Mappings generated during D/I MMU disabled mode are // invalid in normal mode if (oldreg != env->lsu) { DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);#ifdef DEBUG_MMU dump_mmu(env);#endif tlb_flush(env, 1); } return; } case 0x50: // I-MMU regs { int reg = (T0 >> 3) & 0xf; uint64_t oldreg; oldreg = env->immuregs[reg]; switch(reg) { case 0: // RO case 4: return; case 1: // Not in I-MMU case 2: case 7: case 8: return; case 3: // SFSR if ((T1 & 1) == 0) T1 = 0; // Clear SFSR break; case 5: // TSB access case 6: // Tag access default: break; } env->immuregs[reg] = T1; if (oldreg != env->immuregs[reg]) { DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]); }#ifdef DEBUG_MMU dump_mmu(env);#endif return; } case 0x54: // I-MMU data in { unsigned int i; // Try finding an invalid entry for (i = 0; i < 64; i++) { if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) { env->itlb_tag[i] = env->immuregs[6]; env->itlb_tte[i] = T1; return; } } // Try finding an unlocked entry for (i = 0; i < 64; i++) { if ((env->itlb_tte[i] & 0x40) == 0) { env->itlb_tag[i] = env->immuregs[6]; env->itlb_tte[i] = T1; return; } } // error state? return; } case 0x55: // I-MMU data access { unsigned int i = (T0 >> 3) & 0x3f; env->itlb_tag[i] = env->immuregs[6]; env->itlb_tte[i] = T1; return; } case 0x57: // I-MMU demap // XXX return; case 0x58: // D-MMU regs { int reg = (T0 >> 3) & 0xf; uint64_t oldreg; oldreg = env->dmmuregs[reg]; switch(reg) { case 0: // RO case 4: return; case 3: // SFSR if ((T1 & 1) == 0) { T1 = 0; // Clear SFSR, Fault address env->dmmuregs[4] = 0; } env->dmmuregs[reg] = T1; break; case 1: // Primary context case 2: // Secondary context case 5: // TSB access case 6: // Tag access case 7: // Virtual Watchpoint case 8: // Physical Watchpoint default: break; } env->dmmuregs[reg] = T1; if (oldreg != env->dmmuregs[reg]) { DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]); }#ifdef DEBUG_MMU dump_mmu(env);#endif return; } case 0x5c: // D-MMU data in { unsigned int i; // Try finding an invalid entry for (i = 0; i < 64; i++) { if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) { env->dtlb_tag[i] = env->dmmuregs[6]; env->dtlb_tte[i] = T1; return; } } // Try finding an unlocked entry for (i = 0; i < 64; i++) { if ((env->dtlb_tte[i] & 0x40) == 0) { env->dtlb_tag[i] = env->dmmuregs[6]; env->dtlb_tte[i] = T1; return; } } // error state? return; } case 0x5d: // D-MMU data access { unsigned int i = (T0 >> 3) & 0x3f; env->dtlb_tag[i] = env->dmmuregs[6]; env->dtlb_tte[i] = T1; return; } case 0x5f: // D-MMU demap case 0x49: // Interrupt data receive // XXX return; case 0x51: // I-MMU 8k TSB pointer, RO case 0x52: // I-MMU 64k TSB pointer, RO case 0x56: // I-MMU tag read, RO case 0x59: // D-MMU 8k TSB pointer, RO case 0x5a: // D-MMU 64k TSB pointer, RO case 0x5b: // D-MMU data pointer, RO case 0x5e: // D-MMU tag read, RO case 0x48: // Interrupt dispatch, RO case 0x7f: // Incoming interrupt vector, RO case 0x82: // Primary no-fault, RO case 0x83: // Secondary no-fault, RO case 0x8a: // Primary no-fault LE, RO case 0x8b: // Secondary no-fault LE, RO default: do_unassigned_access(T0, 1, 0, 1); return; }}#endif /* CONFIG_USER_ONLY */void helper_ldf_asi(int asi, int size, int rd){ target_ulong tmp_T0 = T0, tmp_T1 = T1; unsigned int i; switch (asi) { case 0xf0: // Block load primary case 0xf1: // Block load secondary case 0xf8: // Block load primary LE case 0xf9: // Block load secondary LE if (rd & 7) { raise_exception(TT_ILL_INSN); return; } if (T0 & 0x3f) { raise_exception(TT_UNALIGNED); return; } for (i = 0; i < 16; i++) { helper_ld_asi(asi & 0x8f, 4, 0); *(uint32_t *)&env->fpr[rd++] = T1; T0 += 4; } T0 = tmp_T0; T1 = tmp_T1; return; default: break; } helper_ld_asi(asi, size, 0); switch(size) { default: case 4: *((uint32_t *)&FT0) = T1; break; case 8: *((int64_t *)&DT0) = T1; break;#if defined(CONFIG_USER_ONLY) case 16: // XXX break;#endif } T1 = tmp_T1;}void helper_stf_asi(int asi, int size, int rd){ target_ulong tmp_T0 = T0, tmp_T1 = T1; unsigned int i; switch (asi) { case 0xf0: // Block store primary case 0xf1: // Block store secondary case 0xf8: // Block store primary LE case 0xf9: // Block store secondary LE if (rd & 7) { raise_exception(TT_ILL_INSN); return; } if (T0 & 0x3f) { raise_exception(TT_UNALIGNED); return; } for (i = 0; i < 16; i++) { T1 = *(uint32_t *)&env->fpr[rd++]; helper_st_asi(asi & 0x8f, 4); T0 += 4; } T0 = tmp_T0; T1 = tmp_T1; return; default: break; } switch(size) { default: case 4: T1 = *((uint32_t *)&FT0); break; case 8: T1 = *((int64_t *)&DT0); break;#if defined(CONFIG_USER_ONLY) case 16: // XXX
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -