📄 validate.c
字号:
CheckBusyCycles(handle, CP4_WAIT_COUNT), &state->CP4Busy, cycle_count);
}
static int CP1MRRC(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMRRC(handle, type, instr, value, ValCP1Reg[reg], ValCP1Reg[reg2],
CheckBusyCycles(handle, CP1_WAIT_COUNT), &state->CP1Busy, cycle_count);
}
static int CP3MRRC(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMRRC(handle, type, instr, value, ValCP3Reg[reg], ValCP3Reg[reg2],
CheckBusyCycles(handle, CP3_WAIT_COUNT), &state->CP3Busy, cycle_count);
}
static int CP4MRRC(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMRRC(handle, type, instr, value, ValCP4Reg[reg], ValCP4Reg[reg2],
CheckBusyCycles(handle, CP4_WAIT_COUNT), &state->CP4Busy, cycle_count);
}
static int CP5MRC(void *handle, int type, ARMword instr,ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return DoMRC(handle, type, instr, value, state->ValCP5Reg[BITS(16,19)],
CheckBusyCycles(handle, CP5_WAIT_COUNT), &state->CP5Busy, cycle_count);
}
static int CP7MRC(void *handle, int type, ARMword instr,ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return DoMRC(handle, type, instr, value, ValCP7Reg[BITS(16,19)],
CheckBusyCycles(handle, 0), &state->CP7Busy, cycle_count);
}
static int CP7MRRC(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMRRC(handle, type, instr, value, ValCP7Reg[reg], ValCP7Reg[reg2],
CheckBusyCycles(handle, 1), &state->CP7Busy, cycle_count);
}
static int CP8MRC(void *handle, int type, ARMword instr,ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return DoMRC(handle, type, instr, value, ValCP8Reg[BITS(16,19)],
CheckBusyCycles(handle, 0), &state->CP8Busy, cycle_count);
}
static int CP8MRRC(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
#if 0
/* Guessed from armv5te_cpd.s */
if ((instr & 0xF) == 2) /* CRm */
return ARMul_CP_CANT;
#endif
if (state->CP8_BounceNext)
{
state->CP8_BounceNext = 0;
return ARMul_CP_CANT;
}
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMRRC(handle, type, instr, value, ValCP8Reg[reg], ValCP8Reg[reg2],
CheckBusyCycles(handle, 1), &state->CP8Busy, cycle_count);
}
/* MCR instructions for CP 1,3,4,5 7 and 8 - */
/* there are 8 versions to allow variations between CP's, with a single */
/* function (DoMCR) which does all the stuff common to all MCRs */
static int DoMCR(void *handle, int type, ARMword instr, ARMword value,
ARMword *reg_val,
unsigned long busy_cycles, CPBusyWait *CPBusy,
ARMTime cycle_count)
{
int result;
UNUSEDARG(instr); (void)handle;
/* Is this CP currently busy waiting? */
if (busy_cycles && CheckBusyWait(type, CPBusy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
if (type == ARMul_CP_FIRST || result == ARMul_CP_FIRST) {
*reg_val = value;
return ARMul_CP_DONE; /* Complete */
}
return ARMul_CP_BUSY;
}
static int DoMCRR(void *handle, int type, ARMword instr, ARMword *value,
ARMword *reg_val0, ARMword *reg_val1,
unsigned long busy_cycles, CPBusyWait *CPBusy,
ARMTime cycle_count)
{
int result = ARMul_CP_DONE; /* In case busy_cycles == 0 */
UNUSEDARG(instr); (void)handle;
/* Is this CP currently busy waiting? */
if (busy_cycles && CheckBusyWait(type, CPBusy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
if (type == ARMul_CP_FIRST || result == ARMul_CP_FIRST) {
*reg_val0 = value[0];
*reg_val1 = value[1];
return ARMul_CP_DONE; /* 1st transfer */
}
return ARMul_CP_BUSY;
}
static int CP1MCR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return DoMCR(handle, type, instr, value ? *value : 0,
&ValCP1Reg[BITS(16,19)], CheckBusyCycles(handle, CP1_WAIT_COUNT), &state->CP1Busy, cycle_count);
}
static int CP3MCR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return DoMCR(handle, type, instr, value ? *value : 0,
&ValCP3Reg[BITS(16,19)], CheckBusyCycles(handle, CP3_WAIT_COUNT), &state->CP3Busy, cycle_count);
}
static int CP4MCR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return DoMCR(handle, type, instr, value ? *value : 0,
&ValCP4Reg[BITS(16,19)], CheckBusyCycles(handle, CP4_WAIT_COUNT), &state->CP4Busy, cycle_count);
}
static int CP1MCRR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
/*
* This is not part of the validation coprocessor specification.
* It is here to test mcrr and mrcc
* The two coprocessor registers ar Crn and Crn + 1.
* If CRn == 15 the second register is 0
*/
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMCRR(handle, type, instr, value, &ValCP1Reg[reg],&ValCP1Reg[reg2],
CheckBusyCycles(handle, CP1_WAIT_COUNT), &state->CP1Busy, cycle_count);
}
static int CP3MCRR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
/*
* This is not part of the validation coprocessor specification.
* It is here to test mcrr and mrcc
* The two coprocessor registers ar Crn and Crn + 1.
* If CRn == 15 the second register is 0
*/
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMCRR(handle, type, instr, value, &ValCP3Reg[reg],&ValCP3Reg[reg2],
CheckBusyCycles(handle, CP3_WAIT_COUNT), &state->CP3Busy, cycle_count);
}
static int CP4MCRR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
/*
* This is not part of the validation coprocessor specification.
* It is here to test mcrr and mrcc
* The two coprocessor registers ar Crn and Crn + 1.
* If CRn == 15 the second register is 0
*/
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMCRR(handle, type, instr, value, &ValCP4Reg[reg],&ValCP4Reg[reg2],
CheckBusyCycles(handle, 1), &state->CP4Busy, cycle_count);
}
static int CP5MCR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return DoMCR(handle, type, instr, value ? *value : 0,
&state->ValCP5Reg[BITS(16,19)], CheckBusyCycles(handle, CP5_WAIT_COUNT), &state->CP5Busy, cycle_count);
}
/* Adapted from CP4MCRR */
static int CP5MCRR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
ARMword reg = BITS(0,3);
/*
* This is not part of the validation coprocessor specification.
* It is here to test mcrr and mrcc
* The two coprocessor registers ar Crn and Crn + 1.
* If CRn == 15 the second register is 0
*/
ARMword reg2 = (reg < 15) ? reg + 1 : 0;
ARMword op = BITS(4,7);
/* For test v6core_MCRR2_MRRC2 */
if (op == 1)
return ARMul_CP_CANT;
return DoMCRR(handle, type, instr, value, &state->ValCP5Reg[reg],
&state->ValCP5Reg[reg2],
CheckBusyCycles(handle, 1), &state->CP5Busy, cycle_count);
}
/* copied from CP4MRRC */
static int CP5MRRC(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
ARMword reg = BITS(0,3);
ARMword reg2 = (reg < 15) ? reg + 1 : 0;
ARMword op = BITS(4,7);
/* For test v6core_MCRR2_MRRC2 */
if (op == 1)
return ARMul_CP_CANT;
return DoMRRC(handle, type, instr, value,
state->ValCP5Reg[reg], state->ValCP5Reg[reg2],
CheckBusyCycles(handle, CP5_WAIT_COUNT), &state->CP5Busy, cycle_count);
}
static int CP7MCR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return DoMCR(handle, type, instr, value ? *value : 0,
&ValCP7Reg[BITS(16,19)], CheckBusyCycles(handle, 0), &state->CP7Busy, cycle_count);
}
static int CP7MCRR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
/*
* This is not part of the validation coprocessor specification.
* It is here to test mcrr and mrcc
* The two coprocessor registers ar Crn and Crn + 1.
* If CRn == 15 the second register is 0
*/
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMCRR(handle, type, instr, value, &ValCP7Reg[reg],&ValCP7Reg[reg2],
CheckBusyCycles(handle, 1), &state->CP7Busy, cycle_count);
}
static int CP8MCR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return DoMCR(handle, type, instr, value ? *value : 0,
&ValCP8Reg[BITS(16,19)], CheckBusyCycles(handle, 0), &state->CP8Busy, cycle_count);
}
static int CP8MCRR(void *handle, int type, ARMword instr, ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
ARMword reg = BITS(0,3);
ARMword reg2;
if (state->CP8_BounceNext)
{
state->CP8_BounceNext = 0;
return ARMul_CP_CANT;
}
/*
* This is not part of the validation coprocessor specification.
* It is here to test mcrr and mrcc
* The two coprocessor registers ar Crn and Crn + 1.
* If CRn == 15 the second register is 0
*/
if(reg < 15)
reg2 = reg + 1;
else
reg2 = 0;
return DoMCRR(handle, type, instr, value, &ValCP8Reg[reg],&ValCP8Reg[reg2],
CheckBusyCycles(handle, 1), &state->CP8Busy, cycle_count);
}
/* CDP co-processor instructions for CP 1,3,4,5,7 and 8 */
static int DoCDP(void *handle, int type, ARMword instr, ARMTime cycle_count, ARMword busy_cycles, CPBusyWait *CPBusy)
{
int result = type;
UNUSEDARG(instr); (void)handle;
if (busy_cycles && CheckBusyWait(type, CPBusy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
return ARMul_CP_DONE;
}
/* The core functionality of CDP instructions has now been placed in DoCDP, which */
/* is used by CP7 and CP8. CP5 is sufficiently different to not use this. */
static int CP4CDP(void *handle, int type, ARMword instr, ARMword *dummy)
{
ValidateState *state=(ValidateState *)handle;
ARMword howlong = ValCP4Reg[BITS(12,13)]; /* See how long we have to busy wait for - if we can */
ARMTime cycle_count = GetCycleCount(state);
(void)dummy;
#ifdef OldCode_BUSY_NOW
return DoCDP(handle, type, instr, cycle_count, howlong, &state->CP4Busy);
#else
/* We've been told to go busy, so record how long for. */
state->CPBusyUntil[4] = cycle_count + howlong + 1;
(void)type;
return ARMul_CP_DONE;
#endif
}
/* CP5 CDP instruction - behaviour not checked.
* cdp p5, OP1, CRd, CRn, CRm, OP2
* BitFields:
* 23:20 OP1 - determines the operation.
* 19:16 CRn
* 15:12 CRd - Which cp reg. For some reason, only 4 registers are supported.
* 11:8 CPnum (==5)
* 7:5 OP2
* 3:0 CRm
*
* If OP1==0xE then bits 19..16 are decoded as
* 19: Reset
* 18: System Error
* 17: IRQ
* 16: FIQ.
*/
static int CP5CDP(void *handle, int type, ARMword instr, ARMword *dummy)
{
ValidateState *state=(ValidateState *)handle;
ARMTime timeNow;
ARMword howlong = state->ValCP5Reg[BITS(12,13)];
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
unsigned long busy_cycles = CheckBusyCycles(handle, CP5_WAIT_COUNT);
int result = type;
(void)dummy;
if (busy_cycles && CheckBusyWait(type, &state->CP5Busy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
/* how long is used to store the number of cycles in advance of now
the required action happens - See Regme in the VHDL */
/* Bits 23..20 is correct for opcode_1*/
#ifdef VERBOSE
printf("** CP5CDP instr:0x%08x op1:%u howlong:%u now:%u ARMulif_Time:%u**\n",
(unsigned)instr, (unsigned)BITS(20,23),
(unsigned)howlong, (unsigned)cycle_count,
(unsigned)ARMulif_Time(&state->coredesc));
#endif
switch((int)BITS(20,23)) {
case 1:
if (howlong == 0) {
ARMulif_SetSignal(&state->coredesc, ARMSignal_FIQ, Signal_On);
}
else {
{
#ifdef VERBOSE_FIQ
printf("ScheduleUnretractable FIQ for %u\n",
(unsigned)(cycle_count + howlong));
#endif
Validate_ScheduleUnretractable(&state->coredesc,
DoAFIQ,state,
cycle_count + howlong, 0);
}
}
return ARMul_CP_DONE;
case 2:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -