+2000-08-31 J.T. Conklin <jtc@redback.com>
+
+ * dcache.c (dcache_info): Output a cache line's state vector so it
+ lines up under the data vector.
+
+ * dcache.c (dcache_read_line): New function.
+ (dcache_peek_byte): Use it.
+ (dcache_alloc): Return NULL if write of reclaimed cache line fails.
+ (dcache_peek_byte, dcache_poke_byte): Return failure if
+ dcache_alloc() returns a NULL data block pointer.
+ (dcache_xfer_memory): Don't force writeback unless we were writing.
+
+ * monitor.c (monitor_expect): Change places where immediate_quit
+ is set to 1 or 0 to increments and decrements respectively. This
+ allows such changes to nest properly.
+ * ocd.c (ocd_start_remote): Likewise.
+ * remote-adapt.c (expect): Likewise.
+ * remote-array.c (expect): Likewise.
+ * remote-eb.c (expect): Likewise.
+ * remote-e7000.c (e7000_start_remote): Likewise.
+ * remote-mips.c (mips_expect_timeout, mips_getstring): Likewise.
+ * remote-nrom.c (expect): Likewise.
+ * remote-os9k.c (expect): Likewise.
+ * remote-sds.c (sds_start_remote): Likewise.
+ * remote-st.c (expect): Likewise.
+ * remote-utils.c (sr_expect): Likewise.
+ * remote.c (remote_start_remote): Likewise.
+ * tracepoint.c (read_actions): Likewise.
+
+ * remote-mips.c (mips_getstring): Balance changes to immediate_quit.
+
2000-08-31 David Anderson <davea@sgi.com>
* MAINTAINERS: Add myself to write-after-approval list.
int cache_has_stuff;
};
-static int dcache_poke_byte (DCACHE * dcache, CORE_ADDR addr, char *ptr);
+static int dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
-static int dcache_peek_byte (DCACHE * dcache, CORE_ADDR addr, char *ptr);
+static int dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
-static struct dcache_block *dcache_hit (DCACHE * dcache, CORE_ADDR addr);
+static struct dcache_block *dcache_hit (DCACHE *dcache, CORE_ADDR addr);
-static int dcache_write_line (DCACHE * dcache, struct dcache_block *db);
+static int dcache_write_line (DCACHE *dcache, struct dcache_block *db);
-static struct dcache_block *dcache_alloc (DCACHE * dcache, CORE_ADDR addr);
+static int dcache_read_line (DCACHE *dcache, struct dcache_block *db);
-static int dcache_writeback (DCACHE * dcache);
+static struct dcache_block *dcache_alloc (DCACHE *dcache, CORE_ADDR addr);
+
+static int dcache_writeback (DCACHE *dcache);
static void dcache_info (char *exp, int tty);
{
int s;
int e;
- s = 0;
+
if (db->anydirty)
{
for (s = 0; s < LINE_SIZE; s++)
}
+/* Read cache line */
+static int
+dcache_read_line (DCACHE *dcache, struct dcache_block *db)
+{
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int res;
+
+ /* If there are any dirty bytes in the line, it must be written
+ before a new line can be read */
+ if (db->anydirty)
+ {
+ if (!dcache_write_line (dcache, db))
+ return 0;
+ }
+
+ len = LINE_SIZE;
+ memaddr = db->addr;
+ myaddr = db->data;
+
+ while (len > 0)
+ {
+ res = (*dcache->read_memory) (memaddr, myaddr, len);
+ if (res == 0)
+ return 0;
+
+ memaddr += res;
+ myaddr += res;
+ len -= res;
+ }
+
+ memset (db->state, ENTRY_OK, sizeof (db->data));
+ db->anydirty = 0;
+
+ return 1;
+}
+
/* Get a free cache block, put or keep it on the valid list,
and return its address. */
{
/* Nothing left on free list, so grab one from the valid list */
db = dcache->valid_head;
- dcache->valid_head = db->p;
- dcache_write_line (dcache, db);
+ if (!dcache_write_line (dcache, db))
+ return NULL;
+
+ dcache->valid_head = db->p;
}
db->addr = MASK(addr);
return db;
}
-/* Using the data cache DCACHE return the contents of the byte at
- address ADDR in the remote machine.
-
- Returns 0 on error. */
-
-static int
-dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
-{
- register struct dcache_block *db = dcache_hit (dcache, addr);
- int ok = 1;
- int done = 0;
- if (db == 0
- || db->state[XFORM (addr)] == ENTRY_BAD)
- {
- if (db)
- {
- dcache_write_line (dcache, db);
- }
- else
- db = dcache_alloc (dcache, addr);
-
- immediate_quit++;
- while (done < LINE_SIZE)
- {
- int try =
- (*dcache->read_memory)
- (db->addr + done,
- db->data + done,
- LINE_SIZE - done);
- if (try == 0)
- return 0;
- done += try;
- }
- immediate_quit--;
-
- memset (db->state, ENTRY_OK, sizeof (db->data));
- db->anydirty = 0;
- }
- *ptr = db->data[XFORM (addr)];
- return ok;
-}
-
/* Writeback any dirty lines to the remote. */
static int
dcache_writeback (DCACHE *dcache)
}
+/* Using the data cache DCACHE return the contents of the byte at
+ address ADDR in the remote machine.
+
+ Returns 0 on error. */
+
+static int
+dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
+{
+ register struct dcache_block *db = dcache_hit (dcache, addr);
+
+ if (!db)
+ {
+ db = dcache_alloc (dcache, addr);
+ if (!db)
+ return 0;
+ }
+
+ if (db->state[XFORM (addr)] == ENTRY_BAD)
+ {
+ if (!dcache_read_line(dcache, db))
+ return 0;
+ }
+
+ *ptr = db->data[XFORM (addr)];
+ return 1;
+}
+
+
/* Write the byte at PTR into ADDR in the data cache.
Return zero on write error.
*/
if (!db)
{
db = dcache_alloc (dcache, addr);
+ if (!db)
+ return 0;
}
db->data[XFORM (addr)] = *ptr;
if (dcache_enabled_p)
{
- int (*xfunc) (DCACHE * dcache, CORE_ADDR addr, char *ptr);
+ int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, char *ptr);
xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
for (i = 0; i < len; i++)
if (!xfunc (dcache, memaddr + i, myaddr + i))
return 0;
}
+
+ if (should_write)
+ dcache_writeback (dcache);
+
dcache->cache_has_stuff = 1;
- dcache_writeback (dcache);
}
else
{
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");
}
}