Lines Matching +full:4 +full:- +full:way

2  * Copyright (c) 2011 - 2019, Max Filippov, Open Source and Linux Lab.
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 #include "qemu/qemu-print.h"
33 #include "exec/helper-proto.h"
34 #include "qemu/host-utils.h"
35 #include "exec/exec-all.h"
36 #include "exec/page-protection.h"
67 * only the side-effects (ie any MMU or other exception) in HELPER()
76 if (v != env->sregs[RASID]) { in HELPER()
77 env->sregs[RASID] = v; in HELPER()
83 bool dtlb, uint32_t way) in get_page_size() argument
85 uint32_t tlbcfg = env->sregs[dtlb ? DTLBCFG : ITLBCFG]; in get_page_size()
87 switch (way) { in get_page_size()
88 case 4: in get_page_size()
103 * Get bit mask for the virtual address bits translated by the TLB way
106 bool dtlb, uint32_t way) in xtensa_tlb_get_addr_mask() argument
108 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in xtensa_tlb_get_addr_mask()
110 env->config->dtlb.varway56 : in xtensa_tlb_get_addr_mask()
111 env->config->itlb.varway56; in xtensa_tlb_get_addr_mask()
113 switch (way) { in xtensa_tlb_get_addr_mask()
114 case 4: in xtensa_tlb_get_addr_mask()
115 return 0xfff00000 << get_page_size(env, dtlb, way) * 2; in xtensa_tlb_get_addr_mask()
119 return 0xf8000000 << get_page_size(env, dtlb, way); in xtensa_tlb_get_addr_mask()
126 return 0xf0000000 << (1 - get_page_size(env, dtlb, way)); in xtensa_tlb_get_addr_mask()
143 static uint32_t get_vpn_mask(const CPUXtensaState *env, bool dtlb, uint32_t way) in get_vpn_mask() argument
145 if (way < 4) { in get_vpn_mask()
147 env->config->dtlb.nrefillentries : in get_vpn_mask()
148 env->config->itlb.nrefillentries) == 32; in get_vpn_mask()
150 } else if (way == 4) { in get_vpn_mask()
151 return xtensa_tlb_get_addr_mask(env, dtlb, way) << 2; in get_vpn_mask()
152 } else if (way <= 6) { in get_vpn_mask()
153 uint32_t mask = xtensa_tlb_get_addr_mask(env, dtlb, way); in get_vpn_mask()
155 env->config->dtlb.varway56 : in get_vpn_mask()
156 env->config->itlb.varway56; in get_vpn_mask()
159 return mask << (way == 5 ? 2 : 3); in get_vpn_mask()
170 * for the given TLB way
177 env->config->dtlb.varway56 : in split_tlb_entry_spec_way()
178 env->config->itlb.varway56; in split_tlb_entry_spec_way()
184 if (wi < 4) { in split_tlb_entry_spec_way()
186 env->config->dtlb.nrefillentries : in split_tlb_entry_spec_way()
187 env->config->itlb.nrefillentries) == 32; in split_tlb_entry_spec_way()
191 case 4: in split_tlb_entry_spec_way()
209 uint32_t eibase = 29 - get_page_size(env, dtlb, wi); in split_tlb_entry_spec_way()
225 * Split TLB address into TLB way, entry index and VPN (with index).
226 * See ISA, 4.6.5.5 - 4.6.5.8 for the TLB addressing format
231 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in split_tlb_entry_spec()
233 if (*wi < (dtlb ? env->config->dtlb.nways : env->config->itlb.nways)) { in split_tlb_entry_spec()
250 const xtensa_tlb *tlb = dtlb ? &env->config->dtlb : &env->config->itlb; in xtensa_tlb_get_entry()
252 assert(wi < tlb->nways && ei < tlb->way_size[wi]); in xtensa_tlb_get_entry()
254 env->dtlb[wi] + ei : in xtensa_tlb_get_entry()
255 env->itlb[wi] + ei; in xtensa_tlb_get_entry()
280 entry->vaddr = vpn; in xtensa_tlb_set_entry_mmu()
281 entry->paddr = pte & xtensa_tlb_get_addr_mask(env, dtlb, wi); in xtensa_tlb_set_entry_mmu()
282 entry->asid = (env->sregs[RASID] >> ((pte >> 1) & 0x18)) & 0xff; in xtensa_tlb_set_entry_mmu()
283 entry->attr = pte & 0xf; in xtensa_tlb_set_entry_mmu()
293 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in xtensa_tlb_set_entry()
294 if (entry->variable) { in xtensa_tlb_set_entry()
295 if (entry->asid) { in xtensa_tlb_set_entry()
296 tlb_flush_page(cs, entry->vaddr); in xtensa_tlb_set_entry()
299 tlb_flush_page(cs, entry->vaddr); in xtensa_tlb_set_entry()
306 tlb_flush_page(cs, entry->vaddr); in xtensa_tlb_set_entry()
307 if (xtensa_option_enabled(env->config, in xtensa_tlb_set_entry()
309 entry->paddr = pte & REGION_PAGE_MASK; in xtensa_tlb_set_entry()
311 entry->attr = pte & 0xf; in xtensa_tlb_set_entry()
322 if (xtensa_get_physical_addr(&cpu->env, false, addr, 0, 0, in xtensa_cpu_get_phys_page_debug()
326 if (xtensa_get_physical_addr(&cpu->env, false, addr, 2, 0, in xtensa_cpu_get_phys_page_debug()
339 for (wi = 0; wi < tlb->nways; ++wi) { in reset_tlb_mmu_all_ways()
340 for (ei = 0; ei < tlb->way_size[wi]; ++ei) { in reset_tlb_mmu_all_ways()
351 if (!tlb->varway56) { in reset_tlb_mmu_ways56()
411 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in reset_mmu()
412 env->sregs[RASID] = 0x04030201; in reset_mmu()
413 env->sregs[ITLBCFG] = 0; in reset_mmu()
414 env->sregs[DTLBCFG] = 0; in reset_mmu()
415 env->autorefill_idx = 0; in reset_mmu()
416 reset_tlb_mmu_all_ways(env, &env->config->itlb, env->itlb); in reset_mmu()
417 reset_tlb_mmu_all_ways(env, &env->config->dtlb, env->dtlb); in reset_mmu()
418 reset_tlb_mmu_ways56(env, &env->config->itlb, env->itlb); in reset_mmu()
419 reset_tlb_mmu_ways56(env, &env->config->dtlb, env->dtlb); in reset_mmu()
420 } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_MPU)) { in reset_mmu()
423 env->sregs[MPUENB] = 0; in reset_mmu()
424 env->sregs[MPUCFG] = env->config->n_mpu_fg_segments; in reset_mmu()
425 env->sregs[CACHEADRDIS] = 0; in reset_mmu()
426 assert(env->config->n_mpu_bg_segments > 0 && in reset_mmu()
427 env->config->mpu_bg[0].vaddr == 0); in reset_mmu()
428 for (i = 1; i < env->config->n_mpu_bg_segments; ++i) { in reset_mmu()
429 assert(env->config->mpu_bg[i].vaddr >= in reset_mmu()
430 env->config->mpu_bg[i - 1].vaddr); in reset_mmu()
433 env->sregs[CACHEATTR] = 0x22222222; in reset_mmu()
434 reset_tlb_region_way0(env, env->itlb); in reset_mmu()
435 reset_tlb_region_way0(env, env->dtlb); in reset_mmu()
442 for (i = 0; i < 4; ++i) { in get_ring()
443 if (((env->sregs[RASID] >> i * 8) & 0xff) == asid) { in get_ring()
454 * \param pwi: [out] way index
464 &env->config->dtlb : &env->config->itlb; in xtensa_tlb_lookup()
466 env->dtlb : env->itlb; in xtensa_tlb_lookup()
471 for (wi = 0; wi < tlb->nways; ++wi) { in xtensa_tlb_lookup()
477 if (ring < 4) { in xtensa_tlb_lookup()
495 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in HELPER()
500 return (entry->vaddr & get_vpn_mask(env, dtlb, wi)) | entry->asid; in HELPER()
514 return entry->paddr | entry->attr; in HELPER()
522 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in HELPER()
525 if (entry && entry->variable && entry->asid) { in HELPER()
526 tlb_flush_page(env_cpu(env), entry->vaddr); in HELPER()
527 entry->asid = 0; in HELPER()
534 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in HELPER()
549 HELPER(exception_cause_vaddr)(env, env->pc, res, v); in HELPER()
590 case 4: in mmu_attr_to_access()
615 [4] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB, in region_attr_to_access()
634 [4] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB, in cacheattr_attr_to_access()
745 [4] = PAGE_READ, in mpu_attr_to_access()
820 ring = (pte >> 4) & 0x3; in get_physical_addr_mmu()
825 wi = ++env->autorefill_idx & 0x3; in get_physical_addr_mmu()
827 env->sregs[EXCVADDR] = vaddr; in get_physical_addr_mmu()
828 qemu_log_mask(CPU_LOG_MMU, "%s: autorefill(%08x): %08x -> %08x\n", in get_physical_addr_mmu()
850 *access = mmu_attr_to_access(entry->attr) & in get_physical_addr_mmu()
860 *paddr = entry->paddr | (vaddr & ~xtensa_tlb_get_addr_mask(env, dtlb, wi)); in get_physical_addr_mmu()
873 (env->sregs[PTEVADDR] | (vaddr >> 10)) & 0xfffffffc; in get_pte()
890 *pte = address_space_ldl(cs->as, paddr, MEMTXATTRS_UNSPECIFIED, in get_pte()
913 *access = region_attr_to_access(entry->attr); in get_physical_addr_region()
922 *paddr = entry->paddr | (vaddr & ~REGION_PAGE_MASK); in get_physical_addr_region()
936 (i == n - 1 || vaddr < entry[i + 1].vaddr)) { in xtensa_mpu_lookup()
948 v &= (2u << (env->config->n_mpu_fg_segments - 1)) - 1; in HELPER()
950 if (v != env->sregs[MPUENB]) { in HELPER()
951 env->sregs[MPUENB] = v; in HELPER()
960 if (segment < env->config->n_mpu_fg_segments) { in HELPER()
961 env->mpu_fg[segment].vaddr = v & -env->config->mpu_align; in HELPER()
962 env->mpu_fg[segment].attr = p & XTENSA_MPU_ATTR_MASK; in HELPER()
963 env->sregs[MPUENB] = deposit32(env->sregs[MPUENB], segment, 1, v); in HELPER()
972 if (segment < env->config->n_mpu_fg_segments) { in HELPER()
973 return env->mpu_fg[segment].vaddr | in HELPER()
974 extract32(env->sregs[MPUENB], segment, 1); in HELPER()
984 if (segment < env->config->n_mpu_fg_segments) { in HELPER()
985 return env->mpu_fg[segment].attr; in HELPER()
997 nhits = xtensa_mpu_lookup(env->mpu_fg, env->config->n_mpu_fg_segments, in HELPER()
1000 HELPER(exception_cause_vaddr)(env, env->pc, in HELPER()
1002 } else if (nhits == 1 && (env->sregs[MPUENB] & (1u << segment))) { in HELPER()
1003 return env->mpu_fg[segment].attr | segment | XTENSA_MPU_PROBE_V; in HELPER()
1005 xtensa_mpu_lookup(env->config->mpu_bg, in HELPER()
1006 env->config->n_mpu_bg_segments, in HELPER()
1008 return env->config->mpu_bg[bg_segment].attr | XTENSA_MPU_PROBE_B; in HELPER()
1021 nhits = xtensa_mpu_lookup(env->mpu_fg, env->config->n_mpu_fg_segments, in get_physical_addr_mpu()
1027 } else if (nhits == 1 && (env->sregs[MPUENB] & (1u << segment))) { in get_physical_addr_mpu()
1028 attr = env->mpu_fg[segment].attr; in get_physical_addr_mpu()
1030 xtensa_mpu_lookup(env->config->mpu_bg, in get_physical_addr_mpu()
1031 env->config->n_mpu_bg_segments, in get_physical_addr_mpu()
1033 attr = env->config->mpu_bg[segment].attr; in get_physical_addr_mpu()
1045 *page_size = env->config->mpu_align; in get_physical_addr_mpu()
1051 * MMU may issue pagewalk and change xtensa autorefill TLB way entry.
1060 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { in xtensa_get_physical_addr()
1064 } else if (xtensa_option_bits_enabled(env->config, in xtensa_get_physical_addr()
1069 } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_MPU)) { in xtensa_get_physical_addr()
1075 *access = cacheattr_attr_to_access(env->sregs[CACHEATTR] >> in xtensa_get_physical_addr()
1085 dtlb ? &env->config->dtlb : &env->config->itlb; in dump_tlb()
1087 xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) ? in dump_tlb()
1090 for (wi = 0; wi < conf->nways; ++wi) { in dump_tlb()
1103 for (ei = 0; ei < conf->way_size[wi]; ++ei) { in dump_tlb()
1107 if (entry->asid) { in dump_tlb()
1114 unsigned access = attr_to_access(entry->attr); in dump_tlb()
1120 qemu_printf("Way %u (%d %s)\n", wi, sz, sz_text); in dump_tlb()
1122 "\t---------- ---------- ---- ---- --- -------\n"); in dump_tlb()
1125 entry->vaddr, in dump_tlb()
1126 entry->paddr, in dump_tlb()
1127 entry->asid, in dump_tlb()
1128 entry->attr, in dump_tlb()
1129 (access & PAGE_READ) ? 'R' : '-', in dump_tlb()
1130 (access & PAGE_WRITE) ? 'W' : '-', in dump_tlb()
1131 (access & PAGE_EXEC) ? 'X' : '-', in dump_tlb()
1145 "\t%s ---------- ---------- ----- ----- ------------- ---------\n", in dump_mpu()
1147 env ? "--" : " "); in dump_mpu()
1154 char cpu_cache = (type & XTENSA_MPU_TYPE_CPU_CACHE) ? '-' : ' '; in dump_mpu()
1158 ((env->sregs[MPUENB] & (1u << i)) ? '+' : '-') : ' ', in dump_mpu()
1160 (access0 & PAGE_READ) ? 'R' : '-', in dump_mpu()
1161 (access0 & PAGE_WRITE) ? 'W' : '-', in dump_mpu()
1162 (access0 & PAGE_EXEC) ? 'X' : '-', in dump_mpu()
1163 (access1 & PAGE_READ) ? 'R' : '-', in dump_mpu()
1164 (access1 & PAGE_WRITE) ? 'W' : '-', in dump_mpu()
1165 (access1 & PAGE_EXEC) ? 'X' : '-'); in dump_mpu()
1182 (type & XTENSA_MPU_TYPE_SYS_R) ? 'R' : '-', in dump_mpu()
1183 (type & XTENSA_MPU_TYPE_SYS_W) ? 'W' : '-', in dump_mpu()
1184 (type & XTENSA_MPU_TYPE_SYS_C) ? 'C' : '-', in dump_mpu()
1198 if (xtensa_option_bits_enabled(env->config, in dump_mmu()
1207 } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_MPU)) { in dump_mmu()
1209 dump_mpu(env, env->mpu_fg, env->config->n_mpu_fg_segments); in dump_mmu()
1211 dump_mpu(NULL, env->config->mpu_bg, env->config->n_mpu_bg_segments); in dump_mmu()