]> git.proxmox.com Git - mirror_qemu.git/blame - target-cris/mmu.c
Replace is_user variable with mmu_idx in softmmu core,
[mirror_qemu.git] / target-cris / mmu.c
CommitLineData
94cff60a
TS
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
34static int cris_mmu_enabled(uint32_t rw_gc_cfg)
35{
36 return (rw_gc_cfg & 12) != 0;
37}
38
39static int cris_mmu_segmented_addr(int seg, uint32_t rw_mm_cfg)
40{
41 return (1 << seg) & rw_mm_cfg;
42}
43
44static 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
65static 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
112int cris_mmu_translate(struct cris_mmu_result_t *res,
113 CPUState *env, uint32_t vaddr,
6ebbf390 114 int rw, int mmu_idx)
94cff60a
TS
115{
116 uint32_t phy = vaddr;
117 int seg;
118 int miss = 0;
6ebbf390 119 int is_user = mmu_idx == MMU_USER_IDX;
94cff60a
TS
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