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

📄 flatmem.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
                    "\n Flatmem connecting to CORE having failed to get BUS.\n");
#endif
  }
  if (!interf)
  {
      Hostif_PrettyPrint(hostif,config,
                         "\n Flatmem cannot get memory-interface.\n");
      return RDIError_UnableToInitialise;
  }
#ifdef VERBOSE_GETMIF
  Hostif_PrettyPrint(hostif,config, "Flatmem got memory-interface %p.\n",
                     interf);
#endif


#ifdef NotInADS11
    /* Ask the downstream memory for its bus. */
    {
        uint32 ID[2]; ID[0]=MemPropertyID_Bus; ID[1]=0;
        mif->mem_info(mif->handle,
                      ACCESS_READ|ACCESS_WORD,&ID[0],
                      (uint64*)&ts->pABus);
        if (!ts->pABus)
        {
            Hostif_PrettyPrint(ts->hostif,ts->config,
          "\n** Flatmem got no response to query for MemPropertyID_Bus **\n");
            ts->pABus = calloc(1,sizeof(ARMul_Bus));
            /* Later, construct such a bus? (*/
            return RDIError_UnableToInitialise;
        }
    }
#endif
    ARMulif_QueryBus(&state->coredesc,"A",&state->p_ABus);
    if (!state->p_ABus)
    {
        Hostif_PrettyPrint(hostif,config,"\n** Flatmem failed to get bus from "
                           "core model. **\n");
        return RDIError_UnableToInitialise;
    }



  /* Ask the host's built-in ARMFlat to disable its RDIInfo. */
  if (interf->mem_info)
  {
      uint64 data = FALSE;
      uint32 ID[2]; ID[0]=MemPropertyID_BaseMemoryEnable; ID[1]=0;      
      interf->mem_info(interf->handle,
                       ACCESS_WRITE|ACCESS_WORD,&ID[0],&data);
  }


  state->memtype = memtype = interf->memtype;
  interf->mem_info=Flat_MemInfo;
  interf->read_clock=Flat_ReadClock;
  interf->read_cycles=Flat_ReadCycles;
  interf->get_cycle_length=Flat_GetCycleLength;

#ifdef VERBOSE_MEM_TYPE
  printf("\nArmflat.c MemInit Type 0x%04x=%u\n",
         (unsigned)type,(unsigned)type);
#endif

  /* Fill in my functions */
  switch (memtype) {
#ifdef PIPELINED
  case ARMul_MemType_PipelinedBasic:
    interf->x.pipe.next=NextCycle;
    interf->x.pipe.access=MemAccessCached;
    interf->x.pipe.delta_cycles = NULL;
    break;
  case ARMul_MemType_PipelinedAMBA:
    interf->x.pipe.next=NextCycle;
    interf->x.pipe.access=MemAccessCached;
    interf->x.pipe.delta_cycles = NULL;
    break;
  case ARMul_MemType_PipelinedARM9:
    interf->x.pipe_arm9.dside_next = NextDCycle;
    interf->x.pipe_arm9.iside_next = NextICycle;
    interf->x.pipe_arm9.harvard_access = MemAccessHarvard;
    interf->x.pipe_arm9.debug_access = MemAccess;
    break;
#endif
  case ARMul_MemType_Basic:
  case ARMul_MemType_16Bit:
    interf->x.basic.access=MemAccess;
    state->p_ABus->bus_Type = BT_Endian;
    break;
  case ARMul_MemType_Thumb:
    interf->x.basic.access=MemAccessThumb;
    state->p_ABus->bus_Type = BT_Endian;
    break;
  case ARMul_MemType_AHB:
  case ARMul_MemType_16BitCached:
  case ARMul_MemType_ThumbCached:
  case ARMul_MemType_ARMissAHB:
    interf->x.basic.access=MemAccessCached;
    state->p_ABus->bus_Type = BT_Endian;
    break;
  case ARMul_MemType_ARM8:
    interf->x.arm8.access=MemAccess;
#ifdef MEM_ACCESS2_DISTINCT
    interf->x.arm8.access2=MemAccess2;
#else
    interf->x.arm8.access2=MemAccess;
#endif
    state->p_ABus->bus_Type = BT_Endian;
    Hostif_PrettyPrint(hostif,config,", double-bandwidth");
    break;
  case ARMul_MemType_StrongARM:
    interf->x.strongarm.access=MemAccessSA;
    interf->x.strongarm.data_cache_busy=DataCacheBusy;
    state->p_ABus->bus_Type = BT_Endian | BT_Harvard;
    Hostif_PrettyPrint(hostif,config,", StrongARM dual-ported");
    break;
#ifndef NO_BYTELANES
  case ARMul_MemType_ByteLanes:
    interf->x.basic.access=MemAccessBL;
    Hostif_PrettyPrint(hostif,config,", byte-laned");
    break;
#endif
  case ARMul_MemType_ARM9:

    interf->x.arm9.access = MemAccess; /* used by debugger */
    interf->x.arm9.harvard_access = MemAccessHarvard;
    state->p_ABus->bus_Type = BT_Endian | BT_Harvard;
    break;
#ifdef OldCode
  case ARMul_MemType_ARMissAHB:
      Hostif_PrettyPrint(hostif,config,", AHB");
      interf->x.armiss_ahb.debug_access=MemAccess;
      interf->x.armiss_ahb.ahb_access=MemAccessAsync;
      state->p_ABus->bus_Type = BT_Endian;
      break;
#endif
  case ARMul_MemType_ARMissCache: /* NOT HANDLED */
  default:
      Hostif_PrettyPrint(hostif,config,"\n Cannot handle memory-type 0x%x.\n",
                         memtype);
      return RDIError_UnableToInitialise;
  }
  /* If we were inserting ourselves into the chain, we'd use
   * ARMul_SwapMasterInfo (called by ARMul_InsertMemInterface2).
   */
  top->mem_ref.handle = interf->mem_link->handle;
  top->mem_ref.master_info = interf->mem_link->master_info;

  top->mem_ref.mif = interf;
  interf->mem_link = &top->mem_ref;



   { uint32 busClockDivisor = 
         ToolConf_DLookupUInt(config, ARMulCnf_MCCfg, 0);
   if (0 == busClockDivisor)
   {
       assert(0);
       busClockDivisor = 1;
   }
   if (top->p_ABus->bus_RegisterPeripHandle == NULL)
   {
     ARMul_Bus_Initialise(top->p_ABus,
                        busClockDivisor,
                        ARMul_BusAccess, /* bus_decoderFunc */
                        state, /* bus_DecoderHandle */
                        ARMul_BusRegisterPerip, /* bus_registerPeripFunc */
                        NULL, /* bus_RegisterPeripHandle */
                        NULL
                        );
   }
   else
   {
     top->p_ABus->bus_CycleLength = busClockDivisor;
   }
   }
   top->p_ABus->bus_LogWidth = 
       flatmem_log2(ToolConf_DLookupUInt(config, (tag_t)"BUS_WIDTH", 32));

#ifdef VERBOSE_BUS
   printf("After calling ARMul_Bus_Initialise : LogWidth=%u\n.",
          (unsigned)top->p_ABus->bus_LogWidth);
#endif

  mem=&top->mem;
  top->BaseMemoryEnabled = TRUE;
  option=ToolConf_Lookup(config,ARMulCnf_MCLK);
  if (option != NULL) clk_speed = ToolConf_Power(option,FALSE);
  if (option == NULL || clk_speed == 0) {
      /* We cannot really tell now, but assume that we have a cached core. */
      char const *opt1 = ToolConf_Lookup(config,(tag_t)"FCLK");
      uint32 cpuspeed = opt1 ? ToolConf_Power(opt1,FALSE) : 0;
      uint32 mccfg = ToolConf_DLookupUInt(config,(tag_t)"MCCFG",0);

      if (!cpuspeed)
      {
          option=ToolConf_Lookup(config,(tag_t)"CPUSPEED");
          cpuspeed = option ? ToolConf_Power(option,FALSE) : 0;
      }
      if (!cpuspeed)
      {
          option=ToolConf_Lookup(config,(tag_t)"DEFAULT_CPUSPEED");
          cpuspeed = option ? ToolConf_Power(option,FALSE) : 0;
      }
      clk_speed = (mccfg != 0) ? cpuspeed / mccfg : 0;

      Hostif_PrettyPrint(hostif,config,
                         "\n*** Core failed to define MCLK - guessing %lu.\n",
                         (unsigned long)clk_speed);
  }
  if (clk_speed == 0) {
      top->clk=0.0;
  } else {
      top->clk=1000000.0/clk_speed; /* in microseconds */
  }

  top->clk_speed = clk_speed;

  /* only report the speed if "CPU Speed" has been set in the config */
 
  if (ARMul_ClockIsEmulated(config)) {
    char *fac;
    double clk=ARMul_SIRange(clk_speed,&fac,FALSE);
    if (clk)  /* Don't print this if it is zero */
        Hostif_PrettyPrint(hostif,config,", %.1f%sHz",clk,fac);
  }


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

  Hostif_PrettyPrint(hostif,config, ", 4GB");

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

  assert(top->memtype == memtype);

  option = ToolConf_Lookup(config, ARMulCnf_MemoryByteSex);
  if (option == NULL) {
    top->memory_byte_sex = FALSE; /* follow bigendSig on core */
  } else switch (safe_toupper(option[0])) {
  case 'B':
    top->memory_byte_sex = TRUE;
    top->write_bigend = TRUE;   /* writes always bigendian */
    break;
  case 'L':
    top->memory_byte_sex = TRUE;
    top->write_bigend = FALSE;  /* writes always littleendian */
    break;
  default:
    top->memory_byte_sex = FALSE; /* follow bigendSig on core */
    break;
  }

  assert(top == state);

  if (!(type & RDIOpen_ByteSexMask))
  { /* We are being told, rather than asked */
      ConfigChange(state, !!(type & 4));
  }



  /* Also handles ConfigChange and DebugEvents!...*/
  ARMulif_InstallEventHandler(&state->coredesc,
                              (ConfigEventSel | DebugEventSel),
                              Flatmem_ConfigEvents, state);
  ARMulif_InstallUnkRDIInfoHandler(&state->coredesc,UnkRDIInfo,top);

  interf->handle=top;

  top->HighestPeripheralAddress = ~(ARMword)0;


  top->NewPageAllocated = calloc(1,sizeof(GenericAccessCallback));
  top->NewPageAllocated->func = flat_newPage;
  top->NewPageAllocated->handle = top;

#ifdef VERBOSE_INIT
   printf("END_INIT(Flatmem)\n.");
#endif
   /* Tell the Core we provide a Bus.
    * This shall allow it to know when we need to be called.
    * Flatmem does this before loading its children, so they can
    * access this bus.
    */
   { static ARMword ID[2] = {BMPropertyID_NewBusConnected,0};
   void *a_pointer = top->p_ABus;
   flatmem_masterInfo(top,ACCESS_WRITE,ID,(uint64*)&a_pointer);
   }

   assert(dbg_state != NULL);
   assert(((RDI_DbgStateForSubAgent *)dbg_state)->size == sizeof(RDI_DbgStateForSubAgent));
   assert(((RDI_DbgStateForSubAgent *)dbg_state)->lib_handle != NULL);

   ARMulAgent_Create(&state->agent, hostif, config,
                     dbg_state,
                     NULL, /*dll_name*/
                     NULL /*ARMul_RDIProcs*/,
        NULL /*((RDI_DbgStateForSubAgent *)dbg_state)->agent_desc.rdi*/);
   if (verbose)
   {
       Hostif_PrettyPrint(hostif,config,"\nFLAT LOADS PERIPHERALS...\n");
   }

   {
       toolconf child = ToolConf_Child(config,(tag_t)"PERIPHERALS");

       ARMul_Agent *agent = (ARMul_Agent *)state->agent;
       agent->module_desc = *dsa->agent_desc; /* Core */
       agent->subagent_desc = *dsa->parent_desc; /* Transparent Agent */
       agent->init_type = type; /* ? Can I add this to the constructor? */
       if (child)
       {
           int err = ToolConf_IterateTags(child, ARMulAgent_AddPeripheral,
                                          state->agent);
           if (err != RDIError_NoError)
           {
#ifdef VERBOSE_INIT
               printf("\nARMul_AddComponent returned err=%i.\n", err);
               /* ToolConf_WriteTo(tconf,stderr); */
               /*fprintf(stderr,"\n>>>>\n");*/
#endif
               Hostif_PrettyPrint(hostif,config,
                  "\n A child of Flatmem failed to initialize, error %i.\n",
                         err);
               return(RDIError_UnableToInitialise);
           }
           if (verbose)
           {
               Hostif_PrettyPrint(hostif,config,"\nFLAT LOADED\n");
           }
       }
       else
       {
           if (verbose)
           {
               Hostif_PrettyPrint(hostif,config,"\nFLAT HAS NO PERIPHERALS\n");
           }
       }
   }

#ifdef VERBOSE_INIT
   printf("END_INIT(Flatmem)\n.");
#endif
}
END_INIT(Flatmem)





/* --- BEGIN PERIPHERAL-ACCESS --- */

#include "rdi_err.h"

static int peripheral_access(void *handle,
                             ARMword address,
                             ARMword *data,
                             ARMul_acc acc)
{

    toplevel *ts=(toplevel *)handle;
  /* See if any peripheral registered on ABus, 
   * unless we have an I- or C-cycle. */

#ifdef VERBOSE_PERIPHERAL_ICYCLES
    if (ACCESS_IS_IDLE(acc))
        printf("armflat.c:peripheral_access(A:%08lx T:%08lx)\n",
               (unsigned long)address, (unsigned long)acc);
#endif


#ifdef NO_IDLES_TO_PERIPHERALS
   if (!(acc & acc_Nmreq))
#endif
   {
       ARMul_Bus *bus = ts->p_ABus;

       ARMul_AccessRequest req;
       int err;
       memset(&req,0,sizeof(req));
       req.req_access_type = acc;
       req.req_addr_size = 1;
       req.req_address[0] = address;
       req.req_data = data;
       err = bus->bus_decoderFunc(bus, &req);
       return Perip2Memret(err);
   }
   return -2; /* Pass Idles back to memory. */
}

/* --- END PERIPHERAL-ACCESS --- */






static unsigned flat_newPage(struct GenericAccessCallback *myCB,
                             ARMword address,
                             ARMword*data, unsigned access_type)
{
    toplevel *top=(toplevel *)myCB->handle;
    unsigned i;
    unsigned nw = access_type / sizeof(ARMword);

    assert(access_type == ARMFLAT_PAGESIZE);
    (void)access_type; (void)address; (void)top;

  /*
   * We fill the new page with data that, if the ARM tried to execute
   * it, it will cause an undefined instruction trap (whether ARM or
   * Thumb)
   */
  for (i=0;i<nw;) {
    data[i++]=0xe7ff0010; /* an ARM undefined instruction */
    /* The ARM undefined insruction has been chosen such that the
     * first halfword is an innocuous Thumb instruction (B 0x2)
     */
    data[i++]=0xe800e800; /* a Thumb undefined instruction */
  }
   /* We are the last in the chain, registered first. */
  assert(myCB->next == NULL);

  return 0;
}


static mempage *NewPage(void *handle,ARMword address)
{
  toplevel *top=(toplevel *)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
     */
      Hostif_DebugPrint(top->hostif, "OUT OF MEMORY\n");
      ARMulif_StopExecution(&top->coredesc, RDIError_OutOfStore);
      return top->mem.page[0];
  }

  top->NewPageAllocated->func(top->NewPageAllocated,address,
                             page->memory,ARMFLAT_PAGESIZE);


  return page;
}


/*
 * Generic memory interface.
 */

/*
 * This is the most basic memory access function - an ARM6/ARM7 interface.
 */
static int MemAccess(void *handle,
                     ARMword address,
                     ARMword *data,
                     ARMul_acc acc)
{
  toplevel *top=(toplevel *)handle;
  unsigned int pageno;
  mempage *page;
  ARMword *ptr;
  ARMword offset;
  int rv;

  if (acc_ACCOUNT(acc)) {
      COUNTCYCLES(top->cycles,acc);

⌨️ 快捷键说明

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