projects
/
qemu
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
removed stdout reference (not portable)
[qemu]
/
target-ppc
/
translate.c
diff --git
a/target-ppc/translate.c
b/target-ppc/translate.c
index
0090973
..
e09e9a7
100644
(file)
--- a/
target-ppc/translate.c
+++ b/
target-ppc/translate.c
@@
-28,8
+28,7
@@
#include "disas.h"
//#define DO_SINGLE_STEP
#include "disas.h"
//#define DO_SINGLE_STEP
-//#define DO_STEP_FLUSH
-//#define DEBUG_DISAS
+//#define PPC_DEBUG_DISAS
enum {
#define DEF(s, n, copy_size) INDEX_op_ ## s,
enum {
#define DEF(s, n, copy_size) INDEX_op_ ## s,
@@
-135,10
+134,6
@@
typedef struct DisasContext {
uint32_t nip;
uint32_t opcode;
uint32_t exception;
uint32_t nip;
uint32_t opcode;
uint32_t exception;
- /* Time base offset */
- uint32_t tb_offset;
- /* Decrementer offset */
- uint32_t decr_offset;
/* Execution mode */
#if !defined(CONFIG_USER_ONLY)
int supervisor;
/* Execution mode */
#if !defined(CONFIG_USER_ONLY)
int supervisor;
@@
-156,21
+151,26
@@
typedef struct opc_handler_t {
void (*handler)(DisasContext *ctx);
} opc_handler_t;
void (*handler)(DisasContext *ctx);
} opc_handler_t;
-#define RET_EXCP(excp, error) \
+#define RET_EXCP(ctx, excp, error) \
do { \
do { \
- gen_op_queue_exception_err(excp, error); \
- ctx->exception = excp; \
- return; \
+ if ((ctx)->exception == EXCP_NONE) { \
+ gen_op_update_nip((ctx)->nip); \
+ } \
+ gen_op_raise_exception_err((excp), (error)); \
+ ctx->exception = (excp); \
} while (0)
} while (0)
-#define RET_INVAL() \
-RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
+#define RET_INVAL(ctx) \
+RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
+
+#define RET_PRIVOPC(ctx) \
+RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
-#define RET_PRIVOPC() \
-RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
+#define RET_PRIVREG(ctx) \
+RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
-#define RET_PRIVREG() \
-RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
+#define RET_MTMSR(ctx) \
+RET_EXCP((ctx), EXCP_MTMSR, 0)
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
static void gen_##name (DisasContext *ctx); \
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
static void gen_##name (DisasContext *ctx); \
@@
-182,10
+182,6
@@
typedef struct opcode_t {
opc_handler_t handler;
} opcode_t;
opc_handler_t handler;
} opcode_t;
-/* XXX: move that elsewhere */
-extern FILE *logfile;
-extern int loglevel;
-
/*** Instruction decoding ***/
#define EXTRACT_HELPER(name, shift, nb) \
static inline uint32_t name (uint32_t opcode) \
/*** Instruction decoding ***/
#define EXTRACT_HELPER(name, shift, nb) \
static inline uint32_t name (uint32_t opcode) \
@@
-312,29
+308,26
@@
GEN_OPCODE_MARK(start);
/* Invalid instruction */
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
{
/* Invalid instruction */
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
{
- RET_INVAL();
+ RET_INVAL(ctx);
}
/* Special opcode to stop emulation */
GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON)
{
}
/* Special opcode to stop emulation */
GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON)
{
- gen_op_queue_exception(EXCP_HLT);
- ctx->exception = EXCP_HLT;
+ RET_EXCP(ctx, EXCP_HLT, 0);
}
/* Special opcode to call open-firmware */
GEN_HANDLER(of_enter, 0x06, 0x01, 0xFF, 0x03FFFFC1, PPC_COMMON)
{
}
/* Special opcode to call open-firmware */
GEN_HANDLER(of_enter, 0x06, 0x01, 0xFF, 0x03FFFFC1, PPC_COMMON)
{
- gen_op_queue_exception(EXCP_OFCALL);
- ctx->exception = EXCP_OFCALL;
+ RET_EXCP(ctx, EXCP_OFCALL, 0);
}
/* Special opcode to call RTAS */
GEN_HANDLER(rtas_enter, 0x06, 0x02, 0xFF, 0x03FFFFC1, PPC_COMMON)
{
printf("RTAS entry point !\n");
}
/* Special opcode to call RTAS */
GEN_HANDLER(rtas_enter, 0x06, 0x02, 0xFF, 0x03FFFFC1, PPC_COMMON)
{
printf("RTAS entry point !\n");
- gen_op_queue_exception(EXCP_RTASCALL);
- ctx->exception = EXCP_RTASCALL;
+ RET_EXCP(ctx, EXCP_RTASCALL, 0);
}
static opc_handler_t invalid_handler = {
}
static opc_handler_t invalid_handler = {
@@
-644,7
+637,7
@@
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
}
gen_op_load_gpr_T0(rS(ctx->opcode));
if (uimm != 0)
}
gen_op_load_gpr_T0(rS(ctx->opcode));
if (uimm != 0)
- gen_op_xori(UIMM(ctx->opcode));
+ gen_op_xori(uimm);
gen_op_store_T0_gpr(rA(ctx->opcode));
}
gen_op_store_T0_gpr(rA(ctx->opcode));
}
@@
-659,7
+652,7
@@
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
}
gen_op_load_gpr_T0(rS(ctx->opcode));
if (uimm != 0)
}
gen_op_load_gpr_T0(rS(ctx->opcode));
if (uimm != 0)
- gen_op_xori(UIMM(ctx->opcode) << 16);
+ gen_op_xori(uimm << 16);
gen_op_store_T0_gpr(rA(ctx->opcode));
}
gen_op_store_T0_gpr(rA(ctx->opcode));
}
@@
-687,25
+680,29
@@
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
mb = MB(ctx->opcode);
me = ME(ctx->opcode);
gen_op_load_gpr_T0(rS(ctx->opcode));
mb = MB(ctx->opcode);
me = ME(ctx->opcode);
gen_op_load_gpr_T0(rS(ctx->opcode));
+#if 1 // TRY
+ if (sh == 0) {
+ gen_op_andi_(MASK(mb, me));
+ goto store;
+ }
+#endif
if (mb == 0) {
if (me == 31) {
gen_op_rotlwi(sh);
goto store;
if (mb == 0) {
if (me == 31) {
gen_op_rotlwi(sh);
goto store;
+#if 0
} else if (me == (31 - sh)) {
gen_op_slwi(sh);
goto store;
} else if (me == (31 - sh)) {
gen_op_slwi(sh);
goto store;
- } else if (sh == 0) {
- gen_op_andi_(MASK(0, me));
- goto store;
+#endif
}
} else if (me == 31) {
}
} else if (me == 31) {
+#if 0
if (sh == (32 - mb)) {
gen_op_srwi(mb);
goto store;
if (sh == (32 - mb)) {
gen_op_srwi(mb);
goto store;
- } else if (sh == 0) {
- gen_op_andi_(MASK(mb, 31));
- goto store;
}
}
+#endif
}
gen_op_rlwinm(sh, MASK(mb, me));
store:
}
gen_op_rlwinm(sh, MASK(mb, me));
store:
@@
-1010,7
+1007,8
@@
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
@@
-1025,7
+1023,8
@@
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
{ \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
{ \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
@@
-1086,7
+1085,8
@@
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
{ \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0) { \
{ \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
@@
-1100,7
+1100,8
@@
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
{ \
if (rA(ctx->opcode) == 0) { \
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
{ \
if (rA(ctx->opcode) == 0) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
@@
-1236,7
+1237,8
@@
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
nr = nb / 4;
if (((start + nr) > 32 && start <= ra && (start + nr - 32) > ra) ||
((start + nr) <= 32 && start <= ra && (start + nr) > ra)) {
nr = nb / 4;
if (((start + nr) > 32 && start <= ra && (start + nr - 32) > ra) ||
((start + nr) <= 32 && start <= ra && (start + nr) > ra)) {
- RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
+ RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
+ return;
}
if (ra == 0) {
gen_op_set_T0(0);
}
if (ra == 0) {
gen_op_set_T0(0);
@@
-1268,12
+1270,16
@@
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
/* stswi */
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
{
/* stswi */
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
{
+ int nb = NB(ctx->opcode);
+
if (rA(ctx->opcode) == 0) {
gen_op_set_T0(0);
} else {
gen_op_load_gpr_T0(rA(ctx->opcode));
}
if (rA(ctx->opcode) == 0) {
gen_op_set_T0(0);
} else {
gen_op_load_gpr_T0(rA(ctx->opcode));
}
- gen_op_set_T1(NB(ctx->opcode));
+ if (nb == 0)
+ nb = 32;
+ gen_op_set_T1(nb);
op_ldsts(stsw, rS(ctx->opcode));
}
op_ldsts(stsw, rS(ctx->opcode));
}
@@
-1376,7
+1382,8
@@
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
@@
-1391,7
+1398,8
@@
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
{ \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
{ \
if (rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode)) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
@@
-1448,7
+1456,8
@@
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
{ \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0) { \
{ \
uint32_t simm = SIMM(ctx->opcode); \
if (rA(ctx->opcode) == 0) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
if (simm != 0) \
@@
-1462,7
+1471,8
@@
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
{ \
if (rA(ctx->opcode) == 0) { \
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
{ \
if (rA(ctx->opcode) == 0) { \
- RET_INVAL(); \
+ RET_INVAL(ctx); \
+ return; \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
} \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
@@
-1502,7
+1512,7
@@
GEN_STFS(fs, 0x14);
/* stfiwx */
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
{
/* stfiwx */
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
{
- RET_INVAL();
+ RET_INVAL(ctx);
}
/*** Branch ***/
}
/*** Branch ***/
@@
-1510,11
+1520,11
@@
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
/* b ba bl bla */
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
{
/* b ba bl bla */
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
{
- uint32_t li = s_ext24(LI(ctx->opcode)), target;
+ uint32_t li, target;
+
+ /* sign extend LI */
+ li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
- gen_op_update_tb(ctx->tb_offset);
- gen_op_update_decr(ctx->decr_offset);
- gen_op_process_exceptions(ctx->nip - 4);
if (AA(ctx->opcode) == 0)
target = ctx->nip + li - 4;
else
if (AA(ctx->opcode) == 0)
target = ctx->nip + li - 4;
else
@@
-1538,10
+1548,6
@@
static inline void gen_bcond(DisasContext *ctx, int type)
uint32_t mask;
uint32_t li;
uint32_t mask;
uint32_t li;
- gen_op_update_tb(ctx->tb_offset);
- gen_op_update_decr(ctx->decr_offset);
- gen_op_process_exceptions(ctx->nip - 4);
-
if ((bo & 0x4) == 0)
gen_op_dec_ctr();
switch(type) {
if ((bo & 0x4) == 0)
gen_op_dec_ctr();
switch(type) {
@@
-1683,14
+1689,15
@@
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
#else
/* Restore CPU state */
if (!ctx->supervisor) {
#else
/* Restore CPU state */
if (!ctx->supervisor) {
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
+ return;
}
gen_op_rfi();
}
gen_op_rfi();
- ctx->exception = EXCP_RFI;
+ RET_EXCP(ctx, EXCP_RFI, 0);
#endif
}
#endif
}
@@
-1698,11
+1705,10
@@
GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
{
#if defined(CONFIG_USER_ONLY)
- gen_op_queue_exception(EXCP_SYSCALL_USER);
+ RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
#else
#else
- gen_op_queue_exception(EXCP_SYSCALL);
+ RET_EXCP(ctx, EXCP_SYSCALL, 0);
#endif
#endif
- ctx->exception = EXCP_SYSCALL;
}
/*** Trap ***/
}
/*** Trap ***/
@@
-1770,10
+1776,11
@@
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
+ return;
}
gen_op_load_msr();
gen_op_store_T0_gpr(rD(ctx->opcode));
}
gen_op_load_msr();
gen_op_store_T0_gpr(rD(ctx->opcode));
@@
-1792,11
+1799,11
@@
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
#endif
{
case -1:
#endif
{
case -1:
- RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
- break;
+ RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
+ return;
case 0:
case 0:
- RET_PRIVREG();
- break;
+ RET_PRIVREG(ctx);
+ return;
default:
break;
}
default:
break;
}
@@
-1910,19
+1917,13
@@
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
gen_op_load_sdr1();
break;
case V_TBL:
gen_op_load_sdr1();
break;
case V_TBL:
- gen_op_update_tb(ctx->tb_offset);
- ctx->tb_offset = 0;
- /* TBL is still in T0 */
+ gen_op_load_tbl();
break;
case V_TBU:
break;
case V_TBU:
- gen_op_update_tb(ctx->tb_offset);
- ctx->tb_offset = 0;
- gen_op_load_tb(1);
+ gen_op_load_tbu();
break;
case DECR:
break;
case DECR:
- gen_op_update_decr(ctx->decr_offset);
- ctx->decr_offset = 0;
- /* decr is still in T0 */
+ gen_op_load_decr();
break;
default:
gen_op_load_spr(sprn);
break;
default:
gen_op_load_spr(sprn);
@@
-1939,18
+1940,15
@@
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
/* We need to update the time base before reading it */
switch (sprn) {
case V_TBL:
/* We need to update the time base before reading it */
switch (sprn) {
case V_TBL:
- gen_op_update_tb(ctx->tb_offset);
- /* TBL is still in T0 */
+ gen_op_load_tbl();
break;
case V_TBU:
break;
case V_TBU:
- gen_op_update_tb(ctx->tb_offset);
- gen_op_load_tb(1);
+ gen_op_load_tbu();
break;
default:
break;
default:
- RET_INVAL();
- break;
+ RET_INVAL(ctx);
+ return;
}
}
- ctx->tb_offset = 0;
gen_op_store_T0_gpr(rD(ctx->opcode));
}
gen_op_store_T0_gpr(rD(ctx->opcode));
}
@@
-1965,15
+1963,16
@@
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
+ return;
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_store_msr();
/* Must stop the translation as machine state (may have) changed */
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_store_msr();
/* Must stop the translation as machine state (may have) changed */
- ctx->exception = EXCP_MTMSR;
+ RET_MTMSR(ctx);
#endif
}
#endif
}
@@
-1995,10
+1994,10
@@
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
#endif
{
case -1:
#endif
{
case -1:
- RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
+ RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
break;
case 0:
break;
case 0:
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
break;
default:
break;
break;
default:
break;
@@
-2016,148
+2015,150
@@
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
break;
case IBAT0U:
gen_op_store_ibat(0, 0);
break;
case IBAT0U:
gen_op_store_ibat(0, 0);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT1U:
gen_op_store_ibat(0, 1);
break;
case IBAT1U:
gen_op_store_ibat(0, 1);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT2U:
gen_op_store_ibat(0, 2);
break;
case IBAT2U:
gen_op_store_ibat(0, 2);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT3U:
gen_op_store_ibat(0, 3);
break;
case IBAT3U:
gen_op_store_ibat(0, 3);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT4U:
gen_op_store_ibat(0, 4);
break;
case IBAT4U:
gen_op_store_ibat(0, 4);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT5U:
gen_op_store_ibat(0, 5);
break;
case IBAT5U:
gen_op_store_ibat(0, 5);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT6U:
gen_op_store_ibat(0, 6);
break;
case IBAT6U:
gen_op_store_ibat(0, 6);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT7U:
gen_op_store_ibat(0, 7);
break;
case IBAT7U:
gen_op_store_ibat(0, 7);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT0L:
gen_op_store_ibat(1, 0);
break;
case IBAT0L:
gen_op_store_ibat(1, 0);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT1L:
gen_op_store_ibat(1, 1);
break;
case IBAT1L:
gen_op_store_ibat(1, 1);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT2L:
gen_op_store_ibat(1, 2);
break;
case IBAT2L:
gen_op_store_ibat(1, 2);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT3L:
gen_op_store_ibat(1, 3);
break;
case IBAT3L:
gen_op_store_ibat(1, 3);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT4L:
gen_op_store_ibat(1, 4);
break;
case IBAT4L:
gen_op_store_ibat(1, 4);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT5L:
gen_op_store_ibat(1, 5);
break;
case IBAT5L:
gen_op_store_ibat(1, 5);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT6L:
gen_op_store_ibat(1, 6);
break;
case IBAT6L:
gen_op_store_ibat(1, 6);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case IBAT7L:
gen_op_store_ibat(1, 7);
break;
case IBAT7L:
gen_op_store_ibat(1, 7);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT0U:
gen_op_store_dbat(0, 0);
break;
case DBAT0U:
gen_op_store_dbat(0, 0);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT1U:
gen_op_store_dbat(0, 1);
break;
case DBAT1U:
gen_op_store_dbat(0, 1);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT2U:
gen_op_store_dbat(0, 2);
break;
case DBAT2U:
gen_op_store_dbat(0, 2);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT3U:
gen_op_store_dbat(0, 3);
break;
case DBAT3U:
gen_op_store_dbat(0, 3);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT4U:
gen_op_store_dbat(0, 4);
break;
case DBAT4U:
gen_op_store_dbat(0, 4);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT5U:
gen_op_store_dbat(0, 5);
break;
case DBAT5U:
gen_op_store_dbat(0, 5);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT6U:
gen_op_store_dbat(0, 6);
break;
case DBAT6U:
gen_op_store_dbat(0, 6);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT7U:
gen_op_store_dbat(0, 7);
break;
case DBAT7U:
gen_op_store_dbat(0, 7);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT0L:
gen_op_store_dbat(1, 0);
break;
case DBAT0L:
gen_op_store_dbat(1, 0);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT1L:
gen_op_store_dbat(1, 1);
break;
case DBAT1L:
gen_op_store_dbat(1, 1);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT2L:
gen_op_store_dbat(1, 2);
break;
case DBAT2L:
gen_op_store_dbat(1, 2);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT3L:
gen_op_store_dbat(1, 3);
break;
case DBAT3L:
gen_op_store_dbat(1, 3);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT4L:
gen_op_store_dbat(1, 4);
break;
case DBAT4L:
gen_op_store_dbat(1, 4);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT5L:
gen_op_store_dbat(1, 5);
break;
case DBAT5L:
gen_op_store_dbat(1, 5);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT6L:
gen_op_store_dbat(1, 6);
break;
case DBAT6L:
gen_op_store_dbat(1, 6);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case DBAT7L:
gen_op_store_dbat(1, 7);
break;
case DBAT7L:
gen_op_store_dbat(1, 7);
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case SDR1:
gen_op_store_sdr1();
break;
case SDR1:
gen_op_store_sdr1();
- gen_op_tlbia();
+ RET_MTMSR(ctx);
break;
case O_TBL:
break;
case O_TBL:
- gen_op_store_tb(0);
- ctx->tb_offset = 0;
+ gen_op_store_tbl();
break;
case O_TBU:
break;
case O_TBU:
- gen_op_store_tb(1);
- ctx->tb_offset = 0;
+ gen_op_store_tbu();
break;
case DECR:
gen_op_store_decr();
break;
case DECR:
gen_op_store_decr();
- ctx->decr_offset = 0;
break;
break;
+#if 0
+ case HID0:
+ gen_op_store_hid0();
+ break;
+#endif
default:
gen_op_store_spr(sprn);
break;
default:
gen_op_store_spr(sprn);
break;
@@
-2186,10
+2187,11
@@
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
+ return;
}
if (rA(ctx->opcode) == 0) {
gen_op_load_gpr_T0(rB(ctx->opcode));
}
if (rA(ctx->opcode) == 0) {
gen_op_load_gpr_T0(rB(ctx->opcode));
@@
-2247,6
+2249,7
@@
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
gen_op_add();
}
op_dcbz();
gen_op_add();
}
op_dcbz();
+ gen_op_check_reservation();
}
/* icbi */
}
/* icbi */
@@
-2274,10
+2277,11
@@
GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE_OPT)
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
+ return;
}
gen_op_load_sr(SR(ctx->opcode));
gen_op_store_T0_gpr(rD(ctx->opcode));
}
gen_op_load_sr(SR(ctx->opcode));
gen_op_store_T0_gpr(rD(ctx->opcode));
@@
-2288,10
+2292,11
@@
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
+ return;
}
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_load_srin();
}
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_load_srin();
@@
-2303,14
+2308,14
@@
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
+ return;
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_store_sr(SR(ctx->opcode));
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_store_sr(SR(ctx->opcode));
- gen_op_tlbia();
#endif
}
#endif
}
@@
-2318,15
+2323,15
@@
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVREG();
+ RET_PRIVREG(ctx);
+ return;
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_store_srin();
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_store_srin();
- gen_op_tlbia();
#endif
}
#endif
}
@@
-2336,12
+2341,16
@@
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVOPC();
+ if (loglevel)
+ fprintf(logfile, "%s: ! supervisor\n", __func__);
+ RET_PRIVOPC(ctx);
+ return;
}
gen_op_tlbia();
}
gen_op_tlbia();
+ RET_MTMSR(ctx);
#endif
}
#endif
}
@@
-2349,13
+2358,15
@@
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
+ return;
}
gen_op_load_gpr_T0(rB(ctx->opcode));
gen_op_tlbie();
}
gen_op_load_gpr_T0(rB(ctx->opcode));
gen_op_tlbie();
+ RET_MTMSR(ctx);
#endif
}
#endif
}
@@
-2363,14
+2374,16
@@
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM)
{
#if defined(CONFIG_USER_ONLY)
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
#else
if (!ctx->supervisor) {
#else
if (!ctx->supervisor) {
- RET_PRIVOPC();
+ RET_PRIVOPC(ctx);
+ return;
}
/* This has no effect: it should ensure that all previous
* tlbie have completed
*/
}
/* This has no effect: it should ensure that all previous
* tlbie have completed
*/
+ RET_MTMSR(ctx);
#endif
}
#endif
}
@@
-2691,59
+2704,78
@@
static void init_spr_rights (uint32_t pvr)
spr_set_rights(DBAT3U, SPR_SR | SPR_SW);
/* DBAT3L (SPR 543) */
spr_set_rights(DBAT3L, SPR_SR | SPR_SW);
spr_set_rights(DBAT3U, SPR_SR | SPR_SW);
/* DBAT3L (SPR 543) */
spr_set_rights(DBAT3L, SPR_SR | SPR_SW);
- /* DABR (SPR 1013) */
- spr_set_rights(DABR, SPR_SR | SPR_SW);
/* FPECR (SPR 1022) */
spr_set_rights(FPECR, SPR_SR | SPR_SW);
/* FPECR (SPR 1022) */
spr_set_rights(FPECR, SPR_SR | SPR_SW);
- /* PIR (SPR 1023) */
+ /* Special registers for PPC 604 */
+ if ((pvr & 0xFFFF0000) == 0x00040000) {
+ /* IABR */
+ spr_set_rights(IABR , SPR_SR | SPR_SW);
+ /* DABR (SPR 1013) */
+ spr_set_rights(DABR, SPR_SR | SPR_SW);
+ /* HID0 */
+ spr_set_rights(HID0, SPR_SR | SPR_SW);
+ /* PIR */
spr_set_rights(PIR, SPR_SR | SPR_SW);
spr_set_rights(PIR, SPR_SR | SPR_SW);
+ /* PMC1 */
+ spr_set_rights(PMC1, SPR_SR | SPR_SW);
+ /* PMC2 */
+ spr_set_rights(PMC2, SPR_SR | SPR_SW);
+ /* MMCR0 */
+ spr_set_rights(MMCR0, SPR_SR | SPR_SW);
+ /* SIA */
+ spr_set_rights(SIA, SPR_SR | SPR_SW);
+ /* SDA */
+ spr_set_rights(SDA, SPR_SR | SPR_SW);
+ }
/* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */
if ((pvr & 0xFFFF0000) == 0x00080000 ||
(pvr & 0xFFFF0000) == 0x70000000) {
/* HID0 */
/* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */
if ((pvr & 0xFFFF0000) == 0x00080000 ||
(pvr & 0xFFFF0000) == 0x70000000) {
/* HID0 */
- spr_set_rights(SPR_ENCODE(1008), SPR_SR | SPR_SW);
+ spr_set_rights(HID0, SPR_SR | SPR_SW);
/* HID1 */
/* HID1 */
- spr_set_rights(SPR_ENCODE(1009), SPR_SR | SPR_SW);
+ spr_set_rights(HID1, SPR_SR | SPR_SW);
/* IABR */
/* IABR */
- spr_set_rights(SPR_ENCODE(1010), SPR_SR | SPR_SW);
+ spr_set_rights(IABR, SPR_SR | SPR_SW);
/* ICTC */
/* ICTC */
- spr_set_rights(SPR_ENCODE(1019), SPR_SR | SPR_SW);
+ spr_set_rights(ICTC, SPR_SR | SPR_SW);
/* L2CR */
/* L2CR */
- spr_set_rights(SPR_ENCODE(1017), SPR_SR | SPR_SW);
+ spr_set_rights(L2CR, SPR_SR | SPR_SW);
/* MMCR0 */
/* MMCR0 */
- spr_set_rights(SPR_ENCODE(952), SPR_SR | SPR_SW);
+ spr_set_rights(MMCR0, SPR_SR | SPR_SW);
/* MMCR1 */
/* MMCR1 */
- spr_set_rights(SPR_ENCODE(956), SPR_SR | SPR_SW);
+ spr_set_rights(MMCR1, SPR_SR | SPR_SW);
/* PMC1 */
/* PMC1 */
- spr_set_rights(SPR_ENCODE(953), SPR_SR | SPR_SW);
+ spr_set_rights(PMC1, SPR_SR | SPR_SW);
/* PMC2 */
/* PMC2 */
- spr_set_rights(SPR_ENCODE(954), SPR_SR | SPR_SW);
+ spr_set_rights(PMC2, SPR_SR | SPR_SW);
/* PMC3 */
/* PMC3 */
- spr_set_rights(SPR_ENCODE(957), SPR_SR | SPR_SW);
+ spr_set_rights(PMC3, SPR_SR | SPR_SW);
/* PMC4 */
/* PMC4 */
- spr_set_rights(SPR_ENCODE(958), SPR_SR | SPR_SW);
+ spr_set_rights(PMC4, SPR_SR | SPR_SW);
/* SIA */
/* SIA */
- spr_set_rights(SPR_ENCODE(955), SPR_SR | SPR_SW);
+ spr_set_rights(SIA, SPR_SR | SPR_SW);
+ /* SDA */
+ spr_set_rights(SDA, SPR_SR | SPR_SW);
/* THRM1 */
/* THRM1 */
- spr_set_rights(SPR_ENCODE(1020), SPR_SR | SPR_SW);
+ spr_set_rights(THRM1, SPR_SR | SPR_SW);
/* THRM2 */
/* THRM2 */
- spr_set_rights(SPR_ENCODE(1021), SPR_SR | SPR_SW);
+ spr_set_rights(THRM2, SPR_SR | SPR_SW);
/* THRM3 */
/* THRM3 */
- spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW);
+ spr_set_rights(THRM3, SPR_SR | SPR_SW);
/* UMMCR0 */
/* UMMCR0 */
- spr_set_rights(SPR_ENCODE(936), SPR_UR | SPR_UW);
+ spr_set_rights(UMMCR0, SPR_UR | SPR_UW);
/* UMMCR1 */
/* UMMCR1 */
- spr_set_rights(SPR_ENCODE(940), SPR_UR | SPR_UW);
+ spr_set_rights(UMMCR1, SPR_UR | SPR_UW);
/* UPMC1 */
/* UPMC1 */
- spr_set_rights(SPR_ENCODE(937), SPR_UR | SPR_UW);
+ spr_set_rights(UPMC1, SPR_UR | SPR_UW);
/* UPMC2 */
/* UPMC2 */
- spr_set_rights(SPR_ENCODE(938), SPR_UR | SPR_UW);
+ spr_set_rights(UPMC2, SPR_UR | SPR_UW);
/* UPMC3 */
/* UPMC3 */
- spr_set_rights(SPR_ENCODE(941), SPR_UR | SPR_UW);
+ spr_set_rights(UPMC3, SPR_UR | SPR_UW);
/* UPMC4 */
/* UPMC4 */
- spr_set_rights(SPR_ENCODE(942), SPR_UR | SPR_UW);
+ spr_set_rights(UPMC4, SPR_UR | SPR_UW);
/* USIA */
/* USIA */
- spr_set_rights(SPR_ENCODE(939), SPR_UR | SPR_UW);
+ spr_set_rights(USIA, SPR_UR | SPR_UW);
}
/* MPC755 has special registers */
if (pvr == 0x00083100) {
}
/* MPC755 has special registers */
if (pvr == 0x00083100) {
@@
-2788,23
+2820,23
@@
static void init_spr_rights (uint32_t pvr)
/* DBAT7L */
spr_set_rights(DBAT7L, SPR_SR | SPR_SW);
/* DMISS */
/* DBAT7L */
spr_set_rights(DBAT7L, SPR_SR | SPR_SW);
/* DMISS */
- spr_set_rights(SPR_ENCODE(976), SPR_SR | SPR_SW);
+ spr_set_rights(DMISS, SPR_SR | SPR_SW);
/* DCMP */
/* DCMP */
- spr_set_rights(SPR_ENCODE(977), SPR_SR | SPR_SW);
+ spr_set_rights(DCMP, SPR_SR | SPR_SW);
/* DHASH1 */
/* DHASH1 */
- spr_set_rights(SPR_ENCODE(978), SPR_SR | SPR_SW);
+ spr_set_rights(DHASH1, SPR_SR | SPR_SW);
/* DHASH2 */
/* DHASH2 */
- spr_set_rights(SPR_ENCODE(979), SPR_SR | SPR_SW);
+ spr_set_rights(DHASH2, SPR_SR | SPR_SW);
/* IMISS */
/* IMISS */
- spr_set_rights(SPR_ENCODE(980), SPR_SR | SPR_SW);
+ spr_set_rights(IMISS, SPR_SR | SPR_SW);
/* ICMP */
/* ICMP */
- spr_set_rights(SPR_ENCODE(981), SPR_SR | SPR_SW);
+ spr_set_rights(ICMP, SPR_SR | SPR_SW);
/* RPA */
/* RPA */
- spr_set_rights(SPR_ENCODE(982), SPR_SR | SPR_SW);
+ spr_set_rights(RPA, SPR_SR | SPR_SW);
/* HID2 */
/* HID2 */
- spr_set_rights(SPR_ENCODE(1011), SPR_SR | SPR_SW);
+ spr_set_rights(HID2, SPR_SR | SPR_SW);
/* L2PM */
/* L2PM */
- spr_set_rights(SPR_ENCODE(1016), SPR_SR | SPR_SW);
+ spr_set_rights(L2PM, SPR_SR | SPR_SW);
}
}
}
}
@@
-2885,7
+2917,6
@@
static int create_ppc_proc (opc_handler_t **ppc_opcodes, unsigned long pvr)
/*****************************************************************************/
/* Misc PPC helpers */
/*****************************************************************************/
/* Misc PPC helpers */
-FILE *stdout;
void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
{
void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
{
@@
-2916,7
+2947,8
@@
void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
}
fprintf(f, " ] ");
fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
}
fprintf(f, " ] ");
- fprintf(f, "TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);
+ fprintf(f, "TB: 0x%08x %08x\n", cpu_ppc_load_tbu(env),
+ cpu_ppc_load_tbl(env));
for (i = 0; i < 16; i++) {
if ((i & 3) == 0)
fprintf(f, "FPR%02d:", i);
for (i = 0; i < 16; i++) {
if ((i & 3) == 0)
fprintf(f, "FPR%02d:", i);
@@
-2924,8
+2956,8
@@
void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
if ((i & 3) == 3)
fprintf(f, "\n");
}
if ((i & 3) == 3)
fprintf(f, "\n");
}
- fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x excp:0x%08x\n",
- env->spr[SRR0], env->spr[SRR1], env->decr, env->exceptions);
+ fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x\n",
+ env->spr[SRR0], env->spr[SRR1], cpu_ppc_load_decr(env));
fprintf(f, "reservation 0x%08x\n", env->reserve);
fflush(f);
}
fprintf(f, "reservation 0x%08x\n", env->reserve);
fflush(f);
}
@@
-2940,10
+2972,9
@@
CPUPPCState *cpu_ppc_init(void)
cpu_exec_init();
cpu_exec_init();
- env = malloc(sizeof(CPUPPCState));
+ env = qemu_mallocz(sizeof(CPUPPCState));
if (!env)
return NULL;
if (!env)
return NULL;
- memset(env, 0, sizeof(CPUPPCState));
#if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE)
setup_machine(env, 0);
#else
#if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE)
setup_machine(env, 0);
#else
@@
-2952,23
+2983,34
@@
CPUPPCState *cpu_ppc_init(void)
// env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
// env->spr[PVR] = 0x00070100; /* IBM 750FX */
#endif
// env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
// env->spr[PVR] = 0x00070100; /* IBM 750FX */
#endif
- env->decr = 0xFFFFFFFF;
- if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0)
- return NULL;
- init_spr_rights(env->spr[PVR]);
tlb_flush(env, 1);
#if defined (DO_SINGLE_STEP)
/* Single step trace mode */
msr_se = 1;
#endif
tlb_flush(env, 1);
#if defined (DO_SINGLE_STEP)
/* Single step trace mode */
msr_se = 1;
#endif
+ msr_fp = 1; /* Allow floating point exceptions */
+ msr_me = 1; /* Allow machine check exceptions */
#if defined(CONFIG_USER_ONLY)
msr_pr = 1;
#if defined(CONFIG_USER_ONLY)
msr_pr = 1;
+ cpu_ppc_register(env, 0x00080000);
+#else
+ env->nip = 0xFFFFFFFC;
#endif
env->access_type = ACCESS_INT;
#endif
env->access_type = ACCESS_INT;
-
+ cpu_single_env = env;
return env;
}
return env;
}
+int cpu_ppc_register (CPUPPCState *env, uint32_t pvr)
+{
+ env->spr[PVR] = pvr;
+ if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0)
+ return -1;
+ init_spr_rights(env->spr[PVR]);
+
+ return 0;
+}
+
void cpu_ppc_close(CPUPPCState *env)
{
/* Should also remove all opcode tables... */
void cpu_ppc_close(CPUPPCState *env)
{
/* Should also remove all opcode tables... */
@@
-2976,14
+3018,13
@@
void cpu_ppc_close(CPUPPCState *env)
}
/*****************************************************************************/
}
/*****************************************************************************/
-void raise_exception_err (int exception_index, int error_code);
int print_insn_powerpc (FILE *out, unsigned long insn, unsigned memaddr,
int dialect);
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
int search_pc)
{
int print_insn_powerpc (FILE *out, unsigned long insn, unsigned memaddr,
int dialect);
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
int search_pc)
{
- DisasContext ctx;
+ DisasContext ctx, *ctxp = &ctx;
opc_handler_t **table, *handler;
uint32_t pc_start;
uint16_t *gen_opc_end;
opc_handler_t **table, *handler;
uint32_t pc_start;
uint16_t *gen_opc_end;
@@
-2994,8
+3035,6
@@
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
gen_opparam_ptr = gen_opparam_buf;
ctx.nip = pc_start;
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
gen_opparam_ptr = gen_opparam_buf;
ctx.nip = pc_start;
- ctx.tb_offset = 0;
- ctx.decr_offset = 0;
ctx.tb = tb;
ctx.exception = EXCP_NONE;
#if defined(CONFIG_USER_ONLY)
ctx.tb = tb;
ctx.exception = EXCP_NONE;
#if defined(CONFIG_USER_ONLY)
@@
-3023,26
+3062,22
@@
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
gen_opc_instr_start[lj] = 1;
}
}
gen_opc_instr_start[lj] = 1;
}
}
-#if defined DEBUG_DISAS
- if (loglevel > 0) {
+#if defined PPC_DEBUG_DISAS
+ if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "----------------\n");
fprintf(logfile, "nip=%08x super=%d ir=%d\n",
ctx.nip, 1 - msr_pr, msr_ir);
}
#endif
ctx.opcode = ldl_code((void *)ctx.nip);
fprintf(logfile, "----------------\n");
fprintf(logfile, "nip=%08x super=%d ir=%d\n",
ctx.nip, 1 - msr_pr, msr_ir);
}
#endif
ctx.opcode = ldl_code((void *)ctx.nip);
-#if defined DEBUG_DISAS
- if (loglevel > 0) {
+#if defined PPC_DEBUG_DISAS
+ if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n",
ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
opc3(ctx.opcode));
}
#endif
ctx.nip += 4;
fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n",
ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
opc3(ctx.opcode));
}
#endif
ctx.nip += 4;
- ctx.tb_offset++;
- /* Check decrementer exception */
- if (++ctx.decr_offset == env->decr + 1)
- ctx.exception = EXCP_DECR;
table = ppc_opcodes;
handler = table[opc1(ctx.opcode)];
if (is_indirect_opcode(handler)) {
table = ppc_opcodes;
handler = table[opc1(ctx.opcode)];
if (is_indirect_opcode(handler)) {
@@
-3054,26
+3089,26
@@
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
}
}
/* Is opcode *REALLY* valid ? */
}
}
/* Is opcode *REALLY* valid ? */
- if ((ctx.opcode & handler->inval) != 0) {
- if (loglevel > 0) {
if (handler->handler == &gen_invalid) {
if (handler->handler == &gen_invalid) {
+ if (loglevel > 0) {
fprintf(logfile, "invalid/unsupported opcode: "
fprintf(logfile, "invalid/unsupported opcode: "
- "%02x -%02x - %02x (%08x) 0x%08x\n",
+ "%02x - %02x - %02x (%08x) 0x%08x %d\n",
opc1(ctx.opcode), opc2(ctx.opcode),
opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), ctx.opcode, ctx.nip - 4);
+ opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
+ } else {
+ printf("invalid/unsupported opcode: "
+ "%02x - %02x - %02x (%08x) 0x%08x %d\n",
+ opc1(ctx.opcode), opc2(ctx.opcode),
+ opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
+ }
} else {
} else {
+ if ((ctx.opcode & handler->inval) != 0) {
+ if (loglevel > 0) {
fprintf(logfile, "invalid bits: %08x for opcode: "
"%02x -%02x - %02x (0x%08x) (0x%08x)\n",
ctx.opcode & handler->inval, opc1(ctx.opcode),
opc2(ctx.opcode), opc3(ctx.opcode),
ctx.opcode, ctx.nip - 4);
fprintf(logfile, "invalid bits: %08x for opcode: "
"%02x -%02x - %02x (0x%08x) (0x%08x)\n",
ctx.opcode & handler->inval, opc1(ctx.opcode),
opc2(ctx.opcode), opc3(ctx.opcode),
ctx.opcode, ctx.nip - 4);
- }
- } else {
- if (handler->handler == &gen_invalid) {
- printf("invalid/unsupported opcode: "
- "%02x -%02x - %02x (%08x) 0x%08x\n",
- opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), ctx.opcode, ctx.nip - 4);
} else {
printf("invalid bits: %08x for opcode: "
"%02x -%02x - %02x (0x%08x) (0x%08x)\n",
} else {
printf("invalid bits: %08x for opcode: "
"%02x -%02x - %02x (0x%08x) (0x%08x)\n",
@@
-3081,11
+3116,11
@@
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
opc2(ctx.opcode), opc3(ctx.opcode),
ctx.opcode, ctx.nip - 4);
}
opc2(ctx.opcode), opc3(ctx.opcode),
ctx.opcode, ctx.nip - 4);
}
+ RET_INVAL(ctxp);
+ break;
}
}
- (*gen_invalid)(&ctx);
- } else {
- (*(handler->handler))(&ctx);
}
}
+ (*(handler->handler))(&ctx);
/* Check trace mode exceptions */
if ((msr_be && ctx.exception == EXCP_BRANCH) ||
/* Check in single step trace mode
/* Check trace mode exceptions */
if ((msr_be && ctx.exception == EXCP_BRANCH) ||
/* Check in single step trace mode
@@
-3098,26
+3133,17
@@
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
(ctx.nip & 0xFC) != 0x04) &&
ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI &&
ctx.exception != EXCP_TRAP)) {
(ctx.nip & 0xFC) != 0x04) &&
ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI &&
ctx.exception != EXCP_TRAP)) {
-#if !defined(CONFIG_USER_ONLY)
- gen_op_queue_exception(EXCP_TRACE);
-#endif
- if (ctx.exception == EXCP_NONE) {
- ctx.exception = EXCP_TRACE;
- }
+ RET_EXCP(ctxp, EXCP_TRACE, 0);
}
/* if we reach a page boundary, stop generation */
if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
}
/* if we reach a page boundary, stop generation */
if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
- if (ctx.exception == EXCP_NONE) {
- gen_op_b((long)ctx.tb, ctx.nip);
- ctx.exception = EXCP_BRANCH;
+ RET_EXCP(ctxp, EXCP_BRANCH, 0);
}
}
}
}
- }
- /* In case of branch, this has already been done *BEFORE* the branch */
- if (ctx.exception != EXCP_BRANCH && ctx.exception != EXCP_RFI) {
- gen_op_update_tb(ctx.tb_offset);
- gen_op_update_decr(ctx.decr_offset);
- gen_op_process_exceptions(ctx.nip);
+ if (ctx.exception == EXCP_NONE) {
+ gen_op_b((unsigned long)ctx.tb, ctx.nip);
+ } else if (ctx.exception != EXCP_BRANCH) {
+ gen_op_set_T0(0);
}
#if 1
/* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
}
#if 1
/* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
@@
-3142,22
+3168,23
@@
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
} else {
tb->size = ctx.nip - pc_start;
}
} else {
tb->size = ctx.nip - pc_start;
}
- env->access_type = ACCESS_INT;
#ifdef DEBUG_DISAS
#ifdef DEBUG_DISAS
- if (loglevel > 0) {
+ if (loglevel & CPU_LOG_TB_CPU) {
fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
cpu_ppc_dump_state(env, logfile, 0);
fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
cpu_ppc_dump_state(env, logfile, 0);
+ }
+ if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
-#if defined(CONFIG_USER_ONLY)
disas(logfile, (void *)pc_start, ctx.nip - pc_start, 0, 0);
disas(logfile, (void *)pc_start, ctx.nip - pc_start, 0, 0);
-#endif
fprintf(logfile, "\n");
fprintf(logfile, "\n");
-
+ }
+ if (loglevel & CPU_LOG_TB_OP) {
fprintf(logfile, "OP:\n");
dump_ops(gen_opc_buf, gen_opparam_buf);
fprintf(logfile, "\n");
}
#endif
fprintf(logfile, "OP:\n");
dump_ops(gen_opc_buf, gen_opparam_buf);
fprintf(logfile, "\n");
}
#endif
+ env->access_type = ACCESS_INT;
return 0;
}
return 0;
}