From fd8e23dc66710d1fc970e08e754aaee44e54cf30 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Tue, 15 Mar 2005 16:54:13 +0000 Subject: [PATCH] Support for vex-directed instruction-cache invalidation, needed for PowerPC icbi instruction support. git-svn-id: svn://svn.valgrind.org/vex/trunk@1037 --- VEX/priv/guest-ppc32/ghelpers.c | 2 ++ VEX/priv/guest-ppc32/toIR.c | 38 +++++++++++++++++++++++++++------ VEX/priv/host-ppc32/hdefs.c | 1 + VEX/priv/ir/irdefs.c | 1 + VEX/pub/libvex_guest_ppc32.h | 4 ++++ VEX/pub/libvex_ir.h | 10 ++++++++- VEX/pub/libvex_trc_values.h | 3 +++ 7 files changed, 52 insertions(+), 7 deletions(-) diff --git a/VEX/priv/guest-ppc32/ghelpers.c b/VEX/priv/guest-ppc32/ghelpers.c index a40f30baf..a16b809b8 100644 --- a/VEX/priv/guest-ppc32/ghelpers.c +++ b/VEX/priv/guest-ppc32/ghelpers.c @@ -280,6 +280,8 @@ void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state ) vex_state->guest_XER = 0; vex_state->guest_EMWARN = 0; + vex_state->guest_TISTART = 0; + vex_state->guest_TILEN = 0; } diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index 96e7b6efb..659a9aac6 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -154,7 +154,8 @@ static IRBB* irbb; #define OFFB_XER offsetof(VexGuestPPC32State,guest_XER) - +#define OFFB_TISTART offsetof(VexGuestPPC32State,guest_TISTART) +#define OFFB_TILEN offsetof(VexGuestPPC32State,guest_TILEN) /*------------------------------------------------------------*/ @@ -2986,7 +2987,7 @@ static Bool dis_proc_ctl ( UInt theInstr ) } -static Bool dis_cache_manage ( UInt theInstr ) +static Bool dis_cache_manage ( UInt theInstr, DisResult* whatNext ) { /* X-Form */ UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ @@ -3009,7 +3010,7 @@ static Bool dis_cache_manage ( UInt theInstr ) case 0x056: // dcbf (Data Cache Block Flush, PPC32 p382) DIP("dcbf r%d,r%d\n", Ra_addr, Rb_addr); - if (1) vex_printf("vex ppc32->IR: kludged dcbf\n"); + if (0) vex_printf("vex ppc32->IR: kludged dcbf\n"); break; case 0x036: // dcbst (Data Cache Block Store, PPC32 p384) @@ -3032,10 +3033,35 @@ static Bool dis_cache_manage ( UInt theInstr ) if (1) vex_printf("vex ppc32->IR: kludged dcbz\n"); break; - case 0x3D6: // icbi (Instruction Cache Block Invalidate, PPC32 p431) + case 0x3D6: { + // icbi (Instruction Cache Block Invalidate, PPC32 p431) + /* Invalidate all translations containing code from the cache + block at (rA|0) + rB. Since we don't know what the cache + line size is, let's assume 256 -- no real I1 cache would ever + have a line size that large, so that's safe. */ + IRTemp addr = newTemp(Ity_I32); + UInt assumed_line_size = 256; DIP("icbi r%d,r%d\n", Ra_addr, Rb_addr); - if (1) vex_printf("vex ppc32->IR: kludged icbi\n"); + + assign( addr, + binop( Iop_Add32, + getIReg(Rb_addr), + Ra_addr==0 ? mkU32(0) : getIReg(Ra_addr)) ); + + /* Round addr down to the start of the containing block. */ + stmt( IRStmt_Put( + OFFB_TISTART, + binop( Iop_And32, + mkexpr(addr), + mkU32( ~(assumed_line_size-1) ))) ); + + stmt( IRStmt_Put(OFFB_TILEN, mkU32(assumed_line_size) ) ); + + irbb->jumpkind = Ijk_TInval; + irbb->next = mkU32(guest_cia_curr_instr + 4); + *whatNext = Dis_StopHere; break; + } default: vex_printf("dis_cache_manage(PPC32)(opc2)\n"); @@ -3321,7 +3347,7 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, case 0x2F6: case 0x056: case 0x036: // dcba, dcbf, dcbst case 0x116: case 0x0F6: case 0x3F6: // dcbt, dcbtst, dcbz case 0x3D6: // icbi - if (dis_cache_manage( theInstr )) goto decode_success; + if (dis_cache_manage( theInstr, &whatNext )) goto decode_success; goto decode_failure; /* External Control Instructions */ diff --git a/VEX/priv/host-ppc32/hdefs.c b/VEX/priv/host-ppc32/hdefs.c index aa081be23..27e7249a6 100644 --- a/VEX/priv/host-ppc32/hdefs.c +++ b/VEX/priv/host-ppc32/hdefs.c @@ -2307,6 +2307,7 @@ Int emit_PPC32Instr ( UChar* buf, Int nbuf, PPC32Instr* i ) case Ijk_EmWarn: magic_num = VEX_TRC_JMP_EMWARN; break; case Ijk_MapFail: magic_num = VEX_TRC_JMP_MAPFAIL; break; case Ijk_NoDecode: magic_num = VEX_TRC_JMP_NODECODE; break; + case Ijk_TInval: magic_num = VEX_TRC_JMP_TINVAL; break; case Ijk_Ret: case Ijk_Call: case Ijk_Boring: diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index a30076e1d..45f597590 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -569,6 +569,7 @@ void ppIRJumpKind ( IRJumpKind kind ) case Ijk_EmWarn: vex_printf("EmWarn"); break; case Ijk_NoDecode: vex_printf("NoDecode"); break; case Ijk_MapFail: vex_printf("MapFail"); break; + case Ijk_TInval: vex_printf("Invalidate"); break; default: vpanic("ppIRJumpKind"); } } diff --git a/VEX/pub/libvex_guest_ppc32.h b/VEX/pub/libvex_guest_ppc32.h index e46fc0352..395c39faa 100644 --- a/VEX/pub/libvex_guest_ppc32.h +++ b/VEX/pub/libvex_guest_ppc32.h @@ -133,6 +133,10 @@ typedef /* Emulation warnings */ /* 420 */ UInt guest_EMWARN; + /* For icbi: record start and length of area to invalidate */ + /* 424 */ UInt guest_TISTART; + /* 428 */ UInt guest_TILEN; + /* Padding to make it have an 8-aligned size */ /* UInt padding; */ } diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 53e34b5fd..dd4a9def4 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -704,6 +704,13 @@ inline static Bool isAtom ( IRExpr* e ) { /* This describes hints which can be passed to the dispatcher at guest control-flow transfer points. + + Re Ijk_Invalidate: typically the guest state will have two + pseudo-registers, guest_TISTART and guest_TILEN, which + specify the start and length of the region to be invalidated. + It is the responsibility of the relevant toIR.c to ensure that + these are filled in with suitable values before issuing a jump + of kind Ijk_TInval. */ typedef enum { @@ -715,7 +722,8 @@ typedef Ijk_Yield, /* client is yielding to thread scheduler */ Ijk_EmWarn, /* report emulation warning before continuing */ Ijk_NoDecode, /* next instruction cannot be decoded */ - Ijk_MapFail /* Vex-provided address translation failed */ + Ijk_MapFail, /* Vex-provided address translation failed */ + Ijk_TInval /* Invalidate translations before continuing. */ } IRJumpKind; diff --git a/VEX/pub/libvex_trc_values.h b/VEX/pub/libvex_trc_values.h index f928071c1..dc09e64e3 100644 --- a/VEX/pub/libvex_trc_values.h +++ b/VEX/pub/libvex_trc_values.h @@ -44,6 +44,9 @@ This file may get included in assembly code, so do not put C-specific constructs in it. */ + +#define VEX_TRC_JMP_TINVAL 13 /* invalidate translations before + continuing */ #define VEX_TRC_JMP_EMWARN 17 /* deliver emulation warning before continuing */ #define VEX_TRC_JMP_SYSCALL 19 /* do a system call before continuing */