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