]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/mn10300/dv-mn103iop.c
Automatic Copyright Year update after running gdb/copyright.py
[thirdparty/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-2022 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 unsigned8 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 unsigned8 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 *(unsigned8 *)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 *(unsigned8 *)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 *(unsigned8 *)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 *(unsigned8 *)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 *(unsigned8 *)dest = io_port->p2ss;
300 }
301 else
302 {
303 *(unsigned8 *)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 unsigned8 buf = *(unsigned8 *)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 unsigned8 buf = *(unsigned8 *)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 unsigned8 buf = *(unsigned8 *)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 unsigned8 buf = *(unsigned8 *)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 };