📄 codeseq.c
字号:
/* Precoditions: Core must have been alerted we
* are in CodeSeq mode, else we risk breakpoints. */
static int Codeseq_RunCode(CodeseqState *state, ARMword stop_pc)
{
ARMword pc;
int err;
do {
err = ARMulif_Step1(&state->coredesc);
pc = ARMulif_GetPC(&state->coredesc);
if (err!=RDIError_NoError) {
if (state->verbose) {
Hostif_ConsolePrint(
state->hostif,
"Warning, codeseq ARMulif_Step1 returns %d\n",err);
}
}
} while (pc >= state->base_address && pc < stop_pc);
if (pc < state->base_address) {
if (state->verbose) {
Hostif_ConsolePrint(
state->hostif,
"Warning, codeseq pc(0x%08x) < base_address(0x%08x)\n",
pc,state->base_address);
Hostif_ConsolePrint(
state->hostif,
" stop_pc=0x%08x, stored pc=0x%08x\n",
stop_pc,state->RegsSavedForRunCodeSequence[15]);
}
err = RDIError_Error;
}
return err;
}
static int Codeseq_RunCodeSequence(CodeseqState *state,
const RDICodeSequence_Data *cs)
{
int rv = RDIError_NoError;
ARMWord OldCPSR = ARMulif_GetCPSR(&state->coredesc);
ARMWord NewCPSR = OldCPSR;
ARMword coremode = OldCPSR & 0x1f ;
ARMWord OldSPSR = ARMulif_GetSPSR(&state->coredesc,coremode);
unsigned i, mode = (unsigned)cs->mode;
ARMul_MemInterface *mif;
uint32 ID[2];
if (cs->numInstructions <= 0)
return RDIError_NoError;
/* Check we understand ISET */
if ((unsigned)cs->iset > 3)
{
return RDIError_BadCPUStateSetting;
}
#ifdef VERBOSE_SDM
Hostif_ConsolePrint(state->hostif,"Begin_Codeseq iset:%u numisntrs:%u",
(unsigned)cs->iset,
(unsigned)cs->numInstructions);
#endif
state->instr_size = (cs->iset & 1) ? 2 : 4;
state->base_address = 0x80000000;
state->stop_pc = state->base_address +
state->instr_size * cs->numInstructions +
4*7; /* For the "nop" instrs to wait for LDR's to complete. */
/*
* Insert mem interface and set up
*/
ID[0] = ARMulBusID_Core;
ID[1] = 0;
mif = ARMulif_QueryMemInterface(&state->coredesc, &ID[0]);
if (mif)
{ /* start if */
state->bus_mem.handle = state;
state->bus_mem.x.basic.access = Codeseq_MemAccess;
/* <Copy info thru. */
state->bus_mem.mem_info=CodeseqMemInfo;
state->bus_mem.read_clock=CodeseqReadClock;
state->bus_mem.read_cycles=CodeseqReadCycles;
state->bus_mem.get_cycle_length = CodeseqGetCycleLength;
/* </> */
switch(mif->memtype)
{
case ARMul_MemType_Basic:
case ARMul_MemType_16Bit:
case ARMul_MemType_Thumb:
/* case ARMul_MemType_BasicCached:*/
case ARMul_MemType_16BitCached:
case ARMul_MemType_ThumbCached:
case ARMul_MemType_ARMissAHB:
break;
case ARMul_MemType_AHB:
break;
case ARMul_MemType_StrongARM:
state->bus_mem.x.strongarm.access = Codeseq_MemAccessSA;
state->bus_mem.x.strongarm.core_exception = CodeseqCoreException;
state->bus_mem.x.strongarm.data_cache_busy = CodeseqDataCacheBusy;
break;
case ARMul_MemType_ARM8:
state->bus_mem.x.arm8.core_exception = CodeseqCoreException;
state->bus_mem.x.arm8.access2 = Codeseq_MemAccess2;
break;
case ARMul_MemType_ARMissCache:
break;
case ARMul_MemType_ARM9: /* ARM9 Harvard */
state->bus_mem.x.arm9.harvard_access = Codeseq_MemAccessHarvard;
break;
case ARMul_MemType_ByteLanes:
default:
break;
}
}
ARMul_InsertMemInterface(mif,
&state->child,
&state->mem_ref,
&state->bus_mem);
/*
* memory model inserted - set up core and run code
*/
/* Save PC because it may have low bits mangled if e.g.
* we switch out of thumb mode. */
state->RegsSavedForRunCodeSequence[15] =
ARMulif_GetReg(&state->coredesc,coremode, 15);
/* use broadcast event here to get cores + models to save cycle counts */
ARMulif_RaiseEvent(&state->coredesc,DebugEvent_RunCodeSequence,
(cs->iset & 1),0);
/* BEGIN FINISH ANY OUTSTANDING LDR's */
{
/* Execute MOV R0,R0 .. MOV R14,R14 */
ARMulif_SetReg(&state->coredesc, RDIMode_Curr, 16, state->base_address);
NewCPSR = (OldCPSR & ~ARM_PSR_T & ~ARM_PSR_J);
ARMulif_SetCPSR(&state->coredesc, NewCPSR);
state->InPreamble = 1;
rv = Codeseq_RunCode(state, state->base_address+4*14);
state->InPreamble = 0;
}
/* END FINISH ANY OUTSTANDING LDR's */
/* Compute new mode */
if (mode > RDICodeSequenceMode_System)
mode = RDICodeSequenceMode_System;
NewCPSR = (OldCPSR & ~ARM_PSR_M & ~ARM_PSR_T & ~ARM_PSR_J) | mode;
if (state->instr_size == 2) NewCPSR |= ARM_PSR_T;
/* Change to new mode and instruction-set. */
ARMulif_SetCPSR(&state->coredesc, NewCPSR);
/* NB By this stage, PC==R15 may be corrupted by the mode change.
* (In ARM9 models, the corruption is odder than expected.) */
#ifdef VERBOSE_SAVEDREGS
Hostif_ConsolePrint(state->hostif,"Saved regs for mode 0x%02x (now mode=%04x): R15:%08x",
(unsigned)coremode, (unsigned)NewCPSR,
(unsigned)state->RegsSavedForRunCodeSequence[15]);
#endif
for (i=0; i<15; i++)
{
state->RegsSavedForRunCodeSequence[i] =
ARMulif_GetReg(&state->coredesc,coremode, i);
#ifdef VERBOSE_SAVEDREGS
Hostif_ConsolePrint(state->hostif," %u:%08x", i,
(unsigned)state->RegsSavedForRunCodeSequence[i]);
#endif
}
#ifdef VERBOSE_SAVEDREGS
Hostif_ConsolePrint(state->hostif,"\n");
#endif
/* Write PC to a fixed value, for debugging.
* NB ARMulator ARM9 models distinguish between
* 15 : R15 and
* 16 : PC (writing this flushes the Execute stage).
*/
ARMulif_SetReg(&state->coredesc, RDIMode_Curr, 16, state->base_address);
/* Write the input registers */
{ unsigned i;
for (i=0;i<cs->numDataIn;i++)
ARMulif_SetReg(&state->coredesc, coremode, i, cs->dataIn[i]);
}
state->CodeSequenceToRun = *cs;
{
# ifdef VERBOSE_CODESEQ
Hostif_ConsolePrint(state->hostif, "Starting codeseq\n");
# endif
#ifdef OldCode
err = ARMulif_Execute(&state->coredesc, FALSE);
#else
rv = Codeseq_RunCode(state, state->stop_pc);
#endif
# ifdef VERBOSE_CODESEQ
Hostif_ConsolePrint(state->hostif, "Finished codeseq\n");
# endif
}
/*
* Code has been run we now need to restore the core to its
* previous state
*/
/* Read data out of the registers */
for (i=0;i<cs->numDataOut;i++)
{
cs->dataOut[i] = ARMulif_GetReg(&state->coredesc, coremode, i);
}
for (i=0; i<15; i++)
{
ARMulif_SetReg(&state->coredesc, coremode, i,
state->RegsSavedForRunCodeSequence[i]);
}
ARMulif_SetCPSR(&state->coredesc, OldCPSR);
ARMulif_SetSPSR(&state->coredesc, coremode, OldSPSR);
/* for r15, write to 16 which also flushes execute stage on 9s */
ARMulif_SetReg(&state->coredesc, coremode, 16,
state->RegsSavedForRunCodeSequence[15]);
ARMulif_RaiseEvent(&state->coredesc,DebugEvent_EndCodeSequence,
0/* use OldCPSR and T bit */,0);
assert(state->mem_ref.mif);
if (state->mem_ref.mif)
{
ARMul_RemoveMemInterface(&state->mem_ref,&state->child);
}
return rv; /* RDIError_NoError; */
}
static int CodeSeq_RDI_info(void *handle,unsigned type,ARMword *arg1,
ARMword *arg2)
{
CodeseqState *state = (CodeseqState *)handle;
UNUSEDARG(arg2);
switch (type) {
case RDIInfo_CodeSequenceInquiry:
{
return RDIError_NoError;
}
case RDIInfo_CodeSequence:
{
const RDICodeSequence_Data *cs = (const RDICodeSequence_Data *)arg1;
return Codeseq_RunCodeSequence(state,cs);
}
default:
break;
}
return RDIError_UnimplementedMessage;
}
static unsigned Codeseq_ConfigEvents(void *handle, void *data)
{
CodeseqState *ts = handle;
ARMul_Event *evt = data;
UNUSEDARG(ts);
if (evt->event != ConfigEvent_Reset)
return FALSE;
return FALSE; /* Carry on */
}
BEGIN_INIT(Codeseq)
{
CodeseqState *cs = state;
if (coldboot)
{
Hostif_PrettyPrint(hostif, config, ", RDI Codesequences");
ARMulif_InstallUnkRDIInfoHandler(&cs->coredesc,
CodeSeq_RDI_info, cs);
ARMulif_InstallEventHandler(&state->coredesc,
ConfigEventSel,
Codeseq_ConfigEvents, cs);
}
state->verbose = ToolConf_DLookupBool(config,(tag_t)"VERBOSE",FALSE);
}
END_INIT(Codeseq)
BEGIN_EXIT(Codeseq)
{
CodeseqState *cs=state;
UNUSEDARG(cs);
}
END_EXIT(Codeseq)
/*--- <SORDI STUFF> ---*/
#define SORDI_DLL_DESCRIPTION_STRING "CodeSeq (a Utility)"
#define SORDI_RDI_PROCVEC Codeseq_AgentRDI
#include "perip_sordi.h"
#include "perip_rdi_agent.h"
IMPLEMENT_AGENT_PROCS_NOEXE_NOMODULE(Codeseq)
IMPLEMENT_AGENT_PROCVEC_NOEXE(Codeseq)
/*--- </> ---*/
/* EOF tracer.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -