* am33.igen: Autoincrement loads/store fixes.
[deliverable/binutils-gdb.git] / sim / mn10300 / dv-mn103iop.c
1 /* This file is part of the program GDB, the GNU debugger.
2
3 Copyright (C) 1998 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 2 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, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21
22 #include "sim-main.h"
23 #include "hw-main.h"
24
25 /* DEVICE
26
27
28 mn103ser - 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->p2ss = 0;
164 io_port->p4ss = 0;
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 if ( nr_bytes == 1 )
376 {
377 io_port->port[io_port_reg].output = *(unsigned16 *)source;
378 }
379 else
380 {
381 hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes,
382 io_port_reg);
383 }
384 }
385
386
387 static void
388 write_output_mode_reg (struct hw *me,
389 struct mn103iop *io_port,
390 unsigned_word io_port_reg,
391 const void *source,
392 unsigned nr_bytes)
393 {
394 if ( nr_bytes == 1 )
395 {
396 /* check if there are fields which can't be written and
397 take appropriate action depending what bits are set */
398 io_port->port[io_port_reg].output_mode = *(unsigned8 *)source;
399 }
400 else
401 {
402 hw_abort (me, "bad write size of %d bytes to P%dMD.", nr_bytes,
403 io_port_reg);
404 }
405 }
406
407
408 static void
409 write_control_reg (struct hw *me,
410 struct mn103iop *io_port,
411 unsigned_word io_port_reg,
412 const void *source,
413 unsigned nr_bytes)
414 {
415 if ( nr_bytes == 1 )
416 {
417 io_port->port[io_port_reg].control = *(unsigned8 *)source;
418 }
419 else
420 {
421 hw_abort (me, "bad write size of %d bytes to P%dDIR.", nr_bytes,
422 io_port_reg);
423 }
424 }
425
426
427 static void
428 write_dedicated_control_reg (struct hw *me,
429 struct mn103iop *io_port,
430 unsigned_word io_port_reg,
431 const void *source,
432 unsigned nr_bytes)
433 {
434 if ( nr_bytes == 1 )
435 {
436 /* select on io_port_reg: */
437 if ( io_port_reg == P2SS )
438 {
439 io_port->p2ss = *(unsigned8 *)source;
440 }
441 else
442 {
443 io_port->p4ss = *(unsigned8 *)source;
444 }
445 }
446 else
447 {
448 hw_abort (me, "bad write size of %d bytes to PSS.", nr_bytes);
449 }
450 }
451
452
453 static unsigned
454 mn103iop_io_write_buffer (struct hw *me,
455 const void *source,
456 int space,
457 unsigned_word base,
458 unsigned nr_bytes)
459 {
460 struct mn103iop *io_port = hw_data (me);
461 enum io_port_register_types io_port_reg;
462 HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
463
464 io_port_reg = decode_addr (me, io_port, base);
465 switch (io_port_reg)
466 {
467 /* Port output registers */
468 case P0OUT:
469 case P1OUT:
470 case P2OUT:
471 case P3OUT:
472 write_output_reg(me, io_port, io_port_reg-P0OUT, source, nr_bytes);
473 break;
474
475 /* Port output mode registers */
476 case P0MD:
477 case P1MD:
478 case P2MD:
479 case P3MD:
480 write_output_mode_reg(me, io_port, io_port_reg-P0MD, source, nr_bytes);
481 break;
482
483 /* Port control registers */
484 case P0DIR:
485 case P1DIR:
486 case P2DIR:
487 case P3DIR:
488 write_control_reg(me, io_port, io_port_reg-P0DIR, source, nr_bytes);
489 break;
490
491 /* Port pin registers */
492 case P0IN:
493 case P1IN:
494 case P2IN:
495 hw_abort(me, "Cannot write to pin register.");
496 break;
497
498 case P2SS:
499 case P4SS:
500 write_dedicated_control_reg(me, io_port, io_port_reg, source, nr_bytes);
501 break;
502
503 default:
504 hw_abort(me, "invalid address");
505 }
506
507 return nr_bytes;
508 }
509
510
511 const struct hw_descriptor dv_mn103iop_descriptor[] = {
512 { "mn103iop", mn103iop_finish, },
513 { NULL },
514 };
This page took 0.050566 seconds and 4 git commands to generate.