dv-mn103iop.c revision 1.6
1/* This file is part of the program GDB, the GNU debugger. 2 3 Copyright (C) 1998-2016 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 47struct mn103iop_block { 48 unsigned_word base; 49 unsigned_word bound; 50}; 51 52 53 54enum 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 77enum { 78 OUTPUT_BLOCK, 79 MODE_BLOCK, 80 DED_CTRL_BLOCK, 81 CTRL_BLOCK, 82 PIN_BLOCK, 83 NR_BLOCKS 84}; 85 86typedef struct _mn10300_ioport { 87 unsigned8 output, output_mode, control, pin; 88 struct hw_event *event; 89} mn10300_ioport; 90 91 92 93struct 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 103static hw_io_read_buffer_method mn103iop_io_read_buffer; 104static hw_io_write_buffer_method mn103iop_io_write_buffer; 105 106static void 107attach_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, ®)) 122 hw_abort (me, "\"reg\" property must contain five addr/size entries"); 123 hw_unit_address_to_attach_address (hw_parent (me), 124 ®.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 ®.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 140static void 141mn103iop_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 170static int 171decode_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 206static void 207read_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 225static void 226read_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 246static void 247read_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 265static void 266read_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 284static void 285read_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 310static unsigned 311mn103iop_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 368static void 369write_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 395static void 396write_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 425static void 426write_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 452static void 453write_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 493static unsigned 494mn103iop_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 551const struct hw_descriptor dv_mn103iop_descriptor[] = { 552 { "mn103iop", mn103iop_finish, }, 553 { NULL }, 554}; 555