1/*  This file is part of the program GDB, the GNU debugger.
2
3    Copyright (C) 1998, 2007 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
24/* DEVICE
25
26
27   mn103iop - mn103002 I/O ports 0-3.
28
29
30   DESCRIPTION
31
32   Implements the mn103002 i/o ports as described in the mn103002 user guide.
33
34
35   PROPERTIES
36
37   reg = <ioport-addr> <ioport-size> ...
38
39
40   BUGS
41
42   */
43
44
45/* The I/O ports' registers' address block */
46
47struct mn103iop_block {
48  unsigned_word base;
49  unsigned_word bound;
50};
51
52
53
54enum io_port_register_types {
55  P0OUT,
56  P1OUT,
57  P2OUT,
58  P3OUT,
59  P0MD,
60  P1MD,
61  P2MD,
62  P3MD,
63  P2SS,
64  P4SS,
65  P0DIR,
66  P1DIR,
67  P2DIR,
68  P3DIR,
69  P0IN,
70  P1IN,
71  P2IN,
72  P3IN,
73};
74
75#define NR_PORTS  4
76
77enum {
78  OUTPUT_BLOCK,
79  MODE_BLOCK,
80  DED_CTRL_BLOCK,
81  CTRL_BLOCK,
82  PIN_BLOCK,
83  NR_BLOCKS
84};
85
86typedef struct _mn10300_ioport {
87  unsigned8 output, output_mode, control, pin;
88  struct hw_event *event;
89} mn10300_ioport;
90
91
92
93struct mn103iop {
94  struct mn103iop_block block[NR_BLOCKS];
95  mn10300_ioport port[NR_PORTS];
96  unsigned8      p2ss, p4ss;
97};
98
99
100/* Finish off the partially created hw device.  Attach our local
101   callbacks.  Wire up our port names etc */
102
103static hw_io_read_buffer_method mn103iop_io_read_buffer;
104static hw_io_write_buffer_method mn103iop_io_write_buffer;
105
106static void
107attach_mn103iop_regs (struct hw *me,
108		      struct mn103iop *io_port)
109{
110  int i;
111  unsigned_word attach_address;
112  int attach_space;
113  unsigned attach_size;
114  reg_property_spec reg;
115
116  if (hw_find_property (me, "reg") == NULL)
117    hw_abort (me, "Missing \"reg\" property");
118
119  for (i=0; i < NR_BLOCKS; ++i )
120    {
121      if (!hw_find_reg_array_property (me, "reg", i, &reg))
122	hw_abort (me, "\"reg\" property must contain five addr/size entries");
123      hw_unit_address_to_attach_address (hw_parent (me),
124					 &reg.address,
125					 &attach_space,
126					 &attach_address,
127					 me);
128      io_port->block[i].base = attach_address;
129      hw_unit_size_to_attach_size (hw_parent (me),
130				   &reg.size,
131				   &attach_size, me);
132      io_port->block[i].bound = attach_address + (attach_size - 1);
133      hw_attach_address (hw_parent (me),
134			 0,
135			 attach_space, attach_address, attach_size,
136			 me);
137    }
138}
139
140static void
141mn103iop_finish (struct hw *me)
142{
143  struct mn103iop *io_port;
144  int i;
145
146  io_port = HW_ZALLOC (me, struct mn103iop);
147  set_hw_data (me, io_port);
148  set_hw_io_read_buffer (me, mn103iop_io_read_buffer);
149  set_hw_io_write_buffer (me, mn103iop_io_write_buffer);
150
151  /* Attach ourself to our parent bus */
152  attach_mn103iop_regs (me, io_port);
153
154  /* Initialize the i/o port registers. */
155  for ( i=0; i<NR_PORTS; ++i )
156    {
157      io_port->port[i].output = 0;
158      io_port->port[i].output_mode = 0;
159      io_port->port[i].control = 0;
160      io_port->port[i].pin = 0;
161    }
162  io_port->port[2].output_mode = 0xff;
163  io_port->p2ss = 0;
164  io_port->p4ss = 0x0f;
165}
166
167
168/* read and write */
169
170static int
171decode_addr (struct hw *me,
172	     struct mn103iop *io_port,
173	     unsigned_word address)
174{
175  unsigned_word offset;
176  offset = address - io_port->block[0].base;
177  switch (offset)
178    {
179    case 0x00: return P0OUT;
180    case 0x01: return P1OUT;
181    case 0x04: return P2OUT;
182    case 0x05: return P3OUT;
183    case 0x20: return P0MD;
184    case 0x21: return P1MD;
185    case 0x24: return P2MD;
186    case 0x25: return P3MD;
187    case 0x44: return P2SS;
188    case 0x48: return P4SS;
189    case 0x60: return P0DIR;
190    case 0x61: return P1DIR;
191    case 0x64: return P2DIR;
192    case 0x65: return P3DIR;
193    case 0x80: return P0IN;
194    case 0x81: return P1IN;
195    case 0x84: return P2IN;
196    case 0x85: return P3IN;
197    default:
198      {
199	hw_abort (me, "bad address");
200	return -1;
201      }
202    }
203}
204
205
206static void
207read_output_reg (struct hw *me,
208		 struct mn103iop *io_port,
209		 unsigned_word io_port_reg,
210		 const void *dest,
211		 unsigned  nr_bytes)
212{
213  if ( nr_bytes == 1 )
214    {
215      *(unsigned8 *)dest = io_port->port[io_port_reg].output;
216    }
217  else
218    {
219      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes,
220		io_port_reg);
221    }
222}
223
224
225static void
226read_output_mode_reg (struct hw *me,
227		      struct mn103iop *io_port,
228		      unsigned_word io_port_reg,
229		      const void *dest,
230		      unsigned  nr_bytes)
231{
232  if ( nr_bytes == 1 )
233    {
234      /* check if there are fields which can't be written and
235	 take appropriate action depending what bits are set */
236      *(unsigned8 *)dest = io_port->port[io_port_reg].output_mode;
237    }
238  else
239    {
240      hw_abort (me, "bad read size of %d bytes to P%dMD.", nr_bytes,
241		io_port_reg);
242    }
243}
244
245
246static void
247read_control_reg (struct hw *me,
248		  struct mn103iop *io_port,
249		  unsigned_word io_port_reg,
250		  const void *dest,
251		  unsigned  nr_bytes)
252{
253  if ( nr_bytes == 1 )
254    {
255      *(unsigned8 *)dest = io_port->port[io_port_reg].control;
256    }
257  else
258    {
259      hw_abort (me, "bad read size of %d bytes to P%dDIR.", nr_bytes,
260		io_port_reg);
261    }
262}
263
264
265static void
266read_pin_reg (struct hw *me,
267	      struct mn103iop *io_port,
268	      unsigned_word io_port_reg,
269	      const void *dest,
270	      unsigned  nr_bytes)
271{
272  if ( nr_bytes == 1 )
273    {
274      *(unsigned8 *)dest = io_port->port[io_port_reg].pin;
275    }
276  else
277    {
278      hw_abort (me, "bad read size of %d bytes to P%dIN.", nr_bytes,
279		io_port_reg);
280    }
281}
282
283
284static void
285read_dedicated_control_reg (struct hw *me,
286			    struct mn103iop *io_port,
287			    unsigned_word io_port_reg,
288			    const void *dest,
289			    unsigned  nr_bytes)
290{
291  if ( nr_bytes == 1 )
292    {
293      /* select on io_port_reg: */
294      if ( io_port_reg == P2SS )
295	{
296	  *(unsigned8 *)dest = io_port->p2ss;
297	}
298      else
299	{
300	  *(unsigned8 *)dest = io_port->p4ss;
301	}
302    }
303  else
304    {
305      hw_abort (me, "bad read size of %d bytes to PSS.", nr_bytes);
306    }
307}
308
309
310static unsigned
311mn103iop_io_read_buffer (struct hw *me,
312			 void *dest,
313			 int space,
314			 unsigned_word base,
315			 unsigned nr_bytes)
316{
317  struct mn103iop *io_port = hw_data (me);
318  enum io_port_register_types io_port_reg;
319  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
320
321  io_port_reg = decode_addr (me, io_port, base);
322  switch (io_port_reg)
323    {
324    /* Port output registers */
325    case P0OUT:
326    case P1OUT:
327    case P2OUT:
328    case P3OUT:
329      read_output_reg(me, io_port, io_port_reg-P0OUT, dest, nr_bytes);
330      break;
331
332    /* Port output mode registers */
333    case P0MD:
334    case P1MD:
335    case P2MD:
336    case P3MD:
337      read_output_mode_reg(me, io_port, io_port_reg-P0MD, dest, nr_bytes);
338      break;
339
340    /* Port control registers */
341    case P0DIR:
342    case P1DIR:
343    case P2DIR:
344    case P3DIR:
345      read_control_reg(me, io_port, io_port_reg-P0DIR, dest, nr_bytes);
346      break;
347
348    /* Port pin registers */
349    case P0IN:
350    case P1IN:
351    case P2IN:
352      read_pin_reg(me, io_port, io_port_reg-P0IN, dest, nr_bytes);
353      break;
354
355    case P2SS:
356    case P4SS:
357      read_dedicated_control_reg(me, io_port, io_port_reg, dest, nr_bytes);
358      break;
359
360    default:
361      hw_abort(me, "invalid address");
362    }
363
364  return nr_bytes;
365}
366
367
368static void
369write_output_reg (struct hw *me,
370		  struct mn103iop *io_port,
371		  unsigned_word io_port_reg,
372		  const void *source,
373		  unsigned  nr_bytes)
374{
375  unsigned8 buf = *(unsigned8 *)source;
376  if ( nr_bytes == 1 )
377    {
378      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
379	{
380	  hw_abort(me, "Cannot write to read-only bits of P3OUT.");
381	}
382      else
383	{
384	  io_port->port[io_port_reg].output = buf;
385	}
386    }
387  else
388    {
389      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes,
390		io_port_reg);
391    }
392}
393
394
395static void
396write_output_mode_reg (struct hw *me,
397		       struct mn103iop *io_port,
398		       unsigned_word io_port_reg,
399		       const void *source,
400		       unsigned  nr_bytes)
401{
402  unsigned8 buf = *(unsigned8 *)source;
403  if ( nr_bytes == 1 )
404    {
405      /* check if there are fields which can't be written and
406	 take appropriate action depending what bits are set */
407      if ( ( io_port_reg == 3 && (buf & 0xfc) != 0 )
408	   || ( (io_port_reg == 0 || io_port_reg == 1)  && (buf & 0xfe) != 0 ) )
409	{
410	  hw_abort(me, "Cannot write to read-only bits of output mode register.");
411	}
412      else
413	{
414	  io_port->port[io_port_reg].output_mode = buf;
415	}
416    }
417  else
418    {
419      hw_abort (me, "bad write size of %d bytes to P%dMD.", nr_bytes,
420		io_port_reg);
421    }
422}
423
424
425static void
426write_control_reg (struct hw *me,
427		   struct mn103iop *io_port,
428		   unsigned_word io_port_reg,
429		   const void *source,
430		   unsigned  nr_bytes)
431{
432  unsigned8 buf = *(unsigned8 *)source;
433  if ( nr_bytes == 1 )
434    {
435      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
436	{
437	  hw_abort(me, "Cannot write to read-only bits of P3DIR.");
438	}
439      else
440	{
441	  io_port->port[io_port_reg].control = buf;
442	}
443    }
444  else
445    {
446      hw_abort (me, "bad write size of %d bytes to P%dDIR.", nr_bytes,
447		io_port_reg);
448    }
449}
450
451
452static void
453write_dedicated_control_reg (struct hw *me,
454			     struct mn103iop *io_port,
455			     unsigned_word io_port_reg,
456			     const void *source,
457			     unsigned  nr_bytes)
458{
459  unsigned8 buf = *(unsigned8 *)source;
460  if ( nr_bytes == 1 )
461    {
462      /* select on io_port_reg: */
463      if ( io_port_reg == P2SS )
464	{
465	  if ( (buf && 0xfc)  != 0 )
466	    {
467	      hw_abort(me, "Cannot write to read-only bits in p2ss.");
468	    }
469	  else
470	    {
471	      io_port->p2ss = buf;
472	    }
473	}
474      else
475	{
476	  if ( (buf && 0xf0) != 0 )
477	    {
478	      hw_abort(me, "Cannot write to read-only bits in p4ss.");
479	    }
480	  else
481	    {
482	      io_port->p4ss = buf;
483	    }
484	}
485    }
486  else
487    {
488      hw_abort (me, "bad write size of %d bytes to PSS.", nr_bytes);
489    }
490}
491
492
493static unsigned
494mn103iop_io_write_buffer (struct hw *me,
495			  const void *source,
496			  int space,
497			  unsigned_word base,
498			  unsigned nr_bytes)
499{
500  struct mn103iop *io_port = hw_data (me);
501  enum io_port_register_types io_port_reg;
502  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
503
504  io_port_reg = decode_addr (me, io_port, base);
505  switch (io_port_reg)
506    {
507    /* Port output registers */
508    case P0OUT:
509    case P1OUT:
510    case P2OUT:
511    case P3OUT:
512      write_output_reg(me, io_port, io_port_reg-P0OUT, source, nr_bytes);
513      break;
514
515    /* Port output mode registers */
516    case P0MD:
517    case P1MD:
518    case P2MD:
519    case P3MD:
520      write_output_mode_reg(me, io_port, io_port_reg-P0MD, source, nr_bytes);
521      break;
522
523    /* Port control registers */
524    case P0DIR:
525    case P1DIR:
526    case P2DIR:
527    case P3DIR:
528      write_control_reg(me, io_port, io_port_reg-P0DIR, source, nr_bytes);
529      break;
530
531    /* Port pin registers */
532    case P0IN:
533    case P1IN:
534    case P2IN:
535      hw_abort(me, "Cannot write to pin register.");
536      break;
537
538    case P2SS:
539    case P4SS:
540      write_dedicated_control_reg(me, io_port, io_port_reg, source, nr_bytes);
541      break;
542
543    default:
544      hw_abort(me, "invalid address");
545    }
546
547  return nr_bytes;
548}
549
550
551const struct hw_descriptor dv_mn103iop_descriptor[] = {
552  { "mn103iop", mn103iop_finish, },
553  { NULL },
554};
555