From 65028ea86dd305523e812809f3619ff4767cc830 Mon Sep 17 00:00:00 2001
From: Jiri Gaisler <jiri@gaisler.se>
Date: Thu, 7 Feb 2019 14:49:28 +0100
Subject: [PATCH] sis: improve debug of SMP systems
---
sim/sis/exec.c | 2 +-
sim/sis/func.c | 91 +++++++++++++++++++++++++++++++-----------------
sim/sis/interf.c | 35 ++++++++-----------
sim/sis/riscv.h | 13 +++++--
sim/sis/sis.c | 29 ++++++++++-----
sim/sis/sis.h | 7 +++-
sim/sis/sparc.h | 8 ++++-
7 files changed, 119 insertions(+), 66 deletions(-)
diff --git a/sim/sis/exec.c b/sim/sis/exec.c
index c885095685..262a080dea 100644
a
|
b
|
init_regs(sregs) |
122 | 122 | { |
123 | 123 | int i; |
124 | 124 | |
125 | | ebase.bphit = 0; |
126 | 125 | ebase.wphit = 0; |
127 | 126 | ebase.lrq = 0; |
128 | 127 | |
… |
… |
init_regs(sregs) |
177 | 176 | sregs[i].mpp = 0; |
178 | 177 | sregs[i].mode = 1; |
179 | 178 | sregs[i].lrq = 0; |
| 179 | sregs[i].bphit = 0; |
180 | 180 | } |
181 | 181 | } |
182 | 182 | |
diff --git a/sim/sis/func.c b/sim/sis/func.c
index 5aac9c6811..7ab55b4c7f 100644
a
|
b
|
struct evcell evbuf[EVENT_MAX]; |
41 | 41 | |
42 | 42 | int ctrl_c = 0; |
43 | 43 | int sis_verbose = 0; |
44 | | char *sis_version = "2.11"; |
| 44 | char *sis_version = "2.12"; |
45 | 45 | int nfp = 0; |
46 | 46 | int ift = 0; |
47 | 47 | int wrp = 0; |
… |
… |
exec_cmd(const char *cmd) |
381 | 381 | reset_all(); |
382 | 382 | reset_stat(sregs); |
383 | 383 | if (last_load_addr != 0) { |
384 | | sregs->pc = last_load_addr & ~1; |
385 | | sregs->npc = sregs->pc + 4; |
| 384 | for (i=0; i<ncpu; i++) { |
| 385 | sregs[i].pc = last_load_addr & ~3; |
| 386 | sregs[i].npc = sregs[i].pc + 4; |
| 387 | } |
386 | 388 | } |
387 | 389 | if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init (); |
388 | 390 | ebase.tlimit = limcalc(ebase.freq); |
… |
… |
check_bpt(sregs) |
768 | 770 | { |
769 | 771 | int32 i; |
770 | 772 | |
771 | | if (ebase.bphit) |
| 773 | if (sregs->bphit) { |
| 774 | sregs->bphit = 0; |
772 | 775 | return 0; |
| 776 | } |
773 | 777 | for (i = 0; i < (int32) ebase.bptnum; i++) { |
774 | 778 | if (sregs->pc == ebase.bpts[i]) |
775 | 779 | return BPT_HIT; |
… |
… |
sys_halt() |
839 | 843 | /* simulate uni-processor system */ |
840 | 844 | |
841 | 845 | static int |
842 | | run_sim_un(icount, dis) |
| 846 | run_sim_un(sregs, icount, dis) |
| 847 | struct pstate *sregs; |
843 | 848 | uint64 icount; |
844 | 849 | int dis; |
845 | 850 | { |
… |
… |
run_sim_un(icount, dis) |
851 | 856 | while (icount > 0) { |
852 | 857 | if (sregs->pwd_mode) { |
853 | 858 | sregs->simtime = ebase.evtime; /* skip forward to next event */ |
854 | | if (ext_irl[0]) irq = check_interrupts(sregs); |
| 859 | if (ext_irl[sregs->cpu]) irq = check_interrupts(sregs); |
855 | 860 | } else { |
856 | 861 | sregs->icnt = 1; |
857 | 862 | sregs->fhold = 0; |
858 | | if (ext_irl[0]) irq = check_interrupts(sregs); |
| 863 | if (ext_irl[sregs->cpu]) irq = check_interrupts(sregs); |
859 | 864 | if (!irq) { |
860 | 865 | mexc = ms->memory_iread (sregs->pc, &sregs->inst, &sregs->hold); |
861 | 866 | if (mexc) { |
862 | 867 | sregs->trap = I_ACC_EXC; |
863 | 868 | } else { |
864 | 869 | if (deb) { |
865 | | if (ebase.histlen) { |
| 870 | if ((ebase.bptnum) && (sregs->bphit = check_bpt(sregs))) |
| 871 | icount = 0; |
| 872 | else { |
| 873 | if (ebase.histlen) { |
866 | 874 | sregs->histbuf[sregs->histind].addr = sregs->pc; |
867 | 875 | sregs->histbuf[sregs->histind].time = ebase.simtime; |
868 | 876 | sregs->histind++; |
869 | 877 | if (sregs->histind >= ebase.histlen) |
870 | 878 | sregs->histind = 0; |
871 | | } |
872 | | if (dis) { |
| 879 | } |
| 880 | if (dis) { |
873 | 881 | printf(" %8" PRIu64 " ", ebase.simtime); |
874 | 882 | dis_mem(sregs->pc, 1, &dinfo); |
875 | | } |
876 | | if ((ebase.bptnum) && (ebase.bphit = check_bpt(sregs))) |
877 | | icount = 0; |
878 | | else { |
| 883 | } |
879 | 884 | dispatch_instruction(sregs); |
880 | 885 | icount--; |
881 | 886 | } |
… |
… |
run_sim_un(icount, dis) |
892 | 897 | sregs->err_mode = 0; |
893 | 898 | sregs->trap = 0; |
894 | 899 | icount = 0; |
| 900 | ebase.bpcpu = sregs->cpu; |
| 901 | if (ebase.histlen) { |
| 902 | sregs->histind--; |
| 903 | if (sregs->histind >= ebase.histlen) |
| 904 | sregs->histind = ebase.histlen - 1; |
| 905 | } |
895 | 906 | } |
896 | 907 | if (sregs->err_mode) { |
897 | 908 | ms->error_mode (sregs->pc); |
898 | 909 | icount = 0; |
| 910 | ebase.bpcpu = sregs->cpu; |
899 | 911 | } |
900 | 912 | } |
901 | 913 | #ifdef STAT |
… |
… |
run_sim_un(icount, dis) |
912 | 924 | } |
913 | 925 | if (sregs->err_mode) |
914 | 926 | return ERROR; |
915 | | if (ebase.bphit) |
| 927 | if (sregs->bphit) |
916 | 928 | return (BPT_HIT); |
917 | 929 | if (ebase.wphit) |
918 | 930 | return (WPT_HIT); |
… |
… |
run_sim_core(sregs, ntime, deb, dis) |
955 | 967 | sregs->trap = I_ACC_EXC; |
956 | 968 | } else { |
957 | 969 | if (deb) { |
| 970 | if ((ebase.bptnum) && (sregs->bphit = check_bpt(sregs))) { |
| 971 | ntime = sregs->simtime; |
| 972 | ctrl_c = 1; |
| 973 | ebase.bpcpu = sregs->cpu; |
| 974 | break; |
| 975 | } |
958 | 976 | if (ebase.histlen) { |
959 | 977 | sregs->histbuf[sregs->histind].addr = sregs->pc; |
960 | 978 | sregs->histbuf[sregs->histind].time = sregs->simtime; |
… |
… |
run_sim_core(sregs, ntime, deb, dis) |
966 | 984 | printf("cpu %d %8" PRIu64 " ", sregs->cpu, sregs->simtime); |
967 | 985 | dis_mem(sregs->pc, 1, &dinfo); |
968 | 986 | } |
969 | | if ((ebase.bptnum) && (ebase.bphit = check_bpt(sregs))) { |
970 | | ntime = sregs->simtime; |
971 | | } else { |
972 | | dispatch_instruction(sregs); |
973 | | } |
| 987 | dispatch_instruction(sregs); |
974 | 988 | } else { |
975 | 989 | dispatch_instruction(sregs); |
976 | 990 | } |
… |
… |
run_sim_core(sregs, ntime, deb, dis) |
984 | 998 | sregs->trap = 0; |
985 | 999 | ntime = sregs->simtime; |
986 | 1000 | ctrl_c = 1; |
| 1001 | ebase.bpcpu = sregs->cpu; |
| 1002 | if (ebase.histlen) { |
| 1003 | sregs->histind--; |
| 1004 | if (sregs->histind >= ebase.histlen) |
| 1005 | sregs->histind = ebase.histlen - 1; |
| 1006 | } |
987 | 1007 | break; |
988 | 1008 | } |
989 | 1009 | if (sregs->err_mode) { |
… |
… |
run_sim_core(sregs, ntime, deb, dis) |
992 | 1012 | sregs->pwdstart = sregs->simtime; |
993 | 1013 | sregs->simtime = ntime; |
994 | 1014 | ctrl_c = 1; |
| 1015 | ebase.bpcpu = sregs->cpu; |
995 | 1016 | break; |
996 | 1017 | } |
997 | 1018 | } |
… |
… |
run_sim_core(sregs, ntime, deb, dis) |
1002 | 1023 | #endif |
1003 | 1024 | sregs->simtime += sregs->icnt + sregs->hold + sregs->fhold; |
1004 | 1025 | } |
1005 | | else |
| 1026 | else { |
1006 | 1027 | sregs->simtime = ntime; |
1007 | 1028 | if (ext_irl[sregs->cpu]) irq = check_interrupts(sregs); |
| 1029 | } |
1008 | 1030 | } |
1009 | 1031 | |
1010 | 1032 | /* time slice simulation of cpu cores in MP system */ |
… |
… |
run_sim_mp(icount, dis) |
1014 | 1036 | uint64 icount; |
1015 | 1037 | int dis; |
1016 | 1038 | { |
1017 | | uint64 ntime; |
| 1039 | uint64 ntime, etime; |
1018 | 1040 | int deb, i; |
1019 | | int err_mode, bphit, wphit; |
| 1041 | int err_mode, bphit, wphit, oldcpu; |
1020 | 1042 | |
1021 | 1043 | err_mode = bphit = wphit = 0; |
1022 | 1044 | icount += ebase.simtime; |
… |
… |
run_sim_mp(icount, dis) |
1031 | 1053 | if (ntime > icount) ntime = icount; |
1032 | 1054 | for(i=0; i<ncpu; i++) { |
1033 | 1055 | deb = dis || ebase.histlen || ebase.bptnum; |
| 1056 | etime = ntime; |
1034 | 1057 | run_sim_core(&sregs[i], ntime, deb, dis); |
1035 | 1058 | err_mode |= sregs[i].err_mode; |
1036 | | bphit |= ebase.bphit; |
| 1059 | bphit |= sregs[i].bphit; |
1037 | 1060 | wphit |= ebase.wphit; |
| 1061 | if (sregs[i].simtime < etime) |
| 1062 | etime = sregs[i].simtime; |
1038 | 1063 | } |
1039 | | advance_time(ntime); |
| 1064 | advance_time(etime); |
1040 | 1065 | if (ctrl_c) { |
1041 | 1066 | icount = 0; |
1042 | 1067 | } |
1043 | 1068 | } |
1044 | | /* align time of all cores to allow single stepping */ |
1045 | | for(i=0; i<ncpu; i++) { |
1046 | | sregs[i].simtime = ebase.simtime; |
1047 | | } |
| 1069 | |
| 1070 | oldcpu = cpu; |
| 1071 | cpu = ebase.bpcpu; |
| 1072 | if (err_mode == NULL_HIT) |
| 1073 | return NULL_HIT; |
1048 | 1074 | if (err_mode) |
1049 | 1075 | return ERROR; |
1050 | 1076 | if (bphit) |
… |
… |
run_sim_mp(icount, dis) |
1054 | 1080 | if (ctrl_c) { |
1055 | 1081 | return CTRL_C; |
1056 | 1082 | } |
| 1083 | cpu = oldcpu; |
1057 | 1084 | return TIME_OUT; |
1058 | 1085 | } |
1059 | 1086 | |
… |
… |
run_sim(icount, dis) |
1071 | 1098 | event(sim_timeout, 2, ebase.tlimit - ebase.simtime); |
1072 | 1099 | if (ebase.coven) |
1073 | 1100 | cov_start(sregs[0].pc); |
1074 | | if (ncpu > 1) |
1075 | | res = run_sim_mp(icount, dis); |
| 1101 | if ((ncpu == 1) || (icount == 1)) |
| 1102 | res = run_sim_un(&sregs[cpu], icount, dis); |
1076 | 1103 | else |
1077 | | res = run_sim_un(icount, dis); |
| 1104 | res = run_sim_mp(icount, dis); |
1078 | 1105 | remove_event(sim_timeout); |
1079 | 1106 | ebase.tottime += get_time() - ebase.starttime; |
1080 | 1107 | ms->restore_stdio (); |
diff --git a/sim/sis/interf.c b/sim/sis/interf.c
index 964304e585..ac85fc0d22 100644
a
|
b
|
run_sim_gdb(icount, dis) |
45 | 45 | |
46 | 46 | if (sis_verbose) |
47 | 47 | (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n", |
48 | | sregs->pc); |
49 | | if ((sregs->pc != 0) && (ebase.simtime == 0)) |
| 48 | sregs[cpu].pc); |
| 49 | if ((sregs[cpu].pc != 0) && (ebase.simtime == 0)) |
50 | 50 | ms->boot_init (); |
51 | 51 | res = run_sim(icount, dis); |
52 | 52 | clearerr(stdin); |
… |
… |
sim_store_register(sd, regno, value, length) |
249 | 249 | |
250 | 250 | regval = (value[0] << 24) | (value[1] << 16) |
251 | 251 | | (value[2] << 8) | value[3]; |
252 | | set_regi(sregs, regno, regval); |
| 252 | set_regi(&sregs[cpu], regno, regval); |
253 | 253 | return length; |
254 | 254 | } |
255 | 255 | |
… |
… |
sim_fetch_register(sd, regno, buf, length) |
261 | 261 | unsigned char *buf; |
262 | 262 | int length; |
263 | 263 | { |
264 | | get_regi(sregs, regno, buf, length); |
| 264 | get_regi(&sregs[cpu], regno, buf, length); |
265 | 265 | return -1; |
266 | 266 | } |
267 | 267 | |
… |
… |
sim_info(sd, verbose) |
292 | 292 | SIM_DESC sd; |
293 | 293 | int verbose; |
294 | 294 | { |
295 | | show_stat(sregs); |
| 295 | show_stat(&sregs[cpu]); |
296 | 296 | } |
297 | 297 | |
298 | 298 | int simstat = OK; |
… |
… |
sim_stop_reason(sd, reason, sigrc) |
319 | 319 | *reason = sim_stopped; |
320 | 320 | *sigrc = GDB_SIGNAL_TRAP; |
321 | 321 | break; |
| 322 | case NULL_HIT: |
| 323 | *reason = sim_stopped; |
| 324 | *sigrc = 11; |
| 325 | break; |
322 | 326 | case ERROR: |
323 | 327 | *sigrc = 0; |
324 | 328 | *reason = sim_exited; |
… |
… |
sim_resume(SIM_DESC sd, int step, int siggnal) |
334 | 338 | { |
335 | 339 | if (sis_verbose) |
336 | 340 | (*sim_callback->printf_filtered) (sim_callback, |
337 | | "sim_resume_start %x : %x : %x : %x : 0x%08x\n", step, siggnal, ebase.bphit, ebase.wphit, sregs[0].pc); |
338 | | if (step) { |
339 | | ebase.bphit = 0; |
340 | | ebase.wphit = 1; |
341 | | simstat = run_sim_gdb(1, 0); |
342 | | ebase.bphit = 0; |
343 | | ebase.wphit = 0; |
344 | | } else if (ebase.bphit || ebase.wphit) { |
345 | | ebase.bphit = 0; |
346 | | ebase.wphit = 1; |
| 341 | "sim_resume_start %x : %x : %x : %x : 0x%08x\n", |
| 342 | step, siggnal, sregs[cpu].bphit, ebase.wphit, sregs[cpu].pc); |
| 343 | if (step) |
347 | 344 | simstat = run_sim_gdb(1, 0); |
348 | | ebase.bphit = ebase.wphit = 0; |
349 | | simstat = run_sim_gdb(UINT64_MAX/2, 0); |
350 | | ebase.bphit = 0; |
351 | | } |
352 | 345 | else |
353 | 346 | simstat = run_sim_gdb(UINT64_MAX/2, 0); |
354 | 347 | |
355 | 348 | if (sis_verbose) |
356 | 349 | (*sim_callback->printf_filtered) (sim_callback, |
357 | | "sim_resume_end %x : %x : %x : %x : %x : 0x%08x\n", step, siggnal, ebase.bphit, ebase.wphit, simstat, sregs[0].pc); |
358 | | if (sis_gdb_break) flush_windows (sregs); |
| 350 | "sim_resume_end %x : %x : %x : %x : %x : 0x%08x\n", step, siggnal, sregs[cpu].bphit, ebase.wphit, simstat, sregs[cpu].pc); |
| 351 | if (sis_gdb_break) flush_windows (&sregs[cpu]); |
359 | 352 | } |
360 | 353 | |
361 | 354 | void |
diff --git a/sim/sis/riscv.h b/sim/sis/riscv.h
index 6a77e8d1fd..a624b6b908 100644
a
|
b
|
dispatch_instruction (sregs) |
481 | 481 | sregs->g[1] = npc; |
482 | 482 | npc = sregs->pc + offset; |
483 | 483 | npc &= ~1; |
| 484 | if (!npc) |
| 485 | sregs->trap = NULL_TRAP; // halt on null pointer |
484 | 486 | if (ebase.coven) |
485 | 487 | cov_jmp (sregs->pc, npc); |
486 | 488 | break; |
… |
… |
dispatch_instruction (sregs) |
684 | 686 | if (sis_gdb_break) |
685 | 687 | { |
686 | 688 | sregs->trap = WPT_TRAP; |
687 | | ebase.bphit = 1; |
| 689 | sregs->bphit = 1; |
688 | 690 | } |
689 | 691 | else |
690 | 692 | sregs->trap = TRAP_EBREAK; |
… |
… |
dispatch_instruction (sregs) |
852 | 854 | sregs->g[rd] = npc; |
853 | 855 | npc = sregs->pc + offset; |
854 | 856 | npc &= ~1; |
| 857 | if (!npc) |
| 858 | sregs->trap = NULL_TRAP; // halt on null pointer |
855 | 859 | if (ebase.coven) |
856 | 860 | cov_jmp (sregs->pc, npc); |
857 | 861 | break; |
… |
… |
dispatch_instruction (sregs) |
864 | 868 | sregs->g[rd] = npc; |
865 | 869 | npc = op1 + offset; |
866 | 870 | npc &= ~1; |
| 871 | if (!npc) |
| 872 | sregs->trap = NULL_TRAP; // halt on null pointer |
867 | 873 | if (ebase.coven) |
868 | 874 | cov_jmp (sregs->pc, npc); |
869 | 875 | sregs->icnt += T_JALR; |
… |
… |
dispatch_instruction (sregs) |
1403 | 1409 | if (sis_gdb_break) |
1404 | 1410 | { |
1405 | 1411 | sregs->trap = WPT_TRAP; |
1406 | | ebase.bphit = 1; |
| 1412 | sregs->bphit = 1; |
1407 | 1413 | } |
1408 | 1414 | else |
1409 | 1415 | sregs->trap = TRAP_EBREAK; |
… |
… |
execute_trap (sregs) |
2036 | 2042 | return (ERROR); |
2037 | 2043 | case WPT_TRAP: |
2038 | 2044 | return (WPT_HIT); |
| 2045 | case NULL_TRAP: |
| 2046 | return (NULL_HIT); |
| 2047 | |
2039 | 2048 | } |
2040 | 2049 | } |
2041 | 2050 | else |
diff --git a/sim/sis/sis.c b/sim/sis/sis.c
index 398da65bc3..0052e3768c 100644
a
|
b
|
main(argc, argv) |
55 | 55 | int lfile = 0; |
56 | 56 | char tlim[64] = ""; |
57 | 57 | int run = 0; |
| 58 | char prompt[8]; |
58 | 59 | |
59 | 60 | cfile = 0; |
60 | 61 | for (i = 0; i < 64; i++) |
61 | 62 | cmdq[i] = 0; |
62 | | printf("\n SIS - SPARC/RISCV instruction simulator %s, copyright Jiri Gaisler 1995\n", sis_version); |
| 63 | printf("\n SIS - SPARC/RISCV instruction simulator %s, copyright Jiri Gaisler 2019\n", sis_version); |
63 | 64 | printf (" Bug-reports to jiri@gaisler.se\n\n"); |
64 | 65 | while (stat < argc) { |
65 | 66 | if (argv[stat][0] == '-') { |
… |
… |
main(argc, argv) |
203 | 204 | cont = 0; |
204 | 205 | } |
205 | 206 | else { |
206 | | cmdq[cmdi] = readline("sis> "); |
| 207 | if (ncpu > 1) |
| 208 | sprintf(prompt, "cpu%d> ", cpu); |
| 209 | else |
| 210 | sprintf(prompt, "sis> "); |
| 211 | cmdq[cmdi] = readline(prompt); |
207 | 212 | if (cmdq[cmdi] && *cmdq[cmdi]) |
208 | 213 | add_history(cmdq[cmdi]); |
209 | 214 | if (cmdq[cmdi]) |
… |
… |
main(argc, argv) |
223 | 228 | ((double) ebase.simtime / (double) ebase.freq) / 1000.0); |
224 | 229 | break; |
225 | 230 | case BPT_HIT: |
226 | | printf("breakpoint at 0x%08x reached\n", sregs[0].pc); |
227 | | ebase.bphit = 1; |
| 231 | printf("cpu %d breakpoint at 0x%08x reached\n", |
| 232 | ebase.bpcpu, sregs[ebase.bpcpu].pc); |
228 | 233 | break; |
229 | 234 | case ERROR: |
230 | | printf("IU in error mode (%d)\n", sregs[0].trap); |
| 235 | printf("cpu %d in error mode (tt = 0x%02x)\n", |
| 236 | ebase.bpcpu, sregs[ebase.bpcpu].trap); |
231 | 237 | stat = 0; |
232 | 238 | printf(" %8" PRIu64 " ", ebase.simtime); |
233 | | dis_mem(sregs[0].pc, 1, &dinfo); |
| 239 | dis_mem(sregs[cpu].pc, 1, &dinfo); |
234 | 240 | break; |
235 | 241 | case WPT_HIT: |
236 | | printf("watchpoint at 0x%08x reached, pc = 0x%08x\n", |
237 | | ebase.wpaddress, sregs[0].pc); |
| 242 | printf("cpu %d watchpoint at 0x%08x reached, pc = 0x%08x\n", |
| 243 | ebase.bpcpu, ebase.wpaddress, sregs[ebase.bpcpu].pc); |
238 | 244 | ebase.wphit = 1; |
239 | 245 | break; |
| 246 | case NULL_HIT: |
| 247 | printf("null pointer dereferenced, cpu %d in error mode\n", |
| 248 | ebase.bpcpu); |
| 249 | stat = 0; |
| 250 | printf(" %8" PRIu64 " ", ebase.simtime); |
| 251 | dis_mem(sregs[cpu].pc, 1, &dinfo); |
| 252 | break; |
240 | 253 | case QUIT: |
241 | 254 | cont = 0; |
242 | 255 | break; |
diff --git a/sim/sis/sis.h b/sim/sis/sis.h
index edb5023938..1d241b33b3 100644
a
|
b
|
struct pstate { |
161 | 161 | uint64 mtimecmp; |
162 | 162 | uint32 lrq; |
163 | 163 | uint32 lrqa; |
| 164 | |
| 165 | uint32 bphit; |
164 | 166 | }; |
165 | 167 | |
166 | 168 | struct evcell { |
… |
… |
struct estate { |
181 | 183 | uint64 simstart; |
182 | 184 | uint64 tlimit; /* Simulation time limit */ |
183 | 185 | uint32 bptnum; |
184 | | uint32 bphit; |
185 | 186 | uint32 bpts[BPT_MAX]; /* Breakpoints */ |
186 | 187 | uint32 wprnum; |
187 | 188 | uint32 wphit; |
… |
… |
struct estate { |
195 | 196 | uint32 lrq; |
196 | 197 | uint32 coven; /* coverage enable */ |
197 | 198 | uint32 ramstart; /* start of RAM */ |
| 199 | uint32 bpcpu; /* cpu that hit breakpoint */ |
198 | 200 | }; |
199 | 201 | |
200 | 202 | /* return values for run_sim */ |
… |
… |
struct estate { |
204 | 206 | #define ERROR 3 |
205 | 207 | #define CTRL_C 4 |
206 | 208 | #define WPT_HIT 5 |
| 209 | #define NULL_HIT 6 |
207 | 210 | #define QUIT 10 |
208 | 211 | |
209 | 212 | /* special simulator trap types */ |
210 | 213 | #define ERROR_TRAP 257 |
211 | 214 | #define WPT_TRAP 258 |
| 215 | #define NULL_TRAP 259 |
212 | 216 | |
213 | 217 | /* cpu type defines */ |
214 | 218 | #define CPU_LEON2 2 |
… |
… |
extern int dumbio; |
270 | 274 | extern int tty_setup; |
271 | 275 | extern int cputype; |
272 | 276 | extern int sis_gdb_break; |
| 277 | extern int cpu; /* active debug cpu */ |
273 | 278 | extern int ncpu; /* number of online cpus */ |
274 | 279 | extern int delta; /* time slice for MP simulation */ |
275 | 280 | extern void pwd_enter(struct pstate *sregs); |
diff --git a/sim/sis/sparc.h b/sim/sis/sparc.h
index 9954a6f522..d90c1a7406 100644
a
|
b
|
dispatch_instruction(sregs) |
652 | 652 | (sregs->inst == 0x91d02001)) |
653 | 653 | { |
654 | 654 | sregs->trap = WPT_TRAP; |
655 | | ebase.bphit = 1; |
| 655 | sregs->bphit = 1; |
656 | 656 | } |
657 | 657 | } |
658 | 658 | break; |
… |
… |
dispatch_instruction(sregs) |
1014 | 1014 | } |
1015 | 1015 | *rdd = sregs->pc; |
1016 | 1016 | npc = rs1 + operand2; |
| 1017 | if (!npc) |
| 1018 | sregs->trap = NULL_TRAP; // halt on null pointer |
1017 | 1019 | if (ebase.coven) { |
1018 | 1020 | cov_jmp(sregs->pc, npc); |
1019 | 1021 | cov_exec(pc); /* delay slot executed */ |
… |
… |
dispatch_instruction(sregs) |
1039 | 1041 | sregs->trap = TRAP_UNALI; |
1040 | 1042 | break; |
1041 | 1043 | } |
| 1044 | if (!address) |
| 1045 | sregs->trap = NULL_TRAP; // halt on null pointer |
1042 | 1046 | sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp | PSR_ET; |
1043 | 1047 | sregs->psr = |
1044 | 1048 | (sregs->psr & ~PSR_S) | ((sregs->psr & PSR_PS) << 1); |
… |
… |
execute_trap(sregs) |
1850 | 1854 | return (ERROR); |
1851 | 1855 | case WPT_TRAP: |
1852 | 1856 | return (WPT_HIT); |
| 1857 | case NULL_TRAP: |
| 1858 | return (NULL_HIT); |
1853 | 1859 | } |
1854 | 1860 | } else { |
1855 | 1861 | |