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

📄 mapfile.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
    return top->mem.page[0];
    }

  /*
   * 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<ARMMAP_PAGESIZE/4;) {
    page->memory[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)
     */
    page->memory[i++]=0xe800e800; /* a Thumb undefined instruction */
  }
  return page;
}
#endif

/*
 * Generic memory interface. Just alter this for a memtype memory system
 */

/* Returns a PERIP_ value from minperip.h */
static INLINE int FindMemoryRegion(
    MapfileState *top, ARMword address, ARMword *data, ARMul_acc acc,
    Bus *bus)
{
  /* first cycle of the access */
  MemDescr *desc;
  unsigned long prop = top->prop;

  (void)data;
      
  for (desc = &top->desc; desc; desc = desc->next) {
    if (address >= desc->desc.start &&
        address <= desc->desc.limit) {

      desc->access_counts[acc & (WIDTH_MASK | acc_seq | acc_Nrw)]++;

      desc->stats_are_valid = FALSE;

      /* If we're looking for I-S cycles, then use the N cycle
       * counter if we're on an I-S boundary
       */
      if ((prop & MAP_SPOTISCYCLES) &&
          acc_SEQ(acc) &&
          acc_nMREQ(bus->last_acc)) {
        /* Use the 'this width, idle, read/write' counter */
        bus->cnt = desc->counter[(acc & (WIDTH_MASK | acc_Nrw)) | acc_Nmreq];
        if (prop & MAP_AMBABUSCOUNTS) {
          /* This count includes an extra cycle for AMBA decode. We
           * don't need this for I-S cycles, so we need to remove it.
           */
          if (bus->cnt > 0) bus->cnt--;
        }
        top->IS_cycles++;
      } else
        bus->cnt = desc->counter[acc & (WIDTH_MASK | acc_seq | acc_Nrw)];

      if (bus->cnt) {
        if (bus->cnt < 0) {
          if (bus->cnt == -1) {/* abort */
            bus->cnt = 0;
            bus->last_acc = acc;

#ifdef VERBOSE_DABORT
            printf("Mapfile DABORT addr:%08lx\n", (unsigned long)address);
#endif

            return PERIP_DABORT /*-1*/;
          }
          /*
           * otherwise, this is a 16-bit SEQ read
           * - takes 1 cycle if top half of word,
           * - takes -cnt-2 cycles otherwise.
           */
          if ((address & 2) == 0) bus->cnt = -bus->cnt-2;
          else break;       /* i.e. fall through - 1 cycle */
        }
        bus->wait_states++;
        bus->last_acc = acc;
        return PERIP_BUSY /*0*/;
      }
      break;                /* fall through */
    } /* endif in-region */
  } /* endfor */
  if ((prop & MAP_AMBABUSCOUNTS) &&
      acc_MREQ(acc) && acc_nSEQ(acc)) {
    /* needs an address decode cycle */
    bus->cnt = 1;
    bus->wait_states++;
    bus->last_acc = acc;
    return PERIP_BUSY /*0*/;
  }

  return PERIP_OK /*1*/;
}

#if USE_BASE_MEMORY
#else
static int MemLookup(MapfileState *top, ARMword address, ARMword *data,
                     ARMul_acc acc)
{
  unsigned int pageno;
  mempage *page;
  ARMword *ptr;
  ARMword offset;

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

#ifdef VERBOSE_MEMLOOKUP
  printf("mapfile:MemLookup(A:%08lx T:%08lx)\n",
         (unsigned long)address,(unsigned long)acc);
#endif

  switch (acc & (ACCESS_SIZE_MASK | ACCESS_IDLE | ACCESS_WRITE) ) 
    {
      case BITS_8:              /* read byte */
        *data = ((unsigned8 *)ptr)[(address ^ top->byteAddrXor) & 3];
        break;
        
      case BITS_16:           /* read half-word */
        *data = *((unsigned16 *)(((char *)ptr)+
                                 ((address ^ top->hwordAddrXor) & 2)));
        return 1;

      case BITS_32:             /* read word */
        *data=*ptr;
        return 1;

      case BITS_64:             /* read dword */
        *data=*ptr;
        if ((offset+4) & OFFSETBITS_WORD) 
        {
            data[1]=ptr[1];
            return 2;
        }
        break;


      case BITS_8 | ACCESS_WRITE:              /* write_byte */
        if (HostEndian!=top->write_bigend) address^=3;
        ((unsigned8 *)ptr)[address & 3]=(unsigned8)(*data);
        break;
        
      case BITS_16 | ACCESS_WRITE:             /* write half-word */
        if (HostEndian!=top->write_bigend) address^=2;
        *((unsigned16 *)(((char *)ptr)+(address & 2))) = (unsigned16)(*data);
        break;

      case BITS_32 | ACCESS_WRITE:             /* write word */
        *ptr=*data;
        return 1;

    case BITS_64 | ACCESS_WRITE:
        *ptr=*data;
        if ((offset+4) & OFFSETBITS_WORD) 
        {
            ptr[1]=data[1];
            return 2;
        }
        break;

      case ACCESS_IDLE:
        return 1;
        
      default:
#ifdef VERBOSE_DABORT
          printf("mapfile:MemLookup -> abort\n");
#endif
          return PERIP_DABORT;

    }
  return PERIP_OK;
}
#endif

static int Mapfile_MemAccess(void *handle, ARMWord address, ARMWord *data,
                             unsigned acc)
{
    MapfileState *top=(MapfileState *)handle;

#ifdef VERBOSE_ACCESS
    /* if (ACCESS_IS_IDLE(acc)) */
    {
        printf("Mapfile_Access AD:%08lx AC:%04lx\n",
               (unsigned long)address, (unsigned long)acc);
    }
#endif

  if (ACCESS_IS_REAL(acc)) 
  {
    ++top->cycles.Total;

#ifdef VERBOSE_ACCOUNTED_ACCESS
        printf("Mapfile_Access! AD:%08lx AC:%04lx\n",
               (unsigned long)address, (unsigned long)acc);
#endif
    if (acc_MREQ(acc)) {
      if (top->d.cnt == 0 || acc != top->d.last_acc) {
        int rv = FindMemoryRegion(top, address, data, acc, &top->d);
        if (rv != PERIP_OK) {
          ADVANCE_BUS_TIME;
          return rv;
        }
        /* else fall through */
      } else {
        /* not the first cycle */
        if (--top->d.cnt) {
          top->d.wait_states++;
          top->d.last_acc = acc;
          ADVANCE_BUS_TIME;
          return PERIP_BUSY;
        }
        /* else fall through */
      }

    } else {
      if (acc_SEQ(acc)) {
        top->cycles.NumCcycles++;
      } else {
        top->cycles.NumIcycles++;
      }
    }
    top->d.cnt = 0;
    top->d.last_acc = acc;
  } /* endif ACCESS_IS_REAL */
  
#if USE_BASE_MEMORY /* T */
  return top->child.x.basic.access(top->child.handle, address, data, acc);
#else
  return MemLookup(top, address, data, acc);
#endif
}


static int Mapfile_MemAccessSA(void *handle,ARMWord address, ARMWord *data,
                               unsigned acc)
{
    MapfileState *top=(MapfileState *)handle;

  if (ACCESS_IS_REAL(acc)) {
    Bus *bus;
    if (acc_OPC(acc)) {
      ++top->cycles.Total;
      bus = &top->i;
    } else {
      bus = &top->d;
    }
    if (acc_MREQ(acc)) {
      if (bus->cnt == 0 || acc != bus->last_acc) {
        int rv = FindMemoryRegion(top, address, data, acc, bus);
        if (rv != PERIP_OK) {
          ADVANCE_BUS_TIME;
          return rv;
        }
        /* else fall through */
      } else {
        /* not the first cycle */
        if (--bus->cnt) {
          bus->wait_states++;
          bus->last_acc = acc;
          ADVANCE_BUS_TIME;
          return PERIP_BUSY /*0*/;
        }
        /* else fall through */
      }

      /*
       * On Harvard architectures there are four types of cycle -
       * we'll reuse the four cycle counters for these:
       *
       *  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_OPC(acc)) {
        /* End of cycle - account for access */
        /* This access is either acc_LoadInstrN or acc_NoFetch */
        if (top->harvard_data_flag) {
          /* data fetched */
          top->harvard_data_flag = FALSE;
          top->cycles.NumScycles++; /* instr/data */
        } else {
          /* no data fetched */
          top->cycles.NumNcycles++;/* instr/no data */
        }
      } else {
        /* don't count on data accesses */
        /* data fetched */
        top->harvard_data_flag = TRUE;
      }
    } else {
      if (acc_OPC(acc)) {
        /* End of cycle - account for access */
        /* This access is either acc_LoadInstrN or acc_NoFetch */
        if (top->harvard_data_flag) {
          /* data fetched */
          top->harvard_data_flag = FALSE;
          top->cycles.NumCcycles++; /* no instr/data */
        } else {
          /* no data fetched */
          top->cycles.NumIcycles++;/* no instr/no data */
        }
      }
    }
    bus->cnt = 0;
    bus->last_acc = acc;
  }
#if USE_BASE_MEMORY
  return top->child.x.basic.access(top->child.handle, address, data, acc);
#else
  return MemLookup(top, address, data, acc);
#endif
}

static const ARMul_Cycles *Mapfile_ReadCycles(void *handle)
{
  static ARMul_Cycles cycles;
  MapfileState *top=(MapfileState *)handle;

  if (!(top->prop & MAP_HARVARD)) {
    ARMword n = 0, s = 0;
    MemDescr *d;
    
    for (d = &top->desc; d != NULL; d = d->next) {
      ARMul_acc acc;
      for (acc = 0; acc < 0x60; acc++) {
        if (acc_MREQ(acc)) {
          if (acc_SEQ(acc)) {
            s += d->access_counts[acc];
          } else {
            n += d->access_counts[acc];
          }
        }
      }
    }
    top->cycles.NumNcycles = n;
    top->cycles.NumScycles = s;
  }

/*  if (top->prop & (MAP_COUNTWAIT | MAP_AMBABUSCOUNTS))  */
  {
    cycles.NumNcycles = top->cycles.NumNcycles;
    cycles.NumScycles = top->cycles.NumScycles;
    cycles.NumIcycles = top->cycles.NumIcycles + top->cycles.NumCcycles;
    cycles.NumCcycles = top->d.wait_states + top->i.wait_states;
  }
/*   else  {
 *    cycles = top->cycles;
 * }
 */
  cycles.Total = top->cycles.Total;
  return &cycles;
}



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

#ifdef VERBOSE_Mapfile_MemAccessHarvard
    printf("Mapfile_MemAccessHarvard BEGIN DA:%08lx DT:%04lx "
           " IA:%08lx IT:%04lx    DS:%i IS:%i\n",
           (unsigned long)daddr,(unsigned long)dacc,
           (unsigned long)iaddr,(unsigned long)iacc, *drv, *irv);
#endif
    /* We do D then I because MemAccessSA expects that. */
    if (!*drv)
        *drv = Mapfile_MemAccessSA(handle,daddr,ddata,dacc);
    else
        Mapfile_MemAccessSA(handle,daddr,ddata,ACCESS_IDLE|ACCESS_DATA);
    if (!*irv)
        *irv = Mapfile_MemAccessSA(handle,iaddr,idata,iacc);
    else
        Mapfile_MemAccessSA(handle,iaddr,idata,ACCESS_IDLE|ACCESS_INSTR);
#ifdef VERBOSE_Mapfile_MemAccessHarvard
    printf("Mapfile_MemAccessHarvard END -> DS:%i IS:%i\n",
           *drv, *irv);
#endif
}



BEGIN_EXIT(Mapfile)
{
  ARMword page;
  MapfileState *top=state; /* (MapfileState *)handle */
  memory *mem=&top->mem;
  MemDescr *desc,*next;

  /* free all truly allocated pages */
  for (page=0; page<NUMPAGES; page++) {
    mempage *pageptr= mem->page[page];
    if (pagept

⌨️ 快捷键说明

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