Пример #1
0
/* Read cache line */
static int
dcache_read_line (DCACHE *dcache, struct dcache_block *db)
{
  CORE_ADDR memaddr;
  gdb_byte *myaddr;
  int len;
  int res;
  int reg_len;
  struct mem_region *region;

  /* 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)
    {
      region = lookup_mem_region(memaddr);
      if (memaddr + len < region->hi)
	reg_len = len;
      else
	reg_len = region->hi - memaddr;

      if (!region->attrib.cache || region->attrib.mode == MEM_WO)
	{
	  memaddr += reg_len;
	  myaddr  += reg_len;
	  len     -= reg_len;
	  continue;
	}
      
      while (reg_len > 0)
	{
	  res = do_xfer_memory (memaddr, myaddr, reg_len, 0,
				&region->attrib);
	  if (res <= 0)
	    return 0;

	  memaddr += res;
	  myaddr  += res;
	  len     -= res;
	  reg_len -= res;
	}
    }

  memset (db->state, ENTRY_OK, sizeof (db->data));
  db->anydirty = 0;
  
  return 1;
}
Пример #2
0
/* Read cache line */
static int
dcache_read_line (DCACHE *dcache, struct dcache_block *db)
{
  CORE_ADDR memaddr;
  gdb_byte *myaddr;
  int len;
  int res;
  int reg_len;
  struct mem_region *region;

  /* 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)
    {
      region = lookup_mem_region(memaddr);
      if (memaddr + len < region->hi)
	reg_len = len;
      else
	reg_len = region->hi - memaddr;

      if (!region->attrib.cache || region->attrib.mode == MEM_WO)
	{
	  memaddr += reg_len;
	  myaddr  += reg_len;
	  len     -= reg_len;
	  continue;
	}
      
      res = target_read (&current_target, TARGET_OBJECT_RAW_MEMORY,
			 NULL, myaddr, memaddr, reg_len);
      if (res < reg_len)
	return 0;

      memaddr += res;
      myaddr += res;
      len -= res;
    }

  memset (db->state, ENTRY_VALID, sizeof (db->data));
  db->anydirty = 0;
  
  return 1;
}
Пример #3
0
/* Writeback any dirty lines. */
static int
dcache_writeback (DCACHE *dcache)
{
  struct dcache_block *db;

  db = dcache->valid_head;

  while (db)
    {
      if (!dcache_write_line (dcache, db))
	return 0;
      db = db->p;
    }
  return 1;
}
Пример #4
0
static struct dcache_block *
dcache_alloc (DCACHE *dcache, CORE_ADDR addr)
{
  struct dcache_block *db;

  /* 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;

      if (!dcache_write_line (dcache, db))
	return NULL;
      
      dcache->valid_head = db->p;
    }

  db->addr = MASK(addr);
  db->refs = 0;
  db->anydirty = 0;
  memset (db->state, ENTRY_BAD, sizeof (db->data));

  /* 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;
}