Ejemplo n.º 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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 3
0
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;

  len = LINE_SIZE;
  memaddr = db->addr;
  myaddr  = db->data;

  while (len > 0)
    {
      /* Don't overrun if this block is right at the end of the region.  */
      region = lookup_mem_region (memaddr);
      if (region->hi == 0 || memaddr + len < region->hi)
	reg_len = len;
      else
	reg_len = region->hi - memaddr;

      /* Skip non-readable regions.  The cache attribute can be ignored,
         since we may be loading this for a stack access.  */
      if (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;
    }

  return 1;
}
Ejemplo n.º 4
0
static int
dcache_write_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 (!db->anydirty)
    return 1;

  len = LINE_SIZE;
  memaddr = db->addr;
  myaddr  = db->data;

  while (len > 0)
    {
      int s;
      int e;
      int dirty_len;
      
      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_RO)
	{
	  memaddr += reg_len;
	  myaddr  += reg_len;
	  len     -= reg_len;
	  continue;
	}

      while (reg_len > 0)
	{
	  s = XFORM(memaddr);
	  while (reg_len > 0) {
	    if (db->state[s] == ENTRY_DIRTY)
	      break;
	    s++;
	    reg_len--;

	    memaddr++;
	    myaddr++;
	    len--;
	  }

	  e = s;
	  while (reg_len > 0) {
	    if (db->state[e] != ENTRY_DIRTY)
	      break;
	    e++;
	    reg_len--;
	  }

	  dirty_len = e - s;
	  while (dirty_len > 0)
	    {
	      res = do_xfer_memory(memaddr, myaddr, dirty_len, 1,
				   &region->attrib);
	      if (res <= 0)
		return 0;

	      memset (&db->state[XFORM(memaddr)], ENTRY_OK, res);
	      memaddr   += res;
	      myaddr    += res;
	      len       -= res;
	      dirty_len -= res;
	    }
	}
    }

  db->anydirty = 0;
  return 1;
}
Ejemplo n.º 5
0
static int
dcache_write_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 (!db->anydirty)
    return 1;

  len = LINE_SIZE;
  memaddr = db->addr;
  myaddr  = db->data;

  while (len > 0)
    {
      int s;
      int e;
      int dirty_len;
      
      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_RO)
	{
	  memaddr += reg_len;
	  myaddr  += reg_len;
	  len     -= reg_len;
	  continue;
	}

      while (reg_len > 0)
	{
	  s = XFORM(memaddr);
	  while (reg_len > 0) {
	    if (db->state[s] == ENTRY_DIRTY)
	      break;
	    s++;
	    reg_len--;

	    memaddr++;
	    myaddr++;
	    len--;
	  }

	  e = s;
	  while (reg_len > 0) {
	    if (db->state[e] != ENTRY_DIRTY)
	      break;
	    e++;
	    reg_len--;
	  }

	  dirty_len = e - s;
	  res = target_write (&current_target, TARGET_OBJECT_RAW_MEMORY,
			      NULL, myaddr, memaddr, dirty_len);
	  if (res < dirty_len)
	    return 0;

	  memset (&db->state[XFORM(memaddr)], ENTRY_VALID, res);
	  memaddr += res;
	  myaddr += res;
	  len -= res;
	}
    }

  db->anydirty = 0;
  return 1;
}