Commit | Line | Data |
---|---|---|
15c16493 AC |
1 | /* This file is part of the program psim. |
2 | ||
3 | Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au> | |
4 | Copyright (C) 1997, Free Software Foundation | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 | ||
20 | */ | |
21 | ||
22 | ||
23 | #include <signal.h> /* FIXME - should be machine dependant version */ | |
24 | #include <stdarg.h> | |
25 | #include <ctype.h> | |
26 | ||
27 | #include "bfd.h" | |
28 | #include "sim-main.h" | |
d9b75947 AC |
29 | #include "sim-utils.h" |
30 | #include "sim-options.h" | |
15c16493 AC |
31 | |
32 | #ifdef HAVE_STDLIB_H | |
33 | #include <stdlib.h> | |
34 | #endif | |
35 | ||
36 | #ifdef HAVE_STRING_H | |
37 | #include <string.h> | |
38 | #else | |
39 | #ifdef HAVE_STRINGS_H | |
40 | #include <strings.h> | |
41 | #endif | |
42 | #endif | |
43 | ||
44 | ||
45 | #define SIM_ADDR unsigned | |
46 | ||
47 | /* Structures used by the simulator, for gdb just have static structures */ | |
48 | ||
49 | struct sim_state simulation = { 0 }; | |
50 | ||
51 | ||
52 | SIM_DESC | |
53 | sim_open (SIM_OPEN_KIND kind, char **argv) | |
54 | { | |
2e61a3ad AC |
55 | SIM_DESC sd = &simulation; |
56 | STATE_OPEN_KIND (sd) = kind; | |
57 | STATE_MAGIC (sd) = SIM_MAGIC_NUMBER; | |
15c16493 | 58 | |
2e61a3ad | 59 | if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) |
15c16493 AC |
60 | return 0; |
61 | ||
62 | /* getopt will print the error message so we just have to exit if this fails. | |
63 | FIXME: Hmmm... in the case of gdb we need getopt to call | |
64 | print_filtered. */ | |
2e61a3ad | 65 | if (sim_parse_args (sd, argv) != SIM_RC_OK) |
dd442a44 DE |
66 | { |
67 | /* Uninstall the modules to avoid memory leaks, | |
68 | file descriptor leaks, etc. */ | |
2e61a3ad | 69 | sim_module_uninstall (sd); |
dd442a44 DE |
70 | return 0; |
71 | } | |
72 | ||
2e61a3ad | 73 | if (sim_post_argv_init (sd) != SIM_RC_OK) |
dd442a44 DE |
74 | { |
75 | /* Uninstall the modules to avoid memory leaks, | |
76 | file descriptor leaks, etc. */ | |
2e61a3ad | 77 | sim_module_uninstall (sd); |
dd442a44 DE |
78 | return 0; |
79 | } | |
15c16493 | 80 | |
f03b093c | 81 | /* Initialize the main processor */ |
2e61a3ad AC |
82 | memset (&STATE_CPU (sd, 0)->reg, 0, sizeof STATE_CPU (sd, 0)->reg); |
83 | memset (&STATE_CPU (sd, 0)->acc, 0, sizeof STATE_CPU (sd, 0)->acc); | |
84 | memset (&STATE_CPU (sd, 0)->cr, 0, sizeof STATE_CPU (sd, 0)->cr); | |
85 | STATE_CPU (sd, 0)->is_user_mode = 0; | |
86 | memset (&STATE_CPU (sd, 0)->cia, 0, sizeof STATE_CPU (sd, 0)->cia); | |
87 | CPU_STATE (STATE_CPU (sd, 0)) = sd; | |
88 | ||
89 | /* establish the simulator configuration */ | |
90 | sim_config (sd, LITTLE_ENDIAN/*d30v always big endian*/); | |
15c16493 | 91 | |
d5e2c74e AC |
92 | #define TIC80_MEM_START 0x2000000 |
93 | #define TIC80_MEM_SIZE 0x100000 | |
94 | ||
15c16493 | 95 | /* external memory */ |
2e61a3ad | 96 | sim_core_attach(sd, |
7a418800 | 97 | NULL, |
15c16493 AC |
98 | attach_raw_memory, |
99 | access_read_write_exec, | |
d5e2c74e | 100 | 0, TIC80_MEM_START, TIC80_MEM_SIZE, NULL, NULL); |
2e61a3ad | 101 | sim_core_attach(sd, |
7a418800 | 102 | NULL, |
d5e2c74e AC |
103 | attach_raw_memory, |
104 | access_read_write_exec, | |
105 | 0, 0, TIC80_MEM_SIZE, NULL, NULL); | |
15c16493 AC |
106 | |
107 | /* FIXME: for now */ | |
2e61a3ad | 108 | return sd; |
15c16493 AC |
109 | } |
110 | ||
111 | ||
112 | /* NOTE: sim_size is going away */ | |
15c16493 | 113 | void |
2e61a3ad | 114 | sim_size (SIM_DESC sd, int i) |
15c16493 | 115 | { |
2e61a3ad | 116 | sim_io_error (sd, "unexpected call to sim_size()"); |
15c16493 AC |
117 | } |
118 | ||
119 | ||
120 | void | |
121 | sim_close (SIM_DESC sd, int quitting) | |
122 | { | |
dd442a44 DE |
123 | /* Uninstall the modules to avoid memory leaks, |
124 | file descriptor leaks, etc. */ | |
2e61a3ad | 125 | sim_module_uninstall (sd); |
15c16493 AC |
126 | } |
127 | ||
128 | ||
129 | SIM_RC | |
130 | sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty) | |
131 | { | |
15c16493 AC |
132 | bfd *prog_bfd; |
133 | ||
134 | prog_bfd = sim_load_file (sd, STATE_MY_NAME (sd), | |
135 | STATE_CALLBACK (sd), | |
136 | prog, | |
137 | /* pass NULL for abfd, we always open our own */ | |
138 | NULL, | |
139 | STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG); | |
140 | if (prog_bfd == NULL) | |
141 | return SIM_RC_FAIL; | |
142 | sim_analyze_program (sd, prog_bfd); | |
143 | return SIM_RC_OK; | |
144 | } | |
145 | ||
146 | ||
147 | void | |
148 | sim_kill (SIM_DESC sd) | |
149 | { | |
150 | } | |
151 | ||
152 | ||
153 | int | |
154 | sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) | |
155 | { | |
abe293a0 AC |
156 | return sim_core_read_buffer (sd, sim_core_write_map, |
157 | buf, mem, length); | |
15c16493 AC |
158 | } |
159 | ||
160 | ||
161 | int | |
162 | sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) | |
163 | { | |
164 | return sim_core_write_buffer (sd, sim_core_write_map, | |
165 | buf, mem, length); | |
166 | } | |
167 | ||
168 | ||
abe293a0 AC |
169 | /* FIXME - these magic numbers need to be moved elsewhere */ |
170 | ||
171 | #define SP_REGNUM 1 /* Contains address of top of stack */ | |
172 | #define FP_REGNUM 31 /* Contains address of executing stack frame */ | |
173 | #define PC_REGNUM 32 /* Contains program counter (FIXME?) */ | |
174 | #define NPC_REGNUM 33 /* Contains the next program counter (FIXME?) */ | |
175 | #define A0_REGNUM 34 /* Accumulator register 0 */ | |
176 | #define A3_REGNUM 37 /* Accumulator register 1 */ | |
177 | ||
178 | #define R0_REGNUM 0 /* General Purpose Register 0 - for sim */ | |
179 | #define Rn_REGNUM 31 /* Last General Purpose Register - for sim */ | |
180 | #define An_REGNUM A3_REGNUM /* Last Accumulator register - for sim */ | |
181 | ||
15c16493 | 182 | void |
abe293a0 | 183 | sim_fetch_register (SIM_DESC sd, int regnr, unsigned char *buf) |
15c16493 | 184 | { |
37a684b8 AC |
185 | if (regnr == R0_REGNUM) |
186 | memset (buf, 0, sizeof (unsigned32)); | |
187 | else if (regnr > R0_REGNUM && regnr <= Rn_REGNUM) | |
c445af5a | 188 | *(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->reg[regnr - R0_REGNUM]); |
abe293a0 AC |
189 | else if (regnr == PC_REGNUM) |
190 | *(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->cia.ip); | |
191 | else if (regnr == NPC_REGNUM) | |
192 | *(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->cia.dp); | |
193 | else if (regnr >= A0_REGNUM && regnr <= An_REGNUM) | |
194 | *(unsigned64*)buf = H2T_8 (STATE_CPU (sd, 0)->acc[regnr - A0_REGNUM]); | |
195 | else | |
196 | sim_io_error (sd, "sim_fetch_register - unknown register nr %d", regnr); | |
197 | return; | |
15c16493 AC |
198 | } |
199 | ||
200 | ||
201 | void | |
abe293a0 | 202 | sim_store_register (SIM_DESC sd, int regnr, unsigned char *buf) |
15c16493 | 203 | { |
abe293a0 | 204 | if (regnr >= R0_REGNUM && regnr <= Rn_REGNUM) |
c445af5a | 205 | STATE_CPU (sd, 0)->reg[regnr - R0_REGNUM] = T2H_4 (*(unsigned32*)buf); |
abe293a0 AC |
206 | else if (regnr == PC_REGNUM) |
207 | STATE_CPU (sd, 0)->cia.ip = T2H_4 (*(unsigned32*)buf); | |
208 | else if (regnr == NPC_REGNUM) | |
209 | STATE_CPU (sd, 0)->cia.dp = T2H_4 (*(unsigned32*)buf); | |
210 | else if (regnr == A0_REGNUM && regnr <= An_REGNUM) | |
43c53e07 | 211 | STATE_CPU (sd, 0)->acc[regnr - A0_REGNUM] = T2H_8 (*(unsigned64*)buf); |
abe293a0 AC |
212 | else |
213 | sim_io_error (sd, "sim_fetch_register - unknown register nr %d", regnr); | |
214 | return; | |
15c16493 AC |
215 | } |
216 | ||
217 | ||
218 | void | |
219 | sim_info (SIM_DESC sd, int verbose) | |
220 | { | |
221 | } | |
222 | ||
223 | ||
224 | SIM_RC | |
225 | sim_create_inferior (SIM_DESC sd, | |
226 | char **argv, | |
227 | char **envp) | |
228 | { | |
229 | STATE_CPU (sd, 0)->cia.ip = STATE_START_ADDR(sd); | |
230 | STATE_CPU (sd, 0)->cia.dp = (STATE_START_ADDR(sd) | |
231 | + sizeof (instruction_word)); | |
381f42ef | 232 | STATE_CPU (sd, 0)->cr[IE_CR] |= IE_CR_IE; |
d5e2c74e | 233 | STATE_CPU (sd, 0)->reg[1] = TIC80_MEM_START + TIC80_MEM_SIZE - 16; |
15c16493 AC |
234 | return SIM_RC_OK; |
235 | } | |
236 | ||
237 | ||
15c16493 AC |
238 | void |
239 | sim_do_command (SIM_DESC sd, char *cmd) | |
240 | { | |
43c53e07 AC |
241 | if (sim_args_command (sd, cmd) != SIM_RC_OK) |
242 | sim_io_eprintf (sd, "Unknown command `%s'\n", cmd); | |
15c16493 AC |
243 | } |
244 | ||
245 | ||
246 | void | |
247 | sim_set_callbacks (SIM_DESC sd, host_callback *callback) | |
248 | { | |
2e61a3ad | 249 | STATE_CALLBACK (sd) = callback; |
15c16493 | 250 | } |