X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fcommon%2Fsim-core.c;h=df46def27573e34f91224d03b4d961eb7ff3a798;hb=41792d688a5a1f158d6e9ecda2b603ae122d69a1;hp=6ce693c77167f0b661bb6bb3b9b06a0d4053bf1a;hpb=a4b44a2b08b22e323d3366de61c19218197422d4;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/common/sim-core.c b/sim/common/sim-core.c index 6ce693c771..df46def275 100644 --- a/sim/common/sim-core.c +++ b/sim/common/sim-core.c @@ -1,40 +1,49 @@ -/* This file is part of the program psim. +/* The common simulator framework for GDB, the GNU Debugger. - Copyright (C) 1994-1997, Andrew Cagney + Copyright 2002-2020 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + Contributed by Andrew Cagney and Red Hat. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ + This file is part of GDB. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -#ifndef _SIM_CORE_C_ -#define _SIM_CORE_C_ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + +#ifndef SIM_CORE_C +#define SIM_CORE_C #include "sim-main.h" #include "sim-assert.h" +#if (WITH_HW) +#include "sim-hw.h" +#endif + +#include + /* "core" module install handler. - This is called via sim_module_install to install the "core" subsystem - into the simulator. */ + This is called via sim_module_install to install the "core" + subsystem into the simulator. */ +#if EXTERN_SIM_CORE_P static MODULE_INIT_FN sim_core_init; static MODULE_UNINSTALL_FN sim_core_uninstall; +#endif -EXTERN_SIM_CORE\ -(SIM_RC) +#if EXTERN_SIM_CORE_P +SIM_RC sim_core_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); @@ -46,53 +55,57 @@ sim_core_install (SIM_DESC sd) /* establish any initial data structures - none */ return SIM_RC_OK; } +#endif /* Uninstall the "core" subsystem from the simulator. */ -STATIC_SIM_CORE\ -(void) +#if EXTERN_SIM_CORE_P +static void sim_core_uninstall (SIM_DESC sd) { - sim_core *core = STATE_CORE(sd); - sim_core_maps map; + sim_core *core = STATE_CORE (sd); + unsigned map; /* blow away any mappings */ - for (map = 0; map < nr_sim_core_maps; map++) { + for (map = 0; map < nr_maps; map++) { sim_core_mapping *curr = core->common.map[map].first; while (curr != NULL) { sim_core_mapping *tbd = curr; curr = curr->next; if (tbd->free_buffer != NULL) { - SIM_ASSERT(tbd->buffer != NULL); - zfree(tbd->free_buffer); + SIM_ASSERT (tbd->buffer != NULL); + free (tbd->free_buffer); } - zfree(tbd); + free (tbd); } core->common.map[map].first = NULL; } } +#endif -STATIC_SIM_CORE\ -(SIM_RC) +#if EXTERN_SIM_CORE_P +static SIM_RC sim_core_init (SIM_DESC sd) { /* Nothing to do */ return SIM_RC_OK; } +#endif #ifndef SIM_CORE_SIGNAL #define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \ sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR)) +#endif -STATIC_SIM_CORE\ -(void) +#if EXTERN_SIM_CORE_P +void sim_core_signal (SIM_DESC sd, sim_cpu *cpu, sim_cia cia, - sim_core_maps map, + unsigned map, int nr_bytes, address_word addr, transfer_type transfer, @@ -103,7 +116,7 @@ sim_core_signal (SIM_DESC sd, switch (sig) { case sim_core_unmapped_signal: - sim_io_eprintf (sd, "core: %d byte %s to unmaped address 0x%lx at 0x%lx\n", + sim_io_eprintf (sd, "core: %d byte %s to unmapped address 0x%lx at 0x%lx\n", nr_bytes, copy, (unsigned long) addr, (unsigned long) ip); sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGSEGV); break; @@ -120,52 +133,36 @@ sim_core_signal (SIM_DESC sd, #endif -STATIC_INLINE_SIM_CORE\ -(const char *) -sim_core_map_to_str (sim_core_maps map) -{ - switch (map) - { - case sim_core_read_map: return "read"; - case sim_core_write_map: return "write"; - case sim_core_execute_map: return "exec"; - default: return "(invalid-map)"; - } -} - - -STATIC_SIM_CORE\ -(sim_core_mapping *) +#if EXTERN_SIM_CORE_P +static sim_core_mapping * new_sim_core_mapping (SIM_DESC sd, int level, int space, address_word addr, address_word nr_bytes, unsigned modulo, - device *device, + struct hw *device, void *buffer, void *free_buffer) { - sim_core_mapping *new_mapping = ZALLOC(sim_core_mapping); + sim_core_mapping *new_mapping = ZALLOC (sim_core_mapping); /* common */ new_mapping->level = level; new_mapping->space = space; new_mapping->base = addr; new_mapping->nr_bytes = nr_bytes; new_mapping->bound = addr + (nr_bytes - 1); - if (modulo == 0) - new_mapping->mask = (unsigned) 0 - 1; - else - new_mapping->mask = modulo - 1; + new_mapping->mask = modulo - 1; new_mapping->buffer = buffer; new_mapping->free_buffer = free_buffer; new_mapping->device = device; return new_mapping; } +#endif -STATIC_SIM_CORE\ -(void) +#if EXTERN_SIM_CORE_P +static void sim_core_map_attach (SIM_DESC sd, sim_core_map *access_map, int level, @@ -173,7 +170,7 @@ sim_core_map_attach (SIM_DESC sd, address_word addr, address_word nr_bytes, unsigned modulo, - device *client, /*callback/default*/ + struct hw *client, /*callback/default*/ void *buffer, /*raw_memory*/ void *free_buffer) /*raw_memory*/ { @@ -188,17 +185,16 @@ sim_core_map_attach (SIM_DESC sd, /* actually do occasionally get a zero size map */ if (nr_bytes == 0) { -#if (WITH_DEVICES) - device_error(client, "called on sim_core_map_attach with size zero"); -#else - sim_io_error (sd, "called on sim_core_map_attach with size zero"); +#if (WITH_HW) + sim_hw_abort (sd, client, "called on sim_core_map_attach with size zero"); #endif + sim_io_error (sd, "called on sim_core_map_attach with size zero"); } /* find the insertion point (between last/next) */ next_mapping = access_map->first; last_mapping = &access_map->first; - while(next_mapping != NULL + while (next_mapping != NULL && (next_mapping->level < level || (next_mapping->level == level && next_mapping->bound < addr))) @@ -209,59 +205,62 @@ sim_core_map_attach (SIM_DESC sd, last_mapping = &next_mapping->next; next_mapping = next_mapping->next; } - + /* check insertion point correct */ SIM_ASSERT (next_mapping == NULL || next_mapping->level >= level); if (next_mapping != NULL && next_mapping->level == level && next_mapping->base < (addr + (nr_bytes - 1))) { -#if (WITH_DEVICES) - device_error (client, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)", +#if WITH_HW + sim_hw_abort (sd, client, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)", space, (long) addr, - (long) nr_bytes, (long) (addr + (nr_bytes - 1)), + (long) nr_bytes, next_mapping->space, (long) next_mapping->base, (long) next_mapping->bound, (long) next_mapping->nr_bytes); -#else +#endif sim_io_error (sd, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)", space, (long) addr, - (long) nr_bytes, (long) (addr + (nr_bytes - 1)), + (long) nr_bytes, next_mapping->space, (long) next_mapping->base, (long) next_mapping->bound, (long) next_mapping->nr_bytes); -#endif } /* create/insert the new mapping */ - *last_mapping = new_sim_core_mapping(sd, - level, - space, addr, nr_bytes, modulo, - client, buffer, free_buffer); + *last_mapping = new_sim_core_mapping (sd, + level, + space, addr, nr_bytes, modulo, + client, buffer, free_buffer); (*last_mapping)->next = next_mapping; } +#endif -EXTERN_SIM_CORE\ -(void) +/* Attach memory or a memory mapped device to the simulator. + See sim-core.h for a full description. */ + +#if EXTERN_SIM_CORE_P +void sim_core_attach (SIM_DESC sd, sim_cpu *cpu, int level, - access_type access, + unsigned mapmask, int space, address_word addr, address_word nr_bytes, unsigned modulo, - device *client, + struct hw *client, void *optional_buffer) { - sim_core *memory = STATE_CORE(sd); - sim_core_maps map; + sim_core *memory = STATE_CORE (sd); + unsigned map; void *buffer; void *free_buffer; @@ -269,32 +268,12 @@ sim_core_attach (SIM_DESC sd, if (cpu != NULL) sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported"); - if ((access & access_read_write_exec) == 0 - || (access & ~access_read_write_exec) != 0) - { -#if (WITH_DEVICES) - device_error(client, "invalid access for core attach"); -#else - sim_io_error (sd, "invalid access for core attach"); -#endif - } - - /* verify modulo memory */ - if (!WITH_MODULO_MEMORY && modulo != 0) - { -#if (WITH_DEVICES) - device_error (client, "sim_core_attach - internal error - modulo memory disabled"); -#else - sim_io_error (sd, "sim_core_attach - internal error - modulo memory disabled"); -#endif - } if (client != NULL && modulo != 0) { -#if (WITH_DEVICES) - device_error (client, "sim_core_attach - internal error - modulo and callback memory conflict"); -#else - sim_io_error (sd, "sim_core_attach - internal error - modulo and callback memory conflict"); +#if (WITH_HW) + sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo and callback memory conflict"); #endif + sim_io_error (sd, "sim_core_attach - internal error - modulo and callback memory conflict"); } if (modulo != 0) { @@ -309,29 +288,28 @@ sim_core_attach (SIM_DESC sd, } if (mask != sizeof (unsigned64) - 1) { -#if (WITH_DEVICES) - device_error (client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo); -#else - sim_io_error (sd, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo); +#if (WITH_HW) + sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo); #endif + sim_io_error (sd, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo); } } /* verify consistency between device and buffer */ if (client != NULL && optional_buffer != NULL) { -#if (WITH_DEVICES) - device_error (client, "sim_core_attach - internal error - conflicting buffer and attach arguments"); -#else - sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments"); +#if (WITH_HW) + sim_hw_abort (sd, client, "sim_core_attach - internal error - conflicting buffer and attach arguments"); #endif + sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments"); } if (client == NULL) { if (optional_buffer == NULL) { int padding = (addr % sizeof (unsigned64)); - free_buffer = zalloc ((modulo == 0 ? nr_bytes : modulo) + padding); + unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding; + free_buffer = zalloc (bytes); buffer = (char*) free_buffer + padding; } else @@ -348,39 +326,19 @@ sim_core_attach (SIM_DESC sd, } /* attach the region to all applicable access maps */ - for (map = 0; - map < nr_sim_core_maps; + for (map = 0; + map < nr_maps; map++) { - switch (map) + if (mapmask & (1 << map)) { - case sim_core_read_map: - if (access & access_read) - sim_core_map_attach (sd, &memory->common.map[map], - level, space, addr, nr_bytes, modulo, - client, buffer, free_buffer); + sim_core_map_attach (sd, &memory->common.map[map], + level, space, addr, nr_bytes, modulo, + client, buffer, free_buffer); free_buffer = NULL; - break; - case sim_core_write_map: - if (access & access_write) - sim_core_map_attach (sd, &memory->common.map[map], - level, space, addr, nr_bytes, modulo, - client, buffer, free_buffer); - free_buffer = NULL; - break; - case sim_core_execute_map: - if (access & access_exec) - sim_core_map_attach (sd, &memory->common.map[map], - level, space, addr, nr_bytes, modulo, - client, buffer, free_buffer); - free_buffer = NULL; - break; - case nr_sim_core_maps: - sim_io_error (sd, "sim_core_attach - internal error - bad switch"); - break; } } - + /* Just copy this map to each of the processor specific data structures. FIXME - later this will be replaced by true processor specific maps. */ @@ -392,11 +350,12 @@ sim_core_attach (SIM_DESC sd, } } } +#endif /* Remove any memory reference related to this address */ -STATIC_INLINE_SIM_CORE\ -(void) +#if EXTERN_SIM_CORE_P +static void sim_core_map_detach (SIM_DESC sd, sim_core_map *access_map, int level, @@ -415,15 +374,16 @@ sim_core_map_detach (SIM_DESC sd, sim_core_mapping *dead = (*entry); (*entry) = dead->next; if (dead->free_buffer != NULL) - zfree (dead->free_buffer); - zfree (dead); + free (dead->free_buffer); + free (dead); return; } } } +#endif -EXTERN_SIM_CORE\ -(void) +#if EXTERN_SIM_CORE_P +void sim_core_detach (SIM_DESC sd, sim_cpu *cpu, int level, @@ -431,8 +391,8 @@ sim_core_detach (SIM_DESC sd, address_word addr) { sim_core *memory = STATE_CORE (sd); - sim_core_maps map; - for (map = 0; map < nr_sim_core_maps; map++) + unsigned map; + for (map = 0; map < nr_maps; map++) { sim_core_map_detach (sd, &memory->common.map[map], level, address_space, addr); @@ -448,18 +408,19 @@ sim_core_detach (SIM_DESC sd, } } } +#endif STATIC_INLINE_SIM_CORE\ (sim_core_mapping *) -sim_core_find_mapping(sim_core_common *core, - sim_core_maps map, - address_word addr, - unsigned nr_bytes, - transfer_type transfer, - int abort, /*either 0 or 1 - hint to inline/-O */ - sim_cpu *cpu, /* abort => cpu != NULL */ - sim_cia cia) +sim_core_find_mapping (sim_core_common *core, + unsigned map, + address_word addr, + unsigned nr_bytes, + transfer_type transfer, + int abort, /*either 0 or 1 - hint to inline/-O */ + sim_cpu *cpu, /* abort => cpu != NULL */ + sim_cia cia) { sim_core_mapping *mapping = core->map[map].first; ASSERT ((addr & (nr_bytes - 1)) == 0); /* must be aligned */ @@ -486,108 +447,129 @@ STATIC_INLINE_SIM_CORE\ sim_core_translate (sim_core_mapping *mapping, address_word addr) { - if (WITH_MODULO_MEMORY) - return (void *)((unsigned8 *) mapping->buffer - + ((addr - mapping->base) & mapping->mask)); - else - return (void *)((unsigned8 *) mapping->buffer - + addr - mapping->base); + return (void *)((unsigned8 *) mapping->buffer + + ((addr - mapping->base) & mapping->mask)); } -EXTERN_SIM_CORE\ -(unsigned) +#if EXTERN_SIM_CORE_P +unsigned sim_core_read_buffer (SIM_DESC sd, sim_cpu *cpu, - sim_core_maps map, + unsigned map, void *buffer, address_word addr, unsigned len) { sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common); unsigned count = 0; - while (count < len) { - unsigned_word raddr = addr + count; + while (count < len) + { + address_word raddr = addr + count; sim_core_mapping *mapping = - sim_core_find_mapping(core, map, + sim_core_find_mapping (core, map, raddr, /*nr-bytes*/1, read_transfer, 0 /*dont-abort*/, NULL, NULL_CIA); if (mapping == NULL) break; -#if (WITH_DEVICES) - if (mapping->device != NULL) { - int nr_bytes = len - count; - if (raddr + nr_bytes - 1> mapping->bound) - nr_bytes = mapping->bound - raddr + 1; - if (device_io_read_buffer(mapping->device, - (unsigned_1*)buffer + count, - mapping->space, - raddr, - nr_bytes) != nr_bytes) - break; - count += nr_bytes; - } - else -#endif +#if (WITH_HW) + if (mapping->device != NULL) { - ((unsigned_1*)buffer)[count] = - *(unsigned_1*)sim_core_translate(mapping, raddr); - count += 1; + int nr_bytes = len - count; + if (raddr + nr_bytes - 1> mapping->bound) + nr_bytes = mapping->bound - raddr + 1; + /* If the access was initiated by a cpu, pass it down so errors can + be propagated properly. For other sources (e.g. GDB or DMA), we + can only signal errors via the return value. */ + if (cpu) + { + sim_cia cia = cpu ? CPU_PC_GET (cpu) : NULL_CIA; + sim_cpu_hw_io_read_buffer (cpu, cia, mapping->device, + (unsigned_1*)buffer + count, + mapping->space, + raddr, + nr_bytes); + } + else if (sim_hw_io_read_buffer (sd, mapping->device, + (unsigned_1*)buffer + count, + mapping->space, + raddr, + nr_bytes) != nr_bytes) + break; + count += nr_bytes; + continue; } - } +#endif + ((unsigned_1*)buffer)[count] = + *(unsigned_1*)sim_core_translate (mapping, raddr); + count += 1; + } return count; } +#endif -EXTERN_SIM_CORE\ -(unsigned) +#if EXTERN_SIM_CORE_P +unsigned sim_core_write_buffer (SIM_DESC sd, sim_cpu *cpu, - sim_core_maps map, + unsigned map, const void *buffer, address_word addr, unsigned len) { sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common); unsigned count = 0; - while (count < len) { - unsigned_word raddr = addr + count; - sim_core_mapping *mapping = - sim_core_find_mapping(core, map, - raddr, /*nr-bytes*/1, - write_transfer, - 0 /*dont-abort*/, NULL, NULL_CIA); - if (mapping == NULL) - break; -#if (WITH_DEVICES) - if (WITH_CALLBACK_MEMORY - && mapping->device != NULL) { - int nr_bytes = len - count; - if (raddr + nr_bytes - 1 > mapping->bound) - nr_bytes = mapping->bound - raddr + 1; - if (device_io_write_buffer(mapping->device, - (unsigned_1*)buffer + count, - mapping->space, - raddr, - nr_bytes) != nr_bytes) + while (count < len) + { + address_word raddr = addr + count; + sim_core_mapping *mapping = + sim_core_find_mapping (core, map, + raddr, /*nr-bytes*/1, + write_transfer, + 0 /*dont-abort*/, NULL, NULL_CIA); + if (mapping == NULL) break; - count += nr_bytes; - } - else +#if (WITH_HW) + if (mapping->device != NULL) + { + int nr_bytes = len - count; + if (raddr + nr_bytes - 1 > mapping->bound) + nr_bytes = mapping->bound - raddr + 1; + /* If the access was initiated by a cpu, pass it down so errors can + be propagated properly. For other sources (e.g. GDB or DMA), we + can only signal errors via the return value. */ + if (cpu) + { + sim_cia cia = cpu ? CPU_PC_GET (cpu) : NULL_CIA; + sim_cpu_hw_io_write_buffer (cpu, cia, mapping->device, + (unsigned_1*)buffer + count, + mapping->space, + raddr, + nr_bytes); + } + else if (sim_hw_io_write_buffer (sd, mapping->device, + (unsigned_1*)buffer + count, + mapping->space, + raddr, + nr_bytes) != nr_bytes) + break; + count += nr_bytes; + continue; + } #endif - { - *(unsigned_1*)sim_core_translate(mapping, raddr) = - ((unsigned_1*)buffer)[count]; - count += 1; - } - } + *(unsigned_1*)sim_core_translate (mapping, raddr) = + ((unsigned_1*)buffer)[count]; + count += 1; + } return count; } +#endif -EXTERN_SIM_CORE\ -(void) +#if EXTERN_SIM_CORE_P +void sim_core_set_xor (SIM_DESC sd, sim_cpu *cpu, int is_xor) @@ -607,7 +589,7 @@ sim_core_set_xor (SIM_DESC sd, mask = 0; while (i - 1 < WITH_XOR_ENDIAN) { - cpu_core->xor[i-1] = mask; + cpu_core->byte_xor[i-1] = mask; mask = (mask << 1) & (WITH_XOR_ENDIAN - 1); i = (i << 1); } @@ -618,18 +600,20 @@ sim_core_set_xor (SIM_DESC sd, core->byte_xor = WITH_XOR_ENDIAN - 1; else core->byte_xor = 0; - } + } } } else { if (is_xor) - sim_engine_abort (sd, cpu, NULL_CIA, + sim_engine_abort (sd, NULL, NULL_CIA, "Attempted to enable xor-endian mode when permenantly disabled."); } } +#endif -STATIC_INLINE_SIM_CORE\ -(void) + +#if EXTERN_SIM_CORE_P +static void reverse_n (unsigned_1 *dest, const unsigned_1 *src, int nr_bytes) @@ -640,18 +624,20 @@ reverse_n (unsigned_1 *dest, dest [nr_bytes - i - 1] = src [i]; } } +#endif -EXTERN_SIM_CORE\ -(unsigned) +#if EXTERN_SIM_CORE_P +unsigned sim_core_xor_read_buffer (SIM_DESC sd, sim_cpu *cpu, - sim_core_maps map, + unsigned map, void *buffer, address_word addr, unsigned nr_bytes) { - address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]); + address_word byte_xor + = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->byte_xor[0]); if (!WITH_XOR_ENDIAN || !byte_xor) return sim_core_read_buffer (sd, cpu, map, buffer, addr, nr_bytes); else @@ -691,18 +677,20 @@ sim_core_xor_read_buffer (SIM_DESC sd, return nr_bytes; } } - - -EXTERN_SIM_CORE\ -(unsigned) +#endif + + +#if EXTERN_SIM_CORE_P +unsigned sim_core_xor_write_buffer (SIM_DESC sd, sim_cpu *cpu, - sim_core_maps map, + unsigned map, const void *buffer, address_word addr, unsigned nr_bytes) { - address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]); + address_word byte_xor + = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->byte_xor[0]); if (!WITH_XOR_ENDIAN || !byte_xor) return sim_core_write_buffer (sd, cpu, map, buffer, addr, nr_bytes); else @@ -742,6 +730,26 @@ sim_core_xor_write_buffer (SIM_DESC sd, return nr_bytes; } } +#endif + +#if EXTERN_SIM_CORE_P +void * +sim_core_trans_addr (SIM_DESC sd, + sim_cpu *cpu, + unsigned map, + address_word addr) +{ + sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common); + sim_core_mapping *mapping = + sim_core_find_mapping (core, map, + addr, /*nr-bytes*/1, + write_transfer, + 0 /*dont-abort*/, NULL, NULL_CIA); + if (mapping == NULL) + return NULL; + return sim_core_translate (mapping, addr); +} +#endif