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