mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
* interp.c (UMEM_SEGMENTS): New define, set to 128.
(sim_size): Use UMEM_SEGMENTS rather than hardwired constant. (sim_close): Reset prog_bfd to NULL after closing it. Also reset prog_bfd_was_opened_p after closing prog_bfd. (sim_load): Reset prog_bfd_was_opened_p after closing prog_bfd. (sim_create_inferior): Get start address from abfd not prog_bfd. (xfer_mem): Do bounds checking on addresses and return zero length read/write on bad addresses, rather than aborting. Prepare to be able to handle xfers that cross segment boundaries, but not yet implemented. Only emit debug message when d10v_debug is set as well as DEBUG being defined.
This commit is contained in:
@ -1,3 +1,17 @@
|
|||||||
|
Thu Jan 22 14:30:36 1998 Fred Fish <fnf@cygnus.com>
|
||||||
|
|
||||||
|
* interp.c (UMEM_SEGMENTS): New define, set to 128.
|
||||||
|
(sim_size): Use UMEM_SEGMENTS rather than hardwired constant.
|
||||||
|
(sim_close): Reset prog_bfd to NULL after closing it. Also
|
||||||
|
reset prog_bfd_was_opened_p after closing prog_bfd.
|
||||||
|
(sim_load): Reset prog_bfd_was_opened_p after closing prog_bfd.
|
||||||
|
(sim_create_inferior): Get start address from abfd not prog_bfd.
|
||||||
|
(xfer_mem): Do bounds checking on addresses and return zero length
|
||||||
|
read/write on bad addresses, rather than aborting. Prepare to
|
||||||
|
be able to handle xfers that cross segment boundaries, but not
|
||||||
|
yet implemented. Only emit debug message when d10v_debug is
|
||||||
|
set as well as DEBUG being defined.
|
||||||
|
|
||||||
Mon Jan 19 22:26:29 1998 Doug Evans <devans@seba>
|
Mon Jan 19 22:26:29 1998 Doug Evans <devans@seba>
|
||||||
|
|
||||||
* configure: Regenerated to track ../common/aclocal.m4 changes.
|
* configure: Regenerated to track ../common/aclocal.m4 changes.
|
||||||
|
@ -6,9 +6,10 @@
|
|||||||
|
|
||||||
#include "d10v_sim.h"
|
#include "d10v_sim.h"
|
||||||
|
|
||||||
#define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
|
#define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
|
||||||
#define DMEM_SIZE 16 /* Data memory is 64K (but only 32K internal RAM) */
|
#define DMEM_SIZE 16 /* Data memory is 64K (but only 32K internal RAM) */
|
||||||
#define UMEM_SIZE 17 /* each unified memory region is 17 bits */
|
#define UMEM_SIZE 17 /* Each unified memory segment is 17 bits */
|
||||||
|
#define UMEM_SEGMENTS 128 /* Number of segments in unified memory region */
|
||||||
|
|
||||||
enum _leftright { LEFT_FIRST, RIGHT_FIRST };
|
enum _leftright { LEFT_FIRST, RIGHT_FIRST };
|
||||||
|
|
||||||
@ -288,7 +289,7 @@ sim_size (power)
|
|||||||
|
|
||||||
if (State.imem)
|
if (State.imem)
|
||||||
{
|
{
|
||||||
for (i=0;i<128;i++)
|
for (i=0;i<UMEM_SEGMENTS;i++)
|
||||||
{
|
{
|
||||||
if (State.umem[i])
|
if (State.umem[i])
|
||||||
{
|
{
|
||||||
@ -302,13 +303,13 @@ sim_size (power)
|
|||||||
|
|
||||||
State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
|
State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
|
||||||
State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
|
State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
|
||||||
for (i=1;i<127;i++)
|
for (i=1;i<(UMEM_SEGMENTS-1);i++)
|
||||||
State.umem[i] = NULL;
|
State.umem[i] = NULL;
|
||||||
State.umem[0] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
State.umem[0] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
||||||
State.umem[1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
State.umem[1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
||||||
State.umem[2] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
State.umem[2] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
||||||
State.umem[127] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
State.umem[UMEM_SEGMENTS-1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
||||||
if (!State.imem || !State.dmem || !State.umem[0] || !State.umem[1] || !State.umem[2] || !State.umem[127] )
|
if (!State.imem || !State.dmem || !State.umem[0] || !State.umem[1] || !State.umem[2] || !State.umem[UMEM_SEGMENTS-1] )
|
||||||
{
|
{
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
|
(*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -339,6 +340,13 @@ init_system ()
|
|||||||
sim_size(1);
|
sim_size(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Transfer data to/from simulated memory. Since a bug in either the
|
||||||
|
simulated program or in gdb or the simulator itself may cause a
|
||||||
|
bogus address to be passed in, we need to do some sanity checking
|
||||||
|
on addresses to make sure they are within bounds. When an address
|
||||||
|
fails the bounds check, treat it as a zero length read/write rather
|
||||||
|
than aborting the entire run. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xfer_mem (addr, buffer, size, write)
|
xfer_mem (addr, buffer, size, write)
|
||||||
SIM_ADDR addr;
|
SIM_ADDR addr;
|
||||||
@ -353,80 +361,110 @@ xfer_mem (addr, buffer, size, write)
|
|||||||
if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
|
if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
|
||||||
{
|
{
|
||||||
if (write)
|
if (write)
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x\n", size, addr);
|
{
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x\n", size, addr);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%x\n", size, addr);
|
{
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%x\n", size, addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* to access data, we use the following mapping */
|
/* to access data, we use the following mapping
|
||||||
/* 0x01000000 - 0x0103ffff : instruction memory */
|
0x00000000 - 0x00ffffff : 16 Mb of external unified memory in segments of 128 Kb each
|
||||||
/* 0x02000000 - 0x0200ffff : data memory */
|
0x01000000 - 0x0103ffff : 256 Kb of external instruction memory
|
||||||
/* 0x00000000 - 0x00ffffff : unified memory */
|
0x02000000 - 0x0200ffff : 32 Kb of on chip data memory + 16 Kb DMAP memory + 16 Kb I/O space */
|
||||||
|
|
||||||
if ( (addr & 0x03000000) == 0)
|
if ((addr | 0x00ffffff) == 0x00ffffff)
|
||||||
{
|
{
|
||||||
/* UNIFIED MEMORY */
|
/* UNIFIED MEMORY (0x00000000 - 0x00ffffff) */
|
||||||
int segment;
|
int startsegment, startoffset; /* Segment and offset within segment where xfer starts */
|
||||||
segment = addr >> UMEM_SIZE;
|
int endsegment, endoffset; /* Segment and offset within segment where xfer ends */
|
||||||
addr &= 0x1ffff;
|
|
||||||
if (!State.umem[segment])
|
startsegment = addr >> UMEM_SIZE;
|
||||||
|
startoffset = addr & ((1 << UMEM_SIZE) - 1);
|
||||||
|
endsegment = (addr + size) >> UMEM_SIZE;
|
||||||
|
endoffset = (addr + size) & ((1 << UMEM_SIZE) - 1);
|
||||||
|
|
||||||
|
/* FIXME: We do not currently implement xfers across segments, so detect this case and fail gracefully. */
|
||||||
|
|
||||||
|
if ((startsegment != endsegment) && !((endsegment == (startsegment + 1)) && endoffset == 0))
|
||||||
|
{
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: Unimplemented support for transfers across unified memory segment boundaries\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (!State.umem[startsegment])
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n",
|
if ((d10v_debug & DEBUG_MEMSIZE) != 0)
|
||||||
add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)), segment);
|
{
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n",
|
||||||
|
add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)), startsegment);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
State.umem[segment] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
State.umem[startsegment] = (uint8 *)calloc(1,1<<UMEM_SIZE);
|
||||||
}
|
}
|
||||||
if (!State.umem[segment])
|
if (!State.umem[startsegment])
|
||||||
{
|
{
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
|
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: Memory allocation of 0x%x bytes failed.\n", 1<<UMEM_SIZE);
|
||||||
exit(1);
|
return (0);
|
||||||
}
|
|
||||||
/* FIXME: need to check size and read/write multiple segments if necessary */
|
|
||||||
if (write)
|
|
||||||
memcpy (State.umem[segment]+addr, buffer, size) ;
|
|
||||||
else
|
|
||||||
memcpy (buffer, State.umem[segment]+addr, size);
|
|
||||||
}
|
|
||||||
else if ( (addr & 0x03000000) == 0x02000000)
|
|
||||||
{
|
|
||||||
/* DATA MEMORY */
|
|
||||||
addr &= ~0x02000000;
|
|
||||||
if (size > (1<<(DMEM_SIZE-1)))
|
|
||||||
{
|
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data section is only %d bytes.\n",1<<(DMEM_SIZE-1));
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
if (write)
|
if (write)
|
||||||
memcpy (State.dmem+addr, buffer, size);
|
|
||||||
else
|
|
||||||
memcpy (buffer, State.dmem+addr, size);
|
|
||||||
}
|
|
||||||
else if ( (addr & 0x03000000) == 0x01000000)
|
|
||||||
{
|
|
||||||
/* INSTRUCTION MEMORY */
|
|
||||||
addr &= ~0x01000000;
|
|
||||||
if (size > (1<<IMEM_SIZE))
|
|
||||||
{
|
{
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: inst section is only %d bytes.\n",1<<IMEM_SIZE);
|
memcpy (State.umem[startsegment]+startoffset, buffer, size);
|
||||||
exit(1);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy (buffer, State.umem[startsegment]+startoffset, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((addr | 0x0003ffff) == 0x0103ffff)
|
||||||
|
{
|
||||||
|
/* INSTRUCTION MEMORY (0x01000000 - 0x0103ffff) */
|
||||||
|
addr &= ((1 << IMEM_SIZE) - 1);
|
||||||
|
if ((addr + size) > (1 << IMEM_SIZE))
|
||||||
|
{
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: instruction address 0x%x is outside range 0-0x%x.\n",
|
||||||
|
addr + size - 1, (1 << IMEM_SIZE) - 1);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
if (write)
|
if (write)
|
||||||
memcpy (State.imem+addr, buffer, size);
|
{
|
||||||
|
memcpy (State.imem+addr, buffer, size);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
memcpy (buffer, State.imem+addr, size);
|
{
|
||||||
|
memcpy (buffer, State.imem+addr, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (write)
|
else if ((addr | 0x0000ffff) == 0x0200ffff)
|
||||||
{
|
{
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: address 0x%x is not in valid range\n",addr);
|
/* DATA MEMORY (0x02000000 - 0x0200ffff) */
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "Instruction addresses start at 0x01000000\n");
|
addr &= ((1 << DMEM_SIZE) - 1);
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "Data addresses start at 0x02000000\n");
|
if ((addr + size) > (1 << DMEM_SIZE))
|
||||||
(*d10v_callback->printf_filtered) (d10v_callback, "Unified addresses start at 0x00000000\n");
|
{
|
||||||
exit(1);
|
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data address 0x%x is outside range 0-0x%x.\n",
|
||||||
|
addr + size - 1, (1 << DMEM_SIZE) - 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (write)
|
||||||
|
{
|
||||||
|
memcpy (State.dmem+addr, buffer, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy (buffer, State.dmem+addr, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
{
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: address 0x%x is not in valid range\n",addr);
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "Unified memory addresses are 0x00000000 - 0x00ffffff\n");
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "Instruction addresses are 0x01000000 - 0x0103ffff\n");
|
||||||
|
(*d10v_callback->printf_filtered) (d10v_callback, "Data addresses are 0x02000000 - 0x0200ffff\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -528,7 +566,11 @@ sim_close (sd, quitting)
|
|||||||
int quitting;
|
int quitting;
|
||||||
{
|
{
|
||||||
if (prog_bfd != NULL && prog_bfd_was_opened_p)
|
if (prog_bfd != NULL && prog_bfd_was_opened_p)
|
||||||
bfd_close (prog_bfd);
|
{
|
||||||
|
bfd_close (prog_bfd);
|
||||||
|
prog_bfd = NULL;
|
||||||
|
prog_bfd_was_opened_p = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -637,6 +679,7 @@ sim_resume (sd, step, siggnal)
|
|||||||
int step, siggnal;
|
int step, siggnal;
|
||||||
{
|
{
|
||||||
uint32 inst;
|
uint32 inst;
|
||||||
|
int do_iba;
|
||||||
|
|
||||||
/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
|
/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
|
||||||
State.exception = 0;
|
State.exception = 0;
|
||||||
@ -648,6 +691,14 @@ sim_resume (sd, step, siggnal)
|
|||||||
inst = get_longword( pc_addr() );
|
inst = get_longword( pc_addr() );
|
||||||
State.pc_changed = 0;
|
State.pc_changed = 0;
|
||||||
ins_type_counters[ (int)INS_CYCLES ]++;
|
ins_type_counters[ (int)INS_CYCLES ]++;
|
||||||
|
|
||||||
|
/* check to see if IBA should be triggered after
|
||||||
|
this instruction */
|
||||||
|
if (State.DB && (PC == IBA))
|
||||||
|
do_iba = 1;
|
||||||
|
else
|
||||||
|
do_iba = 0;
|
||||||
|
|
||||||
switch (inst & 0xC0000000)
|
switch (inst & 0xC0000000)
|
||||||
{
|
{
|
||||||
case 0xC0000000:
|
case 0xC0000000:
|
||||||
@ -688,6 +739,14 @@ sim_resume (sd, step, siggnal)
|
|||||||
else
|
else
|
||||||
PC++;
|
PC++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_iba)
|
||||||
|
{
|
||||||
|
BPC = PC;
|
||||||
|
move_to_cr (BPSW_CR, PSW);
|
||||||
|
move_to_cr (PSW_CR, PSW & PSW_SM_BIT);
|
||||||
|
PC = SDBT_VECTOR_START;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while ( !State.exception && !stop_simulator);
|
while ( !State.exception && !stop_simulator);
|
||||||
|
|
||||||
@ -825,7 +884,7 @@ sim_create_inferior (sd, abfd, argv, env)
|
|||||||
|
|
||||||
/* set PC */
|
/* set PC */
|
||||||
if (abfd != NULL)
|
if (abfd != NULL)
|
||||||
start_address = bfd_get_start_address (prog_bfd);
|
start_address = bfd_get_start_address (abfd);
|
||||||
else
|
else
|
||||||
start_address = 0xffc0 << 2;
|
start_address = 0xffc0 << 2;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -901,6 +960,8 @@ sim_fetch_register (sd, rn, memory)
|
|||||||
WRITE_16 (memory, IMAP1);
|
WRITE_16 (memory, IMAP1);
|
||||||
else if (rn == 34)
|
else if (rn == 34)
|
||||||
WRITE_16 (memory, DMAP);
|
WRITE_16 (memory, DMAP);
|
||||||
|
else if (rn >= 16)
|
||||||
|
WRITE_16 (memory, move_from_cr (rn - 16));
|
||||||
else
|
else
|
||||||
WRITE_16 (memory, State.regs[rn]);
|
WRITE_16 (memory, State.regs[rn]);
|
||||||
}
|
}
|
||||||
@ -922,6 +983,8 @@ sim_store_register (sd, rn, memory)
|
|||||||
SET_IMAP1( READ_16(memory) );
|
SET_IMAP1( READ_16(memory) );
|
||||||
else if (rn == 32)
|
else if (rn == 32)
|
||||||
SET_IMAP0( READ_16(memory) );
|
SET_IMAP0( READ_16(memory) );
|
||||||
|
else if (rn >= 16)
|
||||||
|
move_to_cr (rn - 16, READ_16 (memory));
|
||||||
else
|
else
|
||||||
State.regs[rn]= READ_16 (memory);
|
State.regs[rn]= READ_16 (memory);
|
||||||
}
|
}
|
||||||
@ -945,7 +1008,10 @@ sim_load (sd, prog, abfd, from_tty)
|
|||||||
extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
|
extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
|
||||||
|
|
||||||
if (prog_bfd != NULL && prog_bfd_was_opened_p)
|
if (prog_bfd != NULL && prog_bfd_was_opened_p)
|
||||||
bfd_close (prog_bfd);
|
{
|
||||||
|
bfd_close (prog_bfd);
|
||||||
|
prog_bfd_was_opened_p = 0;
|
||||||
|
}
|
||||||
prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
|
prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
|
||||||
sim_kind == SIM_OPEN_DEBUG,
|
sim_kind == SIM_OPEN_DEBUG,
|
||||||
0, sim_write_phys);
|
0, sim_write_phys);
|
||||||
|
Reference in New Issue
Block a user