int i; dcache->valid_head = 0; dcache->valid_tail = 0;  dcache->free_head = 0; dcache->free_tail = 0;  for (i = 0; i < DCACHE_SIZE; i++) { struct dcache_block *db = dcache->the_cache + i;  if (!dcache->free_head) dcache->free_head = db; else dcache->free_tail->p = db; dcache->free_tail = db; db->p = 0; }  dcache->cache_has_stuff = 0;  return; }    static struct dcache_block * dcache_hit (dcache, addr) DCACHE *dcache; CORE_ADDR addr; { register struct dcache_block *db;   db = dcache->valid_head;  while (db) { if (MASK(addr) == db->addr) { db->refs++; return db; } db = db->p; }  return NULL; }    static int dcache_write_line (dcache, db) DCACHE *dcache; register struct dcache_block *db; { int s; int e; s = 0; if (db->anydirty) { for (s = 0; s < LINE_SIZE; s++) { if (db->state[s] == ENTRY_DIRTY) { int len = 0; for (e = s ; e < LINE_SIZE; e++, len++) if (db->state[e] != ENTRY_DIRTY) break; {  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; } return 1; }     static struct dcache_block * dcache_alloc (dcache) DCACHE *dcache; { register struct dcache_block *db;  if (remote_dcache == 0) abort ();
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));int remote_dcache = 0;DCACHE *last_cache; /* Used by info dcache *//* Free all the data cache blocks, thus discarding all cached data.  */voiddcache_flush (dcache)     DCACHE *dcache;{  int i;  dcache->valid_head = 0;  dcache->valid_tail = 0;  dcache->free_head = 0;  dcache->free_tail = 0;  for (i = 0; i < DCACHE_SIZE; i++)    {      struct dcache_block *db = dcache->the_cache + i;      if (!dcache->free_head)	dcache->free_head = db;      else	dcache->free_tail->p = db;      dcache->free_tail = db;      db->p = 0;    }  dcache->cache_has_stuff = 0;  return;}/* If addr is present in the dcache, return the address of the block   containing it. */static struct dcache_block *dcache_hit (dcache, addr)     DCACHE *dcache;     CORE_ADDR addr;{  register struct dcache_block *db;  /* Search all cache blocks for one that is at this address.  */  db = dcache->valid_head;  while (db)    {      if (MASK(addr) == db->addr)	{	  db->refs++;	  return db;	}      db = db->p;    }  return NULL;}/* Make sure that anything in this line which needs to   be written is. */static intdcache_write_line (dcache, db)     DCACHE *dcache;     register struct dcache_block *db;{  int s;  int e;  s = 0;  if (db->anydirty)    {      for (s = 0; s < LINE_SIZE; s++)	{	  if (db->state[s] == ENTRY_DIRTY)	    {	      int len = 0;	      for (e = s ; e < LINE_SIZE; e++, len++)		if (db->state[e] != ENTRY_DIRTY)		  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;    }  return 1;}/* 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 memory retrieval is   interrupted (which used to put garbage blocks in the valid   list...).  */static struct dcache_block *dcache_alloc (dcache)     DCACHE *dcache;{  register struct dcache_block *db;  if (remote_dcache == 0)    abort ();  /* Take something from the free list */  db = dcache->free_head;  if (db)    {      dcache->free_head = db->p;    }  else    {      /* 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);    }  /* append this line to end of valid list */  if (!dcache->valid_head)    dcache->valid_head = db;  else    dcache->valid_tail->p = db;  dcache->valid_tail = db;  db->p = 0;  return db;}