/* The common simulator framework for GDB, the GNU Debugger.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002-2020 Free Software Foundation, Inc.
Contributed by Andrew Cagney and Red Hat.
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef SIM_CORE_C
#include "sim-hw.h"
#endif
+#include <stdlib.h>
+
/* "core" module install handler.
This is called via sim_module_install to install the "core"
static void
sim_core_uninstall (SIM_DESC sd)
{
- sim_core *core = STATE_CORE(sd);
+ sim_core *core = STATE_CORE (sd);
unsigned map;
/* blow away any mappings */
for (map = 0; map < nr_maps; map++) {
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;
}
address_word addr,
address_word nr_bytes,
unsigned modulo,
-#if WITH_HW
struct hw *device,
-#else
- device *device,
-#endif
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;
address_word addr,
address_word nr_bytes,
unsigned modulo,
-#if WITH_HW
struct hw *client, /*callback/default*/
-#else
- device *client, /*callback/default*/
-#endif
void *buffer, /*raw_memory*/
void *free_buffer) /*raw_memory*/
{
/* 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");
-#endif
#if (WITH_HW)
sim_hw_abort (sd, client, "called on sim_core_map_attach with size zero");
#endif
/* 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)))
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)",
- space,
- (long) addr,
- (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
#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,
}
/* 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
address_word addr,
address_word nr_bytes,
unsigned modulo,
-#if WITH_HW
struct hw *client,
-#else
- device *client,
-#endif
void *optional_buffer)
{
- sim_core *memory = STATE_CORE(sd);
+ sim_core *memory = STATE_CORE (sd);
unsigned map;
void *buffer;
void *free_buffer;
if (cpu != NULL)
sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported");
- /* verify modulo memory */
- if (!WITH_MODULO_MEMORY && modulo != 0)
- {
-#if (WITH_DEVICES)
- device_error (client, "sim_core_attach - internal error - modulo memory disabled");
-#endif
-#if (WITH_HW)
- sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo memory disabled");
-#endif
- sim_io_error (sd, "sim_core_attach - internal error - modulo memory disabled");
- }
if (client != NULL && modulo != 0)
{
-#if (WITH_DEVICES)
- device_error (client, "sim_core_attach - internal error - modulo and callback memory conflict");
-#endif
#if (WITH_HW)
sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo and callback memory conflict");
#endif
}
if (mask != sizeof (unsigned64) - 1)
{
-#if (WITH_DEVICES)
- device_error (client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
-#endif
#if (WITH_HW)
sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
#endif
/* 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");
-#endif
#if (WITH_HW)
sim_hw_abort (sd, client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
#endif
}
/* attach the region to all applicable access maps */
- for (map = 0;
+ for (map = 0;
map < nr_maps;
map++)
{
free_buffer = NULL;
}
}
-
+
/* Just copy this map to each of the processor specific data structures.
FIXME - later this will be replaced by true processor specific
maps. */
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;
}
}
STATIC_INLINE_SIM_CORE\
(sim_core_mapping *)
-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_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 */
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));
}
unsigned count = 0;
while (count < len)
{
- unsigned_word raddr = addr + count;
+ address_word raddr = addr + count;
sim_core_mapping *mapping =
sim_core_find_mapping (core, map,
raddr, /*nr-bytes*/1,
0 /*dont-abort*/, NULL, NULL_CIA);
if (mapping == NULL)
break;
-#if (WITH_DEVICES)
- if (mapping->device != NULL)
- {
- int nr_bytes = len - count;
- sim_cia cia = cpu ? CIA_GET (cpu) : NULL_CIA;
- 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,
- sd,
- cpu,
- cia) != nr_bytes)
- break;
- count += nr_bytes;
- continue;
- }
-#endif
#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 (sim_hw_io_read_buffer (sd, mapping->device,
- (unsigned_1*)buffer + count,
- mapping->space,
- raddr,
- nr_bytes) != nr_bytes)
+ /* 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);
+ *(unsigned_1*)sim_core_translate (mapping, raddr);
count += 1;
}
return count;
unsigned count = 0;
while (count < len)
{
- unsigned_word raddr = addr + count;
+ address_word raddr = addr + count;
sim_core_mapping *mapping =
sim_core_find_mapping (core, map,
raddr, /*nr-bytes*/1,
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;
- sim_cia cia = cpu ? CIA_GET (cpu) : NULL_CIA;
- 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,
- sd,
- cpu,
- cia) != nr_bytes)
- break;
- count += nr_bytes;
- continue;
- }
-#endif
#if (WITH_HW)
- if (WITH_CALLBACK_MEMORY
- && mapping->device != NULL)
+ if (mapping->device != NULL)
{
int nr_bytes = len - count;
if (raddr + nr_bytes - 1 > mapping->bound)
nr_bytes = mapping->bound - raddr + 1;
- if (sim_hw_io_write_buffer (sd, mapping->device,
- (unsigned_1*)buffer + count,
- mapping->space,
- raddr,
- nr_bytes) != nr_bytes)
+ /* 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*)sim_core_translate (mapping, raddr) =
((unsigned_1*)buffer)[count];
count += 1;
}
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);
}
core->byte_xor = WITH_XOR_ENDIAN - 1;
else
core->byte_xor = 0;
- }
+ }
}
}
else {
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
}
}
#endif
-
-
+
+
#if EXTERN_SIM_CORE_P
unsigned
sim_core_xor_write_buffer (SIM_DESC sd,
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
}
#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
+
/* define the read/write 1/2/4/8/16/word functions */