Revision 2374e73e target-alpha/op_helper.c
b/target-alpha/op_helper.c | ||
---|---|---|
1188 | 1188 |
{ |
1189 | 1189 |
cpu_alpha_mtpr(env, iprn, val, NULL); |
1190 | 1190 |
} |
1191 |
|
|
1192 |
void helper_set_alt_mode (void) |
|
1193 |
{ |
|
1194 |
env->saved_mode = env->ps & 0xC; |
|
1195 |
env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC); |
|
1196 |
} |
|
1197 |
|
|
1198 |
void helper_restore_mode (void) |
|
1199 |
{ |
|
1200 |
env->ps = (env->ps & ~0xC) | env->saved_mode; |
|
1201 |
} |
|
1202 |
|
|
1203 | 1191 |
#endif |
1204 | 1192 |
|
1205 | 1193 |
/*****************************************************************************/ |
1206 | 1194 |
/* Softmmu support */ |
1207 | 1195 |
#if !defined (CONFIG_USER_ONLY) |
1208 |
|
|
1209 |
/* XXX: the two following helpers are pure hacks. |
|
1210 |
* Hopefully, we emulate the PALcode, then we should never see |
|
1211 |
* HW_LD / HW_ST instructions. |
|
1212 |
*/ |
|
1213 |
uint64_t helper_ld_virt_to_phys (uint64_t virtaddr) |
|
1214 |
{ |
|
1215 |
uint64_t tlb_addr, physaddr; |
|
1216 |
int index, mmu_idx; |
|
1217 |
void *retaddr; |
|
1218 |
|
|
1219 |
mmu_idx = cpu_mmu_index(env); |
|
1220 |
index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
|
1221 |
redo: |
|
1222 |
tlb_addr = env->tlb_table[mmu_idx][index].addr_read; |
|
1223 |
if ((virtaddr & TARGET_PAGE_MASK) == |
|
1224 |
(tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { |
|
1225 |
physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; |
|
1226 |
} else { |
|
1227 |
/* the page is not in the TLB : fill it */ |
|
1228 |
retaddr = GETPC(); |
|
1229 |
tlb_fill(virtaddr, 0, mmu_idx, retaddr); |
|
1230 |
goto redo; |
|
1231 |
} |
|
1232 |
return physaddr; |
|
1233 |
} |
|
1234 |
|
|
1235 |
uint64_t helper_st_virt_to_phys (uint64_t virtaddr) |
|
1236 |
{ |
|
1237 |
uint64_t tlb_addr, physaddr; |
|
1238 |
int index, mmu_idx; |
|
1239 |
void *retaddr; |
|
1240 |
|
|
1241 |
mmu_idx = cpu_mmu_index(env); |
|
1242 |
index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
|
1243 |
redo: |
|
1244 |
tlb_addr = env->tlb_table[mmu_idx][index].addr_write; |
|
1245 |
if ((virtaddr & TARGET_PAGE_MASK) == |
|
1246 |
(tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { |
|
1247 |
physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; |
|
1248 |
} else { |
|
1249 |
/* the page is not in the TLB : fill it */ |
|
1250 |
retaddr = GETPC(); |
|
1251 |
tlb_fill(virtaddr, 1, mmu_idx, retaddr); |
|
1252 |
goto redo; |
|
1253 |
} |
|
1254 |
return physaddr; |
|
1255 |
} |
|
1256 |
|
|
1257 |
void helper_ldl_raw(uint64_t t0, uint64_t t1) |
|
1196 |
uint64_t helper_ldl_phys(uint64_t p) |
|
1258 | 1197 |
{ |
1259 |
ldl_raw(t1, t0);
|
|
1198 |
return (int32_t)ldl_phys(p);
|
|
1260 | 1199 |
} |
1261 | 1200 |
|
1262 |
void helper_ldq_raw(uint64_t t0, uint64_t t1)
|
|
1201 |
uint64_t helper_ldq_phys(uint64_t p)
|
|
1263 | 1202 |
{ |
1264 |
ldq_raw(t1, t0);
|
|
1203 |
return ldq_phys(p);
|
|
1265 | 1204 |
} |
1266 | 1205 |
|
1267 |
void helper_ldl_l_raw(uint64_t t0, uint64_t t1)
|
|
1206 |
uint64_t helper_ldl_l_phys(uint64_t p)
|
|
1268 | 1207 |
{ |
1269 |
env->lock = t1;
|
|
1270 |
ldl_raw(t1, t0);
|
|
1208 |
env->lock_addr = p;
|
|
1209 |
return env->lock_value = (int32_t)ldl_phys(p);
|
|
1271 | 1210 |
} |
1272 | 1211 |
|
1273 |
void helper_ldq_l_raw(uint64_t t0, uint64_t t1)
|
|
1212 |
uint64_t helper_ldq_l_phys(uint64_t p)
|
|
1274 | 1213 |
{ |
1275 |
env->lock = t1;
|
|
1276 |
ldl_raw(t1, t0);
|
|
1214 |
env->lock_addr = p;
|
|
1215 |
return env->lock_value = ldl_phys(p);
|
|
1277 | 1216 |
} |
1278 | 1217 |
|
1279 |
void helper_ldl_kernel(uint64_t t0, uint64_t t1)
|
|
1218 |
void helper_stl_phys(uint64_t p, uint64_t v)
|
|
1280 | 1219 |
{ |
1281 |
ldl_kernel(t1, t0);
|
|
1220 |
stl_phys(p, v);
|
|
1282 | 1221 |
} |
1283 | 1222 |
|
1284 |
void helper_ldq_kernel(uint64_t t0, uint64_t t1)
|
|
1223 |
void helper_stq_phys(uint64_t p, uint64_t v)
|
|
1285 | 1224 |
{ |
1286 |
ldq_kernel(t1, t0);
|
|
1225 |
stq_phys(p, v);
|
|
1287 | 1226 |
} |
1288 | 1227 |
|
1289 |
void helper_ldl_data(uint64_t t0, uint64_t t1)
|
|
1228 |
uint64_t helper_stl_c_phys(uint64_t p, uint64_t v)
|
|
1290 | 1229 |
{ |
1291 |
ldl_data(t1, t0); |
|
1292 |
} |
|
1230 |
uint64_t ret = 0; |
|
1293 | 1231 |
|
1294 |
void helper_ldq_data(uint64_t t0, uint64_t t1) |
|
1295 |
{ |
|
1296 |
ldq_data(t1, t0); |
|
1297 |
} |
|
1298 |
|
|
1299 |
void helper_stl_raw(uint64_t t0, uint64_t t1) |
|
1300 |
{ |
|
1301 |
stl_raw(t1, t0); |
|
1302 |
} |
|
1303 |
|
|
1304 |
void helper_stq_raw(uint64_t t0, uint64_t t1) |
|
1305 |
{ |
|
1306 |
stq_raw(t1, t0); |
|
1307 |
} |
|
1308 |
|
|
1309 |
uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1) |
|
1310 |
{ |
|
1311 |
uint64_t ret; |
|
1312 |
|
|
1313 |
if (t1 == env->lock) { |
|
1314 |
stl_raw(t1, t0); |
|
1315 |
ret = 0; |
|
1316 |
} else |
|
1317 |
ret = 1; |
|
1318 |
|
|
1319 |
env->lock = 1; |
|
1232 |
if (p == env->lock_addr) { |
|
1233 |
int32_t old = ldl_phys(p); |
|
1234 |
if (old == (int32_t)env->lock_value) { |
|
1235 |
stl_phys(p, v); |
|
1236 |
ret = 1; |
|
1237 |
} |
|
1238 |
} |
|
1239 |
env->lock_addr = -1; |
|
1320 | 1240 |
|
1321 | 1241 |
return ret; |
1322 | 1242 |
} |
1323 | 1243 |
|
1324 |
uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1)
|
|
1244 |
uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
|
|
1325 | 1245 |
{ |
1326 |
uint64_t ret; |
|
1246 |
uint64_t ret = 0;
|
|
1327 | 1247 |
|
1328 |
if (t1 == env->lock) { |
|
1329 |
stq_raw(t1, t0); |
|
1330 |
ret = 0; |
|
1331 |
} else |
|
1332 |
ret = 1; |
|
1333 |
|
|
1334 |
env->lock = 1; |
|
1248 |
if (p == env->lock_addr) { |
|
1249 |
uint64_t old = ldq_phys(p); |
|
1250 |
if (old == env->lock_value) { |
|
1251 |
stq_phys(p, v); |
|
1252 |
ret = 1; |
|
1253 |
} |
|
1254 |
} |
|
1255 |
env->lock_addr = -1; |
|
1335 | 1256 |
|
1336 | 1257 |
return ret; |
1337 | 1258 |
} |
Also available in: Unified diff