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

📄 validate.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
/* validate.c - ARM validation suite co-processxor and OS. )
 *
 * Copyright (C) Advanced RISC Machines Limited, 1995-1998 .
 * Copyright (C) 1998-2001  ARM Limited.
 * All rights reserved.
 *
 * RCS $Revision: 1.3.4.10.2.3 $
 * Checkin $Date: 2003/07/10 15:34:20 $
 * Revising $Author: dsinclai $
 */

#include "minperip.h"
#include "armul_cnf.h"

#ifndef NDEBUG
# if 1
# else
#  define VERBOSE
# endif
#endif

#define ARMSignal_IRQ RDIPropID_ARMSignal_IRQ
#define ARMSignal_FIQ RDIPropID_ARMSignal_FIQ
/* Deprecated - no longer used in V6. */
#define ARMSignal_SE RDIPropID_ARMSignal_SE




#ifndef BITS
# define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) )
#endif

#ifndef BIT
# define BIT(n) ( (instr >> n) & 1 )
#endif
typedef RDI_Error ARMul_Error;



/* Software model of the Validation Suite Coprocessors. Eight    */
/* Coprocessors are defined in the "CPU Validation Test Bench"   */
/* ARM-100-0019-A01. Of these all but CP_PRIVELEGED is supported */

/* ARM7 based models use memory cycle based event scheduling,  */
/* and ARM9 and ARM10 based models use core cycle timings.     */


/* Coprocessor names */
#define CP_BOUNCE_D     0
#define CP_BUSYWAIT_D   1
#define CP_BOUNCE_E     2
#define CP_BUSYWAIT_E   3
#define CP_BUSYWAIT     4
#define CP_TRICKBOX     5
#define CP_PRIVELEGED   6
#define CP_STANDARD     7
#define CP_DTL          8

/* Default Busy_wait count for CP_BUSYWAIT */
#define CP1_WAIT_COUNT  1
#define CP2_WAIT_COUNT  1
#define CP3_WAIT_COUNT  2
#define CP4_WAIT_COUNT  1
#define CP5_WAIT_COUNT  0

typedef struct {
      ARMTime   ulBusyWaitStart;
      int       iBusyWaitDuration;
      int       iBusyWaiting;
} CPBusyWait;

BEGIN_STATE_DECL(Validate)
CPBusyWait CP1Busy /* ={0l,0, FALSE} */;
CPBusyWait CP2Busy /* ={0l,0, FALSE} */;
CPBusyWait CP3Busy /* ={0l,0, FALSE} */;
CPBusyWait CP4Busy /* ={0l,0, FALSE} */;
CPBusyWait CP5Busy /*={0l,0, FALSE} */;
CPBusyWait CP7Busy /*={0l,0, FALSE} */; 
CPBusyWait CP8Busy /*={0l,0, FALSE} */; 


/* All Coprocessors apart from 0 (no registers) and 5 share a common set of registers */ 

 ARMword ValCPStandardReg[16];
#define ValCP1Reg state->ValCPStandardReg
#define ValCP3Reg state->ValCPStandardReg
#define ValCP4Reg state->ValCPStandardReg
#define ValCP7Reg state->ValCPStandardReg
#define ValCP8Reg state->ValCPStandardReg
 ARMword ValCP5Reg[16];
unsigned ValCP5_LDCL_Words;


  int ldc_regNum;
  unsigned ldc_words;
  unsigned ldc_wordsToGet;
  int stc_regNum;
  unsigned stc_words;
  unsigned stc_wordsToSend;
  bool bARM9_CoproIF, bARM9_Extensions;
  unsigned vs_CoproIFType;

  ARMTime FRTimer;
#ifdef NotYet
  ARMul_SchedulerMethod schedule;
#endif
  int CP8_BounceNext;

  unsigned vcp_InterfaceDelay; /* 3 core cycles for ARM9 */
/* ARMul_SchedulerMethod schedule; */
  ARMTime CPBusyUntil[16];

END_STATE_DECL(Validate)


static void DoASE(void *handle);
static void DoAFIQ(void *handle);
static void DoAIRQ(void *handle);

static void DoAReset (void *handle);



static void Validate_ScheduleUnretractable(RDI_ModuleDesc *mdesc,
                                           ARMul_TimedCallBackProc *func,
                                           ValidateState *state,
                                           ARMTime when,
                                           ARMTime atc_period)
{
    void *fhandle = state;

    assert(mdesc == &state->coredesc);
    assert(0 == atc_period);

    when += state->vcp_InterfaceDelay; /* NEEDED FOR ARM926 */

    (void)ARMulif_ScheduleNewTimedCallback_CoreCycles(
        mdesc,  func, fhandle, when, atc_period);
}


/* Check whether the Coprocessor returned ARMul_LAST */
/* and return ARMul_INC instead for non ARM9 based   */
/* models.                                           */
static unsigned CheckLast(void *handle, int result)
{
    ValidateState *state=(ValidateState *)handle;

    if ((result == ARMul_CP_LAST) && !state->bARM9_CoproIF) {
        return ARMul_CP_INC;    
    }
    else {
        return result;
    }
}

/* Determine the correct number of busy cycles for the    */
/* Core - ARM9xxE cores always have one extra on external */
/* Coprocessor operations.                                */
static unsigned long CheckBusyCycles(void *handle, unsigned long busy_cycles)
{
    ValidateState *state=(ValidateState *)handle;

    if (state->bARM9_CoproIF && state->bARM9_Extensions)
        /* was (ARMul_Properties(state) & ARM_ARM9Extensions)*/ {
        /* ARM9xxES Core */
        return busy_cycles + 1;    
    }
    else {
        return busy_cycles;
    }
}


/* Checks whether the copro is waiting for a previous instruction */
/* to complete and also whether there is an interrupt.            */
static bool CheckBusyWait(unsigned type, CPBusyWait *CPBusy, 
                          unsigned long busy_cycles, 
                          ARMTime cycle_count, int *result)
{
  ARMTime finish;

  /* If we get an interrupt, regardless of busy wait status then exit */
  if (type == ARMul_CP_INTERRUPT) {
     CPBusy->iBusyWaiting = FALSE; /* Clear busy waiting flag */
     *result = ARMul_CP_DONE;         /* We've been interrupted */
     return TRUE; 
  }

  /* Is this CP currently busy waiting? */
  if (CPBusy->iBusyWaiting) {

    /* Yes it might be, check times */
    finish = CPBusy->ulBusyWaitStart + CPBusy->iBusyWaitDuration;
    if( cycle_count < finish ) {
        /* Yes it is busy waiting still, so return ARMul_CP_BUSY*/
        *result = ARMul_CP_BUSY;
        return TRUE;
    }
    else {
        /* Assert that we aren't busy waiting any more */
        CPBusy->iBusyWaiting = FALSE;
        *result = ARMul_CP_FIRST;
    }
  }
  else if (type == ARMul_CP_FIRST) {
    /* Start a new Busy Wait */
    CPBusy->iBusyWaiting = TRUE;
    CPBusy->ulBusyWaitStart = cycle_count;
    CPBusy->iBusyWaitDuration = busy_cycles;
    *result = ARMul_CP_BUSY;
    return TRUE;
  }
  return FALSE;

}

/* Code to get the current cycle count total, either */ 
/* core cycle type armulators (ARM9) or others.
 * 
 * Since we are a coprocessor, we'd actually like to use
 * the number of clocks on the coprocessor-bus.
 * NB This coprocessor requires that CoreCycles advances while
 * the core is busy-waited by a coprocessor.
 */
static ARMTime GetCycleCount(ValidateState *state)
{
    /* ValidateState *state=(ValidateState *)handle; */
#ifdef OldCode
  /* This doesn't work for ARMISS, which doesn't emit bus-cyles
   * while waiting for a coprocessor. */
  return ARMulif_Time(&state->coredesc);
#else
  /* ARMulif_CpuCycles causes ARM7TDMI..ARM740T to fail test TD1-32 */
  ARMTime t = ARMulif_CoreCycles(&state->coredesc);
/*   return ( t > 0 ) ? t : ARMulif_Time(&state->coredesc); */
  assert(t != 0 && t != (ARMTime)-1);
  return t;
#endif
}


/* Bouncing Coprocessors (CP0 and CP2) */
static int CP0CDP(void *handle, int type, ARMword instr, ARMword *dummy)
{
    UNUSEDARG(handle);  UNUSEDARG(type);
    UNUSEDARG(instr); (void)dummy;
    
    return ARMul_CP_CANT;
}

static int CP0LDCMCR(void *handle, int type, ARMword instr, ARMword *data)
{
    UNUSEDARG(handle);
    UNUSEDARG(type);
    UNUSEDARG(instr);
    UNUSEDARG(data);    
    return ARMul_CP_CANT;
}


static int CP0STCMRC(void *handle, int type, ARMword instr, ARMword *data)
{
    UNUSEDARG(handle);
    UNUSEDARG(type);
    UNUSEDARG(instr);
    UNUSEDARG(data);    
    return ARMul_CP_CANT;
}

static int CP2CDP(void *handle, int type, ARMword instr, ARMword *dummy)
{
    ValidateState *state=(ValidateState *)handle;
    ARMTime cycle_count = GetCycleCount(state);
    int result;
    (void)instr;
    (void)dummy;

    if (CP2_WAIT_COUNT && CheckBusyWait(type, &state->CP2Busy, CP4_WAIT_COUNT, cycle_count, &result)) {
        return result; /* Either busy waiting or interrupted */
    }
    
    return ARMul_CP_CANT;
}

static int CP2LDCMCR(void *handle, int type, ARMword instr, ARMword *data)
{
    ValidateState *state=(ValidateState *)handle;
    ARMTime cycle_count = GetCycleCount(state);
    int result;
    (void)instr;
    (void)data;

    if (CP2_WAIT_COUNT && CheckBusyWait(type, &state->CP2Busy, CP4_WAIT_COUNT, cycle_count, &result)) {
        return result; /* Either busy waiting or interrupted */
    }

    return ARMul_CP_CANT;
}


static int CP2STCMRC(void *handle, int type, ARMword instr, ARMword *data)
{
    ValidateState *state=(ValidateState *)handle;
    ARMTime cycle_count = GetCycleCount(state);
    int result;
    (void)instr;
    (void)data;

    if (CP2_WAIT_COUNT && CheckBusyWait(type, &state->CP2Busy, CP4_WAIT_COUNT, cycle_count, &result)) {
        return result; /* Either busy waiting or interrupted */
    }

    return ARMul_CP_CANT;
}


static int DoCP4LDC(void *handle, int type, ARMword instr,ARMword data, unsigned long busy_cycles, ARMTime cycle_count)
{
  ValidateState *state=(ValidateState *)handle;

  static int regNum;
  static unsigned words;
  static unsigned wordsToGet;
  int result = type;
 
  if (busy_cycles && CheckBusyWait(type, &state->CP4Busy, busy_cycles, cycle_count, &result)) {
      return result; /* Either busy waiting or interrupted */
  }


  wordsToGet = BIT(22) ? 4 : 1;

  if (type == ARMul_CP_FIRST || result == ARMul_CP_FIRST) {
    regNum = BITS(12,15);  /* Get the register number */
    words = 0;       /* Reset the word fetch counter */
    if (wordsToGet == 1) {
        return ARMul_CP_LAST;
    }
    else {
        return ARMul_CP_INC;
    }
  }

  if (type == ARMul_CP_TRANSFER) {
    if (wordsToGet == 1) {
        return ARMul_CP_LAST;
    }
    else {
        return ARMul_CP_INC;
    }
  }

  if (BIT(22)) {
     /* Its a CPDTL instruction so 4 words to fetch */  
   
     /* Do the data access,  incrementing the register as we go */
     ValCP4Reg[regNum++] = data;
     regNum &= 0xf;

     /* If we've got enough words then return done, else request more ! */

     words++;
     if (words >= wordsToGet) {
        return ARMul_CP_DONE;
     }
     else if ((words+1) == wordsToGet) {
        return ARMul_CP_LAST;
     }
     else {
        return ARMul_CP_INC;
     }
  }
  else {
     /* NOT a long access so get just one word */ 
     ValCP4Reg[BITS(12,15)] = data;
     return ARMul_CP_DONE;
  }
}


static int CP4LDC(void *handle, int type, ARMword instr, ARMword *data)
{
  ValidateState *state=(ValidateState *)handle;
  ARMTime cycle_count = GetCycleCount(state);
  return CheckLast(handle, DoCP4LDC(handle, type, instr, data ? *data : 0, CheckBusyCycles(handle, CP4_WAIT_COUNT), cycle_count));
}




static int DoCP4STC(void *handle, int type, ARMword instr,
                    ARMword *data, unsigned long busy_cycles, ARMTime cycle_count)
{ 
  ValidateState *state=(ValidateState *)handle;
  static int regNum;
  static unsigned words;
  static unsigned wordsToSend;
  int result = type;
  
  if (busy_cycles && CheckBusyWait(type, &state->CP4Busy, busy_cycles, cycle_count, &result)) {
      return result; /* Either busy waiting or interrupted */
  }
 
  if (type == ARMul_CP_FIRST || result == ARMul_CP_FIRST) {
    regNum = BITS(12,15);  /* Get the register number */
    words = 0;       /* Reset the word fetch counter */
    wordsToSend = 1;  /* just to be safe */
    return ARMul_CP_INC;
  }

  if (BIT(22)) {
     /* it's a long access*/
     /* Do we want 2 or 4 words transferred? */
      
     /* Its a CPDTL instruction so 4 words */   
     wordsToSend = 4;

     /* Now do the data access */
     *data = ValCP4Reg[regNum++];

     /* Store the data in Register[regNum] and increment regNum for the
        next transfer */

     /* If we've got enough words then return done, else request more ! */

     if (++words >= wordsToSend)
       return ARMul_CP_DONE;
     else
       return ARMul_CP_INC;
  }
  else {
    /* get just one word */
    *data = ValCP4Reg[regNum]; 
    return ARMul_CP_DONE;
  }
}


static int CP4STC(void *handle, int type,
                       ARMword instr, ARMword *data)
{
  ValidateState *state=(ValidateState *)handle;
  ARMTime cycle_count = GetCycleCount(state);
  int result = CheckLast(handle, DoCP4STC(handle, type, instr, data, CheckBusyCycles(handle, CP4_WAIT_COUNT), 
                                          cycle_count));
  return result;
}


/* CP5 LDC instruction. Does 2 word accesses */
static unsigned DoCP5LDC(void *handle, unsigned type, ARMword instr, ARMword data, unsigned long busy_cycles, ARMTime cycle_count)
{
  ValidateState *state=(ValidateState *)handle;
  static int regNum;
  static unsigned words;
  static unsigned wordsToGet;
  int result = type;

  if (busy_cycles && CheckBusyWait(type, &state->CP5Busy, busy_cycles, cycle_count, &result)) {
      return result; /* Either busy waiting or interrupted */
  }


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -