|
|
1.1 ! root 1: /* ! 2: * CRIS mmu emulation. ! 3: * ! 4: * Copyright (c) 2007 AXIS Communications AB ! 5: * Written by Edgar E. Iglesias. ! 6: * ! 7: * This library is free software; you can redistribute it and/or ! 8: * modify it under the terms of the GNU Lesser General Public ! 9: * License as published by the Free Software Foundation; either ! 10: * version 2 of the License, or (at your option) any later version. ! 11: * ! 12: * This library is distributed in the hope that it will be useful, ! 13: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 15: * Lesser General Public License for more details. ! 16: * ! 17: * You should have received a copy of the GNU Lesser General Public ! 18: * License along with this library; if not, write to the Free Software ! 19: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! 20: */ ! 21: ! 22: #ifndef CONFIG_USER_ONLY ! 23: ! 24: #include <stdio.h> ! 25: #include <string.h> ! 26: #include <stdlib.h> ! 27: ! 28: #include "config.h" ! 29: #include "cpu.h" ! 30: #include "mmu.h" ! 31: #include "exec-all.h" ! 32: ! 33: ! 34: static int cris_mmu_enabled(uint32_t rw_gc_cfg) ! 35: { ! 36: return (rw_gc_cfg & 12) != 0; ! 37: } ! 38: ! 39: static int cris_mmu_segmented_addr(int seg, uint32_t rw_mm_cfg) ! 40: { ! 41: return (1 << seg) & rw_mm_cfg; ! 42: } ! 43: ! 44: static uint32_t cris_mmu_translate_seg(CPUState *env, int seg) ! 45: { ! 46: uint32_t base; ! 47: int i; ! 48: ! 49: if (seg < 8) ! 50: base = env->sregs[SFR_RW_MM_KBASE_LO]; ! 51: else ! 52: base = env->sregs[SFR_RW_MM_KBASE_HI]; ! 53: ! 54: i = seg & 7; ! 55: base >>= i * 4; ! 56: base &= 15; ! 57: ! 58: base <<= 28; ! 59: return base; ! 60: } ! 61: /* Used by the tlb decoder. */ ! 62: #define EXTRACT_FIELD(src, start, end) \ ! 63: (((src) >> start) & ((1 << (end - start + 1)) - 1)) ! 64: ! 65: static int cris_mmu_translate_page(struct cris_mmu_result_t *res, ! 66: CPUState *env, uint32_t vaddr, ! 67: int rw, int usermode) ! 68: { ! 69: unsigned int vpage; ! 70: unsigned int idx; ! 71: uint32_t lo, hi; ! 72: uint32_t vpn, pfn = 0, pid, fg, fv, fk, fw, fx; ! 73: int i, match = 0; ! 74: ! 75: vpage = vaddr >> 13; ! 76: idx = vpage & 31; ! 77: vpage >>= 4; ! 78: ! 79: /* We know the index which to check on each set. ! 80: Scan both I and D. */ ! 81: for (i = 0; i < 4; i++) ! 82: { ! 83: lo = env->tlbsets[0][i][idx].lo; ! 84: hi = env->tlbsets[0][i][idx].hi; ! 85: ! 86: vpn = EXTRACT_FIELD(hi, 13, 31); ! 87: pid = EXTRACT_FIELD(hi, 0, 7); ! 88: ! 89: if (vpn == vpage ! 90: && pid == env->pregs[SR_PID]) { ! 91: match = 1; ! 92: break; ! 93: } ! 94: } ! 95: ! 96: if (match) { ! 97: pfn = EXTRACT_FIELD(lo, 13, 31); ! 98: fg = EXTRACT_FIELD(lo, 4, 4); ! 99: fv = EXTRACT_FIELD(lo, 3, 3); ! 100: fk = EXTRACT_FIELD(lo, 2, 2); ! 101: fw = EXTRACT_FIELD(lo, 1, 1); ! 102: fx = EXTRACT_FIELD(lo, 0, 0); ! 103: } ! 104: printf ("%s match=%d vaddr=%x vpage=%x vpn=%x pfn=%x pid=%x %x\n", ! 105: __func__, match, ! 106: vaddr, vpage, ! 107: vpn, pfn, pid, env->pregs[SR_PID]); ! 108: res->pfn = pfn; ! 109: return !match; ! 110: } ! 111: ! 112: int cris_mmu_translate(struct cris_mmu_result_t *res, ! 113: CPUState *env, uint32_t vaddr, ! 114: int rw, int mmu_idx) ! 115: { ! 116: uint32_t phy = vaddr; ! 117: int seg; ! 118: int miss = 0; ! 119: int is_user = mmu_idx == MMU_USER_IDX; ! 120: ! 121: if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) { ! 122: res->phy = vaddr; ! 123: return 0; ! 124: } ! 125: ! 126: seg = vaddr >> 28; ! 127: if (cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG])) ! 128: { ! 129: uint32_t base; ! 130: ! 131: miss = 0; ! 132: base = cris_mmu_translate_seg(env, seg); ! 133: phy = base | (0x0fffffff & vaddr); ! 134: res->phy = phy; ! 135: } ! 136: else ! 137: { ! 138: miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user); ! 139: if (!miss) { ! 140: phy &= 8191; ! 141: phy |= (res->pfn << 13); ! 142: res->phy = phy; ! 143: } ! 144: } ! 145: // printf ("miss=%d v=%x -> p=%x\n", miss, vaddr, phy); ! 146: return miss; ! 147: } ! 148: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.