]>
Commit | Line | Data |
---|---|---|
d70e3e2b DE |
1 | /* |
2 | * This file is part of SIS. | |
3 | * | |
4 | * SIS, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, European | |
5 | * Space Agency | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify it under | |
8 | * the terms of the GNU General Public License as published by the Free | |
9 | * Software Foundation; either version 2 of the License, or (at your option) | |
10 | * any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 | * more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License along with | |
18 | * this program; if not, write to the Free Software Foundation, Inc., 675 | |
19 | * Mass Ave, Cambridge, MA 02139, USA. | |
20 | * | |
21 | */ | |
22 | ||
23 | #include "config.h" | |
24 | ||
25 | #include <signal.h> | |
26 | #include <string.h> | |
27 | #ifdef HAVE_STDLIB_H | |
28 | #include <stdlib.h> | |
29 | #endif | |
30 | #include <stdio.h> | |
31 | #include "sis.h" | |
32 | #include <dis-asm.h> | |
33 | ||
34 | #ifndef fprintf | |
35 | extern fprintf(); | |
36 | #endif | |
37 | ||
38 | #define VAL(x) strtol(x,(char *)NULL,0) | |
39 | ||
40 | extern char *readline(char *prompt); /* GNU readline function */ | |
41 | ||
42 | /* Command history buffer length - MUST be binary */ | |
43 | #define HIST_LEN 64 | |
44 | ||
45 | extern struct disassemble_info dinfo; | |
46 | extern struct pstate sregs; | |
47 | extern struct estate ebase; | |
48 | ||
49 | extern int ctrl_c; | |
50 | extern int nfp; | |
51 | extern int sis_verbose; | |
52 | extern char *sis_version; | |
53 | extern struct estate ebase; | |
54 | extern struct evcell evbuf[]; | |
55 | extern struct irqcell irqarr[]; | |
56 | extern int irqpend, ext_irl; | |
57 | extern char uart_dev1[]; | |
58 | extern char uart_dev2[]; | |
59 | ||
60 | #ifdef IUREV0 | |
61 | extern int iurev0; | |
62 | #endif | |
63 | ||
64 | #ifdef MECREV0 | |
65 | extern int mecrev0; | |
66 | #endif | |
67 | ||
68 | run_sim(sregs, go, icount, dis) | |
69 | struct pstate *sregs; | |
70 | int go; | |
71 | unsigned int icount; | |
72 | int dis; | |
73 | { | |
74 | int mexc, ws; | |
75 | ||
76 | sregs->starttime = time(NULL); | |
77 | while (!sregs->err_mode & (go || (icount > 0))) { | |
78 | if (sregs->bptnum && check_bpt(sregs)) | |
79 | return (BPT_HIT); | |
80 | sregs->bphit = 0; | |
81 | sregs->fhold = 0; | |
82 | sregs->hold = 0; | |
83 | sregs->icnt = 0; | |
84 | ||
85 | sregs->asi = 9 - ((sregs->psr & 0x080) >> 7); | |
86 | ||
87 | #ifdef IUREV0 | |
88 | if (iurev0 && sregs->rett_err) { | |
89 | sregs->asi &= ~0x1; | |
90 | sregs->asi |= ((sregs->psr & 0x040) >> 6); | |
91 | } | |
92 | #endif | |
93 | ||
94 | mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, &sregs->hold); | |
95 | ||
96 | if (sregs->annul) { | |
97 | sregs->annul = 0; | |
98 | sregs->icnt = 1; | |
99 | sregs->pc = sregs->npc; | |
100 | sregs->npc = sregs->npc + 4; | |
101 | mexc = 0; /* Traps ignored during annul */ | |
102 | } else { | |
103 | check_interrupts(sregs); | |
104 | if (sregs->trap) { | |
105 | sregs->err_mode = execute_trap(sregs); | |
106 | } else { | |
107 | if (mexc) { | |
108 | sregs->trap = I_ACC_EXC; | |
109 | } else { | |
110 | if (sregs->histlen) { | |
111 | sregs->histbuf[sregs->histind].addr = sregs->pc; | |
112 | sregs->histbuf[sregs->histind].time = ebase.simtime; | |
113 | sregs->histind++; | |
114 | if (sregs->histind >= sregs->histlen) | |
115 | sregs->histind = 0; | |
116 | } | |
117 | if (dis) { | |
118 | printf(" %8u ", ebase.simtime); | |
119 | dis_mem(sregs->pc, 1, &dinfo); | |
120 | } | |
121 | dispatch_instruction(sregs); | |
122 | } | |
123 | icount--; | |
124 | } | |
125 | if (sregs->trap) { | |
126 | sregs->err_mode = execute_trap(sregs); | |
127 | } | |
128 | } | |
129 | advance_time(sregs); | |
130 | if (ctrl_c) { | |
131 | go = icount = 0; | |
132 | } | |
133 | } | |
134 | sregs->tottime += time(NULL) - sregs->starttime; | |
135 | if (sregs->err_mode) | |
136 | error_mode(sregs->pc); | |
137 | if (sregs->err_mode) | |
138 | return (ERROR); | |
139 | if (ctrl_c) { | |
140 | ctrl_c = 0; | |
141 | return (CTRL_C); | |
142 | } | |
143 | return (TIME_OUT); | |
144 | } | |
145 | ||
146 | main(argc, argv) | |
147 | int argc; | |
148 | char **argv; | |
149 | { | |
150 | ||
151 | int cont = 1; | |
152 | int stat = 1; | |
153 | int freq = 14; | |
154 | int copt = 0; | |
155 | ||
156 | char lastcmd[128] = "reg"; | |
157 | char *cmd, *cfile, *bacmd; | |
158 | char *cmdq[HIST_LEN]; | |
159 | int cmdi = 0; | |
160 | int i; | |
161 | ||
162 | for (i = 0; i < 64; i++) | |
163 | cmdq[i] = 0; | |
164 | printf("\n SIS - SPARC intruction simulator %s, copyright Jiri Gaisler 1995\n", sis_version); | |
165 | printf(" Bug-reports to [email protected]\n\n"); | |
166 | while (stat < argc) { | |
167 | if (argv[stat][0] == '-') { | |
168 | if (strcmp(argv[stat], "-v") == 0) { | |
169 | sis_verbose = 1; | |
170 | } else if (strcmp(argv[stat], "-c") == 0) { | |
171 | if ((stat + 1) < argc) { | |
172 | copt = 1; | |
173 | cfile = argv[++stat]; | |
174 | } | |
175 | } else if (strcmp(argv[stat], "-nfp") == 0) | |
176 | nfp = 1; | |
177 | #ifdef IUREV0 | |
178 | else if (strcmp(argv[stat], "-iurev0") == 0) | |
179 | iurev0 = 1; | |
180 | #endif | |
181 | #ifdef MECREV0 | |
182 | else if (strcmp(argv[stat], "-mecrev0") == 0) | |
183 | mecrev0 = 1; | |
184 | #endif | |
185 | else if (strcmp(argv[stat], "-uart1") == 0) { | |
186 | if ((stat + 1) < argc) | |
187 | strcpy(uart_dev1, argv[++stat]); | |
188 | } else if (strcmp(argv[stat], "-uart2") == 0) { | |
189 | if ((stat + 1) < argc) | |
190 | strcpy(uart_dev2, argv[++stat]); | |
191 | } else if (strcmp(argv[stat], "-freq") == 0) { | |
192 | if ((stat + 1) < argc) | |
193 | freq = VAL(argv[++stat]); | |
194 | } else { | |
195 | printf("unknown option %s\n", argv[stat]); | |
196 | usage(); | |
197 | exit(1); | |
198 | } | |
199 | } else { | |
200 | bfd_load(argv[stat]); | |
201 | } | |
202 | stat++; | |
203 | } | |
204 | #ifdef IUREV0 | |
205 | if (iurev0) | |
206 | printf(" simulating IU rev.0 jmpl/restore bug\n"); | |
207 | #endif | |
208 | #ifdef MECREV0 | |
209 | if (iurev0) | |
210 | printf(" simulating MEC rev.0 timer and uart interrupt bug\n"); | |
211 | #endif | |
212 | if (nfp) | |
213 | printf("FPU disabled\n"); | |
214 | sregs.freq = freq; | |
215 | ||
216 | INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf); | |
217 | ||
218 | using_history(); | |
219 | init_signals(); | |
220 | ebase.simtime = 0; | |
221 | reset_all(); | |
222 | init_bpt(&sregs); | |
223 | init_sim(); | |
224 | #ifdef STAT | |
225 | reset_stat(&sregs); | |
226 | #endif | |
227 | ||
228 | if (copt) { | |
229 | bacmd = (char *) malloc(256); | |
230 | strcpy(bacmd, "batch "); | |
231 | strcat(bacmd, cfile); | |
232 | exec_cmd(&sregs, bacmd); | |
233 | } | |
234 | while (cont) { | |
235 | ||
236 | if (cmdq[cmdi] != 0) { | |
237 | remove_history(cmdq[cmdi]); | |
238 | free(cmdq[cmdi]); | |
239 | cmdq[cmdi] = 0; | |
240 | } | |
241 | cmdq[cmdi] = readline("sis> "); | |
242 | if (cmdq[cmdi] && *cmdq[cmdi]) | |
243 | add_history(cmdq[cmdi]); | |
244 | if (cmdq[cmdi]) | |
245 | stat = exec_cmd(&sregs, cmdq[cmdi]); | |
246 | else { | |
247 | puts("\n"); | |
248 | exit(0); | |
249 | } | |
250 | switch (stat) { | |
251 | case OK: | |
252 | break; | |
253 | case CTRL_C: | |
254 | printf("\b\bInterrupt!\n"); | |
255 | case TIME_OUT: | |
256 | printf(" Stopped at time %d\n", ebase.simtime); | |
257 | break; | |
258 | case BPT_HIT: | |
259 | printf("breakpoint at 0x%08x reached\n", sregs.pc); | |
260 | sregs.bphit = 1; | |
261 | break; | |
262 | case ERROR: | |
263 | printf("IU in error mode (%d)\n", sregs.trap); | |
264 | stat = 0; | |
265 | printf(" %8d ", ebase.simtime); | |
266 | dis_mem(sregs.pc, 1, &dinfo); | |
267 | break; | |
268 | default: | |
269 | break; | |
270 | } | |
271 | ctrl_c = 0; | |
272 | stat = OK; | |
273 | ||
274 | cmdi = (cmdi + 1) & (HIST_LEN - 1); | |
275 | ||
276 | } | |
277 | } |