fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1197 lines 24 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/arch/sim405/cmd_ppc.c * 7 * Created: 2004-06-01 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2018 Hampa Hug <hampa@hampa.ch> * 9 * Copyright: (C) 2004-2006 Lukas Ruf <ruf@lpr.ch> * 10 *****************************************************************************/ 11 12/***************************************************************************** 13 * This program is free software. You can redistribute it and / or modify it * 14 * under the terms of the GNU General Public License version 2 as published * 15 * by the Free Software Foundation. * 16 * * 17 * This program is distributed in the hope that it will be useful, but * 18 * WITHOUT ANY WARRANTY, without even the implied warranty of * 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 20 * Public License for more details. * 21 *****************************************************************************/ 22 23/***************************************************************************** 24 * This software was developed at the Computer Engineering and Networks * 25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. * 26 *****************************************************************************/ 27 28 29#include "main.h" 30#include "cmd_ppc.h" 31#include "hook.h" 32#include "sim405.h" 33 34#include <stdio.h> 35 36#include <chipset/ppc405/uic.h> 37 38#include <cpu/ppc405/ppc405.h> 39 40#include <lib/cmd.h> 41#include <lib/console.h> 42#include <lib/monitor.h> 43#include <lib/sysdep.h> 44 45 46static mon_cmd_t par_cmd[] = { 47 { "c", "[cnt]", "clock" }, 48 { "gb", "[addr...]", "run with breakpoints" }, 49 { "g", "", "run" }, 50 { "key", "[val...]", "send keycodes to the serial console" }, 51 { "p", "[cnt]", "execute cnt instructions, skip calls [1]" }, 52 { "rfi", "", "execute to next rfi or rfci" }, 53 { "r", "reg [val]", "get or set a register" }, 54 { "s", "[what]", "print status (mem|ppc|spr|time|uart0|uart1|uic)" }, 55 { "tlb", "l [first [count]]", "list TLB entries" }, 56 { "tlb", "s addr", "search the TLB" }, 57 { "t", "[cnt]", "execute cnt instructions [1]" }, 58 { "u", "[addr [cnt]]", "disassemble" }, 59 { "x", "[c|r|v]", "set the translation mode (cpu, real, virtual)" } 60}; 61 62 63void ppc_disasm_str (char *dst, p405_disasm_t *op) 64{ 65 switch (op->argn) { 66 case 0: 67 sprintf (dst, "%08lX %s", (unsigned long) op->ir, op->op); 68 break; 69 70 case 1: 71 sprintf (dst, "%08lX %-8s %s", 72 (unsigned long) op->ir, op->op, op->arg1 73 ); 74 break; 75 76 case 2: 77 sprintf (dst, "%08lX %-8s %s, %s", 78 (unsigned long) op->ir, op->op, op->arg1, op->arg2 79 ); 80 break; 81 82 case 3: 83 sprintf (dst, "%08lX %-8s %s, %s, %s", 84 (unsigned long) op->ir, op->op, 85 op->arg1, op->arg2, op->arg3 86 ); 87 break; 88 89 case 4: 90 sprintf (dst, "%08lX %-8s %s, %s, %s, %s", 91 (unsigned long) op->ir, op->op, 92 op->arg1, op->arg2, op->arg3, op->arg4 93 ); 94 break; 95 96 case 5: 97 sprintf (dst, "%08lX %-8s %s, %s, %s, %s, %s", 98 (unsigned long) op->ir, op->op, 99 op->arg1, op->arg2, op->arg3, op->arg4, op->arg5 100 ); 101 break; 102 103 default: 104 strcpy (dst, "---"); 105 break; 106 } 107} 108 109static 110void prt_tlb_entry (p405_tlbe_t *ent, unsigned idx) 111{ 112 pce_printf ( 113 "%02x: %08lx -> %08lx %06lx V%c E%c R%c W%c X%c Z=%X TID=%02x %08lx", 114 idx, 115 (unsigned long) p405_get_tlbe_epn (ent), 116 (unsigned long) p405_get_tlbe_rpn (ent), 117 (unsigned long) p405_get_tlbe_sizeb (ent), 118 p405_get_tlbe_v (ent) ? '+' : '-', 119 p405_get_tlbe_e (ent) ? '+' : '-', 120 p405_get_tlbe_v (ent) ? '+' : '-', 121 p405_get_tlbe_wr (ent) ? '+' : '-', 122 p405_get_tlbe_ex (ent) ? '+' : '-', 123 (unsigned) p405_get_tlbe_zsel (ent), 124 (unsigned) p405_get_tlbe_tid (ent), 125 (unsigned long) ent->mask 126 ); 127} 128 129void s405_prt_state_ppc (sim405_t *sim) 130{ 131 unsigned i; 132 unsigned long long opcnt, clkcnt; 133 unsigned long delay; 134 double t, efrq; 135 p405_t *c; 136 p405_disasm_t op; 137 char str[256]; 138 139 pce_prt_sep ("PPC405"); 140 141 c = sim->ppc; 142 143 opcnt = p405_get_opcnt (c); 144 clkcnt = p405_get_clkcnt (c); 145 delay = p405_get_delay (c); 146 147 t = (double) (clock() - sim->real_clk) / CLOCKS_PER_SEC; 148 efrq = (t < 0.001) ? 0.0 : (clkcnt / (1000.0 * 1000.0 * t)); 149 150 pce_printf ( 151 "CLK=%llx OP=%llx DLY=%lx CPI=%.4f TIME=%.4f EFRQ=%.6f\n", 152 clkcnt, opcnt, delay, 153 (opcnt > 0) ? ((double) (clkcnt + delay) / (double) opcnt) : 1.0, 154 t, efrq 155 ); 156 157 pce_printf ( 158 " MSR=%08lX XER=%08lX CR=%08lX XER=[%c%c%c]" 159 " CR0=[%c%c%c%c]\n", 160 (unsigned long) p405_get_msr (c), 161 (unsigned long) p405_get_xer (c), 162 (unsigned long) p405_get_cr (c), 163 (p405_get_xer_so (c)) ? 'S' : '-', 164 (p405_get_xer_ov (c)) ? 'O' : '-', 165 (p405_get_xer_ca (c)) ? 'C' : '-', 166 (p405_get_cr_lt (c, 0)) ? 'L' : '-', 167 (p405_get_cr_gt (c, 0)) ? 'G' : '-', 168 (p405_get_cr_eq (c, 0)) ? 'E' : '-', 169 (p405_get_cr_so (c, 0)) ? 'O' : '-' 170 ); 171 172 pce_printf ( 173 " PC=%08lX CTR=%08lX LR=%08lX PID=%08lX ZPR=%08lX\n", 174 (unsigned long) p405_get_pc (c), 175 (unsigned long) p405_get_ctr (c), 176 (unsigned long) p405_get_lr (c), 177 (unsigned long) p405_get_pid (c), 178 (unsigned long) p405_get_zpr (c) 179 ); 180 181 pce_printf ( 182 "SRR0=%08lX SRR1=%08lX SRR2=%08lX SRR3=%08lX ESR=%08lX\n", 183 (unsigned long) p405_get_srr (c, 0), 184 (unsigned long) p405_get_srr (c, 1), 185 (unsigned long) p405_get_srr (c, 2), 186 (unsigned long) p405_get_srr (c, 3), 187 (unsigned long) p405_get_esr (c) 188 ); 189 190 for (i = 0; i < 8; i++) { 191 pce_printf ( 192 " R%02u=%08lX R%02u=%08lX R%02u=%08lX R%02u=%08lX" 193 " SP%u=%08lX\n", 194 i + 0, (unsigned long) p405_get_gpr (c, i + 0), 195 i + 8, (unsigned long) p405_get_gpr (c, i + 8), 196 i + 16, (unsigned long) p405_get_gpr (c, i + 16), 197 i + 24, (unsigned long) p405_get_gpr (c, i + 24), 198 i, (unsigned long) p405_get_sprg (c, i) 199 ); 200 } 201 202 p405_disasm_mem (c, &op, p405_get_pc (c), par_xlat | P405_XLAT_EXEC); 203 ppc_disasm_str (str, &op); 204 205 pce_printf ("%08lX %s\n", (unsigned long) p405_get_pc (c), str); 206} 207 208void s405_prt_state_spr (p405_t *c) 209{ 210 uint32_t msr; 211 212 pce_prt_sep ("PPC405 SPR"); 213 214 msr = p405_get_msr (c); 215 216 pce_printf ( 217 " MSR=%08lX [%s %s %s %s %s %s %s %s %s %s %s %s %s %s]\n", 218 (unsigned long) msr, 219 (msr & P405_MSR_AP) ? "AP" : "ap", 220 (msr & P405_MSR_APE) ? "APE" : "ape", 221 (msr & P405_MSR_WE) ? "WE" : "we", 222 (msr & P405_MSR_CE) ? "CE" : "ce", 223 (msr & P405_MSR_EE) ? "EE" : "ee", 224 (msr & P405_MSR_PR) ? "PR" : "pr", 225 (msr & P405_MSR_FP) ? "FP" : "fp", 226 (msr & P405_MSR_ME) ? "ME" : "me", 227 (msr & P405_MSR_FE0) ? "FE0" : "fe0", 228 (msr & P405_MSR_DWE) ? "DWE" : "dwe", 229 (msr & P405_MSR_DE) ? "DE" : "de", 230 (msr & P405_MSR_FE0) ? "FE1" : "fe1", 231 (msr & P405_MSR_IR) ? "IR" : "ir", 232 (msr & P405_MSR_DR) ? "DR" : "dr" 233 ); 234 235 pce_printf ( 236 " PC=%08lX XER=%08lX CR=%08lX PID=%08lX ZPR=%08lX\n", 237 (unsigned long) p405_get_pc (c), 238 (unsigned long) p405_get_xer (c), 239 (unsigned long) p405_get_cr (c), 240 (unsigned long) p405_get_pid (c), 241 (unsigned long) p405_get_zpr (c) 242 ); 243 244 pce_printf ( 245 "SPG0=%08lX SRR0=%08lX LR=%08lX CTR=%08lX ESR=%08lX\n", 246 (unsigned long) p405_get_sprg (c, 0), 247 (unsigned long) p405_get_srr (c, 0), 248 (unsigned long) p405_get_lr (c), 249 (unsigned long) p405_get_ctr (c), 250 (unsigned long) p405_get_esr (c) 251 ); 252 253 pce_printf ( 254 "SPG1=%08lX SRR1=%08lX TBU=%08lX TBL=%08lX DEAR=%08lX\n", 255 (unsigned long) p405_get_sprg (c, 1), 256 (unsigned long) p405_get_srr (c, 1), 257 (unsigned long) p405_get_tbu (c), 258 (unsigned long) p405_get_tbl (c), 259 (unsigned long) p405_get_dear (c) 260 ); 261 262 pce_printf ("SPG2=%08lX SRR2=%08lX EVPR=%08lX\n", 263 (unsigned long) p405_get_sprg (c, 2), 264 (unsigned long) p405_get_srr (c, 2), 265 (unsigned long) p405_get_evpr (c) 266 ); 267 268 pce_printf ( 269 "SPG3=%08lX SRR3=%08lX DCCR=%08lX DCWR=%08lX ICCR=%08lX\n", 270 (unsigned long) p405_get_sprg (c, 3), 271 (unsigned long) p405_get_srr (c, 3), 272 (unsigned long) p405_get_dccr (c), 273 (unsigned long) p405_get_dcwr (c), 274 (unsigned long) p405_get_iccr (c) 275 ); 276 277 pce_printf ("SPG4=%08lX DBC0=%08lX PIT0=%08lX PIT1=%08lX\n", 278 (unsigned long) p405_get_sprg (c, 4), 279 (unsigned long) p405_get_dbcr0 (c), 280 (unsigned long) p405_get_pit (c, 0), 281 (unsigned long) p405_get_pit (c, 1) 282 ); 283 284 pce_printf ("SPG5=%08lX DBC1=%08lX TCR=%08lX TSR=%08lX\n", 285 (unsigned long) p405_get_sprg (c, 5), 286 (unsigned long) p405_get_dbcr0 (c), 287 (unsigned long) p405_get_tcr (c), 288 (unsigned long) p405_get_tsr (c) 289 ); 290 291 pce_printf ("SPG6=%08lX DBSR=%08lX\n", 292 (unsigned long) p405_get_sprg (c, 6), 293 (unsigned long) p405_get_dbsr (c) 294 ); 295 296 pce_printf ("SPG7=%08lX\n", 297 (unsigned long) p405_get_sprg (c, 7) 298 ); 299} 300 301void s405_prt_state_uic (p405_uic_t *uic) 302{ 303 pce_prt_sep ("UIC"); 304 305 pce_printf ( 306 " L=%08lX N00=%08lX N08=%08lX N16=%08lX N24=%08lX\n", 307 (unsigned long) p405uic_get_levels (uic), 308 p405uic_get_int_cnt (uic, 0), 309 p405uic_get_int_cnt (uic, 8), 310 p405uic_get_int_cnt (uic, 16), 311 p405uic_get_int_cnt (uic, 24) 312 ); 313 pce_printf ( 314 " SR=%08lX N01=%08lX N09=%08lX N17=%08lX N25=%08lX\n", 315 (unsigned long) p405uic_get_sr (uic), 316 p405uic_get_int_cnt (uic, 1), 317 p405uic_get_int_cnt (uic, 9), 318 p405uic_get_int_cnt (uic, 17), 319 p405uic_get_int_cnt (uic, 25) 320 ); 321 pce_printf ( 322 " ER=%08lX N02=%08lX N10=%08lX N18=%08lX N26=%08lX\n", 323 (unsigned long) p405uic_get_er (uic), 324 p405uic_get_int_cnt (uic, 2), 325 p405uic_get_int_cnt (uic, 10), 326 p405uic_get_int_cnt (uic, 18), 327 p405uic_get_int_cnt (uic, 26) 328 ); 329 pce_printf ( 330 "MSR=%08lX N03=%08lX N11=%08lX N19=%08lX N27=%08lX\n", 331 (unsigned long) p405uic_get_msr (uic), 332 p405uic_get_int_cnt (uic, 3), 333 p405uic_get_int_cnt (uic, 11), 334 p405uic_get_int_cnt (uic, 19), 335 p405uic_get_int_cnt (uic, 27) 336 ); 337 pce_printf ( 338 " CR=%08lX N04=%08lX N12=%08lX N20=%08lX N28=%08lX\n", 339 (unsigned long) p405uic_get_cr (uic), 340 p405uic_get_int_cnt (uic, 4), 341 p405uic_get_int_cnt (uic, 12), 342 p405uic_get_int_cnt (uic, 20), 343 p405uic_get_int_cnt (uic, 28) 344 ); 345 pce_printf ( 346 " PR=%08lX N05=%08lX N13=%08lX N21=%08lX N29=%08lX\n", 347 (unsigned long) p405uic_get_pr (uic), 348 p405uic_get_int_cnt (uic, 5), 349 p405uic_get_int_cnt (uic, 13), 350 p405uic_get_int_cnt (uic, 21), 351 p405uic_get_int_cnt (uic, 29) 352 ); 353 pce_printf ( 354 " TR=%08lX N06=%08lX N14=%08lX N22=%08lX N30=%08lX\n", 355 (unsigned long) p405uic_get_tr (uic), 356 p405uic_get_int_cnt (uic, 6), 357 p405uic_get_int_cnt (uic, 14), 358 p405uic_get_int_cnt (uic, 22), 359 p405uic_get_int_cnt (uic, 30) 360 ); 361 pce_printf ( 362 "VCR=%08lX N07=%08lX N15=%08lX N23=%08lX N31=%08lX\n", 363 (unsigned long) p405uic_get_vcr (uic), 364 p405uic_get_int_cnt (uic, 7), 365 p405uic_get_int_cnt (uic, 15), 366 p405uic_get_int_cnt (uic, 23), 367 p405uic_get_int_cnt (uic, 31) 368 ); 369 pce_printf (" VR=%08lX\n", (unsigned long) p405uic_get_vr (uic)); 370} 371 372static 373void s405_print_state_uart (e8250_t *uart, unsigned long base) 374{ 375 char p; 376 unsigned char lsr, msr; 377 378 lsr = e8250_get_lsr (uart); 379 msr = e8250_get_msr (uart); 380 381 switch (e8250_get_parity (uart)) { 382 case E8250_PARITY_N: 383 p = 'N'; 384 break; 385 386 case E8250_PARITY_E: 387 p = 'E'; 388 break; 389 390 case E8250_PARITY_O: 391 p = 'O'; 392 break; 393 394 case E8250_PARITY_M: 395 p = 'M'; 396 break; 397 398 case E8250_PARITY_S: 399 p = 'S'; 400 break; 401 402 default: 403 p = '?'; 404 break; 405 } 406 407 pce_prt_sep ("8250-UART"); 408 409 pce_printf ( 410 "IO=%08lX %lu %u%c%u DTR=%d RTS=%d DSR=%d CTS=%d DCD=%d RI=%d\n" 411 "TxD=%02X%c RxD=%02X%c SCR=%02X DIV=%04X\n" 412 "IER=%02X IIR=%02X LCR=%02X LSR=%02X MCR=%02X MSR=%02X\n", 413 base, 414 e8250_get_bps (uart), e8250_get_databits (uart), p, 415 e8250_get_stopbits (uart), 416 e8250_get_dtr (uart), e8250_get_rts (uart), 417 (msr & E8250_MSR_DSR) != 0, 418 (msr & E8250_MSR_CTS) != 0, 419 (msr & E8250_MSR_DCD) != 0, 420 (msr & E8250_MSR_RI) != 0, 421 uart->txd, (lsr & E8250_LSR_TBE) ? ' ' : '*', 422 uart->rxd, (lsr & E8250_LSR_RRD) ? '*' : ' ', 423 uart->scratch, uart->divisor, 424 uart->ier, uart->iir, uart->lcr, lsr, uart->mcr, msr 425 ); 426} 427 428static 429void s405_print_state_time (sim405_t *sim) 430{ 431 p405_t *c; 432 unsigned long tcr, tsr, tbl, msk, rem; 433 434 c = sim->ppc; 435 436 tcr = p405_get_tcr (c); 437 tsr = p405_get_tsr (c); 438 tbl = p405_get_tbl (c); 439 440 msk = 0x100UL << ((tcr >> 22) & 0x0c); 441 rem = msk - (tbl & (msk - 1)) + ((tbl & msk) ? msk : 0); 442 443 pce_prt_sep ("TIME"); 444 445 pce_printf ("TBU=%08lX TBL=%08lX\n", 446 (unsigned long) p405_get_tbu (c), 447 tbl 448 ); 449 450 pce_printf ("TCR=%08lX [PIE=%d ARE=%d FIE=%d FP=%X WIE=%d]\n", 451 tcr, 452 (tcr & P405_TCR_PIE) != 0, 453 (tcr & P405_TCR_ARE) != 0, 454 (tcr & P405_TCR_FIE) != 0, 455 (unsigned) ((tcr >> 24) & 3), 456 (tcr & P405_TCR_WIE) != 0 457 ); 458 459 pce_printf ("TSR=%08lX [PIS=%d FIS=%d WIS=%d]\n", 460 tsr, 461 (tsr & P405_TSR_PIS) != 0, 462 (tsr & P405_TSR_FIS) != 0, 463 (tsr & P405_TSR_WIS) != 0 464 ); 465 466 pce_printf ("PIT VAL=%08lX REL=%08lX ARE=%d PIE=%d PIS=%d\n", 467 (unsigned long) (p405_get_pit (c, 0)), 468 (unsigned long) (p405_get_pit (c, 1)), 469 (tcr & P405_TCR_ARE) != 0, 470 (tcr & P405_TCR_PIE) != 0, 471 (tsr & P405_TSR_PIS) != 0 472 ); 473 474 pce_printf ("FIT REM=%08lX TBL=%08lx MSK=%06lX FIE=%d FIS=%d\n", 475 rem, 476 tbl, 477 msk, 478 (tcr & P405_TCR_FIE) != 0, 479 (tsr & P405_TSR_FIS) != 0 480 ); 481} 482 483void s405_prt_state_mem (sim405_t *sim) 484{ 485 FILE *fp; 486 487 pce_prt_sep ("PPC MEM"); 488 489 mem_prt_state (sim->mem, pce_get_fp_out()); 490 491 fp = pce_get_redir_out(); 492 if (fp != NULL) { 493 mem_prt_state (sim->mem, fp); 494 } 495} 496 497void prt_state (sim405_t *sim, const char *str) 498{ 499 cmd_t cmd; 500 501 cmd_set_str (&cmd, str); 502 503 if (cmd_match_eol (&cmd)) { 504 return; 505 } 506 507 while (!cmd_match_eol (&cmd)) { 508 if (cmd_match (&cmd, "ppc") || cmd_match (&cmd, "cpu")) { 509 s405_prt_state_ppc (sim); 510 } 511 else if (cmd_match (&cmd, "spr")) { 512 s405_prt_state_spr (sim->ppc); 513 } 514 else if (cmd_match (&cmd, "uic")) { 515 s405_prt_state_uic (&sim->uic); 516 } 517 else if (cmd_match (&cmd, "uart0")) { 518 if (sim->serport[0] != NULL) { 519 s405_print_state_uart (&sim->serport[0]->uart, sim->serport[0]->io); 520 } 521 } 522 else if (cmd_match (&cmd, "uart1")) { 523 if (sim->serport[1] != NULL) { 524 s405_print_state_uart (&sim->serport[1]->uart, sim->serport[1]->io); 525 } 526 } 527 else if (cmd_match (&cmd, "time")) { 528 s405_print_state_time (sim); 529 } 530 else if (cmd_match (&cmd, "mem")) { 531 s405_prt_state_mem (sim); 532 } 533 else { 534 pce_printf ("unknown component (%s)\n", 535 cmd_get_str (&cmd) 536 ); 537 return; 538 } 539 } 540} 541 542 543static 544int ppc_check_break (sim405_t *sim) 545{ 546 if (bps_check (&sim->bps, 0, p405_get_pc (sim->ppc), stdout)) { 547 return (1); 548 } 549 550 if (sim->brk) { 551 return (1); 552 } 553 554 return (0); 555} 556 557static 558void ppc_exec (sim405_t *sim) 559{ 560 unsigned long long old; 561 562 old = p405_get_opcnt (sim->ppc); 563 564 while (p405_get_opcnt (sim->ppc) == old) { 565 s405_clock (sim, 1); 566 } 567} 568 569static 570int ppc_exec_to (sim405_t *sim, unsigned long addr) 571{ 572 while (p405_get_pc (sim->ppc) != addr) { 573 s405_clock (sim, 1); 574 575 if (sim->brk) { 576 return (1); 577 } 578 } 579 580 return (0); 581} 582 583static 584int ppc_exec_off (sim405_t *sim, unsigned long addr) 585{ 586 while (p405_get_pc (sim->ppc) == addr) { 587 s405_clock (sim, 1); 588 589 if (sim->brk) { 590 return (1); 591 } 592 } 593 594 return (0); 595} 596 597void ppc_run (sim405_t *sim) 598{ 599 pce_start (&sim->brk); 600 s405_clock_discontinuity (sim); 601 602 while (1) { 603 s405_clock (sim, 64); 604 605 if (sim->brk) { 606 break; 607 } 608 } 609 610 pce_stop(); 611} 612 613 614static 615int s405_trap (sim405_t *sim, unsigned ofs) 616{ 617 int log; 618 char *name; 619 620 log = 0; 621 622 switch (ofs) { 623 case 0x0300: 624 name = "data store"; 625 break; 626 627 case 0x0400: 628 name = "instruction store"; 629 break; 630 631 case 0x0500: 632 name = "external interrupt"; 633 break; 634 635 case 0x0700: 636 name = "program"; 637 if (sim->ppc->exception_esr & P405_ESR_PIL) { 638 log = 0; 639 } 640 else if (sim->ppc->exception_esr & P405_ESR_PTR) { 641 log = 1; 642 } 643 break; 644 645 case 0x0800: 646 name = "fpu unavailable"; 647 log = 1; 648 break; 649 650 case 0x0c00: 651 name = "system call"; 652 break; 653 654 case 0x1000: 655 name = "PIT"; 656 break; 657 658 case 0x1010: 659 name = "FIT"; 660 break; 661 662 case 0x1100: 663 name = "TLB miss data"; 664 break; 665 666 case 0x1200: 667 name = "TLB miss instruction"; 668 break; 669 670 default: 671 name = "unknown"; 672 log = 1; 673 break; 674 } 675 676 if (log) { 677 pce_log (MSG_DEB, "%08lX: ESR=%08lX DEAR=%08lX IR=%0lX OFS=%04X %s\n", 678 (unsigned long) p405_get_pc (sim->ppc), 679 (unsigned long) sim->ppc->exception_esr, 680 (unsigned long) sim->ppc->exception_dear, 681 (unsigned long) sim->ppc->ir, 682 ofs, name 683 ); 684 } 685 686 return (0); 687} 688 689static 690void ppc_log_undef (void *ext, unsigned long ir) 691{ 692 unsigned op1, op2; 693 sim405_t *sim; 694 695 sim = (sim405_t *) ext; 696 697 op1 = (ir >> 26) & 0x3f; 698 op2 = (ir >> 1) & 0x3ff; 699 700 if (op1 == 4) { 701 /* various multiply-accumulate instructions */ 702 return; 703 } 704 705 pce_log (MSG_DEB, 706 "%08lX: undefined operation [%08lX] op1=%02X op2=%03X\n", 707 (unsigned long) p405_get_pc (sim->ppc), ir, op1, op2 708 ); 709 710 /* s405_break (sim, PCE_BRK_STOP); */ 711} 712 713#if 0 714static 715void ppc_log_mem (void *ext, unsigned mode, 716 unsigned long raddr, unsigned long vaddr, unsigned long val) 717{ 718 sim405_t *sim; 719 720 sim = (sim405_t *) ext; 721 722 if ((raddr >= 0xe0000000UL) && (raddr < 0xef600000UL)) { 723 pce_log (MSG_DEB, "mem: 0x%08lx 0x%08lx %02x\n", raddr, val, mode); 724 } 725} 726#endif 727 728static 729void do_c (cmd_t *cmd, sim405_t *sim) 730{ 731 unsigned long cnt; 732 733 cnt = 1; 734 735 cmd_match_uint32 (cmd, &cnt); 736 737 if (!cmd_match_end (cmd)) { 738 return; 739 } 740 741 while (cnt > 0) { 742 s405_clock (sim, 1); 743 cnt -= 1; 744 } 745 746 s405_prt_state_ppc (sim); 747} 748 749static 750void do_g_b (cmd_t *cmd, sim405_t *sim) 751{ 752 unsigned long addr; 753 breakpoint_t *bp; 754 755 while (cmd_match_uint32 (cmd, &addr)) { 756 bp = bp_addr_new (addr); 757 bps_bp_add (&sim->bps, bp); 758 } 759 760 if (!cmd_match_end (cmd)) { 761 return; 762 } 763 764 pce_start (&sim->brk); 765 s405_clock_discontinuity (sim); 766 767 while (1) { 768 ppc_exec (sim); 769 770 if (ppc_check_break (sim)) { 771 break; 772 } 773 } 774 775 pce_stop(); 776} 777 778static 779void do_g (cmd_t *cmd, sim405_t *sim) 780{ 781 if (cmd_match (cmd, "b")) { 782 do_g_b (cmd, sim); 783 return; 784 } 785 786 if (!cmd_match_end (cmd)) { 787 return; 788 } 789 790 ppc_run (sim); 791} 792 793static 794void do_key (cmd_t *cmd, sim405_t *sim) 795{ 796 unsigned short c; 797 798 while (cmd_match_uint16 (cmd, &c)) { 799 s405_set_keycode (sim, c); 800 } 801 802 if (!cmd_match_end (cmd)) { 803 return; 804 } 805} 806 807static 808void do_p (cmd_t *cmd, sim405_t *sim) 809{ 810 unsigned long cnt; 811 p405_disasm_t dis; 812 813 cnt = 1; 814 815 cmd_match_uint32 (cmd, &cnt); 816 817 if (!cmd_match_end (cmd)) { 818 return; 819 } 820 821 pce_start (&sim->brk); 822 s405_clock_discontinuity (sim); 823 824 while (cnt > 0) { 825 p405_disasm_mem (sim->ppc, &dis, p405_get_pc (sim->ppc), P405_XLAT_CPU | P405_XLAT_EXEC); 826 827 if (dis.flags & P405_DFLAG_CALL) { 828 if (ppc_exec_to (sim, p405_get_pc (sim->ppc) + 4)) { 829 break; 830 } 831 } 832 else { 833 uint32_t msr; 834 835 msr = p405_get_msr (sim->ppc); 836 837 if (ppc_exec_off (sim, p405_get_pc (sim->ppc))) { 838 break; 839 } 840 841 if (msr & P405_MSR_PR) { 842 /* check if exception occured */ 843 while ((p405_get_msr (sim->ppc) & P405_MSR_PR) == 0) { 844 s405_clock (sim, 1); 845 846 if (sim->brk) { 847 break; 848 } 849 } 850 } 851 } 852 853 cnt -= 1; 854 } 855 856 pce_stop(); 857 858 s405_prt_state_ppc (sim); 859} 860 861static 862void do_rfi (cmd_t *cmd, sim405_t *sim) 863{ 864 p405_disasm_t dis; 865 866 if (!cmd_match_end (cmd)) { 867 return; 868 } 869 870 pce_start (&sim->brk); 871 s405_clock_discontinuity (sim); 872 873 while (1) { 874 p405_disasm_mem (sim->ppc, &dis, p405_get_pc (sim->ppc), 875 P405_XLAT_CPU | P405_XLAT_EXEC 876 ); 877 878 if (ppc_exec_off (sim, p405_get_pc (sim->ppc))) { 879 break; 880 } 881 882 if (dis.flags & P405_DFLAG_RFI) { 883 break; 884 } 885 } 886 887 pce_stop(); 888 889 s405_prt_state_ppc (sim); 890} 891 892static 893void do_r (cmd_t *cmd, sim405_t *sim) 894{ 895 unsigned long val; 896 char sym[256]; 897 898 if (cmd_match_eol (cmd)) { 899 s405_prt_state_ppc (sim); 900 return; 901 } 902 903 if (!cmd_match_ident (cmd, sym, 256)) { 904 pce_printf ("missing register\n"); 905 return; 906 } 907 908 if (p405_get_reg (sim->ppc, sym, &val)) { 909 pce_printf ("bad register (%s)\n", sym); 910 return; 911 } 912 913 if (cmd_match_eol (cmd)) { 914 pce_printf ("%08lX\n", val); 915 return; 916 } 917 918 if (!cmd_match_uint32 (cmd, &val)) { 919 pce_printf ("missing value\n"); 920 return; 921 } 922 923 if (!cmd_match_end (cmd)) { 924 return; 925 } 926 927 p405_set_reg (sim->ppc, sym, val); 928 929 s405_prt_state_ppc (sim); 930} 931 932static 933void do_s (cmd_t *cmd, sim405_t *sim) 934{ 935 if (cmd_match_eol (cmd)) { 936 s405_prt_state_ppc (sim); 937 return; 938 } 939 940 prt_state (sim, cmd_get_str (cmd)); 941} 942 943static 944void do_tlb_l (cmd_t *cmd, sim405_t *sim) 945{ 946 unsigned long i, n, max; 947 p405_tlbe_t *ent; 948 949 i = 0; 950 n = p405_get_tlb_entry_cnt (sim->ppc); 951 952 max = n; 953 954 if (cmd_match_uint32 (cmd, &i)) { 955 cmd_match_uint32 (cmd, &n); 956 } 957 958 if (!cmd_match_end (cmd)) { 959 return; 960 } 961 962 i = i % max; 963 964 while (n > 0) { 965 ent = p405_get_tlb_entry_idx (sim->ppc, i); 966 967 if (ent != NULL) { 968 prt_tlb_entry (ent, i); 969 fputs ("\n", stdout); 970 } 971 972 i = (i + 1) % max; 973 n -= 1; 974 } 975} 976 977static 978void do_tlb_s (cmd_t *cmd, sim405_t *sim) 979{ 980 unsigned long addr; 981 unsigned idx; 982 p405_tlbe_t *ent; 983 984 if (!cmd_match_uint32 (cmd, &addr)) { 985 cmd_error (cmd, "expecting address"); 986 return; 987 } 988 989 if (!cmd_match_end (cmd)) { 990 return; 991 } 992 993 idx = p405_get_tlb_index (sim->ppc, addr); 994 ent = p405_get_tlb_entry_idx (sim->ppc, idx); 995 996 if (ent == NULL) { 997 pce_printf ("no match\n"); 998 } 999 else { 1000 prt_tlb_entry (ent, idx); 1001 pce_puts ("\n"); 1002 } 1003} 1004 1005static 1006void do_tlb (cmd_t *cmd, sim405_t *sim) 1007{ 1008 if (cmd_match (cmd, "l")) { 1009 do_tlb_l (cmd, sim); 1010 } 1011 else if (cmd_match (cmd, "s")) { 1012 do_tlb_s (cmd, sim); 1013 } 1014 else { 1015 cmd_error (cmd, "unknown tlb command"); 1016 } 1017} 1018 1019static 1020void do_t (cmd_t *cmd, sim405_t *sim) 1021{ 1022 unsigned long i, n; 1023 1024 n = 1; 1025 1026 cmd_match_uint32 (cmd, &n); 1027 1028 if (!cmd_match_end (cmd)) { 1029 return; 1030 } 1031 1032 pce_start (&sim->brk); 1033 s405_clock_discontinuity (sim); 1034 1035 for (i = 0; i < n; i++) { 1036 ppc_exec (sim); 1037 } 1038 1039 pce_stop(); 1040 1041 s405_prt_state_ppc (sim); 1042} 1043 1044static 1045void do_u (cmd_t *cmd, sim405_t *sim) 1046{ 1047 unsigned i; 1048 int to; 1049 unsigned long addr, cnt; 1050 static unsigned int first = 1; 1051 static unsigned long saddr = 0; 1052 p405_disasm_t op; 1053 char str[256]; 1054 1055 if (first) { 1056 first = 0; 1057 saddr = p405_get_pc (sim->ppc); 1058 } 1059 1060 to = 0; 1061 addr = saddr; 1062 cnt = 16; 1063 1064 if (cmd_match (cmd, "-")) { 1065 to = 1; 1066 } 1067 1068 if (cmd_match_uint32 (cmd, &addr)) { 1069 cmd_match_uint32 (cmd, &cnt); 1070 } 1071 1072 if (!cmd_match_end (cmd)) { 1073 return; 1074 } 1075 1076 if (to) { 1077 addr -= 4 * (cnt - 1); 1078 } 1079 1080 for (i = 0; i < cnt; i++) { 1081 p405_disasm_mem (sim->ppc, &op, addr, par_xlat | P405_XLAT_EXEC); 1082 ppc_disasm_str (str, &op); 1083 1084 pce_printf ("%08lX %s\n", addr, str); 1085 1086 addr += 4; 1087 } 1088 1089 saddr = addr; 1090} 1091 1092static 1093void do_x (cmd_t *cmd, sim405_t *sim) 1094{ 1095 unsigned xlat; 1096 1097 if (cmd_match_eol (cmd)) { 1098 switch (par_xlat) { 1099 case P405_XLAT_CPU: 1100 pce_printf ("xlat cpu\n"); 1101 break; 1102 1103 case P405_XLAT_REAL: 1104 pce_printf ("xlat real\n"); 1105 break; 1106 1107 case P405_XLAT_VIRTUAL: 1108 pce_printf ("xlat virtual\n"); 1109 break; 1110 1111 default: 1112 pce_printf ("xlat unknown\n"); 1113 break; 1114 } 1115 1116 return; 1117 } 1118 1119 if (cmd_match (cmd, "c")) { 1120 xlat = P405_XLAT_CPU; 1121 } 1122 else if (cmd_match (cmd, "r")) { 1123 xlat = P405_XLAT_REAL; 1124 } 1125 else if (cmd_match (cmd, "v")) { 1126 xlat = P405_XLAT_VIRTUAL; 1127 } 1128 else { 1129 cmd_error (cmd, "unknown translation type"); 1130 return; 1131 } 1132 1133 if (!cmd_match_end (cmd)) { 1134 return; 1135 } 1136 1137 par_xlat = xlat; 1138} 1139 1140int ppc_do_cmd (sim405_t *sim, cmd_t *cmd) 1141{ 1142 if (cmd_match (cmd, "b")) { 1143 cmd_do_b (cmd, &sim->bps); 1144 } 1145 else if (cmd_match (cmd, "c")) { 1146 do_c (cmd, sim); 1147 } 1148 else if (cmd_match (cmd, "g")) { 1149 do_g (cmd, sim); 1150 } 1151 else if (cmd_match (cmd, "key")) { 1152 do_key (cmd, sim); 1153 } 1154 else if (cmd_match (cmd, "p")) { 1155 do_p (cmd, sim); 1156 } 1157 else if (cmd_match (cmd, "rfi")) { 1158 do_rfi (cmd, sim); 1159 } 1160 else if (cmd_match (cmd, "r")) { 1161 do_r (cmd, sim); 1162 } 1163 else if (cmd_match (cmd, "s")) { 1164 do_s (cmd, sim); 1165 } 1166 else if (cmd_match (cmd, "tlb")) { 1167 do_tlb (cmd, sim); 1168 } 1169 else if (cmd_match (cmd, "t")) { 1170 do_t (cmd, sim); 1171 } 1172 else if (cmd_match (cmd, "u")) { 1173 do_u (cmd, sim); 1174 } 1175 else if (cmd_match (cmd, "x")) { 1176 do_x (cmd, sim); 1177 } 1178 else { 1179 return (1); 1180 } 1181 1182 return (0); 1183} 1184 1185void ppc_cmd_init (sim405_t *sim, monitor_t *mon) 1186{ 1187 mon_cmd_add (mon, par_cmd, sizeof (par_cmd) / sizeof (par_cmd[0])); 1188 mon_cmd_add_bp (mon); 1189 1190 sim->ppc->log_ext = sim; 1191 sim->ppc->log_opcode = NULL; 1192 sim->ppc->log_undef = &ppc_log_undef; 1193 sim->ppc->log_mem = NULL; 1194 1195 p405_set_hook_fct (sim->ppc, sim, s405_hook); 1196 p405_set_trap_fct (sim->ppc, sim, s405_trap); 1197}