This is the mail archive of the sid@sources.redhat.com mailing list for the SID project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] hw-cache: new pins


Hi,

The attached patch adds two pins:

flush-and-invalidate
flush-and-invalidate-set

to the hw-cache component. These supplement the existing flushing and invalidating pins by providing atomic "flush and invalidate" operations. This is necessary for some architectures which require such an operation and require it to be a nop if the selected line is clean. In this case, the existing sequential flush+invalidate still results in an invalidated line and invalidate+flush fails because it causes a cache miss on the "flush" step.

The patch also fixes a bug in cache_component::flush_set which was flushing the selected line even when it was already clean.

Approved by bje and committed.

Dave
2002-07-16  Dave Brolley  <brolley@redhat.com>

	* cache.h (cache): Add flush_and_invalidate_set_pin and
	flush_and_invalidate_pin.
	* cache.cxx (cache_component): Initialize flush_and_invalidate_set_pin
	and flush_and_invalidate_pin. Add flush-and-invalidate and
	flush-and-invalidate-set pins.
	(flush_set): Don't flush an invalid line.
	(flush_and_invalidate_set): New method.
	(flush_and_invalidate_line): New method.
	* hw-cache.xml, hw-cache.txt: Modified accordingly.

Index: sid/component/cache/cache.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cache.cxx,v
retrieving revision 1.14
diff -c -p -r1.14 cache.cxx
*** sid/component/cache/cache.cxx	8 Jun 2002 20:33:18 -0000	1.14
--- sid/component/cache/cache.cxx	16 Jul 2002 19:10:34 -0000
*************** cache_component::cache_component (unsign
*** 55,63 ****
--- 55,65 ----
     flush_all_pin (this, &cache_component::flush_all_lines),
     flush_pin (this, &cache_component::flush_line),
     flush_set_pin (this, &cache_component::flush_set),
+    flush_and_invalidate_set_pin (this, &cache_component::flush_and_invalidate_set),
     invalidate_all_pin (this, &cache_component::invalidate_all_lines),
     invalidate_pin (this, &cache_component::invalidate_line),
     invalidate_set_pin (this, &cache_component::invalidate_set),
+    flush_and_invalidate_pin (this, &cache_component::flush_and_invalidate_line),
     prefetch_pin (this, &cache_component::prefetch_line),
     lock_pin (this, &cache_component::lock_line),
     unlock_pin (this, &cache_component::unlock_line),
*************** cache_component::cache_component (unsign
*** 83,89 ****
--- 85,93 ----
    add_pin ("flush", &flush_pin);
    add_pin ("invalidate-all", &invalidate_all_pin);
    add_pin ("invalidate-set", &invalidate_set_pin);
+   add_pin ("flush-and-invalidate-set", &flush_and_invalidate_set_pin);
    add_pin ("invalidate", &invalidate_pin);
+   add_pin ("flush-and-invalidate", &flush_and_invalidate_pin);
    add_pin ("prefetch", &prefetch_pin);
    add_pin ("lock", &lock_pin);  
    add_pin ("unlock", &unlock_pin);
*************** cache_component::flush_set (host_int_4 i
*** 391,402 ****
    for (unsigned i = 0; i < set.num_lines(); i++)
      {
        cache_line& line = set [i];
!       if (line.dirty_p ())
  	(void) write_line (line);
      }
  }
  
  void
  cache_component::invalidate_all_lines (host_int_4 ignore)
  {
    acache.invalidate ();
--- 395,424 ----
    for (unsigned i = 0; i < set.num_lines(); i++)
      {
        cache_line& line = set [i];
!       if (line.valid_p () && line.dirty_p ())
  	(void) write_line (line);
      }
  }
  
  void
+ cache_component::flush_and_invalidate_set (host_int_4 index)
+ {
+   if (index >= acache.num_sets ())
+     return; // bad value
+ 
+   cache_set& set = acache [index];
+   for (unsigned i = 0; i < set.num_lines(); i++)
+     {
+       cache_line& line = set [i];
+       if (line.valid_p () && line.dirty_p ())
+ 	{
+ 	  (void) write_line (line);
+ 	  line.invalidate ();
+ 	}
+     }
+ }
+ 
+ void
  cache_component::invalidate_all_lines (host_int_4 ignore)
  {
    acache.invalidate ();
*************** cache_component::invalidate_line (host_i
*** 409,414 ****
--- 431,448 ----
    cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
    if (hit)
      line.invalidate ();
+ }
+ 
+ void
+ cache_component::flush_and_invalidate_line (host_int_4 addr)
+ {
+   bool hit;
+   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
+   if (hit && line.dirty_p ())
+     {
+       (void) write_line (line);
+       line.invalidate ();
+     }
  }
  
  void
Index: sid/component/cache/cache.h
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cache.h,v
retrieving revision 1.7
diff -c -p -r1.7 cache.h
*** sid/component/cache/cache.h	8 Jun 2002 20:33:18 -0000	1.7
--- sid/component/cache/cache.h	16 Jul 2002 19:10:34 -0000
*************** private:
*** 134,144 ****
--- 134,150 ----
    callback_pin<cache_component> flush_set_pin;
    void flush_set (host_int_4 set);
  
+   callback_pin<cache_component> flush_and_invalidate_set_pin;
+   void flush_and_invalidate_set (host_int_4 set);
+ 
    callback_pin<cache_component> invalidate_all_pin;
    void invalidate_all_lines (host_int_4 ignore);
  
    callback_pin<cache_component> invalidate_pin;
    void invalidate_line (host_int_4 addr);
+ 
+   callback_pin<cache_component> flush_and_invalidate_pin;
+   void flush_and_invalidate_line (host_int_4 addr);
  
    callback_pin<cache_component> invalidate_set_pin;
    void invalidate_set (host_int_4 set);
Index: sid/component/cache/hw-cache.xml
===================================================================
RCS file: /cvs/src/src/sid/component/cache/hw-cache.xml,v
retrieving revision 1.7
diff -c -p -r1.7 hw-cache.xml
*** sid/component/cache/hw-cache.xml	8 Jun 2002 20:33:18 -0000	1.7
--- sid/component/cache/hw-cache.xml	16 Jul 2002 19:10:35 -0000
***************
*** 18,23 ****
--- 18,25 ----
      <defpin name="invalidate" direction="in" legalvalues="32-bit address" behaviors="invalidating" />
      <defpin name="invalidate-all" direction="in" legalvalues="any" behaviors="invalidating" />
      <defpin name="invalidate-set" direction="in" legalvalues="set index" behaviors="invalidating" />
+     <defpin name="flush-and-invalidate" direction="in" legalvalues="32-bit address" behaviors="flushing, invalidating" />
+     <defpin name="fluish-and-invalidate-set" direction="in" legalvalues="set index" behaviors="flushing, invalidating" />
      <defpin name="prefetch" direction="in" legalvalues="32-bit address" behaviors="prefetching" />
      <defpin name="lock" direction="in" legalvalues="32-bit address" behaviors="line locking" />
      <defpin name="unlock" direction="in" legalvalues="32-bit address" behaviors="line locking" />
***************
*** 160,166 ****
  	a line to memory.  For this purpose, the component provides
  	<pin>flush</pin> which can be driven with an address.  If the
  	address falls on a line that is present and dirty, it will be
! 	flushed to memory and marked as not dirty.  The entire cache
          can be flushed by driving <pin>flush-all</pin>.</p>
      </behavior>
  
--- 162,170 ----
  	a line to memory.  For this purpose, the component provides
  	<pin>flush</pin> which can be driven with an address.  If the
  	address falls on a line that is present and dirty, it will be
! 	flushed to memory and marked as not dirty.  A line can be
! 	flushed and invalidated in one atomic operation by driving the
! 	<pin>flush-and-invalidate</pin> pin.  The entire cache
          can be flushed by driving <pin>flush-all</pin>.</p>
      </behavior>
  
***************
*** 174,180 ****
  	with an address.  If the address falls on a line that is
  	present, it will be invalidated.  No consideration is made for
  	dirty lines, so a line should be flushed before being
! 	invalidated.  The entire cache can be invalidated by driving
  	<pin>invalidate-all</pin>.</p>
      </behavior>
  
--- 178,186 ----
  	with an address.  If the address falls on a line that is
  	present, it will be invalidated.  No consideration is made for
  	dirty lines, so a line should be flushed before being
! 	invalidated.  A line can be flushed and invalidated in one
! 	atomic operation by driving the <pin>flush-and-invalidate</pin>
! 	pin.  The entire cache can be invalidated by driving
  	<pin>invalidate-all</pin>.</p>
      </behavior>
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]