linux-mips
[Top] [All Lists]

Re: [patch] pg-r4k.c bugs for R4k systems with a secondary cache

To: Ralf Baechle <ralf@linux-mips.org>
Subject: Re: [patch] pg-r4k.c bugs for R4k systems with a secondary cache
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Date: Tue, 27 Jan 2004 12:09:49 +0100 (CET)
Cc: linux-mips@linux-mips.org
In-reply-to: <Pine.LNX.4.55.0401261731370.26076@jurand.ds.pg.gda.pl>
Organization: Technical University of Gdansk
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <Pine.LNX.4.55.0401261731370.26076@jurand.ds.pg.gda.pl>
Sender: linux-mips-bounce@linux-mips.org
On Mon, 26 Jan 2004, Maciej W. Rozycki wrote:

>  This patch fixes a bug in build_cdex() that makes the function invoke the
> Create Dirty Exclusive command for the D-cache when a secondary cache is
> present.  This is unnecessary as the Create Dirty Exclusive command for
> the S-cache acts upon the D-cache appropriately and (for reasons yet to be
> investigated) using the command on the D-cache directly leads to memory
> corruption on my R4400SC system.  With the patch the system appears
> stable.
> 
>  The patch also removes references to has_scache which currently disable 
> code for the S-cache line size of 128 bytes as the variable is always 0.

 Here is a somewhat better version.  It's functionally equivalent.  OK to 
apply?

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.24-pre2-20040116-mips-pg-r4k-scache-1
diff -up --recursive --new-file 
linux-mips-2.4.24-pre2-20040116.macro/arch/mips/mm/pg-r4k.c 
linux-mips-2.4.24-pre2-20040116/arch/mips/mm/pg-r4k.c
--- linux-mips-2.4.24-pre2-20040116.macro/arch/mips/mm/pg-r4k.c 2004-01-03 
03:56:38.000000000 +0000
+++ linux-mips-2.4.24-pre2-20040116/arch/mips/mm/pg-r4k.c       2004-01-26 
23:55:43.000000000 +0000
@@ -67,7 +67,6 @@ static int pref_offset_copy  __initdata 
 static unsigned int pref_src_mode __initdata;
 static unsigned int pref_dst_mode __initdata;
 
-static int has_scache __initdata = 0;
 static int load_offset __initdata = 0;
 static int store_offset __initdata = 0;
 
@@ -126,21 +125,25 @@ static inline void build_dst_pref(int ad
        }
 }
 
-static inline void build_cdex(void)
+static inline void build_cdex_s(void)
 {
        union mips_instruction mi;
 
-       if (cpu_has_cache_cdex_s &&
-           !(store_offset & (cpu_scache_line_size() - 1))) {
+       if ((store_offset & (cpu_scache_line_size() - 1)))
+               return;
 
-               mi.c_format.opcode     = cache_op;
-               mi.c_format.rs         = 4;     /* $a0 */
-               mi.c_format.c_op       = 3;     /* Create Dirty Exclusive */
-               mi.c_format.cache      = 3;     /* Secondary Data Cache */
-               mi.c_format.simmediate = store_offset;
+       mi.c_format.opcode     = cache_op;
+       mi.c_format.rs         = 4;             /* $a0 */
+       mi.c_format.c_op       = 3;             /* Create Dirty Exclusive */
+       mi.c_format.cache      = 3;             /* Secondary Data Cache */
+       mi.c_format.simmediate = store_offset;
 
-               *epc++ = mi.word;
-       }
+       *epc++ = mi.word;
+}
+
+static inline void build_cdex_p(void)
+{
+       union mips_instruction mi;
 
        if (store_offset & (cpu_dcache_line_size() - 1))
                return;
@@ -212,8 +215,10 @@ static inline void build_store_reg(int r
                        build_dst_pref(pref_offset_copy);
                else
                        build_dst_pref(pref_offset_clear);
+       else if (cpu_has_cache_cdex_s)
+               build_cdex_s();
        else if (cpu_has_cache_cdex_p)
-               build_cdex();
+               build_cdex_p();
 
        __build_store_reg(reg);
 }
@@ -332,7 +337,7 @@ dest = epc;
        build_store_reg(0);
        build_store_reg(0);
        build_store_reg(0);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_store_reg(0);
                build_store_reg(0);
                build_store_reg(0);
@@ -341,7 +346,7 @@ dest = epc;
        build_addiu_a0(2 * store_offset);
        build_store_reg(0);
        build_store_reg(0);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_store_reg(0);
                build_store_reg(0);
                build_store_reg(0);
@@ -405,7 +410,7 @@ dest = epc;
        build_store_reg( 9);
        build_store_reg(10);
        build_store_reg(11);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_load_reg( 8);
                build_load_reg( 9);
                build_load_reg(10);
@@ -424,7 +429,7 @@ dest = epc;
        build_store_reg( 8);
        build_store_reg( 9);
        build_store_reg(10);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_store_reg(11);
                build_load_reg( 8);
                build_load_reg( 9);
diff -up --recursive --new-file 
linux-mips-2.4.24-pre2-20040116.macro/arch/mips64/mm/pg-r4k.c 
linux-mips-2.4.24-pre2-20040116/arch/mips64/mm/pg-r4k.c
--- linux-mips-2.4.24-pre2-20040116.macro/arch/mips64/mm/pg-r4k.c       
2004-01-03 03:56:46.000000000 +0000
+++ linux-mips-2.4.24-pre2-20040116/arch/mips64/mm/pg-r4k.c     2004-01-26 
23:55:43.000000000 +0000
@@ -67,7 +67,6 @@ static int pref_offset_copy  __initdata 
 static unsigned int pref_src_mode __initdata;
 static unsigned int pref_dst_mode __initdata;
 
-static int has_scache __initdata = 0;
 static int load_offset __initdata = 0;
 static int store_offset __initdata = 0;
 
@@ -126,21 +125,25 @@ static inline void build_dst_pref(int ad
        }
 }
 
-static inline void build_cdex(void)
+static inline void build_cdex_s(void)
 {
        union mips_instruction mi;
 
-       if (cpu_has_cache_cdex_s &&
-           !(store_offset & (cpu_scache_line_size() - 1))) {
+       if ((store_offset & (cpu_scache_line_size() - 1)))
+               return;
 
-               mi.c_format.opcode     = cache_op;
-               mi.c_format.rs         = 4;     /* $a0 */
-               mi.c_format.c_op       = 3;     /* Create Dirty Exclusive */
-               mi.c_format.cache      = 3;     /* Secondary Data Cache */
-               mi.c_format.simmediate = store_offset;
+       mi.c_format.opcode     = cache_op;
+       mi.c_format.rs         = 4;             /* $a0 */
+       mi.c_format.c_op       = 3;             /* Create Dirty Exclusive */
+       mi.c_format.cache      = 3;             /* Secondary Data Cache */
+       mi.c_format.simmediate = store_offset;
 
-               *epc++ = mi.word;
-       }
+       *epc++ = mi.word;
+}
+
+static inline void build_cdex_p(void)
+{
+       union mips_instruction mi;
 
        if (store_offset & (cpu_dcache_line_size() - 1))
                return;
@@ -212,8 +215,10 @@ static inline void build_store_reg(int r
                        build_dst_pref(pref_offset_copy);
                else
                        build_dst_pref(pref_offset_clear);
+       else if (cpu_has_cache_cdex_s)
+               build_cdex_s();
        else if (cpu_has_cache_cdex_p)
-               build_cdex();
+               build_cdex_p();
 
        __build_store_reg(reg);
 }
@@ -332,7 +337,7 @@ dest = epc;
        build_store_reg(0);
        build_store_reg(0);
        build_store_reg(0);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_store_reg(0);
                build_store_reg(0);
                build_store_reg(0);
@@ -341,7 +346,7 @@ dest = epc;
        build_addiu_a0(2 * store_offset);
        build_store_reg(0);
        build_store_reg(0);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_store_reg(0);
                build_store_reg(0);
                build_store_reg(0);
@@ -405,7 +410,7 @@ dest = epc;
        build_store_reg( 9);
        build_store_reg(10);
        build_store_reg(11);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_load_reg( 8);
                build_load_reg( 9);
                build_load_reg(10);
@@ -424,7 +429,7 @@ dest = epc;
        build_store_reg( 8);
        build_store_reg( 9);
        build_store_reg(10);
-       if (has_scache && cpu_scache_line_size() == 128) {
+       if (cpu_scache_line_size() == 128) {
                build_store_reg(11);
                build_load_reg( 8);
                build_load_reg( 9);

<Prev in Thread] Current Thread [Next in Thread>