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

📄 armsym.c

📁 嵌入式的开发的一个开源仿真程序源码,其是开源的,很不错的奉献给大家
💻 C
📖 第 1 页 / 共 2 页
字号:
  if ((state->energy.enable_func_energy)
      && !(strcmp (state->energy.func_energy, fnp->func_symbol->name)))
    {
      printf ("energy_report %s %f\n", fnp->func_symbol->name, fenergy);
    }

  /* <tktan> BUG200104101936 */
  if (state->energy.energy_prof)
    {
      fnp->func_symbol->total_energy += fenergy;
      fnp->func_symbol->total_cycle += fcycle;
      (fnp->func_symbol->instances)++;
    }
  //printf("Destroy child,name %s \n",fnp->func_symbol->name);
  tsp->level = level - 1;
  return;
}


/************************************************
  Function to check the different kind of branch 
************************************************/
void
ARMul_CallCheck (ARMul_State * state, ARMword cur_pc, ARMword to_pc,
		 ARMword instr)
{
  FUNC_NODE *child_node;
  TASK_STACK *tsp;
  SYM_FUNC *symp;
  int i, bt, level;
  ARMword new_task_id, fp_value;

  tsp = (TASK_STACK *) state->energy.cur_task;
  level = tsp->level;
  fp_value = state->Reg[11];	// BUG200311301153
#if 0
  if (debug != tsp->task_id || !debug)
    {
      printf ("cur_task is changed! %x \n", tsp->task_id);
      debug = tsp->task_id;
    }
#endif

  /* <tktan> BUG200105311233 */
  if (level >= MAX_LEVEL)
    {
      printf ("ARMul_CallCheck failed\n");
      printf ("level %d \n", level);
      //exit(-1);
    }
  // First check if it is normal return
  if (to_pc == (tsp->func_stack[level].ret_addr + 4))
    {
      if (state->energy.func_display & state->energy.func_disp_start)
	{			/* <tktan> BUG200104191428 */
	  //if(1){
	  printf ("[%x:%d:%x] Function return %s (%x)--> %s (%x)\n",
		  tsp->task_id, level, fp_value,
		  tsp->func_stack[level].func_symbol->name, cur_pc,
		  tsp->func_stack[level - 1].func_symbol->name, to_pc);
	}

      /* <tktan> BUG200104101736 */
      ARMul_DestroyChild (state);

      return;
    }
  // Check if it is a trap return
  // a trap return is one that jump to a saved interrupted address, saved
  // in .ret_addr
  bt = 0;
  while ((level - bt >= 0) && (bt <= 3))
    {
      if (to_pc == tsp->func_stack[level - bt].ret_addr)
	{
	  if (state->energy.func_display & state->energy.func_disp_start)
	    {			/* <tktan> BUG200104191428 */
	      printf ("[%x:%d:%x] Trap Return -> %s\n", tsp->task_id, level,
		      fp_value,
		      tsp->func_stack[level - bt - 1].func_symbol->name);
	    }

	  /* <tktan> BUG200104101736 */
	  for (i = 0; i <= bt; i++)
	    {
	      ARMul_DestroyChild (state);
	    }

	  return;
	}
      bt++;
    }

  // BUG200311212039
  // check if it is a recursive call, or I was missing some returns through
  // abnormal jumps
  bt = 0;
  while ((level - bt >= 0) && (bt <= 2))
    {
      if (to_pc == tsp->func_stack[level - bt].func_start_addr)
	{
	  if (state->energy.func_display & state->energy.func_disp_start)
	    {			/* <tktan> BUG200104191428 */
	      printf ("[%x:%d:%x] Function %s ended\n", tsp->task_id, level,
		      fp_value,
		      tsp->func_stack[level - bt].func_symbol->name);
	    }

	  /* <tktan> BUG200104101736 */
	  for (i = 0; i <= bt; i++)
	    {
	      ARMul_DestroyChild (state);
	    }

	}
      bt++;
    }
  tsp = (TASK_STACK *) state->energy.cur_task;
  level = tsp->level;

  // check if it is a trap
  //if (!(to_pc & 0xffffffe0) && (state->Reg[14] == (cur_pc+4))) { // check for pc from 0x0 - 0x1f
  // BUG200311302126: Reg[14]_abt is cur_pc+8 for DataAbort,
  // but cur_pc+4 for other exception. So, better not check it 
  if (!(to_pc & 0xffffffe0))
    {				// check for pc from 0x0 - 0x1f
      child_node = ARMul_CreateChild (state);	/* <tktan> BUG200104101736 */
      child_node->ret_addr = cur_pc;
      child_node->func_start_addr = to_pc;
      child_node->func_symbol = &trap_sym;

      if (state->energy.func_display & state->energy.func_disp_start)
	{			/* <tktan> BUG200104191428 */
	  printf ("[%x:%d:%x] Function %s(%x) --> Trap %x\n", tsp->task_id,
		  level, fp_value, tsp->func_stack[level].func_symbol->name,
		  cur_pc, to_pc);
	}
      return;
    }

  // Check if it is a function call

  if ((state->Reg[14] == (cur_pc + 4)) ||	/* <tktan> BUG200105172030 */
      (BITS (20, 27) & 0xf0) == 0xb0)
    {				/* <tktan> BUG200104012116 */

      symp = ARMul_GetSym (to_pc);
      if (symp)
	{
	  // it is an entry into a function
	  child_node = ARMul_CreateChild (state);	/* <tktan> BUG2001040101736 */
	  child_node->ret_addr = cur_pc;
	  child_node->func_start_addr = to_pc;
	  child_node->func_symbol = symp;


	  /* <tktan> BUG200105211055 : perform task switch */
	  if (!strcmp (symp->name, "__switch_to"))
	    {			// BUG200204021340
	      ARMul_TaskSwitch (state);
	    }
	  if (!strcmp (symp->name, "copy_thread"))
	    {
	      new_task_id = ARMul_TaskCreate (state);
	    }
	}

    }				/* <tktan> BUG200104012116 */
  // Just a normal branch, maybe
  return;
}

/* <tktan> BUG200105211055 : perform task switch */
void
ARMul_TaskSwitch (ARMul_State * state)
{
  TASK_STACK *ctsp, *oldtsp, *newtsp;
  //ARMword to_thread_id;
  ARMword to_task_id;
  int done = 0;

  //to_thread_id = state->Reg[2] ; // r1, the to_task task structure
  to_task_id = state->Reg[7];
  oldtsp = (TASK_STACK *) state->energy.cur_task;
  //printf("cur_task id %x \n",state->Reg[0]);
  oldtsp->task_id = state->Reg[0];	/* <tktan> BUG200106051701 */
  //printf("Task ThreadInfo Switch from %x to %x\n", oldtsp->thread_id, to_thread_id);
  //printf("task switch from %x to %x \n",oldtsp->task_id,to_task_id);
  ctsp = oldtsp->next;
  while (!done && (ctsp != oldtsp))
    {
      if (ctsp->task_id == to_task_id)
	{
	  done = 1;
	  newtsp = ctsp;
	}
//      printf("ctsp taskid=%x,next task_id=%x \n",ctsp->task_id,ctsp->next->task_id);
      ctsp = ctsp->next;
    }

  if (done)
    state->energy.cur_task = (void *) newtsp;
  else
    {
      printf ("Error : Can not find task stack\n");
      //print_allTask(state);
      exit (-1);
    }
}
void
print_allTask (ARMul_State * state)
{
  TASK_STACK *ctsp, *oldtsp, *newtsp;
  ARMword to_task_id;

  oldtsp = (TASK_STACK *) state->energy.cur_task;
  ctsp = oldtsp;
#if 0
  printf ("Begin to print all task...\n");
  do
    {
      printf ("ctsp taskid=%x,next task_id=%x \n", ctsp->task_id,
	      ctsp->next->task_id);
      ctsp = ctsp->next;
    }
  while (ctsp != oldtsp);
  printf ("End to print....\n");
#endif
}

/* <tktan> BUG200105211055 : create new task stack */
ARMword
ARMul_TaskCreate (ARMul_State * state)
{
  TASK_STACK *oldtsp, *newtsp, *oldnext;
  ARMword to_task_id;
  int i;

  to_task_id = state->Reg[3];	// r3, the to_task task structure
  if (to_task_id == 0x00000000)
    {				// BUG200204081717
      to_task_id = state->Reg[5];	// r5 store the to_task task structure
    }

  oldtsp = (TASK_STACK *) state->energy.cur_task;

  newtsp = malloc (sizeof (TASK_STACK));
  memcpy (newtsp, oldtsp, sizeof (TASK_STACK));
  newtsp->task_id = to_task_id;
  newtsp->level -= 2;		// point to the SWI level

  /* <tktan> BUG200105222137 */
  newtsp->total_cycle = 0;
  // newtsp->total_energy = 0.0; BUG200106142205, possible problem
  newtsp->total_energy = 0;
  for (i = 0; i <= newtsp->level; i++)
    {
      newtsp->func_stack[i].tcycle = 0;
      newtsp->func_stack[i].tenergy = 0;
    }

  /* put newtsp after oldtsp */
  oldnext = oldtsp->next;
  oldtsp->next = newtsp;
  newtsp->next = oldnext;
  //printf("Create a new task,task_id=%x \n",to_task_id);
//print_allTask(state);
  return (to_task_id);
}

/********************************************
 *  Function to report energy tree
 *******************************************/
void
ARMul_ReportEnergy (ARMul_State * state, FILE * pf)
{
  int i, j;
  ENTRY entry, *ep;
  char text[9];
  SYM_FUNC *symp;
  asymbol *symptr;
  ARMword address;
  TASK_STACK *ctsp, *oldtsp;
  float energy;

  ARMul_Consolidate (state);	// <tktan> BUG200105222137 

  for (i = 0; i < number_of_symbols; i++)
    {
      symptr = symbol_table[i];
      address = symptr->value + symptr->section->vma;	// adjust for section address

      if (((i < kernel_number) && (symbol_table[i]->flags == 0x01)) ||	// <tktan> BUG200105172154, BUG200106022219
	  ((i < kernel_number) && (symbol_table[i]->flags == 0x02)) ||	// <tktan> BUG200204051654, BUG200311211406
	  (symbol_table[i]->flags & 0x10))
	{			// Is a function symbol

	  // ***********************************************************
	  // This is converting the function symbol value to char string
	  // and use it as a key in the GNU hash table
	  // ********************************************************
	  entry.key = text;
	  for (j = 0; j < 8; j++)
	    {
	      entry.key[j] = itoa_tab[(address >> (j << 2)) & 0xf];
	    }
	  entry.key[8] = 0;

	  ep = hsearch (entry, FIND);
	  if (ep != 0)
	    {
	      symp = (SYM_FUNC *) ep->data;
	      /*modified by ksh for evaluate the usrappl program only */
	      /*
	         if(strncmp(symp->name,"usrappl",7) != 0){
	         continue;
	         }
	       */
	      if (symp->instances > 0)
		{		// only show if executed
		  energy = symp->total_energy;
		  fprintf (pf, "%s %d %lld %f\n", symp->name, symp->instances,
			   symp->total_cycle, energy);
		}
	    }
	}
    }

  /* <tktan> BUG200105222137 : print out task energy */
  oldtsp = (TASK_STACK *) state->energy.cur_task;
  ctsp = oldtsp;
  do
    {
      energy = ctsp->total_energy;
      fprintf (pf, "Task[%x] %lld %f\n", ctsp->task_id, ctsp->total_cycle,
	       energy);
      ctsp = ctsp->next;
    }
  while (ctsp != oldtsp);
}

/* <tktan> BUG200105222137 : consolidate unfinished function energy */
void
ARMul_Consolidate (ARMul_State * state)
{
  long long fenergy;		// <tktan> BUG200106142205
  long long fcycle;		// <tktan> BUG200106142205
  FUNC_NODE *fnp;
  TASK_STACK *ctsp, *oldtsp;
  int i;
  double energy;

  /* <tktan> BUG200105222137 : report energy for tasks */
  /* <tktan> BUG200106041235 : use do instead of while */
  oldtsp = (TASK_STACK *) state->energy.cur_task;
  ctsp = oldtsp;
  do
    {
      for (i = ctsp->level; i >= 0; i--)
	{
	  fnp = &(ctsp->func_stack[i]);
	  fenergy = ctsp->total_energy - fnp->tenergy;
	  fcycle = ctsp->total_cycle - fnp->tcycle;

	  /* copied from <tktan> BUG200105181702 */
	  if ((state->energy.enable_func_energy)
	      &&
	      !(strcmp (state->energy.func_energy, fnp->func_symbol->name)))
	    {
	      //energy = I2ENERGY(fenergy);
	      //fprintf(pf,"energy_report %s %f\n", fnp->func_symbol->name, energy);
	    }

	  /* copied from <tktan> BUG200104101936 */
	  fnp->func_symbol->total_energy += fenergy;
	  fnp->func_symbol->total_cycle += fcycle;
	  (fnp->func_symbol->instances)++;
	}
      ctsp = ctsp->next;
    }
  while (ctsp != oldtsp);
}

⌨️ 快捷键说明

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