4 * Copyright (c) 2007 AXIS Communications AB
5 * Written by Edgar E. Iglesias.
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.
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.
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
22 #ifndef CONFIG_USER_ONLY
34 static int cris_mmu_enabled(uint32_t rw_gc_cfg)
36 return (rw_gc_cfg & 12) != 0;
39 static int cris_mmu_segmented_addr(int seg, uint32_t rw_mm_cfg)
41 return (1 << seg) & rw_mm_cfg;
44 static uint32_t cris_mmu_translate_seg(CPUState *env, int seg)
50 base = env->sregs[SFR_RW_MM_KBASE_LO];
52 base = env->sregs[SFR_RW_MM_KBASE_HI];
61 /* Used by the tlb decoder. */
62 #define EXTRACT_FIELD(src, start, end) \
63 (((src) >> start) & ((1 << (end - start + 1)) - 1))
65 static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
66 CPUState *env, uint32_t vaddr,
72 uint32_t vpn, pfn = 0, pid, fg, fv, fk, fw, fx;
79 /* We know the index which to check on each set.
81 for (i = 0; i < 4; i++)
83 lo = env->tlbsets[0][i][idx].lo;
84 hi = env->tlbsets[0][i][idx].hi;
86 vpn = EXTRACT_FIELD(hi, 13, 31);
87 pid = EXTRACT_FIELD(hi, 0, 7);
90 && pid == env->pregs[PR_PID]) {
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);
104 printf ("%s match=%d vaddr=%x vpage=%x vpn=%x pfn=%x pid=%x %x\n",
107 vpn, pfn, pid, env->pregs[PR_PID]);
112 int cris_mmu_translate(struct cris_mmu_result_t *res,
113 CPUState *env, uint32_t vaddr,
116 uint32_t phy = vaddr;
119 int is_user = mmu_idx == MMU_USER_IDX;
121 if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
127 if (cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG]))
132 base = cris_mmu_translate_seg(env, seg);
133 phy = base | (0x0fffffff & vaddr);
138 miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user);
141 phy |= (res->pfn << 13);
145 // printf ("miss=%d v=%x -> p=%x\n", miss, vaddr, phy);