Exemplo n.º 1
0
static void
attach_bfin_uart_regs (struct hw *me, struct bfin_uart *uart)
{
  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_UART2_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_UART2_SIZE);

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

  uart->base = attach_address;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
/* Helper function to easily add CFI erase regions to the existing set.  */
static void
cfi_add_erase_region (struct hw *me, struct cfi *cfi,
		      unsigned blocks, unsigned size)
{
  unsigned num_regions = cfi->query.num_erase_regions;
  struct cfi_erase_region *region;
  unsigned char *qry_region;

  /* Store for our own usage.  */
  region = &cfi->erase_regions[num_regions];
  region->blocks = blocks;
  region->size = size;
  if (num_regions == 0)
    region->start = 0;
  else
    region->start = region[-1].end;
  region->end = region->start + (blocks * size);

  /* Regions are 4 bytes long.  */
  qry_region = cfi->erase_region_info + 4 * num_regions;

  /* [0][1] = number erase blocks - 1 */
  if (blocks > 0xffff + 1)
    hw_abort (me, "erase blocks %u too big to fit into region info", blocks);
  cfi_encode_16bit (&qry_region[0], blocks - 1);

  /* [2][3] = block size / 256 bytes */
  if (size > 0xffff * 256)
    hw_abort (me, "erase size %u too big to fit into region info", size);
  cfi_encode_16bit (&qry_region[2], size / 256);

  /* Yet another region.  */
  cfi->query.num_erase_regions = num_regions + 1;
}
Exemplo n.º 5
0
static void
write_intmode_reg (struct hw *me,
		   struct mn103ser *serial,
		   unsigned_word serial_reg,
		   const void *source,
		   unsigned  nr_bytes)
{
unsigned8 val = *(unsigned8 *)source;

  if ( nr_bytes == 1 )
    {
      /* Check for attempt to write to read-only bits of register. */
      if ( ( serial_reg == 2 && (val & 0xCA) != 0 )
	   || ( serial_reg != 2 && (val & 0x4A) != 0 ) )
	{
	  hw_abort(me, "Cannot write to read-only bits of SC%dICR.",
		   serial_reg);
	}
      else
	{
	  serial->device[serial_reg].intmode = val;
	}
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to SC%dICR.", nr_bytes, 
		serial_reg);
    }
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
static void
write_control_reg (struct hw *me,
		   struct mn103ser *serial,
		   unsigned_word serial_reg,
		   const void *source,
		   unsigned  nr_bytes)
{
  unsigned16 val = LE2H_2 (*(unsigned16 *)source);

  /* really allow 1 byte write, too */
  if ( nr_bytes == 2 )
    {
      if ( serial_reg == 2 && (val & 0x0C04) != 0 )
	{
	  hw_abort(me, "Cannot write to read-only bits of SC2CTR.");
	}
      else
	{
	  serial->device[serial_reg].control = val;
	}
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes, 
		serial_reg);
    }
}
Exemplo n.º 9
0
static void
write_control_reg (struct hw *me,
		   struct mn103iop *io_port,
		   unsigned_word io_port_reg,
		   const void *source,
		   unsigned  nr_bytes)
{
  unsigned8 buf = *(unsigned8 *)source;
  if ( nr_bytes == 1 )
    {
      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
	{
	  hw_abort(me, "Cannot write to read-only bits of P3DIR.");
	}
      else
	{
	  io_port->port[io_port_reg].control = buf;
	}
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to P%dDIR.", nr_bytes, 
		io_port_reg);
    }
}
Exemplo n.º 10
0
static void
write_output_mode_reg (struct hw *me,
		       struct mn103iop *io_port,
		       unsigned_word io_port_reg,
		       const void *source,
		       unsigned  nr_bytes)
{
  unsigned8 buf = *(unsigned8 *)source;
  if ( nr_bytes == 1 )
    {
      /* check if there are fields which can't be written and
	 take appropriate action depending what bits are set */
      if ( ( io_port_reg == 3 && (buf & 0xfc) != 0 )
	   || ( (io_port_reg == 0 || io_port_reg == 1)  && (buf & 0xfe) != 0 ) )
	{
	  hw_abort(me, "Cannot write to read-only bits of output mode register.");
	}
      else
	{
	  io_port->port[io_port_reg].output_mode = buf;
	}
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to P%dMD.", nr_bytes, 
		io_port_reg);
    }
}
Exemplo n.º 11
0
static void
attach_mn103int_regs (struct hw *me,
                      struct mn103int *controller)
{
    int i;
    if (hw_find_property (me, "reg") == NULL)
        hw_abort (me, "Missing \"reg\" property");
    for (i = 0; i < NR_BLOCKS; i++)
    {
        unsigned_word attach_address;
        int attach_space;
        unsigned attach_size;
        reg_property_spec reg;
        if (!hw_find_reg_array_property (me, "reg", i, &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[i].base = attach_address;
        hw_unit_size_to_attach_size (hw_parent (me),
                                     &reg.size,
                                     &attach_size, me);
        controller->block[i].bound = attach_address + (attach_size - 1);
        hw_attach_address (hw_parent (me),
                           0,
                           attach_space, attach_address, attach_size,
                           me);
    }
}
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);
}
static unsigned
mn103iop_io_write_buffer (struct hw *me,
			  const void *source,
			  int space,
			  unsigned_word base,
			  unsigned nr_bytes)
{
  struct mn103iop *io_port = hw_data (me);
  enum io_port_register_types io_port_reg;
  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));

  io_port_reg = decode_addr (me, io_port, base);
  switch (io_port_reg)
    {
    /* Port output registers */
    case P0OUT:
    case P1OUT:
    case P2OUT:
    case P3OUT:
      write_output_reg(me, io_port, io_port_reg-P0OUT, source, nr_bytes);
      break;

    /* Port output mode registers */
    case P0MD:
    case P1MD:
    case P2MD:
    case P3MD:
      write_output_mode_reg(me, io_port, io_port_reg-P0MD, source, nr_bytes);
      break;

    /* Port control registers */
    case P0DIR:
    case P1DIR:
    case P2DIR:
    case P3DIR:
      write_control_reg(me, io_port, io_port_reg-P0DIR, source, nr_bytes);
      break;

    /* Port pin registers */
    case P0IN:
    case P1IN:
    case P2IN:
      hw_abort(me, "Cannot write to pin register.");
      break;

    case P2SS:
    case P4SS:
      write_dedicated_control_reg(me, io_port, io_port_reg, source, nr_bytes);
      break;

    default:
      hw_abort(me, "invalid address");
    }

  return nr_bytes;
}     
Exemplo n.º 14
0
static void
read_special_timer6_reg (struct hw *me,
			 struct mn103tim *timers,
			 int timer_nr,
			 void *dest,
			 unsigned  nr_bytes)
{
  unsigned32 val;

  switch (nr_bytes) {
  case 1:
    {
      switch ( timer_nr ) {
      case TM6MDA:
	*(unsigned8 *)dest = timers->tm6mda;
	break;
    
      case TM6MDB:
	*(unsigned8 *)dest = timers->tm6mdb;
	break;
    
      case TM6CA:
	*(unsigned8 *)dest = timers->tm6ca;
	break;
    
      case TM6CB:
	*(unsigned8 *)dest = timers->tm6cb;
	break;
      
      default:
	break;
      }
      break;
    }
    
  case 2:
    if ( timer_nr == TM6CA )
      {
	*(unsigned16 *)dest = timers->tm6ca;
      }
    else if ( timer_nr == TM6CB )
      {
	*(unsigned16 *)dest = timers->tm6cb;
      }
    else
      {
	hw_abort(me, "bad read size for timer 6 mode A/B register");
      }
    break;

  default:
    hw_abort(me, "bad read size for timer 6 register");
  }
      
}
Exemplo n.º 15
0
static void
write_special_timer6_reg (struct hw *me,
			  struct mn103tim *timers,
			  int timer_nr,
			  const void *source,
			  unsigned  nr_bytes)
{
  unsigned32 val;

  switch (nr_bytes) {
  case 1:
    {
      switch ( timer_nr ) {
      case TM6MDA:
	timers->tm6mda = *(unsigned8 *)source;
	break;
    
      case TM6MDB:
	timers->tm6mdb = *(unsigned8 *)source;
	break;
    
      case TM6CA:
	timers->tm6ca = *(unsigned8 *)source;
	break;
    
      case TM6CB:
	timers->tm6cb = *(unsigned8 *)source;
	break;
      
      default:
	break;
      }
      break;
    }
    
  case 2:
    if ( timer_nr == TM6CA )
      {
	timers->tm6ca = *(unsigned16 *)source;
      }
    else if ( timer_nr == TM6CB )
      {
	timers->tm6cb = *(unsigned16 *)source;
      }
    else
      {
	hw_abort(me, "bad read size for timer 6 mode A/B register");
      }
    break;

  default:
    hw_abort(me, "bad read size for timer 6 register");
  }
      
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
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);
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
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);
}
Exemplo n.º 21
0
void
hw_find_ihandle_runtime_property (struct hw *me,
				  const char *property,
				  ihandle_runtime_property_spec *ihandle)
{
  struct hw_property_data *entry = find_property_data (me, property);
  if (entry == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (entry->property->type != ihandle_property
      || entry->property->disposition != permenant_object)
    hw_abort (me, "property \"%s\" of wrong type", property);
  ASSERT (entry->init_array != NULL);
  /* the full path */
  ihandle->full_path = entry->init_array;
}
Exemplo n.º 22
0
static const char *
full_name_of_hw (struct hw *leaf,
		 char *buf,
		 unsigned sizeof_buf)
{
  /* get a buffer */
  char full_name[1024];
  if (buf == (char*)0)
    {
      buf = full_name;
      sizeof_buf = sizeof (full_name);
    }

  /* use head recursion to construct the path */

  if (hw_parent (leaf) == NULL)
    /* root */
    {
      if (sizeof_buf < 1)
	hw_abort (leaf, "buffer overflow");
      *buf = '\0';
    }
  else
    /* sub node */
    {
      char unit[1024];
      full_name_of_hw (hw_parent (leaf), buf, sizeof_buf);
      if (hw_unit_encode (hw_parent (leaf),
			  hw_unit_address (leaf),
			  unit + 1,
			  sizeof (unit) - 1)
	  > 0)
	unit[0] = '@';
      else
	unit[0] = '\0';
      if (strlen (buf) + strlen ("/") + strlen (hw_name (leaf)) + strlen (unit)
	  >= sizeof_buf)
	hw_abort (leaf, "buffer overflow");
      strcat (buf, "/");
      strcat (buf, hw_name (leaf));
      strcat (buf, unit);
    }

  /* return it usefully */
  if (buf == full_name)
    buf = hw_strdup (leaf, full_name);
  return buf;
}
Exemplo n.º 23
0
static unsigned
mn103tim_io_write_buffer (struct hw *me,
			  const void *source,
			  int space,
			  unsigned_word base,
			  unsigned nr_bytes)
{
  struct mn103tim *timers = hw_data (me);
  enum timer_register_types timer_reg;

  HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
	     (int) nr_bytes, *(unsigned32 *)source));

  timer_reg = decode_addr (me, timers, base);

  /* It can be either a mode register, a base register, a binary counter, */
  /* or a special timer 6 register.  Check in that order. */
  if ( timer_reg <= LAST_MODE_REG )
    {
      if ( timer_reg == 6 ) 
	{
	  write_tm6md(me, timers, base, source, nr_bytes);
	}
      else
	{
	  write_mode_reg(me, timers, timer_reg-FIRST_MODE_REG,
			 source, nr_bytes);
	}
    }
  else if ( timer_reg <= LAST_BASE_REG )
    {
      write_base_reg(me, timers, timer_reg-FIRST_BASE_REG, source, nr_bytes);
    }
  else if ( timer_reg <= LAST_COUNTER )
    {
      hw_abort(me, "cannot write to counter");
    }
  else if ( timer_reg <= LAST_TIMER_REG )
    {
      write_special_timer6_reg(me, timers, timer_reg, source, nr_bytes);
    }
  else
    {
      hw_abort(me, "invalid reg type");
    }

  return nr_bytes;
}     
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
0
void
hw_add_duplicate_property (struct hw *me,
			   const char *property,
			   const struct hw_property *original)
{
  struct hw_property_data *master;
  TRACE (trace_devices,
	 ("hw_add_duplicate_property(me=0x%lx, property=%s, ...)\n",
	  (long)me, property));
  if (original->disposition != permenant_object)
    hw_abort (me, "Can only duplicate permenant objects");
  /* find the original's master */
  master = original->owner->properties_of_hw;
  while (master->property != original)
    {
      master = master->next;
      ASSERT(master != NULL);
    }
  /* now duplicate it */
  hw_add_property (me, property,
		   original->type,
		   master->init_array, master->sizeof_init_array,
		   original->array, original->sizeof_array,
		   original, permenant_object);
}
static int
decode_addr (struct hw *me,
	     struct mn103iop *io_port,
	     unsigned_word address)
{
  unsigned_word offset;
  offset = address - io_port->block[0].base;
  switch (offset)
    {
    case 0x00: return P0OUT;
    case 0x01: return P1OUT;
    case 0x04: return P2OUT;
    case 0x05: return P3OUT;
    case 0x20: return P0MD;
    case 0x21: return P1MD;
    case 0x24: return P2MD;
    case 0x25: return P3MD;
    case 0x44: return P2SS;
    case 0x48: return P4SS;
    case 0x60: return P0DIR;
    case 0x61: return P1DIR;
    case 0x64: return P2DIR;
    case 0x65: return P3DIR;
    case 0x80: return P0IN;
    case 0x81: return P1IN;
    case 0x84: return P2IN;
    case 0x85: return P3IN;
    default: 
      {
	hw_abort (me, "bad address");
	return -1;
      }
    }
}
static unsigned
mn103int_io_write_buffer (struct hw *me,
			  const void *source,
			  int space,
			  unsigned_word base,
			  unsigned nr_bytes)
{
  struct mn103int *controller = hw_data (me);
  const unsigned8 *buf = source;
  unsigned byte;
  /* HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); */
  for (byte = 0; byte < nr_bytes; byte++)
    {
      unsigned_word address = base + byte;
      unsigned_word offset;
      switch (decode_addr (me, controller, address, &offset))
	{
	case ICR_BLOCK:
	  write_icr (me, controller, offset, buf[byte]);
	  break;
	case IAGR_BLOCK:
	  /* not allowed */
	  break;
	case EXTMD_BLOCK:
	  write_extmd (me, controller, offset, buf[byte]);
	  break;
	default:
	  hw_abort (me, "bad switch");
	}
    }
  return nr_bytes;
}     
static unsigned
mn103int_io_read_buffer (struct hw *me,
			 void *dest,
			 int space,
			 unsigned_word base,
			 unsigned nr_bytes)
{
  struct mn103int *controller = hw_data (me);
  unsigned8 *buf = dest;
  unsigned byte;
  /* HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); */
  for (byte = 0; byte < nr_bytes; byte++)
    {
      unsigned_word address = base + byte;
      unsigned_word offset;
      switch (decode_addr (me, controller, address, &offset))
	{
	case ICR_BLOCK:
	  buf[byte] = read_icr (me, controller, offset);
	  break;
	case IAGR_BLOCK:
	  buf[byte] = read_iagr (me, controller, offset);
	  break;
	case EXTMD_BLOCK:
	  buf[byte] = read_extmd (me, controller, offset);
	  break;
	default:
	  hw_abort (me, "bad switch");
	}
    }
  return nr_bytes;
}     
static void
tx3904sio_port_event (struct hw *me,
		     int my_port,
		     struct hw *source,
		     int source_port,
		     int level)
{
  struct tx3904sio *controller = hw_data (me);

  switch (my_port)
    {
    case RESET_PORT:
      {
	HW_TRACE ((me, "reset"));

	tx3904sio_fifo_reset(me, & controller->rx_fifo);
	tx3904sio_fifo_reset(me, & controller->tx_fifo);
	controller->slsr = controller->sdicr
	  = controller->sdisr = controller->sfcr
	  = controller->sbgr = 0;
	controller->slcr = 0x40000000; /* set TWUB */
	controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */
	/* Don't interfere with I/O poller. */
	break;
      }

    default:
      hw_abort (me, "Event on unknown port %d", my_port);
      break;
    }
}
Exemplo n.º 30
0
void
create_hw_event_data (struct hw *me)
{
  if (me->events_of_hw != NULL)
    hw_abort (me, "stray events");
  /* NOP */
}