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

📄 tracer.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
  option=ToolConf_Lookup(ts->config, ARMulCnf_Pipe);
  if (option) {
    ts->prop|=TRACE_PIPE;
    ts->output.handle=(void *)popen(option,"w");
    if (ts->output.handle == NULL) {
      Hostif_ConsolePrint(ts->hostif,
                         "Could not open pipe to '%s' - abandoning trace.\n",
                         option);
      return 0;
    }
    ts->output.write = (Tracer_WriteProc *)fwrite;
    ts->output.close = (Tracer_CloseProc *)pclose;
    ts->output.flush = (Tracer_FlushProc *)fflush;
    return 1;
  }
#endif
  
  fprintf(stderr,"No trace file configured - abandoning trace.\n");
  return 1;
}

static void Tracer_Close(TracerState *ts)
{
  if (ts->output.close)
    ts->output.close(ts->output.handle);
}

static void Tracer_Flush(TracerState *ts)
{
  if (ts->output.flush)
    ts->output.flush(ts->output.handle);
}

static GenericCallbackFunc Tracer_NumberedEventHandler;
static unsigned Tracer_NumberedEventHandler(void *handle, void *data)
{
  ARMul_Event *evt = (ARMul_Event *)data;
  TracerState *ts=(TracerState *)handle;

  unsigned int event = evt->event;
  /* ARMword addr1 = evt->data1; ARMword addr2 = evt->data2; */
    /* look at my set of handled events */
  TSEventNumberRecord *thing =
      (TSEventNumberRecord*)hash_Get(ts->ts_EventNumHash,event);


#if 0
      Hostif_ConsolePrint(ts->hostif, /*ts->config,*/
                       "\nTracer_NumberedEventHandler event 0x%08x %p %s\n", 
                       (unsigned)event, thing,
                          (thing != NULL) ? thing->name : "?");
#endif


  if (thing != NULL)
  {
      /* Trace thing.name, evt->data1, evt->data2 */
    void *f=ts->output.handle;
    Tracer_PrintfProc *tprintf = ts->output.tprintf;
#ifdef OldCode
    tprintf(f,"E %s 0x%08x 0x%08x", thing->name,
            (unsigned)evt->data1, (unsigned)evt->data2);
#else /* Make it look more like the old events */
    tprintf(f,"E %08lX %08lX %x %s",
            (unsigned)evt->data1, (unsigned)evt->data2,
            (unsigned)evt->event, thing->name);
#endif
    Tracer_newline(ts);
      if (ts->prop & TRACE_UNBUFF)
          Tracer_Flush(ts);
      /* !Todo: Remember this event so we don't
       * bother with the old event-format if we get the same event there.
       * (or some other duplication-avoidance-strategy)
       */
  }
  return FALSE;
}

/*
 * The function is called from the ARMulator when rdi_log & 16 is true.
 * It is used to generate an executed instruction stream trace.
 */
static GenericCallbackFunc Tracer_EventHandler;
static unsigned Tracer_EventHandler(void *handle, void *data)
{
  ARMul_Event *evt = (ARMul_Event *)data;
  TracerState *ts=(TracerState *)handle;

  Trace_Packet packet;
  unsigned int event = evt->event;
  ARMword addr1 = evt->data1; ARMword addr2 = evt->data2;
  /* Mask events */
  if ((event & ts->event_mask)!=ts->event_set)
      return FALSE;

  if ((ts->prop & TRACE_RANGE) && (addr1<ts->range_lo ||
                                   (addr1>=ts->range_hi && ts->range_hi!=0)))
    /* range test fails */
    return FALSE;

  if (ts->sample_base) {
    if (ts->sample--)           /* not this one */
      return FALSE;
    ts->sample=ts->sample_base-1;
  }

  packet.type=Trace_Event;

  packet.u.event.addr=addr1;
  packet.u.event.addr2=addr2;
  packet.u.event.type=event;

  Tracer_Dispatch(&ts->Core_Tracer,&packet);
  if (ts->prop & TRACE_UNBUFF)
      Tracer_Flush(ts);
  return FALSE;
}

/*
 * this function is called for every instruction.
 * Preconds:
 * . ts->Core_Tracer initialised.
 */

static void trace_func(void *handle, ARMword pc, ARMword instr,
                       ARMword cpsr, ARMword condpassed)
{
  TracerState *ts=(TracerState *)handle;
  Trace_Packet packet;

#if 0
  ts->output.tprintf(ts->output.handle,
     "trace_func pc:%08x i:%08x cpsr:%08x it:%u\n",
     (unsigned)pc,(unsigned)instr,(unsigned)cpsr,(unsigned)condpassed);
#endif

  if ((ts->prop & TRACE_RANGE) && (pc<ts->range_lo ||
                                   (pc>=ts->range_hi && ts->range_hi!=0)))
    /* range test fails */
  {
#if 0
      ts->output.tprintf(ts->output.handle,
           "trace_func range test fails.\n");
#endif
    return;
  }
  
  packet.u.instr.iset = ((cpsr >> (24-1)) & 2)  /* J BIT -> bit 1 */
                      | ((cpsr >> 5) & 1);      /* T BIT -> bit 0 */
  if (packet.u.instr.iset == ISET_JAVA)
  {
      /* Don't trace cycles which are not the first for each java-opcode,
       * or other things which are not real java opcodes
       * (e.g. prefetch abort) -
       * the disassembler will not understand. */
      if (ts->prop & TRACE_JAZELLEFAKEOPCODES)
      {
          /* This is only for debugging the core model. */
          if ((instr & JAVA_EXT_MASK) == JAVA_EXT_NOT_FIRST_CYCLE)
          {
              return;
          }
      }
      else
      {
          /* This is more generally useful. */
          if ((instr & JAVA_EXT_MASK) > 255)
              return;
      }

      /* condpassed is not useful for Java bytecodes. */
      packet.u.instr.executed = TRUE;
  }
  else
  {
      packet.u.instr.executed = (unsigned char)(condpassed & 1);
  }

  if (ts->sample_base) {
    if (ts->sample--)           /* not this one */
      return;
    ts->sample=ts->sample_base-1;
  }


  packet.type=Trace_Instr;
  packet.u.instr.pc=pc;
  packet.u.instr.instr=instr;
  Tracer_Dispatch(&ts->Core_Tracer,&packet);
  if (ts->prop & TRACE_UNBUFF)
      Tracer_Flush(ts);
}


static int TraceX(ATracer *as, ARMword addr, uint32 *data, int rv,
                   unsigned acc,
                   int packet_type)
{
  TracerState *ts = as->ts;
  Trace_Packet packet;
  if ((ts->prop & TRACE_RANGE) && (addr<ts->range_lo ||
                                   (addr>=ts->range_hi && ts->range_hi!=0)))
  {
    /* range test fails */
#ifdef VERBOSE_BUS
  printf("!Tracer_MemAccess - out of range!\n");
#endif

    return rv;
  }

  if (ts->sample_base) {
    if (ts->sample--)           /* not this one */
    {
      return rv;
    }
    ts->sample=ts->sample_base-1;
  }

  if (/* (ts->prop & TRACE_MEM) && */
      ((ts->prop & TRACE_WAITS) || (rv != 0)) &&
      ((ts->prop & TRACE_NONACC) || acc_ACCOUNT(acc)) &&
      ((ts->prop & TRACE_IDLE) || !ACCESS_IS_IDLE(acc)) &&
      /* We always care about prefetch-aborts! */
      ((ts->prop & TRACE_OPCODEFETCH) || !acc_OPC(acc) || rv < 0)
      ) 
  {
    packet.type=packet_type; /* E.g. Trace_MemAccess */
    packet.u.mem_access.acc=acc;
    packet.u.mem_access.addr=addr;
    packet.u.mem_access.predict=as->current;
/*    packet.u.mem_access.word1=(acc_MREQ(acc) ? *word : 0);  -- original */
    packet.u.mem_access.word1=(data != NULL) ? *data : 0;
    if (acc_WIDTH(acc) == BITS_64)
        packet.u.mem_access.word2=(data != NULL) ? data[1] : 0;
    packet.u.mem_access.rv=rv;

    Tracer_Dispatch(as,&packet);
    if (ts->prop & TRACE_UNBUFF)
        Tracer_Flush(ts);

    /* Use ts->advance to store predicted cycle information, then
     * delay into ts->current to check prediction against actual. */
    if (acc_ACCOUNT(acc) && rv != 0) {
      as->current=as->advance;
    }
  }
#ifdef VERBOSE_NOSEND
  else
  {
      printf("!Tracer_MemAccess - not sending packet!\n");
  }
#endif
  return rv;
}


/* Function called when RDI_LOG changes, so we can control logging
 * memory accesses */

/* <<<< Pass-thru functions */

static void TraceNextCycle(void *handle,ARMword addr,ARMul_acc acc)
{
  ATracer *as = (ATracer *)handle;
  /* TracerState *ts = as->ts; */

  as->child.x.pipe.next(as->child.handle,addr,acc); 

  /* NextCycle info before non-accounted accesses should
   *   - ideally not happen
   *   - be marked as non-accounted if it does happen
   * This enables the NextCycle info from the previous child
   * access to relate to the next child access regardless of
   * intervening non-accounted accesses.
   */
  if (acc_ACCOUNT(acc)) {
    /* store next cycle information */
    as->advance.addr = addr;
    as->advance.acc = acc;
  }
}

static void TraceNextDCycle(void *handle,ARMword addr, ARMword data, ARMul_acc acc)
{
  ATracer *as = (ATracer *)handle;
/*  TracerState *ts = (TracerState *)handle;*/

  as->child.x.pipe_arm9.dside_next(as->child.handle,addr,data,acc); 

/* NextCycle info before non-accounted accesses should
 *   - ideally not happen
 *   - be marked as non-accounted if it does happen
 * This enables the NextCycle info from the previous real
 * access to relate to the next real access regardless of
 * intervening non-accounted accesses.
 */
  if (acc_ACCOUNT(acc)) {
    /* store next cycle information */
    as->dside_advance.addr=addr;
    as->dside_advance.acc=acc;
  }
}

static void TraceNextICycle(void *handle,ARMword addr,ARMul_acc acc)
{
  ATracer *as = (ATracer *)handle;

  as->child.x.pipe_arm9.iside_next(as->child.handle,addr,acc); 

  /* NextCycle info before non-accounted accesses should
   *   - ideally not happen
   *   - be marked as non-accounted if it does happen
   * This enables the NextCycle info from the previous child
   * access to relate to the next child access regardless of
   * intervening non-accounted accesses.
   */
  if (acc_ACCOUNT(acc)) {
    /* store next cycle information */
    as->iside_advance.addr = addr;
    as->iside_advance.acc = acc;
  }
}


/* Pipelined Multi-Layer AHB memory interface functions */

static unsigned int TraceMultiLayerRegister(void *handle, tag_t hint)
{
    /* AHB Layer registration */
    ATracer *as = (ATracer *)handle;
    
    return as->child.x.pipe_multi_layer.register_layer(as->child.handle, hint);
}

static unsigned long TraceMultiLayerDeltaCycles(void *handle, unsigned int layer_id)
{
  ATracer *as = (ATracer *)handle;

  return (as->child.x.pipe_multi_layer.delta_cycles(as->child.handle, layer_id));
}

static void TraceBusMultiLayerNext(void *handle, unsigned int layer_id, ARMword address, ARMword *data, ARMul_acc acc)
{
  ATracer *as = (ATracer *)handle;

  as->child.x.pipe_multi_layer.next_access(as->child.handle, layer_id, address, data, acc); 

  /* NextCycle info before non-accounted accesses should
   *   - ideally not happen
   *   - be marked as non-accounted if it does happen
   * This enables the NextCycle info from the previous child
   * access to relate to the next child access regardless of
   * intervening non-accounted accesses.
   */
  if (acc_ACCOUNT(acc)) {
    /* store next cycle information */
    as->advance.addr = address;
    as->advance.acc = acc;
  }
}

static int TraceBusMultiLayerCurrent(void *handle, unsigned int layer_id, ARMword address, 
                                     ARMword *data, ARMul_acc acc)
{
    ATracer *as = (ATracer *)handle;
    int err = as->child.x.pipe_multi_layer.current_access(as->child.handle, layer_id, address, data, acc);

    TraceX(as, address, data, err, acc, as->as_TraceType);
    return err;
}


static unsigned long TraceDeltaCycles(void *handle)
{
  ATracer *as = (ATracer *)handle;

  return (as->child.x.pipe.delta_cycles(as->child.handle));
}

static void TraceCoreException(void *handle,ARMword address,
                               ARMword penc)
{
    ATracer *as = (ATracer *)handle;
    as->child.x.arm8.core_exception(as->child.handle,address,penc);
}

static unsigned int TraceDataCacheBusy(void *handle)
{
    ATracer *as = (ATracer *)handle;
    return as->child.x.strongarm.data_cache_busy(as->child.handle);
}

static void TraceBusMemAccessHarvard(void *handle,
                     ARMword daddr,ARMword *dword, ARMul_acc dacc, int *drv,
                     ARMword iaddr,ARMword *iword, ARMul_acc iacc, int *irv)
{
  ATracer *as=(ATracer *)handle;
  TracerState *ts = as->ts;
  as->child.x.pipe_arm9.harvard_access(as->child.handle,
                                       daddr, dword, dacc, drv,
                                       iaddr, iword, iacc, irv); 

 if ((ts->prop & TRACE_WAITS) || (*irv && *drv)) { /* ARM9 waits for this! */

  as->current = as->dside_current;
  /* The checks for *drv may not have the desired effect? */
  if (*drv) { /* Don't bother with all those waits! */
      TraceX(as, daddr, dword, *drv, dacc, as->as_TraceType);
  }
  as->current = as->iside_current;
  if (*irv) { /* Don't trace all those waits! */
      TraceX(as, iaddr, iword, *irv, iacc, as->as_TraceType);
  }
 }

  if (!(ts->prop & TRACE_RANGE) || ((daddr>=ts->range_lo) && (daddr>=ts->range_hi))) {
    if (acc_ACCOUNT(dacc) && (*drv != 0)) {
      as->dside_current=as->dside_advance;  /* delay next cycle information by 1 cycle */
    }
  }

  if (!(ts->prop & TRACE_RANGE) || ((iaddr>=ts->range_lo) && (iaddr>=ts->range_hi))) {
    if (acc_ACCOUNT(i

⌨️ 快捷键说明

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