Lines Matching +full:- +full:- +full:-
4 * Copyright (c) 2004-2005 Jocelyn Mayer
25 #include "exec/page-protection.h"
27 #include "accel/tcg/cpu-ldst.h"
29 #include "exec/helper-proto.h"
34 /* Discard entries from env->tlb[first] onwards. */ in r4k_mips_tlb_flush_extra()
35 while (env->tlb->tlb_in_use > first) { in r4k_mips_tlb_flush_extra()
36 r4k_invalidate_tlb(env, --env->tlb->tlb_in_use, 0); in r4k_mips_tlb_flush_extra()
53 uint64_t mask = env->CP0_PageMask >> (TARGET_PAGE_BITS + 1); in r4k_fill_tlb()
56 tlb = &env->tlb->mmu.r4k.tlb[idx]; in r4k_fill_tlb()
57 if (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) { in r4k_fill_tlb()
58 tlb->EHINV = 1; in r4k_fill_tlb()
61 tlb->EHINV = 0; in r4k_fill_tlb()
62 tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1); in r4k_fill_tlb()
64 tlb->VPN &= env->SEGMask; in r4k_fill_tlb()
66 tlb->ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; in r4k_fill_tlb()
67 tlb->MMID = env->CP0_MemoryMapID; in r4k_fill_tlb()
68 tlb->PageMask = env->CP0_PageMask; in r4k_fill_tlb()
69 tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1; in r4k_fill_tlb()
70 tlb->V0 = (env->CP0_EntryLo0 & 2) != 0; in r4k_fill_tlb()
71 tlb->D0 = (env->CP0_EntryLo0 & 4) != 0; in r4k_fill_tlb()
72 tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7; in r4k_fill_tlb()
73 tlb->XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1; in r4k_fill_tlb()
74 tlb->RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1; in r4k_fill_tlb()
75 tlb->PFN[0] = (get_tlb_pfn_from_entrylo(env->CP0_EntryLo0) & ~mask) << 12; in r4k_fill_tlb()
76 tlb->V1 = (env->CP0_EntryLo1 & 2) != 0; in r4k_fill_tlb()
77 tlb->D1 = (env->CP0_EntryLo1 & 4) != 0; in r4k_fill_tlb()
78 tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7; in r4k_fill_tlb()
79 tlb->XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1; in r4k_fill_tlb()
80 tlb->RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1; in r4k_fill_tlb()
81 tlb->PFN[1] = (get_tlb_pfn_from_entrylo(env->CP0_EntryLo1) & ~mask) << 12; in r4k_fill_tlb()
86 bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); in r4k_helper_tlbinv()
87 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; in r4k_helper_tlbinv()
88 uint32_t MMID = env->CP0_MemoryMapID; in r4k_helper_tlbinv()
94 for (idx = 0; idx < env->tlb->nb_tlb; idx++) { in r4k_helper_tlbinv()
95 tlb = &env->tlb->mmu.r4k.tlb[idx]; in r4k_helper_tlbinv()
96 tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; in r4k_helper_tlbinv()
97 if (!tlb->G && tlb_mmid == MMID) { in r4k_helper_tlbinv()
98 tlb->EHINV = 1; in r4k_helper_tlbinv()
108 for (idx = 0; idx < env->tlb->nb_tlb; idx++) { in r4k_helper_tlbinvf()
109 env->tlb->mmu.r4k.tlb[idx].EHINV = 1; in r4k_helper_tlbinvf()
116 bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); in r4k_helper_tlbwi()
118 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; in r4k_helper_tlbwi()
119 uint32_t MMID = env->CP0_MemoryMapID; in r4k_helper_tlbwi()
127 idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb; in r4k_helper_tlbwi()
128 tlb = &env->tlb->mmu.r4k.tlb[idx]; in r4k_helper_tlbwi()
129 VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1); in r4k_helper_tlbwi()
131 VPN &= env->SEGMask; in r4k_helper_tlbwi()
133 EHINV = (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) != 0; in r4k_helper_tlbwi()
134 G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1; in r4k_helper_tlbwi()
135 V0 = (env->CP0_EntryLo0 & 2) != 0; in r4k_helper_tlbwi()
136 D0 = (env->CP0_EntryLo0 & 4) != 0; in r4k_helper_tlbwi()
137 XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) &1; in r4k_helper_tlbwi()
138 RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) &1; in r4k_helper_tlbwi()
139 V1 = (env->CP0_EntryLo1 & 2) != 0; in r4k_helper_tlbwi()
140 D1 = (env->CP0_EntryLo1 & 4) != 0; in r4k_helper_tlbwi()
141 XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) &1; in r4k_helper_tlbwi()
142 RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) &1; in r4k_helper_tlbwi()
144 tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; in r4k_helper_tlbwi()
149 if (tlb->VPN != VPN || tlb_mmid != MMID || tlb->G != G || in r4k_helper_tlbwi()
150 (!tlb->EHINV && EHINV) || in r4k_helper_tlbwi()
151 (tlb->V0 && !V0) || (tlb->D0 && !D0) || in r4k_helper_tlbwi()
152 (!tlb->XI0 && XI0) || (!tlb->RI0 && RI0) || in r4k_helper_tlbwi()
153 (tlb->V1 && !V1) || (tlb->D1 && !D1) || in r4k_helper_tlbwi()
154 (!tlb->XI1 && XI1) || (!tlb->RI1 && RI1)) { in r4k_helper_tlbwi()
155 r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb); in r4k_helper_tlbwi()
172 bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); in r4k_helper_tlbp()
177 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; in r4k_helper_tlbp()
178 uint32_t MMID = env->CP0_MemoryMapID; in r4k_helper_tlbp()
183 for (i = 0; i < env->tlb->nb_tlb; i++) { in r4k_helper_tlbp()
184 tlb = &env->tlb->mmu.r4k.tlb[i]; in r4k_helper_tlbp()
186 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); in r4k_helper_tlbp()
187 tag = env->CP0_EntryHi & ~mask; in r4k_helper_tlbp()
188 VPN = tlb->VPN & ~mask; in r4k_helper_tlbp()
190 tag &= env->SEGMask; in r4k_helper_tlbp()
192 tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; in r4k_helper_tlbp()
194 if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) { in r4k_helper_tlbp()
196 env->CP0_Index = i; in r4k_helper_tlbp()
200 if (i == env->tlb->nb_tlb) { in r4k_helper_tlbp()
202 for (i = env->tlb->nb_tlb; i < env->tlb->tlb_in_use; i++) { in r4k_helper_tlbp()
203 tlb = &env->tlb->mmu.r4k.tlb[i]; in r4k_helper_tlbp()
205 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); in r4k_helper_tlbp()
206 tag = env->CP0_EntryHi & ~mask; in r4k_helper_tlbp()
207 VPN = tlb->VPN & ~mask; in r4k_helper_tlbp()
209 tag &= env->SEGMask; in r4k_helper_tlbp()
211 tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; in r4k_helper_tlbp()
213 if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag) { in r4k_helper_tlbp()
219 env->CP0_Index |= 0x80000000; in r4k_helper_tlbp()
235 bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); in r4k_helper_tlbr()
236 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; in r4k_helper_tlbr()
237 uint32_t MMID = env->CP0_MemoryMapID; in r4k_helper_tlbr()
243 idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb; in r4k_helper_tlbr()
244 tlb = &env->tlb->mmu.r4k.tlb[idx]; in r4k_helper_tlbr()
246 tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; in r4k_helper_tlbr()
252 r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb); in r4k_helper_tlbr()
254 if (tlb->EHINV) { in r4k_helper_tlbr()
255 env->CP0_EntryHi = 1 << CP0EnHi_EHINV; in r4k_helper_tlbr()
256 env->CP0_PageMask = 0; in r4k_helper_tlbr()
257 env->CP0_EntryLo0 = 0; in r4k_helper_tlbr()
258 env->CP0_EntryLo1 = 0; in r4k_helper_tlbr()
260 env->CP0_EntryHi = mi ? tlb->VPN : tlb->VPN | tlb->ASID; in r4k_helper_tlbr()
261 env->CP0_MemoryMapID = tlb->MMID; in r4k_helper_tlbr()
262 env->CP0_PageMask = tlb->PageMask; in r4k_helper_tlbr()
263 env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) | in r4k_helper_tlbr()
264 ((uint64_t)tlb->RI0 << CP0EnLo_RI) | in r4k_helper_tlbr()
265 ((uint64_t)tlb->XI0 << CP0EnLo_XI) | (tlb->C0 << 3) | in r4k_helper_tlbr()
266 get_entrylo_pfn_from_tlb(tlb->PFN[0] >> 12); in r4k_helper_tlbr()
267 env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) | in r4k_helper_tlbr()
268 ((uint64_t)tlb->RI1 << CP0EnLo_RI) | in r4k_helper_tlbr()
269 ((uint64_t)tlb->XI1 << CP0EnLo_XI) | (tlb->C1 << 3) | in r4k_helper_tlbr()
270 get_entrylo_pfn_from_tlb(tlb->PFN[1] >> 12); in r4k_helper_tlbr()
276 env->tlb->helper_tlbwi(env); in helper_tlbwi()
281 env->tlb->helper_tlbwr(env); in helper_tlbwr()
286 env->tlb->helper_tlbp(env); in helper_tlbp()
291 env->tlb->helper_tlbr(env); in helper_tlbr()
296 env->tlb->helper_tlbinv(env); in helper_tlbinv()
301 env->tlb->helper_tlbinvf(env); in helper_tlbinvf()
319 for (idx = 0; idx < env->tlb->nb_tlb; idx++) { in global_invalidate_tlb()
320 tlb = &env->tlb->mmu.r4k.tlb[idx]; in global_invalidate_tlb()
322 (((tlb->VPN & ~tlb->PageMask) == (invMsgVPN2 & ~tlb->PageMask)) in global_invalidate_tlb()
325 (extract64(env->CP0_EntryHi, 62, 2) == invMsgR) in global_invalidate_tlb()
328 MMidMatch = tlb->MMID == invMsgMMid; in global_invalidate_tlb()
329 if ((invAll && (idx > env->CP0_Wired)) || in global_invalidate_tlb()
330 (VAMatch && invVAMMid && (tlb->G || MMidMatch)) || in global_invalidate_tlb()
332 (MMidMatch && !(tlb->G) && invMMid)) { in global_invalidate_tlb()
333 tlb->EHINV = 1; in global_invalidate_tlb()
347 uint32_t invMsgMMid = env->CP0_MemoryMapID; in helper_ginvt()
356 global_invalidate_tlb(&other_cpu->env, invMsgVPN2, invMsgR, invMsgMMid, in helper_ginvt()
376 if (!(env->CP0_Status & (1 << CP0St_ERL))) { in fixed_mmu_map_address()
391 /* MIPS32/MIPS64 R4000-style MMU emulation */
395 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; in r4k_map_address()
396 uint32_t MMID = env->CP0_MemoryMapID; in r4k_map_address()
397 bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); in r4k_map_address()
403 for (i = 0; i < env->tlb->tlb_in_use; i++) { in r4k_map_address()
404 r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i]; in r4k_map_address()
406 target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); in r4k_map_address()
408 target_ulong VPN = tlb->VPN & ~mask; in r4k_map_address()
410 tag &= env->SEGMask; in r4k_map_address()
414 tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; in r4k_map_address()
415 if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) { in r4k_map_address()
419 if (!(n ? tlb->V1 : tlb->V0)) { in r4k_map_address()
422 if (access_type == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) { in r4k_map_address()
425 if (access_type == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) { in r4k_map_address()
428 if (access_type != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) { in r4k_map_address()
429 *physical = tlb->PFN[n] | (address & (mask >> 1)); in r4k_map_address()
431 if (n ? tlb->D1 : tlb->D0) { in r4k_map_address()
434 if (!(n ? tlb->XI1 : tlb->XI0)) { in r4k_map_address()
447 env->tlb->nb_tlb = 1; in no_mmu_init()
448 env->tlb->map_address = &no_mmu_map_address; in no_mmu_init()
453 env->tlb->nb_tlb = 1; in fixed_mmu_init()
454 env->tlb->map_address = &fixed_mmu_map_address; in fixed_mmu_init()
459 env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63); in r4k_mmu_init()
460 env->tlb->map_address = &r4k_map_address; in r4k_mmu_init()
461 env->tlb->helper_tlbwi = r4k_helper_tlbwi; in r4k_mmu_init()
462 env->tlb->helper_tlbwr = r4k_helper_tlbwr; in r4k_mmu_init()
463 env->tlb->helper_tlbp = r4k_helper_tlbp; in r4k_mmu_init()
464 env->tlb->helper_tlbr = r4k_helper_tlbr; in r4k_mmu_init()
465 env->tlb->helper_tlbinv = r4k_helper_tlbinv; in r4k_mmu_init()
466 env->tlb->helper_tlbinvf = r4k_helper_tlbinvf; in r4k_mmu_init()
471 env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext)); in mmu_init()
473 switch (def->mmu_type) { in mmu_init()
495 env->tlb->tlb_in_use = env->tlb->nb_tlb; in cpu_mips_tlb_flush()
541 /* Execute-Inhibit Exception */ in raise_mmu_exception()
542 if (env->CP0_PageGrain & (1 << CP0PG_IEC)) { in raise_mmu_exception()
549 /* Read-Inhibit Exception */ in raise_mmu_exception()
550 if (env->CP0_PageGrain & (1 << CP0PG_IEC)) { in raise_mmu_exception()
558 if (!(env->hflags & MIPS_HFLAG_DM)) { in raise_mmu_exception()
559 env->CP0_BadVAddr = address; in raise_mmu_exception()
561 env->CP0_Context = (env->CP0_Context & ~0x007fffff) | in raise_mmu_exception()
563 env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | in raise_mmu_exception()
564 (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) | in raise_mmu_exception()
567 env->CP0_EntryHi &= env->SEGMask; in raise_mmu_exception()
568 env->CP0_XContext = in raise_mmu_exception()
569 (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) | /* PTEBase */ in raise_mmu_exception()
570 (extract64(address, 62, 2) << (env->SEGBITS - 9)) | /* R */ in raise_mmu_exception()
571 (extract64(address, 13, env->SEGBITS - 13) << 4); /* BadVPN2 */ in raise_mmu_exception()
573 cs->exception_index = exception; in raise_mmu_exception()
574 env->error_code = error_code; in raise_mmu_exception()
601 if ((vaddr & (memop_size(op) - 1)) != 0) { in get_pte()
622 ptei -= 32; in get_tlb_entry_layout()
624 result >>= (ptei - 2); in get_tlb_entry_layout()
636 int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1; in walk_directory()
637 int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F; in walk_directory()
638 int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1; in walk_directory()
639 int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F; in walk_directory()
659 w = directory_index - 1; in walk_directory()
699 int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F; in page_table_walk_refill()
700 int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F; in page_table_walk_refill()
701 int mdw = (env->CP0_PWSize >> CP0PS_MDW) & 0x3F; in page_table_walk_refill()
702 int ptw = (env->CP0_PWSize >> CP0PS_PTW) & 0x3F; in page_table_walk_refill()
703 int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F; in page_table_walk_refill()
718 /*For the 32-bit architectures, this bit is fixed to 0.*/ in page_table_walk_refill()
719 MemOp native_op = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? MO_32 : MO_64; in page_table_walk_refill()
722 int pf_gdw = (env->CP0_PWField >> CP0PF_GDW) & 0x3F; in page_table_walk_refill()
723 int pf_udw = (env->CP0_PWField >> CP0PF_UDW) & 0x3F; in page_table_walk_refill()
724 int pf_mdw = (env->CP0_PWField >> CP0PF_MDW) & 0x3F; in page_table_walk_refill()
725 int pf_ptw = (env->CP0_PWField >> CP0PF_PTW) & 0x3F; in page_table_walk_refill()
726 int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F; in page_table_walk_refill()
729 int gindex = (address >> pf_gdw) & ((1 << gdw) - 1); in page_table_walk_refill()
730 int uindex = (address >> pf_udw) & ((1 << udw) - 1); in page_table_walk_refill()
731 int mindex = (address >> pf_mdw) & ((1 << mdw) - 1); in page_table_walk_refill()
732 int ptindex = (address >> pf_ptw) & ((1 << ptw) - 1); in page_table_walk_refill()
735 int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1; in page_table_walk_refill()
741 /* Starting address - Page Table Base */ in page_table_walk_refill()
742 uint64_t vaddr = env->CP0_PWBase; in page_table_walk_refill()
749 if (!(env->CP0_Config3 & (1 << CP0C3_PW))) { in page_table_walk_refill()
753 if (!(env->CP0_PWCtl & (1 << CP0PC_PWEN))) { in page_table_walk_refill()
826 /* Leaf Level Page Table - First half of PTE pair */ in page_table_walk_refill()
838 /* Leaf Level Page Table - Second half of PTE pair */ in page_table_walk_refill()
852 m = (1 << pf_ptw) - 1; in page_table_walk_refill()
859 m = (1 << pf_gdw) - 1; in page_table_walk_refill()
865 m = (1 << pf_udw) - 1; in page_table_walk_refill()
871 m = (1 << pf_mdw) - 1; in page_table_walk_refill()
880 pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF); in page_table_walk_refill()
882 target_ulong tmp_entryhi = env->CP0_EntryHi; in page_table_walk_refill()
883 int32_t tmp_pagemask = env->CP0_PageMask; in page_table_walk_refill()
884 uint64_t tmp_entrylo0 = env->CP0_EntryLo0; in page_table_walk_refill()
885 uint64_t tmp_entrylo1 = env->CP0_EntryLo1; in page_table_walk_refill()
887 env->CP0_EntryHi = pw_entryhi; in page_table_walk_refill()
888 env->CP0_PageMask = pw_pagemask; in page_table_walk_refill()
889 env->CP0_EntryLo0 = pw_entrylo0; in page_table_walk_refill()
890 env->CP0_EntryLo1 = pw_entrylo1; in page_table_walk_refill()
899 env->CP0_EntryHi = tmp_entryhi; in page_table_walk_refill()
900 env->CP0_PageMask = tmp_pagemask; in page_table_walk_refill()
901 env->CP0_EntryLo0 = tmp_entrylo0; in page_table_walk_refill()
902 env->CP0_EntryLo1 = tmp_entrylo1; in page_table_walk_refill()
940 if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) { in mips_cpu_tlb_fill()
943 * as if they were kernel-mode load instructions. in mips_cpu_tlb_fill()
945 int ptw_mmu_idx = (env->hflags & MIPS_HFLAG_ERL ? in mips_cpu_tlb_fill()
965 do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); in mips_cpu_tlb_fill()
989 /* Exception handlers are entered in 32-bit mode. */ in set_hflags_for_handler()
990 env->hflags &= ~(MIPS_HFLAG_M16); in set_hflags_for_handler()
992 if (env->insn_flags & ASE_MICROMIPS) { in set_hflags_for_handler()
993 env->hflags |= (!!(env->CP0_Config3 & in set_hflags_for_handler()
1001 if (env->insn_flags & ISA_NANOMIPS32) { in set_badinstr_registers()
1002 if (env->CP0_Config3 & (1 << CP0C3_BI)) { in set_badinstr_registers()
1003 uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16; in set_badinstr_registers()
1005 instr |= cpu_lduw_code(env, env->active_tc.PC + 2); in set_badinstr_registers()
1007 env->CP0_BadInstr = instr; in set_badinstr_registers()
1010 instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16; in set_badinstr_registers()
1011 env->CP0_BadInstrX = instr; in set_badinstr_registers()
1017 if (env->hflags & MIPS_HFLAG_M16) { in set_badinstr_registers()
1021 if (env->CP0_Config3 & (1 << CP0C3_BI)) { in set_badinstr_registers()
1022 env->CP0_BadInstr = cpu_ldl_code(env, env->active_tc.PC); in set_badinstr_registers()
1024 if ((env->CP0_Config3 & (1 << CP0C3_BP)) && in set_badinstr_registers()
1025 (env->hflags & MIPS_HFLAG_BMASK)) { in set_badinstr_registers()
1026 env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4); in set_badinstr_registers()
1033 CPUMIPSState *env = &cpu->env; in mips_cpu_do_interrupt()
1036 int cause = -1; in mips_cpu_do_interrupt()
1039 && cs->exception_index != EXCP_EXT_INTERRUPT) { in mips_cpu_do_interrupt()
1042 __func__, env->active_tc.PC, env->CP0_EPC, in mips_cpu_do_interrupt()
1043 mips_exception_name(cs->exception_index)); in mips_cpu_do_interrupt()
1045 if (cs->exception_index == EXCP_EXT_INTERRUPT && in mips_cpu_do_interrupt()
1046 (env->hflags & MIPS_HFLAG_DM)) { in mips_cpu_do_interrupt()
1047 cs->exception_index = EXCP_DINT; in mips_cpu_do_interrupt()
1050 switch (cs->exception_index) { in mips_cpu_do_interrupt()
1052 cs->exception_index = EXCP_NONE; in mips_cpu_do_interrupt()
1054 env->active_tc.PC += env->error_code; in mips_cpu_do_interrupt()
1057 env->CP0_Debug |= 1 << CP0DB_DSS; in mips_cpu_do_interrupt()
1064 env->CP0_DEPC = env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16); in mips_cpu_do_interrupt()
1067 env->CP0_Debug |= 1 << CP0DB_DINT; in mips_cpu_do_interrupt()
1070 env->CP0_Debug |= 1 << CP0DB_DIB; in mips_cpu_do_interrupt()
1073 env->CP0_Debug |= 1 << CP0DB_DBp; in mips_cpu_do_interrupt()
1074 /* Setup DExcCode - SDBBP instruction */ in mips_cpu_do_interrupt()
1075 env->CP0_Debug = (env->CP0_Debug & ~(0x1fULL << CP0DB_DEC)) | in mips_cpu_do_interrupt()
1079 env->CP0_Debug |= 1 << CP0DB_DDBS; in mips_cpu_do_interrupt()
1082 env->CP0_Debug |= 1 << CP0DB_DDBL; in mips_cpu_do_interrupt()
1084 env->CP0_DEPC = exception_resume_pc(env); in mips_cpu_do_interrupt()
1085 env->hflags &= ~MIPS_HFLAG_BMASK; in mips_cpu_do_interrupt()
1087 if (env->insn_flags & ISA_MIPS3) { in mips_cpu_do_interrupt()
1088 env->hflags |= MIPS_HFLAG_64; in mips_cpu_do_interrupt()
1089 if (!(env->insn_flags & ISA_MIPS_R6) || in mips_cpu_do_interrupt()
1090 env->CP0_Status & (1 << CP0St_KX)) { in mips_cpu_do_interrupt()
1091 env->hflags &= ~MIPS_HFLAG_AWRAP; in mips_cpu_do_interrupt()
1094 env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_CP0; in mips_cpu_do_interrupt()
1095 env->hflags &= ~(MIPS_HFLAG_KSU); in mips_cpu_do_interrupt()
1097 if (!(env->CP0_Status & (1 << CP0St_EXL))) { in mips_cpu_do_interrupt()
1098 env->CP0_Cause &= ~(1U << CP0Ca_BD); in mips_cpu_do_interrupt()
1100 env->active_tc.PC = env->exception_base + 0x480; in mips_cpu_do_interrupt()
1107 env->CP0_Status |= (1 << CP0St_SR); in mips_cpu_do_interrupt()
1108 memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo)); in mips_cpu_do_interrupt()
1111 env->CP0_Status |= (1 << CP0St_NMI); in mips_cpu_do_interrupt()
1113 env->CP0_ErrorEPC = exception_resume_pc(env); in mips_cpu_do_interrupt()
1114 env->hflags &= ~MIPS_HFLAG_BMASK; in mips_cpu_do_interrupt()
1115 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); in mips_cpu_do_interrupt()
1116 if (env->insn_flags & ISA_MIPS3) { in mips_cpu_do_interrupt()
1117 env->hflags |= MIPS_HFLAG_64; in mips_cpu_do_interrupt()
1118 if (!(env->insn_flags & ISA_MIPS_R6) || in mips_cpu_do_interrupt()
1119 env->CP0_Status & (1 << CP0St_KX)) { in mips_cpu_do_interrupt()
1120 env->hflags &= ~MIPS_HFLAG_AWRAP; in mips_cpu_do_interrupt()
1123 env->hflags |= MIPS_HFLAG_CP0; in mips_cpu_do_interrupt()
1124 env->hflags &= ~(MIPS_HFLAG_KSU); in mips_cpu_do_interrupt()
1125 if (!(env->CP0_Status & (1 << CP0St_EXL))) { in mips_cpu_do_interrupt()
1126 env->CP0_Cause &= ~(1U << CP0Ca_BD); in mips_cpu_do_interrupt()
1128 env->active_tc.PC = env->exception_base; in mips_cpu_do_interrupt()
1133 if (env->CP0_Cause & (1 << CP0Ca_IV)) { in mips_cpu_do_interrupt()
1134 uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f; in mips_cpu_do_interrupt()
1136 if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) { in mips_cpu_do_interrupt()
1140 uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP; in mips_cpu_do_interrupt()
1142 if (env->CP0_Config3 & (1 << CP0C3_VEIC)) { in mips_cpu_do_interrupt()
1151 * Mask with Status.IM7-IM0 to get enabled interrupts. in mips_cpu_do_interrupt()
1153 pending &= (env->CP0_Status >> CP0St_IM) & 0xff; in mips_cpu_do_interrupt()
1154 /* Find the highest-priority interrupt. */ in mips_cpu_do_interrupt()
1165 update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); in mips_cpu_do_interrupt()
1169 update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); in mips_cpu_do_interrupt()
1170 if ((env->error_code & EXCP_TLB_NOMATCH) && in mips_cpu_do_interrupt()
1171 !(env->CP0_Status & (1 << CP0St_EXL))) { in mips_cpu_do_interrupt()
1173 int R = env->CP0_BadVAddr >> 62; in mips_cpu_do_interrupt()
1174 int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; in mips_cpu_do_interrupt()
1175 int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; in mips_cpu_do_interrupt()
1178 (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) { in mips_cpu_do_interrupt()
1191 if ((env->error_code & EXCP_TLB_NOMATCH) && in mips_cpu_do_interrupt()
1192 !(env->CP0_Status & (1 << CP0St_EXL))) { in mips_cpu_do_interrupt()
1194 int R = env->CP0_BadVAddr >> 62; in mips_cpu_do_interrupt()
1195 int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; in mips_cpu_do_interrupt()
1196 int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; in mips_cpu_do_interrupt()
1199 (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) { in mips_cpu_do_interrupt()
1211 update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); in mips_cpu_do_interrupt()
1238 env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) | in mips_cpu_do_interrupt()
1239 (env->error_code << CP0Ca_CE); in mips_cpu_do_interrupt()
1291 if (!(env->CP0_Status & (1 << CP0St_EXL))) { in mips_cpu_do_interrupt()
1292 env->CP0_EPC = exception_resume_pc(env); in mips_cpu_do_interrupt()
1296 if (env->hflags & MIPS_HFLAG_BMASK) { in mips_cpu_do_interrupt()
1297 env->CP0_Cause |= (1U << CP0Ca_BD); in mips_cpu_do_interrupt()
1299 env->CP0_Cause &= ~(1U << CP0Ca_BD); in mips_cpu_do_interrupt()
1301 env->CP0_Status |= (1 << CP0St_EXL); in mips_cpu_do_interrupt()
1302 if (env->insn_flags & ISA_MIPS3) { in mips_cpu_do_interrupt()
1303 env->hflags |= MIPS_HFLAG_64; in mips_cpu_do_interrupt()
1304 if (!(env->insn_flags & ISA_MIPS_R6) || in mips_cpu_do_interrupt()
1305 env->CP0_Status & (1 << CP0St_KX)) { in mips_cpu_do_interrupt()
1306 env->hflags &= ~MIPS_HFLAG_AWRAP; in mips_cpu_do_interrupt()
1309 env->hflags |= MIPS_HFLAG_CP0; in mips_cpu_do_interrupt()
1310 env->hflags &= ~(MIPS_HFLAG_KSU); in mips_cpu_do_interrupt()
1312 env->hflags &= ~MIPS_HFLAG_BMASK; in mips_cpu_do_interrupt()
1313 if (env->CP0_Status & (1 << CP0St_BEV)) { in mips_cpu_do_interrupt()
1314 env->active_tc.PC = env->exception_base + 0x200; in mips_cpu_do_interrupt()
1315 } else if (cause == 30 && !(env->CP0_Config3 & (1 << CP0C3_SC) && in mips_cpu_do_interrupt()
1316 env->CP0_Config5 & (1 << CP0C5_CV))) { in mips_cpu_do_interrupt()
1318 env->active_tc.PC = KSEG1_BASE | (env->CP0_EBase & 0x1FFFF000); in mips_cpu_do_interrupt()
1320 env->active_tc.PC = env->CP0_EBase & ~0xfff; in mips_cpu_do_interrupt()
1323 env->active_tc.PC += offset; in mips_cpu_do_interrupt()
1325 env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | in mips_cpu_do_interrupt()
1332 && cs->exception_index != EXCP_EXT_INTERRUPT) { in mips_cpu_do_interrupt()
1335 __func__, env->active_tc.PC, env->CP0_EPC, cause, in mips_cpu_do_interrupt()
1336 env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, in mips_cpu_do_interrupt()
1337 env->CP0_DEPC); in mips_cpu_do_interrupt()
1339 cs->exception_index = EXCP_NONE; in mips_cpu_do_interrupt()
1350 cs->exception_index = EXCP_EXT_INTERRUPT; in mips_cpu_exec_interrupt()
1351 env->error_code = 0; in mips_cpu_exec_interrupt()
1365 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; in r4k_invalidate_tlb()
1366 uint32_t MMID = env->CP0_MemoryMapID; in r4k_invalidate_tlb()
1367 bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); in r4k_invalidate_tlb()
1373 tlb = &env->tlb->mmu.r4k.tlb[idx]; in r4k_invalidate_tlb()
1378 tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; in r4k_invalidate_tlb()
1379 if (tlb->G == 0 && tlb_mmid != MMID) { in r4k_invalidate_tlb()
1383 if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) { in r4k_invalidate_tlb()
1389 env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb; in r4k_invalidate_tlb()
1390 env->tlb->tlb_in_use++; in r4k_invalidate_tlb()
1395 mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); in r4k_invalidate_tlb()
1396 if (tlb->V0) { in r4k_invalidate_tlb()
1397 addr = tlb->VPN & ~mask; in r4k_invalidate_tlb()
1399 if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { in r4k_invalidate_tlb()
1409 if (tlb->V1) { in r4k_invalidate_tlb()
1410 addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); in r4k_invalidate_tlb()
1412 if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { in r4k_invalidate_tlb()
1417 while (addr - 1 < end) { in r4k_invalidate_tlb()