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