⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 validate.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
               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 + -