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

📄 mapfile.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
     u64_to_dbl(top->cycles.NumIcycles) +
     u64_to_dbl(top->cycles.NumCcycles)  +
     u64_to_dbl(top->d.wait_states))*top->clk;  
#ifdef VERBOSE_TIMES
  printf("Mapfile_ReadClock->%f (clk=%f)\n Ncycles = %d\n, scycles = %d\n, Icycles = %d\n, ccycles = %d\n wait states = %d\n",
         t,top->clk, 
         (unsigned int)top->cycles.NumNcycles, 
         (unsigned int)top->cycles.NumScycles,
         (unsigned int)top->cycles.NumIcycles,
         (unsigned int)top->cycles.NumCcycles,
         (unsigned int)top->d.wait_states);
#endif
  return (ARMTime)(int64)t;
}


static unsigned Mapfile_MemInfo(void *handle, unsigned type, ARMword *pID,
                                uint64 *data)
{
    MapfileState *top=(MapfileState *)handle;
    if (ACCESS_IS_READ(type))
    {
        switch (*pID) {
        case MemPropertyID_TotalCycles:
            *data = top->cycles.Total;
            return RDIError_NoError;
        case MemPropertyID_CycleSpeed:
            *data = top->clk_speed;
            return RDIError_NoError;
#if USE_BASE_MEMORY
#else
        case MemPropertyID_BaseMemoryRef:    /* We are a LEAF */
            *(ARMul_MemInterfaceRef*)data = top->mem_ref;
            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;
#endif
        default:
            break;
        }
    }
    else
    {
        switch (*pID) {
#if USE_BASE_MEMORY
#else
        case MemPropertyID_BaseMemoryEnable: /* We are a LEAF */
            top->BaseMemoryEnabled = (bool)*data;
            return RDIError_NoError;
#endif
        default:
            break;
        }
    }
    /* Ask Flatmem. */
    if (top->child.mem_info)
    {
        return top->child.mem_info(top->child.handle,type,pID,data);
    }
    else
    {
        return RDIError_UnimplementedMessage;
    }
}

static bool Mapfile_InsertMemory(toplevel *ts)
{
    /* First, get the bus */
    /* Then a reference to the start of the (non-cache)memory-chain */
    ARMword *pprop = &ts->prop;

    ARMul_MemInterface *mif;
    uint32 ID[2];
    ID[0] = ARMulBusID_Bus;
    ID[1] = 0;
    mif = ARMulif_QueryMemInterface(&ts->coredesc, &ID[0]);
    if (!mif)
    {
        ID[0] = ARMulBusID_Core;
        mif = ARMulif_QueryMemInterface(&ts->coredesc, &ID[0]);
    }

    /* Ask for the last reference in the chain. */
    if (mif)
    {
        ARMul_MemInterface *mif2 = NULL;        
        uint32 ID[2]; ID[0]=MemPropertyID_BaseMemoryRef; ID[1]=0;
        mif->mem_info(mif->handle,
                      ACCESS_WRITE|ACCESS_WORD,&ID[0],(uint64*)&mif2);
        if (mif2)
        {
            mif = mif2;
        }
    }


#ifdef VERBOSE_BUS
    printf("Mapfile::mif=%p ID:%u\n",mif,(unsigned)ID[0]);
#endif
    if (mif)
    {
        /* Ask the downstream memory for its bus.
         * If that fails (because the bus is now owned by BIU instead
         * of Flatmem) ask the core.
         * !TODO: Ask >upstream< memory.
         */
        {
            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)
            {
                ARMulif_QueryBus(&ts->coredesc,"",&ts->pABus);
            }

            if (!ts->pABus)
            {
                Hostif_PrettyPrint(ts->hostif,ts->config,
        "\n** Mapfile got no response to query for MemPropertyID_Bus **\n");
                ts->pABus = calloc(1,sizeof(ARMul_Bus));
                /* Later, construct such a bus? (*/

                ts->FailedToInstal = TRUE;
                return FALSE; /*RDIError_UnableToInitialise;*/
            }
        }

        ts->bus_mem.handle = ts;

        ts->bus_mem.x.basic.access = Mapfile_MemAccess;
        
        /* <Copy info thru. */
        ts->bus_mem.mem_info=Mapfile_MemInfo;
        /* If not emulated time, don't offer one */
        if (mif->read_clock)
            ts->bus_mem.read_clock=Mapfile_ReadClock;
        ts->bus_mem.read_cycles=Mapfile_ReadCycles;
        ts->bus_mem.get_cycle_length = Mapfile_GetCycleLength;
        ts->memtype = mif->memtype;
        switch(ts->memtype) 
        {
        case ARMul_MemType_Basic:
        case ARMul_MemType_16Bit:
        case ARMul_MemType_Thumb:
/*        case ARMul_MemType_BasicCached: */
        case ARMul_MemType_16BitCached:
        case ARMul_MemType_ThumbCached:
        case ARMul_MemType_ARMissAHB:
            break;
        case ARMul_MemType_AHB:
            break;
        case ARMul_MemType_StrongARM:
            *pprop |= MAP_HARVARD;
            ts->bus_mem.x.strongarm.access = Mapfile_MemAccessSA;
            ts->bus_mem.x.strongarm.core_exception = Mapfile_CoreException;
            ts->bus_mem.x.strongarm.data_cache_busy = Mapfile_DataCacheBusy;
            break;
        case ARMul_MemType_ARM8:
            ts->bus_mem.x.arm8.core_exception = Mapfile_CoreException;
            ts->bus_mem.x.arm8.access2 = Mapfile_MemAccess; /* MemAccess2 */
            break;

        case ARMul_MemType_ARM9: /* ARM9 Harvard   */
            *pprop |= MAP_HARVARD;
            ts->bus_mem.x.arm9.harvard_access = Mapfile_MemAccessHarvard;
            break;
        case ARMul_MemType_ARMissCache:
        case ARMul_MemType_ByteLanes:       
        default:
            Hostif_ConsolePrint(ts->hostif,
                     "Mapfile cannot handle this type of MemoryInterface.\n");
            return FALSE;
        }
        ARMul_InsertMemInterface(mif,
                                 &ts->child,
                                 &ts->mem_ref,
                                 &ts->bus_mem);
        return TRUE;
    }
    else
    {
        Hostif_ConsolePrint(ts->hostif,
                            "Core didn't give Mapfile a MemoryInterface.\n");
        return FALSE;
    }
}



/*
 * RDIInfo proc for installing the memory map.
 * Adds to the HEAD of the list
 *
 * Returns 0:Ok else error.
 */

static int InstallMemDescr(void *handle, RDI_MemDescr *md, char *region_name)
{
  MapfileState *top=(MapfileState *)handle;
  long cnt = 1, seq = 1, counter;
  int i, limit;
  unsigned long mult=top->mult,period=top->period;
  MemDescr *list = top->FailedToInstal ? NULL:calloc(1,sizeof(MemDescr));
  if (list==NULL) 
  {
      return (top->FailedToInstal=TRUE);
  }


  if (top->num_regions == 0) {
    if (Mapfile_InsertMemory(top))
        Hostif_ConsolePrint(top->hostif,"Memory map:\n");
    else
    {
        Hostif_ConsolePrint(top->hostif,"Memory map cannot start-up.\n");
        top->FailedToInstal = TRUE;
        return RDIError_Error;
    }
  }

  ++top->num_regions;

  *list = top->desc;
  top->desc.next = list;
  list = &top->desc;

  list->md_Name = StrDup(region_name);
  list->desc=*md;

  list->desc.limit+=list->desc.start-1;
  list->desc.width+=BITS_8;     /* 0->8 bits, 1->16, 2->32 */

  Hostif_ConsolePrint(top->hostif,"\
  %08x..%08x, %.2d-Bit, %c%c%c, wait states:",
                    list->desc.start,list->desc.limit,
                    1<<list->desc.width,
                    (list->desc.access & 4) ? '*' : ' ',
                    (list->desc.access & 2) ? 'w' : '-',
                    (list->desc.access & 1) ? 'r' : '-');



  /*
   * Cycle counts are kept in an array so that the mem_access function only
   * has to do an array lookup to get the cycle count. The work is done
   * here in setting up the array.
   * When spotting I-S cycles, the mem_access function uses an otherwise
   * unused entry (that for an idle cycle) to get the number of wait states.
   */

  limit = (top->prop & MAP_SPOTISCYCLES) ? 0x60 : 0x40;

  /* Many times around this loop correspond to illegal values of
   * acc_WIDTH.
   * Two values -- cnt and seq -- are used to say how many cycles are
   * needed for this type of access (N/S/I-S, Read or Write), cnt being
   * the number of cycles for the access, seq being for any sequential
   * cycles needed when accessing a value wider than the bus.
   * These values are invariant across the different bus widths, so are
   * set up the first time around the loop for a particular access type,
   * when the bus width is the illegal value '0'
   */

  for (i = 0; i < limit; i++) {
    counter=1;
    switch (acc_WIDTH(i)) {
    case BITS_64:
      counter=((list->desc.width==BITS_8) ? (cnt + seq * (8-1)) :
               (list->desc.width==BITS_16) ? (cnt + seq * (4-1)) :
               (list->desc.width==BITS_32) ? (cnt + seq * (2-1)) : cnt);
      if (acc_nSEQ(i) && acc_MREQ(i) && counter &&
          (top->prop & MAP_AMBABUSCOUNTS)) {
        counter++;              /* AMBA decode cycle for N */
      }
      break;
    case BITS_32:
      counter=((list->desc.width==BITS_8) ? (cnt + seq * 3) :
               (list->desc.width==BITS_16) ? (cnt + seq) : cnt);
      if (acc_nSEQ(i) && acc_MREQ(i) && counter &&
          (top->prop & MAP_AMBABUSCOUNTS)) {
        counter++;              /* AMBA decode cycle for N */
      }
      break;

    case BITS_16:
      counter=((list->desc.width==BITS_8) ? (cnt + seq) : cnt);
      if (!acc_SEQ(i) && counter && top->prop & MAP_AMBABUSCOUNTS)
        counter++;              /* AMBA decode cycle for N */
      if (acc_READ(i) && acc_SEQ(i) && (list->desc.access & 4) &&
          counter > 1) {
        /* latched read possibly */
        counter = -counter;
      }
      break;

    default:
    case BITS_8:
      counter=cnt;
      if (!acc_SEQ(i) && counter && top->prop & MAP_AMBABUSCOUNTS)
         counter++;             /* AMBA decode cycle for N */
      break;

    case 0:
      /* First time round for this access type - get the base figures. */
      if (acc_nMREQ(i)) {
        /* Time for I-S cycles, if spotting them */
        if (acc_READ(i)) {
          if ((list->desc.access & 1) != 0) {   /* read okay */
            /* number of ticks needed for a sequential access */
            seq = list->desc.Sread_ns * mult;
            /* now divide by 'period' to get number of cycles, and add one
             * more cycle if there's any remainder */
            seq = (seq / period) + ((seq % period) != 0 || (seq == 0));

            /* cnt is set to the number of ticks needed for a non-seq
             * access. */
            cnt = list->desc.Nread_ns * mult;

            /* The number of wait-states needed for an I-S access depends
             * on the mode being used, which determines how many cycles there
             * are to start with.
             */
            switch (top->prop & MAP_ISMODE) {
            case MAP_IS_SPEC:
              /* For speculative decode, there are 2 cycles to start with */
              /* divide by the period to get the number of cycles, add one
               * more if there's any remainder, then take off the one free
               * we have from the speculative decode */
              cnt = (cnt / period) + ((cnt % period) != 0) - 1;
              break;

            case MAP_IS_EARLY:
              /* For the early decode, there are 1.5 cycles to start with */
              /* divide by the period to get the number of cycles, and add
               * one if the remainder is greater than half-a-cycle. */
              cnt = (cnt / period) + ((cnt % period) >= (period / 2));
              break;

            case MAP_IS_LATE:   /* one + wait cycle */
              /* For the late decode, there's only 1 cycle to start with */
              /* now divide by 'period' to get number of cycles, and add one
               * more cycle if there's any remainder */
              cnt = (cnt / period) + ((cnt % period) != 0);
              break;
            }
            /* Make sure we have at least 1 cycle! */
            if (cnt <= 0) cnt = 1;
          } else {
            seq = cnt = 0;      /* zero cycles signals 'abort' */
          }
        } else {                /* write */
          if ((list->desc.access & 1) != 0) {   /* read okay */
            /* see above */
            seq = list->desc.Swrite_ns * mult;
            seq = (seq / period) + ((seq % period) != 0 || (seq == 0));

            cnt = list->desc.Nwrite_ns * mult;
            switch (top->prop & MAP_ISMODE) {
            case MAP_IS_SPEC:   /* two cycles */
              cnt = (cnt / period) + ((cnt % period) != 0) - 1;
              break;
            case MAP_IS_EARLY:  /* 1.5 cycles */
              cnt = (cnt / period) + ((cnt % period) >= (period / 2));
              break;
            case MAP_IS_LATE:   /* one cycle */
              cnt = (cnt / period) + ((cnt % period) != 0);
              break;
            }
            if (cnt <= 0) cnt = 1;
          } else {
            seq = cnt = 0;
          }
        }
      } else if (acc_READ(i)) { /* read */
        if (list->desc.access & 1) { /* read access okay */
          /* see above */
          seq = list->desc.Sread_ns * mult;
          seq = (seq / period) + ((seq % period) != 0 || (seq == 0));
          if (acc_SEQ(i)) {
            cnt = seq;
          } else {
            /* see above */
            cnt = list->desc.Nread_ns * mult;
            cnt = (cnt / period) + ((cnt % period) != 0 || (cnt == 0));
          }
        } else {
          seq = cnt = 0;
        }
      } else {                  /* write */
        if (list->desc.access & 2) { /* write access okay */
          /* see above */
          seq = list->desc.Swrite_ns * mult;
          seq = (seq / period) + ((seq % period) != 0 || (seq == 0));
          if (acc_SEQ(i)) {
            cnt = seq;
          } else {
            /* see above */
            cnt = list->desc.Nwrite_ns * mult;
            cnt = (cnt / period) + ((cnt % period) != 0 || (cnt == 0));
          }
        } else {
          seq = cnt = 0;
        }
      }

      /* report the wait states */
      Hostif_ConsolePrint(top->hostif, " %c", acc_READ(i) ? 'R' : 'W');

⌨️ 快捷键说明

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