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,6 +1949,21 @@ void OPPROTO op_hrfid (void) | ||
| 1949 | RETURN(); | 1949 | RETURN(); |
| 1950 | } | 1950 | } |
| 1951 | #endif | 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 | #endif | 1967 | #endif |
| 1953 | 1968 | ||
| 1954 | /* Trap word */ | 1969 | /* Trap word */ |
target-ppc/translate_init.c
| @@ -389,6 +389,32 @@ static void spr_write_pir (void *opaque, int sprn) | @@ -389,6 +389,32 @@ static void spr_write_pir (void *opaque, int sprn) | ||
| 389 | } | 389 | } |
| 390 | #endif | 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 | #if defined(CONFIG_USER_ONLY) | 418 | #if defined(CONFIG_USER_ONLY) |
| 393 | #define spr_register(env, num, name, uea_read, uea_write, \ | 419 | #define spr_register(env, num, name, uea_read, uea_write, \ |
| 394 | oea_read, oea_write, initial_value) \ | 420 | oea_read, oea_write, initial_value) \ |
| @@ -1311,97 +1337,97 @@ static void gen_spr_BookE (CPUPPCState *env) | @@ -1311,97 +1337,97 @@ static void gen_spr_BookE (CPUPPCState *env) | ||
| 1311 | 0x00000000); | 1337 | 0x00000000); |
| 1312 | spr_register(env, SPR_BOOKE_IVPR, "IVPR", | 1338 | spr_register(env, SPR_BOOKE_IVPR, "IVPR", |
| 1313 | SPR_NOACCESS, SPR_NOACCESS, | 1339 | SPR_NOACCESS, SPR_NOACCESS, |
| 1314 | - &spr_read_generic, &spr_write_generic, | 1340 | + &spr_read_generic, &spr_write_excp_prefix, |
| 1315 | 0x00000000); | 1341 | 0x00000000); |
| 1316 | /* Exception vectors */ | 1342 | /* Exception vectors */ |
| 1317 | spr_register(env, SPR_BOOKE_IVOR0, "IVOR0", | 1343 | spr_register(env, SPR_BOOKE_IVOR0, "IVOR0", |
| 1318 | SPR_NOACCESS, SPR_NOACCESS, | 1344 | SPR_NOACCESS, SPR_NOACCESS, |
| 1319 | - &spr_read_generic, &spr_write_generic, | 1345 | + &spr_read_generic, &spr_write_excp_vector, |
| 1320 | 0x00000000); | 1346 | 0x00000000); |
| 1321 | spr_register(env, SPR_BOOKE_IVOR1, "IVOR1", | 1347 | spr_register(env, SPR_BOOKE_IVOR1, "IVOR1", |
| 1322 | SPR_NOACCESS, SPR_NOACCESS, | 1348 | SPR_NOACCESS, SPR_NOACCESS, |
| 1323 | - &spr_read_generic, &spr_write_generic, | 1349 | + &spr_read_generic, &spr_write_excp_vector, |
| 1324 | 0x00000000); | 1350 | 0x00000000); |
| 1325 | spr_register(env, SPR_BOOKE_IVOR2, "IVOR2", | 1351 | spr_register(env, SPR_BOOKE_IVOR2, "IVOR2", |
| 1326 | SPR_NOACCESS, SPR_NOACCESS, | 1352 | SPR_NOACCESS, SPR_NOACCESS, |
| 1327 | - &spr_read_generic, &spr_write_generic, | 1353 | + &spr_read_generic, &spr_write_excp_vector, |
| 1328 | 0x00000000); | 1354 | 0x00000000); |
| 1329 | spr_register(env, SPR_BOOKE_IVOR3, "IVOR3", | 1355 | spr_register(env, SPR_BOOKE_IVOR3, "IVOR3", |
| 1330 | SPR_NOACCESS, SPR_NOACCESS, | 1356 | SPR_NOACCESS, SPR_NOACCESS, |
| 1331 | - &spr_read_generic, &spr_write_generic, | 1357 | + &spr_read_generic, &spr_write_excp_vector, |
| 1332 | 0x00000000); | 1358 | 0x00000000); |
| 1333 | spr_register(env, SPR_BOOKE_IVOR4, "IVOR4", | 1359 | spr_register(env, SPR_BOOKE_IVOR4, "IVOR4", |
| 1334 | SPR_NOACCESS, SPR_NOACCESS, | 1360 | SPR_NOACCESS, SPR_NOACCESS, |
| 1335 | - &spr_read_generic, &spr_write_generic, | 1361 | + &spr_read_generic, &spr_write_excp_vector, |
| 1336 | 0x00000000); | 1362 | 0x00000000); |
| 1337 | spr_register(env, SPR_BOOKE_IVOR5, "IVOR5", | 1363 | spr_register(env, SPR_BOOKE_IVOR5, "IVOR5", |
| 1338 | SPR_NOACCESS, SPR_NOACCESS, | 1364 | SPR_NOACCESS, SPR_NOACCESS, |
| 1339 | - &spr_read_generic, &spr_write_generic, | 1365 | + &spr_read_generic, &spr_write_excp_vector, |
| 1340 | 0x00000000); | 1366 | 0x00000000); |
| 1341 | spr_register(env, SPR_BOOKE_IVOR6, "IVOR6", | 1367 | spr_register(env, SPR_BOOKE_IVOR6, "IVOR6", |
| 1342 | SPR_NOACCESS, SPR_NOACCESS, | 1368 | SPR_NOACCESS, SPR_NOACCESS, |
| 1343 | - &spr_read_generic, &spr_write_generic, | 1369 | + &spr_read_generic, &spr_write_excp_vector, |
| 1344 | 0x00000000); | 1370 | 0x00000000); |
| 1345 | spr_register(env, SPR_BOOKE_IVOR7, "IVOR7", | 1371 | spr_register(env, SPR_BOOKE_IVOR7, "IVOR7", |
| 1346 | SPR_NOACCESS, SPR_NOACCESS, | 1372 | SPR_NOACCESS, SPR_NOACCESS, |
| 1347 | - &spr_read_generic, &spr_write_generic, | 1373 | + &spr_read_generic, &spr_write_excp_vector, |
| 1348 | 0x00000000); | 1374 | 0x00000000); |
| 1349 | spr_register(env, SPR_BOOKE_IVOR8, "IVOR8", | 1375 | spr_register(env, SPR_BOOKE_IVOR8, "IVOR8", |
| 1350 | SPR_NOACCESS, SPR_NOACCESS, | 1376 | SPR_NOACCESS, SPR_NOACCESS, |
| 1351 | - &spr_read_generic, &spr_write_generic, | 1377 | + &spr_read_generic, &spr_write_excp_vector, |
| 1352 | 0x00000000); | 1378 | 0x00000000); |
| 1353 | spr_register(env, SPR_BOOKE_IVOR9, "IVOR9", | 1379 | spr_register(env, SPR_BOOKE_IVOR9, "IVOR9", |
| 1354 | SPR_NOACCESS, SPR_NOACCESS, | 1380 | SPR_NOACCESS, SPR_NOACCESS, |
| 1355 | - &spr_read_generic, &spr_write_generic, | 1381 | + &spr_read_generic, &spr_write_excp_vector, |
| 1356 | 0x00000000); | 1382 | 0x00000000); |
| 1357 | spr_register(env, SPR_BOOKE_IVOR10, "IVOR10", | 1383 | spr_register(env, SPR_BOOKE_IVOR10, "IVOR10", |
| 1358 | SPR_NOACCESS, SPR_NOACCESS, | 1384 | SPR_NOACCESS, SPR_NOACCESS, |
| 1359 | - &spr_read_generic, &spr_write_generic, | 1385 | + &spr_read_generic, &spr_write_excp_vector, |
| 1360 | 0x00000000); | 1386 | 0x00000000); |
| 1361 | spr_register(env, SPR_BOOKE_IVOR11, "IVOR11", | 1387 | spr_register(env, SPR_BOOKE_IVOR11, "IVOR11", |
| 1362 | SPR_NOACCESS, SPR_NOACCESS, | 1388 | SPR_NOACCESS, SPR_NOACCESS, |
| 1363 | - &spr_read_generic, &spr_write_generic, | 1389 | + &spr_read_generic, &spr_write_excp_vector, |
| 1364 | 0x00000000); | 1390 | 0x00000000); |
| 1365 | spr_register(env, SPR_BOOKE_IVOR12, "IVOR12", | 1391 | spr_register(env, SPR_BOOKE_IVOR12, "IVOR12", |
| 1366 | SPR_NOACCESS, SPR_NOACCESS, | 1392 | SPR_NOACCESS, SPR_NOACCESS, |
| 1367 | - &spr_read_generic, &spr_write_generic, | 1393 | + &spr_read_generic, &spr_write_excp_vector, |
| 1368 | 0x00000000); | 1394 | 0x00000000); |
| 1369 | spr_register(env, SPR_BOOKE_IVOR13, "IVOR13", | 1395 | spr_register(env, SPR_BOOKE_IVOR13, "IVOR13", |
| 1370 | SPR_NOACCESS, SPR_NOACCESS, | 1396 | SPR_NOACCESS, SPR_NOACCESS, |
| 1371 | - &spr_read_generic, &spr_write_generic, | 1397 | + &spr_read_generic, &spr_write_excp_vector, |
| 1372 | 0x00000000); | 1398 | 0x00000000); |
| 1373 | spr_register(env, SPR_BOOKE_IVOR14, "IVOR14", | 1399 | spr_register(env, SPR_BOOKE_IVOR14, "IVOR14", |
| 1374 | SPR_NOACCESS, SPR_NOACCESS, | 1400 | SPR_NOACCESS, SPR_NOACCESS, |
| 1375 | - &spr_read_generic, &spr_write_generic, | 1401 | + &spr_read_generic, &spr_write_excp_vector, |
| 1376 | 0x00000000); | 1402 | 0x00000000); |
| 1377 | spr_register(env, SPR_BOOKE_IVOR15, "IVOR15", | 1403 | spr_register(env, SPR_BOOKE_IVOR15, "IVOR15", |
| 1378 | SPR_NOACCESS, SPR_NOACCESS, | 1404 | SPR_NOACCESS, SPR_NOACCESS, |
| 1379 | - &spr_read_generic, &spr_write_generic, | 1405 | + &spr_read_generic, &spr_write_excp_vector, |
| 1380 | 0x00000000); | 1406 | 0x00000000); |
| 1381 | #if 0 | 1407 | #if 0 |
| 1382 | spr_register(env, SPR_BOOKE_IVOR32, "IVOR32", | 1408 | spr_register(env, SPR_BOOKE_IVOR32, "IVOR32", |
| 1383 | SPR_NOACCESS, SPR_NOACCESS, | 1409 | SPR_NOACCESS, SPR_NOACCESS, |
| 1384 | - &spr_read_generic, &spr_write_generic, | 1410 | + &spr_read_generic, &spr_write_excp_vector, |
| 1385 | 0x00000000); | 1411 | 0x00000000); |
| 1386 | spr_register(env, SPR_BOOKE_IVOR33, "IVOR33", | 1412 | spr_register(env, SPR_BOOKE_IVOR33, "IVOR33", |
| 1387 | SPR_NOACCESS, SPR_NOACCESS, | 1413 | SPR_NOACCESS, SPR_NOACCESS, |
| 1388 | - &spr_read_generic, &spr_write_generic, | 1414 | + &spr_read_generic, &spr_write_excp_vector, |
| 1389 | 0x00000000); | 1415 | 0x00000000); |
| 1390 | spr_register(env, SPR_BOOKE_IVOR34, "IVOR34", | 1416 | spr_register(env, SPR_BOOKE_IVOR34, "IVOR34", |
| 1391 | SPR_NOACCESS, SPR_NOACCESS, | 1417 | SPR_NOACCESS, SPR_NOACCESS, |
| 1392 | - &spr_read_generic, &spr_write_generic, | 1418 | + &spr_read_generic, &spr_write_excp_vector, |
| 1393 | 0x00000000); | 1419 | 0x00000000); |
| 1394 | spr_register(env, SPR_BOOKE_IVOR35, "IVOR35", | 1420 | spr_register(env, SPR_BOOKE_IVOR35, "IVOR35", |
| 1395 | SPR_NOACCESS, SPR_NOACCESS, | 1421 | SPR_NOACCESS, SPR_NOACCESS, |
| 1396 | - &spr_read_generic, &spr_write_generic, | 1422 | + &spr_read_generic, &spr_write_excp_vector, |
| 1397 | 0x00000000); | 1423 | 0x00000000); |
| 1398 | spr_register(env, SPR_BOOKE_IVOR36, "IVOR36", | 1424 | spr_register(env, SPR_BOOKE_IVOR36, "IVOR36", |
| 1399 | SPR_NOACCESS, SPR_NOACCESS, | 1425 | SPR_NOACCESS, SPR_NOACCESS, |
| 1400 | - &spr_read_generic, &spr_write_generic, | 1426 | + &spr_read_generic, &spr_write_excp_vector, |
| 1401 | 0x00000000); | 1427 | 0x00000000); |
| 1402 | spr_register(env, SPR_BOOKE_IVOR37, "IVOR37", | 1428 | spr_register(env, SPR_BOOKE_IVOR37, "IVOR37", |
| 1403 | SPR_NOACCESS, SPR_NOACCESS, | 1429 | SPR_NOACCESS, SPR_NOACCESS, |
| 1404 | - &spr_read_generic, &spr_write_generic, | 1430 | + &spr_read_generic, &spr_write_excp_vector, |
| 1405 | 0x00000000); | 1431 | 0x00000000); |
| 1406 | #endif | 1432 | #endif |
| 1407 | spr_register(env, SPR_BOOKE_PID, "PID", | 1433 | spr_register(env, SPR_BOOKE_PID, "PID", |
| @@ -1720,7 +1746,7 @@ static void gen_spr_40x (CPUPPCState *env) | @@ -1720,7 +1746,7 @@ static void gen_spr_40x (CPUPPCState *env) | ||
| 1720 | 0x00000000); | 1746 | 0x00000000); |
| 1721 | spr_register(env, SPR_40x_EVPR, "EVPR", | 1747 | spr_register(env, SPR_40x_EVPR, "EVPR", |
| 1722 | SPR_NOACCESS, SPR_NOACCESS, | 1748 | SPR_NOACCESS, SPR_NOACCESS, |
| 1723 | - &spr_read_generic, &spr_write_generic, | 1749 | + &spr_read_generic, &spr_write_excp_prefix, |
| 1724 | 0x00000000); | 1750 | 0x00000000); |
| 1725 | spr_register(env, SPR_40x_SRR2, "SRR2", | 1751 | spr_register(env, SPR_40x_SRR2, "SRR2", |
| 1726 | &spr_read_generic, &spr_write_generic, | 1752 | &spr_read_generic, &spr_write_generic, |
| @@ -2147,6 +2173,9 @@ static void init_excp_4xx_real (CPUPPCState *env) | @@ -2147,6 +2173,9 @@ static void init_excp_4xx_real (CPUPPCState *env) | ||
| 2147 | env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010; | 2173 | env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010; |
| 2148 | env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020; | 2174 | env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020; |
| 2149 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; | 2175 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; |
| 2176 | + env->excp_prefix = 0x00000000; | ||
| 2177 | + env->ivor_mask = 0x0000FFF0; | ||
| 2178 | + env->ivpr_mask = 0xFFFF0000; | ||
| 2150 | #endif | 2179 | #endif |
| 2151 | } | 2180 | } |
| 2152 | 2181 | ||
| @@ -2167,6 +2196,9 @@ static void init_excp_4xx_softmmu (CPUPPCState *env) | @@ -2167,6 +2196,9 @@ static void init_excp_4xx_softmmu (CPUPPCState *env) | ||
| 2167 | env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100; | 2196 | env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100; |
| 2168 | env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200; | 2197 | env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200; |
| 2169 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; | 2198 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; |
| 2199 | + env->excp_prefix = 0x00000000; | ||
| 2200 | + env->ivor_mask = 0x0000FFF0; | ||
| 2201 | + env->ivpr_mask = 0xFFFF0000; | ||
| 2170 | #endif | 2202 | #endif |
| 2171 | } | 2203 | } |
| 2172 | 2204 |