xref: /netbsd-src/external/gpl3/gdb/dist/sim/mn10300/dv-mn103iop.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /*  This file is part of the program GDB, the GNU debugger.
2 
3     Copyright (C) 1998-2019 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 
47 struct mn103iop_block {
48   unsigned_word base;
49   unsigned_word bound;
50 };
51 
52 
53 
54 enum 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 
77 enum {
78   OUTPUT_BLOCK,
79   MODE_BLOCK,
80   DED_CTRL_BLOCK,
81   CTRL_BLOCK,
82   PIN_BLOCK,
83   NR_BLOCKS
84 };
85 
86 typedef struct _mn10300_ioport {
87   unsigned8 output, output_mode, control, pin;
88   struct hw_event *event;
89 } mn10300_ioport;
90 
91 
92 
93 struct 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 
103 static hw_io_read_buffer_method mn103iop_io_read_buffer;
104 static hw_io_write_buffer_method mn103iop_io_write_buffer;
105 
106 static void
107 attach_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 
140 static void
141 mn103iop_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 
170 static int
171 decode_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 
206 static void
207 read_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 
225 static void
226 read_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 
246 static void
247 read_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 
265 static void
266 read_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 
284 static void
285 read_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 
310 static unsigned
311 mn103iop_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 
368 static void
369 write_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 
395 static void
396 write_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 
425 static void
426 write_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 
452 static void
453 write_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 
493 static unsigned
494 mn103iop_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 
551 const struct hw_descriptor dv_mn103iop_descriptor[] = {
552   { "mn103iop", mn103iop_finish, },
553   { NULL },
554 };
555