Passify GCC.
[deliverable/binutils-gdb.git] / sim / common / sim-core.c
CommitLineData
f2de7dfd
AC
1/* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
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 of the License, or
8 (at your option) 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
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22#ifndef _SIM_CORE_C_
23#define _SIM_CORE_C_
24
c967f187
DE
25#include "sim-main.h"
26#include "sim-assert.h"
f2de7dfd
AC
27
28
c967f187 29/* "core" module install handler.
cd0d873d 30
c967f187
DE
31 This is called via sim_module_install to install the "core" subsystem
32 into the simulator. */
33
cd0d873d
AC
34static MODULE_INIT_FN sim_core_init;
35static MODULE_UNINSTALL_FN sim_core_uninstall;
36
c967f187
DE
37EXTERN_SIM_CORE\
38(SIM_RC)
39sim_core_install (SIM_DESC sd)
40{
50a2a691 41 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
c967f187
DE
42 sim_module_add_uninstall_fn (sd, sim_core_uninstall);
43 sim_module_add_init_fn (sd, sim_core_init);
44 return SIM_RC_OK;
45}
46
47
48/* Uninstall the "core" subsystem from the simulator. */
49
cd0d873d 50STATIC_SIM_CORE\
f2de7dfd 51(void)
c967f187
DE
52sim_core_uninstall (SIM_DESC sd)
53{
54 /* FIXME: free buffers, etc. */
55}
56
57
cd0d873d 58STATIC_SIM_CORE\
c967f187
DE
59(SIM_RC)
60sim_core_init (SIM_DESC sd)
f2de7dfd 61{
1fe05280 62 sim_core *memory = STATE_CORE(sd);
c967f187 63 sim_core_maps map;
f2de7dfd 64 for (map = 0;
c967f187 65 map < nr_sim_core_maps;
f2de7dfd
AC
66 map++) {
67 /* blow away old mappings */
c967f187 68 sim_core_mapping *curr = memory->map[map].first;
f2de7dfd 69 while (curr != NULL) {
c967f187 70 sim_core_mapping *tbd = curr;
f2de7dfd
AC
71 curr = curr->next;
72 if (tbd->free_buffer) {
c967f187 73 SIM_ASSERT(tbd->buffer != NULL);
f2de7dfd
AC
74 zfree(tbd->buffer);
75 }
76 zfree(tbd);
77 }
78 memory->map[map].first = NULL;
79 }
c967f187 80 return SIM_RC_OK;
f2de7dfd
AC
81}
82
83
84
50a2a691
AC
85#ifndef SIM_CORE_SIGNAL
86#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
87sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
88
cd0d873d
AC
89STATIC_SIM_CORE\
90(void)
50a2a691
AC
91sim_core_signal (SIM_DESC sd,
92 sim_cpu *cpu,
93 sim_cia cia,
94 sim_core_maps map,
95 int nr_bytes,
96 address_word addr,
97 transfer_type transfer,
98 sim_core_signals sig)
99{
100 const char *copy = (transfer == read_transfer ? "read" : "write");
101 switch (sig)
102 {
103 case sim_core_unmapped_signal:
104 sim_engine_abort (sd, cpu, cia, "sim-core: %d byte %s to unmaped address 0x%lx",
105 nr_bytes, copy, (unsigned long) addr);
106 break;
107 case sim_core_unaligned_signal:
108 sim_engine_abort (sd, cpu, cia, "sim-core: %d byte misaligned %s to address 0x%lx",
109 nr_bytes, copy, (unsigned long) addr);
110 break;
111 default:
112 sim_engine_abort (sd, cpu, cia, "sim_core_signal - internal error - bad switch");
113 }
114}
50a2a691
AC
115#endif
116
cd0d873d 117
1fe05280
AC
118STATIC_INLINE_SIM_CORE\
119(const char *)
120sim_core_map_to_str (sim_core_maps map)
121{
122 switch (map)
123 {
124 case sim_core_read_map: return "read";
125 case sim_core_write_map: return "write";
126 case sim_core_execute_map: return "exec";
127 default: return "(invalid-map)";
128 }
129}
130
131
cd0d873d 132STATIC_SIM_CORE\
c967f187
DE
133(sim_core_mapping *)
134new_sim_core_mapping(SIM_DESC sd,
50a2a691
AC
135 attach_type attach,
136 int space,
cd0d873d 137 address_word addr,
50a2a691
AC
138 unsigned nr_bytes,
139 device *device,
140 void *buffer,
141 int free_buffer)
f2de7dfd 142{
c967f187 143 sim_core_mapping *new_mapping = ZALLOC(sim_core_mapping);
f2de7dfd
AC
144 /* common */
145 new_mapping->level = attach;
146 new_mapping->space = space;
147 new_mapping->base = addr;
148 new_mapping->nr_bytes = nr_bytes;
149 new_mapping->bound = addr + (nr_bytes - 1);
150 if (attach == attach_raw_memory) {
151 new_mapping->buffer = buffer;
152 new_mapping->free_buffer = free_buffer;
153 }
154 else if (attach >= attach_callback) {
155 new_mapping->device = device;
156 }
157 else {
c967f187 158 sim_io_error (sd, "new_sim_core_mapping - internal error - unknown attach type %d\n",
f2de7dfd
AC
159 attach);
160 }
161 return new_mapping;
162}
163
164
cd0d873d 165STATIC_SIM_CORE\
f2de7dfd 166(void)
c967f187 167sim_core_map_attach(SIM_DESC sd,
7a418800
AC
168 sim_core_map *access_map,
169 attach_type attach,
170 int space,
cd0d873d 171 address_word addr,
7a418800
AC
172 unsigned nr_bytes, /* host limited */
173 device *client, /*callback/default*/
174 void *buffer, /*raw_memory*/
175 int free_buffer) /*raw_memory*/
f2de7dfd
AC
176{
177 /* find the insertion point for this additional mapping and then
178 insert */
c967f187
DE
179 sim_core_mapping *next_mapping;
180 sim_core_mapping **last_mapping;
f2de7dfd 181
c967f187 182 SIM_ASSERT((attach >= attach_callback && client != NULL && buffer == NULL && !free_buffer)
f2de7dfd
AC
183 || (attach == attach_raw_memory && client == NULL && buffer != NULL));
184
185 /* actually do occasionally get a zero size map */
186 if (nr_bytes == 0) {
187#if (WITH_DEVICES)
c967f187 188 device_error(client, "called on sim_core_map_attach with size zero");
f2de7dfd 189#else
c967f187 190 sim_io_error (sd, "called on sim_core_map_attach with size zero");
f2de7dfd
AC
191#endif
192 }
193
194 /* find the insertion point (between last/next) */
195 next_mapping = access_map->first;
196 last_mapping = &access_map->first;
197 while(next_mapping != NULL
198 && (next_mapping->level < attach
199 || (next_mapping->level == attach
200 && next_mapping->bound < addr))) {
201 /* provided levels are the same */
202 /* assert: next_mapping->base > all bases before next_mapping */
203 /* assert: next_mapping->bound >= all bounds before next_mapping */
204 last_mapping = &next_mapping->next;
205 next_mapping = next_mapping->next;
206 }
207
208 /* check insertion point correct */
c967f187 209 SIM_ASSERT(next_mapping == NULL || next_mapping->level >= attach);
f2de7dfd
AC
210 if (next_mapping != NULL && next_mapping->level == attach
211 && next_mapping->base < (addr + (nr_bytes - 1))) {
212#if (WITH_DEVICES)
213 device_error(client, "map overlap when attaching %d:0x%lx (%ld)",
214 space, (long)addr, (long)nr_bytes);
215#else
c967f187 216 sim_io_error (sd, "map overlap when attaching %d:0x%lx (%ld)",
f2de7dfd
AC
217 space, (long)addr, (long)nr_bytes);
218#endif
219 }
220
221 /* create/insert the new mapping */
c967f187 222 *last_mapping = new_sim_core_mapping(sd,
f2de7dfd
AC
223 attach,
224 space, addr, nr_bytes,
225 client, buffer, free_buffer);
226 (*last_mapping)->next = next_mapping;
227}
228
229
cd0d873d 230EXTERN_SIM_CORE\
f2de7dfd 231(void)
c967f187 232sim_core_attach(SIM_DESC sd,
7a418800
AC
233 sim_cpu *cpu,
234 attach_type attach,
235 access_type access,
236 int space,
cd0d873d 237 address_word addr,
7a418800
AC
238 unsigned nr_bytes, /* host limited */
239 device *client,
240 void *optional_buffer)
f2de7dfd 241{
1fe05280 242 sim_core *memory = STATE_CORE(sd);
c967f187 243 sim_core_maps map;
f2de7dfd
AC
244 void *buffer;
245 int buffer_freed;
7a418800
AC
246 int i;
247
248 /* check for for attempt to use unimplemented per-processor core map */
249 if (cpu != NULL)
250 sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported");
251
f2de7dfd
AC
252 if ((access & access_read_write_exec) == 0
253 || (access & ~access_read_write_exec) != 0) {
254#if (WITH_DEVICES)
255 device_error(client, "invalid access for core attach");
256#else
c967f187 257 sim_io_error (sd, "invalid access for core attach");
f2de7dfd
AC
258#endif
259 }
260 /* verify the attach type */
261 if (attach == attach_raw_memory) {
262 if (optional_buffer == NULL) {
263 buffer = zalloc(nr_bytes);
264 buffer_freed = 0;
265 }
266 else {
267 buffer = optional_buffer;
268 buffer_freed = 1;
269 }
270 }
271 else if (attach >= attach_callback) {
272 buffer = NULL;
273 buffer_freed = 1;
274 }
275 else {
276#if (WITH_DEVICES)
c967f187 277 device_error(client, "sim_core_attach - conflicting buffer and attach arguments");
f2de7dfd 278#else
c967f187 279 sim_io_error (sd, "sim_core_attach - conflicting buffer and attach arguments");
f2de7dfd
AC
280#endif
281 buffer = NULL;
282 buffer_freed = 1;
283 }
284 /* attach the region to all applicable access maps */
285 for (map = 0;
c967f187 286 map < nr_sim_core_maps;
f2de7dfd
AC
287 map++) {
288 switch (map) {
c967f187 289 case sim_core_read_map:
f2de7dfd 290 if (access & access_read)
c967f187 291 sim_core_map_attach(sd, &memory->map[map],
f2de7dfd
AC
292 attach,
293 space, addr, nr_bytes,
294 client, buffer, !buffer_freed);
295 buffer_freed ++;
296 break;
c967f187 297 case sim_core_write_map:
f2de7dfd 298 if (access & access_write)
c967f187 299 sim_core_map_attach(sd, &memory->map[map],
f2de7dfd
AC
300 attach,
301 space, addr, nr_bytes,
302 client, buffer, !buffer_freed);
303 buffer_freed ++;
304 break;
c967f187 305 case sim_core_execute_map:
f2de7dfd 306 if (access & access_exec)
c967f187 307 sim_core_map_attach(sd, &memory->map[map],
f2de7dfd
AC
308 attach,
309 space, addr, nr_bytes,
310 client, buffer, !buffer_freed);
311 buffer_freed ++;
312 break;
c967f187
DE
313 case nr_sim_core_maps:
314 sim_io_error (sd, "sim_core_attach - internal error - bad switch");
f2de7dfd
AC
315 break;
316 }
317 }
7a418800
AC
318
319 /* Just copy this map to each of the processor specific data structures.
320 FIXME - later this will be replaced by true processor specific
321 maps. */
322 for (i = 0; i < MAX_NR_PROCESSORS; i++)
cd0d873d
AC
323 {
324 CPU_CORE (STATE_CPU (sd, i))->common = *STATE_CORE (sd);
325 }
f2de7dfd
AC
326}
327
328
329STATIC_INLINE_SIM_CORE\
c967f187 330(sim_core_mapping *)
7a418800 331sim_core_find_mapping(sim_core *core,
c967f187 332 sim_core_maps map,
cd0d873d 333 address_word addr,
f2de7dfd 334 unsigned nr_bytes,
50a2a691 335 transfer_type transfer,
7a418800
AC
336 int abort, /*either 0 or 1 - hint to inline/-O */
337 sim_cpu *cpu, /* abort => cpu != NULL */
1fe05280 338 sim_cia cia)
f2de7dfd 339{
7a418800
AC
340 sim_core_mapping *mapping = core->map[map].first;
341 ASSERT ((addr & (nr_bytes - 1)) == 0); /* must be aligned */
342 ASSERT ((addr + (nr_bytes - 1)) >= addr); /* must not wrap */
343 ASSERT (!abort || cpu != NULL); /* abort needs a non null CPU */
344 while (mapping != NULL)
345 {
346 if (addr >= mapping->base
347 && (addr + (nr_bytes - 1)) <= mapping->bound)
348 return mapping;
349 mapping = mapping->next;
350 }
f2de7dfd 351 if (abort)
7a418800 352 {
50a2a691
AC
353 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, nr_bytes, addr, transfer,
354 sim_core_unmapped_signal);
7a418800 355 }
f2de7dfd
AC
356 return NULL;
357}
358
359
360STATIC_INLINE_SIM_CORE\
361(void *)
c967f187 362sim_core_translate(sim_core_mapping *mapping,
cd0d873d 363 address_word addr)
f2de7dfd
AC
364{
365 return (void *)(((char *)mapping->buffer) + addr - mapping->base);
366}
367
368
cd0d873d 369EXTERN_SIM_CORE\
f2de7dfd 370(unsigned)
c967f187
DE
371sim_core_read_buffer(SIM_DESC sd,
372 sim_core_maps map,
f2de7dfd 373 void *buffer,
cd0d873d 374 address_word addr,
f2de7dfd
AC
375 unsigned len)
376{
377 unsigned count = 0;
378 while (count < len) {
379 unsigned_word raddr = addr + count;
c967f187 380 sim_core_mapping *mapping =
7a418800 381 sim_core_find_mapping(STATE_CORE (sd), map,
50a2a691
AC
382 raddr, /*nr-bytes*/1,
383 read_transfer,
1fe05280 384 0, NULL, NULL_CIA); /*dont-abort*/
f2de7dfd
AC
385 if (mapping == NULL)
386 break;
387#if (WITH_DEVICES)
388 if (mapping->device != NULL) {
389 int nr_bytes = len - count;
390 if (raddr + nr_bytes - 1> mapping->bound)
391 nr_bytes = mapping->bound - raddr + 1;
392 if (device_io_read_buffer(mapping->device,
393 (unsigned_1*)buffer + count,
394 mapping->space,
395 raddr,
396 nr_bytes) != nr_bytes)
397 break;
398 count += nr_bytes;
399 }
400 else
401#endif
402 {
403 ((unsigned_1*)buffer)[count] =
c967f187 404 *(unsigned_1*)sim_core_translate(mapping, raddr);
f2de7dfd
AC
405 count += 1;
406 }
407 }
408 return count;
409}
410
411
cd0d873d 412EXTERN_SIM_CORE\
f2de7dfd 413(unsigned)
c967f187
DE
414sim_core_write_buffer(SIM_DESC sd,
415 sim_core_maps map,
f2de7dfd 416 const void *buffer,
cd0d873d 417 address_word addr,
f2de7dfd
AC
418 unsigned len)
419{
420 unsigned count = 0;
421 while (count < len) {
422 unsigned_word raddr = addr + count;
7a418800 423 sim_core_mapping *mapping = sim_core_find_mapping(STATE_CORE (sd), map,
50a2a691
AC
424 raddr, /*nr-bytes*/1,
425 write_transfer,
1fe05280 426 0, NULL, NULL_CIA); /*dont-abort*/
f2de7dfd
AC
427 if (mapping == NULL)
428 break;
429#if (WITH_DEVICES)
430 if (WITH_CALLBACK_MEMORY
431 && mapping->device != NULL) {
432 int nr_bytes = len - count;
433 if (raddr + nr_bytes - 1 > mapping->bound)
434 nr_bytes = mapping->bound - raddr + 1;
435 if (device_io_write_buffer(mapping->device,
436 (unsigned_1*)buffer + count,
437 mapping->space,
438 raddr,
439 nr_bytes) != nr_bytes)
440 break;
441 count += nr_bytes;
442 }
443 else
444#endif
445 {
c967f187 446 *(unsigned_1*)sim_core_translate(mapping, raddr) =
f2de7dfd
AC
447 ((unsigned_1*)buffer)[count];
448 count += 1;
449 }
450 }
451 return count;
452}
453
454
cd0d873d
AC
455EXTERN_SIM_CORE\
456(void)
457sim_core_set_xor (sim_cpu *cpu,
458 sim_cia cia,
459 int is_xor)
460{
461 sim_cpu_core *cpu_core = CPU_CORE (cpu);
462 /* set up the XOR registers if required. */
463 if (WITH_XOR_ENDIAN) {
464 {
465 int i = 1;
466 unsigned mask;
467 if (is_xor)
468 mask = WITH_XOR_ENDIAN - 1;
469 else
470 mask = 0;
471 while (i - 1 < WITH_XOR_ENDIAN)
472 {
473 cpu_core->xor[i-1] = mask;
474 mask = (mask << 1) & (WITH_XOR_ENDIAN - 1);
475 i = (i << 1);
476 }
477 }
478 }
479 else {
480 if (is_xor)
481 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
482 "Attempted to enable xor-endian mode when permenantly disabled.");
483 }
484}
485
486
487
488
f2de7dfd
AC
489/* define the read/write 1/2/4/8/word functions */
490
491#define N 1
492#include "sim-n-core.h"
493#undef N
494
495#define N 2
496#include "sim-n-core.h"
497#undef N
498
499#define N 4
500#include "sim-n-core.h"
501#undef N
502
503#define N 8
504#include "sim-n-core.h"
505#undef N
506
507#define N word
508#include "sim-n-core.h"
509#undef N
510
511#endif
This page took 0.059637 seconds and 4 git commands to generate.