Revision 6fc76aa9 target-ppc/mmu-hash32.c
b/target-ppc/mmu-hash32.c | ||
---|---|---|
113 | 113 |
return ret; |
114 | 114 |
} |
115 | 115 |
|
116 |
static void hash32_bat_size(CPUPPCState *env, target_ulong *blp, int *validp,
|
|
117 |
target_ulong batu, target_ulong batl) |
|
116 |
static target_ulong hash32_bat_size(CPUPPCState *env,
|
|
117 |
target_ulong batu, target_ulong batl)
|
|
118 | 118 |
{ |
119 |
target_ulong bl; |
|
120 |
int valid; |
|
121 |
|
|
122 |
bl = (batu & BATU32_BL) << 15; |
|
123 |
valid = 0; |
|
124 |
if (((msr_pr == 0) && (batu & BATU32_VS)) || |
|
125 |
((msr_pr != 0) && (batu & BATU32_VP))) { |
|
126 |
valid = 1; |
|
119 |
if ((msr_pr && !(batu & BATU32_VP)) |
|
120 |
|| (!msr_pr && !(batu & BATU32_VS))) { |
|
121 |
return 0; |
|
127 | 122 |
} |
128 |
*blp = bl; |
|
129 |
*validp = valid;
|
|
123 |
|
|
124 |
return BATU32_BEPI & ~((batu & BATU32_BL) << 15);
|
|
130 | 125 |
} |
131 | 126 |
|
132 | 127 |
static int hash32_bat_prot(CPUPPCState *env, |
... | ... | |
145 | 140 |
return prot; |
146 | 141 |
} |
147 | 142 |
|
148 |
static void hash32_bat_601_size(CPUPPCState *env, target_ulong *blp, int *validp,
|
|
143 |
static target_ulong hash32_bat_601_size(CPUPPCState *env,
|
|
149 | 144 |
target_ulong batu, target_ulong batl) |
150 | 145 |
{ |
151 |
target_ulong bl; |
|
152 |
int valid; |
|
153 |
|
|
154 |
bl = (batl & BATL32_601_BL) << 17; |
|
155 |
LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n", |
|
156 |
(uint8_t)(batl & BATL32_601_BL), bl, ~bl); |
|
157 |
valid = !!(batl & BATL32_601_V); |
|
158 |
*blp = bl; |
|
159 |
*validp = valid; |
|
146 |
if (!(batl & BATL32_601_V)) { |
|
147 |
return 0; |
|
148 |
} |
|
149 |
|
|
150 |
return BATU32_BEPI & ~((batl & BATL32_601_BL) << 17); |
|
160 | 151 |
} |
161 | 152 |
|
162 | 153 |
static int hash32_bat_601_prot(CPUPPCState *env, |
... | ... | |
177 | 168 |
target_ulong virtual, int rwx) |
178 | 169 |
{ |
179 | 170 |
target_ulong *BATlt, *BATut; |
180 |
target_ulong BEPIl, BEPIu, bl; |
|
181 |
int i, valid, prot; |
|
171 |
int i, prot; |
|
182 | 172 |
int ret = -1; |
183 | 173 |
|
184 | 174 |
LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__, |
... | ... | |
193 | 183 |
for (i = 0; i < env->nb_BATs; i++) { |
194 | 184 |
target_ulong batu = BATut[i]; |
195 | 185 |
target_ulong batl = BATlt[i]; |
186 |
target_ulong mask; |
|
196 | 187 |
|
197 |
BEPIu = batu & BATU32_BEPIU; |
|
198 |
BEPIl = batu & BATU32_BEPIL; |
|
199 | 188 |
if (unlikely(env->mmu_model == POWERPC_MMU_601)) { |
200 |
hash32_bat_601_size(env, &bl, &valid, batu, batl);
|
|
189 |
mask = hash32_bat_601_size(env, batu, batl);
|
|
201 | 190 |
prot = hash32_bat_601_prot(env, batu, batl); |
202 | 191 |
} else { |
203 |
hash32_bat_size(env, &bl, &valid, batu, batl);
|
|
192 |
mask = hash32_bat_size(env, batu, batl);
|
|
204 | 193 |
prot = hash32_bat_prot(env, batu, batl); |
205 | 194 |
} |
206 | 195 |
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx |
207 | 196 |
" BATl " TARGET_FMT_lx "\n", __func__, |
208 | 197 |
type == ACCESS_CODE ? 'I' : 'D', i, virtual, batu, batl); |
209 |
if ((virtual & BATU32_BEPIU) == BEPIu && |
|
210 |
((virtual & BATU32_BEPIL) & ~bl) == BEPIl) {
|
|
198 |
|
|
199 |
if (mask && ((virtual & mask) == (batu & BATU32_BEPI))) {
|
|
211 | 200 |
/* BAT matches */ |
212 |
if (valid != 0) { |
|
213 |
/* Get physical address */ |
|
214 |
ctx->raddr = (batl & BATL32_BRPNU) | |
|
215 |
((virtual & BATU32_BEPIL & bl) | (batl & BATL32_BRPNL)) | |
|
216 |
(virtual & 0x0001F000); |
|
217 |
/* Compute access rights */ |
|
218 |
ctx->prot = prot; |
|
219 |
ret = ppc_hash32_check_prot(ctx->prot, rwx); |
|
220 |
if (ret == 0) { |
|
221 |
LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n", |
|
222 |
i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-', |
|
223 |
ctx->prot & PAGE_WRITE ? 'W' : '-'); |
|
224 |
} |
|
225 |
break; |
|
201 |
/* Get physical address */ |
|
202 |
ctx->raddr = (batl & mask) | (virtual & ~mask); |
|
203 |
ctx->raddr &= TARGET_PAGE_MASK; |
|
204 |
/* Compute access rights */ |
|
205 |
ctx->prot = prot; |
|
206 |
ret = ppc_hash32_check_prot(ctx->prot, rwx); |
|
207 |
if (ret == 0) { |
|
208 |
LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n", |
|
209 |
i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-', |
|
210 |
ctx->prot & PAGE_WRITE ? 'W' : '-'); |
|
226 | 211 |
} |
212 |
break; |
|
227 | 213 |
} |
228 | 214 |
} |
229 | 215 |
if (ret < 0) { |
Also available in: Unified diff