sim: convert old style prototypes
[external/binutils.git] / sim / mn10300 / dv-mn103iop.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
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 };