예제 #1
0
파일: cache.c 프로젝트: 01hyang/u-boot
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);
}
예제 #2
0
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;
}
예제 #3
0
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);
      }
}
예제 #4
0
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;
    }
}