static unsigned8
read_iagr (struct hw *me,
	   struct mn103int *controller,
	   unsigned_word offset)
{
  unsigned8 val;
  switch (offset)
    {
    case 0:
      {
	if (!(controller->group[controller->interrupt_accepted_group].request
	      & controller->group[controller->interrupt_accepted_group].enable))
	  {
	    /* oops, lost the request */
	    val = 0;
	    HW_TRACE ((me, "read-iagr:0 lost-0"));
	  }
	else
	  {
	    val = (controller->interrupt_accepted_group << 2);
	    HW_TRACE ((me, "read-iagr:0 %d", (int) val));
	  }
	break;
      }
    case 1:
      val = 0;
      HW_TRACE ((me, "read-iagr:1 %d", (int) val));
      break;
    default:
      val = 0;
      HW_TRACE ((me, "read-iagr 0x%08lx bad offset", (long) offset));
      break;
    }
  return val;
}
Exemplo n.º 2
0
/* All reads to the flash address space come here.  Using the state
   machine, we figure out what to return -- actual data stored in the
   flash, the CFI query structure, some status info, or something else ?
   Any requests that we can't handle are passed to the command set-
   specific read function.  */
static unsigned
cfi_io_read_buffer (struct hw *me, void *dest, int space,
		    address_word addr, unsigned nr_bytes)
{
  struct cfi *cfi = hw_data (me);
  unsigned char *sdest = dest;
  unsigned offset, shifted_offset;

  offset = addr & (cfi->dev_size - 1);
  shifted_offset = cfi_unshift_addr (cfi, offset);

  /* XXX: Is this OK to enforce ?  */
#if 0
  if (cfi->state != CFI_STATE_READ && cfi->width != nr_bytes)
    {
      HW_TRACE ((me, "read 0x%08lx length %u does not match flash width %u",
		 (unsigned long) addr, nr_bytes, cfi->width));
      return nr_bytes;
    }
#endif

  HW_TRACE ((me, "%s read 0x%08lx length %u",
	     state_names[cfi->state], (unsigned long) addr, nr_bytes));

  switch (cfi->state)
    {
    case CFI_STATE_READ:
      memcpy (dest, cfi->data + offset, nr_bytes);
      break;

    case CFI_STATE_CFI_QUERY:
      if (shifted_offset >= CFI_ADDR_CFI_QUERY_RESULT &&
	  shifted_offset < CFI_ADDR_CFI_QUERY_RESULT + sizeof (cfi->query) +
		     (cfi->query.num_erase_regions * 4))
	{
	  unsigned char *qry;

	  shifted_offset -= CFI_ADDR_CFI_QUERY_RESULT;
	  if (shifted_offset >= sizeof (cfi->query))
	    {
	      qry = cfi->erase_region_info;
	      shifted_offset -= sizeof (cfi->query);
	    }
	  else
	    qry = (void *) &cfi->query;

	  sdest[0] = qry[shifted_offset];
	  memset (sdest + 1, 0, nr_bytes - 1);

	  break;
	}

    default:
      if (!cfi->cmdset->read (me, cfi, dest, offset, shifted_offset, nr_bytes))
	HW_TRACE ((me, "unhandled state %s", state_names[cfi->state]));
      break;
    }

  return nr_bytes;
}
Exemplo n.º 3
0
static void
bfin_gpio_port_event (struct hw *me, int my_port, struct hw *source,
		      int source_port, int level)
{
  struct bfin_gpio *port = hw_data (me);
  bu32 bit = (1 << my_port);

  /* Normalize the level value.  A simulated device can send any value
     it likes to us, but in reality we only care about 0 and 1.  This
     lets us assume only those two values below.  */
  level = !!level;

  HW_TRACE ((me, "pin %i set to %i", my_port, level));

  /* Only screw with state if this pin is set as an input, and the
     input is actually enabled, and it isn't in peripheral mode.  */
  if ((port->dir & bit) || !(port->inen & bit) || !(port->fer & bit))
    {
      HW_TRACE ((me, "ignoring level due to DIR=%i INEN=%i FER=%i",
		 !!(port->dir & bit), !!(port->inen & bit),
		 !!(port->fer & bit)));
      return;
    }

  hw_port_event (me, my_port, level);
}
Exemplo n.º 4
0
static unsigned
hw_pal_io_write_buffer (struct hw *me,
			const void *source,
			int space,
			unsigned_word addr,
			unsigned nr_bytes)
{
  hw_pal_device *hw_pal = (hw_pal_device*) hw_data (me);
  unsigned_1 *byte = (unsigned_1 *) source;
  
  switch (addr & hw_pal_address_mask)
    {

    case hw_pal_reset_register:
      hw_halt (me, sim_exited, byte[0]);
      break;

    case hw_pal_int_register:
      hw_port_event (me,
		     INT_PORT + byte[0], /*port*/
		     (nr_bytes > 1 ? byte[1] : 0)); /* val */
      break;

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

    case hw_pal_read_status:
      hw_pal->input.status = byte[0];
      HW_TRACE ((me, "write - input-status %d\n", byte[0]));
      break;

    case hw_pal_write_fifo:
      write_hw_pal (me, byte[0]);
      HW_TRACE ((me, "write - output-fifo %d\n", byte[0]));
      break;

    case hw_pal_write_status:
      hw_pal->output.status = byte[0];
      HW_TRACE ((me, "write - output-status %d\n", byte[0]));
      break;

    case hw_pal_countdown:
      do_counter_write (me, hw_pal, "countdown",
			&hw_pal->countdown, source, nr_bytes);
      break;
      
    case hw_pal_timer:
      do_counter_write (me, hw_pal, "timer",
			&hw_pal->timer, source, nr_bytes);
      break;
      
    }
  return nr_bytes;
}
static unsigned8
read_icr (struct hw *me,
	  struct mn103int *controller,
	  unsigned_word base)
{
  unsigned_word offset;
  struct mn103int_group *group = decode_group (me, controller, base, &offset);
  unsigned8 val = 0;
  switch (group->type)
    {

    case NMI_GROUP:
      switch (offset)
	{
	case 0:
	  val = INSERT_ID (group->request);
	  HW_TRACE ((me, "read-icr group=%d:0 nmi 0x%02x",
		     group->gid, val));
	  break;
	default:
	  break;
	}
      break;

    case LEVEL_GROUP:
      switch (offset)
	{
	case 0:
	  val = (INSERT_IR (group->request)
		 | INSERT_ID (group->request & group->enable));
	  HW_TRACE ((me, "read-icr group=%d:0 level 0x%02x",
		     group->gid, val));
	  break;
	case 1:
	  val = (INSERT_LV (group->level)
		 | INSERT_IE (group->enable));
	  HW_TRACE ((me, "read-icr level-%d:1 level 0x%02x",
		     group->gid, val));
	  break;
	}
      break;

    default:
      break;

    }

  return val;
}
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.º 7
0
static void
bfin_mmr_invalid (struct hw *me, SIM_CPU *cpu, address_word addr,
		  unsigned nr_bytes, bool write)
{
  if (!cpu)
    cpu = hw_system_cpu (me);

  /* Only throw a fit if the cpu is doing the access.  DMA/GDB simply
     go unnoticed.  Not exactly hardware behavior, but close enough.  */
  if (!cpu)
    {
      sim_io_eprintf (hw_system (me), "%s: invalid MMR access @ %#x\n",
		      hw_path (me), addr);
      return;
    }

  HW_TRACE ((me, "invalid MMR %s to 0x%08lx length %u",
	     write ? "write" : "read", (unsigned long) addr, nr_bytes));

  /* XXX: is this what hardware does ?  */
  if (addr >= BFIN_CORE_MMR_BASE)
    /* XXX: This should be setting up CPLB fault addrs ?  */
    mmu_process_fault (cpu, addr, write, false, false, true);
  else
    /* XXX: Newer parts set up an interrupt from EBIU and program
            EBIU_ERRADDR with the address.  */
    cec_hwerr (cpu, HWERR_SYSTEM_MMR);
}
Exemplo n.º 8
0
static void
bfin_mmr_invalid (struct hw *me, address_word addr,
		  unsigned nr_bytes, bool write, bool missing)
{
  SIM_CPU *cpu = hw_system_cpu (me);
  const char *rw = write ? "write" : "read";
  const char *reason =
    missing ? "no such register" :
              (addr & 3) ? "must be 32-bit aligned" : "invalid length";

  /* Only throw a fit if the cpu is doing the access.  DMA/GDB simply
     go unnoticed.  Not exactly hardware behavior, but close enough.  */
  if (!cpu)
    {
      sim_io_eprintf (hw_system (me),
		      "%s: invalid MMR %s at %#x length %u: %s\n",
		      hw_path (me), rw, addr, nr_bytes, reason);
      return;
    }

  HW_TRACE ((me, "invalid MMR %s at %#x length %u: %s",
	     rw, addr, nr_bytes, reason));

  /* XXX: is this what hardware does ?  What about priority of unaligned vs
     wrong length vs missing register ?  What about system-vs-core ?  */
  /* XXX: We should move this addr check to a model property so we get the
     same behavior regardless of where we map the model.  */
  if (addr >= BFIN_CORE_MMR_BASE)
    /* XXX: This should be setting up CPLB fault addrs ?  */
    mmu_process_fault (cpu, addr, write, false, false, true);
  else
    /* XXX: Newer parts set up an interrupt from EBIU and program
            EBIU_ERRADDR with the address.  */
    cec_hwerr (cpu, HWERR_SYSTEM_MMR);
}
static void
push_interrupt_level (struct hw *me,
		      struct mn103int *controller)
{
  int selected = find_highest_interrupt_group (me, controller);
  int level = controller->group[selected].level;
  HW_TRACE ((me, "port-out - selected=%d level=%d", selected, level));
  hw_port_event (me, LEVEL_PORT, level);
}
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.º 11
0
static void
do_counter_event (struct hw *me,
		  void *data)
{
  hw_pal_counter *counter = (hw_pal_counter *) data;
  if (counter->periodic_p)
    {
      HW_TRACE ((me, "timer expired"));
      counter->start = hw_event_queue_time (me);
      hw_port_event (me, TIMER_PORT, 1);
      hw_event_queue_schedule (me, counter->delta, do_counter_event, counter);
    }
  else
    {
      HW_TRACE ((me, "countdown expired"));
      counter->delta = 0;
      hw_port_event (me, COUNTDOWN_PORT, 1);
    }
}
static unsigned
m68hc11eepr_io_read_buffer (struct hw *me,
			    void *dest,
			    int space,
			    unsigned_word base,
			    unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11eepr *controller;
  sim_cpu *cpu;
  
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  sd         = hw_system (me);
  controller = hw_data (me);
  cpu        = STATE_CPU (sd, 0);

  if (space == io_map)
    {
      unsigned cnt = 0;
      
      while (nr_bytes != 0)
        {
          switch (base)
            {
            case M6811_PPROG:
            case M6811_CONFIG:
              *((uint8*) dest) = cpu->ios[base];
              break;

            default:
              hw_abort (me, "reading wrong register 0x%04x", base);
            }
          dest = (uint8*) (dest) + 1;
          base++;
          nr_bytes--;
          cnt++;
        }
      return cnt;
    }

  /* In theory, we can't read the EEPROM when it's being programmed.  */
  if ((cpu->ios[M6811_PPROG] & M6811_EELAT) != 0
      && cpu_is_running (cpu))
    {
      sim_memory_error (cpu, SIM_SIGBUS, base,
			"EEprom not configured for reading");
    }

  base = base - controller->base_address;
  memcpy (dest, &controller->eeprom[base], nr_bytes);
  return nr_bytes;
}
Exemplo n.º 13
0
static void
mn103cpu_port_event (struct hw *me,
		     int my_port,
		     struct hw *source,
		     int source_port,
		     int level)
{
  struct mn103cpu *controller = hw_data (me);

  /* Schedule our event handler *now* */
  if (controller->pending_handler == NULL)
    controller->pending_handler =
      hw_event_queue_schedule (me, 0, deliver_mn103cpu_interrupt, NULL);

  switch (my_port)
    {
      
    case RESET_PORT:
      controller->pending_reset = 1;
      HW_TRACE ((me, "port-in reset"));
      break;
      
    case NMI_PORT:
      controller->pending_nmi = 1;
      HW_TRACE ((me, "port-in nmi"));
      break;
      
    case LEVEL_PORT:
      controller->pending_level = level;
      HW_TRACE ((me, "port-in level=%d", level));
      break;
      
    default:
      hw_abort (me, "bad switch");
      break;

    }
}
static unsigned
tx3904sio_io_read_buffer (struct hw *me,
			 void *dest,
			 int space,
			 unsigned_word base,
			 unsigned nr_bytes)
{
  struct tx3904sio *controller = hw_data (me);
  unsigned byte;

  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  /* tickle fifos */
  tx3904sio_tickle(me);

  for (byte = 0; byte < nr_bytes; byte++)
    {
      address_word address = base + byte;
      int reg_number = (address - controller->base_address) / 4;
      int reg_offset = (address - controller->base_address) % 4;
      unsigned_4 register_value; /* in target byte order */

      /* fill in entire register_value word */
      switch (reg_number)
	{
	case SLCR_REG: register_value = controller->slcr; break;
	case SLSR_REG: register_value = controller->slsr; break;
	case SDICR_REG: register_value = controller->sdicr; break;
	case SDISR_REG: register_value = controller->sdisr; break;
	case SFCR_REG: register_value = controller->sfcr; break;
	case SBGR_REG: register_value = controller->sbgr; break;
	case TFIFO_REG: register_value = 0; break;
	case SFIFO_REG:
	  /* consume rx fifo for MS byte */
	  if(reg_offset == 0 && tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
	    register_value = (tx3904sio_fifo_pop(me, & controller->rx_fifo) << 24);
	  else
	    register_value = 0;
	  break;
	default: register_value = 0;
	}

      /* write requested byte out */
      register_value = H2T_4(register_value);
      /* HW_TRACE ((me, "byte %d %02x", reg_offset, ((char*)& register_value)[reg_offset])); */
      memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
    }

  return nr_bytes;
}     
Exemplo n.º 15
0
static void
do_counter_read (struct hw *me,
		 hw_pal_device *pal,
		 const char *reg,
		 hw_pal_counter *counter,
		 unsigned32 *word,
		 unsigned nr_bytes)
{
  unsigned32 val;
  if (nr_bytes != 4)
    hw_abort (me, "%s - bad read size must be 4 bytes", reg);
  val = counter->delta;
  HW_TRACE ((me, "read - %s %ld", reg, (long) val));
  *word = H2BE_4 (val);
}
Exemplo n.º 16
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.º 17
0
static unsigned
m68hc11tim_io_read_buffer (struct hw *me,
                           void *dest,
                           int space,
                           unsigned_word base,
                           unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11tim *controller;
  sim_cpu *cpu;
  unsigned8 val;
  unsigned cnt = 0;
  
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  sd  = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);

  while (nr_bytes)
    {
      switch (base)
        {
          /* The cpu_absolute_cycle is updated after each instruction.
             Reading in a 16-bit register will be split in two accesses
             but this will be atomic within the simulator.  */
        case M6811_TCTN_H:
          val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
                         / (controller->clock_prescaler * 256));
          break;

        case M6811_TCTN_L:
          val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
                         / controller->clock_prescaler);
          break;

        default:
          val = cpu->ios[base];
          break;
        }
      *((unsigned8*) dest) = val;
      dest = (char*) dest + 1;
      base++;
      nr_bytes--;
      cnt++;
    }
  return cnt;
}
static unsigned8
read_extmd (struct hw *me,
	    struct mn103int *controller,
	    unsigned_word offset)
{
  int gid;
  unsigned8 val = 0;
  struct mn103int_group *group = external_group (controller, offset);
  if (group != NULL)
    {
      for (gid = 0; gid < 4; gid++)
	{
	  val |= (group[gid].trigger << (gid * 2));
	}
    }
  HW_TRACE ((me, "read-extmd 0x%02lx", (long) val));
  return val;
}
static void
write_extmd (struct hw *me,
	     struct mn103int *controller,
	     unsigned_word offset,
	     unsigned8 val)
{
  int gid;
  struct mn103int_group *group = external_group (controller, offset);
  if (group != NULL)
    {
      for (gid = 0; gid < 4; gid++)
	{
	  group[gid].trigger = (val >> (gid * 2)) & 0x3;
	  /* MAYBE: interrupts already pending? */
	}
    }
  HW_TRACE ((me, "write-extmd 0x%02lx", (long) val));
}
Exemplo n.º 20
0
static unsigned
m68hc11sio_io_read_buffer (struct hw *me,
                           void *dest,
                           int space,
                           unsigned_word base,
                           unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11sio *controller;
  sim_cpu *cpu;
  unsigned8 val;
  
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  sd  = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);

  switch (base)
    {
    case M6811_SCSR:
      controller->rx_clear_scsr = cpu->ios[M6811_SCSR]
        & (M6811_RDRF | M6811_IDLE | M6811_OR | M6811_NF | M6811_FE);
      
    case M6811_BAUD:
    case M6811_SCCR1:
    case M6811_SCCR2:
      val = cpu->ios[base];
      break;
      
    case M6811_SCDR:
      if (controller->rx_clear_scsr)
        {
          cpu->ios[M6811_SCSR] &= ~controller->rx_clear_scsr;
        }
      val = controller->rx_char;
      break;
      
    default:
      return 0;
    }
  *((unsigned8*) dest) = val;
  return 1;
}
Exemplo n.º 21
0
static unsigned
m68hc11spi_io_read_buffer (struct hw *me,
                           void *dest,
                           int space,
                           unsigned_word base,
                           unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11spi *controller;
  sim_cpu *cpu;
  unsigned8 val;
  
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  sd  = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);

  switch (base)
    {
    case M6811_SPSR:
      controller->rx_clear_scsr = cpu->ios[M6811_SCSR]
        & (M6811_SPIF | M6811_WCOL | M6811_MODF);
      
    case M6811_SPCR:
      val = cpu->ios[base];
      break;
      
    case M6811_SPDR:
      if (controller->rx_clear_scsr)
        {
          cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
          controller->rx_clear_scsr = 0;
          interrupts_update_pending (&cpu->cpu_interrupts);
        }
      val = controller->rx_char;
      break;
      
    default:
      return 0;
    }
  *((unsigned8*) dest) = val;
  return 1;
}
Exemplo n.º 22
0
static void
do_counter_value (struct hw *me,
		  hw_pal_device *pal,
		  const char *reg,
		  hw_pal_counter *counter,
		  unsigned32 *word,
		  unsigned nr_bytes)
{
  unsigned32 val;
  if (nr_bytes != 4)
    hw_abort (me, "%s - bad read size must be 4 bytes", reg);
  if (counter->delta != 0)
    val = (counter->start + counter->delta
	   - hw_event_queue_time (me));
  else
    val = 0;
  HW_TRACE ((me, "read - %s %ld", reg, (long) val));
  *word = H2BE_4 (val);
}
Exemplo n.º 23
0
static unsigned
tx3904irc_io_write_buffer (struct hw *me,
			  const void *source,
			  int space,
			  unsigned_word base,
			  unsigned nr_bytes)
{
  struct tx3904irc *controller = hw_data (me);
  unsigned byte;

  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
  for (byte = 0; byte < nr_bytes; byte++)
    {
      address_word address = base + byte;
      int reg_number = (address - controller->base_address) / 4;
      int reg_offset = (address - controller->base_address) % 4;
      unsigned_4* register_ptr;
      unsigned_4 register_value;

      /* fill in entire register_value word */
      switch (reg_number)
	{
	case ISR_REG: register_ptr = & controller->isr; break;
	case IMR_REG: register_ptr = & controller->imr; break;
	case ILR0_REG: register_ptr = & controller->ilr[0]; break;
	case ILR1_REG: register_ptr = & controller->ilr[1]; break;
	case ILR2_REG: register_ptr = & controller->ilr[2]; break;
	case ILR3_REG: register_ptr = & controller->ilr[3]; break;
	default: register_ptr = & register_value; /* used as a dummy */
	}

      /* HW_TRACE ((me, "reg %d pre: %08lx", reg_number, (long) *register_ptr)); */

      /* overwrite requested byte */
      register_value = H2T_4(* register_ptr);
      memcpy (((char*)&register_value)+reg_offset, (const char*)source + byte, 1);
      * register_ptr = T2H_4(register_value);

      /* HW_TRACE ((me, "post: %08lx", (long) *register_ptr)); */
    }
  return nr_bytes;
}     
static unsigned
nvram_io_read_buffer (struct hw *me,
                      void *dest,
                      int space,
                      unsigned_word base,
                      unsigned nr_bytes)
{
  struct nvram *controller = hw_data (me);
  
  HW_TRACE ((me, "read 0x%08lx %d [%ld]",
             (long) base, (int) nr_bytes,
             (long) (base - controller->base_address)));

  base -= controller->base_address;
  if (base + nr_bytes > controller->size)
    nr_bytes = controller->size - base;
  
  memcpy (dest, &controller->data[base], nr_bytes);
  return nr_bytes;
}
Exemplo n.º 25
0
static void
do_counter_write (struct hw *me,
		  hw_pal_device *pal,
		  const char *reg,
		  hw_pal_counter *counter,
		  const unsigned32 *word,
		  unsigned nr_bytes)
{
  if (nr_bytes != 4)
    hw_abort (me, "%s - bad write size must be 4 bytes", reg);
  if (counter->handler != NULL)
    {
      hw_event_queue_deschedule (me, counter->handler);
      counter->handler = NULL;
    }
  counter->delta = BE2H_4 (*word);
  counter->start = hw_event_queue_time (me);
  HW_TRACE ((me, "write - %s %ld", reg, (long) counter->delta));
  if (counter->delta > 0)
    hw_event_queue_schedule (me, counter->delta, do_counter_event, counter);
}
Exemplo n.º 26
0
static void
m68hc11spi_port_event (struct hw *me,
                       int my_port,
                       struct hw *source,
                       int source_port,
                       int level)
{
  SIM_DESC sd;
  struct m68hc11spi *controller;
  sim_cpu* cpu;
  unsigned8 val;
  
  controller = hw_data (me);
  sd         = hw_system (me);
  cpu        = STATE_CPU (sd, 0);  
  switch (my_port)
    {
    case RESET_PORT:
      {
	HW_TRACE ((me, "SPI reset"));

        /* Reset the state of SPI registers.  */
        controller->rx_clear_scsr = 0;
        if (controller->spi_event)
          {
            hw_event_queue_deschedule (me, controller->spi_event);
            controller->spi_event = 0;
          }

        val = 0;
        m68hc11spi_io_write_buffer (me, &val, io_map,
                                    (unsigned_word) M6811_SPCR, 1);
        break;
      }

    default:
      hw_abort (me, "Event on unknown port %d", my_port);
      break;
    }
}
Exemplo n.º 27
0
static unsigned
mn103tim_io_read_buffer (struct hw *me,
			 void *dest,
			 int space,
			 unsigned_word base,
			 unsigned nr_bytes)
{
  struct mn103tim *timers = hw_data (me);
  enum timer_register_types timer_reg;

  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  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 >= FIRST_MODE_REG && timer_reg <= LAST_MODE_REG )
    {
      read_mode_reg(me, timers, timer_reg-FIRST_MODE_REG, dest, nr_bytes);
    }
  else if ( timer_reg <= LAST_BASE_REG )
    {
      read_base_reg(me, timers, timer_reg-FIRST_BASE_REG, dest, nr_bytes);
    }
  else if ( timer_reg <= LAST_COUNTER )
    {
      read_counter(me, timers, timer_reg-FIRST_COUNTER, dest, nr_bytes);
    }
  else if ( timer_reg <= LAST_TIMER_REG )
    {
      read_special_timer6_reg(me, timers, timer_reg, dest, nr_bytes);
    }
  else
    {
      hw_abort(me, "invalid timer register address.");
    }

  return nr_bytes;
}     
Exemplo n.º 28
0
static unsigned
tx3904tmr_io_read_buffer (struct hw *me,
			 void *dest,
			 int space,
			 unsigned_word base,
			 unsigned nr_bytes)
{
  struct tx3904tmr *controller = hw_data (me);
  unsigned byte;

  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
  for (byte = 0; byte < nr_bytes; byte++)
    {
      address_word address = base + byte;
      int reg_number = (address - controller->base_address) / 4;
      int reg_offset = 3 - (address - controller->base_address) % 4;
      unsigned_4 register_value; /* in target byte order */

      /* fill in entire register_value word */
      switch (reg_number)
	{
	case TCR_REG: register_value = controller->tcr; break;
	case TISR_REG: register_value = controller->tisr; break;
	case CPRA_REG: register_value = controller->cpra; break;
	case CPRB_REG: register_value = controller->cprb; break;
	case ITMR_REG: register_value = controller->itmr; break;
	case CCDR_REG: register_value = controller->ccdr; break;
	case PMGR_REG: register_value = controller->pmgr; break;
	case WTMR_REG: register_value = controller->wtmr; break;
	case TRR_REG: register_value = controller->trr; break;
	default: register_value = 0;
	}

      /* write requested byte out */
      memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
    }

  return nr_bytes;
}     
Exemplo n.º 29
0
static void
tx3904tmr_port_event (struct hw *me,
		     int my_port,
		     struct hw *source,
		     int source_port,
		     int level)
{
  struct tx3904tmr *controller = hw_data (me);

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

	/* preset flip-flop to FFI value */
	controller->ff = GET_PMGR_FFI(controller);

	controller->tcr = 
	  controller->itmr =
	  controller->ccdr =
	  controller->pmgr = 
	  controller->wtmr =
	  controller->tisr = 
	  controller->trr = 0;
	controller->cpra = controller->cprb = 0x00FFFFFF;
	controller->last_ticks = controller->roundoff_ticks = 0;
	if(controller->event != NULL)
	  hw_event_queue_deschedule(me, controller->event);
	controller->event = NULL;
	break;
      }

    default:
      hw_abort (me, "Event on unknown port %d", my_port);
      break;
    }
}
Exemplo n.º 30
0
static void
dv_core_attach_address_callback (struct hw *me,
				 int level,
				 int space,
				 address_word addr,
				 address_word nr_bytes,
				 struct hw *client)
{
  HW_TRACE ((me, "attach - level=%d, space=%d, addr=0x%lx, nr_bytes=%ld, client=%s",
	     level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_path (client)));
  /* NOTE: At preset the space is assumed to be zero.  Perhaphs the
     space should be mapped onto something for instance: space0 -
     unified memory; space1 - IO memory; ... */
  sim_core_attach (hw_system (me),
		   NULL, /*cpu*/
		   level,
		   access_read_write_exec,
		   space, addr,
		   nr_bytes,
		   0, /* modulo */
		   client,
		   NULL);
}