Commit 6f5d427d587bf8a39b3a93c0d515d0929578b923
1 parent
4e290a0b
Implement embedded PowerPC exceptions prefix and vectors registers.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3300 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
71 additions
and
24 deletions
target-ppc/op.c
... | ... | @@ -1949,6 +1949,21 @@ void OPPROTO op_hrfid (void) |
1949 | 1949 | RETURN(); |
1950 | 1950 | } |
1951 | 1951 | #endif |
1952 | + | |
1953 | +/* Exception vectors */ | |
1954 | +void OPPROTO op_store_excp_prefix (void) | |
1955 | +{ | |
1956 | + T0 &= env->ivpr_mask; | |
1957 | + env->excp_prefix = T0; | |
1958 | + RETURN(); | |
1959 | +} | |
1960 | + | |
1961 | +void OPPROTO op_store_excp_vector (void) | |
1962 | +{ | |
1963 | + T0 &= env->ivor_mask; | |
1964 | + env->excp_vectors[PARAM1] = T0; | |
1965 | + RETURN(); | |
1966 | +} | |
1952 | 1967 | #endif |
1953 | 1968 | |
1954 | 1969 | /* Trap word */ | ... | ... |
target-ppc/translate_init.c
... | ... | @@ -389,6 +389,32 @@ static void spr_write_pir (void *opaque, int sprn) |
389 | 389 | } |
390 | 390 | #endif |
391 | 391 | |
392 | +#if !defined(CONFIG_USER_ONLY) | |
393 | +/* Callback used to write the exception vector base */ | |
394 | +static void spr_write_excp_prefix (void *opaque, int sprn) | |
395 | +{ | |
396 | + gen_op_store_excp_prefix(); | |
397 | + gen_op_store_spr(sprn); | |
398 | +} | |
399 | + | |
400 | +static void spr_write_excp_vector (void *opaque, int sprn) | |
401 | +{ | |
402 | + DisasContext *ctx = opaque; | |
403 | + | |
404 | + if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) { | |
405 | + gen_op_store_excp_vector(sprn - SPR_BOOKE_IVOR0); | |
406 | + gen_op_store_spr(sprn); | |
407 | + } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) { | |
408 | + gen_op_store_excp_vector(sprn - SPR_BOOKE_IVOR32 + 32); | |
409 | + gen_op_store_spr(sprn); | |
410 | + } else { | |
411 | + printf("Trying to write an unknown exception vector %d %03x\n", | |
412 | + sprn, sprn); | |
413 | + GEN_EXCP_PRIVREG(ctx); | |
414 | + } | |
415 | +} | |
416 | +#endif | |
417 | + | |
392 | 418 | #if defined(CONFIG_USER_ONLY) |
393 | 419 | #define spr_register(env, num, name, uea_read, uea_write, \ |
394 | 420 | oea_read, oea_write, initial_value) \ |
... | ... | @@ -1311,97 +1337,97 @@ static void gen_spr_BookE (CPUPPCState *env) |
1311 | 1337 | 0x00000000); |
1312 | 1338 | spr_register(env, SPR_BOOKE_IVPR, "IVPR", |
1313 | 1339 | SPR_NOACCESS, SPR_NOACCESS, |
1314 | - &spr_read_generic, &spr_write_generic, | |
1340 | + &spr_read_generic, &spr_write_excp_prefix, | |
1315 | 1341 | 0x00000000); |
1316 | 1342 | /* Exception vectors */ |
1317 | 1343 | spr_register(env, SPR_BOOKE_IVOR0, "IVOR0", |
1318 | 1344 | SPR_NOACCESS, SPR_NOACCESS, |
1319 | - &spr_read_generic, &spr_write_generic, | |
1345 | + &spr_read_generic, &spr_write_excp_vector, | |
1320 | 1346 | 0x00000000); |
1321 | 1347 | spr_register(env, SPR_BOOKE_IVOR1, "IVOR1", |
1322 | 1348 | SPR_NOACCESS, SPR_NOACCESS, |
1323 | - &spr_read_generic, &spr_write_generic, | |
1349 | + &spr_read_generic, &spr_write_excp_vector, | |
1324 | 1350 | 0x00000000); |
1325 | 1351 | spr_register(env, SPR_BOOKE_IVOR2, "IVOR2", |
1326 | 1352 | SPR_NOACCESS, SPR_NOACCESS, |
1327 | - &spr_read_generic, &spr_write_generic, | |
1353 | + &spr_read_generic, &spr_write_excp_vector, | |
1328 | 1354 | 0x00000000); |
1329 | 1355 | spr_register(env, SPR_BOOKE_IVOR3, "IVOR3", |
1330 | 1356 | SPR_NOACCESS, SPR_NOACCESS, |
1331 | - &spr_read_generic, &spr_write_generic, | |
1357 | + &spr_read_generic, &spr_write_excp_vector, | |
1332 | 1358 | 0x00000000); |
1333 | 1359 | spr_register(env, SPR_BOOKE_IVOR4, "IVOR4", |
1334 | 1360 | SPR_NOACCESS, SPR_NOACCESS, |
1335 | - &spr_read_generic, &spr_write_generic, | |
1361 | + &spr_read_generic, &spr_write_excp_vector, | |
1336 | 1362 | 0x00000000); |
1337 | 1363 | spr_register(env, SPR_BOOKE_IVOR5, "IVOR5", |
1338 | 1364 | SPR_NOACCESS, SPR_NOACCESS, |
1339 | - &spr_read_generic, &spr_write_generic, | |
1365 | + &spr_read_generic, &spr_write_excp_vector, | |
1340 | 1366 | 0x00000000); |
1341 | 1367 | spr_register(env, SPR_BOOKE_IVOR6, "IVOR6", |
1342 | 1368 | SPR_NOACCESS, SPR_NOACCESS, |
1343 | - &spr_read_generic, &spr_write_generic, | |
1369 | + &spr_read_generic, &spr_write_excp_vector, | |
1344 | 1370 | 0x00000000); |
1345 | 1371 | spr_register(env, SPR_BOOKE_IVOR7, "IVOR7", |
1346 | 1372 | SPR_NOACCESS, SPR_NOACCESS, |
1347 | - &spr_read_generic, &spr_write_generic, | |
1373 | + &spr_read_generic, &spr_write_excp_vector, | |
1348 | 1374 | 0x00000000); |
1349 | 1375 | spr_register(env, SPR_BOOKE_IVOR8, "IVOR8", |
1350 | 1376 | SPR_NOACCESS, SPR_NOACCESS, |
1351 | - &spr_read_generic, &spr_write_generic, | |
1377 | + &spr_read_generic, &spr_write_excp_vector, | |
1352 | 1378 | 0x00000000); |
1353 | 1379 | spr_register(env, SPR_BOOKE_IVOR9, "IVOR9", |
1354 | 1380 | SPR_NOACCESS, SPR_NOACCESS, |
1355 | - &spr_read_generic, &spr_write_generic, | |
1381 | + &spr_read_generic, &spr_write_excp_vector, | |
1356 | 1382 | 0x00000000); |
1357 | 1383 | spr_register(env, SPR_BOOKE_IVOR10, "IVOR10", |
1358 | 1384 | SPR_NOACCESS, SPR_NOACCESS, |
1359 | - &spr_read_generic, &spr_write_generic, | |
1385 | + &spr_read_generic, &spr_write_excp_vector, | |
1360 | 1386 | 0x00000000); |
1361 | 1387 | spr_register(env, SPR_BOOKE_IVOR11, "IVOR11", |
1362 | 1388 | SPR_NOACCESS, SPR_NOACCESS, |
1363 | - &spr_read_generic, &spr_write_generic, | |
1389 | + &spr_read_generic, &spr_write_excp_vector, | |
1364 | 1390 | 0x00000000); |
1365 | 1391 | spr_register(env, SPR_BOOKE_IVOR12, "IVOR12", |
1366 | 1392 | SPR_NOACCESS, SPR_NOACCESS, |
1367 | - &spr_read_generic, &spr_write_generic, | |
1393 | + &spr_read_generic, &spr_write_excp_vector, | |
1368 | 1394 | 0x00000000); |
1369 | 1395 | spr_register(env, SPR_BOOKE_IVOR13, "IVOR13", |
1370 | 1396 | SPR_NOACCESS, SPR_NOACCESS, |
1371 | - &spr_read_generic, &spr_write_generic, | |
1397 | + &spr_read_generic, &spr_write_excp_vector, | |
1372 | 1398 | 0x00000000); |
1373 | 1399 | spr_register(env, SPR_BOOKE_IVOR14, "IVOR14", |
1374 | 1400 | SPR_NOACCESS, SPR_NOACCESS, |
1375 | - &spr_read_generic, &spr_write_generic, | |
1401 | + &spr_read_generic, &spr_write_excp_vector, | |
1376 | 1402 | 0x00000000); |
1377 | 1403 | spr_register(env, SPR_BOOKE_IVOR15, "IVOR15", |
1378 | 1404 | SPR_NOACCESS, SPR_NOACCESS, |
1379 | - &spr_read_generic, &spr_write_generic, | |
1405 | + &spr_read_generic, &spr_write_excp_vector, | |
1380 | 1406 | 0x00000000); |
1381 | 1407 | #if 0 |
1382 | 1408 | spr_register(env, SPR_BOOKE_IVOR32, "IVOR32", |
1383 | 1409 | SPR_NOACCESS, SPR_NOACCESS, |
1384 | - &spr_read_generic, &spr_write_generic, | |
1410 | + &spr_read_generic, &spr_write_excp_vector, | |
1385 | 1411 | 0x00000000); |
1386 | 1412 | spr_register(env, SPR_BOOKE_IVOR33, "IVOR33", |
1387 | 1413 | SPR_NOACCESS, SPR_NOACCESS, |
1388 | - &spr_read_generic, &spr_write_generic, | |
1414 | + &spr_read_generic, &spr_write_excp_vector, | |
1389 | 1415 | 0x00000000); |
1390 | 1416 | spr_register(env, SPR_BOOKE_IVOR34, "IVOR34", |
1391 | 1417 | SPR_NOACCESS, SPR_NOACCESS, |
1392 | - &spr_read_generic, &spr_write_generic, | |
1418 | + &spr_read_generic, &spr_write_excp_vector, | |
1393 | 1419 | 0x00000000); |
1394 | 1420 | spr_register(env, SPR_BOOKE_IVOR35, "IVOR35", |
1395 | 1421 | SPR_NOACCESS, SPR_NOACCESS, |
1396 | - &spr_read_generic, &spr_write_generic, | |
1422 | + &spr_read_generic, &spr_write_excp_vector, | |
1397 | 1423 | 0x00000000); |
1398 | 1424 | spr_register(env, SPR_BOOKE_IVOR36, "IVOR36", |
1399 | 1425 | SPR_NOACCESS, SPR_NOACCESS, |
1400 | - &spr_read_generic, &spr_write_generic, | |
1426 | + &spr_read_generic, &spr_write_excp_vector, | |
1401 | 1427 | 0x00000000); |
1402 | 1428 | spr_register(env, SPR_BOOKE_IVOR37, "IVOR37", |
1403 | 1429 | SPR_NOACCESS, SPR_NOACCESS, |
1404 | - &spr_read_generic, &spr_write_generic, | |
1430 | + &spr_read_generic, &spr_write_excp_vector, | |
1405 | 1431 | 0x00000000); |
1406 | 1432 | #endif |
1407 | 1433 | spr_register(env, SPR_BOOKE_PID, "PID", |
... | ... | @@ -1720,7 +1746,7 @@ static void gen_spr_40x (CPUPPCState *env) |
1720 | 1746 | 0x00000000); |
1721 | 1747 | spr_register(env, SPR_40x_EVPR, "EVPR", |
1722 | 1748 | SPR_NOACCESS, SPR_NOACCESS, |
1723 | - &spr_read_generic, &spr_write_generic, | |
1749 | + &spr_read_generic, &spr_write_excp_prefix, | |
1724 | 1750 | 0x00000000); |
1725 | 1751 | spr_register(env, SPR_40x_SRR2, "SRR2", |
1726 | 1752 | &spr_read_generic, &spr_write_generic, |
... | ... | @@ -2147,6 +2173,9 @@ static void init_excp_4xx_real (CPUPPCState *env) |
2147 | 2173 | env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010; |
2148 | 2174 | env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020; |
2149 | 2175 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; |
2176 | + env->excp_prefix = 0x00000000; | |
2177 | + env->ivor_mask = 0x0000FFF0; | |
2178 | + env->ivpr_mask = 0xFFFF0000; | |
2150 | 2179 | #endif |
2151 | 2180 | } |
2152 | 2181 | |
... | ... | @@ -2167,6 +2196,9 @@ static void init_excp_4xx_softmmu (CPUPPCState *env) |
2167 | 2196 | env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100; |
2168 | 2197 | env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200; |
2169 | 2198 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; |
2199 | + env->excp_prefix = 0x00000000; | |
2200 | + env->ivor_mask = 0x0000FFF0; | |
2201 | + env->ivpr_mask = 0xFFFF0000; | |
2170 | 2202 | #endif |
2171 | 2203 | } |
2172 | 2204 | ... | ... |