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