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

📄 sim-hw.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
字号:
/* Simulator hardware option handling.   Copyright (C) 1998 Free Software Foundation, Inc.   Contributed by Cygnus Support and Andrew Cagney.This file is part of GDB, the GNU debugger.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public License alongwith this program; if not, write to the Free Software Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#include "sim-main.h"#include "sim-assert.h"#include "sim-options.h"#include "sim-hw.h"#include "hw-tree.h"#include "hw-device.h"#include "hw-main.h"#include "hw-base.h"#ifdef HAVE_STRING_H#include <string.h>#else#ifdef HAVE_STRINGS_H#include <strings.h>#endif#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#include <ctype.h>#include <errno.h>struct sim_hw {  struct hw *tree;  int trace_p;  int info_p;  /* if called from a processor */  sim_cpu *cpu;  sim_cia cia;};struct hw *sim_hw_parse (struct sim_state *sd,	      const char *fmt,	      ...){  struct hw *current;  va_list ap;  va_start (ap, fmt);  current = hw_tree_vparse (STATE_HW (sd)->tree, fmt, ap);  va_end (ap);  return current;}struct printer {  struct sim_state *file;  void (*print) (struct sim_state *, const char *, va_list ap);};static voiddo_print (void *file, const char *fmt, ...){  struct printer *p = file;  va_list ap;  va_start (ap, fmt);  p->print (p->file, fmt, ap);  va_end (ap);}voidsim_hw_print (struct sim_state *sd,	      void (*print) (struct sim_state *, const char *, va_list ap)){  struct printer p;  p.file = sd;  p.print = print;  hw_tree_print (STATE_HW (sd)->tree, do_print, &p);}/* command line options. */enum {  OPTION_HW_INFO = OPTION_START,  OPTION_HW_TRACE,  OPTION_HW_DEVICE,  OPTION_HW_LIST,  OPTION_HW_FILE,};static DECLARE_OPTION_HANDLER (hw_option_handler);static const OPTION hw_options[] ={  { {"hw-info", no_argument, NULL, OPTION_HW_INFO },      '\0', NULL, "List configurable hw regions",      hw_option_handler },  { {"info-hw", no_argument, NULL, OPTION_HW_INFO },      '\0', NULL, NULL,      hw_option_handler },  { {"hw-trace", optional_argument, NULL, OPTION_HW_TRACE },      '\0', "on|off", "Trace all hardware devices",      hw_option_handler },  { {"trace-hw", optional_argument, NULL, OPTION_HW_TRACE },      '\0', NULL, NULL,      hw_option_handler },  { {"hw-device", required_argument, NULL, OPTION_HW_DEVICE },      '\0', "DEVICE", "Add the specified device",      hw_option_handler },  { {"hw-list", no_argument, NULL, OPTION_HW_LIST },      '\0', NULL, "List the device tree",      hw_option_handler },  { {"hw-file", required_argument, NULL, OPTION_HW_FILE },      '\0', "FILE", "Add the devices listed in the file",      hw_option_handler },  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }};/* Copied from ../ppc/psim.c:psim_merge_device_file() */static SIM_RCmerge_device_file (struct sim_state *sd,		   const char *file_name){  FILE *description;  struct hw *current = STATE_HW (sd)->tree;  int line_nr;  char device_path[1000];    /* try opening the file */  description = fopen (file_name, "r");  if (description == NULL)    {      perror (file_name);      return SIM_RC_FAIL;    }    line_nr = 0;  while (fgets (device_path, sizeof(device_path), description))    {      char *device;      /* check that a complete line was read */      if (strchr (device_path, '\n') == NULL)	{	  fclose (description);	  sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr);	  return SIM_RC_FAIL;	}      *strchr (device_path, '\n') = '\0';      line_nr++;      /* skip comments ("#" or ";") and blank lines lines */      for (device = device_path;	   *device != '\0' && isspace (*device);	   device++);      if (device[0] == '#'	  || device[0] == ';'	  || device[0] == '\0')	continue;      /* merge any appended lines */      while (device_path[strlen (device_path) - 1] == '\\')	{	  int curlen = strlen (device_path) - 1;	  /* zap the `\' at the end of the line */	  device_path[curlen] = '\0';	  /* append the next line */	  if (!fgets (device_path + curlen,		      sizeof (device_path) - curlen,		      description))	    {	      fclose (description);	      sim_io_eprintf (sd, "%s:%d: unexpected eof", file_name, line_nr);	      return SIM_RC_FAIL;	    }	  if (strchr(device_path, '\n') == NULL)	    {	      fclose(description);	      sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr);	      return SIM_RC_FAIL;	    }	  *strchr(device_path, '\n') = '\0';	  line_nr++;	}      /* parse this line */      current = hw_tree_parse (current, "%s", device);    }  fclose (description);  return SIM_RC_OK;}static SIM_RChw_option_handler (struct sim_state *sd, sim_cpu *cpu, int opt,		   char *arg, int is_command){  switch (opt)    {    case OPTION_HW_INFO:      {	/* delay info until after the tree is finished */	STATE_HW (sd)->info_p = 1;	return SIM_RC_OK;	break;      }    case OPTION_HW_TRACE:      {	if (arg == NULL)	  {	    STATE_HW (sd)->trace_p = 1;	  }	else if (strcmp (arg, "yes") == 0		 || strcmp (arg, "on") == 0)	  {	    STATE_HW (sd)->trace_p = 1;	  }	else if (strcmp (arg, "no") == 0		 || strcmp (arg, "off") == 0)	  {	    STATE_HW (sd)->trace_p = 0;	  }	else	  {	    sim_io_eprintf (sd, "Option --hw-trace ignored\n");	    /* set tracing on all devices */	    return SIM_RC_FAIL;	  }	/* FIXME: Not very nice - see also hw-base.c */	if (STATE_HW (sd)->trace_p)	  hw_tree_parse (STATE_HW (sd)->tree, "/global-trace? true");	return SIM_RC_OK;	break;      }    case OPTION_HW_DEVICE:      {	hw_tree_parse (STATE_HW (sd)->tree, arg);	return SIM_RC_OK;      }    case OPTION_HW_LIST:      {	sim_hw_print (sd, sim_io_vprintf);	return SIM_RC_OK;      }      case OPTION_HW_FILE:      {	return merge_device_file (sd, arg);      }    default:      sim_io_eprintf (sd, "Unknown hw option %d\n", opt);      return SIM_RC_FAIL;    }  return SIM_RC_FAIL;}/* "hw" module install handler.   This is called via sim_module_install to install the "hw" subsystem   into the simulator.  */static MODULE_INIT_FN sim_hw_init;static MODULE_UNINSTALL_FN sim_hw_uninstall;SIM_RCsim_hw_install (struct sim_state *sd){  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);  sim_add_option_table (sd, NULL, hw_options);  sim_module_add_uninstall_fn (sd, sim_hw_uninstall);  sim_module_add_init_fn (sd, sim_hw_init);  STATE_HW (sd) = ZALLOC (struct sim_hw);  STATE_HW (sd)->tree = hw_tree_create (sd, "core");  return SIM_RC_OK;}static SIM_RCsim_hw_init (struct sim_state *sd){  /* FIXME: anything needed? */  hw_tree_finish (STATE_HW (sd)->tree);  if (STATE_HW (sd)->info_p)    sim_hw_print (sd, sim_io_vprintf);  return SIM_RC_OK;}/* Uninstall the "hw" subsystem from the simulator.  */static voidsim_hw_uninstall (struct sim_state *sd){  /* hw_tree_delete (STATE_HW (sd)->tree); */  zfree (STATE_HW (sd));  STATE_HW (sd) = NULL;}/* Data transfers to/from the hardware device tree.  There are several   cases. *//* CPU: The simulation is running and the current CPU/CIA   initiates a data transfer. */void sim_cpu_hw_io_read_buffer (sim_cpu *cpu,			   sim_cia cia,			   struct hw *hw,			   void *dest,			   int space,			   unsigned_word addr,			   unsigned nr_bytes){  SIM_DESC sd = CPU_STATE (cpu);  STATE_HW (sd)->cpu = cpu;  STATE_HW (sd)->cia = cia;  if (hw_io_read_buffer (hw, dest, space, addr, nr_bytes) != nr_bytes)    sim_engine_abort (sd, cpu, cia, "broken CPU read");}void sim_cpu_hw_io_write_buffer (sim_cpu *cpu,			    sim_cia cia,			    struct hw *hw,			    const void *source,			    int space,			    unsigned_word addr,			    unsigned nr_bytes){  SIM_DESC sd = CPU_STATE (cpu);  STATE_HW (sd)->cpu = cpu;  STATE_HW (sd)->cia = cia;  if (hw_io_write_buffer (hw, source, space, addr, nr_bytes) != nr_bytes)    sim_engine_abort (sd, cpu, cia, "broken CPU write");}/* SYSTEM: A data transfer is being initiated by the system. */unsigned sim_hw_io_read_buffer (struct sim_state *sd,		       struct hw *hw,		       void *dest,		       int space,		       unsigned_word addr,		       unsigned nr_bytes){  STATE_HW (sd)->cpu = NULL;  return hw_io_read_buffer (hw, dest, space, addr, nr_bytes);}unsignedsim_hw_io_write_buffer (struct sim_state *sd,			struct hw *hw,			const void *source,			int space,			unsigned_word addr,			unsigned nr_bytes){  STATE_HW (sd)->cpu = NULL;  return hw_io_write_buffer (hw, source, space, addr, nr_bytes);}/* Abort the simulation specifying HW as the reason */voidhw_vabort (struct hw *me,	   const char *fmt,	   va_list ap){  const char *name;  char *msg;  /* find an identity */  if (me != NULL && hw_path (me) != NULL && hw_path (me) [0] != '\0')    name = hw_path (me);  else if (me != NULL && hw_name (me) != NULL && hw_name (me)[0] != '\0')    name = hw_name (me);  else if (me != NULL && hw_family (me) != NULL && hw_family (me)[0] != '\0')    name = hw_family (me);  else    name = "device";  /* construct an updated format string */  msg = alloca (strlen (name) + strlen (": ") + strlen (fmt) + 1);  strcpy (msg, name);  strcat (msg, ": ");  strcat (msg, fmt);  /* report the problem */  sim_engine_vabort (hw_system (me),		     STATE_HW (hw_system (me))->cpu,		     STATE_HW (hw_system (me))->cia,		     msg, ap);}voidhw_abort (struct hw *me,	  const char *fmt,	  ...){  va_list ap;  /* report the problem */  va_start (ap, fmt);  hw_vabort (me, fmt, ap);  va_end (ap);}voidsim_hw_abort (struct sim_state *sd,	      struct hw *me,	      const char *fmt,	      ...){  va_list ap;  va_start (ap, fmt);  if (me == NULL)    sim_engine_vabort (sd, NULL, NULL_CIA, fmt, ap);  else    hw_vabort (me, fmt, ap);  va_end (ap);}/* MISC routines to tie HW into the rest of the system */voidhw_halt (struct hw *me,	 int reason,	 int status){  struct sim_state *sd = hw_system (me);  struct sim_hw *sim = STATE_HW (sd);  sim_engine_halt (sd, sim->cpu, NULL, sim->cia, reason, status);}struct _sim_cpu *hw_system_cpu (struct hw *me){  return STATE_HW (hw_system (me))->cpu;}voidhw_trace (struct hw *me,	  const char *fmt,	  ...){  if (hw_trace_p (me)) /* to be sure, to be sure */    {      va_list ap;      va_start (ap, fmt);      sim_io_eprintf (hw_system (me), "%s: ", hw_path (me));      sim_io_evprintf (hw_system (me), fmt, ap);      sim_io_eprintf (hw_system (me), "\n");      va_end (ap);    }}/* Based on gdb-4.17/sim/ppc/main.c:sim_io_read_stdin() */intdo_hw_poll_read (struct hw *me,		 do_hw_poll_read_method *read,		 int sim_io_fd,		 void *buf,		 unsigned sizeof_buf){  int status = read (hw_system (me), sim_io_fd, buf, sizeof_buf);  if (status > 0)    return status;  else if (status == 0 && sizeof_buf == 0)    return 0;  else if (status == 0)    return HW_IO_EOF;  else /* status < 0 */    {#ifdef EAGAIN      if (STATE_CALLBACK (hw_system (me))->last_errno == EAGAIN)	return HW_IO_NOT_READY;      else	return HW_IO_EOF;#else      return HW_IO_EOF;#endif    }}

⌨️ 快捷键说明

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