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

📄 armul_mem.h

📁 realview22.rar
💻 H
📖 第 1 页 / 共 2 页
字号:
#define MAH_FromLineFill MAH_Internal

#define MemAccessHit_ID_MASK 0xF0
#define MemAccessHit_ID_SHIFT 4
enum MemAccessHitID {
    MAH_ID_Unknown = 0,
    MAH_ID_Unified,
    MAH_ID_Instr,
    MAH_ID_Data
};
#define MAHID_Data (MAH_ID_Data << MemAccessHit_ID_SHIFT)
#define MAHID_Instr (MAH_ID_Instr << MemAccessHit_ID_SHIFT)

extern char const *MemAccessHit_NamesLong[MAH_ARRAY_SIZE];
extern char const *MemAccessHit_Names3[MAH_ARRAY_SIZE];
extern char const *MemAccessHit_Names1[MAH_ARRAY_SIZE];

/*
 * Function to return a "time elapsed" counter in microseconds.
 * If NULL, then Unix "clock()" is used.
 */

typedef ARMTime armul_ReadClock(void *handle);

/*
 * Function to return a cycle count. Returns NULL if not available,
 * or may be assigned to be NULL.
 * On some processors cycle types may overlap (e.g. F cycles
 * and I cycles overlap on cached processors, or additional wait-state
 * cycles on a standard memory model). Hence there is a "total"
 * field, which should be filled in as the total number of cycles on the
 * model's primary clock.
 */

typedef struct {
    /* This is incremented once per call to ARMflat or Mapfile. */
  ARMTime Total;  /* Bus-Cycles, used for ARMul_Time() */

    ARMTime ac_counts[8]; /* 4..7 are non-accounted */
# define NumNcycles ac_counts[0]
# define NumScycles ac_counts[1]
# define NumIcycles ac_counts[2]
# define NumCcycles ac_counts[3]
# define COUNTCYCLES(c,acc) c.ac_counts[ (acc & 0xE0) >> 5 ]++

  ARMTime ac_IWaits, ac_DWaits; /* 8,9 */
  ARMTime ac_MergedIS; /* 10 */

  ARMTime NumFcycles; /* Internal cycles not corrseponding to any of the above.
                       */
  ARMTime CoreCycles; /* #Times the core's pipeline has advanced
                       * as counted by ARM9/SA1's Fetch stage.*/

} ARMul_Cycles;

typedef const ARMul_Cycles *armul_ReadCycles(void *handle);

/*
 * Function to return the number of core cycles in an individual memory
 * access.
 * On cached processors where the number of core cycles in a given memory
 * cycle can vary this function is used to keep track of the number
 * of core cycles required before the next external memory access.
 */
typedef unsigned long armul_ReadDeltaCycles(void *handle);
typedef unsigned long armul_MultiLayerReadDeltaCycles(void *handle, unsigned int layer);

/* For Multi-Layer AHB systems the following function is used to
 * register a layer. The value returned should be used when the
 * layer is accessed via other Multi-Layer access functions.
 * The hint parameter can be used by a memory model for labeling
 * purposes.
 */
typedef unsigned int armul_MultiLayerRegister(void *handle, tag_t hint);


/*
 * For synchronous memory interfaces, this function returns the duration
 * of a cycle, in tenths of a nanosecond. All calls to "MemAccess" are
 * assumed to take this long by the caller. To insert wait states, return
 * '0' from MemAccess, or use an asynchronous memory interface (not yet
 * supported)
 */
typedef unsigned long armul_GetCycleLength(void *handle);

/*
 * The MemAccess functions return the number of datums read, or -1 for an abort
 *  (N.B. 0 signifies "wait", so a successful idle cycle returns 1)
 *  - MemAccess2 can return up to two words
 *  - MemAccAsync fills in a counter for the time til the next memory cycle
 */
typedef int armul_MemAccess(void *handle,
                            ARMword address,
                            ARMword *data,
                            ARMul_acc access_type);

typedef int armul_MultiLayerMemAccess(void *handle,
                                      unsigned int layer,
                                      ARMword address,
                                      ARMword *data,
                                      ARMul_acc access_type);

typedef void armul_MemBurstCount(void *handle, unsigned Count, unsigned IsWrite);


/* Used by cycle based models which include two clock
 * domains - eg , core clock and bus clock - to advance
 * the bus clock one cycle
 */  
typedef void armul_AdvanceBus(void *handle, ARMword phase);

/* This call provides information on the next cycle type, which enables
 * the ARMulator to be used in logic simulation environments where
 * pipelined address are required.
 * LOCK & nTRANS are provided via callbacks - these APIs are
 * called a cycle in advance when a pipelined ARMulator is used.
 */
typedef void armul_NextCycle(void *handle,
                             ARMword address,
                             ARMul_acc access_type);

typedef void armul_NextDataCycle(void *handle,
                             ARMword address,
                             ARMword data, 
                             ARMul_acc access_type);

typedef void armul_MultiLayerNext(void *handle,
                                  unsigned int layer,
                                  ARMword address,
                                  ARMword *data,
                                  ARMul_acc access_type);

/* DRS 2000-09-24 MemAccess2 only needs one data-pointer.
 * This makes it the same as a normal access-fn */

typedef int armul_MemAccess2(void *,ARMword,ARMword *,ARMul_acc);

/* Used for ARMISS core calling cache. */
typedef int armul_MemAccAsync(void *handle, ARMword address, ARMword *data,
                              ARMul_acc acc, ARMTime *abs_time);


/* Memory access function used for true Harvard models, where both busses */
/* present the required access parameters in the same function call.      */
typedef void armul_HarvardMemAccess(void *, ARMword, ARMword *, ARMul_acc, int *,
                                            ARMword, ARMword *, ARMul_acc, int *);

/* For GASP1020E, ARMul_MemType_PipelineARM10 */
typedef void armul_HarvardMemAccess64(
    void *handle,
    ARMword daddr, ARMword *ddata1, ARMword *ddata2, ARMul_acc dacc, int *drv,
    ARMword iaddr, ARMword *idata1, ARMword *idata2, ARMul_acc iacc, int *irv);


typedef int armul_BytelanesMemAccess(void *,ARMword *addr, ARMword *data,
                                     ARMword *lanes,
                                     ARMul_acc);


/*
 * When the core takes an exception - e.g. an access to the vectors in a
 * 26-bit mode, on a processor which supports exporting such exceptions
 * (i.e. an ARM8) this function is called if supplied. penc is the priority
 * encoding for the exception in question.
 */
typedef void armul_CoreException(void *handle,ARMword address,
                                 ARMword penc);

/*
 * StrongARM has a tightly coupled data-cache, where the pipeline needs
 * to know if the data cache is busy. This function provides that
 * functionality.
 */

typedef unsigned int armul_DataCacheBusy(void *handle);

/*
 * Function to return the grant status of the AMBA bus in cycle-based
 * simulation (1=granted, 0=not-granted). This only applies to pipelined
 * AMBA processors and will determine whether an access proceeds or not.
 *
 */
typedef unsigned long armul_ArbitrateBus(void *handle, ARMword request);
typedef unsigned long armul_MultiLayerArbitrateBus(void *handle, 
                                                   unsigned int layer, 
                                                   ARMword request);

/*
 * Function to indicate that the previous prediction has proven to be invalid
 * as a result of data returned by the current cycle. Typically used for late
 * kill signals on the bus of the ARM9 integer core.
 */
typedef void armul_KillAccess(void* handle, ARMword data_addr, ARMul_acc data_acc,
                              ARMword instr_addr, ARMul_acc instr_acc);

typedef struct armul_meminterface_ref {
    /* This points to where a memory-model's armul_meminterface has
     * been installed or moved to. */
    struct armul_meminterface *mif;
    /* This allows a memory to tell the cache or core something. */
    void *handle;
    armul_InfoProc *master_info;
} ARMul_MemInterfaceRef;

/* QQQ: Why isn't armul_MemAccess *[debug_]access;
 * also outside the union?
 */
struct armul_meminterface {
    void *handle;
    /* armul_MemAccess *debug_access; */
    
    /* 
     * This allows any memory object to keep track of where its
     * interface has been moved to (so long as whatever moves it
     * remembers to update this link). NB Only objects which switch themselves
     * in and out need to do this.
     */
    struct armul_meminterface_ref *mem_link;
    /*
     * This allows a watcher to know what type of veneer to insert
     */
  ARMul_MemType memtype;

    /* This allows a client to query or inform its memory. */
  armul_InfoProc *mem_info;

  armul_ReadClock *read_clock;
  armul_ReadCycles *read_cycles;
  armul_GetCycleLength *get_cycle_length;

  union {
    struct {
      armul_MemAccess *access;
      armul_NextCycle *next;
      armul_ReadDeltaCycles *delta_cycles;
      /* Cycle-based models have arbitrate */
      armul_ArbitrateBus *arbitrate;
    } pipe;
    struct {
      armul_MemAccess *debug_access;
      armul_CoreException *core_exception;
      armul_HarvardMemAccess  *harvard_access;
      armul_NextDataCycle *dside_next;
      armul_NextCycle *iside_next;
      /* ARM10 has delta_cycles */
      armul_ReadDeltaCycles *delta_cycles;
        /* These ifdef's are required to avoid expanding the size of
         * this structure between ADS1.1 and ADS1.2, which causes
         * pain when trying to build memory-models which work in either. */
/* #ifdef PIPELINED */
      /* Cycle-based models have advance_bus and kill_access*/
      armul_AdvanceBus *advance_bus;
      armul_KillAccess *kill_access;
/* #endif */
    } pipe_arm9;
    struct {
      armul_MemAccess *debug_access;
      armul_CoreException *core_exception;
      armul_MultiLayerRegister  *register_layer;
      armul_MultiLayerMemAccess *current_access;
      armul_MultiLayerNext      *next_access;
      armul_MultiLayerReadDeltaCycles *delta_cycles;
/* #ifdef PIPELINED */
      /* Cycle-based models have arbitrate */
      armul_MultiLayerArbitrateBus *arbitrate;
/* #endif */
    } pipe_multi_layer;
    struct {
      armul_MemAccess *access;
    } basic;
    struct {
      armul_MemAccess *access;
      armul_CoreException *core_exception;
      armul_MemAccess2 *access2;
    } arm8;
    struct {
      armul_MemAccess *access;
      armul_CoreException *core_exception;
      armul_DataCacheBusy *data_cache_busy;
    } strongarm;
    struct {
      armul_MemAccess *access;
      armul_CoreException *core_exception;
      armul_DataCacheBusy *data_cache_busy;
      armul_BytelanesMemAccess *bytelanes_access;
    } bytelanes;
    struct {
      armul_MemAccess *access;
      armul_CoreException *core_exception;
      armul_HarvardMemAccess *harvard_access;
        armul_DataCacheBusy *data_cache_busy_obsolete; /* Never called */
      armul_MemBurstCount *burst_count;
    } arm9;
      /* ARM10+XScale core->cache. */
    struct {
      armul_MemAccess *debug_access;
      armul_MemAccAsync *i_access;
      armul_MemAccAsync *d_read;
      armul_MemAccAsync *d_write;
    } armiss_cache;
      /* This structure is the same as basic, but the access-function
       * must be capable of 64-bit transfers.
       * Also, ICycles will not be generated.
       */
    struct {
      armul_MemAccess *access;
    } armiss_ahb;



    struct {
      armul_MemAccess *debug_access;
      armul_CoreException *core_exception;
      armul_HarvardMemAccess64  *harvard_access;
        /* !TODO: This may need to become NextDataCycle in gasp1020E! */
      armul_NextCycle *dside_next;
      armul_NextCycle *iside_next;
      /* ARM10 has delta_cycles */
      armul_ReadDeltaCycles *delta_cycles;
        /* These ifdef's are required to avoid expanding the size of
         * this structure between ADS1.1 and ADS1.2, which causes
         * pain when trying to build memory-models which work in either. */
      /* Cycle-based models have advance_bus and kill_access*/
#if 0
      armul_AdvanceBus *advance_bus;
      armul_KillAccess *kill_access;
#endif
    } pipe_arm10;




  } x;
};


/* 
 * Purpose: Given an existing interface connection,
 * Insert a new one, copying the old one to 'newChild'.
 *
 * Parameters:
 * Out:
 *       *newChild: memory owned by the caller. This call will fill that in
 *                  with the function pointers of the downstream memory
 *                  (copied from *mem).
 * InOut:
 *       *mem:      memory owned by someone soon to be upstream of
 *                  the caller. Caller will write function-pointers into
 *                  this after this call.
 * In:
 * *preparedEarlier: A set of function-pointers belonging to the caller
 *                  to be given to the upstream owner of *mem
 *                  (copied to *mem).
 *       newLink:   Address of 'leash' to mem
 *                  (newLink->mif will be updated if anyone
 *                   plugs themselves in upstream of us).
 *                  Note that only newLink->mem_link is changed - the other
 *                  fields of *newLink are unchanged.
 *               (These are expected to be a callback for newChild
 *                  to call through.)
 */
void ARMul_InsertMemInterface(ARMul_MemInterface *mem,
                              ARMul_MemInterface *newChild,
                              ARMul_MemInterfaceRef *newLink,
                              ARMul_MemInterface *preparedEarlier);
/* This is like the above, but also swaps the upwards ("master") memory-info
 *  callbacks at *newLink and *mem->mem_link.
 */
void ARMul_InsertMemInterface2(ARMul_MemInterface *mem,
                               ARMul_MemInterface *newChild,
                               ARMul_MemInterfaceRef *newLink,
                               ARMul_MemInterface *preparedEarlier);


/*
 * This is called by the owner of the function-pointers,
 * rather than the owner of the memory where they currently
 * reside.
 * Parameters:
 *      memref:   Address of pointer to set of function-pointers the
 *                 caller owns.
 *      child:    Address of downstream set of function-pointers.
 * NB: If the function-pointers at *memref are not saved, they are lost.
 */
void ARMul_RemoveMemInterface(ARMul_MemInterfaceRef *memref,
                              ARMul_MemInterface *child);

/* This is like the above, but also swaps the upwards ("master") memory-info
 *  callbacks at *newLink and *mem->mem_link.
 */
void ARMul_RemoveMemInterface2(ARMul_MemInterfaceRef *memref,
                               ARMul_MemInterface *child);


void ARMul_SwapMasterInfo(ARMul_MemInterfaceRef *my_ref,
                          ARMul_MemInterfaceRef *child_ref);


#if defined(__cplusplus) && !defined(CLX_CPP_LINKAGE)
}
#endif


#endif /* armul_mem__h */

⌨️ 快捷键说明

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