/* Caching code. Typically used by remote back ends for
caching remote memory.
- Copyright 1992, 1993, 1995 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1995, 1998 Free Software Foundation, Inc.
This file is part of GDB.
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. */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "dcache.h"
#include "gdbcmd.h"
-#include <string.h>
-
+#include "gdb_string.h"
+#include "gdbcore.h"
/*
The data cache could lead to incorrect results because it doesn't know
struct dcache_block
{
struct dcache_block *p; /* next in list */
- unsigned int addr; /* Address for which data is recorded. */
- unsigned char data[LINE_SIZE]; /* bytes at given address */
+ CORE_ADDR addr; /* Address for which data is recorded. */
+ char data[LINE_SIZE]; /* bytes at given address */
unsigned char state[LINE_SIZE]; /* what state the data is in */
/* whether anything in state is dirty - used to speed up the
int cache_has_stuff;
} ;
-int remote_dcache = 1;
+static int dcache_poke_byte PARAMS ((DCACHE *dcache, CORE_ADDR addr,
+ char *ptr));
-DCACHE *last_cache; /* Used by info dcache */
+static int dcache_peek_byte PARAMS ((DCACHE *dcache, CORE_ADDR addr,
+ char *ptr));
+
+static struct dcache_block *dcache_hit PARAMS ((DCACHE *dcache,
+ CORE_ADDR addr));
+
+static int dcache_write_line PARAMS ((DCACHE *dcache,struct dcache_block *db));
+
+static struct dcache_block *dcache_alloc PARAMS ((DCACHE *dcache));
+
+static int dcache_writeback PARAMS ((DCACHE *dcache));
+static void dcache_info PARAMS ((char *exp, int tty));
+
+void _initialize_dcache PARAMS ((void));
+
+int remote_dcache = 0;
+
+DCACHE *last_cache; /* Used by info dcache */
/* Free all the data cache blocks, thus discarding all cached data. */
/* If addr is present in the dcache, return the address of the block
containing it. */
-static
-struct dcache_block *
+
+static struct dcache_block *
dcache_hit (dcache, addr)
DCACHE *dcache;
- unsigned int addr;
+ CORE_ADDR addr;
{
register struct dcache_block *db;
int len = 0;
for (e = s ; e < LINE_SIZE; e++, len++)
if (db->state[e] != ENTRY_DIRTY)
- {
- /* all bytes from s..s+len-1 need to
- be written out */
- int done = 0;
- while (done < len) {
- int t = dcache->write_memory (db->addr + s + done,
- db->data + s + done,
- len - done);
- if (t == 0)
- return 0;
- done += t;
- }
- memset (db->state + s, ENTRY_OK, len);
- s = e;
- break;
- }
+ break;
+ {
+ /* all bytes from s..s+len-1 need to
+ be written out */
+ int done = 0;
+ while (done < len) {
+ int t = dcache->write_memory (db->addr + s + done,
+ db->data + s + done,
+ len - done);
+ if (t == 0)
+ return 0;
+ done += t;
+ }
+ memset (db->state + s, ENTRY_OK, len);
+ s = e;
+ }
}
}
db->anydirty = 0;
prevents errors from creeping in if a memory retrieval is
interrupted (which used to put garbage blocks in the valid
list...). */
-static
-struct dcache_block *
+
+static struct dcache_block *
dcache_alloc (dcache)
DCACHE *dcache;
{
abort ();
/* Take something from the free list */
- if (db = dcache->free_head)
+ db = dcache->free_head;
+ if (db)
{
dcache->free_head = db->p;
}
-
- if (!db)
+ else
{
- /* Nothing left on free list, so grab on from the valid list */
+ /* Nothing left on free list, so grab one from the valid list */
db = dcache->valid_head;
dcache->valid_head = db->p;
Returns 0 on error. */
-int
+static int
dcache_peek_byte (dcache, addr, ptr)
DCACHE *dcache;
CORE_ADDR addr;
- unsigned char *ptr;
+ char *ptr;
{
register struct dcache_block *db = dcache_hit (dcache, addr);
int ok=1;
else
db = dcache_alloc (dcache);
immediate_quit++;
- db->addr = MASK (addr);
+ db->addr = MASK (addr);
while (done < LINE_SIZE)
{
int try =
(*dcache->read_memory)
(db->addr + done,
- (unsigned char *) db->data + done,
+ db->data + done,
LINE_SIZE - done);
if (try == 0)
return 0;
return ok;
}
-/* Using the data cache DCACHE return the contents of the word at
- address ADDR in the remote machine.
-
- Returns 0 on error. */
-
-int
-dcache_peek (dcache, addr, data)
- DCACHE *dcache;
- CORE_ADDR addr;
- int *data;
-{
- unsigned char *dp = (unsigned char *) data;
- int i;
- for (i = 0; i < sizeof (int); i++)
- {
- if (!dcache_peek_byte (dcache, addr, dp + i))
- return 0;
- }
- return 1;
-}
-
-
/* Writeback any dirty lines to the remote. */
static int
dcache_writeback (dcache)
CORE_ADDR addr;
{
int res;
- dcache_peek (dcache, addr, &res);
+
+ if (dcache_xfer_memory (dcache, addr, (char *)&res, sizeof res, 0) != sizeof res)
+ memory_error (EIO, addr);
+
return res;
}
Return zero on write error.
*/
-int
+static int
dcache_poke_byte (dcache, addr, ptr)
DCACHE *dcache;
CORE_ADDR addr;
CORE_ADDR addr;
int data;
{
- unsigned char *dp = (unsigned char *) (&data);
- int i;
- for (i = 0; i < sizeof (int); i++)
- {
- if (!dcache_poke_byte (dcache, addr, dp + i))
- return 0;
- }
- dcache_writeback (dcache);
- return 1;
+ if (dcache_xfer_memory (dcache, addr, (char *)&data, sizeof data, 1) != sizeof data)
+ return 0;
+
+ return dcache_writeback (dcache);
}
if (remote_dcache)
{
- int (*xfunc) ()
- = should_write ? dcache_poke_byte : dcache_peek_byte;
+ int (*xfunc) PARAMS ((DCACHE *dcache, CORE_ADDR addr, char *ptr));
+ xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
for (i = 0; i < len; i++)
{
}
else
{
- int (*xfunc) ()
- = should_write ? dcache->write_memory : dcache->read_memory;
+ memxferfunc xfunc;
+ xfunc = should_write ? dcache->write_memory : dcache->read_memory;
if (dcache->cache_has_stuff)
dcache_flush (dcache);
p->addr, p->refs);
for (j = 0; j < LINE_SIZE; j++)
- printf_filtered ("%02x", p->data[j]);
+ printf_filtered ("%02x", p->data[j] & 0xFF);
printf_filtered ("\n");
for (j = 0; j < LINE_SIZE; j++)
- printf_filtered ("% 2x", p->state[j]);
+ printf_filtered (" %2x", p->state[j]);
printf_filtered ("\n");
}
}