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