* Make-common.in (SIM_NEW_COMMON_OBJS): New variable.
[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 27
fd89abc2
AC
28#include <signal.h>
29
30/* for Windows builds. signal numbers used by MSVC are mostly
31 the same as non-linux unixen. */
32#ifndef SIGBUS
33# define SIGBUS 10
34#endif
35
f2de7dfd 36
c967f187 37/* "core" module install handler.
cd0d873d 38
c967f187
DE
39 This is called via sim_module_install to install the "core" subsystem
40 into the simulator. */
41
cd0d873d
AC
42static MODULE_INIT_FN sim_core_init;
43static MODULE_UNINSTALL_FN sim_core_uninstall;
44
c967f187
DE
45EXTERN_SIM_CORE\
46(SIM_RC)
47sim_core_install (SIM_DESC sd)
48{
50a2a691 49 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
a34abff8
AC
50
51 /* establish the other handlers */
c967f187
DE
52 sim_module_add_uninstall_fn (sd, sim_core_uninstall);
53 sim_module_add_init_fn (sd, sim_core_init);
a34abff8
AC
54
55 /* establish any initial data structures - none */
c967f187
DE
56 return SIM_RC_OK;
57}
58
59
60/* Uninstall the "core" subsystem from the simulator. */
61
cd0d873d 62STATIC_SIM_CORE\
f2de7dfd 63(void)
c967f187 64sim_core_uninstall (SIM_DESC sd)
f2de7dfd 65{
f90b720b 66 sim_core *core = STATE_CORE(sd);
c967f187 67 sim_core_maps map;
a34abff8 68 /* blow away any mappings */
f90b720b 69 for (map = 0; map < nr_sim_core_maps; map++) {
f90b720b 70 sim_core_mapping *curr = core->common.map[map].first;
f2de7dfd 71 while (curr != NULL) {
c967f187 72 sim_core_mapping *tbd = curr;
f2de7dfd 73 curr = curr->next;
fd89abc2 74 if (tbd->free_buffer != NULL) {
c967f187 75 SIM_ASSERT(tbd->buffer != NULL);
fd89abc2 76 zfree(tbd->free_buffer);
f2de7dfd
AC
77 }
78 zfree(tbd);
79 }
f90b720b
AC
80 core->common.map[map].first = NULL;
81 }
a34abff8
AC
82}
83
84
85STATIC_SIM_CORE\
86(SIM_RC)
87sim_core_init (SIM_DESC sd)
88{
89 /* Nothing to do */
c967f187 90 return SIM_RC_OK;
f2de7dfd
AC
91}
92
93
94
50a2a691
AC
95#ifndef SIM_CORE_SIGNAL
96#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
97sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
98
cd0d873d
AC
99STATIC_SIM_CORE\
100(void)
50a2a691
AC
101sim_core_signal (SIM_DESC sd,
102 sim_cpu *cpu,
103 sim_cia cia,
104 sim_core_maps map,
105 int nr_bytes,
106 address_word addr,
107 transfer_type transfer,
108 sim_core_signals sig)
109{
110 const char *copy = (transfer == read_transfer ? "read" : "write");
cf02c13c
DE
111 /* The CIA could either be a struct or a simple type. Regardless,
112 the address of the instruction is found in the first word. */
113 address_word ip = *(address_word*)&cia;
50a2a691
AC
114 switch (sig)
115 {
116 case sim_core_unmapped_signal:
cf02c13c
DE
117 sim_io_eprintf (sd, "core: %d byte %s to unmaped address 0x%lx at 0x%lx\n",
118 nr_bytes, copy, (unsigned long) addr, (unsigned long) ip);
fd89abc2 119 sim_engine_halt (sd, cpu, NULL, cia, sim_signalled, SIGSEGV);
50a2a691
AC
120 break;
121 case sim_core_unaligned_signal:
cf02c13c
DE
122 sim_io_eprintf (sd, "core: %d byte misaligned %s to address 0x%lx at 0x%lx\n",
123 nr_bytes, copy, (unsigned long) addr, (unsigned long) ip);
fd89abc2 124 sim_engine_halt (sd, cpu, NULL, cia, sim_signalled, SIGBUS);
50a2a691
AC
125 break;
126 default:
fd89abc2
AC
127 sim_engine_abort (sd, cpu, cia,
128 "sim_core_signal - internal error - bad switch");
50a2a691
AC
129 }
130}
50a2a691
AC
131#endif
132
cd0d873d 133
1fe05280
AC
134STATIC_INLINE_SIM_CORE\
135(const char *)
136sim_core_map_to_str (sim_core_maps map)
137{
138 switch (map)
139 {
140 case sim_core_read_map: return "read";
141 case sim_core_write_map: return "write";
142 case sim_core_execute_map: return "exec";
143 default: return "(invalid-map)";
144 }
145}
146
147
cd0d873d 148STATIC_SIM_CORE\
c967f187 149(sim_core_mapping *)
a34abff8 150new_sim_core_mapping (SIM_DESC sd,
fcc86d82 151 int level,
a34abff8
AC
152 int space,
153 address_word addr,
154 address_word nr_bytes,
155 unsigned modulo,
156 device *device,
157 void *buffer,
fd89abc2 158 void *free_buffer)
f2de7dfd 159{
c967f187 160 sim_core_mapping *new_mapping = ZALLOC(sim_core_mapping);
f2de7dfd 161 /* common */
fcc86d82 162 new_mapping->level = level;
f2de7dfd
AC
163 new_mapping->space = space;
164 new_mapping->base = addr;
165 new_mapping->nr_bytes = nr_bytes;
166 new_mapping->bound = addr + (nr_bytes - 1);
a34abff8
AC
167 if (modulo == 0)
168 new_mapping->mask = (unsigned) 0 - 1;
169 else
170 new_mapping->mask = modulo - 1;
fcc86d82
AC
171 new_mapping->buffer = buffer;
172 new_mapping->free_buffer = free_buffer;
173 new_mapping->device = device;
f2de7dfd
AC
174 return new_mapping;
175}
176
177
cd0d873d 178STATIC_SIM_CORE\
f2de7dfd 179(void)
a34abff8
AC
180sim_core_map_attach (SIM_DESC sd,
181 sim_core_map *access_map,
fcc86d82 182 int level,
a34abff8
AC
183 int space,
184 address_word addr,
185 address_word nr_bytes,
186 unsigned modulo,
187 device *client, /*callback/default*/
188 void *buffer, /*raw_memory*/
fd89abc2 189 void *free_buffer) /*raw_memory*/
f2de7dfd
AC
190{
191 /* find the insertion point for this additional mapping and then
192 insert */
c967f187
DE
193 sim_core_mapping *next_mapping;
194 sim_core_mapping **last_mapping;
f2de7dfd 195
fcc86d82
AC
196 SIM_ASSERT ((client == NULL) != (buffer == NULL));
197 SIM_ASSERT ((client == NULL) >= (free_buffer != NULL));
f2de7dfd
AC
198
199 /* actually do occasionally get a zero size map */
a34abff8
AC
200 if (nr_bytes == 0)
201 {
f2de7dfd 202#if (WITH_DEVICES)
a34abff8 203 device_error(client, "called on sim_core_map_attach with size zero");
f2de7dfd 204#else
a34abff8 205 sim_io_error (sd, "called on sim_core_map_attach with size zero");
f2de7dfd 206#endif
a34abff8 207 }
f2de7dfd
AC
208
209 /* find the insertion point (between last/next) */
210 next_mapping = access_map->first;
211 last_mapping = &access_map->first;
212 while(next_mapping != NULL
fcc86d82
AC
213 && (next_mapping->level < level
214 || (next_mapping->level == level
a34abff8
AC
215 && next_mapping->bound < addr)))
216 {
217 /* provided levels are the same */
218 /* assert: next_mapping->base > all bases before next_mapping */
219 /* assert: next_mapping->bound >= all bounds before next_mapping */
220 last_mapping = &next_mapping->next;
221 next_mapping = next_mapping->next;
222 }
223
f2de7dfd 224 /* check insertion point correct */
fcc86d82
AC
225 SIM_ASSERT (next_mapping == NULL || next_mapping->level >= level);
226 if (next_mapping != NULL && next_mapping->level == level
80c651f0
AC
227 && next_mapping->base < (addr + (nr_bytes - 1)))
228 {
f2de7dfd 229#if (WITH_DEVICES)
80c651f0
AC
230 device_error (client, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
231 space,
232 (long) addr,
233 (long) nr_bytes,
234 (long) (addr + (nr_bytes - 1)),
235 next_mapping->space,
236 (long) next_mapping->base,
237 (long) next_mapping->bound,
238 (long) next_mapping->nr_bytes);
f2de7dfd 239#else
80c651f0
AC
240 sim_io_error (sd, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
241 space,
242 (long) addr,
243 (long) nr_bytes,
244 (long) (addr + (nr_bytes - 1)),
245 next_mapping->space,
246 (long) next_mapping->base,
247 (long) next_mapping->bound,
248 (long) next_mapping->nr_bytes);
f2de7dfd
AC
249#endif
250 }
251
252 /* create/insert the new mapping */
c967f187 253 *last_mapping = new_sim_core_mapping(sd,
fcc86d82 254 level,
a34abff8 255 space, addr, nr_bytes, modulo,
80c651f0 256 client, buffer, free_buffer);
f2de7dfd
AC
257 (*last_mapping)->next = next_mapping;
258}
259
260
cd0d873d 261EXTERN_SIM_CORE\
f2de7dfd 262(void)
a34abff8
AC
263sim_core_attach (SIM_DESC sd,
264 sim_cpu *cpu,
fcc86d82 265 int level,
a34abff8
AC
266 access_type access,
267 int space,
268 address_word addr,
269 address_word nr_bytes,
270 unsigned modulo,
271 device *client,
272 void *optional_buffer)
f2de7dfd 273{
1fe05280 274 sim_core *memory = STATE_CORE(sd);
c967f187 275 sim_core_maps map;
f2de7dfd 276 void *buffer;
fd89abc2 277 void *free_buffer;
7a418800
AC
278
279 /* check for for attempt to use unimplemented per-processor core map */
280 if (cpu != NULL)
281 sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported");
282
f2de7dfd 283 if ((access & access_read_write_exec) == 0
a34abff8
AC
284 || (access & ~access_read_write_exec) != 0)
285 {
f2de7dfd 286#if (WITH_DEVICES)
a34abff8 287 device_error(client, "invalid access for core attach");
f2de7dfd 288#else
a34abff8 289 sim_io_error (sd, "invalid access for core attach");
f2de7dfd 290#endif
a34abff8
AC
291 }
292
fcc86d82
AC
293 /* verify modulo memory */
294 if (!WITH_MODULO_MEMORY && modulo != 0)
295 {
296#if (WITH_DEVICES)
297 device_error (client, "sim_core_attach - internal error - modulo memory disabled");
298#else
299 sim_io_error (sd, "sim_core_attach - internal error - modulo memory disabled");
300#endif
301 }
302 if (client != NULL && modulo != 0)
a34abff8 303 {
a34abff8 304#if (WITH_DEVICES)
fcc86d82 305 device_error (client, "sim_core_attach - internal error - modulo and callback memory conflict");
a34abff8 306#else
fcc86d82 307 sim_io_error (sd, "sim_core_attach - internal error - modulo and callback memory conflict");
a34abff8 308#endif
fcc86d82
AC
309 }
310 if (modulo != 0)
311 {
312 unsigned mask = modulo - 1;
313 /* any zero bits */
314 while (mask >= sizeof (unsigned64)) /* minimum modulo */
315 {
316 if ((mask & 1) == 0)
317 mask = 0;
318 else
319 mask >>= 1;
a34abff8 320 }
fcc86d82 321 if (mask != sizeof (unsigned64) - 1)
a34abff8
AC
322 {
323#if (WITH_DEVICES)
fcc86d82 324 device_error (client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
a34abff8 325#else
fcc86d82 326 sim_io_error (sd, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
a34abff8
AC
327#endif
328 }
fcc86d82
AC
329 }
330
331 /* verify consistency between device and buffer */
332 if (client != NULL && optional_buffer != NULL)
333 {
334#if (WITH_DEVICES)
335 device_error (client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
336#else
337 sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments");
338#endif
339 }
340 if (client == NULL)
341 {
a34abff8
AC
342 if (optional_buffer == NULL)
343 {
fd89abc2
AC
344 int padding = (addr % sizeof (unsigned64));
345 free_buffer = zalloc ((modulo == 0 ? nr_bytes : modulo) + padding);
346 buffer = (char*) free_buffer + padding;
a34abff8
AC
347 }
348 else
349 {
350 buffer = optional_buffer;
fd89abc2 351 free_buffer = NULL;
a34abff8 352 }
f2de7dfd 353 }
a34abff8
AC
354 else
355 {
fcc86d82 356 /* a device */
a34abff8 357 buffer = NULL;
fd89abc2 358 free_buffer = NULL;
a34abff8
AC
359 }
360
f2de7dfd
AC
361 /* attach the region to all applicable access maps */
362 for (map = 0;
c967f187 363 map < nr_sim_core_maps;
a34abff8
AC
364 map++)
365 {
366 switch (map)
367 {
368 case sim_core_read_map:
369 if (access & access_read)
370 sim_core_map_attach (sd, &memory->common.map[map],
fcc86d82 371 level, space, addr, nr_bytes, modulo,
fd89abc2
AC
372 client, buffer, free_buffer);
373 free_buffer = NULL;
a34abff8
AC
374 break;
375 case sim_core_write_map:
376 if (access & access_write)
377 sim_core_map_attach (sd, &memory->common.map[map],
fcc86d82 378 level, space, addr, nr_bytes, modulo,
fd89abc2
AC
379 client, buffer, free_buffer);
380 free_buffer = NULL;
a34abff8
AC
381 break;
382 case sim_core_execute_map:
383 if (access & access_exec)
384 sim_core_map_attach (sd, &memory->common.map[map],
fcc86d82 385 level, space, addr, nr_bytes, modulo,
fd89abc2
AC
386 client, buffer, free_buffer);
387 free_buffer = NULL;
a34abff8
AC
388 break;
389 case nr_sim_core_maps:
390 sim_io_error (sd, "sim_core_attach - internal error - bad switch");
391 break;
392 }
f2de7dfd 393 }
a34abff8 394
7a418800
AC
395 /* Just copy this map to each of the processor specific data structures.
396 FIXME - later this will be replaced by true processor specific
397 maps. */
f90b720b
AC
398 {
399 int i;
400 for (i = 0; i < MAX_NR_PROCESSORS; i++)
401 {
402 CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
403 }
404 }
f2de7dfd
AC
405}
406
407
a34abff8
AC
408/* Remove any memory reference related to this address */
409STATIC_INLINE_SIM_CORE\
410(void)
411sim_core_map_detach (SIM_DESC sd,
412 sim_core_map *access_map,
fcc86d82 413 int level,
a34abff8
AC
414 int space,
415 address_word addr)
416{
417 sim_core_mapping **entry;
418 for (entry = &access_map->first;
419 (*entry) != NULL;
420 entry = &(*entry)->next)
421 {
422 if ((*entry)->base == addr
fcc86d82 423 && (*entry)->level == level
a34abff8
AC
424 && (*entry)->space == space)
425 {
426 sim_core_mapping *dead = (*entry);
427 (*entry) = dead->next;
fd89abc2
AC
428 if (dead->free_buffer != NULL)
429 zfree (dead->free_buffer);
a34abff8
AC
430 zfree (dead);
431 return;
432 }
433 }
434}
435
436EXTERN_SIM_CORE\
437(void)
438sim_core_detach (SIM_DESC sd,
439 sim_cpu *cpu,
fcc86d82 440 int level,
a34abff8
AC
441 int address_space,
442 address_word addr)
443{
444 sim_core *memory = STATE_CORE (sd);
445 sim_core_maps map;
446 for (map = 0; map < nr_sim_core_maps; map++)
447 {
448 sim_core_map_detach (sd, &memory->common.map[map],
fcc86d82 449 level, address_space, addr);
a34abff8
AC
450 }
451 /* Just copy this update to each of the processor specific data
452 structures. FIXME - later this will be replaced by true
453 processor specific maps. */
454 {
455 int i;
456 for (i = 0; i < MAX_NR_PROCESSORS; i++)
457 {
458 CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
459 }
460 }
461}
462
463
f2de7dfd 464STATIC_INLINE_SIM_CORE\
c967f187 465(sim_core_mapping *)
f90b720b 466sim_core_find_mapping(sim_core_common *core,
c967f187 467 sim_core_maps map,
cd0d873d 468 address_word addr,
f2de7dfd 469 unsigned nr_bytes,
50a2a691 470 transfer_type transfer,
7a418800
AC
471 int abort, /*either 0 or 1 - hint to inline/-O */
472 sim_cpu *cpu, /* abort => cpu != NULL */
1fe05280 473 sim_cia cia)
f2de7dfd 474{
7a418800
AC
475 sim_core_mapping *mapping = core->map[map].first;
476 ASSERT ((addr & (nr_bytes - 1)) == 0); /* must be aligned */
477 ASSERT ((addr + (nr_bytes - 1)) >= addr); /* must not wrap */
478 ASSERT (!abort || cpu != NULL); /* abort needs a non null CPU */
479 while (mapping != NULL)
480 {
481 if (addr >= mapping->base
482 && (addr + (nr_bytes - 1)) <= mapping->bound)
483 return mapping;
484 mapping = mapping->next;
485 }
f2de7dfd 486 if (abort)
7a418800 487 {
50a2a691
AC
488 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, nr_bytes, addr, transfer,
489 sim_core_unmapped_signal);
7a418800 490 }
f2de7dfd
AC
491 return NULL;
492}
493
494
495STATIC_INLINE_SIM_CORE\
496(void *)
f90b720b
AC
497sim_core_translate (sim_core_mapping *mapping,
498 address_word addr)
f2de7dfd 499{
a34abff8
AC
500 if (WITH_MODULO_MEMORY)
501 return (void *)((unsigned8 *) mapping->buffer
502 + ((addr - mapping->base) & mapping->mask));
503 else
504 return (void *)((unsigned8 *) mapping->buffer
505 + addr - mapping->base);
f2de7dfd
AC
506}
507
508
cd0d873d 509EXTERN_SIM_CORE\
f2de7dfd 510(unsigned)
f90b720b
AC
511sim_core_read_buffer (SIM_DESC sd,
512 sim_cpu *cpu,
513 sim_core_maps map,
514 void *buffer,
515 address_word addr,
516 unsigned len)
f2de7dfd 517{
f90b720b 518 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
f2de7dfd
AC
519 unsigned count = 0;
520 while (count < len) {
521 unsigned_word raddr = addr + count;
c967f187 522 sim_core_mapping *mapping =
f90b720b 523 sim_core_find_mapping(core, map,
50a2a691
AC
524 raddr, /*nr-bytes*/1,
525 read_transfer,
f90b720b 526 0 /*dont-abort*/, NULL, NULL_CIA);
f2de7dfd
AC
527 if (mapping == NULL)
528 break;
529#if (WITH_DEVICES)
530 if (mapping->device != NULL) {
531 int nr_bytes = len - count;
532 if (raddr + nr_bytes - 1> mapping->bound)
533 nr_bytes = mapping->bound - raddr + 1;
534 if (device_io_read_buffer(mapping->device,
535 (unsigned_1*)buffer + count,
536 mapping->space,
537 raddr,
538 nr_bytes) != nr_bytes)
539 break;
540 count += nr_bytes;
541 }
542 else
543#endif
544 {
545 ((unsigned_1*)buffer)[count] =
c967f187 546 *(unsigned_1*)sim_core_translate(mapping, raddr);
f2de7dfd
AC
547 count += 1;
548 }
549 }
550 return count;
551}
552
553
cd0d873d 554EXTERN_SIM_CORE\
f2de7dfd 555(unsigned)
f90b720b
AC
556sim_core_write_buffer (SIM_DESC sd,
557 sim_cpu *cpu,
558 sim_core_maps map,
559 const void *buffer,
560 address_word addr,
561 unsigned len)
f2de7dfd 562{
f90b720b 563 sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
f2de7dfd
AC
564 unsigned count = 0;
565 while (count < len) {
566 unsigned_word raddr = addr + count;
f90b720b
AC
567 sim_core_mapping *mapping =
568 sim_core_find_mapping(core, map,
569 raddr, /*nr-bytes*/1,
570 write_transfer,
571 0 /*dont-abort*/, NULL, NULL_CIA);
f2de7dfd
AC
572 if (mapping == NULL)
573 break;
574#if (WITH_DEVICES)
575 if (WITH_CALLBACK_MEMORY
576 && mapping->device != NULL) {
577 int nr_bytes = len - count;
578 if (raddr + nr_bytes - 1 > mapping->bound)
579 nr_bytes = mapping->bound - raddr + 1;
580 if (device_io_write_buffer(mapping->device,
581 (unsigned_1*)buffer + count,
582 mapping->space,
583 raddr,
584 nr_bytes) != nr_bytes)
585 break;
586 count += nr_bytes;
587 }
588 else
589#endif
590 {
c967f187 591 *(unsigned_1*)sim_core_translate(mapping, raddr) =
f2de7dfd
AC
592 ((unsigned_1*)buffer)[count];
593 count += 1;
594 }
595 }
596 return count;
597}
598
599
cd0d873d
AC
600EXTERN_SIM_CORE\
601(void)
f90b720b
AC
602sim_core_set_xor (SIM_DESC sd,
603 sim_cpu *cpu,
cd0d873d
AC
604 int is_xor)
605{
f90b720b 606 /* set up the XOR map if required. */
cd0d873d
AC
607 if (WITH_XOR_ENDIAN) {
608 {
f90b720b
AC
609 sim_core *core = STATE_CORE (sd);
610 sim_cpu_core *cpu_core = (cpu != NULL ? CPU_CORE (cpu) : NULL);
611 if (cpu_core != NULL)
cd0d873d 612 {
f90b720b
AC
613 int i = 1;
614 unsigned mask;
615 if (is_xor)
616 mask = WITH_XOR_ENDIAN - 1;
617 else
618 mask = 0;
619 while (i - 1 < WITH_XOR_ENDIAN)
620 {
621 cpu_core->xor[i-1] = mask;
622 mask = (mask << 1) & (WITH_XOR_ENDIAN - 1);
623 i = (i << 1);
624 }
cd0d873d 625 }
f90b720b
AC
626 else
627 {
628 if (is_xor)
629 core->byte_xor = WITH_XOR_ENDIAN - 1;
630 else
631 core->byte_xor = 0;
632 }
cd0d873d
AC
633 }
634 }
635 else {
636 if (is_xor)
f90b720b 637 sim_engine_abort (sd, cpu, NULL_CIA,
cd0d873d
AC
638 "Attempted to enable xor-endian mode when permenantly disabled.");
639 }
640}
641
f90b720b
AC
642STATIC_INLINE_SIM_CORE\
643(void)
644reverse_n (unsigned_1 *dest,
645 const unsigned_1 *src,
646 int nr_bytes)
647{
648 int i;
649 for (i = 0; i < nr_bytes; i++)
650 {
651 dest [nr_bytes - i - 1] = src [i];
652 }
653}
654
655
656EXTERN_SIM_CORE\
657(unsigned)
658sim_core_xor_read_buffer (SIM_DESC sd,
659 sim_cpu *cpu,
660 sim_core_maps map,
661 void *buffer,
662 address_word addr,
663 unsigned nr_bytes)
664{
665 address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]);
666 if (!WITH_XOR_ENDIAN || !byte_xor)
667 return sim_core_read_buffer (sd, cpu, map, buffer, addr, nr_bytes);
668 else
669 /* only break up transfers when xor-endian is both selected and enabled */
670 {
31dda65a 671 unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero-sized array */
f90b720b
AC
672 unsigned nr_transfered = 0;
673 address_word start = addr;
674 unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
675 address_word stop;
676 /* initial and intermediate transfers are broken when they cross
677 an XOR endian boundary */
678 while (nr_transfered + nr_this_transfer < nr_bytes)
679 /* initial/intermediate transfers */
680 {
681 /* since xor-endian is enabled stop^xor defines the start
682 address of the transfer */
683 stop = start + nr_this_transfer - 1;
684 SIM_ASSERT (start <= stop);
685 SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
686 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
687 != nr_this_transfer)
688 return nr_transfered;
689 reverse_n (&((unsigned_1*)buffer)[nr_transfered], x, nr_this_transfer);
690 nr_transfered += nr_this_transfer;
691 nr_this_transfer = WITH_XOR_ENDIAN;
692 start = stop + 1;
693 }
694 /* final transfer */
695 nr_this_transfer = nr_bytes - nr_transfered;
696 stop = start + nr_this_transfer - 1;
697 SIM_ASSERT (stop == (addr + nr_bytes - 1));
698 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
699 != nr_this_transfer)
700 return nr_transfered;
701 reverse_n (&((unsigned_1*)buffer)[nr_transfered], x, nr_this_transfer);
702 return nr_bytes;
703 }
704}
705
706
707EXTERN_SIM_CORE\
708(unsigned)
709sim_core_xor_write_buffer (SIM_DESC sd,
710 sim_cpu *cpu,
711 sim_core_maps map,
712 const void *buffer,
713 address_word addr,
714 unsigned nr_bytes)
715{
716 address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]);
717 if (!WITH_XOR_ENDIAN || !byte_xor)
718 return sim_core_write_buffer (sd, cpu, map, buffer, addr, nr_bytes);
719 else
720 /* only break up transfers when xor-endian is both selected and enabled */
721 {
fd89abc2 722 unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero sized array */
f90b720b
AC
723 unsigned nr_transfered = 0;
724 address_word start = addr;
725 unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
726 address_word stop;
727 /* initial and intermediate transfers are broken when they cross
728 an XOR endian boundary */
729 while (nr_transfered + nr_this_transfer < nr_bytes)
730 /* initial/intermediate transfers */
731 {
732 /* since xor-endian is enabled stop^xor defines the start
733 address of the transfer */
734 stop = start + nr_this_transfer - 1;
735 SIM_ASSERT (start <= stop);
736 SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
737 reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
738 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
739 != nr_this_transfer)
740 return nr_transfered;
741 nr_transfered += nr_this_transfer;
742 nr_this_transfer = WITH_XOR_ENDIAN;
743 start = stop + 1;
744 }
745 /* final transfer */
746 nr_this_transfer = nr_bytes - nr_transfered;
747 stop = start + nr_this_transfer - 1;
748 SIM_ASSERT (stop == (addr + nr_bytes - 1));
749 reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
750 if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
751 != nr_this_transfer)
752 return nr_transfered;
753 return nr_bytes;
754 }
755}
cd0d873d
AC
756
757
758
f45dd42b 759/* define the read/write 1/2/4/8/16/word functions */
f2de7dfd 760
63be8feb 761#define N 16
f2de7dfd 762#include "sim-n-core.h"
f2de7dfd 763
63be8feb
AC
764#define N 8
765#include "sim-n-core.h"
766
767#define N 7
768#define M 8
769#include "sim-n-core.h"
770
771#define N 6
772#define M 8
773#include "sim-n-core.h"
774
775#define N 5
776#define M 8
f2de7dfd 777#include "sim-n-core.h"
f2de7dfd
AC
778
779#define N 4
780#include "sim-n-core.h"
f2de7dfd 781
63be8feb
AC
782#define N 3
783#define M 4
f2de7dfd 784#include "sim-n-core.h"
f2de7dfd 785
63be8feb
AC
786#define N 2
787#include "sim-n-core.h"
788
789#define N 1
f45dd42b 790#include "sim-n-core.h"
f45dd42b 791
f2de7dfd 792#endif
This page took 0.077149 seconds and 4 git commands to generate.