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 | ... | ... |