void invalidate_dcache_range(unsigned long start, unsigned long stop) { unsigned long v, linesz; linesz = CONFIG_SYS_DCACHE_LINESZ; /* You asked for it, you got it */ start = start & ~(linesz - 1); stop = (stop + linesz - 1) & ~(linesz - 1); for (v = start; v < stop; v += linesz) dcache_invalidate_line((void *)v); }
int dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr, int len, int should_write) { int i; int res; int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr); xfunc = should_write ? dcache_poke_byte : dcache_peek_byte; /* If this is a different inferior from what we've recorded, flush the cache. */ if (! ptid_equal (inferior_ptid, dcache->ptid)) { dcache_invalidate (dcache); dcache->ptid = inferior_ptid; } /* Do write-through first, so that if it fails, we don't write to the cache at all. */ if (should_write) { res = target_write (ops, TARGET_OBJECT_RAW_MEMORY, NULL, myaddr, memaddr, len); if (res <= 0) return res; /* Update LEN to what was actually written. */ len = res; } for (i = 0; i < len; i++) { if (!xfunc (dcache, memaddr + i, myaddr + i)) { /* That failed. Discard its cache line so we don't have a partially read line. */ dcache_invalidate_line (dcache, memaddr + i); /* If we're writing, we still wrote LEN bytes. */ if (should_write) return len; else return i; } } return len; }
void dcache_update (DCACHE *dcache, enum target_xfer_status status, CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len) { ULONGEST i; for (i = 0; i < len; i++) if (status == TARGET_XFER_OK) dcache_poke_byte (dcache, memaddr + i, myaddr + i); else { /* Discard the whole cache line so we don't have a partially valid line. */ dcache_invalidate_line (dcache, memaddr + i); } }
enum target_xfer_status dcache_read_memory_partial (struct target_ops *ops, DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, ULONGEST *xfered_len) { ULONGEST i; /* If this is a different inferior from what we've recorded, flush the cache. */ if (! ptid_equal (inferior_ptid, dcache->ptid)) { dcache_invalidate (dcache); dcache->ptid = inferior_ptid; } for (i = 0; i < len; i++) { if (!dcache_peek_byte (dcache, memaddr + i, myaddr + i)) { /* That failed. Discard its cache line so we don't have a partially read line. */ dcache_invalidate_line (dcache, memaddr + i); break; } } if (i == 0) { /* Even though reading the whole line failed, we may be able to read a piece starting where the caller wanted. */ return raw_memory_xfer_partial (ops, myaddr, NULL, memaddr, len, xfered_len); } else { *xfered_len = i; return TARGET_XFER_OK; } }