1 /* This file is part of the program GDB, the GNU debugger. 2 3 Copyright (C) 1998-2024 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 "sim-fpu.h" 26 #include "sim-signal.h" 27 #include "hw-main.h" 28 29 #include "mn10300-sim.h" 30 31 /* DEVICE 32 33 34 mn103cpu - mn10300 cpu virtual device 35 36 37 DESCRIPTION 38 39 40 Implements the external mn10300 functionality. This includes the 41 delivery of interrupts generated from other devices and the 42 handling of device specific registers. 43 44 45 PROPERTIES 46 47 48 reg = <address> <size> 49 50 Specify the address of the mn10300's control register block. This 51 block contains the Interrupt Vector Registers. 52 53 The reg property value `0x20000000 0x42' locates the register block 54 at the address specified in the mn10300 user guide. 55 56 57 PORTS 58 59 60 reset (input) 61 62 Currently ignored. 63 64 65 nmi (input) 66 67 Deliver a non-maskable interrupt to the processor. 68 69 70 level (input) 71 72 Maskable interrupt level port port. The interrupt controller 73 notifies the processor of any change in the level of pending 74 requested interrupts via this port. 75 76 77 ack (output) 78 79 Output signal indicating that the processor is delivering a level 80 interrupt. The value passed with the event specifies the level of 81 the interrupt being delivered. 82 83 84 BUGS 85 86 87 When delivering an interrupt, this code assumes that there is only 88 one processor (number 0). 89 90 This code does not attempt to be efficient at handling pending 91 interrupts. It simply schedules the interrupt delivery handler 92 every instruction cycle until all pending interrupts go away. An 93 alternative implementation might modify instructions that change 94 the PSW and have them check to see if the change makes an interrupt 95 delivery possible. 96 97 */ 98 99 100 /* The interrupt vectors */ 101 102 enum { NR_VECTORS = 7, }; 103 104 105 /* The interrupt controller register address blocks */ 106 107 struct mn103cpu_block { 108 unsigned_word base; 109 unsigned_word bound; 110 }; 111 112 113 struct mn103cpu { 114 struct mn103cpu_block block; 115 struct hw_event *pending_handler; 116 int pending_level; 117 int pending_nmi; 118 int pending_reset; 119 /* the visible registers */ 120 uint16_t interrupt_vector[NR_VECTORS]; 121 uint16_t internal_memory_control; 122 uint16_t cpu_mode; 123 }; 124 125 126 127 /* input port ID's */ 128 129 enum { 130 RESET_PORT, 131 NMI_PORT, 132 LEVEL_PORT, 133 }; 134 135 136 /* output port ID's */ 137 138 enum { 139 ACK_PORT, 140 }; 141 142 static const struct hw_port_descriptor mn103cpu_ports[] = { 143 144 /* interrupt inputs */ 145 { "reset", RESET_PORT, 0, input_port, }, 146 { "nmi", NMI_PORT, 0, input_port, }, 147 { "level", LEVEL_PORT, 0, input_port, }, 148 149 /* interrupt ack (latch) output from cpu */ 150 { "ack", ACK_PORT, 0, output_port, }, 151 152 { NULL, }, 153 }; 154 155 156 /* Finish off the partially created hw device. Attach our local 157 callbacks. Wire up our port names etc */ 158 159 static hw_io_read_buffer_method mn103cpu_io_read_buffer; 160 static hw_io_write_buffer_method mn103cpu_io_write_buffer; 161 static hw_port_event_method mn103cpu_port_event; 162 163 static void 164 attach_mn103cpu_regs (struct hw *me, 165 struct mn103cpu *controller) 166 { 167 unsigned_word attach_address; 168 int attach_space; 169 unsigned attach_size; 170 reg_property_spec reg; 171 if (hw_find_property (me, "reg") == NULL) 172 hw_abort (me, "Missing \"reg\" property"); 173 if (!hw_find_reg_array_property (me, "reg", 0, ®)) 174 hw_abort (me, "\"reg\" property must contain three addr/size entries"); 175 hw_unit_address_to_attach_address (hw_parent (me), 176 ®.address, 177 &attach_space, 178 &attach_address, 179 me); 180 controller->block.base = attach_address; 181 hw_unit_size_to_attach_size (hw_parent (me), 182 ®.size, 183 &attach_size, me); 184 controller->block.bound = attach_address + (attach_size - 1); 185 if ((controller->block.base & 3) != 0) 186 hw_abort (me, "cpu register block must be 4 byte aligned"); 187 hw_attach_address (hw_parent (me), 188 0, 189 attach_space, attach_address, attach_size, 190 me); 191 } 192 193 194 static void 195 mn103cpu_finish (struct hw *me) 196 { 197 struct mn103cpu *controller; 198 199 controller = HW_ZALLOC (me, struct mn103cpu); 200 set_hw_data (me, controller); 201 set_hw_io_read_buffer (me, mn103cpu_io_read_buffer); 202 set_hw_io_write_buffer (me, mn103cpu_io_write_buffer); 203 set_hw_ports (me, mn103cpu_ports); 204 set_hw_port_event (me, mn103cpu_port_event); 205 206 /* Attach ourself to our parent bus */ 207 attach_mn103cpu_regs (me, controller); 208 209 /* Initialize the read-only registers */ 210 controller->pending_level = 7; /* FIXME */ 211 /* ... */ 212 } 213 214 215 216 /* An event arrives on an interrupt port */ 217 218 static void 219 deliver_mn103cpu_interrupt (struct hw *me, 220 void *data) 221 { 222 struct mn103cpu *controller = hw_data (me); 223 SIM_DESC simulator = hw_system (me); 224 sim_cpu *cpu = STATE_CPU (simulator, 0); 225 226 if (controller->pending_reset) 227 { 228 controller->pending_reset = 0; 229 /* need to clear all registers et.al! */ 230 HW_TRACE ((me, "Reset!")); 231 hw_abort (me, "Reset!"); 232 } 233 else if (controller->pending_nmi) 234 { 235 controller->pending_nmi = 0; 236 store_word (SP - 4, CPU_PC_GET (cpu)); 237 store_half (SP - 8, PSW); 238 PSW &= ~PSW_IE; 239 SP = SP - 8; 240 CPU_PC_SET (cpu, 0x40000008); 241 HW_TRACE ((me, "nmi pc=0x%08lx psw=0x%04x sp=0x%08lx", 242 (long) CPU_PC_GET (cpu), (unsigned) PSW, (long) SP)); 243 } 244 else if ((controller->pending_level < EXTRACT_PSW_LM) 245 && (PSW & PSW_IE)) 246 { 247 /* Don't clear pending level. Request continues to be pending 248 until the interrupt controller clears/changes it */ 249 store_word (SP - 4, CPU_PC_GET (cpu)); 250 store_half (SP - 8, PSW); 251 PSW &= ~PSW_IE; 252 PSW &= ~PSW_LM; 253 PSW |= INSERT_PSW_LM (controller->pending_level); 254 SP = SP - 8; 255 CPU_PC_SET (cpu, 0x40000000 + controller->interrupt_vector[controller->pending_level]); 256 HW_TRACE ((me, "port-out ack %d", controller->pending_level)); 257 hw_port_event (me, ACK_PORT, controller->pending_level); 258 HW_TRACE ((me, "int level=%d pc=0x%08lx psw=0x%04x sp=0x%08lx", 259 controller->pending_level, 260 (long) CPU_PC_GET (cpu), (unsigned) PSW, (long) SP)); 261 } 262 263 if (controller->pending_level < 7) /* FIXME */ 264 { 265 /* As long as there is the potential need to deliver an 266 interrupt we keep rescheduling this routine. */ 267 if (controller->pending_handler != NULL) 268 controller->pending_handler = 269 hw_event_queue_schedule (me, 1, deliver_mn103cpu_interrupt, NULL); 270 } 271 else 272 { 273 /* Don't bother re-scheduling the interrupt handler as there is 274 nothing to deliver */ 275 controller->pending_handler = NULL; 276 } 277 278 } 279 280 281 static void 282 mn103cpu_port_event (struct hw *me, 283 int my_port, 284 struct hw *source, 285 int source_port, 286 int level) 287 { 288 struct mn103cpu *controller = hw_data (me); 289 290 /* Schedule our event handler *now* */ 291 if (controller->pending_handler == NULL) 292 controller->pending_handler = 293 hw_event_queue_schedule (me, 0, deliver_mn103cpu_interrupt, NULL); 294 295 switch (my_port) 296 { 297 298 case RESET_PORT: 299 controller->pending_reset = 1; 300 HW_TRACE ((me, "port-in reset")); 301 break; 302 303 case NMI_PORT: 304 controller->pending_nmi = 1; 305 HW_TRACE ((me, "port-in nmi")); 306 break; 307 308 case LEVEL_PORT: 309 controller->pending_level = level; 310 HW_TRACE ((me, "port-in level=%d", level)); 311 break; 312 313 default: 314 hw_abort (me, "bad switch"); 315 break; 316 317 } 318 } 319 320 321 /* Read/write to a CPU register */ 322 323 enum mn103cpu_regs { 324 INVALID_REG, 325 IVR0_REG, 326 IVR1_REG, 327 IVR2_REG, 328 IVR3_REG, 329 IVR4_REG, 330 IVR5_REG, 331 IVR6_REG, 332 IMCR_REG, 333 CPUM_REG, 334 }; 335 336 static enum mn103cpu_regs 337 decode_mn103cpu_addr (struct hw *me, 338 struct mn103cpu *controller, 339 unsigned_word base) 340 { 341 switch (base - controller->block.base) 342 { 343 case 0x000: return IVR0_REG; 344 case 0x004: return IVR1_REG; 345 case 0x008: return IVR2_REG; 346 case 0x00c: return IVR3_REG; 347 case 0x010: return IVR4_REG; 348 case 0x014: return IVR5_REG; 349 case 0x018: return IVR6_REG; 350 case 0x020: return IMCR_REG; 351 case 0x040: return CPUM_REG; 352 default: return INVALID_REG; 353 } 354 } 355 356 static unsigned 357 mn103cpu_io_read_buffer (struct hw *me, 358 void *dest, 359 int space, 360 unsigned_word base, 361 unsigned nr_bytes) 362 { 363 struct mn103cpu *controller = hw_data (me); 364 uint16_t val = 0; 365 enum mn103cpu_regs reg = decode_mn103cpu_addr (me, controller, base); 366 367 switch (reg) 368 { 369 case IVR0_REG: 370 case IVR1_REG: 371 case IVR2_REG: 372 case IVR3_REG: 373 case IVR4_REG: 374 case IVR5_REG: 375 case IVR6_REG: 376 val = controller->interrupt_vector[reg - IVR0_REG]; 377 break; 378 case IMCR_REG: 379 val = controller->internal_memory_control; 380 break; 381 case CPUM_REG: 382 val = controller->cpu_mode; 383 break; 384 default: 385 /* just ignore the read */ 386 break; 387 } 388 389 if (nr_bytes == 2) 390 *(uint16_t*) dest = H2LE_2 (val); 391 392 return nr_bytes; 393 } 394 395 static unsigned 396 mn103cpu_io_write_buffer (struct hw *me, 397 const void *source, 398 int space, 399 unsigned_word base, 400 unsigned nr_bytes) 401 { 402 struct mn103cpu *controller = hw_data (me); 403 uint16_t val; 404 enum mn103cpu_regs reg; 405 406 if (nr_bytes != 2) 407 hw_abort (me, "must be two byte write"); 408 409 reg = decode_mn103cpu_addr (me, controller, base); 410 val = LE2H_2 (* (uint16_t *) source); 411 412 switch (reg) 413 { 414 case IVR0_REG: 415 case IVR1_REG: 416 case IVR2_REG: 417 case IVR3_REG: 418 case IVR4_REG: 419 case IVR5_REG: 420 case IVR6_REG: 421 controller->interrupt_vector[reg - IVR0_REG] = val; 422 HW_TRACE ((me, "ivr%d = 0x%04lx", reg - IVR0_REG, (long) val)); 423 break; 424 default: 425 /* just ignore the write */ 426 break; 427 } 428 429 return nr_bytes; 430 } 431 432 433 const struct hw_descriptor dv_mn103cpu_descriptor[] = { 434 { "mn103cpu", mn103cpu_finish, }, 435 { NULL }, 436 }; 437