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

📄 interp.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
			      unsigned long *phys,			      void *regcache,			      unsigned long (*imap_register) (void *regcache,							      int reg_nr)){  short map;  int regno;  int sp;  int segno;  last_from = "logical-insn";  if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS))    {      /* Logical address outside of IMAP segments, not supported */      return 0;    }  regno = (offset / IMAP_BLOCK_SIZE);  offset = (offset % IMAP_BLOCK_SIZE);  if (offset + nr_bytes > IMAP_BLOCK_SIZE)    {      /* Don't cross a BLOCK boundary */      nr_bytes = IMAP_BLOCK_SIZE - offset;    }  map = imap_register (regcache, regno);  sp = (map & 0x3000) >> 12;  segno = (map & 0x007f);  switch (sp)    {    case 0: /* 00: unified memory */      *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset;      last_to = "unified";      break;    case 1: /* 01: instruction memory */      *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;      last_to = "chip-insn";      break;    case 2: /*10*/      /* Reserved. */      return 0;    case 3: /* 11: for testing  - instruction memory */      offset = (offset % 0x800);      *phys = SIM_D10V_MEMORY_INSN + offset;      if (offset + nr_bytes > 0x800)	/* don't cross VM boundary */	nr_bytes = 0x800 - offset;      last_to = "test-insn";      break;    }  return nr_bytes;}unsigned longsim_d10v_translate_addr (unsigned long memaddr,			 int nr_bytes,			 unsigned long *targ_addr,			 void *regcache,			 unsigned long (*dmap_register) (void *regcache,							 int reg_nr),			 unsigned long (*imap_register) (void *regcache,							 int reg_nr)){  unsigned long phys;  unsigned long seg;  unsigned long off;  last_from = "unknown";  last_to = "unknown";  seg = (memaddr >> 24);  off = (memaddr & 0xffffffL);  /* However, if we've asked to use the previous generation of segment     mapping, rearrange the segments as follows. */  if (old_segment_mapping)    {      switch (seg)	{	case 0x00: /* DMAP translated memory */	  seg = 0x10;	  break;	case 0x01: /* IMAP translated memory */	  seg = 0x11;	  break;	case 0x10: /* On-chip data memory */	  seg = 0x02;	  break;	case 0x11: /* On-chip insn memory */	  seg = 0x01;	  break;	case 0x12: /* Unified memory */	  seg = 0x00;	  break;	}    }  switch (seg)    {    case 0x00:			/* Physical unified memory */      last_from = "phys-unified";      last_to = "unified";      phys = SIM_D10V_MEMORY_UNIFIED + off;      if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)	nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);      break;    case 0x01:			/* Physical instruction memory */      last_from = "phys-insn";      last_to = "chip-insn";      phys = SIM_D10V_MEMORY_INSN + off;      if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)	nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);      break;    case 0x02:			/* Physical data memory segment */      last_from = "phys-data";      last_to = "chip-data";      phys = SIM_D10V_MEMORY_DATA + off;      if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)	nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);      break;    case 0x10:			/* in logical data address segment */      nr_bytes = sim_d10v_translate_dmap_addr (off, nr_bytes, &phys, regcache,					       dmap_register);      break;    case 0x11:			/* in logical instruction address segment */      nr_bytes = sim_d10v_translate_imap_addr (off, nr_bytes, &phys, regcache,					       imap_register);      break;    default:      return 0;    }  *targ_addr = phys;  return nr_bytes;}/* Return a pointer into the raw buffer designated by phys_addr.  It   is assumed that the client has already ensured that the access   isn't going to cross a segment boundary. */uint8 *map_memory (unsigned phys_addr){  uint8 **memory;  uint8 *raw;  unsigned offset;  int segment = ((phys_addr >> 24) & 0xff);    switch (segment)    {          case 0x00: /* Unified memory */      {	memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];	last_segname = "umem";	break;      }        case 0x01: /* On-chip insn memory */      {	memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];	last_segname = "imem";	break;      }        case 0x02: /* On-chip data memory */      {	if ((phys_addr & 0xff00) == 0xff00)	  {	    phys_addr = (phys_addr & 0xffff);	    if (phys_addr == DMAP2_SHADDOW)	      {		phys_addr = DMAP2_OFFSET;		last_segname = "dmap";	      }	    else	      last_segname = "reg";	  }	else	  last_segname = "dmem";	memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];	break;      }        default:      /* OOPS! */      last_segname = "scrap";      return State.mem.fault;    }    if (*memory == NULL)    {      *memory = calloc (1, SEGMENT_SIZE);      if (*memory == NULL)	{	  (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n");	  return State.mem.fault;	}    }    offset = (phys_addr % SEGMENT_SIZE);  raw = *memory + offset;  return raw;}  /* Transfer data to/from simulated memory.  Since a bug in either the   simulated program or in gdb or the simulator itself may cause a   bogus address to be passed in, we need to do some sanity checking   on addresses to make sure they are within bounds.  When an address   fails the bounds check, treat it as a zero length read/write rather   than aborting the entire run. */static intxfer_mem (SIM_ADDR virt,	  unsigned char *buffer,	  int size,	  int write_p){  uint8 *memory;  unsigned long phys;  int phys_size;  phys_size = sim_d10v_translate_addr (virt, size, &phys, NULL,				       dmap_register, imap_register);  if (phys_size == 0)    return 0;  memory = map_memory (phys);#ifdef DEBUG  if ((d10v_debug & DEBUG_INSTRUCTION) != 0)    {      (*d10v_callback->printf_filtered)	(d10v_callback,	 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",	     (write_p ? "write" : "read"),	 phys_size, virt, last_from,	 phys, last_to,	 (long) memory, last_segname);    }#endif  if (write_p)    {      memcpy (memory, buffer, phys_size);    }  else    {      memcpy (buffer, memory, phys_size);    }    return phys_size;}intsim_write (sd, addr, buffer, size)     SIM_DESC sd;     SIM_ADDR addr;     unsigned char *buffer;     int size;{  /* FIXME: this should be performing a virtual transfer */  return xfer_mem( addr, buffer, size, 1);}intsim_read (sd, addr, buffer, size)     SIM_DESC sd;     SIM_ADDR addr;     unsigned char *buffer;     int size;{  /* FIXME: this should be performing a virtual transfer */  return xfer_mem( addr, buffer, size, 0);}SIM_DESCsim_open (kind, callback, abfd, argv)     SIM_OPEN_KIND kind;     host_callback *callback;     struct bfd *abfd;     char **argv;{  struct simops *s;  struct hash_entry *h;  static int init_p = 0;  char **p;  sim_kind = kind;  d10v_callback = callback;  myname = argv[0];  old_segment_mapping = 0;  /* NOTE: This argument parsing is only effective when this function     is called by GDB. Standalone argument parsing is handled by     sim/common/run.c. */  for (p = argv + 1; *p; ++p)    {      if (strcmp (*p, "-oldseg") == 0)	old_segment_mapping = 1;#ifdef DEBUG      else if (strcmp (*p, "-t") == 0)	d10v_debug = DEBUG;      else if (strncmp (*p, "-t", 2) == 0)	d10v_debug = atoi (*p + 2);#endif      else	(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);    }    /* put all the opcodes in the hash table */  if (!init_p++)    {      for (s = Simops; s->func; s++)	{	  h = &hash_table[hash(s->opcode,s->format)];      	  /* go to the last entry in the chain */	  while (h->next)	    h = h->next;	  if (h->ops)	    {	      h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));	      if (!h->next)		perror ("malloc failure");	      h = h->next;	    }	  h->ops = s;	  h->mask = s->mask;	  h->opcode = s->opcode;	  h->size = s->is_long;	}    }  /* reset the processor state */  if (!State.mem.data[0])    sim_size (1);  sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);  /* Fudge our descriptor.  */  return (SIM_DESC) 1;}voidsim_close (sd, quitting)     SIM_DESC sd;     int quitting;{  if (prog_bfd != NULL && prog_bfd_was_opened_p)    {      bfd_close (prog_bfd);      prog_bfd = NULL;      prog_bfd_was_opened_p = 0;    }}voidsim_set_profile (n)     int n;{  (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);}voidsim_set_profile_size (n)     int n;{  (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);}uint8 *dmem_addr (uint16 offset){  unsigned long phys;  uint8 *mem;  int phys_size;  /* Note: DMEM address range is 0..0x10000. Calling code can compute     things like ``0xfffe + 0x0e60 == 0x10e5d''.  Since offset's type     is uint16 this is modulo'ed onto 0x0e5d. */  phys_size = sim_d10v_translate_dmap_addr (offset, 1, &phys, NULL,					    dmap_register);  if (phys_size == 0)    {      mem = State.mem.fault;    }  else    mem = map_memory (phys);#ifdef DEBUG  if ((d10v_debug & DEBUG_MEMORY))    {      (*d10v_callback->printf_filtered)	(d10v_callback,	 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",	 offset, last_from,	 phys, phys_size, last_to,	 (long) mem, last_segname);    }#endif  return mem;}uint8 *imem_addr (uint32 offset){  unsigned long phys;  uint8 *mem;  int phys_size = sim_d10v_translate_imap_addr (offset, 1, &phys, NULL,						imap_register);  if (phys_size == 0)    {      return State.mem.fault;    }  mem = map_memory (phys); #ifdef DEBUG  if ((d10v_debug & DEBUG_MEMORY))    {      (*d10v_callback->printf_filtered)	(d10v_callback,	 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",	 offset, last_from,	 phys, phys_size, last_to,	 (long) mem, last_segname);    }#endif  return mem;}static int stop_simulator = 0;intsim_stop (sd)     SIM_DESC sd;{  stop_simulator = 1;  return 1;}/* Run (or resume) the program.  */voidsim_resume (sd, step, siggnal)     SIM_DESC sd;     int step, siggnal;{  uint32 inst;  uint8 *iaddr;/*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d)  PC=0x%x\n",step,siggnal,PC); */  State.exception = 0;  if (step)    sim_stop (sd);  switch (siggnal)    {    case 0:      break;#ifdef SIGBUS    case SIGBUS:#endif    case SIGSEGV:      SET_BPC (PC);      SET_BPSW (PSW);      SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));      JMP (AE_VECTOR_START);      SLOT_FLUSH ();      break;    case SIGILL:      SET_BPC (PC);      SET_BPSW (PSW);      SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));      JMP (RIE_VECTOR_START);      SLOT_FLUSH ();      break;    default:      /* just ignore it */      break;    }  do    {      iaddr = imem_addr ((uint32)PC << 2);      if (iaddr == State.mem.fault) 	{ 	  State.exception = SIGBUS; 	  break; 	}       inst = get_longword( iaddr );        State.pc_changed = 0;      ins_type_counters[ (int)INS_CYCLES ]++;      

⌨️ 快捷键说明

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