Example #1
0
const char *
hw_tree_find_string_property (struct hw *root,
			      const char *path_to_property)
{
  name_specifier spec;
  if (!split_property_specifier (root, path_to_property, &spec))
    hw_abort (root, "Invalid property path %s", path_to_property);
  root = split_find_device (root, &spec);
  if (spec.name != NULL)
    hw_abort (root, "device \"%s\" not found (property \"%s\")",
	      spec.name, path_to_property);
  return hw_find_string_property (root, spec.property);
}
static void
attach_m68hc11eepr_regs (struct hw *me,
                         struct m68hc11eepr *controller)
{
  unsigned_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain one addr/size entry");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space,
				     &attach_address,
				     me);
  hw_unit_size_to_attach_size (hw_parent (me),
			       &reg.size,
			       &attach_size, me);

  /* Attach the two IO registers that control the EEPROM.
     The EEPROM is only attached at reset time because it may
     be enabled/disabled by the EEON bit in the CONFIG register.  */
  hw_attach_address (hw_parent (me), M6811_IO_LEVEL,
                     io_map, M6811_PPROG, 1, me);
  hw_attach_address (hw_parent (me), M6811_IO_LEVEL,
                     io_map, M6811_CONFIG, 1, me);

  if (hw_find_property (me, "file") == NULL)
    controller->file_name = "m6811.eeprom";
  else
    controller->file_name = hw_find_string_property (me, "file");
  
  controller->attach_space = attach_space;
  controller->base_address = attach_address;
  controller->eeprom = (char*) hw_malloc (me, attach_size + 1);
  controller->eeprom_min_cycles = 10000;
  controller->size = attach_size + 1;
  controller->mapped = 0;
  
  m6811eepr_memory_rw (controller, O_RDONLY);
}
static void
attach_tx3904sio_regs (struct hw *me,
		      struct tx3904sio *controller)
{
  unsigned_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain one addr/size entry");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space,
				     &attach_address,
				     me);
  hw_unit_size_to_attach_size (hw_parent (me),
			       &reg.size,
			       &attach_size, me);

  hw_attach_address (hw_parent (me), 0,
		     attach_space, attach_address, attach_size,
		     me);

  if(hw_find_property(me, "backend") != NULL)
    {
      const char* value = hw_find_string_property(me, "backend");
      if(! strcmp(value, "tcp"))
	controller->backend = sio_tcp;
      else if(! strcmp(value, "stdio"))
	controller->backend = sio_stdio;
      else
	hw_abort(me, "illegal value for backend parameter `%s': use tcp or stdio", value);
    }

  controller->base_address = attach_address;
}
static void
attach_m68hc11sio_regs (struct hw *me,
                        struct m68hc11sio *controller)
{
  hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map,
                     M6811_SCI_FIRST_REG,
                     M6811_SCI_LAST_REG - M6811_SCI_FIRST_REG + 1,
		     me);

  if (hw_find_property(me, "backend") != NULL)
    {
      const char *value = hw_find_string_property(me, "backend");
      if(! strcmp(value, "tcp"))
	controller->backend = sio_tcp;
      else if(! strcmp(value, "stdio"))
	controller->backend = sio_stdio;
      else
	hw_abort (me, "illegal value for backend parameter `%s':"
                  "use tcp or stdio", value);
    }
}
Example #5
0
static void
bfin_ppi_finish (struct hw *me)
{
  struct bfin_ppi *ppi;
  const char *color;

  ppi = HW_ZALLOC (me, struct bfin_ppi);

  set_hw_data (me, ppi);
  set_hw_io_read_buffer (me, bfin_ppi_io_read_buffer);
  set_hw_io_write_buffer (me, bfin_ppi_io_write_buffer);
  set_hw_dma_read_buffer (me, bfin_ppi_dma_read_buffer);
  set_hw_dma_write_buffer (me, bfin_ppi_dma_write_buffer);
  set_hw_ports (me, bfin_ppi_ports);

  attach_bfin_ppi_regs (me, ppi);

  /* Initialize the PPI.  */
  if (hw_find_property (me, "color"))
    color = hw_find_string_property (me, "color");
  else
    color = NULL;
  ppi->color = bfin_gui_color (color);
}
static void
attach_nvram_regs (struct hw *me, struct nvram *controller)
{
  unsigned_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;
  int result, oerrno;

  /* Get ram bank description (base and size).  */
  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain one addr/size entry");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space,
				     &attach_address,
				     me);
  hw_unit_size_to_attach_size (hw_parent (me),
			       &reg.size,
			       &attach_size, me);

  hw_attach_address (hw_parent (me), 0,
		     attach_space, attach_address, attach_size,
		     me);

  controller->mode         = NVRAM_SAVE_ALL;
  controller->base_address = attach_address;
  controller->size         = attach_size;
  controller->fd           = -1;
  
  /* Get the file where the ram content must be loaded/saved.  */
  if(hw_find_property (me, "file") == NULL)
    hw_abort (me, "Missing \"file\" property");
  
  controller->file_name = hw_find_string_property (me, "file");

  /* Get the mode which defines how to save the memory.  */
  if(hw_find_property (me, "mode") != NULL)
    {
      const char *value = hw_find_string_property (me, "mode");

      if (strcmp (value, "map") == 0)
        controller->mode = NVRAM_MAP_FILE;
      else if (strcmp (value, "save-modified") == 0)
        controller->mode = NVRAM_SAVE_MODIFIED;
      else if (strcmp (value, "save-all") == 0)
        controller->mode = NVRAM_SAVE_ALL;
      else
	hw_abort (me, "illegal value for mode parameter `%s': "
                  "use map, save-modified or save-all", value);
    }

  /* Initialize the ram by loading/mapping the file in memory.
     If the file does not exist, create and give it some content.  */
  switch (controller->mode)
    {
    case NVRAM_MAP_FILE:
      hw_abort (me, "'map' mode is not yet implemented, use 'save-modified'");
      break;

    case NVRAM_SAVE_MODIFIED:
    case NVRAM_SAVE_ALL:
      controller->data = (char*) hw_malloc (me, attach_size);
      if (controller->data == 0)
        hw_abort (me, "Not enough memory, try to use the mode 'map'");

      memset (controller->data, 0, attach_size);
      controller->fd = open (controller->file_name, O_RDWR);
      if (controller->fd < 0)
        {
          controller->fd = open (controller->file_name,
                                 O_RDWR | O_CREAT, 0644);
          if (controller->fd < 0)
            hw_abort (me, "Cannot open or create file '%s'",
                      controller->file_name);
          result = write (controller->fd, controller->data, attach_size);
          if (result != attach_size)
            {
              oerrno = errno;
              hw_free (me, controller->data);
              close (controller->fd);
              errno = oerrno;
              hw_abort (me, "Failed to save the ram content");
            }
        }
      else
        {
          result = read (controller->fd, controller->data, attach_size);
          if (result != attach_size)
            {
              oerrno = errno;
              hw_free (me, controller->data);
              close (controller->fd);
              errno = oerrno;
              hw_abort (me, "Failed to load the ram content");
            }
        }
      if (controller->mode == NVRAM_SAVE_ALL)
        {
          close (controller->fd);
          controller->fd = -1;
        }
      break;

    default:
      break;
    }
}
Example #7
0
static void
cris_finish (struct hw *me)
{
  struct cris_hw *crishw;
  const struct hw_property *vec_for_int;
  const struct hw_property *multiple_int;

  crishw = HW_ZALLOC (me, struct cris_hw);
  set_hw_data (me, crishw);
  set_hw_ports (me, cris_ports);
  set_hw_port_event (me, cris_port_event);

  vec_for_int = hw_find_property (me, "vec-for-int");
  if (vec_for_int != NULL)
    {
      unsigned32 vecsize;
      unsigned32 i;

      if (hw_property_type (vec_for_int) != array_property)
	hw_abort (me, "property \"vec-for-int\" has the wrong type");

      vecsize = hw_property_sizeof_array (vec_for_int) / sizeof (signed_cell);

      if ((vecsize % 2) != 0)
	hw_abort (me, "translation vector does not consist of even pairs");

      crishw->int_to_vec
	= hw_malloc (me, (vecsize/2 + 1) * sizeof (crishw->int_to_vec[0]));

      for (i = 0; i < vecsize/2; i++)
	{
	  signed_cell portval_sc;
	  signed_cell vec_sc;

	  if (!hw_find_integer_array_property (me, "vec-for-int", i*2,
					       &portval_sc)
	      || !hw_find_integer_array_property (me, "vec-for-int", i*2 + 1,
						  &vec_sc)
	      || portval_sc < 0
	      || vec_sc < 0)
	    hw_abort (me, "no valid vector translation pair %u", i);

	  crishw->int_to_vec[i].portval = (unsigned32) portval_sc;
	  crishw->int_to_vec[i].vec = (unsigned32) vec_sc;
	}

      crishw->int_to_vec[i].portval = 0;
      crishw->int_to_vec[i].vec = 0;
    }

  multiple_int = hw_find_property (me, "multiple-int");
  if (multiple_int != NULL)
    {
      if (hw_property_type (multiple_int) == integer_property)
	{
	  crishw->multiple_int_vector
	    = hw_find_integer_property (me, "multiple-int");
	  crishw->multi_int_action = cris_multint_vector;
	}
      else
	{
	  const char *action = hw_find_string_property (me, "multiple-int");

	  if (action == NULL)
	    hw_abort (me, "property \"multiple-int\" has the wrong type");

	  if (strcmp (action, "abort") == 0)
	    crishw->multi_int_action = cris_multint_abort;
	  else if (strcmp (action, "ignore_previous") == 0)
	    crishw->multi_int_action = cris_multint_ignore_previous;
	  else
	    hw_abort (me, "property \"multiple-int\" must be one of <vector number>\n"
		      "\"abort\" and \"ignore_previous\", not \"%s\"", action);
	}
    }
  else
    crishw->multi_int_action = cris_multint_abort;
}
Example #8
0
static int
split_device_specifier (struct hw *current,
			const char *device_specifier,
			name_specifier *spec)
{
  char *chp = NULL;

  /* expand any leading alias if present */
  if (current != NULL
      && *device_specifier != '\0'
      && *device_specifier != '.'
      && *device_specifier != '/')
    {
      struct hw *aliases = hw_tree_find_device (current, "/aliases");
      char alias[32];
      int len = 0;
      while (device_specifier[len] != '\0'
	     && device_specifier[len] != '/'
	     && device_specifier[len] != ':'
	     && !isspace (device_specifier[len]))
	{
	  alias[len] = device_specifier[len];
	  len++;
	  if (len >= sizeof(alias))
	    hw_abort (NULL, "split_device_specifier: buffer overflow");
	}
      alias[len] = '\0';
      if (aliases != NULL
	  && hw_find_property (aliases, alias))
	{
	  strcpy (spec->buf, hw_find_string_property(aliases, alias));
	  strcat (spec->buf, device_specifier + len);
	}
      else
	{
	  strcpy (spec->buf, device_specifier);
	}
    }
  else
    {
      strcpy(spec->buf, device_specifier);
    }

  /* check no overflow */
  if (strlen(spec->buf) >= sizeof(spec->buf))
    hw_abort (NULL, "split_device_specifier: buffer overflow\n");

  /* strip leading spaces */
  chp = spec->buf;
  while (*chp != '\0' && isspace(*chp))
    chp++;
  if (*chp == '\0')
    return 0;

  /* find the path and terminate it with null */
  spec->path = chp;
  while (*chp != '\0' && !isspace(*chp))
    chp++;
  if (*chp != '\0')
    {
      *chp = '\0';
      chp++;
    }

  /* and any value */
  while (*chp != '\0' && isspace(*chp))
    chp++;
  spec->value = chp;

  /* now go back and chop the property off of the path */
  if (spec->value[0] == '\0')
    {
      spec->property = NULL; /*not a property*/
      spec->value = NULL;
    }
  else if (spec->value[0] == '>'
	   || spec->value[0] == '<')
    {
      /* an interrupt spec */
      spec->property = NULL;
    }
  else
    {
      chp = strrchr(spec->path, '/');
      if (chp == NULL)
	{
	  spec->property = spec->path;
	  spec->path = strchr(spec->property, '\0');
	}
      else
	{
	  *chp = '\0';
	  spec->property = chp+1;
	}
    }

  /* and mark the rest as invalid */
  spec->name = NULL;
  spec->family = NULL;
  spec->unit = NULL;
  spec->args = NULL;
  spec->last_name = NULL;
  spec->last_family = NULL;
  spec->last_unit = NULL;
  spec->last_args = NULL;

  return 1;
}
Example #9
0
static void
print_properties (struct hw *me,
		  struct printer *p)
{
  const struct hw_property *property;
  for (property = hw_find_property (me, NULL);
       property != NULL;
       property = hw_next_property (property))
    {
      if (hw_parent (me) == NULL)
	p->print (p->file, "/%s", property->name);
      else
	p->print (p->file, "%s/%s", hw_path (me), property->name);
      if (property->original != NULL)
	{
	  p->print (p->file, " !");
	  p->print (p->file, "%s/%s",
		     hw_path (property->original->owner),
		     property->original->name);
	}
      else
	{
	  switch (property->type)
	    {
	    case array_property:
	      {
		if ((property->sizeof_array % sizeof (signed_cell)) == 0)
		  {
		    unsigned_cell *w = (unsigned_cell*) property->array;
		    int cell_nr;
		    for (cell_nr = 0;
			 cell_nr < (property->sizeof_array / sizeof (unsigned_cell));
			 cell_nr++)
		      {
			p->print (p->file, " 0x%lx", (unsigned long) BE2H_cell (w[cell_nr]));
		      }
		  }
		else
		  {
		    unsigned8 *w = (unsigned8*)property->array;
		    p->print (p->file, " [");
		    while ((char*)w - (char*)property->array < property->sizeof_array)
		      {
			p->print (p->file, " 0x%2x", BE2H_1 (*w));
			w++;
		      }
		  }
		break;
	      }
	    case boolean_property:
	      {
		int b = hw_find_boolean_property(me, property->name);
		p->print (p->file, " %s", b ? "true"  : "false");
		break;
	      }
#if NOT_YET
	    case ihandle_property:
	      {
		if (property->array != NULL)
		  {
		    device_instance *instance = hw_find_ihandle_property (me, property->name);
		    p->print (p->file, " *%s", device_instance_path(instance));
		  }
		else
		  {
		    /* not yet initialized, ask the device for the path */
		    ihandle_runtime_property_spec spec;
		    hw_find_ihandle_runtime_property (me, property->name, &spec);
		    p->print (p->file, " *%s", spec.full_path);
		  }
		break;
	      }
#endif
	    case integer_property:
	      {
		unsigned_word w = hw_find_integer_property (me, property->name);
		p->print (p->file, " 0x%lx", (unsigned long)w);
		break;
	      }
	    case range_array_property:
	      {
		print_ranges_property (me, property, p);
		break;
	      }
	    case reg_array_property:
	      {
		print_reg_property (me, property, p);
		break;
	      }
	    case string_property:
	      {
		const char *s = hw_find_string_property (me, property->name);
		print_string (me, s, p);
		break;
	      }
	    case string_array_property:
	      {
		print_string_array_property (me, property, p);
		break;
	      }
	    }
	}
      p->print (p->file, "\n");
    }
}