Commit | Line | Data |
---|---|---|
92fa4579 FCE |
1 | /* Main simulator entry points for the M32R. |
2 | Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. | |
3 | Contributed by Cygnus Support. | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 2, or (at your option) | |
8 | any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License along | |
16 | with this program; if not, write to the Free Software Foundation, Inc., | |
17 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
18 | ||
19 | #include "sim-main.h" | |
20 | #ifdef HAVE_STDLIB_H | |
21 | #include <stdlib.h> | |
22 | #endif | |
23 | #include "sim-options.h" | |
24 | #include "libiberty.h" | |
25 | #include "bfd.h" | |
26 | #include "sim-assert.h" | |
27 | ||
28 | ||
29 | static void free_state (SIM_DESC); | |
30 | ||
31 | /* Records simulator descriptor so utilities like m32r_dump_regs can be | |
32 | called from gdb. */ | |
33 | SIM_DESC current_state; | |
34 | \f | |
35 | /* Cover function of sim_state_free to free the cpu buffers as well. */ | |
36 | ||
37 | static void | |
38 | free_state (SIM_DESC sd) | |
39 | { | |
40 | if (STATE_MODULES (sd) != NULL) | |
41 | sim_module_uninstall (sd); | |
42 | sim_cpu_free_all (sd); | |
43 | sim_state_free (sd); | |
44 | } | |
45 | ||
46 | /* Create an instance of the simulator. */ | |
47 | ||
48 | SIM_DESC | |
49 | sim_open (kind, callback, abfd, argv) | |
50 | SIM_OPEN_KIND kind; | |
51 | host_callback *callback; | |
52 | struct _bfd *abfd; | |
53 | char **argv; | |
54 | { | |
55 | SIM_DESC sd = sim_state_alloc (kind, callback); | |
56 | ||
57 | sim_cpu_alloc_all (sd, 1, 0); | |
58 | ||
59 | if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) | |
60 | { | |
61 | free_state (sd); | |
62 | return 0; | |
63 | } | |
64 | ||
65 | /* Allocate core managed memory */ | |
66 | sim_do_commandf (sd, "memory region 0,0x%lx", M32R_DEFAULT_MEM_SIZE); | |
67 | ||
68 | /* getopt will print the error message so we just have to exit if this fails. | |
69 | FIXME: Hmmm... in the case of gdb we need getopt to call | |
70 | print_filtered. */ | |
71 | if (sim_parse_args (sd, argv) != SIM_RC_OK) | |
72 | { | |
73 | free_state (sd); | |
74 | return 0; | |
75 | } | |
76 | ||
77 | /* check for/establish the reference program image */ | |
78 | if (sim_analyze_program (sd, | |
79 | (STATE_PROG_ARGV (sd) != NULL | |
80 | ? *STATE_PROG_ARGV (sd) | |
81 | : NULL), | |
82 | abfd) != SIM_RC_OK) | |
83 | { | |
84 | free_state (sd); | |
85 | return 0; | |
86 | } | |
87 | ||
88 | /* Establish any remaining configuration options. */ | |
89 | if (sim_config (sd) != SIM_RC_OK) | |
90 | { | |
91 | free_state (sd); | |
92 | return 0; | |
93 | } | |
94 | ||
95 | if (sim_post_argv_init (sd) != SIM_RC_OK) | |
96 | { | |
97 | free_state (sd); | |
98 | return 0; | |
99 | } | |
100 | ||
101 | /* Store in a global so things like sparc32_dump_regs can be invoked | |
102 | from the gdb command line. */ | |
103 | current_state = sd; | |
104 | sim_gx_read_block_list(); | |
105 | return sd; | |
106 | } | |
107 | ||
108 | void | |
109 | sim_close (sd, quitting) | |
110 | SIM_DESC sd; | |
111 | int quitting; | |
112 | { | |
113 | sim_gx_write_block_list(); | |
114 | sim_module_uninstall (sd); | |
115 | } | |
116 | ||
117 | ||
118 | USI | |
119 | m32r_h_pc_get (SIM_CPU *current_cpu) | |
120 | { | |
121 | return current_cpu->regs.h_pc; | |
122 | } | |
123 | ||
124 | /* Set a value for h-pc. */ | |
125 | ||
126 | void | |
127 | m32r_h_pc_set (SIM_CPU *current_cpu, USI newval) | |
128 | { | |
129 | current_cpu->regs.h_pc = newval; | |
130 | } | |
131 | ||
132 | ||
133 | SIM_RC | |
134 | sim_create_inferior (sd, abfd, argv, envp) | |
135 | SIM_DESC sd; | |
136 | struct _bfd *abfd; | |
137 | char **argv; | |
138 | char **envp; | |
139 | { | |
140 | SIM_CPU *current_cpu = STATE_CPU (sd, 0); | |
141 | SIM_ADDR addr; | |
142 | ||
143 | CPU_PC_STORE (current_cpu) = m32r_h_pc_set; | |
144 | CPU_PC_FETCH (current_cpu) = m32r_h_pc_get; | |
3d7075f5 FCE |
145 | CPU_REG_STORE (current_cpu) = NULL; |
146 | CPU_REG_FETCH (current_cpu) = NULL; | |
92fa4579 FCE |
147 | |
148 | if (abfd != NULL) | |
149 | addr = bfd_get_start_address (abfd); | |
150 | else | |
151 | addr = 0; | |
152 | ||
153 | sim_pc_set (current_cpu, addr); | |
154 | ||
155 | #if 0 | |
156 | STATE_ARGV (sd) = sim_copy_argv (argv); | |
157 | STATE_ENVP (sd) = sim_copy_argv (envp); | |
158 | #endif | |
159 | ||
160 | return SIM_RC_OK; | |
161 | } | |
162 | ||
163 | int | |
164 | sim_stop (SIM_DESC sd) | |
165 | { | |
166 | sim_io_error(sd, "cannot sim_stop\n"); | |
167 | } | |
168 | ||
169 | /* This isn't part of the official interface. | |
170 | This is just a good place to put this for now. */ | |
171 | ||
172 | void | |
173 | sim_sync_stop (SIM_DESC sd, SIM_CPU *cpu, PCADDR pc, enum sim_stop reason, int sigrc) | |
174 | { | |
175 | sim_io_error(sd, "cannot sim_stop\n"); | |
176 | } | |
177 | ||
178 | void | |
179 | sim_resume (sd, step, siggnal) | |
180 | SIM_DESC sd; | |
181 | int step, siggnal; | |
182 | { | |
183 | sim_engine *engine = STATE_ENGINE (sd); | |
184 | jmp_buf buf; | |
185 | int jmpval; | |
186 | ||
187 | sim_module_resume (sd); | |
188 | ASSERT(step == 0); /* XXX */ | |
189 | ||
190 | engine->jmpbuf = &buf; | |
191 | jmpval = setjmp (buf); | |
192 | if(jmpval == 0) | |
193 | sim_engine_run(sd, 0, 1, siggnal); | |
194 | engine->jmpbuf = NULL; | |
195 | ||
196 | sim_module_suspend (sd); | |
197 | } | |
198 | ||
199 | /* The contents of BUF are in target byte order. */ | |
200 | ||
201 | int | |
202 | sim_fetch_register (sd, rn, buf, length) | |
203 | SIM_DESC sd; | |
204 | int rn; | |
205 | unsigned char *buf; | |
206 | int length; | |
207 | { | |
208 | SIM_CPU *cpu = STATE_CPU (sd, 0); | |
209 | ||
210 | return (* CPU_REG_FETCH (cpu)) (cpu, rn, buf, length); | |
211 | } | |
212 | ||
213 | /* The contents of BUF are in target byte order. */ | |
214 | ||
215 | int | |
216 | sim_store_register (sd, rn, buf, length) | |
217 | SIM_DESC sd; | |
218 | int rn; | |
219 | unsigned char *buf; | |
220 | int length; | |
221 | { | |
222 | SIM_CPU *cpu = STATE_CPU (sd, 0); | |
223 | ||
224 | return (* CPU_REG_STORE (cpu)) (cpu, rn, buf, length); | |
225 | } | |
226 | ||
227 | void | |
228 | sim_do_command (sd, cmd) | |
229 | SIM_DESC sd; | |
230 | char *cmd; | |
231 | { | |
232 | if (sim_args_command (sd, cmd) != SIM_RC_OK) | |
233 | sim_io_eprintf (sd, "Unknown command `%s'\n", cmd); | |
234 | } | |
235 | \f | |
236 | /* Utility fns to access registers, without knowing the current mach. */ | |
237 | ||
238 | SI | |
239 | h_gr_get (SIM_CPU *current_cpu, UINT regno) | |
240 | { | |
241 | SIM_DESC sd = CURRENT_STATE; | |
242 | sim_io_error(sd, "cannot h_gr_get\n"); | |
243 | } | |
244 | ||
245 | void | |
246 | h_gr_set (SIM_CPU *current_cpu, UINT regno, SI newval) | |
247 | { | |
248 | SIM_DESC sd = CURRENT_STATE; | |
249 | sim_io_error(sd, "cannot h_gr_set\n"); | |
250 | } |