break dcache code out of remote-bug.c
This commit is contained in:
parent
bf9d25378e
commit
755892d6ff
7 changed files with 306 additions and 194 deletions
|
@ -81,6 +81,8 @@ coredep.c
|
||||||
corelow.c
|
corelow.c
|
||||||
cp-valprint.c
|
cp-valprint.c
|
||||||
dbxread.c
|
dbxread.c
|
||||||
|
dcache.c
|
||||||
|
dcache.h
|
||||||
defs.h
|
defs.h
|
||||||
delta68-nat.c
|
delta68-nat.c
|
||||||
demangle.c
|
demangle.c
|
||||||
|
|
|
@ -1,3 +1,22 @@
|
||||||
|
Tue Aug 31 15:01:27 1993 K. Richard Pixley (rich@sendai.cygnus.com)
|
||||||
|
|
||||||
|
Break dcache code out of remote-bug.c into dcache.[hc].
|
||||||
|
* Makefile.in (dcache_h): new macro.
|
||||||
|
(HFILES): added $(dcache_h).
|
||||||
|
(ALLDEPFILES): added dcache.c.
|
||||||
|
(dcache.o): new rule.
|
||||||
|
(remote-bug.o): now depends on $(dcache_h).
|
||||||
|
* remote-bug.c: include dcache.h. remove externs for insque and
|
||||||
|
remque, add extern for bcopy. Prototype bug_close,
|
||||||
|
bug_clear_breakpoints, bug_write_cr. dcache code moved to
|
||||||
|
dcache.[hc]. Changed dcache calling convention to include an
|
||||||
|
initial DCACHE argument.
|
||||||
|
(bug_dcache): new static variable.
|
||||||
|
(bug_read_inferior_memory): change second arg to
|
||||||
|
unsigned char.
|
||||||
|
* dcache.[ch]: new files.
|
||||||
|
* config/m88k/m88k.mt (TDEPFILES): add dcache.o.
|
||||||
|
|
||||||
Tue Aug 31 10:33:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
|
Tue Aug 31 10:33:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
|
||||||
|
|
||||||
* c-typeprint.c (c_print_type_base): Treat show = 0 just like
|
* c-typeprint.c (c_print_type_base): Treat show = 0 just like
|
||||||
|
|
|
@ -336,6 +336,7 @@ udiheaders = \
|
||||||
29k-share/udi/udipt29k.h \
|
29k-share/udi/udipt29k.h \
|
||||||
29k-share/udi/udisoc.h
|
29k-share/udi/udisoc.h
|
||||||
|
|
||||||
|
dcache_h = dcache.h
|
||||||
|
|
||||||
gdbcore_h = gdbcore.h $(bfd_h)
|
gdbcore_h = gdbcore.h $(bfd_h)
|
||||||
|
|
||||||
|
@ -371,7 +372,7 @@ HFILES = buildsym.h call-cmds.h defs.h environ.h $(gdbcmd_h) \
|
||||||
nindy-share/env.h nindy-share/stop.h \
|
nindy-share/env.h nindy-share/stop.h \
|
||||||
vx-share/dbgRpcLib.h vx-share/ptrace.h vx-share/vxTypes.h \
|
vx-share/dbgRpcLib.h vx-share/ptrace.h vx-share/vxTypes.h \
|
||||||
vx-share/vxWorks.h vx-share/wait.h vx-share/xdr_ld.h \
|
vx-share/vxWorks.h vx-share/wait.h vx-share/xdr_ld.h \
|
||||||
vx-share/xdr_ptrace.h vx-share/xdr_rdb.h thread.h
|
vx-share/xdr_ptrace.h vx-share/xdr_rdb.h thread.h $(dcache_h)
|
||||||
|
|
||||||
# GDB "info" files, which should be included in their entirety
|
# GDB "info" files, which should be included in their entirety
|
||||||
INFOFILES = gdb.info*
|
INFOFILES = gdb.info*
|
||||||
|
@ -799,7 +800,7 @@ unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
|
||||||
ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
|
ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
|
||||||
a29k-pinsn.c a29k-tdep.c a68v-nat.c altos-xdep.c arm-convert.s \
|
a29k-pinsn.c a29k-tdep.c a68v-nat.c altos-xdep.c arm-convert.s \
|
||||||
arm-pinsn.c arm-tdep.c arm-xdep.c convex-pinsn.c convex-tdep.c \
|
arm-pinsn.c arm-tdep.c arm-xdep.c convex-pinsn.c convex-tdep.c \
|
||||||
convex-xdep.c core-svr4.c coredep.c corelow.c delta68-nat.c \
|
convex-xdep.c core-svr4.c coredep.c corelow.c dcache.c delta68-nat.c \
|
||||||
dpx2-nat.c exec.c fork-child.c \
|
dpx2-nat.c exec.c fork-child.c \
|
||||||
go32-xdep.c gould-pinsn.c gould-xdep.c h8300-tdep.c h8500-tdep.c \
|
go32-xdep.c gould-pinsn.c gould-xdep.c h8300-tdep.c h8500-tdep.c \
|
||||||
hp300ux-nat.c hppa-pinsn.c hppa-tdep.c hppab-nat.c hppah-nat.c \
|
hp300ux-nat.c hppa-pinsn.c hppa-tdep.c hppab-nat.c hppah-nat.c \
|
||||||
|
@ -1013,6 +1014,8 @@ corelow.o: corelow.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
|
||||||
cp-valprint.o: cp-valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
|
cp-valprint.o: cp-valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
|
||||||
$(gdbtypes_h) $(symtab_h) $(value_h)
|
$(gdbtypes_h) $(symtab_h) $(value_h)
|
||||||
|
|
||||||
|
dcache.o: dcache.c $(dcache_h)
|
||||||
|
|
||||||
dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
|
dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
|
||||||
complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
|
complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
|
||||||
$(gdbtypes_h) language.h objfiles.h partial-stab.h stabsread.h \
|
$(gdbtypes_h) language.h objfiles.h partial-stab.h stabsread.h \
|
||||||
|
@ -1195,7 +1198,7 @@ remote-adapt.o: remote-adapt.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
||||||
$(inferior_h) target.h terminal.h
|
$(inferior_h) target.h terminal.h
|
||||||
|
|
||||||
remote-bug.o: remote-bug.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
remote-bug.o: remote-bug.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
||||||
$(inferior_h) target.h terminal.h
|
$(inferior_h) target.h terminal.h $(dcache_h)
|
||||||
|
|
||||||
remote-eb.o: remote-eb.c $(wait_h) $(srcdir)/config/a29k/tm-a29k.h \
|
remote-eb.o: remote-eb.c $(wait_h) $(srcdir)/config/a29k/tm-a29k.h \
|
||||||
$(defs_h) $(gdbcore_h) $(inferior_h) symfile.h target.h terminal.h
|
$(defs_h) $(gdbcore_h) $(inferior_h) symfile.h target.h terminal.h
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: Motorola 88000 Binary Compatability Standard
|
# Target: Motorola 88000 Binary Compatability Standard
|
||||||
TDEPFILES= m88k-tdep.o m88k-pinsn.o exec.o remote-bug.o
|
TDEPFILES= m88k-tdep.o m88k-pinsn.o exec.o remote-bug.o dcache.o
|
||||||
TM_FILE= tm-m88k.h
|
TM_FILE= tm-m88k.h
|
||||||
|
|
189
gdb/dcache.c
Normal file
189
gdb/dcache.c
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
/* Caching code. Typically used by remote back ends for
|
||||||
|
caching remote memory.
|
||||||
|
|
||||||
|
Copyright 1992, 1993 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "dcache.h"
|
||||||
|
|
||||||
|
extern int insque();
|
||||||
|
extern int remque();
|
||||||
|
|
||||||
|
/* The data cache records all the data read from the remote machine
|
||||||
|
since the last time it stopped.
|
||||||
|
|
||||||
|
Each cache block holds line_size bytes of data
|
||||||
|
starting at a multiple-of-line_size address. */
|
||||||
|
|
||||||
|
#define LINE_SIZE_MASK ((LINE_SIZE - 1)) /* eg 7*2+1= 111*/
|
||||||
|
#define XFORM(x) (((x) & LINE_SIZE_MASK) >> 2)
|
||||||
|
|
||||||
|
/* Free all the data cache blocks, thus discarding all cached data. */
|
||||||
|
void
|
||||||
|
dcache_flush (dcache)
|
||||||
|
DCACHE *dcache;
|
||||||
|
{
|
||||||
|
register struct dcache_block *db;
|
||||||
|
|
||||||
|
while ((db = dcache->dcache_valid.next) != &dcache->dcache_valid)
|
||||||
|
{
|
||||||
|
remque (db);
|
||||||
|
insque (db, &dcache->dcache_free);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If addr is present in the dcache, return the address of the block
|
||||||
|
* containing it.
|
||||||
|
*/
|
||||||
|
struct dcache_block *
|
||||||
|
dcache_hit (dcache, addr)
|
||||||
|
DCACHE *dcache;
|
||||||
|
unsigned int addr;
|
||||||
|
{
|
||||||
|
register struct dcache_block *db;
|
||||||
|
|
||||||
|
if (addr & 3)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
/* Search all cache blocks for one that is at this address. */
|
||||||
|
db = dcache->dcache_valid.next;
|
||||||
|
while (db != &dcache->dcache_valid)
|
||||||
|
{
|
||||||
|
if ((addr & ~LINE_SIZE_MASK) == db->addr)
|
||||||
|
return db;
|
||||||
|
db = db->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the int data at address ADDR in dcache block DC. */
|
||||||
|
int
|
||||||
|
dcache_value (db, addr)
|
||||||
|
struct dcache_block *db;
|
||||||
|
unsigned int addr;
|
||||||
|
{
|
||||||
|
if (addr & 3)
|
||||||
|
abort ();
|
||||||
|
return (db->data[XFORM (addr)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a free cache block, put or keep it on the valid list,
|
||||||
|
and return its address. The caller should store into the block
|
||||||
|
the address and data that it describes, then remque it from the
|
||||||
|
free list and insert it into the valid list. This procedure
|
||||||
|
prevents errors from creeping in if a ninMemGet is interrupted
|
||||||
|
(which used to put garbage blocks in the valid list...). */
|
||||||
|
struct dcache_block *
|
||||||
|
dcache_alloc (dcache)
|
||||||
|
DCACHE *dcache;
|
||||||
|
{
|
||||||
|
register struct dcache_block *db;
|
||||||
|
|
||||||
|
if ((db = dcache->dcache_free.next) == &dcache->dcache_free)
|
||||||
|
{
|
||||||
|
/* If we can't get one from the free list, take last valid and put
|
||||||
|
it on the free list. */
|
||||||
|
db = dcache->dcache_valid.last;
|
||||||
|
remque (db);
|
||||||
|
insque (db, &dcache->dcache_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
remque (db);
|
||||||
|
insque (db, &dcache->dcache_valid);
|
||||||
|
return (db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the contents of the word at address ADDR in the remote machine,
|
||||||
|
using the data cache. */
|
||||||
|
int
|
||||||
|
dcache_fetch (dcache, addr)
|
||||||
|
DCACHE *dcache;
|
||||||
|
CORE_ADDR addr;
|
||||||
|
{
|
||||||
|
register struct dcache_block *db;
|
||||||
|
|
||||||
|
db = dcache_hit (dcache, addr);
|
||||||
|
if (db == 0)
|
||||||
|
{
|
||||||
|
db = dcache_alloc (dcache);
|
||||||
|
immediate_quit++;
|
||||||
|
(*dcache->read_memory) (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
|
||||||
|
immediate_quit--;
|
||||||
|
db->addr = addr & ~LINE_SIZE_MASK;
|
||||||
|
remque (db); /* Off the free list */
|
||||||
|
insque (db, &dcache->dcache_valid); /* On the valid list */
|
||||||
|
}
|
||||||
|
return (dcache_value (db, addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the word at ADDR both in the data cache and in the remote machine. */
|
||||||
|
void
|
||||||
|
dcache_poke (dcache, addr, data)
|
||||||
|
DCACHE *dcache;
|
||||||
|
CORE_ADDR addr;
|
||||||
|
int data;
|
||||||
|
{
|
||||||
|
register struct dcache_block *db;
|
||||||
|
|
||||||
|
/* First make sure the word is IN the cache. DB is its cache block. */
|
||||||
|
db = dcache_hit (dcache, addr);
|
||||||
|
if (db == 0)
|
||||||
|
{
|
||||||
|
db = dcache_alloc (dcache);
|
||||||
|
immediate_quit++;
|
||||||
|
(*dcache->write_memory) (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
|
||||||
|
immediate_quit--;
|
||||||
|
db->addr = addr & ~LINE_SIZE_MASK;
|
||||||
|
remque (db); /* Off the free list */
|
||||||
|
insque (db, &dcache->dcache_valid); /* On the valid list */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modify the word in the cache. */
|
||||||
|
db->data[XFORM (addr)] = data;
|
||||||
|
|
||||||
|
/* Send the changed word. */
|
||||||
|
immediate_quit++;
|
||||||
|
(*dcache->write_memory) (addr, (unsigned char *) &data, 4);
|
||||||
|
immediate_quit--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the data cache. */
|
||||||
|
DCACHE *
|
||||||
|
dcache_init (reading, writing)
|
||||||
|
memxferfunc reading;
|
||||||
|
memxferfunc writing;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register struct dcache_block *db;
|
||||||
|
DCACHE *dcache;
|
||||||
|
|
||||||
|
dcache = xmalloc(sizeof(*dcache));
|
||||||
|
dcache->read_memory = reading;
|
||||||
|
dcache->write_memory = writing;
|
||||||
|
dcache->the_cache = xmalloc(sizeof(*dcache->the_cache) * DCACHE_SIZE);
|
||||||
|
|
||||||
|
dcache->dcache_free.next = dcache->dcache_free.last = &dcache->dcache_free;
|
||||||
|
dcache->dcache_valid.next = dcache->dcache_valid.last = &dcache->dcache_valid;
|
||||||
|
for (db = dcache->the_cache, i = 0; i < DCACHE_SIZE; i++, db++)
|
||||||
|
insque (db, &dcache->dcache_free);
|
||||||
|
|
||||||
|
return(dcache);
|
||||||
|
}
|
||||||
|
|
67
gdb/dcache.h
Normal file
67
gdb/dcache.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/* Declarations for caching. Typically used by remote back ends for
|
||||||
|
caching remote memory.
|
||||||
|
|
||||||
|
Copyright 1992, 1993 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef DCACHE_H
|
||||||
|
#define DCACHE_H
|
||||||
|
|
||||||
|
#define LINE_SIZE_POWER (4)
|
||||||
|
/* eg 1<<3 == 8 */
|
||||||
|
#define LINE_SIZE (1 << LINE_SIZE_POWER)
|
||||||
|
/* Number of cache blocks */
|
||||||
|
#define DCACHE_SIZE (64)
|
||||||
|
|
||||||
|
struct dcache_block
|
||||||
|
{
|
||||||
|
struct dcache_block *next, *last;
|
||||||
|
unsigned int addr; /* Address for which data is recorded. */
|
||||||
|
int data[LINE_SIZE / sizeof (int)];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*memxferfunc) PARAMS((CORE_ADDR memaddr,
|
||||||
|
unsigned char *myaddr,
|
||||||
|
int len));
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* Function to actually read the target memory. */
|
||||||
|
memxferfunc read_memory;
|
||||||
|
|
||||||
|
/* Function to actually write the target memory */
|
||||||
|
memxferfunc write_memory;
|
||||||
|
|
||||||
|
/* free list */
|
||||||
|
struct dcache_block dcache_free;
|
||||||
|
|
||||||
|
/* in use list */
|
||||||
|
struct dcache_block dcache_valid;
|
||||||
|
|
||||||
|
/* The cache itself. */
|
||||||
|
struct dcache_block *the_cache;
|
||||||
|
|
||||||
|
} DCACHE;
|
||||||
|
|
||||||
|
int dcache_fetch PARAMS((DCACHE *dcache, CORE_ADDR addr));
|
||||||
|
void dcache_flush PARAMS((DCACHE *dcache));
|
||||||
|
DCACHE *dcache_init PARAMS((memxferfunc reading, memxferfunc writing));
|
||||||
|
|
||||||
|
/* Write the word at ADDR both in the data cache and in the remote machine. */
|
||||||
|
void dcache_poke PARAMS((DCACHE *dcache, CORE_ADDR addr, int data));
|
||||||
|
|
||||||
|
#endif /* DCACHE_H */
|
212
gdb/remote-bug.c
212
gdb/remote-bug.c
|
@ -38,9 +38,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "gdbcmd.h"
|
#include "gdbcmd.h"
|
||||||
|
|
||||||
|
#include "dcache.h"
|
||||||
|
|
||||||
extern int sleep();
|
extern int sleep();
|
||||||
extern int remque();
|
extern int bcopy();
|
||||||
extern int insque();
|
|
||||||
|
|
||||||
/* External data declarations */
|
/* External data declarations */
|
||||||
extern int stop_soon_quietly; /* for wait_for_inferior */
|
extern int stop_soon_quietly; /* for wait_for_inferior */
|
||||||
|
@ -49,26 +50,27 @@ extern int stop_soon_quietly; /* for wait_for_inferior */
|
||||||
extern struct target_ops bug_ops; /* Forward declaration */
|
extern struct target_ops bug_ops; /* Forward declaration */
|
||||||
|
|
||||||
/* Forward function declarations */
|
/* Forward function declarations */
|
||||||
static void bug_close ();
|
|
||||||
static int bug_clear_breakpoints ();
|
|
||||||
static void bug_write_cr();
|
|
||||||
|
|
||||||
#if __STDC__ == 1
|
static int bug_clear_breakpoints PARAMS((void));
|
||||||
|
static void bug_close PARAMS((int quitting));
|
||||||
|
static void bug_write_cr PARAMS((char *string));
|
||||||
|
|
||||||
static int bug_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
|
static int bug_read_inferior_memory PARAMS((CORE_ADDR memaddr,
|
||||||
static int bug_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
|
unsigned char *myaddr,
|
||||||
|
int len));
|
||||||
|
|
||||||
#else
|
static int bug_write_inferior_memory PARAMS((CORE_ADDR memaddr,
|
||||||
|
unsigned char *myaddr,
|
||||||
static int bug_read_inferior_memory ();
|
int len));
|
||||||
static int bug_write_inferior_memory ();
|
|
||||||
|
|
||||||
#endif /* not __STDC__ */
|
|
||||||
|
|
||||||
/* This is the serial descriptor to our target. */
|
/* This is the serial descriptor to our target. */
|
||||||
|
|
||||||
static serial_t desc = NULL;
|
static serial_t desc = NULL;
|
||||||
|
|
||||||
|
/* This is our data cache. */
|
||||||
|
|
||||||
|
static DCACHE *bug_dcache;
|
||||||
|
|
||||||
/* This variable is somewhat arbitrary. It's here so that it can be
|
/* This variable is somewhat arbitrary. It's here so that it can be
|
||||||
set from within a running gdb. */
|
set from within a running gdb. */
|
||||||
|
|
||||||
|
@ -110,176 +112,6 @@ static int srec_sleep = 0;
|
||||||
|
|
||||||
static int srec_noise = 0;
|
static int srec_noise = 0;
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* Caching stuff stolen from remote-nindy.c */
|
|
||||||
|
|
||||||
/* The data cache records all the data read from the remote machine
|
|
||||||
since the last time it stopped.
|
|
||||||
|
|
||||||
Each cache block holds LINE_SIZE bytes of data
|
|
||||||
starting at a multiple-of-LINE_SIZE address. */
|
|
||||||
|
|
||||||
#define LINE_SIZE_POWER 4
|
|
||||||
#define LINE_SIZE (1<<LINE_SIZE_POWER) /* eg 1<<3 == 8 */
|
|
||||||
#define LINE_SIZE_MASK ((LINE_SIZE-1)) /* eg 7*2+1= 111*/
|
|
||||||
#define DCACHE_SIZE 64 /* Number of cache blocks */
|
|
||||||
#define XFORM(x) ((x&LINE_SIZE_MASK)>>2)
|
|
||||||
struct dcache_block
|
|
||||||
{
|
|
||||||
struct dcache_block *next, *last;
|
|
||||||
unsigned int addr; /* Address for which data is recorded. */
|
|
||||||
int data[LINE_SIZE / sizeof (int)];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dcache_block dcache_free, dcache_valid;
|
|
||||||
|
|
||||||
/* Free all the data cache blocks, thus discarding all cached data. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
dcache_flush ()
|
|
||||||
{
|
|
||||||
register struct dcache_block *db;
|
|
||||||
|
|
||||||
while ((db = dcache_valid.next) != &dcache_valid)
|
|
||||||
{
|
|
||||||
remque (db);
|
|
||||||
insque (db, &dcache_free);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If addr is present in the dcache, return the address of the block
|
|
||||||
* containing it.
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
struct dcache_block *
|
|
||||||
dcache_hit (addr)
|
|
||||||
unsigned int addr;
|
|
||||||
{
|
|
||||||
register struct dcache_block *db;
|
|
||||||
|
|
||||||
if (addr & 3)
|
|
||||||
abort ();
|
|
||||||
|
|
||||||
/* Search all cache blocks for one that is at this address. */
|
|
||||||
db = dcache_valid.next;
|
|
||||||
while (db != &dcache_valid)
|
|
||||||
{
|
|
||||||
if ((addr & ~LINE_SIZE_MASK) == db->addr)
|
|
||||||
return db;
|
|
||||||
db = db->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the int data at address ADDR in dcache block DC. */
|
|
||||||
static
|
|
||||||
int
|
|
||||||
dcache_value (db, addr)
|
|
||||||
struct dcache_block *db;
|
|
||||||
unsigned int addr;
|
|
||||||
{
|
|
||||||
if (addr & 3)
|
|
||||||
abort ();
|
|
||||||
return (db->data[XFORM (addr)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get a free cache block, put or keep it on the valid list,
|
|
||||||
and return its address. The caller should store into the block
|
|
||||||
the address and data that it describes, then remque it from the
|
|
||||||
free list and insert it into the valid list. This procedure
|
|
||||||
prevents errors from creeping in if a ninMemGet is interrupted
|
|
||||||
(which used to put garbage blocks in the valid list...). */
|
|
||||||
static
|
|
||||||
struct dcache_block *
|
|
||||||
dcache_alloc ()
|
|
||||||
{
|
|
||||||
register struct dcache_block *db;
|
|
||||||
|
|
||||||
if ((db = dcache_free.next) == &dcache_free)
|
|
||||||
{
|
|
||||||
/* If we can't get one from the free list, take last valid and put
|
|
||||||
it on the free list. */
|
|
||||||
db = dcache_valid.last;
|
|
||||||
remque (db);
|
|
||||||
insque (db, &dcache_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
remque (db);
|
|
||||||
insque (db, &dcache_valid);
|
|
||||||
return (db);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the contents of the word at address ADDR in the remote machine,
|
|
||||||
using the data cache. */
|
|
||||||
static
|
|
||||||
int
|
|
||||||
dcache_fetch (addr)
|
|
||||||
CORE_ADDR addr;
|
|
||||||
{
|
|
||||||
register struct dcache_block *db;
|
|
||||||
|
|
||||||
db = dcache_hit (addr);
|
|
||||||
if (db == 0)
|
|
||||||
{
|
|
||||||
db = dcache_alloc ();
|
|
||||||
immediate_quit++;
|
|
||||||
bug_read_inferior_memory (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
|
|
||||||
immediate_quit--;
|
|
||||||
db->addr = addr & ~LINE_SIZE_MASK;
|
|
||||||
remque (db); /* Off the free list */
|
|
||||||
insque (db, &dcache_valid); /* On the valid list */
|
|
||||||
}
|
|
||||||
return (dcache_value (db, addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the word at ADDR both in the data cache and in the remote machine. */
|
|
||||||
static void
|
|
||||||
dcache_poke (addr, data)
|
|
||||||
CORE_ADDR addr;
|
|
||||||
int data;
|
|
||||||
{
|
|
||||||
register struct dcache_block *db;
|
|
||||||
|
|
||||||
/* First make sure the word is IN the cache. DB is its cache block. */
|
|
||||||
db = dcache_hit (addr);
|
|
||||||
if (db == 0)
|
|
||||||
{
|
|
||||||
db = dcache_alloc ();
|
|
||||||
immediate_quit++;
|
|
||||||
bug_write_inferior_memory (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
|
|
||||||
immediate_quit--;
|
|
||||||
db->addr = addr & ~LINE_SIZE_MASK;
|
|
||||||
remque (db); /* Off the free list */
|
|
||||||
insque (db, &dcache_valid); /* On the valid list */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Modify the word in the cache. */
|
|
||||||
db->data[XFORM (addr)] = data;
|
|
||||||
|
|
||||||
/* Send the changed word. */
|
|
||||||
immediate_quit++;
|
|
||||||
bug_write_inferior_memory (addr, (unsigned char *) &data, 4);
|
|
||||||
immediate_quit--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The cache itself. */
|
|
||||||
struct dcache_block the_cache[DCACHE_SIZE];
|
|
||||||
|
|
||||||
/* Initialize the data cache. */
|
|
||||||
static void
|
|
||||||
dcache_init ()
|
|
||||||
{
|
|
||||||
register i;
|
|
||||||
register struct dcache_block *db;
|
|
||||||
|
|
||||||
db = the_cache;
|
|
||||||
dcache_free.next = dcache_free.last = &dcache_free;
|
|
||||||
dcache_valid.next = dcache_valid.last = &dcache_valid;
|
|
||||||
for (i = 0; i < DCACHE_SIZE; i++, db++)
|
|
||||||
insque (db, &dcache_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* I/O stuff stolen from remote-eb.c
|
* I/O stuff stolen from remote-eb.c
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -489,7 +321,7 @@ bug_load (args, fromtty)
|
||||||
|
|
||||||
check_open ();
|
check_open ();
|
||||||
|
|
||||||
dcache_flush ();
|
dcache_flush (bug_dcache);
|
||||||
inferior_pid = 0;
|
inferior_pid = 0;
|
||||||
abfd = bfd_openr (args, 0);
|
abfd = bfd_openr (args, 0);
|
||||||
if (!abfd)
|
if (!abfd)
|
||||||
|
@ -616,7 +448,7 @@ bug_open (name, from_tty)
|
||||||
SERIAL_RAW (desc);
|
SERIAL_RAW (desc);
|
||||||
is_open = 1;
|
is_open = 1;
|
||||||
|
|
||||||
dcache_init ();
|
bug_dcache = dcache_init (bug_read_inferior_memory, bug_write_inferior_memory);
|
||||||
|
|
||||||
/* Hello? Are you there? */
|
/* Hello? Are you there? */
|
||||||
SERIAL_WRITE (desc, "\r", 1);
|
SERIAL_WRITE (desc, "\r", 1);
|
||||||
|
@ -666,7 +498,7 @@ void
|
||||||
bug_resume (pid, step, sig)
|
bug_resume (pid, step, sig)
|
||||||
int pid, step, sig;
|
int pid, step, sig;
|
||||||
{
|
{
|
||||||
dcache_flush ();
|
dcache_flush (bug_dcache);
|
||||||
|
|
||||||
if (step)
|
if (step)
|
||||||
{
|
{
|
||||||
|
@ -1040,7 +872,7 @@ int
|
||||||
bug_fetch_word (addr)
|
bug_fetch_word (addr)
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
{
|
{
|
||||||
return dcache_fetch (addr);
|
return dcache_fetch (bug_dcache, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a word WORD into remote address ADDR.
|
/* Write a word WORD into remote address ADDR.
|
||||||
|
@ -1051,7 +883,7 @@ bug_store_word (addr, word)
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
int word;
|
int word;
|
||||||
{
|
{
|
||||||
dcache_poke (addr, word);
|
dcache_poke (bug_dcache, addr, word);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1312,7 +1144,7 @@ bug_files_info ()
|
||||||
static int
|
static int
|
||||||
bug_read_inferior_memory (memaddr, myaddr, len)
|
bug_read_inferior_memory (memaddr, myaddr, len)
|
||||||
CORE_ADDR memaddr;
|
CORE_ADDR memaddr;
|
||||||
char *myaddr;
|
unsigned char *myaddr;
|
||||||
int len;
|
int len;
|
||||||
{
|
{
|
||||||
char request[100];
|
char request[100];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue