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

📄 flatmem.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
   *  Instruction fetched, No data fetched      N
   *  Instruction fetched, data fetched         S
   *  No instruction fetched, No data fetched   I
   *  No instruction fetched, data fetched      C
   */

  if (acc_ACCOUNT(acc)) {
    if (acc_OPC(acc)) {
      /* End of cycle - account for access */
      /* This access is either acc_LoadInstrN or acc_NoFetch */
      if (top->sa_memacc_flag) {
        /* data fetched */
        top->sa_memacc_flag=0;
        if (acc_MREQ(acc)) top->cycles.NumScycles++;
        else top->cycles.NumCcycles++;
      } else {
        /* no data fetched */
        if (acc_MREQ(acc)) top->cycles.NumNcycles++;
        else top->cycles.NumIcycles++;
      }
    } else if (acc_MREQ(acc)) { /* should be */
      top->sa_memacc_flag=1;    /* flag */
    }
  }

  if ((address >= top->LowestPeripheralAddress) &&
      (address <= top->HighestPeripheralAddress) &&
      (rv = peripheral_access(handle,address,data,acc)) != -2)
  {
      return rv;
  }

  pageno=address>>PAGEBITS;
  page=top->mem.page[pageno];

  if (page==NULL) {
    top->mem.page[pageno]=page=NewPage(top,address);
  }
  offset = address & OFFSETBITS_WORD;
  ptr=(ARMword *)((char *)(page->memory)+offset);

  if (acc_MREQ(acc)) {
    if (acc_READ(acc)) {
      switch (acc & WIDTH_MASK) {
      case BITS_8:              /* read byte */
        if (HostEndian!=top->read_bigend) address^=3;
        *data = ((unsigned8 *)ptr)[address & 3];
        break;
        
      case BITS_16: {           /* read half-word */
        /* extract half-word */
#ifndef HOST_HAS_NO_16BIT_TYPE
        /*
         * unsigned16 is always a 16-bit type, but if there is no native
         * 16-bit type (e.g. ARM!) then we can do something a bit more
         * cunning.
         */
        if (HostEndian!=top->read_bigend) address^=2;
        *data = *((unsigned16 *)(((char *)ptr)+(address & 2)));
#else
        unsigned32 datum;
        datum=*ptr;
        if (HostEndian!=top->read_bigend) address^=2;
        if (address & 2) datum<<=16;
        *data = (datum>>16);
#endif
      }
        break;
        
      case BITS_32:             /* read word */
        *data=*ptr;
        break;

      default:
          return_PERIP_DABORT;
      }
    } else {
      switch (acc & WIDTH_MASK) {
        /* extract byte */
      case BITS_8:              /* write_byte */
        if (HostEndian!=top->write_bigend) address^=3;
        ((unsigned8 *)ptr)[address & 3]=(unsigned8)(*data);
        break;
        
      case BITS_16:             /* write half-word */
        if (HostEndian!=top->write_bigend) address^=2;
        *((unsigned16 *)(((char *)ptr)+(address & 2)))=(unsigned16)(*data);
        break;

      case BITS_32:             /* write word */
        *ptr=*data;
        break;

      default:
          return_PERIP_DABORT;
      }
    }                           /* internal cycle */
  }

  return 1;
}

/*
 * Memory access function that supports byte lanes
 */

#ifndef NO_BYTELANES
static int MemAccessBL(void *handle,
                       ARMword address,
                       ARMword *data,
                       ARMul_acc acc)
{
  toplevel *top=(toplevel *)handle;
  unsigned int pageno;
  mempage *page;
  ARMword *ptr;
  ARMword offset;

  if (acc_ACCOUNT(acc)) {
    if (acc_SEQ(acc)) {
      if (acc_MREQ(acc)) top->cycles.NumScycles++;
      else top->cycles.NumCcycles++;
    } else if (acc_MREQ(acc)) top->cycles.NumNcycles++;
    else top->cycles.NumIcycles++;
  }

  pageno=address>>PAGEBITS;
  page=top->mem.page[pageno];

  if (page==NULL) {
    top->mem.page[pageno]=page=NewPage(top,address);
  }
  offset = address & OFFSETBITS_WORD;
  ptr=(ARMword *)((char *)(page->memory)+offset);

  if (acc_MREQ(acc)) {
    if (acc_BYTELANE(acc)==BYTELANE_MASK) { /* word */
      if (acc_READ(acc)) *data = *ptr;
      else *ptr = *data;
    } else {
      unsigned32 mask;
      static const unsigned32 masks[] = {
        0x00000000, 0x000000ff,
        0x0000ff00, 0x0000ffff,
        0x00ff0000, 0x00ff00ff,
        0x00ffff00, 0x00ffffff,
        0xff000000, 0xff0000ff,
        0xff00ff00, 0xff00ffff,
        0xffff0000, 0xffff00ff,
        0xffffff00, 0xffffffff,
      };
      mask=masks[acc_BYTELANE(acc)];
      if (acc_READ(acc)) *data = *ptr & mask;
      else *ptr = (*ptr & ~mask) | (*data & mask);
    }                           /* internal cycle */
  }

  return 1;
}
#endif

static void MemAccessHarvard(void *handle,
                       ARMword daddr,ARMword *ddata, ARMul_acc dacc, int *drv,
                       ARMword iaddr,ARMword *idata, ARMul_acc iacc, int *irv)
{

    toplevel *top=(toplevel *)handle;
    unsigned int pageno;
    mempage *page;
    ARMword *ptr;
    ARMword offset;

    /* This call doesn't happen for debug accesses, so no need
     * to check acc_ACCOUNT. */
    /* top->p_ABus->bus_BusyUntil++; */
    
    /* Update cycle counters - use the same scheme */
    /* as the StrongARM model (see MemAccessSA()). */
    
    if (acc_MREQ(iacc) && acc_MREQ(dacc)) {
        top->cycles.NumScycles++;
    }
    else if (acc_MREQ(iacc) && acc_nMREQ(dacc)) {
        top->cycles.NumNcycles++;
    }
    else if (acc_nMREQ(iacc) && acc_MREQ(dacc)) {
        top->cycles.NumCcycles++;
    }
    else {
        top->cycles.NumIcycles++;  
    }
    
    /* Deal with Instruction side first */
    
    if (acc_MREQ(iacc)) {
        
        int rv;
        
        if ((iaddr >= top->LowestPeripheralAddress) &&
            (iaddr <= top->HighestPeripheralAddress) &&
            (rv = peripheral_access(handle,iaddr,idata,iacc)) != -2)
        {
            *irv = rv; goto idone;
        }
        
        pageno=iaddr>>PAGEBITS;
        page=top->mem.page[pageno];
        
        if (page==NULL) {
            top->mem.page[pageno]=page=NewPage(top,iaddr);
        }
        offset = iaddr & OFFSETBITS_WORD;
        ptr=(ARMword *)((char *)(page->memory)+offset);
        
        switch (iacc & WIDTH_MASK) {
        case BITS_8: {
            unsigned32 datum = *ptr;
            if (HostEndian!=top->read_bigend) iaddr^=3;
            datum<<=(3 *(iaddr & 3));
            *idata = datum & 0xFF;
        }
        case BITS_16: {           /* read half-word */
            /* extract half-word */
#ifndef HOST_HAS_NO_16BIT_TYPE
            /*
             * unsigned16 is always a 16-bit type, but if there is no native
             * 16-bit type (e.g. ARM!) then we can do something a bit more
             * cunning.
             */
            if (HostEndian!=top->read_bigend) iaddr^=2;
            *idata = *((unsigned16 *)(((char *)ptr)+(iaddr & 2)));
#else
            unsigned32 datum = *ptr;
            if (HostEndian!=top->read_bigend) iaddr^=2;
            if (iaddr & 2) datum<<=16;
            *idata = (datum>>16);
#endif
        }
        break;
        
        case BITS_32:             /* read word */
            *idata=*ptr;
            break;
            
        case BITS_64:             /* read 2 words */
            *idata=*ptr;
            idata[1]=ptr[1];
            break;
            
        }
    }
    *irv = 1;

idone:
  /* Now deal with data side */

  if (acc_MREQ(dacc) /*dacc != acc_Icycle*/) {

      int rv;
      if ((daddr >= top->LowestPeripheralAddress) &&
          (daddr <= top->HighestPeripheralAddress) &&
          (rv = peripheral_access(handle,daddr,ddata,dacc)) != -2)
      {
          *drv = rv; goto ddone;
      }

    pageno=daddr>>PAGEBITS;
    page=top->mem.page[pageno];

    if (page==NULL) {
      top->mem.page[pageno]=page=NewPage(top,daddr);
    }
    offset = daddr & OFFSETBITS_WORD;
    ptr=(ARMword *)((char *)(page->memory)+offset);


    if (acc_READ(dacc)) {
          switch (dacc & WIDTH_MASK) {
          case BITS_8:              /* read byte */
            if (HostEndian!=top->read_bigend) daddr^=3;
            *ddata = ((unsigned8 *)ptr)[daddr & 3];
            break;
        
          case BITS_16: {           /* read half-word */
            /* extract half-word */
#ifndef HOST_HAS_NO_16BIT_TYPE
            /*
             * unsigned16 is always a 16-bit type, but if there is no native
             * 16-bit type (e.g. ARM!) then we can do something a bit more
             * cunning.
             */
            if (HostEndian!=top->read_bigend) daddr^=2;
            *ddata = *((unsigned16 *)(((char *)ptr)+(daddr & 2)));
#else
            unsigned32 datum;
            datum=*ptr;
            if (HostEndian!=top->read_bigend) daddr^=2;
            if (daddr & 2) datum<<=16;
            *ddata = (datum>>16);
#endif
            }
            break;
        
          case BITS_32:             /* read word */
            *ddata=*ptr;
            break;

          case BITS_64:             /* read dword */
            *ddata = *ptr;
            ddata[1] = ptr[1];
            break;

          default:
            break;
          }
    } else {
          switch (dacc & WIDTH_MASK) {
            /* extract byte */
          case BITS_8:              /* write_byte */
            if (HostEndian!=top->write_bigend) daddr^=3;
            ((unsigned8 *)ptr)[daddr & 3]=(unsigned8)(*ddata);
            break;
        
          case BITS_16:             /* write half-word */
            if (HostEndian!=top->write_bigend) daddr^=2;
            *((unsigned16 *)(((char *)ptr)+(daddr & 2))) = (unsigned16)(*ddata);
            break;

          case BITS_32:             /* write word */
            *ptr=*ddata;
            break;

          case BITS_64:             /* write 2 words */
            *ptr = *ddata;
            ptr[1] = ddata[1];
            break;

          default:
            break;
          }
    }
  }

  *drv = 1;
ddone:
  ;
}

#ifdef PIPELINED
static void NextDCycle(void *handle, ARMword addr, ARMul_acc acc)
{
    NextCycle(handle, addr, acc);
}
static void NextICycle(void *handle, ARMword addr, ARMul_acc acc)
{
    NextCycle(handle, addr, acc);
}
#endif

/*
 * Utility functions:
 */


static unsigned Flat_MemInfo(void *handle, unsigned type, ARMword *pID,
                        uint64 *data)
{
    toplevel *top=(toplevel *)handle;
    if (ACCESS_IS_READ(type))
    {
        switch (*pID) {
        case MemPropertyID_TotalCycles:
            *data = (top->cycles.NumNcycles + top->cycles.NumScycles +
                     top->cycles.NumIcycles + top->cycles.NumCcycles);
            return RDIError_NoError;
        case MemPropertyID_CycleSpeed:
            *data = top->clk_speed;
            return RDIError_NoError;
        case MemPropertyID_BaseMemoryRef:    /* We are a LEAF */
            *(ARMul_MemInterface**)data = top->mem_ref.mif;
            assert(top->mem_ref.mif->mem_link == &top->mem_ref);
            return RDIError_NoError;
        case MemPropertyID_BaseMemoryEnable: /* We are a LEAF */
            *data = top->BaseMemoryEnabled;
            return RDIError_NoError;

        default:
            return RDIError_UnimplementedMessage;
        }
    }
    else
    {
        switch (*pID) {
        case MemPropertyID_BaseMemoryEnable: /* We are a LEAF */
            top->BaseMemoryEnabled = (bool)*data;
            return RDIError_NoError;
        default:
            return RDIError_UnimplementedMessage;
        }
    }
}



static const ARMul_Cycles *Flat_ReadCycles(void *handle)
{
  toplevel *top=(toplevel *)handle;
  top->cycles.Total=(top->cycles.NumNcycles + top->cycles.NumScycles +
                     top->cycles.NumIcycles + top->cycles.NumCcycles);
  return &(top->cycles);
}

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

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


/* For ARMulAgent_AddPeripheral */
extern void Target_add_names(toolconf tconf);
extern void Target_add_names(toolconf tconf)
{
    (void)tconf;
}


BEGIN_EXIT(Flatmem)
{
/*
 * Remove the memory interface
 */
  ARMword page;
  toplevel *top=state;
  memory *mem=&top->mem;
  /* free all truly allocated pages */
  for (page=0; page<NUMPAGES; page++) {
    mempage *pageptr= mem->page[page];
    if (pageptr) {
      free((char *)pageptr);
    }
  }

  ClxList_Destroy((ClxList*)&top->NewPageAllocated,NULL);

  ARMulAgent_Destroy(&top->agent);

  /* top-level structure is freed by END_EXIT macro  */
}
END_EXIT(Flatmem)



/*--- <SORDI STUFF> ---*/
#define SORDI_DLL_NAME_STRING "Flatmem"
#define SORDI_DLL_DESCRIPTION_STRING "Flatmem Leaf memory model"
#define SORDI_RDI_PROCVEC Flatmem_AgentRDI
#include "perip_sordi.h"

#include "perip_rdi_agent.h"
    IMPLEMENT_AGENT_PROCS_NOEXE_NOMODULE(Flatmem)
    IMPLEMENT_AGENT_PROCVEC_NOEXE(Flatmem)

/*--- </> ---*/


/* EOF flatmem.c */


⌨️ 快捷键说明

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