コード例 #1
0
ファイル: hw-base.c プロジェクト: Claruarius/stblinux-2.6.37
void
hw_finish (struct hw *me)
{
  if (hw_finished_p (me))
    hw_abort (me, "Attempt to finish finished device");

  /* Fill in the (hopefully) defined address/size cells values */
  if (hw_find_property (me, "#address-cells") != NULL)
    me->nr_address_cells_of_hw_unit =
      hw_find_integer_property (me, "#address-cells");
  else
    me->nr_address_cells_of_hw_unit = 2;
  if (hw_find_property (me, "#size-cells") != NULL)
    me->nr_size_cells_of_hw_unit =
      hw_find_integer_property (me, "#size-cells");
  else
    me->nr_size_cells_of_hw_unit = 1;

  /* Fill in the (hopefully) defined trace variable */
  if (hw_find_property (me, "trace?") != NULL)
    me->trace_of_hw_p = hw_find_boolean_property (me, "trace?");
  /* allow global variable to define default tracing */
  else if (! hw_trace_p (me)
	   && hw_find_property (hw_root (me), "global-trace?") != NULL
	   && hw_find_boolean_property (hw_root (me), "global-trace?"))
    me->trace_of_hw_p = 1;


  /* Allow the real device to override any methods */
  me->base_of_hw->descriptor->to_finish (me);
  me->base_of_hw->finished_p = 1;
}
コード例 #2
0
ファイル: dv-mn103cpu.c プロジェクト: Distrotech/binutils
static void
attach_mn103cpu_regs (struct hw *me,
		      struct mn103cpu *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 three addr/size entries");
  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space,
				     &attach_address,
				     me);
  controller->block.base = attach_address;
  hw_unit_size_to_attach_size (hw_parent (me),
			       &reg.size,
			       &attach_size, me);
  controller->block.bound = attach_address + (attach_size - 1);
  if ((controller->block.base & 3) != 0)
    hw_abort (me, "cpu register block must be 4 byte aligned");
  hw_attach_address (hw_parent (me),
		     0,
		     attach_space, attach_address, attach_size,
		     me);
}
コード例 #3
0
int
hw_find_integer_array_property (struct hw *me,
				const char *property,
				unsigned index,
				signed_cell *integer)
{
  const struct hw_property *node;
  int sizeof_integer = sizeof (*integer);
  signed_cell *cell;
  TRACE (trace_devices,
	 ("hw_find_integer(me=0x%lx, property=%s)\n",
	  (long)me, property));
  
  /* check things sane */
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != integer_property
      && node->type != array_property)
    hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
  if ((node->sizeof_array % sizeof_integer) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
  if (node->sizeof_array <= sizeof_integer * index)
    return 0;
  
  /* Find and convert the value */
  cell = ((signed_cell*)node->array) + index;
  *integer = BE2H_cell (*cell);
  
  return node->sizeof_array / sizeof_integer;
}
コード例 #4
0
ファイル: dv-tx3904irc.c プロジェクト: Winter3un/ctf_task
static void
attach_tx3904irc_regs (struct hw *me,
		      struct tx3904irc *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);

  controller->base_address = attach_address;
}
コード例 #5
0
static void
hw_pal_finish (struct hw *hw)
{
  /* create the descriptor */
  hw_pal_device *hw_pal = HW_ZALLOC (hw, hw_pal_device);
  hw_pal->output.status = 1;
  hw_pal->output.buffer = '\0';
  hw_pal->input.status = 0;
  hw_pal->input.buffer = '\0';
  set_hw_data (hw, hw_pal);
  set_hw_attach_address (hw, hw_pal_attach_address);
  set_hw_io_read_buffer (hw, hw_pal_io_read_buffer);
  set_hw_io_write_buffer (hw, hw_pal_io_write_buffer);
  set_hw_ports (hw, hw_pal_ports);
  /* attach ourselves */
  do_hw_attach_regs (hw);
  /* If so configured, enable polled input */
  if (hw_find_property (hw, "poll?") != NULL
      && hw_find_boolean_property (hw, "poll?"))
    {
      hw_pal->reader = sim_io_poll_read;
    }
  else
    {
      hw_pal->reader = sim_io_read;
    }
  /* tag the periodic timer */
  hw_pal->timer.periodic_p = 1;
}
コード例 #6
0
ファイル: dv-bfin_cec.c プロジェクト: Drakey83/steamlink-sdk
static void
attach_bfin_cec_regs (struct hw *me, struct bfin_cec *cec)
{
  address_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 three addr/size entries");

  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);

  if (attach_size != BFIN_COREMMR_CEC_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_CEC_SIZE);

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

  cec->base = attach_address;
  /* XXX: should take from the device tree.  */
  cec->cpu = STATE_CPU (hw_system (me), 0);
  cec->me = me;
}
コード例 #7
0
ファイル: dv-mn103ser.c プロジェクト: Drakey83/steamlink-sdk
static void
attach_mn103ser_regs (struct hw *me,
		      struct mn103ser *serial)
{
  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 three addr/size entries");
  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space,
				     &attach_address,
				     me);
  serial->block.base = attach_address;
  hw_unit_size_to_attach_size (hw_parent (me),
			       &reg.size,
			       &attach_size, me);
  serial->block.bound = attach_address + (attach_size - 1);
  hw_attach_address (hw_parent (me),
		     0,
		     attach_space, attach_address, attach_size,
		     me);
}
static void
attach_mn103iop_regs (struct hw *me,
		      struct mn103iop *io_port)
{
  int i;
  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");

  for (i=0; i < NR_BLOCKS; ++i )
    {
      if (!hw_find_reg_array_property (me, "reg", i, &reg))
	hw_abort (me, "\"reg\" property must contain five addr/size entries");
      hw_unit_address_to_attach_address (hw_parent (me),
					 &reg.address,
					 &attach_space,
					 &attach_address,
					 me);
      io_port->block[i].base = attach_address;
      hw_unit_size_to_attach_size (hw_parent (me),
				   &reg.size,
				   &attach_size, me);
      io_port->block[i].bound = attach_address + (attach_size - 1);
      hw_attach_address (hw_parent (me),
			 0,
			 attach_space, attach_address, attach_size,
			 me);
    }
}
コード例 #9
0
static void
attach_bfin_ppi_regs (struct hw *me, struct bfin_ppi *ppi)
{
  address_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 three addr/size entries");

  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);

  if (attach_size != BFIN_MMR_PPI_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_PPI_SIZE);

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

  ppi->base = attach_address;
}
コード例 #10
0
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);
}
コード例 #11
0
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;
}
コード例 #12
0
const struct hw_property *
hw_find_array_property (struct hw *me,
			const char *property)
{
  const struct hw_property *node;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != array_property)
    hw_abort (me, "property \"%s\" of wrong type (array)", property);
  return node;
}
コード例 #13
0
ファイル: hw-tree.c プロジェクト: Claruarius/stblinux-2.6.37
const struct hw_property *
hw_tree_find_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)
    return NULL; /* not a leaf */
  return hw_find_property (root, spec.property);
}
コード例 #14
0
ファイル: hw-base.c プロジェクト: Claruarius/stblinux-2.6.37
void
do_hw_attach_regs (struct hw *hw)
{
  static const char *(reg_property_names[]) = {
    "attach-addresses",
    "assigned-addresses",
    "reg",
    "alternate-reg" ,
    NULL
  };
  const char **reg_property_name;
  int nr_valid_reg_properties = 0;
  for (reg_property_name = reg_property_names;
       *reg_property_name != NULL;
       reg_property_name++)
    {
      if (hw_find_property (hw, *reg_property_name) != NULL)
	{
	  reg_property_spec reg;
	  int reg_entry;
	  for (reg_entry = 0;
	       hw_find_reg_array_property (hw, *reg_property_name, reg_entry,
					   &reg);
	       reg_entry++)
	    {
	      unsigned_word attach_address;
	      int attach_space;
	      unsigned attach_size;
	      if (!hw_unit_address_to_attach_address (hw_parent (hw),
						      &reg.address,
						      &attach_space,
						      &attach_address,
						      hw))
		continue;
	      if (!hw_unit_size_to_attach_size (hw_parent (hw),
						&reg.size,
						&attach_size, hw))
		continue;
	      hw_attach_address (hw_parent (hw),
				 0,
				 attach_space, attach_address, attach_size,
				 hw);
	      nr_valid_reg_properties++;
	    }
	  /* if first option matches don't try for any others */
	  if (reg_property_name == reg_property_names)
	    break;
	}
    }
}
コード例 #15
0
const char *
hw_find_string_property (struct hw *me,
			 const char *property)
{
  const struct hw_property *node;
  const char *string;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != string_property)
    hw_abort (me, "property \"%s\" of wrong type (string)", property);
  string = node->array;
  ASSERT (strlen(string) + 1 == node->sizeof_array);
  return string;
}
コード例 #16
0
int
hw_find_boolean_property (struct hw *me,
			  const char *property)
{
  const struct hw_property *node;
  unsigned_cell boolean;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != boolean_property)
    hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
  ASSERT (sizeof (boolean) == node->sizeof_array);
  memcpy (&boolean, node->array, sizeof (boolean));
  return boolean;
}
コード例 #17
0
ファイル: hw-properties.c プロジェクト: bminor/binutils-gdb
signed_cell
hw_find_integer_property (struct hw *me,
			  const char *property)
{
  const struct hw_property *node;
  signed_cell integer;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != integer_property)
    hw_abort (me, "property \"%s\" of wrong type (integer)", property);
  ASSERT (sizeof (integer) == node->sizeof_array);
  memcpy (&integer, node->array, sizeof (integer));
  return BE2H_cell (integer);
}
コード例 #18
0
int
hw_find_range_array_property (struct hw *me,
			      const char *property,
			      unsigned index,
			      range_property_spec *range)
{
  const struct hw_property *node;
  unsigned sizeof_entry = (nr_range_property_cells (me, 1)
			   * sizeof (unsigned_cell));
  const unsigned_cell *cells;
  
  /* locate the property */
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != range_array_property)
    hw_abort (me, "property \"%s\" of wrong type (range array)", property);
  
  /* aligned ? */
  if ((node->sizeof_array % sizeof_entry) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
	      property);
  
  /* within bounds? */
  if (node->sizeof_array < sizeof_entry * (index + 1))
    return 0;
  
  /* find the range of interest */
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
  
  /* copy the child address out - converting as we go */
  cells = cells_to_unit_address (cells, &range->child_address,
				 hw_unit_nr_address_cells (me));
  
  /* copy the parent address out - converting as we go */
  cells = cells_to_unit_address (cells, &range->parent_address,
				 hw_unit_nr_address_cells (hw_parent (me)));
  
  /* copy the size - converting as we go */
  cells = cells_to_unit_address (cells, &range->size,
				 hw_unit_nr_size_cells (me));
  
  return node->sizeof_array / sizeof_entry;
}
コード例 #19
0
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);
    }
}
コード例 #20
0
hw_instance *
hw_find_ihandle_property (struct hw *me,
			  const char *property)
{
  const hw_property_data *node;
  unsigned_cell ihandle;
  hw_instance *instance;

  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != ihandle_property)
    hw_abort(me, "property \"%s\" of wrong type (ihandle)", property);
  if (node->array == NULL)
    hw_abort(me, "runtime property \"%s\" not yet initialized", property);

  ASSERT (sizeof(ihandle) == node->sizeof_array);
  memcpy (&ihandle, node->array, sizeof(ihandle));
  instance = external_to_hw_instance (me, BE2H_cell(ihandle));
  ASSERT (instance != NULL);
  return instance;
}
コード例 #21
0
ファイル: dv-mn103ser.c プロジェクト: Drakey83/steamlink-sdk
static void
mn103ser_finish (struct hw *me)
{
  struct mn103ser *serial;
  int i;

  serial = HW_ZALLOC (me, struct mn103ser);
  set_hw_data (me, serial);
  set_hw_io_read_buffer (me, mn103ser_io_read_buffer);
  set_hw_io_write_buffer (me, mn103ser_io_write_buffer);
  set_hw_ports (me, mn103ser_ports);

  /* Attach ourself to our parent bus */
  attach_mn103ser_regs (me, serial);

  /* If so configured, enable polled input */
  if (hw_find_property (me, "poll?") != NULL
      && hw_find_boolean_property (me, "poll?"))
    {
      serial->reader = sim_io_poll_read;
    }
  else
    {
      serial->reader = sim_io_read;
    }

  /* Initialize the serial device registers. */
  for ( i=0; i<NR_SERIAL_DEVS; ++i )
    {
      serial->device[i].txb = 0;
      serial->device[i].rxb = 0;
      serial->device[i].status = 0;
      serial->device[i].control = 0;
      serial->device[i].intmode = 0;
      serial->device[i].event = NULL;
    }
}
コード例 #22
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);
}
コード例 #23
0
ファイル: dv-cfi.c プロジェクト: ChrisG0x20/gdb
/* Device tree options:
     Required:
       .../reg <addr> <len>
       .../cmdset <primary; integer> [alt; integer]
     Optional:
       .../size <device size (must be pow of 2)>
       .../width <8|16|32>
       .../write_size <integer (must be pow of 2)>
       .../erase_regions <number blocks> <block size> \
                         [<number blocks> <block size> ...]
       .../voltage <vcc min> <vcc max> <vpp min> <vpp max>
       .../timeouts <typ unit write>  <typ buf write>  \
                    <typ block erase> <typ chip erase> \
                    <max unit write>  <max buf write>  \
                    <max block erase> <max chip erase>
       .../file <file> [ro|rw]
     Defaults:
       size: <len> from "reg"
       width: 8
       write_size: 0 (not supported)
       erase_region: 1 (can only erase whole chip)
       voltage: 0.0V (for all)
       timeouts: typ: 1µs, not supported, 1ms, not supported
                 max: 1µs, 1ms, 1ms, not supported

  TODO: Verify user args are valid (e.g. voltage is 8 bits).  */
static void
attach_cfi_regs (struct hw *me, struct cfi *cfi)
{
  address_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;
  bool fd_writable;
  int i, ret, fd;
  signed_cell ival;

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

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

  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);

  /* Extract the desired flash command set.  */
  ret = hw_find_integer_array_property (me, "cmdset", 0, &ival);
  if (ret != 1 && ret != 2)
    hw_abort (me, "\"cmdset\" property takes 1 or 2 entries");
  cfi_encode_16bit (cfi->query.p_id, ival);

  for (i = 0; i < ARRAY_SIZE (cfi_cmdsets); ++i)
    if (cfi_cmdsets[i]->id == ival)
      cfi->cmdset = cfi_cmdsets[i];
  if (cfi->cmdset == NULL)
    hw_abort (me, "cmdset %u not supported", ival);

  if (ret == 2)
    {
      hw_find_integer_array_property (me, "cmdset", 1, &ival);
      cfi_encode_16bit (cfi->query.a_id, ival);
    }

  /* Extract the desired device size.  */
  if (hw_find_property (me, "size"))
    cfi->dev_size = hw_find_integer_property (me, "size");
  else
    cfi->dev_size = attach_size;
  cfi->query.dev_size = log2 (cfi->dev_size);

  /* Extract the desired flash width.  */
  if (hw_find_property (me, "width"))
    {
      cfi->width = hw_find_integer_property (me, "width");
      if (cfi->width != 8 && cfi->width != 16 && cfi->width != 32)
	hw_abort (me, "\"width\" must be 8 or 16 or 32, not %u", cfi->width);
    }
  else
    /* Default to 8 bit.  */
    cfi->width = 8;
  /* Turn 8/16/32 into 1/2/4.  */
  cfi->width /= 8;

  /* Extract optional write buffer size.  */
  if (hw_find_property (me, "write_size"))
    {
      ival = hw_find_integer_property (me, "write_size");
      cfi_encode_16bit (cfi->query.max_buf_write_len, log2 (ival));
    }

  /* Extract optional erase regions.  */
  if (hw_find_property (me, "erase_regions"))
    {
      ret = hw_find_integer_array_property (me, "erase_regions", 0, &ival);
      if (ret % 2)
	hw_abort (me, "\"erase_regions\" must be specified in sets of 2");

      cfi->erase_region_info = HW_NALLOC (me, unsigned char, ret / 2);
      cfi->erase_regions = HW_NALLOC (me, struct cfi_erase_region, ret / 2);

      for (i = 0; i < ret; i += 2)
	{
	  unsigned blocks, size;

	  hw_find_integer_array_property (me, "erase_regions", i, &ival);
	  blocks = ival;

	  hw_find_integer_array_property (me, "erase_regions", i + 1, &ival);
	  size = ival;

	  cfi_add_erase_region (me, cfi, blocks, size);
	}
    }
コード例 #24
0
ファイル: hw-tree.c プロジェクト: Claruarius/stblinux-2.6.37
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");
    }
}
コード例 #25
0
int
hw_find_string_array_property (struct hw *me,
			       const char *property,
			       unsigned index,
			       string_property_spec *string)
{
  const struct hw_property *node;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  switch (node->type)
    {
    default:
      hw_abort (me, "property \"%s\" of wrong type", property);
      break;
    case string_property:
      if (index == 0)
	{
	  *string = node->array;
	  ASSERT (strlen(*string) + 1 == node->sizeof_array);
	  return 1;
	}
      break;
    case array_property:
      if (node->sizeof_array == 0
	  || ((char*)node->array)[node->sizeof_array - 1] != '\0')
	hw_abort (me, "property \"%s\" invalid for string array", property);
      /* FALL THROUGH */
    case string_array_property:
      ASSERT (node->sizeof_array > 0);
      ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
      {
	const char *chp = node->array;
	int nr_entries = 0;
	/* count the number of strings, keeping an eye out for the one
	   we're looking for */
	*string = chp;
	do
	  {
	    if (*chp == '\0')
	      {
		/* next string */
		nr_entries++;
		chp++;
		if (nr_entries == index)
		  *string = chp;
	      }
	    else
	      {
		chp++;
	      }
	  } while (chp < (char*)node->array + node->sizeof_array);
	if (index < nr_entries)
	  return nr_entries;
	else
	  {
	    *string = NULL;
	    return 0;
	  }
      }
      break;
    }
  return 0;
}
コード例 #26
0
ファイル: hw-tree.c プロジェクト: Claruarius/stblinux-2.6.37
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;
}
コード例 #27
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;
}
コード例 #28
0
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;
    }
}