1/*> interp.c <*/ 2/* Simulator for the MIPS architecture. 3 4 This file is part of the MIPS sim 5 6 THIS SOFTWARE IS NOT COPYRIGHTED 7 8 Cygnus offers the following for use in the public domain. Cygnus 9 makes no warranty with regard to the software or it's performance 10 and the user accepts the software "AS IS" with all faults. 11 12 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO 13 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 14 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 15 16NOTEs: 17 18The IDT monitor (found on the VR4300 board), seems to lie about 19register contents. It seems to treat the registers as sign-extended 2032-bit values. This cause *REAL* problems when single-stepping 64-bit 21code on the hardware. 22 23*/ 24 25/* The TRACE manifests enable the provision of extra features. If they 26 are not defined then a simpler (quicker) simulator is constructed 27 without the required run-time checks, etc. */ 28#if 1 /* 0 to allow user build selection, 1 to force inclusion */ 29#define TRACE (1) 30#endif 31 32#include "bfd.h" 33#include "sim-main.h" 34#include "sim-utils.h" 35#include "sim-options.h" 36#include "sim-assert.h" 37#include "sim-hw.h" 38 39#include "itable.h" 40 41 42#include "config.h" 43 44#include <stdio.h> 45#include <stdarg.h> 46#include <ansidecl.h> 47#include <ctype.h> 48#include <limits.h> 49#include <math.h> 50#ifdef HAVE_STDLIB_H 51#include <stdlib.h> 52#endif 53#ifdef HAVE_STRING_H 54#include <string.h> 55#else 56#ifdef HAVE_STRINGS_H 57#include <strings.h> 58#endif 59#endif 60 61#include "getopt.h" 62#include "libiberty.h" 63#include "bfd.h" 64#include "gdb/callback.h" /* GDB simulator callback interface */ 65#include "gdb/remote-sim.h" /* GDB simulator interface */ 66 67#include "sysdep.h" 68 69#ifndef PARAMS 70#define PARAMS(x) 71#endif 72 73char* pr_addr PARAMS ((SIM_ADDR addr)); 74char* pr_uword64 PARAMS ((uword64 addr)); 75 76 77/* Within interp.c we refer to the sim_state and sim_cpu directly. */ 78#define CPU cpu 79#define SD sd 80 81 82/* The following reserved instruction value is used when a simulator 83 trap is required. NOTE: Care must be taken, since this value may be 84 used in later revisions of the MIPS ISA. */ 85 86#define RSVD_INSTRUCTION (0x00000005) 87#define RSVD_INSTRUCTION_MASK (0xFC00003F) 88 89#define RSVD_INSTRUCTION_ARG_SHIFT 6 90#define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF 91 92 93/* Bits in the Debug register */ 94#define Debug_DBD 0x80000000 /* Debug Branch Delay */ 95#define Debug_DM 0x40000000 /* Debug Mode */ 96#define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */ 97 98/*---------------------------------------------------------------------------*/ 99/*-- GDB simulator interface ------------------------------------------------*/ 100/*---------------------------------------------------------------------------*/ 101 102static void ColdReset PARAMS((SIM_DESC sd)); 103 104/*---------------------------------------------------------------------------*/ 105 106 107 108#define DELAYSLOT() {\ 109 if (STATE & simDELAYSLOT)\ 110 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\ 111 STATE |= simDELAYSLOT;\ 112 } 113 114#define JALDELAYSLOT() {\ 115 DELAYSLOT ();\ 116 STATE |= simJALDELAYSLOT;\ 117 } 118 119#define NULLIFY() {\ 120 STATE &= ~simDELAYSLOT;\ 121 STATE |= simSKIPNEXT;\ 122 } 123 124#define CANCELDELAYSLOT() {\ 125 DSSTATE = 0;\ 126 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\ 127 } 128 129#define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0) 130#define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0) 131 132/* Note that the monitor code essentially assumes this layout of memory. 133 If you change these, change the monitor code, too. */ 134/* FIXME Currently addresses are truncated to 32-bits, see 135 mips/sim-main.c:address_translation(). If that changes, then these 136 values will need to be extended, and tested for more carefully. */ 137#define K0BASE (0x80000000) 138#define K0SIZE (0x20000000) 139#define K1BASE (0xA0000000) 140#define K1SIZE (0x20000000) 141 142/* Simple run-time monitor support. 143 144 We emulate the monitor by placing magic reserved instructions at 145 the monitor's entry points; when we hit these instructions, instead 146 of raising an exception (as we would normally), we look at the 147 instruction and perform the appropriate monitory operation. 148 149 `*_monitor_base' are the physical addresses at which the corresponding 150 monitor vectors are located. `0' means none. By default, 151 install all three. 152 The RSVD_INSTRUCTION... macros specify the magic instructions we 153 use at the monitor entry points. */ 154static int firmware_option_p = 0; 155static SIM_ADDR idt_monitor_base = 0xBFC00000; 156static SIM_ADDR pmon_monitor_base = 0xBFC00500; 157static SIM_ADDR lsipmon_monitor_base = 0xBFC00200; 158 159static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg); 160 161 162#define MEM_SIZE (8 << 20) /* 8 MBytes */ 163 164 165#if defined(TRACE) 166static char *tracefile = "trace.din"; /* default filename for trace log */ 167FILE *tracefh = NULL; 168static void open_trace PARAMS((SIM_DESC sd)); 169#endif /* TRACE */ 170 171static const char * get_insn_name (sim_cpu *, int); 172 173/* simulation target board. NULL=canonical */ 174static char* board = NULL; 175 176 177static DECLARE_OPTION_HANDLER (mips_option_handler); 178 179enum { 180 OPTION_DINERO_TRACE = OPTION_START, 181 OPTION_DINERO_FILE, 182 OPTION_FIRMWARE, 183 OPTION_INFO_MEMORY, 184 OPTION_BOARD 185}; 186 187static int display_mem_info = 0; 188 189static SIM_RC 190mips_option_handler (sd, cpu, opt, arg, is_command) 191 SIM_DESC sd; 192 sim_cpu *cpu; 193 int opt; 194 char *arg; 195 int is_command; 196{ 197 int cpu_nr; 198 switch (opt) 199 { 200 case OPTION_DINERO_TRACE: /* ??? */ 201#if defined(TRACE) 202 /* Eventually the simTRACE flag could be treated as a toggle, to 203 allow external control of the program points being traced 204 (i.e. only from main onwards, excluding the run-time setup, 205 etc.). */ 206 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) 207 { 208 sim_cpu *cpu = STATE_CPU (sd, cpu_nr); 209 if (arg == NULL) 210 STATE |= simTRACE; 211 else if (strcmp (arg, "yes") == 0) 212 STATE |= simTRACE; 213 else if (strcmp (arg, "no") == 0) 214 STATE &= ~simTRACE; 215 else if (strcmp (arg, "on") == 0) 216 STATE |= simTRACE; 217 else if (strcmp (arg, "off") == 0) 218 STATE &= ~simTRACE; 219 else 220 { 221 fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg); 222 return SIM_RC_FAIL; 223 } 224 } 225 return SIM_RC_OK; 226#else /* !TRACE */ 227 fprintf(stderr,"\ 228Simulator constructed without dinero tracing support (for performance).\n\ 229Re-compile simulator with \"-DTRACE\" to enable this option.\n"); 230 return SIM_RC_FAIL; 231#endif /* !TRACE */ 232 233 case OPTION_DINERO_FILE: 234#if defined(TRACE) 235 if (optarg != NULL) { 236 char *tmp; 237 tmp = (char *)malloc(strlen(optarg) + 1); 238 if (tmp == NULL) 239 { 240 sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg); 241 return SIM_RC_FAIL; 242 } 243 else { 244 strcpy(tmp,optarg); 245 tracefile = tmp; 246 sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile); 247 } 248 } 249#endif /* TRACE */ 250 return SIM_RC_OK; 251 252 case OPTION_FIRMWARE: 253 return sim_firmware_command (sd, arg); 254 255 case OPTION_BOARD: 256 { 257 if (arg) 258 { 259 board = zalloc(strlen(arg) + 1); 260 strcpy(board, arg); 261 } 262 return SIM_RC_OK; 263 } 264 265 case OPTION_INFO_MEMORY: 266 display_mem_info = 1; 267 break; 268 } 269 270 return SIM_RC_OK; 271} 272 273 274static const OPTION mips_options[] = 275{ 276 { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE}, 277 '\0', "on|off", "Enable dinero tracing", 278 mips_option_handler }, 279 { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE}, 280 '\0', "FILE", "Write dinero trace to FILE", 281 mips_option_handler }, 282 { {"firmware", required_argument, NULL, OPTION_FIRMWARE}, 283 '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor", 284 mips_option_handler }, 285 { {"board", required_argument, NULL, OPTION_BOARD}, 286 '\0', "none" /* rely on compile-time string concatenation for other options */ 287 288#define BOARD_JMR3904 "jmr3904" 289 "|" BOARD_JMR3904 290#define BOARD_JMR3904_PAL "jmr3904pal" 291 "|" BOARD_JMR3904_PAL 292#define BOARD_JMR3904_DEBUG "jmr3904debug" 293 "|" BOARD_JMR3904_DEBUG 294#define BOARD_BSP "bsp" 295 "|" BOARD_BSP 296 297 , "Customize simulation for a particular board.", mips_option_handler }, 298 299 /* These next two options have the same names as ones found in the 300 memory_options[] array in common/sim-memopt.c. This is because 301 the intention is to provide an alternative handler for those two 302 options. We need an alternative handler because the memory 303 regions are not set up until after the command line arguments 304 have been parsed, and so we cannot display the memory info whilst 305 processing the command line. There is a hack in sim_open to 306 remove these handlers when we want the real --memory-info option 307 to work. */ 308 { { "info-memory", no_argument, NULL, OPTION_INFO_MEMORY }, 309 '\0', NULL, "List configured memory regions", mips_option_handler }, 310 { { "memory-info", no_argument, NULL, OPTION_INFO_MEMORY }, 311 '\0', NULL, NULL, mips_option_handler }, 312 313 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL } 314}; 315 316 317int interrupt_pending; 318 319void 320interrupt_event (SIM_DESC sd, void *data) 321{ 322 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ 323 address_word cia = CIA_GET (cpu); 324 if (SR & status_IE) 325 { 326 interrupt_pending = 0; 327 SignalExceptionInterrupt (1); /* interrupt "1" */ 328 } 329 else if (!interrupt_pending) 330 sim_events_schedule (sd, 1, interrupt_event, data); 331} 332 333 334/*---------------------------------------------------------------------------*/ 335/*-- Device registration hook -----------------------------------------------*/ 336/*---------------------------------------------------------------------------*/ 337static void device_init(SIM_DESC sd) { 338#ifdef DEVICE_INIT 339 extern void register_devices(SIM_DESC); 340 register_devices(sd); 341#endif 342} 343 344/*---------------------------------------------------------------------------*/ 345/*-- GDB simulator interface ------------------------------------------------*/ 346/*---------------------------------------------------------------------------*/ 347 348SIM_DESC 349sim_open (kind, cb, abfd, argv) 350 SIM_OPEN_KIND kind; 351 host_callback *cb; 352 struct bfd *abfd; 353 char **argv; 354{ 355 SIM_DESC sd = sim_state_alloc (kind, cb); 356 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ 357 358 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 359 360 /* FIXME: watchpoints code shouldn't need this */ 361 STATE_WATCHPOINTS (sd)->pc = &(PC); 362 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); 363 STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event; 364 365 /* Initialize the mechanism for doing insn profiling. */ 366 CPU_INSN_NAME (cpu) = get_insn_name; 367 CPU_MAX_INSNS (cpu) = nr_itable_entries; 368 369 STATE = 0; 370 371 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 372 return 0; 373 sim_add_option_table (sd, NULL, mips_options); 374 375 376 /* getopt will print the error message so we just have to exit if this fails. 377 FIXME: Hmmm... in the case of gdb we need getopt to call 378 print_filtered. */ 379 if (sim_parse_args (sd, argv) != SIM_RC_OK) 380 { 381 /* Uninstall the modules to avoid memory leaks, 382 file descriptor leaks, etc. */ 383 sim_module_uninstall (sd); 384 return 0; 385 } 386 387 /* handle board-specific memory maps */ 388 if (board == NULL) 389 { 390 /* Allocate core managed memory */ 391 sim_memopt *entry, *match = NULL; 392 address_word mem_size = 0; 393 int mapped = 0; 394 395 /* For compatibility with the old code - under this (at level one) 396 are the kernel spaces K0 & K1. Both of these map to a single 397 smaller sub region */ 398 sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */ 399 400 /* Look for largest memory region defined on command-line at 401 phys address 0. */ 402#ifdef SIM_HAVE_FLATMEM 403 mem_size = STATE_MEM_SIZE (sd); 404#endif 405 for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next) 406 { 407 /* If we find an entry at address 0, then we will end up 408 allocating a new buffer in the "memory alias" command 409 below. The region at address 0 will be deleted. */ 410 address_word size = (entry->modulo != 0 411 ? entry->modulo : entry->nr_bytes); 412 if (entry->addr == 0 413 && (!match || entry->level < match->level)) 414 match = entry; 415 else if (entry->addr == K0BASE || entry->addr == K1BASE) 416 mapped = 1; 417 else 418 { 419 sim_memopt *alias; 420 for (alias = entry->alias; alias != NULL; alias = alias->next) 421 { 422 if (alias->addr == 0 423 && (!match || entry->level < match->level)) 424 match = entry; 425 else if (alias->addr == K0BASE || alias->addr == K1BASE) 426 mapped = 1; 427 } 428 } 429 } 430 431 if (!mapped) 432 { 433 if (match) 434 { 435 /* Get existing memory region size. */ 436 mem_size = (match->modulo != 0 437 ? match->modulo : match->nr_bytes); 438 /* Delete old region. */ 439 sim_do_commandf (sd, "memory delete %d:0x%lx@%d", 440 match->space, match->addr, match->level); 441 } 442 else if (mem_size == 0) 443 mem_size = MEM_SIZE; 444 /* Limit to KSEG1 size (512MB) */ 445 if (mem_size > K1SIZE) 446 mem_size = K1SIZE; 447 /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */ 448 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x", 449 K1BASE, K1SIZE, (long)mem_size, K0BASE); 450 } 451 452 device_init(sd); 453 } 454 else if (board != NULL 455 && (strcmp(board, BOARD_BSP) == 0)) 456 { 457 int i; 458 459 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT; 460 461 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */ 462 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x", 463 0x9FC00000, 464 4 * 1024 * 1024, /* 4 MB */ 465 0xBFC00000); 466 467 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */ 468 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x", 469 0x80000000, 470 4 * 1024 * 1024, /* 4 MB */ 471 0xA0000000); 472 473 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */ 474 for (i=0; i<8; i++) /* 32 MB total */ 475 { 476 unsigned size = 4 * 1024 * 1024; /* 4 MB */ 477 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x", 478 0x88000000 + (i * size), 479 size, 480 0xA8000000 + (i * size)); 481 } 482 } 483#if (WITH_HW) 484 else if (board != NULL 485 && (strcmp(board, BOARD_JMR3904) == 0 || 486 strcmp(board, BOARD_JMR3904_PAL) == 0 || 487 strcmp(board, BOARD_JMR3904_DEBUG) == 0)) 488 { 489 /* match VIRTUAL memory layout of JMR-TX3904 board */ 490 int i; 491 492 /* --- disable monitor unless forced on by user --- */ 493 494 if (! firmware_option_p) 495 { 496 idt_monitor_base = 0; 497 pmon_monitor_base = 0; 498 lsipmon_monitor_base = 0; 499 } 500 501 /* --- environment --- */ 502 503 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT; 504 505 /* --- memory --- */ 506 507 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */ 508 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x", 509 0x9FC00000, 510 4 * 1024 * 1024, /* 4 MB */ 511 0xBFC00000); 512 513 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */ 514 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x", 515 0x80000000, 516 4 * 1024 * 1024, /* 4 MB */ 517 0xA0000000); 518 519 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */ 520 for (i=0; i<8; i++) /* 32 MB total */ 521 { 522 unsigned size = 4 * 1024 * 1024; /* 4 MB */ 523 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x", 524 0x88000000 + (i * size), 525 size, 526 0xA8000000 + (i * size)); 527 } 528 529 /* Dummy memory regions for unsimulated devices - sorted by address */ 530 531 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */ 532 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */ 533 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */ 534 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */ 535 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */ 536 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */ 537 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */ 538 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */ 539 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */ 540 541 542 /* --- simulated devices --- */ 543 sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20"); 544 sim_hw_parse (sd, "/tx3904cpu"); 545 sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100"); 546 sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100"); 547 sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100"); 548 sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100"); 549 { 550 /* FIXME: poking at dv-sockser internals, use tcp backend if 551 --sockser_addr option was given.*/ 552 extern char* sockser_addr; 553 if(sockser_addr == NULL) 554 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio"); 555 else 556 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp"); 557 } 558 sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100"); 559 sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio"); 560 561 /* -- device connections --- */ 562 sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu"); 563 sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc"); 564 sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc"); 565 sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc"); 566 sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc"); 567 sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc"); 568 569 /* add PAL timer & I/O module */ 570 if(! strcmp(board, BOARD_JMR3904_PAL)) 571 { 572 /* the device */ 573 sim_hw_parse (sd, "/pal@0xffff0000"); 574 sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64"); 575 576 /* wire up interrupt ports to irc */ 577 sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc"); 578 sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc"); 579 sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc"); 580 } 581 582 if(! strcmp(board, BOARD_JMR3904_DEBUG)) 583 { 584 /* -- DEBUG: glue interrupt generators --- */ 585 sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50"); 586 sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc"); 587 sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc"); 588 sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc"); 589 sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc"); 590 sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc"); 591 sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc"); 592 sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc"); 593 sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc"); 594 sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc"); 595 sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc"); 596 sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc"); 597 sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc"); 598 sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc"); 599 sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc"); 600 sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc"); 601 sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc"); 602 sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc"); 603 sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu"); 604 } 605 606 device_init(sd); 607 } 608#endif 609 610 if (display_mem_info) 611 { 612 struct option_list * ol; 613 struct option_list * prev; 614 615 /* This is a hack. We want to execute the real --memory-info command 616 line switch which is handled in common/sim-memopts.c, not the 617 override we have defined in this file. So we remove the 618 mips_options array from the state options list. This is safe 619 because we have now processed all of the command line. */ 620 for (ol = STATE_OPTIONS (sd), prev = NULL; 621 ol != NULL; 622 prev = ol, ol = ol->next) 623 if (ol->options == mips_options) 624 break; 625 626 SIM_ASSERT (ol != NULL); 627 628 if (prev == NULL) 629 STATE_OPTIONS (sd) = ol->next; 630 else 631 prev->next = ol->next; 632 633 sim_do_commandf (sd, "memory-info"); 634 } 635 636 /* check for/establish the a reference program image */ 637 if (sim_analyze_program (sd, 638 (STATE_PROG_ARGV (sd) != NULL 639 ? *STATE_PROG_ARGV (sd) 640 : NULL), 641 abfd) != SIM_RC_OK) 642 { 643 sim_module_uninstall (sd); 644 return 0; 645 } 646 647 /* Configure/verify the target byte order and other runtime 648 configuration options */ 649 if (sim_config (sd) != SIM_RC_OK) 650 { 651 sim_module_uninstall (sd); 652 return 0; 653 } 654 655 if (sim_post_argv_init (sd) != SIM_RC_OK) 656 { 657 /* Uninstall the modules to avoid memory leaks, 658 file descriptor leaks, etc. */ 659 sim_module_uninstall (sd); 660 return 0; 661 } 662 663 /* verify assumptions the simulator made about the host type system. 664 This macro does not return if there is a problem */ 665 SIM_ASSERT (sizeof(int) == (4 * sizeof(char))); 666 SIM_ASSERT (sizeof(word64) == (8 * sizeof(char))); 667 668 /* This is NASTY, in that we are assuming the size of specific 669 registers: */ 670 { 671 int rn; 672 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++) 673 { 674 if (rn < 32) 675 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE; 676 else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR))) 677 cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE; 678 else if ((rn >= 33) && (rn <= 37)) 679 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE; 680 else if ((rn == SRIDX) 681 || (rn == FCR0IDX) 682 || (rn == FCR31IDX) 683 || ((rn >= 72) && (rn <= 89))) 684 cpu->register_widths[rn] = 32; 685 else 686 cpu->register_widths[rn] = 0; 687 } 688 689 690 } 691 692#if defined(TRACE) 693 if (STATE & simTRACE) 694 open_trace(sd); 695#endif /* TRACE */ 696 697 /* 698 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n", 699 idt_monitor_base, 700 pmon_monitor_base, 701 lsipmon_monitor_base); 702 */ 703 704 /* Write the monitor trap address handlers into the monitor (eeprom) 705 address space. This can only be done once the target endianness 706 has been determined. */ 707 if (idt_monitor_base != 0) 708 { 709 unsigned loop; 710 unsigned idt_monitor_size = 1 << 11; 711 712 /* the default monitor region */ 713 sim_do_commandf (sd, "memory region 0x%x,0x%x", 714 idt_monitor_base, idt_monitor_size); 715 716 /* Entry into the IDT monitor is via fixed address vectors, and 717 not using machine instructions. To avoid clashing with use of 718 the MIPS TRAP system, we place our own (simulator specific) 719 "undefined" instructions into the relevant vector slots. */ 720 for (loop = 0; (loop < idt_monitor_size); loop += 4) 721 { 722 address_word vaddr = (idt_monitor_base + loop); 723 unsigned32 insn = (RSVD_INSTRUCTION | 724 (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) 725 << RSVD_INSTRUCTION_ARG_SHIFT)); 726 H2T (insn); 727 sim_write (sd, vaddr, (char *)&insn, sizeof (insn)); 728 } 729 } 730 731 if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0)) 732 { 733 /* The PMON monitor uses the same address space, but rather than 734 branching into it the address of a routine is loaded. We can 735 cheat for the moment, and direct the PMON routine to IDT style 736 instructions within the monitor space. This relies on the IDT 737 monitor not using the locations from 0xBFC00500 onwards as its 738 entry points.*/ 739 unsigned loop; 740 for (loop = 0; (loop < 24); loop++) 741 { 742 unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */ 743 switch (loop) 744 { 745 case 0: /* read */ 746 value = 7; 747 break; 748 case 1: /* write */ 749 value = 8; 750 break; 751 case 2: /* open */ 752 value = 6; 753 break; 754 case 3: /* close */ 755 value = 10; 756 break; 757 case 5: /* printf */ 758 value = ((0x500 - 16) / 8); /* not an IDT reason code */ 759 break; 760 case 8: /* cliexit */ 761 value = 17; 762 break; 763 case 11: /* flush_cache */ 764 value = 28; 765 break; 766 } 767 768 SIM_ASSERT (idt_monitor_base != 0); 769 value = ((unsigned int) idt_monitor_base + (value * 8)); 770 H2T (value); 771 772 if (pmon_monitor_base != 0) 773 { 774 address_word vaddr = (pmon_monitor_base + (loop * 4)); 775 sim_write (sd, vaddr, (char *)&value, sizeof (value)); 776 } 777 778 if (lsipmon_monitor_base != 0) 779 { 780 address_word vaddr = (lsipmon_monitor_base + (loop * 4)); 781 sim_write (sd, vaddr, (char *)&value, sizeof (value)); 782 } 783 } 784 785 /* Write an abort sequence into the TRAP (common) exception vector 786 addresses. This is to catch code executing a TRAP (et.al.) 787 instruction without installing a trap handler. */ 788 if ((idt_monitor_base != 0) || 789 (pmon_monitor_base != 0) || 790 (lsipmon_monitor_base != 0)) 791 { 792 unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */, 793 HALT_INSTRUCTION /* BREAK */ }; 794 H2T (halt[0]); 795 H2T (halt[1]); 796 sim_write (sd, 0x80000000, (char *) halt, sizeof (halt)); 797 sim_write (sd, 0x80000180, (char *) halt, sizeof (halt)); 798 sim_write (sd, 0x80000200, (char *) halt, sizeof (halt)); 799 /* XXX: Write here unconditionally? */ 800 sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt)); 801 sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt)); 802 sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt)); 803 } 804 } 805 806 807 808 return sd; 809} 810 811#if defined(TRACE) 812static void 813open_trace(sd) 814 SIM_DESC sd; 815{ 816 tracefh = fopen(tracefile,"wb+"); 817 if (tracefh == NULL) 818 { 819 sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile); 820 tracefh = stderr; 821 } 822} 823#endif /* TRACE */ 824 825/* Return name of an insn, used by insn profiling. */ 826static const char * 827get_insn_name (sim_cpu *cpu, int i) 828{ 829 return itable[i].name; 830} 831 832void 833sim_close (sd, quitting) 834 SIM_DESC sd; 835 int quitting; 836{ 837#ifdef DEBUG 838 printf("DBG: sim_close: entered (quitting = %d)\n",quitting); 839#endif 840 841 842 /* "quitting" is non-zero if we cannot hang on errors */ 843 844 /* shut down modules */ 845 sim_module_uninstall (sd); 846 847 /* Ensure that any resources allocated through the callback 848 mechanism are released: */ 849 sim_io_shutdown (sd); 850 851#if defined(TRACE) 852 if (tracefh != NULL && tracefh != stderr) 853 fclose(tracefh); 854 tracefh = NULL; 855#endif /* TRACE */ 856 857 /* FIXME - free SD */ 858 859 return; 860} 861 862 863int 864sim_write (sd,addr,buffer,size) 865 SIM_DESC sd; 866 SIM_ADDR addr; 867 unsigned char *buffer; 868 int size; 869{ 870 int index; 871 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ 872 873 /* Return the number of bytes written, or zero if error. */ 874#ifdef DEBUG 875 sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size); 876#endif 877 878 /* We use raw read and write routines, since we do not want to count 879 the GDB memory accesses in our statistics gathering. */ 880 881 for (index = 0; index < size; index++) 882 { 883 address_word vaddr = (address_word)addr + index; 884 address_word paddr; 885 int cca; 886 if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW)) 887 break; 888 if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1) 889 break; 890 } 891 892 return(index); 893} 894 895int 896sim_read (sd,addr,buffer,size) 897 SIM_DESC sd; 898 SIM_ADDR addr; 899 unsigned char *buffer; 900 int size; 901{ 902 int index; 903 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ 904 905 /* Return the number of bytes read, or zero if error. */ 906#ifdef DEBUG 907 sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size); 908#endif /* DEBUG */ 909 910 for (index = 0; (index < size); index++) 911 { 912 address_word vaddr = (address_word)addr + index; 913 address_word paddr; 914 int cca; 915 if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW)) 916 break; 917 if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1) 918 break; 919 } 920 921 return(index); 922} 923 924int 925sim_store_register (sd,rn,memory,length) 926 SIM_DESC sd; 927 int rn; 928 unsigned char *memory; 929 int length; 930{ 931 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ 932 /* NOTE: gdb (the client) stores registers in target byte order 933 while the simulator uses host byte order */ 934#ifdef DEBUG 935 sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory))); 936#endif /* DEBUG */ 937 938 /* Unfortunately this suffers from the same problem as the register 939 numbering one. We need to know what the width of each logical 940 register number is for the architecture being simulated. */ 941 942 if (cpu->register_widths[rn] == 0) 943 { 944 sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn); 945 return 0; 946 } 947 948 949 950 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR) 951 { 952 cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted; 953 if (cpu->register_widths[rn] == 32) 954 { 955 if (length == 8) 956 { 957 cpu->fgr[rn - FGR_BASE] = 958 (unsigned32) T2H_8 (*(unsigned64*)memory); 959 return 8; 960 } 961 else 962 { 963 cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory); 964 return 4; 965 } 966 } 967 else 968 { 969 if (length == 8) 970 { 971 cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory); 972 return 8; 973 } 974 else 975 { 976 cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory); 977 return 4; 978 } 979 } 980 } 981 982 if (cpu->register_widths[rn] == 32) 983 { 984 if (length == 8) 985 { 986 cpu->registers[rn] = 987 (unsigned32) T2H_8 (*(unsigned64*)memory); 988 return 8; 989 } 990 else 991 { 992 cpu->registers[rn] = T2H_4 (*(unsigned32*)memory); 993 return 4; 994 } 995 } 996 else 997 { 998 if (length == 8) 999 { 1000 cpu->registers[rn] = T2H_8 (*(unsigned64*)memory); 1001 return 8; 1002 } 1003 else 1004 { 1005 cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory); 1006 return 4; 1007 } 1008 } 1009 1010 return 0; 1011} 1012 1013int 1014sim_fetch_register (sd,rn,memory,length) 1015 SIM_DESC sd; 1016 int rn; 1017 unsigned char *memory; 1018 int length; 1019{ 1020 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ 1021 /* NOTE: gdb (the client) stores registers in target byte order 1022 while the simulator uses host byte order */ 1023#ifdef DEBUG 1024#if 0 /* FIXME: doesn't compile */ 1025 sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn])); 1026#endif 1027#endif /* DEBUG */ 1028 1029 if (cpu->register_widths[rn] == 0) 1030 { 1031 sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn); 1032 return 0; 1033 } 1034 1035 1036 1037 /* Any floating point register */ 1038 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR) 1039 { 1040 if (cpu->register_widths[rn] == 32) 1041 { 1042 if (length == 8) 1043 { 1044 *(unsigned64*)memory = 1045 H2T_8 ((unsigned32) (cpu->fgr[rn - FGR_BASE])); 1046 return 8; 1047 } 1048 else 1049 { 1050 *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]); 1051 return 4; 1052 } 1053 } 1054 else 1055 { 1056 if (length == 8) 1057 { 1058 *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]); 1059 return 8; 1060 } 1061 else 1062 { 1063 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE])); 1064 return 4; 1065 } 1066 } 1067 } 1068 1069 if (cpu->register_widths[rn] == 32) 1070 { 1071 if (length == 8) 1072 { 1073 *(unsigned64*)memory = 1074 H2T_8 ((unsigned32) (cpu->registers[rn])); 1075 return 8; 1076 } 1077 else 1078 { 1079 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn])); 1080 return 4; 1081 } 1082 } 1083 else 1084 { 1085 if (length == 8) 1086 { 1087 *(unsigned64*)memory = 1088 H2T_8 ((unsigned64) (cpu->registers[rn])); 1089 return 8; 1090 } 1091 else 1092 { 1093 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn])); 1094 return 4; 1095 } 1096 } 1097 1098 return 0; 1099} 1100 1101 1102SIM_RC 1103sim_create_inferior (sd, abfd, argv,env) 1104 SIM_DESC sd; 1105 struct bfd *abfd; 1106 char **argv; 1107 char **env; 1108{ 1109 1110#ifdef DEBUG 1111#if 0 /* FIXME: doesn't compile */ 1112 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n", 1113 pr_addr(PC)); 1114#endif 1115#endif /* DEBUG */ 1116 1117 ColdReset(sd); 1118 1119 if (abfd != NULL) 1120 { 1121 /* override PC value set by ColdReset () */ 1122 int cpu_nr; 1123 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++) 1124 { 1125 sim_cpu *cpu = STATE_CPU (sd, cpu_nr); 1126 CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd)); 1127 } 1128 } 1129 1130#if 0 /* def DEBUG */ 1131 if (argv || env) 1132 { 1133 /* We should really place the argv slot values into the argument 1134 registers, and onto the stack as required. However, this 1135 assumes that we have a stack defined, which is not 1136 necessarily true at the moment. */ 1137 char **cptr; 1138 sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n"); 1139 for (cptr = argv; (cptr && *cptr); cptr++) 1140 printf("DBG: arg \"%s\"\n",*cptr); 1141 } 1142#endif /* DEBUG */ 1143 1144 return SIM_RC_OK; 1145} 1146 1147void 1148sim_do_command (sd,cmd) 1149 SIM_DESC sd; 1150 char *cmd; 1151{ 1152 if (sim_args_command (sd, cmd) != SIM_RC_OK) 1153 sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n", 1154 cmd); 1155} 1156 1157/*---------------------------------------------------------------------------*/ 1158/*-- Private simulator support interface ------------------------------------*/ 1159/*---------------------------------------------------------------------------*/ 1160 1161/* Read a null terminated string from memory, return in a buffer */ 1162static char * 1163fetch_str (SIM_DESC sd, 1164 address_word addr) 1165{ 1166 char *buf; 1167 int nr = 0; 1168 char null; 1169 while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0) 1170 nr++; 1171 buf = NZALLOC (char, nr + 1); 1172 sim_read (sd, addr, buf, nr); 1173 return buf; 1174} 1175 1176 1177/* Implements the "sim firmware" command: 1178 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME. 1179 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS 1180 defaults to the normal address for that monitor. 1181 sim firmware none --- don't emulate any ROM monitor. Useful 1182 if you need a clean address space. */ 1183static SIM_RC 1184sim_firmware_command (SIM_DESC sd, char *arg) 1185{ 1186 int address_present = 0; 1187 SIM_ADDR address; 1188 1189 /* Signal occurrence of this option. */ 1190 firmware_option_p = 1; 1191 1192 /* Parse out the address, if present. */ 1193 { 1194 char *p = strchr (arg, '@'); 1195 if (p) 1196 { 1197 char *q; 1198 address_present = 1; 1199 p ++; /* skip over @ */ 1200 1201 address = strtoul (p, &q, 0); 1202 if (*q != '\0') 1203 { 1204 sim_io_printf (sd, "Invalid address given to the" 1205 "`sim firmware NAME@ADDRESS' command: %s\n", 1206 p); 1207 return SIM_RC_FAIL; 1208 } 1209 } 1210 else 1211 { 1212 address_present = 0; 1213 address = -1; /* Dummy value. */ 1214 } 1215 } 1216 1217 if (! strncmp (arg, "idt", 3)) 1218 { 1219 idt_monitor_base = address_present ? address : 0xBFC00000; 1220 pmon_monitor_base = 0; 1221 lsipmon_monitor_base = 0; 1222 } 1223 else if (! strncmp (arg, "pmon", 4)) 1224 { 1225 /* pmon uses indirect calls. Hook into implied idt. */ 1226 pmon_monitor_base = address_present ? address : 0xBFC00500; 1227 idt_monitor_base = pmon_monitor_base - 0x500; 1228 lsipmon_monitor_base = 0; 1229 } 1230 else if (! strncmp (arg, "lsipmon", 7)) 1231 { 1232 /* lsipmon uses indirect calls. Hook into implied idt. */ 1233 pmon_monitor_base = 0; 1234 lsipmon_monitor_base = address_present ? address : 0xBFC00200; 1235 idt_monitor_base = lsipmon_monitor_base - 0x200; 1236 } 1237 else if (! strncmp (arg, "none", 4)) 1238 { 1239 if (address_present) 1240 { 1241 sim_io_printf (sd, 1242 "The `sim firmware none' command does " 1243 "not take an `ADDRESS' argument.\n"); 1244 return SIM_RC_FAIL; 1245 } 1246 idt_monitor_base = 0; 1247 pmon_monitor_base = 0; 1248 lsipmon_monitor_base = 0; 1249 } 1250 else 1251 { 1252 sim_io_printf (sd, "\ 1253Unrecognized name given to the `sim firmware NAME' command: %s\n\ 1254Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n", 1255 arg); 1256 return SIM_RC_FAIL; 1257 } 1258 1259 return SIM_RC_OK; 1260} 1261 1262 1263 1264/* Simple monitor interface (currently setup for the IDT and PMON monitors) */ 1265int 1266sim_monitor (SIM_DESC sd, 1267 sim_cpu *cpu, 1268 address_word cia, 1269 unsigned int reason) 1270{ 1271#ifdef DEBUG 1272 printf("DBG: sim_monitor: entered (reason = %d)\n",reason); 1273#endif /* DEBUG */ 1274 1275 /* The IDT monitor actually allows two instructions per vector 1276 slot. However, the simulator currently causes a trap on each 1277 individual instruction. We cheat, and lose the bottom bit. */ 1278 reason >>= 1; 1279 1280 /* The following callback functions are available, however the 1281 monitor we are simulating does not make use of them: get_errno, 1282 isatty, lseek, rename, system, time and unlink */ 1283 switch (reason) 1284 { 1285 1286 case 6: /* int open(char *path,int flags) */ 1287 { 1288 char *path = fetch_str (sd, A0); 1289 V0 = sim_io_open (sd, path, (int)A1); 1290 zfree (path); 1291 break; 1292 } 1293 1294 case 7: /* int read(int file,char *ptr,int len) */ 1295 { 1296 int fd = A0; 1297 int nr = A2; 1298 char *buf = zalloc (nr); 1299 V0 = sim_io_read (sd, fd, buf, nr); 1300 sim_write (sd, A1, buf, nr); 1301 zfree (buf); 1302 } 1303 break; 1304 1305 case 8: /* int write(int file,char *ptr,int len) */ 1306 { 1307 int fd = A0; 1308 int nr = A2; 1309 char *buf = zalloc (nr); 1310 sim_read (sd, A1, buf, nr); 1311 V0 = sim_io_write (sd, fd, buf, nr); 1312 if (fd == 1) 1313 sim_io_flush_stdout (sd); 1314 else if (fd == 2) 1315 sim_io_flush_stderr (sd); 1316 zfree (buf); 1317 break; 1318 } 1319 1320 case 10: /* int close(int file) */ 1321 { 1322 V0 = sim_io_close (sd, (int)A0); 1323 break; 1324 } 1325 1326 case 2: /* Densan monitor: char inbyte(int waitflag) */ 1327 { 1328 if (A0 == 0) /* waitflag == NOWAIT */ 1329 V0 = (unsigned_word)-1; 1330 } 1331 /* Drop through to case 11 */ 1332 1333 case 11: /* char inbyte(void) */ 1334 { 1335 char tmp; 1336 /* ensure that all output has gone... */ 1337 sim_io_flush_stdout (sd); 1338 if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char)) 1339 { 1340 sim_io_error(sd,"Invalid return from character read"); 1341 V0 = (unsigned_word)-1; 1342 } 1343 else 1344 V0 = (unsigned_word)tmp; 1345 break; 1346 } 1347 1348 case 3: /* Densan monitor: void co(char chr) */ 1349 case 12: /* void outbyte(char chr) : write a byte to "stdout" */ 1350 { 1351 char tmp = (char)(A0 & 0xFF); 1352 sim_io_write_stdout (sd, &tmp, sizeof(char)); 1353 break; 1354 } 1355 1356 case 17: /* void _exit() */ 1357 { 1358 sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n"); 1359 sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited, 1360 (unsigned int)(A0 & 0xFFFFFFFF)); 1361 break; 1362 } 1363 1364 case 28: /* PMON flush_cache */ 1365 break; 1366 1367 case 55: /* void get_mem_info(unsigned int *ptr) */ 1368 /* in: A0 = pointer to three word memory location */ 1369 /* out: [A0 + 0] = size */ 1370 /* [A0 + 4] = instruction cache size */ 1371 /* [A0 + 8] = data cache size */ 1372 { 1373 unsigned_4 value; 1374 unsigned_4 zero = 0; 1375 address_word mem_size; 1376 sim_memopt *entry, *match = NULL; 1377 1378 /* Search for memory region mapped to KSEG0 or KSEG1. */ 1379 for (entry = STATE_MEMOPT (sd); 1380 entry != NULL; 1381 entry = entry->next) 1382 { 1383 if ((entry->addr == K0BASE || entry->addr == K1BASE) 1384 && (!match || entry->level < match->level)) 1385 match = entry; 1386 else 1387 { 1388 sim_memopt *alias; 1389 for (alias = entry->alias; 1390 alias != NULL; 1391 alias = alias->next) 1392 if ((alias->addr == K0BASE || alias->addr == K1BASE) 1393 && (!match || entry->level < match->level)) 1394 match = entry; 1395 } 1396 } 1397 1398 /* Get region size, limit to KSEG1 size (512MB). */ 1399 SIM_ASSERT (match != NULL); 1400 mem_size = (match->modulo != 0 1401 ? match->modulo : match->nr_bytes); 1402 if (mem_size > K1SIZE) 1403 mem_size = K1SIZE; 1404 1405 value = mem_size; 1406 H2T (value); 1407 sim_write (sd, A0 + 0, (char *)&value, 4); 1408 sim_write (sd, A0 + 4, (char *)&zero, 4); 1409 sim_write (sd, A0 + 8, (char *)&zero, 4); 1410 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */ 1411 break; 1412 } 1413 1414 case 158: /* PMON printf */ 1415 /* in: A0 = pointer to format string */ 1416 /* A1 = optional argument 1 */ 1417 /* A2 = optional argument 2 */ 1418 /* A3 = optional argument 3 */ 1419 /* out: void */ 1420 /* The following is based on the PMON printf source */ 1421 { 1422 address_word s = A0; 1423 char c; 1424 signed_word *ap = &A1; /* 1st argument */ 1425 /* This isn't the quickest way, since we call the host print 1426 routine for every character almost. But it does avoid 1427 having to allocate and manage a temporary string buffer. */ 1428 /* TODO: Include check that we only use three arguments (A1, 1429 A2 and A3) */ 1430 while (sim_read (sd, s++, &c, 1) && c != '\0') 1431 { 1432 if (c == '%') 1433 { 1434 char tmp[40]; 1435 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST; 1436 int width = 0, trunc = 0, haddot = 0, longlong = 0; 1437 while (sim_read (sd, s++, &c, 1) && c != '\0') 1438 { 1439 if (strchr ("dobxXulscefg%", c)) 1440 break; 1441 else if (c == '-') 1442 fmt = FMT_LJUST; 1443 else if (c == '0') 1444 fmt = FMT_RJUST0; 1445 else if (c == '~') 1446 fmt = FMT_CENTER; 1447 else if (c == '*') 1448 { 1449 if (haddot) 1450 trunc = (int)*ap++; 1451 else 1452 width = (int)*ap++; 1453 } 1454 else if (c >= '1' && c <= '9') 1455 { 1456 address_word t = s; 1457 unsigned int n; 1458 while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c)) 1459 tmp[s - t] = c; 1460 tmp[s - t] = '\0'; 1461 n = (unsigned int)strtol(tmp,NULL,10); 1462 if (haddot) 1463 trunc = n; 1464 else 1465 width = n; 1466 s--; 1467 } 1468 else if (c == '.') 1469 haddot = 1; 1470 } 1471 switch (c) 1472 { 1473 case '%': 1474 sim_io_printf (sd, "%%"); 1475 break; 1476 case 's': 1477 if ((int)*ap != 0) 1478 { 1479 address_word p = *ap++; 1480 char ch; 1481 while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0') 1482 sim_io_printf(sd, "%c", ch); 1483 } 1484 else 1485 sim_io_printf(sd,"(null)"); 1486 break; 1487 case 'c': 1488 sim_io_printf (sd, "%c", (int)*ap++); 1489 break; 1490 default: 1491 if (c == 'l') 1492 { 1493 sim_read (sd, s++, &c, 1); 1494 if (c == 'l') 1495 { 1496 longlong = 1; 1497 sim_read (sd, s++, &c, 1); 1498 } 1499 } 1500 if (strchr ("dobxXu", c)) 1501 { 1502 word64 lv = (word64) *ap++; 1503 if (c == 'b') 1504 sim_io_printf(sd,"<binary not supported>"); 1505 else 1506 { 1507 sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c); 1508 if (longlong) 1509 sim_io_printf(sd, tmp, lv); 1510 else 1511 sim_io_printf(sd, tmp, (int)lv); 1512 } 1513 } 1514 else if (strchr ("eEfgG", c)) 1515 { 1516 double dbl = *(double*)(ap++); 1517 sprintf (tmp, "%%%d.%d%c", width, trunc, c); 1518 sim_io_printf (sd, tmp, dbl); 1519 trunc = 0; 1520 } 1521 } 1522 } 1523 else 1524 sim_io_printf(sd, "%c", c); 1525 } 1526 break; 1527 } 1528 1529 default: 1530 /* Unknown reason. */ 1531 return 0; 1532 } 1533 return 1; 1534} 1535 1536/* Store a word into memory. */ 1537 1538static void 1539store_word (SIM_DESC sd, 1540 sim_cpu *cpu, 1541 address_word cia, 1542 uword64 vaddr, 1543 signed_word val) 1544{ 1545 address_word paddr; 1546 int uncached; 1547 1548 if ((vaddr & 3) != 0) 1549 SignalExceptionAddressStore (); 1550 else 1551 { 1552 if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, 1553 isTARGET, isREAL)) 1554 { 1555 const uword64 mask = 7; 1556 uword64 memval; 1557 unsigned int byte; 1558 1559 paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)); 1560 byte = (vaddr & mask) ^ (BigEndianCPU << 2); 1561 memval = ((uword64) val) << (8 * byte); 1562 StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr, 1563 isREAL); 1564 } 1565 } 1566} 1567 1568/* Load a word from memory. */ 1569 1570static signed_word 1571load_word (SIM_DESC sd, 1572 sim_cpu *cpu, 1573 address_word cia, 1574 uword64 vaddr) 1575{ 1576 if ((vaddr & 3) != 0) 1577 { 1578 SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal); 1579 } 1580 else 1581 { 1582 address_word paddr; 1583 int uncached; 1584 1585 if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, 1586 isTARGET, isREAL)) 1587 { 1588 const uword64 mask = 0x7; 1589 const unsigned int reverse = ReverseEndian ? 1 : 0; 1590 const unsigned int bigend = BigEndianCPU ? 1 : 0; 1591 uword64 memval; 1592 unsigned int byte; 1593 1594 paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2)); 1595 LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr, 1596 isDATA, isREAL); 1597 byte = (vaddr & mask) ^ (bigend << 2); 1598 return EXTEND32 (memval >> (8 * byte)); 1599 } 1600 } 1601 1602 return 0; 1603} 1604 1605/* Simulate the mips16 entry and exit pseudo-instructions. These 1606 would normally be handled by the reserved instruction exception 1607 code, but for ease of simulation we just handle them directly. */ 1608 1609static void 1610mips16_entry (SIM_DESC sd, 1611 sim_cpu *cpu, 1612 address_word cia, 1613 unsigned int insn) 1614{ 1615 int aregs, sregs, rreg; 1616 1617#ifdef DEBUG 1618 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn); 1619#endif /* DEBUG */ 1620 1621 aregs = (insn & 0x700) >> 8; 1622 sregs = (insn & 0x0c0) >> 6; 1623 rreg = (insn & 0x020) >> 5; 1624 1625 /* This should be checked by the caller. */ 1626 if (sregs == 3) 1627 abort (); 1628 1629 if (aregs < 5) 1630 { 1631 int i; 1632 signed_word tsp; 1633 1634 /* This is the entry pseudo-instruction. */ 1635 1636 for (i = 0; i < aregs; i++) 1637 store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]); 1638 1639 tsp = SP; 1640 SP -= 32; 1641 1642 if (rreg) 1643 { 1644 tsp -= 4; 1645 store_word (SD, CPU, cia, (uword64) tsp, RA); 1646 } 1647 1648 for (i = 0; i < sregs; i++) 1649 { 1650 tsp -= 4; 1651 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]); 1652 } 1653 } 1654 else 1655 { 1656 int i; 1657 signed_word tsp; 1658 1659 /* This is the exit pseudo-instruction. */ 1660 1661 tsp = SP + 32; 1662 1663 if (rreg) 1664 { 1665 tsp -= 4; 1666 RA = load_word (SD, CPU, cia, (uword64) tsp); 1667 } 1668 1669 for (i = 0; i < sregs; i++) 1670 { 1671 tsp -= 4; 1672 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp); 1673 } 1674 1675 SP += 32; 1676 1677 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT) 1678 { 1679 if (aregs == 5) 1680 { 1681 FGR[0] = WORD64LO (GPR[4]); 1682 FPR_STATE[0] = fmt_uninterpreted; 1683 } 1684 else if (aregs == 6) 1685 { 1686 FGR[0] = WORD64LO (GPR[5]); 1687 FGR[1] = WORD64LO (GPR[4]); 1688 FPR_STATE[0] = fmt_uninterpreted; 1689 FPR_STATE[1] = fmt_uninterpreted; 1690 } 1691 } 1692 1693 PC = RA; 1694 } 1695 1696} 1697 1698/*-- trace support ----------------------------------------------------------*/ 1699 1700/* The TRACE support is provided (if required) in the memory accessing 1701 routines. Since we are also providing the architecture specific 1702 features, the architecture simulation code can also deal with 1703 notifying the TRACE world of cache flushes, etc. Similarly we do 1704 not need to provide profiling support in the simulator engine, 1705 since we can sample in the instruction fetch control loop. By 1706 defining the TRACE manifest, we add tracing as a run-time 1707 option. */ 1708 1709#if defined(TRACE) 1710/* Tracing by default produces "din" format (as required by 1711 dineroIII). Each line of such a trace file *MUST* have a din label 1712 and address field. The rest of the line is ignored, so comments can 1713 be included if desired. The first field is the label which must be 1714 one of the following values: 1715 1716 0 read data 1717 1 write data 1718 2 instruction fetch 1719 3 escape record (treated as unknown access type) 1720 4 escape record (causes cache flush) 1721 1722 The address field is a 32bit (lower-case) hexadecimal address 1723 value. The address should *NOT* be preceded by "0x". 1724 1725 The size of the memory transfer is not important when dealing with 1726 cache lines (as long as no more than a cache line can be 1727 transferred in a single operation :-), however more information 1728 could be given following the dineroIII requirement to allow more 1729 complete memory and cache simulators to provide better 1730 results. i.e. the University of Pisa has a cache simulator that can 1731 also take bus size and speed as (variable) inputs to calculate 1732 complete system performance (a much more useful ability when trying 1733 to construct an end product, rather than a processor). They 1734 currently have an ARM version of their tool called ChARM. */ 1735 1736 1737void 1738dotrace (SIM_DESC sd, 1739 sim_cpu *cpu, 1740 FILE *tracefh, 1741 int type, 1742 SIM_ADDR address, 1743 int width, 1744 char *comment,...) 1745{ 1746 if (STATE & simTRACE) { 1747 va_list ap; 1748 fprintf(tracefh,"%d %s ; width %d ; ", 1749 type, 1750 pr_addr(address), 1751 width); 1752 va_start(ap,comment); 1753 vfprintf(tracefh,comment,ap); 1754 va_end(ap); 1755 fprintf(tracefh,"\n"); 1756 } 1757 /* NOTE: Since the "din" format will only accept 32bit addresses, and 1758 we may be generating 64bit ones, we should put the hi-32bits of the 1759 address into the comment field. */ 1760 1761 /* TODO: Provide a buffer for the trace lines. We can then avoid 1762 performing writes until the buffer is filled, or the file is 1763 being closed. */ 1764 1765 /* NOTE: We could consider adding a comment field to the "din" file 1766 produced using type 3 markers (unknown access). This would then 1767 allow information about the program that the "din" is for, and 1768 the MIPs world that was being simulated, to be placed into the 1769 trace file. */ 1770 1771 return; 1772} 1773#endif /* TRACE */ 1774 1775/*---------------------------------------------------------------------------*/ 1776/*-- simulator engine -------------------------------------------------------*/ 1777/*---------------------------------------------------------------------------*/ 1778 1779static void 1780ColdReset (SIM_DESC sd) 1781{ 1782 int cpu_nr; 1783 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++) 1784 { 1785 sim_cpu *cpu = STATE_CPU (sd, cpu_nr); 1786 /* RESET: Fixed PC address: */ 1787 PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000); 1788 /* The reset vector address is in the unmapped, uncached memory space. */ 1789 1790 SR &= ~(status_SR | status_TS | status_RP); 1791 SR |= (status_ERL | status_BEV); 1792 1793 /* Cheat and allow access to the complete register set immediately */ 1794 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT 1795 && WITH_TARGET_WORD_BITSIZE == 64) 1796 SR |= status_FR; /* 64bit registers */ 1797 1798 /* Ensure that any instructions with pending register updates are 1799 cleared: */ 1800 PENDING_INVALIDATE(); 1801 1802 /* Initialise the FPU registers to the unknown state */ 1803 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT) 1804 { 1805 int rn; 1806 for (rn = 0; (rn < 32); rn++) 1807 FPR_STATE[rn] = fmt_uninterpreted; 1808 } 1809 1810 /* Initialise the Config0 register. */ 1811 C0_CONFIG = 0x80000000 /* Config1 present */ 1812 | 2; /* KSEG0 uncached */ 1813 if (WITH_TARGET_WORD_BITSIZE == 64) 1814 { 1815 /* FIXME Currently mips/sim-main.c:address_translation() 1816 truncates all addresses to 32-bits. */ 1817 if (0 && WITH_TARGET_ADDRESS_BITSIZE == 64) 1818 C0_CONFIG |= (2 << 13); /* MIPS64, 64-bit addresses */ 1819 else 1820 C0_CONFIG |= (1 << 13); /* MIPS64, 32-bit addresses */ 1821 } 1822 if (BigEndianMem) 1823 C0_CONFIG |= 0x00008000; /* Big Endian */ 1824 } 1825} 1826 1827 1828 1829 1830/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */ 1831/* Signal an exception condition. This will result in an exception 1832 that aborts the instruction. The instruction operation pseudocode 1833 will never see a return from this function call. */ 1834 1835void 1836signal_exception (SIM_DESC sd, 1837 sim_cpu *cpu, 1838 address_word cia, 1839 int exception,...) 1840{ 1841 /* int vector; */ 1842 1843#ifdef DEBUG 1844 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia)); 1845#endif /* DEBUG */ 1846 1847 /* Ensure that any active atomic read/modify/write operation will fail: */ 1848 LLBIT = 0; 1849 1850 /* Save registers before interrupt dispatching */ 1851#ifdef SIM_CPU_EXCEPTION_TRIGGER 1852 SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia); 1853#endif 1854 1855 switch (exception) { 1856 1857 case DebugBreakPoint: 1858 if (! (Debug & Debug_DM)) 1859 { 1860 if (INDELAYSLOT()) 1861 { 1862 CANCELDELAYSLOT(); 1863 1864 Debug |= Debug_DBD; /* signaled from within in delay slot */ 1865 DEPC = cia - 4; /* reference the branch instruction */ 1866 } 1867 else 1868 { 1869 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */ 1870 DEPC = cia; 1871 } 1872 1873 Debug |= Debug_DM; /* in debugging mode */ 1874 Debug |= Debug_DBp; /* raising a DBp exception */ 1875 PC = 0xBFC00200; 1876 sim_engine_restart (SD, CPU, NULL, NULL_CIA); 1877 } 1878 break; 1879 1880 case ReservedInstruction: 1881 { 1882 va_list ap; 1883 unsigned int instruction; 1884 va_start(ap,exception); 1885 instruction = va_arg(ap,unsigned int); 1886 va_end(ap); 1887 /* Provide simple monitor support using ReservedInstruction 1888 exceptions. The following code simulates the fixed vector 1889 entry points into the IDT monitor by causing a simulator 1890 trap, performing the monitor operation, and returning to 1891 the address held in the $ra register (standard PCS return 1892 address). This means we only need to pre-load the vector 1893 space with suitable instruction values. For systems were 1894 actual trap instructions are used, we would not need to 1895 perform this magic. */ 1896 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION) 1897 { 1898 int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK; 1899 if (!sim_monitor (SD, CPU, cia, reason)) 1900 sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia)); 1901 1902 /* NOTE: This assumes that a branch-and-link style 1903 instruction was used to enter the vector (which is the 1904 case with the current IDT monitor). */ 1905 sim_engine_restart (SD, CPU, NULL, RA); 1906 } 1907 /* Look for the mips16 entry and exit instructions, and 1908 simulate a handler for them. */ 1909 else if ((cia & 1) != 0 1910 && (instruction & 0xf81f) == 0xe809 1911 && (instruction & 0x0c0) != 0x0c0) 1912 { 1913 mips16_entry (SD, CPU, cia, instruction); 1914 sim_engine_restart (sd, NULL, NULL, NULL_CIA); 1915 } 1916 /* else fall through to normal exception processing */ 1917 sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia)); 1918 } 1919 1920 default: 1921 /* Store exception code into current exception id variable (used 1922 by exit code): */ 1923 1924 /* TODO: If not simulating exceptions then stop the simulator 1925 execution. At the moment we always stop the simulation. */ 1926 1927#ifdef SUBTARGET_R3900 1928 /* update interrupt-related registers */ 1929 1930 /* insert exception code in bits 6:2 */ 1931 CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2); 1932 /* shift IE/KU history bits left */ 1933 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2); 1934 1935 if (STATE & simDELAYSLOT) 1936 { 1937 STATE &= ~simDELAYSLOT; 1938 CAUSE |= cause_BD; 1939 EPC = (cia - 4); /* reference the branch instruction */ 1940 } 1941 else 1942 EPC = cia; 1943 1944 if (SR & status_BEV) 1945 PC = (signed)0xBFC00000 + 0x180; 1946 else 1947 PC = (signed)0x80000000 + 0x080; 1948#else 1949 /* See figure 5-17 for an outline of the code below */ 1950 if (! (SR & status_EXL)) 1951 { 1952 CAUSE = (exception << 2); 1953 if (STATE & simDELAYSLOT) 1954 { 1955 STATE &= ~simDELAYSLOT; 1956 CAUSE |= cause_BD; 1957 EPC = (cia - 4); /* reference the branch instruction */ 1958 } 1959 else 1960 EPC = cia; 1961 /* FIXME: TLB et.al. */ 1962 /* vector = 0x180; */ 1963 } 1964 else 1965 { 1966 CAUSE = (exception << 2); 1967 /* vector = 0x180; */ 1968 } 1969 SR |= status_EXL; 1970 /* Store exception code into current exception id variable (used 1971 by exit code): */ 1972 1973 if (SR & status_BEV) 1974 PC = (signed)0xBFC00200 + 0x180; 1975 else 1976 PC = (signed)0x80000000 + 0x180; 1977#endif 1978 1979 switch ((CAUSE >> 2) & 0x1F) 1980 { 1981 case Interrupt: 1982 /* Interrupts arrive during event processing, no need to 1983 restart */ 1984 return; 1985 1986 case NMIReset: 1987 /* Ditto */ 1988#ifdef SUBTARGET_3900 1989 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */ 1990 PC = (signed)0xBFC00000; 1991#endif /* SUBTARGET_3900 */ 1992 return; 1993 1994 case TLBModification: 1995 case TLBLoad: 1996 case TLBStore: 1997 case AddressLoad: 1998 case AddressStore: 1999 case InstructionFetch: 2000 case DataReference: 2001 /* The following is so that the simulator will continue from the 2002 exception handler address. */ 2003 sim_engine_halt (SD, CPU, NULL, PC, 2004 sim_stopped, SIM_SIGBUS); 2005 2006 case ReservedInstruction: 2007 case CoProcessorUnusable: 2008 PC = EPC; 2009 sim_engine_halt (SD, CPU, NULL, PC, 2010 sim_stopped, SIM_SIGILL); 2011 2012 case IntegerOverflow: 2013 case FPE: 2014 sim_engine_halt (SD, CPU, NULL, PC, 2015 sim_stopped, SIM_SIGFPE); 2016 2017 case BreakPoint: 2018 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP); 2019 break; 2020 2021 case SystemCall: 2022 case Trap: 2023 sim_engine_restart (SD, CPU, NULL, PC); 2024 break; 2025 2026 case Watch: 2027 PC = EPC; 2028 sim_engine_halt (SD, CPU, NULL, PC, 2029 sim_stopped, SIM_SIGTRAP); 2030 2031 default: /* Unknown internal exception */ 2032 PC = EPC; 2033 sim_engine_halt (SD, CPU, NULL, PC, 2034 sim_stopped, SIM_SIGABRT); 2035 2036 } 2037 2038 case SimulatorFault: 2039 { 2040 va_list ap; 2041 char *msg; 2042 va_start(ap,exception); 2043 msg = va_arg(ap,char *); 2044 va_end(ap); 2045 sim_engine_abort (SD, CPU, NULL_CIA, 2046 "FATAL: Simulator error \"%s\"\n",msg); 2047 } 2048 } 2049 2050 return; 2051} 2052 2053 2054 2055/* This function implements what the MIPS32 and MIPS64 ISAs define as 2056 "UNPREDICTABLE" behaviour. 2057 2058 About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results 2059 may vary from processor implementation to processor implementation, 2060 instruction to instruction, or as a function of time on the same 2061 implementation or instruction. Software can never depend on results 2062 that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers 2063 Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision 2064 0.95, page 2.) 2065 2066 For UNPREDICTABLE behaviour, we print a message, if possible print 2067 the offending instructions mips.igen instruction name (provided by 2068 the caller), and stop the simulator. 2069 2070 XXX FIXME: eventually, stopping the simulator should be made conditional 2071 on a command-line option. */ 2072void 2073unpredictable_action(sim_cpu *cpu, address_word cia) 2074{ 2075 SIM_DESC sd = CPU_STATE(cpu); 2076 2077 sim_io_eprintf(sd, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia)); 2078 sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGABRT); 2079} 2080 2081 2082/*-- co-processor support routines ------------------------------------------*/ 2083 2084static int UNUSED 2085CoProcPresent(unsigned int coproc_number) 2086{ 2087 /* Return TRUE if simulator provides a model for the given co-processor number */ 2088 return(0); 2089} 2090 2091void 2092cop_lw (SIM_DESC sd, 2093 sim_cpu *cpu, 2094 address_word cia, 2095 int coproc_num, 2096 int coproc_reg, 2097 unsigned int memword) 2098{ 2099 switch (coproc_num) 2100 { 2101 case 1: 2102 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT) 2103 { 2104#ifdef DEBUG 2105 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword)); 2106#endif 2107 StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword); 2108 break; 2109 } 2110 2111 default: 2112#if 0 /* this should be controlled by a configuration option */ 2113 sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia)); 2114#endif 2115 break; 2116 } 2117 2118 return; 2119} 2120 2121void 2122cop_ld (SIM_DESC sd, 2123 sim_cpu *cpu, 2124 address_word cia, 2125 int coproc_num, 2126 int coproc_reg, 2127 uword64 memword) 2128{ 2129 2130#ifdef DEBUG 2131 printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num, coproc_reg, pr_uword64(memword), pr_addr(cia) ); 2132#endif 2133 2134 switch (coproc_num) { 2135 case 1: 2136 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT) 2137 { 2138 StoreFPR(coproc_reg,fmt_uninterpreted_64,memword); 2139 break; 2140 } 2141 2142 default: 2143#if 0 /* this message should be controlled by a configuration option */ 2144 sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia)); 2145#endif 2146 break; 2147 } 2148 2149 return; 2150} 2151 2152 2153 2154 2155unsigned int 2156cop_sw (SIM_DESC sd, 2157 sim_cpu *cpu, 2158 address_word cia, 2159 int coproc_num, 2160 int coproc_reg) 2161{ 2162 unsigned int value = 0; 2163 2164 switch (coproc_num) 2165 { 2166 case 1: 2167 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT) 2168 { 2169 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32); 2170 break; 2171 } 2172 2173 default: 2174#if 0 /* should be controlled by configuration option */ 2175 sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia)); 2176#endif 2177 break; 2178 } 2179 2180 return(value); 2181} 2182 2183uword64 2184cop_sd (SIM_DESC sd, 2185 sim_cpu *cpu, 2186 address_word cia, 2187 int coproc_num, 2188 int coproc_reg) 2189{ 2190 uword64 value = 0; 2191 switch (coproc_num) 2192 { 2193 case 1: 2194 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT) 2195 { 2196 value = ValueFPR(coproc_reg,fmt_uninterpreted_64); 2197 break; 2198 } 2199 2200 default: 2201#if 0 /* should be controlled by configuration option */ 2202 sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia)); 2203#endif 2204 break; 2205 } 2206 2207 return(value); 2208} 2209 2210 2211 2212 2213void 2214decode_coproc (SIM_DESC sd, 2215 sim_cpu *cpu, 2216 address_word cia, 2217 unsigned int instruction) 2218{ 2219 int coprocnum = ((instruction >> 26) & 3); 2220 2221 switch (coprocnum) 2222 { 2223 case 0: /* standard CPU control and cache registers */ 2224 { 2225 int code = ((instruction >> 21) & 0x1F); 2226 int rt = ((instruction >> 16) & 0x1F); 2227 int rd = ((instruction >> 11) & 0x1F); 2228 int tail = instruction & 0x3ff; 2229 /* R4000 Users Manual (second edition) lists the following CP0 2230 instructions: 2231 CODE><-RT><RD-><--TAIL---> 2232 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000) 2233 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000) 2234 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000) 2235 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000) 2236 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001) 2237 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010) 2238 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110) 2239 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000) 2240 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii) 2241 ERET Exception return (VR4100 = 01000010000000000000000000011000) 2242 */ 2243 if (((code == 0x00) || (code == 0x04) /* MFC0 / MTC0 */ 2244 || (code == 0x01) || (code == 0x05)) /* DMFC0 / DMTC0 */ 2245 && tail == 0) 2246 { 2247 /* Clear double/single coprocessor move bit. */ 2248 code &= ~1; 2249 2250 /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */ 2251 2252 switch (rd) /* NOTEs: Standard CP0 registers */ 2253 { 2254 /* 0 = Index R4000 VR4100 VR4300 */ 2255 /* 1 = Random R4000 VR4100 VR4300 */ 2256 /* 2 = EntryLo0 R4000 VR4100 VR4300 */ 2257 /* 3 = EntryLo1 R4000 VR4100 VR4300 */ 2258 /* 4 = Context R4000 VR4100 VR4300 */ 2259 /* 5 = PageMask R4000 VR4100 VR4300 */ 2260 /* 6 = Wired R4000 VR4100 VR4300 */ 2261 /* 8 = BadVAddr R4000 VR4100 VR4300 */ 2262 /* 9 = Count R4000 VR4100 VR4300 */ 2263 /* 10 = EntryHi R4000 VR4100 VR4300 */ 2264 /* 11 = Compare R4000 VR4100 VR4300 */ 2265 /* 12 = SR R4000 VR4100 VR4300 */ 2266#ifdef SUBTARGET_R3900 2267 case 3: 2268 /* 3 = Config R3900 */ 2269 case 7: 2270 /* 7 = Cache R3900 */ 2271 case 15: 2272 /* 15 = PRID R3900 */ 2273 2274 /* ignore */ 2275 break; 2276 2277 case 8: 2278 /* 8 = BadVAddr R4000 VR4100 VR4300 */ 2279 if (code == 0x00) 2280 GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR; 2281 else 2282 COP0_BADVADDR = GPR[rt]; 2283 break; 2284 2285#endif /* SUBTARGET_R3900 */ 2286 case 12: 2287 if (code == 0x00) 2288 GPR[rt] = SR; 2289 else 2290 SR = GPR[rt]; 2291 break; 2292 /* 13 = Cause R4000 VR4100 VR4300 */ 2293 case 13: 2294 if (code == 0x00) 2295 GPR[rt] = CAUSE; 2296 else 2297 CAUSE = GPR[rt]; 2298 break; 2299 /* 14 = EPC R4000 VR4100 VR4300 */ 2300 case 14: 2301 if (code == 0x00) 2302 GPR[rt] = (signed_word) (signed_address) EPC; 2303 else 2304 EPC = GPR[rt]; 2305 break; 2306 /* 15 = PRId R4000 VR4100 VR4300 */ 2307#ifdef SUBTARGET_R3900 2308 /* 16 = Debug */ 2309 case 16: 2310 if (code == 0x00) 2311 GPR[rt] = Debug; 2312 else 2313 Debug = GPR[rt]; 2314 break; 2315#else 2316 /* 16 = Config R4000 VR4100 VR4300 */ 2317 case 16: 2318 if (code == 0x00) 2319 GPR[rt] = C0_CONFIG; 2320 else 2321 /* only bottom three bits are writable */ 2322 C0_CONFIG = (C0_CONFIG & ~0x7) | (GPR[rt] & 0x7); 2323 break; 2324#endif 2325#ifdef SUBTARGET_R3900 2326 /* 17 = Debug */ 2327 case 17: 2328 if (code == 0x00) 2329 GPR[rt] = DEPC; 2330 else 2331 DEPC = GPR[rt]; 2332 break; 2333#else 2334 /* 17 = LLAddr R4000 VR4100 VR4300 */ 2335#endif 2336 /* 18 = WatchLo R4000 VR4100 VR4300 */ 2337 /* 19 = WatchHi R4000 VR4100 VR4300 */ 2338 /* 20 = XContext R4000 VR4100 VR4300 */ 2339 /* 26 = PErr or ECC R4000 VR4100 VR4300 */ 2340 /* 27 = CacheErr R4000 VR4100 */ 2341 /* 28 = TagLo R4000 VR4100 VR4300 */ 2342 /* 29 = TagHi R4000 VR4100 VR4300 */ 2343 /* 30 = ErrorEPC R4000 VR4100 VR4300 */ 2344 if (STATE_VERBOSE_P(SD)) 2345 sim_io_eprintf (SD, 2346 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n", 2347 (unsigned long)cia); 2348 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */ 2349 /* CPR[0,rd] = GPR[rt]; */ 2350 default: 2351 if (code == 0x00) 2352 GPR[rt] = (signed_word) (signed32) COP0_GPR[rd]; 2353 else 2354 COP0_GPR[rd] = GPR[rt]; 2355#if 0 2356 if (code == 0x00) 2357 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia); 2358 else 2359 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia); 2360#endif 2361 } 2362 } 2363 else if ((code == 0x00 || code == 0x01) 2364 && rd == 16) 2365 { 2366 /* [D]MFC0 RT,C0_CONFIG,SEL */ 2367 signed32 cfg = 0; 2368 switch (tail & 0x07) 2369 { 2370 case 0: 2371 cfg = C0_CONFIG; 2372 break; 2373 case 1: 2374 /* MIPS32 r/o Config1: 2375 Config2 present */ 2376 cfg = 0x80000000; 2377 /* MIPS16 implemented. 2378 XXX How to check configuration? */ 2379 cfg |= 0x0000004; 2380 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT) 2381 /* MDMX & FPU implemented */ 2382 cfg |= 0x00000021; 2383 break; 2384 case 2: 2385 /* MIPS32 r/o Config2: 2386 Config3 present. */ 2387 cfg = 0x80000000; 2388 break; 2389 case 3: 2390 /* MIPS32 r/o Config3: 2391 SmartMIPS implemented. */ 2392 cfg = 0x00000002; 2393 break; 2394 } 2395 GPR[rt] = cfg; 2396 } 2397 else if (code == 0x10 && (tail & 0x3f) == 0x18) 2398 { 2399 /* ERET */ 2400 if (SR & status_ERL) 2401 { 2402 /* Oops, not yet available */ 2403 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet"); 2404 PC = EPC; 2405 SR &= ~status_ERL; 2406 } 2407 else 2408 { 2409 PC = EPC; 2410 SR &= ~status_EXL; 2411 } 2412 } 2413 else if (code == 0x10 && (tail & 0x3f) == 0x10) 2414 { 2415 /* RFE */ 2416#ifdef SUBTARGET_R3900 2417 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */ 2418 2419 /* shift IE/KU history bits right */ 2420 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0); 2421 2422 /* TODO: CACHE register */ 2423#endif /* SUBTARGET_R3900 */ 2424 } 2425 else if (code == 0x10 && (tail & 0x3f) == 0x1F) 2426 { 2427 /* DERET */ 2428 Debug &= ~Debug_DM; 2429 DELAYSLOT(); 2430 DSPC = DEPC; 2431 } 2432 else 2433 sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia)); 2434 /* TODO: When executing an ERET or RFE instruction we should 2435 clear LLBIT, to ensure that any out-standing atomic 2436 read/modify/write sequence fails. */ 2437 } 2438 break; 2439 2440 case 2: /* co-processor 2 */ 2441 { 2442 int handle = 0; 2443 2444 2445 if(! handle) 2446 { 2447 sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n", 2448 instruction,pr_addr(cia)); 2449 } 2450 } 2451 break; 2452 2453 case 1: /* should not occur (FPU co-processor) */ 2454 case 3: /* should not occur (FPU co-processor) */ 2455 SignalException(ReservedInstruction,instruction); 2456 break; 2457 } 2458 2459 return; 2460} 2461 2462 2463/* This code copied from gdb's utils.c. Would like to share this code, 2464 but don't know of a common place where both could get to it. */ 2465 2466/* Temporary storage using circular buffer */ 2467#define NUMCELLS 16 2468#define CELLSIZE 32 2469static char* 2470get_cell (void) 2471{ 2472 static char buf[NUMCELLS][CELLSIZE]; 2473 static int cell=0; 2474 if (++cell>=NUMCELLS) cell=0; 2475 return buf[cell]; 2476} 2477 2478/* Print routines to handle variable size regs, etc */ 2479 2480/* Eliminate warning from compiler on 32-bit systems */ 2481static int thirty_two = 32; 2482 2483char* 2484pr_addr(addr) 2485 SIM_ADDR addr; 2486{ 2487 char *paddr_str=get_cell(); 2488 switch (sizeof(addr)) 2489 { 2490 case 8: 2491 sprintf(paddr_str,"%08lx%08lx", 2492 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff)); 2493 break; 2494 case 4: 2495 sprintf(paddr_str,"%08lx",(unsigned long)addr); 2496 break; 2497 case 2: 2498 sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff)); 2499 break; 2500 default: 2501 sprintf(paddr_str,"%x",addr); 2502 } 2503 return paddr_str; 2504} 2505 2506char* 2507pr_uword64(addr) 2508 uword64 addr; 2509{ 2510 char *paddr_str=get_cell(); 2511 sprintf(paddr_str,"%08lx%08lx", 2512 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff)); 2513 return paddr_str; 2514} 2515 2516 2517void 2518mips_core_signal (SIM_DESC sd, 2519 sim_cpu *cpu, 2520 sim_cia cia, 2521 unsigned map, 2522 int nr_bytes, 2523 address_word addr, 2524 transfer_type transfer, 2525 sim_core_signals sig) 2526{ 2527 const char *copy = (transfer == read_transfer ? "read" : "write"); 2528 address_word ip = CIA_ADDR (cia); 2529 2530 switch (sig) 2531 { 2532 case sim_core_unmapped_signal: 2533 sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n", 2534 nr_bytes, copy, 2535 (unsigned long) addr, (unsigned long) ip); 2536 COP0_BADVADDR = addr; 2537 SignalExceptionDataReference(); 2538 break; 2539 2540 case sim_core_unaligned_signal: 2541 sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n", 2542 nr_bytes, copy, 2543 (unsigned long) addr, (unsigned long) ip); 2544 COP0_BADVADDR = addr; 2545 if(transfer == read_transfer) 2546 SignalExceptionAddressLoad(); 2547 else 2548 SignalExceptionAddressStore(); 2549 break; 2550 2551 default: 2552 sim_engine_abort (sd, cpu, cia, 2553 "mips_core_signal - internal error - bad switch"); 2554 } 2555} 2556 2557 2558void 2559mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia) 2560{ 2561 ASSERT(cpu != NULL); 2562 2563 if(cpu->exc_suspended > 0) 2564 sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended); 2565 2566 PC = cia; 2567 memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers)); 2568 cpu->exc_suspended = 0; 2569} 2570 2571void 2572mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception) 2573{ 2574 ASSERT(cpu != NULL); 2575 2576 if(cpu->exc_suspended > 0) 2577 sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n", 2578 cpu->exc_suspended, exception); 2579 2580 memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers)); 2581 memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers)); 2582 cpu->exc_suspended = exception; 2583} 2584 2585void 2586mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception) 2587{ 2588 ASSERT(cpu != NULL); 2589 2590 if(exception == 0 && cpu->exc_suspended > 0) 2591 { 2592 /* warn not for breakpoints */ 2593 if(cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP)) 2594 sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n", 2595 cpu->exc_suspended); 2596 } 2597 else if(exception != 0 && cpu->exc_suspended > 0) 2598 { 2599 if(exception != cpu->exc_suspended) 2600 sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n", 2601 cpu->exc_suspended, exception); 2602 2603 memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers)); 2604 } 2605 else if(exception != 0 && cpu->exc_suspended == 0) 2606 { 2607 sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception); 2608 } 2609 cpu->exc_suspended = 0; 2610} 2611 2612 2613/*---------------------------------------------------------------------------*/ 2614/*> EOF interp.c <*/ 2615