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

📄 mapfile.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
/* mapfile.c - - Memory model that supports an "armsd.map" file 
 * Formerly known as armmap.c
 * Copyright (C) Advanced RISC Machines Limited, 1995. All rights reserved.
 * Copyright (C) ARM Limited, 1999-2003. All rights reserved. 
 */
#define MODEL_NAME Mapfile

/*
 * RCS $Revision: 1.16.4.23.18.8 $
 * Checkin $Date: 2003/05/12 14:32:06 $
 * Revising $Author: dsinclai $
 */

/* !Todo:
 * + Respond to some forms of Reset by clearing the cycle-counters?
 * + Free the StrDup'd md_Name's at the end, and md->num_state.
 */

#include <string.h>
#include <ctype.h>

#include "minperip.h"
#include "armul_mem.h" /* Mix'n match */
#include "armul_callbackid.h"
#include "addcounter.h"
#define ACDTEST(FUNC,RET) if (FUNC == RDIError_BufferFull) \
                               RET = RDIError_BufferFull
#include "armul_cyc.h"
#include "armul_lib.h" /* for ARMul_SIRange() */

#include "rdi_conf.h"
#include "armul_cnf.h"
#include "dir.h"                 /* for dir_getcwd */
#include "stringx.h"             /* for StrDup     */
#include "mini_simrdi_manager.h" /* for SIMABS awareness */

/* ---- IMPLEMENTATION DECISIONS ---- */
/*
 * In order to allow FPE to work with mapfile, mapfile must
 * enable the base memory and allow all non-aborting accesses to fall
 * through to the base memory
 */
#define USE_BASE_MEMORY 1
/* NUL_BIU owns the bus. */
#define MAPFILE_OWNS_BUS 0

#if MAPFILE_OWNS_BUS
# define ADVANCE_BUS_TIME top->pABus->bus_BusyUntil++
#else
# define ADVANCE_BUS_TIME
#endif

#ifndef NDEBUG
# if 1
# else
#  define VERBOSE_Mapfile_MemAccessHarvard
#  define VERBOSE_TIMES
#  define VERBOSE_BUS
#  define VERBOSE_MEMLOOKUP
#  define VERBOSE_DABORT
#  define VERBOSE_ACCESS
#  define VERBOSE_ENDIAN
#  define VERBOSE_CYCLE_DESC
#  define VERBOSE_INIT
#  define VERBOSE_ACCOUNTED_ACCESS
# endif
#endif


#ifdef HOST_ENDIAN_BIG
# define HostEndian 1
#elif defined(HOST_ENDIAN_LITTLE)
# define HostEndian 0
#else
# error "HOST_ENDIAN_UNKNOWN"
#endif


#include "rdi_stat.h"

#include "clxlist.h"

/* Possibly inline some functions */
#ifndef INLINE
# error "INLINE not defined"
#endif

#define ModelName (tag_t)"MapFile"

#define FOE(a) Mapfile_FreeOnExit(state,a)

/* armmap.c */
/* #define ARMulCnf_CountWaitStates (tag_t)"COUNTWAITSTATES" */
#define ARMulCnf_AMBABusCounts (tag_t)"AMBABUSCOUNTS"
#define ARMulCnf_SpotISCycles (tag_t)"SPOTISCYCLES"
#define ARMulCnf_ISTiming (tag_t)"ISTIMING"

struct NumState;

typedef struct MemDescr {
  struct MemDescr *next; /* So we can put these in a list */
  /* cycle counters */
  /* @@@ N.B. this table RELIES on the bit positions in acc words.
   * for indexing and for it's size.
   */
#if (WIDTH_MASK | acc_Nrw | acc_seq | acc_Nmreq) == 0x7f
  unsigned long access_counts[0x60];   /* number of accesses to this region */
  /* This is build by interpreting the RDI_MemDescr */
  int counter[0x60];            /* wait states - -ve for "special" */
#else
#  error Code relies on things about ARMul_accs
#endif

  RDI_MemDescr desc;

  /* Cache of the stats computations. */
  bool_int stats_are_valid;
  RDI_MemAccessStats stats;


  /* Added for when we load the map-file ourselves. */
  char *md_Name;
    /* To be freed at the end */
  struct NumState *num_state;
} MemDescr;


#define NUMPAGES 64 * 1024
#define ARMMAP_PAGESIZE 64 * 1024
#define PAGEBITS 16
#define OFFSETBITS 0xffff
#define OFFSETBITS_WORD 0xfffc

typedef struct {
  ARMword memory[ARMMAP_PAGESIZE/4];
} mempage;

typedef struct {
  mempage *page[NUMPAGES];
} memory;

typedef struct {
  ARMTime wait_states;    /* counter for wait states */
  ARMul_acc last_acc;           /* last cycle flag */
  int cnt;                      /* cycle-by-cycle counter */
} Bus;

/* was typedef ... toplevel; */
BEGIN_STATE_DECL(Mapfile)
  unsigned read_bigend, write_bigend;

  ARMword byteAddrXor,hwordAddrXor; /* for reads */

  MemDescr desc;
  ARMul_Cycles cycles;
  ARMul_Cycles saved_cycles;
  unsigned long IS_cycles;      /* counter for IS_cycles */
  unsigned long saved_IS_cycles;      
  Bus i, d, saved_i, saved_d;
  bool harvard_data_flag;
  memory mem;
  unsigned num_regions;

  /* Three values give the clock speed: 
   * clk - clockspeed, as cycle length in us
   * mult/period - integer representation of the same, for determining
   * the waitstates. The clock period is period*mult ns. This is done to
   * try to keep precision in division.
   */
  double clk;
  unsigned long mult,period;

  unsigned long prop;

#if USE_BASE_MEMORY
#else
  bool BaseMemoryEnabled;
#endif

  ARMul_MemInterface bus_mem,
                     child;      /* the base memory we override */
  ARMul_MemInterfaceRef mem_ref;
  ARMTime clk_speed;
  bool FailedToInstal;
  char *mf_CycleNames[16];
  int memtype;

  ARMul_Bus *pABus;
  bool pABus_isMine; /* Did we allocate the above? */

  /* Name of mapfile we loaded, else NULL. */
  char const *mf_MapFileLoaded;
  /*
   * SIMABS awareness:
   *
   * We need for semihosting exit to return RDIError_TargetStopped if we hit
   * the semihosting stop vector.  Otherwise there is no way for a step call
   * to figure out that it has stopped.
   */
   SimRdiProcVec* simrdiprocvec; /* non-null if running under a SimRdi_Manager */
   /* To avoid memory-leaks... */
#ifdef OldCode
   SimRdi_Regwin_Advert* mf_ad_to_destroy;
#else
   Advert_ID      mf_ad_to_destroy;
#endif

END_STATE_DECL(Mapfile)

/* Type of an argument to function Mapfile_SimReg which reads
 * numeric values to display in the Cycle-counts Tab in RVDebugger. */
typedef struct NumState {
    MemDescr *md;
    /* MapfileState *state; */
    double clk; /* This is all we need from state! */
    unsigned index; /* So we can use an enum to display the region-name. */
} NumState;


/* #define MAP_COUNTWAIT     0x0001 */
#define MAP_AMBABUSCOUNTS 0x0002
#define MAP_SPOTISCYCLES  0x0004
#define MAP_HARVARD       0x0008

/*
 * When spotting I-S cycles, a memory controller can either:
 * - speculatively decode all I cycles. This gives 2 cycles to do the I-S
 *   access.
 * - check for nMREQ in the middle of I cycles. This gives 1.5 cycles to do
 *   the access.
 * - process each cycle in turn. This gives only 1 cycle to do the access.
 * armmap.c can model each of these, "SPECULATIVE", "EARLY" or "LATE"
 */
#define MAP_ISMODE        0x0030
#define MAP_IS_SPEC       0x0010
#define MAP_IS_EARLY      0x0020
#define MAP_IS_LATE       0x0030

#define MAP_FIXEDSEX      0x0040 /* memory bytesex is fixed */

static const struct {
  tag_t option;
  unsigned long flag;
} MapOption[] = {
/*  ARMulCnf_CountWaitStates, MAP_COUNTWAIT, */
  ARMulCnf_AMBABusCounts, MAP_AMBABUSCOUNTS,
  ARMulCnf_SpotISCycles, MAP_SPOTISCYCLES,
  NULL, 0
};



static int Mapfile_MemAccess(void *handle, ARMWord address, ARMWord *data,
                             unsigned acc);
static int Mapfile_MemAccessSA(void *handle,ARMWord address, ARMWord *data,
                               unsigned acc);
static void Mapfile_MemAccessHarvard(void *handle,
                       ARMword daddr,ARMword *ddata, ARMul_acc dacc, int *drv,
                       ARMword iaddr,ARMword *idata, ARMul_acc iacc, int *irv);

static const ARMul_Cycles *Mapfile_ReadCycles(void *handle);

#define toplevel MapfileState



/* {{{ Helper functions  */


/* returns an RDI_Error, or 0 if OK */
typedef int MemConfigCBFunc(void *handle, RDI_MemDescr *mc, char *region_name);


typedef struct {
    RDI_MemDescr md;
    } MemConfig;

typedef enum { Error_OK = 0, Error_MapFile_NotFound, Error_MapFile_Invalid } Dbg_Error;

/* This is the original ReadMemMap function from armdbg/dbg_stat.c.
 * Modifications:
 * . allow width=8 for ARM10,ARM11.
 * . call a callback-function instead of allocating a list.
 */
static Dbg_Error ReadMemMap(char const *fname,
                            MemConfigCBFunc *func, void *handle)
{
    char line_buffer[256], name[256], prot[256];
    MemConfig m;
#ifdef OldCode
    MemConfig *ml = NULL;
#endif
    FILE *fp = fopen(fname, "r");
#ifdef OldCode
    if (memconfig) *memconfig = 0;
#endif
    if (fp == NULL) return Error_MapFile_NotFound;  /* BGC - Was Error_MemConfig */
    for (;;) {
        int c, n = 0;
        char *s, *line = line_buffer;
        unsigned long width;
        int flags;
        while (isspace(c = fgetc(fp))) continue;
        while (c != EOF && c != '\n') {
            if (n < 255) line[n++] = c;
            c = fgetc(fp);
        }
        if (c == EOF && n == 0) break;
        line[n] = 0;

        /* DE34315 - allow ;; comments at the start of lines */
        if( n>=2 && (line[0] == ';') && (line[1] == ';') )
            continue;

        c = sscanf(line, "%lx %lx %s %lu %s %n",
                   &m.md.start, &m.md.limit, name, &width, prot, &n);
        if (c < 5) return Error_MapFile_Invalid;    /* BGC - Was Error_BadCfg */ 
        for (s = prot; (c = *s) != 0; s++) *s = safe_toupper(*s);
        flags = 0;
        if (strcmp(prot, "none") != 0 && strcmp(prot, "-") != 0)
            for (s = prot; (c = *s++) != 0; ) {
                if (c == 'R' && !(flags & 1))
                    flags |= 1;
                else if (c == 'W' && !(flags & 2))
                    flags |= 2;
                else if (c == '*' && !(flags & 4))
                    flags |= 4;
                else
                    return Error_MapFile_Invalid;  /* BGC - Was Error_BadCfg */
            }
        m.md.access = flags;
        if (width == 1) width = 0;
        else if (width == 2) width = 1;
        else if (width == 4) width = 2;
        else if (width == 8) width = 3; /* For ARM10 or ARM11. */
        else return Error_MapFile_Invalid;         /* BGC - Was Error_BadCfg */
        m.md.width = (unsigned char)width;
        line += n;
        c = sscanf(line, "%lu %n", &m.md.Nread_ns, &n);
        if (c < 1) return Error_MapFile_Invalid;      /* BGC - Was Error_BadCfg */
        m.md.Sread_ns = m.md.Nread_ns;
        line += n;
        if (*line == '/') {
            line++;
            c = sscanf(line, "%lu %n", &m.md.Sread_ns, &n);
            if (c < 1) return Error_MapFile_Invalid;  /* BGC - Was Error_BadCfg */
            line += n;
        }
        c = sscanf(line, "%lu %n", &m.md.Nwrite_ns, &n);
        if (c < 1) return Error_MapFile_Invalid;      /* BGC - Was Error_BadCfg */
        m.md.Swrite_ns = m.md.Nwrite_ns;
        line += n;
        if (*line == '/') {
            line++;
            c = sscanf(line, "%lu %n", &m.md.Swrite_ns, &n);
            if (c < 1) return Error_MapFile_Invalid;  /* BGC - Was Error_BadCfg */
            line += n;
        }
        {
            int rv = func(handle, &m.md, name);
            if (rv != 0)
            {
                fclose(fp);
                return rv;
            }
        }
    }
    fclose(fp);
    return Error_OK;
}


/* }}} */


static unsigned int Mapfile_DataCacheBusy(void *handle)
{
  UNUSEDARG(handle);
  return FALSE;
}

/* If we are a leaf memory, we don't need to pass this along.
 * We are NOT a leaf memory, but we never go between a core
 *  and its cache.
 */
#define Mapfile_CoreException NULL

static unsigned long Mapfile_GetCycleLength(void *handle)
{
  /* Returns the cycle length in tenths of a nanosecond */
  MapfileState *top=(MapfileState *)handle;
  return (unsigned long)(top->clk*10000.0);
}

/* Needed for MSVC++6 */
static double u64_to_dbl(uint64 v)
{
    int64 v2 = (int64)v;
    return (double)v2;
}


static ARMTime Mapfile_ReadClock(void *handle)
{
  /* returns a us count */
  toplevel *top=(toplevel *)handle;
  double t;
  Mapfile_ReadCycles(handle);
  t=(u64_to_dbl(top->cycles.NumNcycles) +
     u64_to_dbl(top->cycles.NumScycles) +

⌨️ 快捷键说明

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