Home | History | Annotate | Line # | Download | only in mn10300
      1   1.1  christos /*  This file is part of the program GDB, the GNU debugger.
      2   1.1  christos 
      3  1.11  christos     Copyright (C) 1998-2024 Free Software Foundation, Inc.
      4   1.1  christos     Contributed by Cygnus Solutions.
      5   1.1  christos 
      6   1.1  christos     This program is free software; you can redistribute it and/or modify
      7   1.1  christos     it under the terms of the GNU General Public License as published by
      8   1.1  christos     the Free Software Foundation; either version 3 of the License, or
      9   1.1  christos     (at your option) any later version.
     10   1.1  christos 
     11   1.1  christos     This program is distributed in the hope that it will be useful,
     12   1.1  christos     but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  christos     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1  christos     GNU General Public License for more details.
     15   1.1  christos 
     16   1.1  christos     You should have received a copy of the GNU General Public License
     17   1.1  christos     along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18   1.1  christos 
     19   1.1  christos     */
     20   1.1  christos 
     21  1.10  christos /* This must come before any other includes.  */
     22  1.10  christos #include "defs.h"
     23  1.10  christos 
     24   1.1  christos #include "sim-main.h"
     25   1.1  christos #include "hw-main.h"
     26   1.1  christos #include "dv-sockser.h"
     27   1.1  christos 
     28   1.1  christos 
     29   1.1  christos /* DEVICE
     30   1.1  christos 
     31   1.1  christos 
     32   1.1  christos    mn103ser - mn103002 serial devices 0, 1 and 2.
     33   1.1  christos 
     34   1.1  christos 
     35   1.1  christos    DESCRIPTION
     36   1.1  christos 
     37   1.1  christos    Implements the mn103002 serial interfaces as described in the
     38   1.1  christos    mn103002 user guide.
     39   1.1  christos 
     40   1.1  christos 
     41   1.1  christos    PROPERTIES
     42   1.1  christos 
     43   1.1  christos    reg = <serial-addr> <serial-size>
     44   1.1  christos 
     45   1.1  christos 
     46   1.1  christos    BUGS
     47   1.1  christos 
     48   1.1  christos    */
     49   1.1  christos 
     50   1.1  christos 
     51   1.1  christos /* The serial devices' registers' address block */
     52   1.1  christos 
     53   1.1  christos struct mn103ser_block {
     54   1.1  christos   unsigned_word base;
     55   1.1  christos   unsigned_word bound;
     56   1.1  christos };
     57   1.1  christos 
     58   1.1  christos 
     59   1.1  christos 
     60   1.1  christos enum serial_register_types {
     61   1.1  christos     SC0CTR,
     62   1.1  christos     SC1CTR,
     63   1.1  christos     SC2CTR,
     64   1.1  christos     SC0ICR,
     65   1.1  christos     SC1ICR,
     66   1.1  christos     SC2ICR,
     67   1.1  christos     SC0TXB,
     68   1.1  christos     SC1TXB,
     69   1.1  christos     SC2TXB,
     70   1.1  christos     SC0RXB,
     71   1.1  christos     SC1RXB,
     72   1.1  christos     SC2RXB,
     73   1.1  christos     SC0STR,
     74   1.1  christos     SC1STR,
     75   1.1  christos     SC2STR,
     76   1.1  christos     SC2TIM,
     77   1.1  christos };
     78   1.1  christos 
     79   1.1  christos 
     80   1.1  christos #define NR_SERIAL_DEVS  3
     81   1.1  christos #define SIO_STAT_RRDY 0x0010
     82   1.1  christos 
     83   1.1  christos typedef struct _mn10300_serial {
     84  1.10  christos   uint16_t status, control;
     85  1.10  christos   uint8_t  txb, rxb, intmode;
     86   1.1  christos   struct hw_event *event;
     87   1.1  christos } mn10300_serial;
     88   1.1  christos 
     89   1.1  christos 
     90   1.1  christos 
     91   1.1  christos struct mn103ser {
     92   1.1  christos   struct mn103ser_block block;
     93   1.1  christos   mn10300_serial device[NR_SERIAL_DEVS];
     94  1.10  christos   uint8_t      serial2_timer_reg;
     95   1.1  christos   do_hw_poll_read_method *reader;
     96   1.1  christos };
     97   1.1  christos 
     98   1.1  christos /* output port ID's */
     99   1.1  christos 
    100   1.1  christos /* for mn103002 */
    101   1.1  christos enum {
    102   1.1  christos   SERIAL0_RECEIVE,
    103   1.1  christos   SERIAL1_RECEIVE,
    104   1.1  christos   SERIAL2_RECEIVE,
    105   1.1  christos   SERIAL0_SEND,
    106   1.1  christos   SERIAL1_SEND,
    107   1.1  christos   SERIAL2_SEND,
    108   1.1  christos };
    109   1.1  christos 
    110   1.1  christos 
    111   1.1  christos static const struct hw_port_descriptor mn103ser_ports[] = {
    112   1.1  christos 
    113   1.1  christos   { "serial-0-receive",  SERIAL0_RECEIVE, 0, output_port, },
    114   1.1  christos   { "serial-1-receive",  SERIAL1_RECEIVE, 0, output_port, },
    115   1.1  christos   { "serial-2-receive",  SERIAL2_RECEIVE, 0, output_port, },
    116   1.1  christos   { "serial-0-transmit", SERIAL0_SEND, 0, output_port, },
    117   1.1  christos   { "serial-1-transmit", SERIAL1_SEND, 0, output_port, },
    118   1.1  christos   { "serial-2-transmit", SERIAL2_SEND, 0, output_port, },
    119   1.1  christos 
    120   1.1  christos   { NULL, },
    121   1.1  christos };
    122   1.1  christos 
    123   1.1  christos 
    124   1.1  christos 
    125   1.1  christos /* Finish off the partially created hw device.  Attach our local
    126   1.1  christos    callbacks.  Wire up our port names etc */
    127   1.1  christos 
    128   1.1  christos static hw_io_read_buffer_method mn103ser_io_read_buffer;
    129   1.1  christos static hw_io_write_buffer_method mn103ser_io_write_buffer;
    130   1.1  christos 
    131   1.1  christos static void
    132   1.1  christos attach_mn103ser_regs (struct hw *me,
    133   1.1  christos 		      struct mn103ser *serial)
    134   1.1  christos {
    135   1.1  christos   unsigned_word attach_address;
    136   1.1  christos   int attach_space;
    137   1.1  christos   unsigned attach_size;
    138   1.1  christos   reg_property_spec reg;
    139   1.1  christos 
    140   1.1  christos   if (hw_find_property (me, "reg") == NULL)
    141   1.1  christos     hw_abort (me, "Missing \"reg\" property");
    142   1.1  christos 
    143   1.1  christos   if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    144   1.1  christos     hw_abort (me, "\"reg\" property must contain three addr/size entries");
    145   1.1  christos   hw_unit_address_to_attach_address (hw_parent (me),
    146   1.1  christos 				     &reg.address,
    147   1.1  christos 				     &attach_space,
    148   1.1  christos 				     &attach_address,
    149   1.1  christos 				     me);
    150   1.1  christos   serial->block.base = attach_address;
    151   1.1  christos   hw_unit_size_to_attach_size (hw_parent (me),
    152   1.1  christos 			       &reg.size,
    153   1.1  christos 			       &attach_size, me);
    154   1.1  christos   serial->block.bound = attach_address + (attach_size - 1);
    155   1.1  christos   hw_attach_address (hw_parent (me),
    156   1.1  christos 		     0,
    157   1.1  christos 		     attach_space, attach_address, attach_size,
    158   1.1  christos 		     me);
    159   1.1  christos }
    160   1.1  christos 
    161   1.1  christos static void
    162   1.1  christos mn103ser_finish (struct hw *me)
    163   1.1  christos {
    164   1.1  christos   struct mn103ser *serial;
    165   1.1  christos   int i;
    166   1.1  christos 
    167   1.1  christos   serial = HW_ZALLOC (me, struct mn103ser);
    168   1.1  christos   set_hw_data (me, serial);
    169   1.1  christos   set_hw_io_read_buffer (me, mn103ser_io_read_buffer);
    170   1.1  christos   set_hw_io_write_buffer (me, mn103ser_io_write_buffer);
    171   1.1  christos   set_hw_ports (me, mn103ser_ports);
    172   1.1  christos 
    173   1.1  christos   /* Attach ourself to our parent bus */
    174   1.1  christos   attach_mn103ser_regs (me, serial);
    175   1.1  christos 
    176   1.1  christos   /* If so configured, enable polled input */
    177   1.1  christos   if (hw_find_property (me, "poll?") != NULL
    178   1.1  christos       && hw_find_boolean_property (me, "poll?"))
    179   1.1  christos     {
    180   1.1  christos       serial->reader = sim_io_poll_read;
    181   1.1  christos     }
    182   1.1  christos   else
    183   1.1  christos     {
    184   1.1  christos       serial->reader = sim_io_read;
    185   1.1  christos     }
    186   1.1  christos 
    187   1.1  christos   /* Initialize the serial device registers. */
    188   1.1  christos   for ( i=0; i<NR_SERIAL_DEVS; ++i )
    189   1.1  christos     {
    190   1.1  christos       serial->device[i].txb = 0;
    191   1.1  christos       serial->device[i].rxb = 0;
    192   1.1  christos       serial->device[i].status = 0;
    193   1.1  christos       serial->device[i].control = 0;
    194   1.1  christos       serial->device[i].intmode = 0;
    195   1.1  christos       serial->device[i].event = NULL;
    196   1.1  christos     }
    197   1.1  christos }
    198   1.1  christos 
    199   1.1  christos 
    200   1.1  christos /* read and write */
    201   1.1  christos 
    202   1.1  christos static int
    203   1.1  christos decode_addr (struct hw *me,
    204   1.1  christos 	     struct mn103ser *serial,
    205   1.1  christos 	     unsigned_word address)
    206   1.1  christos {
    207   1.1  christos   unsigned_word offset;
    208   1.1  christos   offset = address - serial->block.base;
    209   1.1  christos   switch (offset)
    210   1.1  christos     {
    211   1.1  christos     case 0x00: return SC0CTR;
    212   1.1  christos     case 0x04: return SC0ICR;
    213   1.1  christos     case 0x08: return SC0TXB;
    214   1.1  christos     case 0x09: return SC0RXB;
    215   1.1  christos     case 0x0C: return SC0STR;
    216   1.1  christos     case 0x10: return SC1CTR;
    217   1.1  christos     case 0x14: return SC1ICR;
    218   1.1  christos     case 0x18: return SC1TXB;
    219   1.1  christos     case 0x19: return SC1RXB;
    220   1.1  christos     case 0x1C: return SC1STR;
    221   1.1  christos     case 0x20: return SC2CTR;
    222   1.1  christos     case 0x24: return SC2ICR;
    223   1.1  christos     case 0x28: return SC2TXB;
    224   1.1  christos     case 0x29: return SC2RXB;
    225   1.1  christos     case 0x2C: return SC2STR;
    226   1.1  christos     case 0x2D: return SC2TIM;
    227   1.1  christos     default:
    228   1.1  christos       {
    229   1.1  christos 	hw_abort (me, "bad address");
    230   1.1  christos 	return -1;
    231   1.1  christos       }
    232   1.1  christos     }
    233   1.1  christos }
    234   1.1  christos 
    235   1.1  christos static void
    236   1.1  christos do_polling_event (struct hw *me,
    237   1.1  christos 		  void *data)
    238   1.1  christos {
    239   1.1  christos   SIM_DESC sd = hw_system (me);
    240   1.1  christos   struct mn103ser *serial = hw_data(me);
    241  1.10  christos   long serial_reg = (uintptr_t) data;
    242   1.1  christos   char c;
    243   1.1  christos   int count, status;
    244   1.1  christos 
    245   1.1  christos   status = dv_sockser_status (sd);
    246   1.1  christos   if (!(status & DV_SOCKSER_DISCONNECTED))
    247   1.1  christos     {
    248   1.1  christos       int rd;
    249   1.1  christos       rd = dv_sockser_read (sd);
    250   1.1  christos       if(rd != -1)
    251   1.1  christos 	{
    252   1.1  christos 	  c = (char) rd;
    253   1.1  christos 	  count = 1;
    254   1.1  christos 	}
    255   1.1  christos       else
    256   1.1  christos 	{
    257   1.1  christos 	  count = HW_IO_NOT_READY;
    258   1.1  christos 	}
    259   1.1  christos     }
    260   1.1  christos   else
    261   1.1  christos     {
    262   1.1  christos       count = do_hw_poll_read (me, serial->reader,
    263   1.1  christos 			       0/*STDIN*/, &c, sizeof(c));
    264   1.1  christos     }
    265   1.1  christos 
    266   1.1  christos 
    267   1.1  christos   switch (count)
    268   1.1  christos     {
    269   1.1  christos     case HW_IO_NOT_READY:
    270   1.1  christos     case HW_IO_EOF:
    271   1.1  christos       serial->device[serial_reg].rxb = 0;
    272   1.1  christos       serial->device[serial_reg].status &= ~SIO_STAT_RRDY;
    273   1.1  christos       break;
    274   1.1  christos     default:
    275   1.1  christos       serial->device[serial_reg].rxb = c;
    276   1.1  christos       serial->device[serial_reg].status |= SIO_STAT_RRDY;
    277   1.1  christos       hw_port_event (me, serial_reg+SERIAL0_RECEIVE, 1);
    278   1.1  christos     }
    279   1.1  christos 
    280   1.1  christos   /* Schedule next polling event */
    281   1.1  christos   serial->device[serial_reg].event
    282   1.1  christos     = hw_event_queue_schedule (me, 1000,
    283  1.10  christos 			       do_polling_event, (void *)(uintptr_t)serial_reg);
    284   1.1  christos 
    285   1.1  christos }
    286   1.1  christos 
    287   1.1  christos static void
    288   1.1  christos read_control_reg (struct hw *me,
    289   1.1  christos 		  struct mn103ser *serial,
    290   1.1  christos 		  unsigned_word serial_reg,
    291   1.1  christos 		  void *dest,
    292   1.1  christos 		  unsigned  nr_bytes)
    293   1.1  christos {
    294   1.1  christos   /* really allow 1 byte read, too */
    295   1.1  christos   if ( nr_bytes == 2 )
    296   1.1  christos     {
    297  1.10  christos       *(uint16_t *)dest = H2LE_2 (serial->device[serial_reg].control);
    298   1.1  christos     }
    299   1.1  christos   else
    300   1.1  christos     {
    301   1.1  christos       hw_abort (me, "bad read size of %d bytes from SC%dCTR.", nr_bytes,
    302   1.1  christos 		serial_reg);
    303   1.1  christos     }
    304   1.1  christos }
    305   1.1  christos 
    306   1.1  christos 
    307   1.1  christos static void
    308   1.1  christos read_intmode_reg (struct hw *me,
    309   1.1  christos 		  struct mn103ser *serial,
    310   1.1  christos 		  unsigned_word serial_reg,
    311   1.1  christos 		  void *dest,
    312   1.1  christos 		  unsigned  nr_bytes)
    313   1.1  christos {
    314   1.1  christos   if ( nr_bytes == 1 )
    315   1.1  christos     {
    316  1.10  christos       *(uint8_t *)dest = serial->device[serial_reg].intmode;
    317   1.1  christos     }
    318   1.1  christos   else
    319   1.1  christos     {
    320   1.1  christos       hw_abort (me, "bad read size of %d bytes from SC%dICR.", nr_bytes,
    321   1.1  christos 		serial_reg);
    322   1.1  christos     }
    323   1.1  christos }
    324   1.1  christos 
    325   1.1  christos 
    326   1.1  christos static void
    327   1.1  christos read_txb (struct hw *me,
    328   1.1  christos 	  struct mn103ser *serial,
    329   1.1  christos 	  unsigned_word serial_reg,
    330   1.1  christos 	  void *dest,
    331   1.1  christos 	  unsigned  nr_bytes)
    332   1.1  christos {
    333   1.1  christos   if ( nr_bytes == 1 )
    334   1.1  christos     {
    335  1.10  christos       *(uint8_t *)dest = serial->device[serial_reg].txb;
    336   1.1  christos     }
    337   1.1  christos   else
    338   1.1  christos     {
    339   1.1  christos       hw_abort (me, "bad read size of %d bytes from SC%dTXB.", nr_bytes,
    340   1.1  christos 		serial_reg);
    341   1.1  christos     }
    342   1.1  christos }
    343   1.1  christos 
    344   1.1  christos 
    345   1.1  christos static void
    346   1.1  christos read_rxb (struct hw *me,
    347   1.1  christos 	  struct mn103ser *serial,
    348   1.1  christos 	  unsigned_word serial_reg,
    349   1.1  christos 	  void *dest,
    350   1.1  christos 	  unsigned  nr_bytes)
    351   1.1  christos {
    352   1.1  christos   if ( nr_bytes == 1 )
    353   1.1  christos     {
    354  1.10  christos       *(uint8_t *)dest = serial->device[serial_reg].rxb;
    355   1.1  christos       /* Reception buffer is now empty. */
    356   1.1  christos       serial->device[serial_reg].status &= ~SIO_STAT_RRDY;
    357   1.1  christos     }
    358   1.1  christos   else
    359   1.1  christos     {
    360   1.1  christos       hw_abort (me, "bad read size of %d bytes from SC%dRXB.", nr_bytes,
    361   1.1  christos 		serial_reg);
    362   1.1  christos     }
    363   1.1  christos }
    364   1.1  christos 
    365   1.1  christos 
    366   1.1  christos static void
    367   1.1  christos read_status_reg (struct hw *me,
    368   1.1  christos 		 struct mn103ser *serial,
    369   1.1  christos 		 unsigned_word serial_reg,
    370   1.1  christos 		 void *dest,
    371   1.1  christos 		 unsigned  nr_bytes)
    372   1.1  christos {
    373   1.1  christos   char c;
    374   1.1  christos   int count;
    375   1.1  christos 
    376   1.1  christos   if ( (serial->device[serial_reg].status & SIO_STAT_RRDY) == 0 )
    377   1.1  christos     {
    378   1.1  christos       SIM_DESC sd = hw_system (me);
    379   1.1  christos       int status;
    380   1.1  christos 
    381   1.1  christos       /* FIFO is empty */
    382   1.1  christos       /* Kill current poll event */
    383   1.1  christos       if ( NULL != serial->device[serial_reg].event )
    384   1.1  christos 	{
    385   1.1  christos 	  hw_event_queue_deschedule (me, serial->device[serial_reg].event);
    386   1.1  christos 	  serial->device[serial_reg].event = NULL;
    387   1.1  christos 	}
    388   1.1  christos 
    389   1.1  christos       status = dv_sockser_status (sd);
    390   1.1  christos       if (!(status & DV_SOCKSER_DISCONNECTED))
    391   1.1  christos 	{
    392   1.1  christos 	  int rd;
    393   1.1  christos 	  rd = dv_sockser_read (sd);
    394   1.1  christos 	  if(rd != -1)
    395   1.1  christos 	    {
    396   1.1  christos 	      c = (char) rd;
    397   1.1  christos 	      count = 1;
    398   1.1  christos 	    }
    399   1.1  christos 	  else
    400   1.1  christos 	    {
    401   1.1  christos 	      count = HW_IO_NOT_READY;
    402   1.1  christos 	    }
    403   1.1  christos 	}
    404   1.1  christos       else
    405   1.1  christos 	{
    406   1.1  christos 	  count = do_hw_poll_read (me, serial->reader,
    407   1.1  christos 				   0/*STDIN*/, &c, sizeof(c));
    408   1.1  christos 	}
    409   1.1  christos 
    410   1.1  christos       switch (count)
    411   1.1  christos 	{
    412   1.1  christos 	case HW_IO_NOT_READY:
    413   1.1  christos 	case HW_IO_EOF:
    414   1.1  christos 	  serial->device[serial_reg].rxb = 0;
    415   1.1  christos 	  serial->device[serial_reg].status &= ~SIO_STAT_RRDY;
    416   1.1  christos 	  break;
    417   1.1  christos 	default:
    418   1.1  christos 	  serial->device[serial_reg].rxb = c;
    419   1.1  christos 	  serial->device[serial_reg].status |= SIO_STAT_RRDY;
    420   1.1  christos 	  hw_port_event (me, serial_reg+SERIAL0_RECEIVE, 1);
    421   1.1  christos 	}
    422   1.1  christos 
    423   1.1  christos       /* schedule polling event */
    424   1.1  christos       serial->device[serial_reg].event
    425   1.1  christos 	= hw_event_queue_schedule (me, 1000,
    426   1.1  christos 				   do_polling_event,
    427  1.10  christos 				   (void *)(uintptr_t)serial_reg);
    428   1.1  christos     }
    429   1.1  christos 
    430   1.1  christos   if ( nr_bytes == 1 )
    431   1.1  christos     {
    432  1.10  christos       *(uint8_t *)dest = (uint8_t)serial->device[serial_reg].status;
    433   1.1  christos     }
    434   1.1  christos   else if ( nr_bytes == 2 && serial_reg != SC2STR )
    435   1.1  christos     {
    436  1.10  christos       *(uint16_t *)dest = H2LE_2 (serial->device[serial_reg].status);
    437   1.1  christos     }
    438   1.1  christos   else
    439   1.1  christos     {
    440   1.1  christos       hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes,
    441   1.1  christos 		serial_reg);
    442   1.1  christos     }
    443   1.1  christos }
    444   1.1  christos 
    445   1.1  christos 
    446   1.1  christos static void
    447   1.1  christos read_serial2_timer_reg (struct hw *me,
    448   1.1  christos 			struct mn103ser *serial,
    449   1.1  christos 			void *dest,
    450   1.1  christos 			unsigned  nr_bytes)
    451   1.1  christos {
    452   1.1  christos   if ( nr_bytes == 1 )
    453   1.1  christos     {
    454  1.10  christos       * (uint8_t *) dest = (uint8_t) serial->serial2_timer_reg;
    455   1.1  christos     }
    456   1.1  christos   else
    457   1.1  christos     {
    458   1.1  christos       hw_abort (me, "bad read size of %d bytes to SC2TIM.", nr_bytes);
    459   1.1  christos     }
    460   1.1  christos }
    461   1.1  christos 
    462   1.1  christos 
    463   1.1  christos static unsigned
    464   1.1  christos mn103ser_io_read_buffer (struct hw *me,
    465   1.1  christos 			 void *dest,
    466   1.1  christos 			 int space,
    467   1.1  christos 			 unsigned_word base,
    468   1.1  christos 			 unsigned nr_bytes)
    469   1.1  christos {
    470   1.1  christos   struct mn103ser *serial = hw_data (me);
    471   1.1  christos   enum serial_register_types serial_reg;
    472   1.1  christos   HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
    473   1.1  christos 
    474   1.1  christos   serial_reg = decode_addr (me, serial, base);
    475   1.1  christos   switch (serial_reg)
    476   1.1  christos     {
    477   1.1  christos     /* control registers */
    478   1.1  christos     case SC0CTR:
    479   1.1  christos     case SC1CTR:
    480   1.1  christos     case SC2CTR:
    481   1.1  christos       read_control_reg(me, serial, serial_reg-SC0CTR, dest, nr_bytes);
    482   1.1  christos       HW_TRACE ((me, "read - ctrl reg%d has 0x%x\n", serial_reg-SC0CTR,
    483  1.10  christos 		 *(uint8_t *)dest));
    484   1.1  christos       break;
    485   1.1  christos 
    486   1.1  christos     /* interrupt mode registers */
    487   1.1  christos     case SC0ICR:
    488   1.1  christos     case SC1ICR:
    489   1.1  christos     case SC2ICR:
    490   1.1  christos       read_intmode_reg(me, serial, serial_reg-SC0ICR, dest, nr_bytes);
    491   1.1  christos       HW_TRACE ((me, "read - intmode reg%d has 0x%x\n", serial_reg-SC0ICR,
    492  1.10  christos 		 *(uint8_t *)dest));
    493   1.1  christos       break;
    494   1.1  christos 
    495   1.1  christos     /* transmission buffers */
    496   1.1  christos     case SC0TXB:
    497   1.1  christos     case SC1TXB:
    498   1.1  christos     case SC2TXB:
    499   1.1  christos       read_txb(me, serial, serial_reg-SC0TXB, dest, nr_bytes);
    500   1.1  christos       HW_TRACE ((me, "read - txb%d has %c\n", serial_reg-SC0TXB,
    501   1.1  christos 		 *(char *)dest));
    502   1.1  christos       break;
    503   1.1  christos 
    504   1.1  christos     /* reception buffers */
    505   1.1  christos     case SC0RXB:
    506   1.1  christos     case SC1RXB:
    507   1.1  christos     case SC2RXB:
    508   1.1  christos       read_rxb(me, serial, serial_reg-SC0RXB, dest, nr_bytes);
    509   1.1  christos       HW_TRACE ((me, "read - rxb%d has %c\n", serial_reg-SC0RXB,
    510   1.1  christos 		 *(char *)dest));
    511   1.1  christos      break;
    512   1.1  christos 
    513   1.1  christos     /* status registers */
    514   1.1  christos     case SC0STR:
    515   1.1  christos     case SC1STR:
    516   1.1  christos     case SC2STR:
    517   1.1  christos       read_status_reg(me, serial, serial_reg-SC0STR, dest, nr_bytes);
    518   1.1  christos       HW_TRACE ((me, "read - status reg%d has 0x%x\n", serial_reg-SC0STR,
    519  1.10  christos 		 *(uint8_t *)dest));
    520   1.1  christos       break;
    521   1.1  christos 
    522   1.1  christos     case SC2TIM:
    523   1.1  christos       read_serial2_timer_reg(me, serial, dest, nr_bytes);
    524  1.10  christos       HW_TRACE ((me, "read - serial2 timer reg %d\n", *(uint8_t *)dest));
    525   1.1  christos       break;
    526   1.1  christos 
    527   1.1  christos     default:
    528   1.1  christos       hw_abort(me, "invalid address");
    529   1.1  christos     }
    530   1.1  christos 
    531   1.1  christos   return nr_bytes;
    532   1.1  christos }
    533   1.1  christos 
    534   1.1  christos 
    535   1.1  christos static void
    536   1.1  christos write_control_reg (struct hw *me,
    537   1.1  christos 		   struct mn103ser *serial,
    538   1.1  christos 		   unsigned_word serial_reg,
    539   1.1  christos 		   const void *source,
    540   1.1  christos 		   unsigned  nr_bytes)
    541   1.1  christos {
    542  1.10  christos   uint16_t val = LE2H_2 (*(uint16_t *)source);
    543   1.1  christos 
    544   1.1  christos   /* really allow 1 byte write, too */
    545   1.1  christos   if ( nr_bytes == 2 )
    546   1.1  christos     {
    547   1.1  christos       if ( serial_reg == 2 && (val & 0x0C04) != 0 )
    548   1.1  christos 	{
    549   1.1  christos 	  hw_abort(me, "Cannot write to read-only bits of SC2CTR.");
    550   1.1  christos 	}
    551   1.1  christos       else
    552   1.1  christos 	{
    553   1.1  christos 	  serial->device[serial_reg].control = val;
    554   1.1  christos 	}
    555   1.1  christos     }
    556   1.1  christos   else
    557   1.1  christos     {
    558   1.1  christos       hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes,
    559   1.1  christos 		serial_reg);
    560   1.1  christos     }
    561   1.1  christos }
    562   1.1  christos 
    563   1.1  christos 
    564   1.1  christos static void
    565   1.1  christos write_intmode_reg (struct hw *me,
    566   1.1  christos 		   struct mn103ser *serial,
    567   1.1  christos 		   unsigned_word serial_reg,
    568   1.1  christos 		   const void *source,
    569   1.1  christos 		   unsigned  nr_bytes)
    570   1.1  christos {
    571  1.10  christos uint8_t val = *(uint8_t *)source;
    572   1.1  christos 
    573   1.1  christos   if ( nr_bytes == 1 )
    574   1.1  christos     {
    575   1.1  christos       /* Check for attempt to write to read-only bits of register. */
    576   1.1  christos       if ( ( serial_reg == 2 && (val & 0xCA) != 0 )
    577   1.1  christos 	   || ( serial_reg != 2 && (val & 0x4A) != 0 ) )
    578   1.1  christos 	{
    579   1.1  christos 	  hw_abort(me, "Cannot write to read-only bits of SC%dICR.",
    580   1.1  christos 		   serial_reg);
    581   1.1  christos 	}
    582   1.1  christos       else
    583   1.1  christos 	{
    584   1.1  christos 	  serial->device[serial_reg].intmode = val;
    585   1.1  christos 	}
    586   1.1  christos     }
    587   1.1  christos   else
    588   1.1  christos     {
    589   1.1  christos       hw_abort (me, "bad write size of %d bytes to SC%dICR.", nr_bytes,
    590   1.1  christos 		serial_reg);
    591   1.1  christos     }
    592   1.1  christos }
    593   1.1  christos 
    594   1.1  christos 
    595   1.1  christos static void
    596   1.1  christos write_txb (struct hw *me,
    597   1.1  christos 	   struct mn103ser *serial,
    598   1.1  christos 	   unsigned_word serial_reg,
    599   1.1  christos 	   const void *source,
    600   1.1  christos 	   unsigned  nr_bytes)
    601   1.1  christos {
    602   1.1  christos   if ( nr_bytes == 1 )
    603   1.1  christos     {
    604   1.1  christos       SIM_DESC sd = hw_system (me);
    605   1.1  christos       int status;
    606   1.1  christos 
    607  1.10  christos       serial->device[serial_reg].txb = *(uint8_t *)source;
    608   1.1  christos 
    609   1.1  christos       status = dv_sockser_status (sd);
    610   1.1  christos       if (!(status & DV_SOCKSER_DISCONNECTED))
    611   1.1  christos 	{
    612   1.1  christos 	  dv_sockser_write(sd, * (char*) source);
    613   1.1  christos 	}
    614   1.1  christos       else
    615   1.1  christos 	{
    616   1.1  christos 	  sim_io_write_stdout(sd, (char *)source, 1);
    617   1.1  christos 	  sim_io_flush_stdout(sd);
    618   1.1  christos 	}
    619   1.1  christos 
    620   1.1  christos       hw_port_event (me, serial_reg+SERIAL0_SEND, 1);
    621   1.1  christos     }
    622   1.1  christos   else
    623   1.1  christos     {
    624   1.1  christos       hw_abort (me, "bad write size of %d bytes to SC%dTXB.", nr_bytes,
    625   1.1  christos 		serial_reg);
    626   1.1  christos     }
    627   1.1  christos }
    628   1.1  christos 
    629   1.1  christos 
    630   1.1  christos static void
    631   1.1  christos write_serial2_timer_reg (struct hw *me,
    632   1.1  christos 			 struct mn103ser *serial,
    633   1.1  christos 			 const void *source,
    634   1.1  christos 			 unsigned  nr_bytes)
    635   1.1  christos {
    636   1.1  christos   if ( nr_bytes == 1 )
    637   1.1  christos     {
    638  1.10  christos       serial->serial2_timer_reg = *(uint8_t *)source;
    639   1.1  christos     }
    640   1.1  christos   else
    641   1.1  christos     {
    642   1.1  christos       hw_abort (me, "bad write size of %d bytes to SC2TIM.", nr_bytes);
    643   1.1  christos     }
    644   1.1  christos }
    645   1.1  christos 
    646   1.1  christos 
    647   1.1  christos static unsigned
    648   1.1  christos mn103ser_io_write_buffer (struct hw *me,
    649   1.1  christos 			  const void *source,
    650   1.1  christos 			  int space,
    651   1.1  christos 			  unsigned_word base,
    652   1.1  christos 			  unsigned nr_bytes)
    653   1.1  christos {
    654   1.1  christos   struct mn103ser *serial = hw_data (me);
    655   1.1  christos   enum serial_register_types serial_reg;
    656   1.1  christos   HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
    657   1.1  christos 
    658   1.1  christos   serial_reg = decode_addr (me, serial, base);
    659   1.1  christos   switch (serial_reg)
    660   1.1  christos     {
    661   1.1  christos     /* control registers */
    662   1.1  christos     case SC0CTR:
    663   1.1  christos     case SC1CTR:
    664   1.1  christos     case SC2CTR:
    665   1.1  christos       HW_TRACE ((me, "write - ctrl reg%d has 0x%x, nrbytes=%d.\n",
    666  1.10  christos 		 serial_reg-SC0CTR, *(uint8_t *)source, nr_bytes));
    667   1.1  christos       write_control_reg(me, serial, serial_reg-SC0CTR, source, nr_bytes);
    668   1.1  christos       break;
    669   1.1  christos 
    670   1.1  christos     /* interrupt mode registers */
    671   1.1  christos     case SC0ICR:
    672   1.1  christos     case SC1ICR:
    673   1.1  christos     case SC2ICR:
    674   1.1  christos       HW_TRACE ((me, "write - intmode reg%d has 0x%x, nrbytes=%d.\n",
    675  1.10  christos 		 serial_reg-SC0ICR, *(uint8_t *)source, nr_bytes));
    676   1.1  christos       write_intmode_reg(me, serial, serial_reg-SC0ICR, source, nr_bytes);
    677   1.1  christos       break;
    678   1.1  christos 
    679   1.1  christos     /* transmission buffers */
    680   1.1  christos     case SC0TXB:
    681   1.1  christos     case SC1TXB:
    682   1.1  christos     case SC2TXB:
    683   1.1  christos       HW_TRACE ((me, "write - txb%d has %c, nrbytes=%d.\n",
    684   1.1  christos 		 serial_reg-SC0TXB, *(char *)source, nr_bytes));
    685   1.1  christos       write_txb(me, serial, serial_reg-SC0TXB, source, nr_bytes);
    686   1.1  christos       break;
    687   1.1  christos 
    688   1.1  christos     /* reception buffers */
    689   1.1  christos     case SC0RXB:
    690   1.1  christos     case SC1RXB:
    691   1.1  christos     case SC2RXB:
    692   1.1  christos       hw_abort(me, "Cannot write to reception buffer.");
    693   1.1  christos      break;
    694   1.1  christos 
    695   1.1  christos     /* status registers */
    696   1.1  christos     case SC0STR:
    697   1.1  christos     case SC1STR:
    698   1.1  christos     case SC2STR:
    699   1.1  christos       hw_abort(me, "Cannot write to status register.");
    700   1.1  christos       break;
    701   1.1  christos 
    702   1.1  christos     case SC2TIM:
    703   1.1  christos       HW_TRACE ((me, "read - serial2 timer reg %d (nrbytes=%d)\n",
    704  1.10  christos 		 *(uint8_t *)source, nr_bytes));
    705   1.1  christos       write_serial2_timer_reg(me, serial, source, nr_bytes);
    706   1.1  christos       break;
    707   1.1  christos 
    708   1.1  christos     default:
    709   1.1  christos       hw_abort(me, "invalid address");
    710   1.1  christos     }
    711   1.1  christos 
    712   1.1  christos   return nr_bytes;
    713   1.1  christos }
    714   1.1  christos 
    715   1.1  christos 
    716   1.1  christos const struct hw_descriptor dv_mn103ser_descriptor[] = {
    717   1.1  christos   { "mn103ser", mn103ser_finish, },
    718   1.1  christos   { NULL },
    719   1.1  christos };
    720