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

📄 mapfile.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
    case 7: /* S-Writes */
        regval->reg32 = desc->stats.Swrites; break;
    case 8: /* Time(ns) */
        regval->reg32 = desc->stats.ns; break;
    case 9: /* Time(s) */
        regval->reg32 = desc->stats.s; break;
    case 10: /* Region_Name */
        regval->reg32 = num_state->index; break;
    default:
        return SIM_REGISTER_ACCESS;
    }
    return SIM_OK;
  }
  else return SIM_REGISTER_ACCESS; /* All items are read-only here. */
}



static Register_Definition mapfile_reg_defs[] = {
    /* readonlyQ is 0=> read/write, 1=> readonly, 2=>writeonly */
#define S(symbol,buttonname,readonlyQ) \
  { 4,  EECHGCASE_DOWN, TYPE_UNSIGNED_LONG, /* "@mapfile_" */ symbol, buttonname, readonlyQ, 0 }
#ifdef NotYet /* RVDebugger doesn't support 64-bits yet. */
#define D(symbol,buttonname,readonlyQ) \
  { 8,  EECHGCASE_DOWN, TYPE_UNSIGNED_LONG_LONG, /* "@mapfile_" */ symbol, buttonname, readonlyQ, 0 }
#endif
    /* These entries are orderred - treat as an enum  whose
     * values are the cases in function Mapfile_SimReg. */
    S("Address",             "Base address         ", 1),
    S("Limit",               "Limit address        ", 1),
    S("Width",               "Width in bytes       ", 1),
    S("Access",              "ReadWriteAbility     ", 1),
    S("Reads_N",             "Non-sequential Reads ", 1),
    S("Reads_S",             "Sequential Reads     ", 1),
    S("Writes_N",            "Non-sequential Writes", 1),
    S("Writes_S",            "Sequential Writes    ", 1),
    S("Time_ns",             "Time(ns)             ", 1),
    S("Time_s",              "Time(s)              ", 1),
    S("Region_Name",         "Region Name          ", 1),
#undef S
};

#define NUM_ENUMS 2
char *mapfile_AccessTypeEnum[NUM_ENUMS] = {
    "MapFileAccessType=None,ReadOnly,WriteOnly,All, *",
    "MapFileRegionName=1,2,3,4,5,6," /* !We overwrite this! */
};


#define ADD_TO_NEW_TAB
#ifdef ADD_TO_NEW_TAB

/* Returns an allocated string, pre-FOE'd, (or NULL on out-of-memory). */
static char *make_enum_name(MapfileState *state)
{
    char *str1 = NULL;
    MemDescr *md = &state->desc; /* ! */
    unsigned i;
    for (i = 0; i < state->num_regions; i++)
    {
        if (str1 == NULL)
        {
            str1 = StrMultiCat("MapFileRegionName=",md->md_Name,NULL);
        }
        else
        {
            char *str2 = str1;
            str1 = StrMultiCat(str1,",",md->md_Name,NULL);
            free(str2);
        }
        md = md->next;
    }
    return FOE(str1);
}

static RegWin *new_RegWin(MapfileState *state)
{
    RegWin *rw = (RegWin*)calloc(1,sizeof(RegWin));
    if (rw != NULL)
    {
        MemDescr *md = &state->desc; /* ! */
        unsigned i;
        unsigned numrd = sizeof(mapfile_reg_defs)/sizeof(mapfile_reg_defs[0]);
        /* {{{ Fill in the RegWin fields. */
        /* !Todo: Use the instance-name in case we have a multi-core system! */
        rw->tab_name = "Mapfile,Statistics from Mapfile Regions";
#define NUM_HEADER_LINES 1
        rw->line_cnt = state->num_regions + NUM_HEADER_LINES;
        rw->enum_cnt = NUM_ENUMS;
        rw->lines = (char**)FOE(calloc(rw->line_cnt,sizeof(char *)));
        rw->enum_list = FOE(calloc(NUM_ENUMS,sizeof(char*)));
        rw->enum_list[0] = mapfile_AccessTypeEnum[0];
        rw->enum_list[1] = make_enum_name(state);
        /* {{ Fill in Lines */

        rw->lines[0] = "_Address  Limit    Width    Access   "
            "Reads_N  Reads_S  "
            "Writes_N Writes_S Time_ns  Time_s   Region_Name     ";

        for (i = 0; i < state->num_regions; i++)
        {
            unsigned j;
            char *str1 = NULL;

            for (j=0; j<numrd; j++)
            {
                char *name = StrMultiCat("@mapfile_",md->md_Name,"_",
                                     mapfile_reg_defs[j].name, NULL);
                switch(j)
                {
                case 3: /* && i == 0 */  /* "Access" */
                {
                    char *s2 = name;
                    name = StrMultiCat(name,"=MapFileAccessType", NULL);
                    free(s2);
                    break;
                }
                case 10: /* "Region_Name" */
                {
                    char *s2 = name;
                    name = StrMultiCat(name,"=MapFileRegionName", NULL);
                    free(s2);
                    break;
                }

                }
                if (str1 != NULL)
                {
                    char *s2 = str1;
                    str1 = StrMultiCat(str1,",",name, NULL);
                    free(s2); free(name);
                }
                else
                {
                    str1 = name;
                }
            }
            rw->lines[i+ NUM_HEADER_LINES] = FOE(str1);
            md = md->next;
        }
        /* }} Fill in Lines */
        /* }}} */
    }
    return FOE(rw);
}
#endif

static void
Mapfile_SimRdiListener( SimRdiRegistrationProcVec* srpv,
                        void* handle )
{
    MapfileState *state = (MapfileState *)handle;
    SimRdiProcVec* spv = srpv->simrdiprocvec;

    unsigned i;
    MemDescr *md = &state->desc; /* ! */
    state->simrdiprocvec = spv;
#ifdef VERBOSE_SIMRDI
    Hostif_ConsolePrint(state->hostif,"\n** MAPFILE Mapfile_SimRdiListener num:%i **\n",
                        srpv->number);
#endif
    if( srpv->number < 1
        || spv == NULL
        || spv->signature != SIMRDIPROCVEC_SIGNATURE
        || (spv->version.major) != 0x01
        || spv->null == NULL
        || spv->null->advertise == NULL
        || spv->null->c_new == NULL
        )
    {
#ifdef VERBOSE_SIMRDI
    Hostif_ConsolePrint(state->hostif,"\n** MAPFILE Mapfile_SimRdiListener FAIL **\n");
#endif
        return;
    }
    /* Q: Should a tree-view be
     *    + Region1
     *    |  + Stat1 (.. Stat6)
     * or
     *    + Stat1
     *    |  + Region1
     * Or should I supply both?
     * A: A table-view would be best if possible, and the former is closest.
     */
/* #define ADD_TO_EXISTING_TAB */
    /* Add the statistics to a pre-allocated tab. */
    for (i = 0; i < state->num_regions; i++)
    {
        SimRdi_Uniregs_Advert* ad =
            spv->uniregs->c_new( spv->uniregs );
        /* }}} */
        if( ad != NULL )
        {
        /*  state->advert_regs = ad->x.id; */
             /* "ButtonName" */
            ad->x.name     = md->md_Name;  /* ? What's this for? */

            ad->x.handle      = state;
            ad->x.coredesc    = &state->coredesc;
            
            ad->description = md->md_Name; /* Displayed in Tab with [+] next to it. */
            
            ad->len        = sizeof(mapfile_reg_defs)/sizeof(mapfile_reg_defs[0]);
             /* Display in Cycle counters tab. */
            ad->block_num  = uniregs_cycle_counter;
            {
            unsigned s = sizeof(mapfile_reg_defs);
            Register_Definition *rdefs = FOE(malloc(s));
            if (rdefs == NULL) return;
            memcpy(rdefs,mapfile_reg_defs,s);
            { unsigned j;
            /* Make the names distinct - else it all fails horribly. */
            for (j=0; j<(unsigned)ad->len; j++)
            {
                rdefs[j].name = FOE(StrMultiCat("@mapfile_",md->md_Name,"_",
                                            rdefs[j].name, NULL));
            }
            }
            ad->desc       = rdefs;
            }
            /* We allocate some new state to distinguish each region. */
            {
            NumState *num_state = (NumState *)calloc(1,sizeof(NumState));
            num_state->md = md;
            num_state->clk = state->clk;
            num_state->index = i;
            ad->handle_for_function = (void*)num_state;
            md->num_state = (void*)num_state; /* so we can free it */
            }
            ad->_SimReg             = Mapfile_SimReg;
            ad->start_reg_number = 0 /* i * 0x20 - for testing */;
#ifndef ADD_TO_EXISTING_TAB
            ad->x.config_flags |= UNIREGS_DO_NOT_AUTO_GENERATE_REG_WIN;
#endif
            spv->uniregs->advertise( spv->uniregs, ad );

        }
        md = md->next;
    }
#ifdef ADD_TO_NEW_TAB
    {
    RegWin *rw = new_RegWin(state);
    if (rw != NULL)
    {
        SimRdi_Regwin_Advert* ad =
            spv->regwin->c_new( spv->regwin );

        ad->regwin = rw;
        state->mf_ad_to_destroy = ad->x.id;
        spv->regwin->advertise( spv->regwin, ad );
    }
    }
#endif
}


BEGIN_INIT(Mapfile)
{
  MapfileState *top=state;
  memory *mem=&top->mem;

  unsigned page, i;
  unsigned long prop = 0;

  Hostif_PrettyPrint(hostif, config, ", Mapfile");

  /* Initialise a catch-all for the whole of memory */
  top->desc.desc.handle = RDI_NoHandle;
  top->desc.desc.start = 0l;
  top->desc.desc.limit = 0xffffffffl;
  top->desc.desc.width = 2;
  top->desc.desc.access = 3;
  top->desc.desc.Nread_ns =
    top->desc.desc.Nwrite_ns =
    top->desc.desc.Sread_ns =
    top->desc.desc.Swrite_ns = 0;
  memset(&top->desc.access_counts, 0, sizeof(top->desc.access_counts));
  memset(&top->desc.counter, 0, sizeof(top->desc.counter));
  top->desc.next = NULL;

#if USE_BASE_MEMORY
#else
  top->BaseMemoryEnabled = ToolConf_DLookupBool(config,
                                           (tag_t)"ENABLE_UNMAPPED_MEMORY",
                                               TRUE);
#endif

  {
  /* Get cycle-length in 10ths of a nanosecond. */
  uint32 bus_cycle_length =
      ARMulif_GetCycleLength(&state->coredesc); /* !REVERT RENAME! */
  if (!bus_cycle_length)
  {
      uint32 mclk = ARMul_GetMCLK(config);
      if (mclk) {
          bus_cycle_length = (uint32)(0.5 + 100000.0 * 100000.0 / mclk);
      }
  }

  if (!bus_cycle_length)
  {
      Hostif_PrettyPrint(hostif, config,
                     "\n** Mapfile cannot get bus cycle-length from core."
                         "Defaulting to 20MHz.\n");
      bus_cycle_length = 500; /* default to 20MHz */
  }

  top->mult=10; /* Convert ns to 10ths of ns */
  top->period=bus_cycle_length;
  top->clk=(double)bus_cycle_length / 10000.0; /* in microseconds */
  }
  

  for (i = 0; MapOption[i].option != NULL; i++) {
      if (ToolConf_DLookupBool(config, MapOption[i].option,FALSE)) {
          prop |= MapOption[i].flag;
      }
  }

  if (prop & MAP_SPOTISCYCLES) {
    char const *option = ToolConf_Lookup(config, ARMulCnf_ISTiming);
    if (option != NULL && ToolConf_Cmp(option, "SPECULATIVE"))
      prop |= MAP_IS_SPEC;
    else if (option != NULL && ToolConf_Cmp(option, "EARLY"))
      prop |= MAP_IS_EARLY;
    else
      prop |= MAP_IS_LATE;
  }

  top->prop = prop;

  for (page=0; page<NUMPAGES; page++) {
    mem->page[page]=NULL;
  }

  top->cycles.NumNcycles=0;
  top->cycles.NumScycles=0;
  top->cycles.NumIcycles=0;
  top->cycles.NumCcycles=0;
  top->cycles.NumFcycles=0;

  top->d.wait_states=0;
  top->d.cnt=0;

  top->i.wait_states=0;
  top->i.cnt=0;

  top->harvard_data_flag = FALSE;

  top->write_bigend = HostEndian ? 3 : 0; /* writes start littleendian */
  top->read_bigend = top->write_bigend;

  ARMulif_InstallUnkRDIInfoHandler(&state->coredesc,RDI_info,top);
  ARMulif_InstallEventHandler(&state->coredesc,
                              (ConfigEventSel | DebugEventSel),
                              Mapfile_ConfigEvents, state);
  {
  char const *mfl = ToolConf_Lookup(config,(tag_t)"MAPFILETOLOAD");
  if (mfl != NULL && mfl[0])
  {
    int errfl = ReadMemMap(mfl, InstallMemDescr, top);
    switch (errfl)
    {
    case Error_OK:
        top->mf_MapFileLoaded = mfl;
        break;
    case Error_MapFile_NotFound:
    {
        char buf[513];
        memset(buf,0,513);
        dir_getcwd(buf,512);
        Hostif_ConsolePrint(hostif,"\n** MAPFILETOLOAD=%s not found, cwd=%s **\n", mfl, buf);
        return RDIError_UnableToInitialise;
    }
    case Error_MapFile_Invalid:
        /* !Todo: A line-number would be useful! */
        Hostif_ConsolePrint(hostif,"\n** MAPFILETOLOAD=%s mapfile invalid. **\n", mfl);
        return RDIError_UnableToInitialise;
    default:
        Hostif_ConsolePrint(hostif,"\n** MAPFILETOLOAD=%s unknown error **\n", mfl);
        return RDIError_UnableToInitialise;
    }
#ifdef VERBOSE_SIMRDI
    Hostif_ConsolePrint(hostif,"\n** MAPFILE calling ARMulif_InstallSimRdiRegistration **\n");
#endif
    ARMulif_InstallSimRdiRegistration( &state->coredesc,
                                       Mapfile_SimRdiListener,
                                       state );
  }
  }
}
END_INIT(Mapfile)


#if USE_BASE_MEMORY
#else
static mempage *NewPage(void *handle)
{
  unsigned int i;
  MapfileState *top=(MapfileState *)handle;
  mempage *page=(mempage *)malloc(sizeof(mempage));

  if ( page == NULL)
    {
    /* The malloc failed. we have to do a number of things.
        1. call ARMulRaiseError
        2. Call ARMul_ModelBroken
        3. Return the zero page so that emulation continues
        long enough for the halt to take effect
     */

⌨️ 快捷键说明

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