예제 #1
0
struct hw *
hw_tree_vparse (struct hw *current,
		const char *fmt,
		va_list ap)
{
  char device_specifier[1024];
  name_specifier spec;

  /* format the path */
  vsprintf (device_specifier, fmt, ap);
  if (strlen (device_specifier) >= sizeof (device_specifier))
    hw_abort (NULL, "device_tree_add_deviced: buffer overflow\n");

  /* construct the tree down to the final struct hw */
  current = split_fill_path (current, device_specifier, &spec);

  /* is there an interrupt spec */
  if (spec.property == NULL
      && spec.value != NULL)
    {
      char *op = split_value (&spec);
      switch (op[0])
	{
	case '>':
	  {
	    char *my_port_name = split_value (&spec);
	    int my_port;
	    char *dest_port_name = split_value (&spec);
	    int dest_port;
	    name_specifier dest_spec;
	    char *dest_hw_name = split_value (&spec);
	    struct hw *dest;
	    /* find my name */
	    if (!hw_finished_p (current))
	      hw_finish (current);
	    my_port = hw_port_decode (current, my_port_name, output_port);
	    /* find the dest device and port */
	    dest = split_fill_path (current, dest_hw_name, &dest_spec);
	    if (!hw_finished_p (dest))
	      hw_finish (dest);
	    dest_port = hw_port_decode (dest, dest_port_name,
					input_port);
	    /* connect the two */
	    hw_port_attach (current,
			    my_port,
			    dest,
			    dest_port,
			    permenant_object);
	    break;
	  }
	default:
	  hw_abort (current, "unreconised interrupt spec %s\n", spec.value);
	  break;
	}
    }

  /* is there a property */
  if (spec.property != NULL)
    {
      if (strcmp (spec.value, "true") == 0)
	hw_add_boolean_property (current, spec.property, 1);
      else if (strcmp (spec.value, "false") == 0)
	hw_add_boolean_property (current, spec.property, 0);
      else
	{
	  const struct hw_property *property;
	  switch (spec.value[0])
	    {
#if NOT_YET
	    case '*':
	      {
		parse_ihandle_property (current, spec.property, spec.value + 1);
		break;
	      }
#endif
	    case '[':
	      {
		unsigned8 words[1024];
		char *curr = spec.value + 1;
		int nr_words = 0;
		while (1)
		  {
		    char *next;
		    words[nr_words] = H2BE_1 (strtoul (curr, &next, 0));
		    if (curr == next)
		      break;
		    curr = next;
		    nr_words += 1;
		  }
		hw_add_array_property (current, spec.property,
				       words, sizeof(words[0]) * nr_words);
		break;
	      }
	    case '"':
	      {
		parse_string_property (current, spec.property, spec.value);
		break;
	      }
	    case '!':
	      {
		spec.value++;
		property = hw_tree_find_property (current, spec.value);
		if (property == NULL)
		  hw_abort (current, "property %s not found\n", spec.value);
		hw_add_duplicate_property (current,
					   spec.property,
					   property);
		break;
	      }
	    default:
	      {
		if (strcmp (spec.property, "reg") == 0
		    || strcmp (spec.property, "assigned-addresses") == 0
		    || strcmp (spec.property, "alternate-reg") == 0)
		  {
		    parse_reg_property (current, spec.property, spec.value);
		  }
		else if (strcmp (spec.property, "ranges") == 0)
		  {
		    parse_ranges_property (current, spec.property, spec.value);
		  }
		else if (isdigit(spec.value[0])
			 || (spec.value[0] == '-' && isdigit(spec.value[1]))
			 || (spec.value[0] == '+' && isdigit(spec.value[1])))
		  {
		    parse_integer_property(current, spec.property, spec.value);
		  }
		else
		  parse_string_property(current, spec.property, spec.value);
		break;
	      }
	    }
	}
    }
  return current;
}
예제 #2
0
static int
sim_hw_configure (SIM_DESC sd)
{
  const struct bfd_arch_info *arch;
  struct hw *device_tree;
  sim_cpu *cpu;
  
  arch = STATE_ARCHITECTURE (sd);
  if (arch == 0)
    return 0;

  cpu = STATE_CPU (sd, 0);
  cpu->cpu_configured_arch = arch;
  device_tree = sim_hw_parse (sd, "/");
  if (arch->arch == bfd_arch_m68hc11)
    {
      cpu->cpu_interpretor = cpu_interp_m6811;
      if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
	{
	  /* Allocate core managed memory */

	  /* the monitor  */
	  sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
			   /* MONITOR_BASE, MONITOR_SIZE */
			   0x8000, M6811_RAM_LEVEL, 0x8000);
	  sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
			   M6811_RAM_LEVEL);
	  sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
          if (cpu->bank_start < cpu->bank_end)
            {
              sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
                               cpu->bank_virtual, M6811_RAM_LEVEL);
              sim_hw_parse (sd, "/m68hc11/use_bank 1");
            }
	}
      if (cpu->cpu_start_mode)
        {
          sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
        }
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
	  sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
	}
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
	{
	  /* M68hc11 Timer configuration. */
	  sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
          sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
	}

      /* Create the SPI device.  */
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
	}
      if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
	{
	  /* M68hc11 persistent ram configuration. */
	  sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
	  sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
	  sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
	  /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
	}
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
	  sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
	}
      sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
      sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
      sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
      sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
      cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
    }
  else
    {
      cpu->cpu_interpretor = cpu_interp_m6812;
      if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
	{
	  /* Allocate core external memory.  */
	  sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
			   0x8000, M6811_RAM_LEVEL, 0x8000);
	  sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
			   M6811_RAM_LEVEL);
          if (cpu->bank_start < cpu->bank_end)
            {
              sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
                               cpu->bank_virtual, M6811_RAM_LEVEL);
              sim_hw_parse (sd, "/m68hc12/use_bank 1");
            }
	  sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
	}

      if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
	{
	  sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
	  sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
	}
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
	{
	  /* M68hc11 Timer configuration. */
	  sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
          sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
	}

      /* Create the SPI device.  */
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
	}
      if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
	{
	  /* M68hc11 persistent ram configuration. */
	  sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
	  sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
	  sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
	}
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
	{
	  sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
	  sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
	}

      sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
      sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
      sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
      sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
      cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
    }
  return 1;
}
예제 #3
0
static unsigned
hw_pal_io_read_buffer (struct hw *me,
		       void *dest,
		       int space,
		       unsigned_word addr,
		       unsigned nr_bytes)
{
  hw_pal_device *hw_pal = (hw_pal_device *) hw_data (me);
  unsigned_1 *byte = (unsigned_1 *) dest;
  memset (dest, 0, nr_bytes);
  switch (addr & hw_pal_address_mask)
    {

    case hw_pal_cpu_nr_register:
#ifdef CPU_INDEX
      *byte = CPU_INDEX (hw_system_cpu (me));
#else
      *byte = 0;
#endif
      HW_TRACE ((me, "read - cpu-nr %d\n", *byte));
      break;

    case hw_pal_nr_cpu_register:
      if (hw_tree_find_property (me, "/openprom/options/smp") == NULL)
	{
	  *byte = 1;
	  HW_TRACE ((me, "read - nr-cpu %d (not defined)\n", *byte));
	}
      else
	{
	  *byte = hw_tree_find_integer_property (me, "/openprom/options/smp");
	  HW_TRACE ((me, "read - nr-cpu %d\n", *byte));
	}
      break;

    case hw_pal_read_fifo:
      *byte = hw_pal->input.buffer;
      HW_TRACE ((me, "read - input-fifo %d\n", *byte));
      break;

    case hw_pal_read_status:
      scan_hw_pal (me);
      *byte = hw_pal->input.status;
      HW_TRACE ((me, "read - input-status %d\n", *byte));
      break;

    case hw_pal_write_fifo:
      *byte = hw_pal->output.buffer;
      HW_TRACE ((me, "read - output-fifo %d\n", *byte));
      break;

    case hw_pal_write_status:
      *byte = hw_pal->output.status;
      HW_TRACE ((me, "read - output-status %d\n", *byte));
      break;

    case hw_pal_countdown:
      do_counter_read (me, hw_pal, "countdown",
		       &hw_pal->countdown, dest, nr_bytes);
      break;

    case hw_pal_countdown_value:
      do_counter_value (me, hw_pal, "countdown-value",
			&hw_pal->countdown, dest, nr_bytes);
      break;

    case hw_pal_timer:
      do_counter_read (me, hw_pal, "timer",
		       &hw_pal->timer, dest, nr_bytes);
      break;

    case hw_pal_timer_value:
      do_counter_value (me, hw_pal, "timer-value",
			&hw_pal->timer, dest, nr_bytes);
      break;

    default:
      HW_TRACE ((me, "read - ???\n"));
      break;

    }
  return nr_bytes;
}