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