Subject: Strange, strange occurence

From: "S C" <[email-masked]>
Date: Fri, 09 Jul 2004 18:50:00 +0000

Well I'm hoping it isn't so strange to some of you folks and you'll be able 
to tell what's going on :)

Here's my problem:

Using MontaVista Linux 3.1 on a Toshiba RBTx4938 board. Using YAMON, when I 
download the kernel via the debug ethernet port it runs fine. If I download 
the kernel via the Tx4938 inbuilt ethernet controller, it crashes!

Memory checksumming and a quick manual memory dump inspection reveals that 
the kernel download went perfectly ok, and the image is completely and 
correctly downloaded to RAM.

The crash is occuring inside the function r4k_flush_icache_range().

I tried 'flush -i' and 'flush -d' on YAMON after the download but before the 
'go', but that didn't help. I also tried completely disabling caches and 
loading/running uncached, but it gave the same error.

Now, the final twist! Using an ICE, I set a breakpoint at the 
r4k_flush_icache_range function. Then I loaded the kernel as usual, ran it 
with the ICE, stepped through a few instructions inside the 
r4k_flush_icache_range function and then did a 'cont'. The kernel now booted 
fine!

If I don't set the breakpoint inside that function though, and just try to 
run with the ICE the same
error (Inst fetch/Load error) occurs.

I'm at a loss trying to figure out what's going on. I suspect it has 
something to do with caches perhaps (duh!), but have no clue what!  Anybody 
out there face a similar kind of a situation before?

Thanks in advance for any help offered.

Regards,
-Steve

_________________________________________________________________
MSN 9 Dial-up Internet Access helps fight spam and pop-ups – now 2 months 
FREE! http://join.msn.click-url.com/go/onm00200361ave/direct/01/

---

From: "Niels Sterrenburg" <[email-masked]>
Date: Sat, 10 Jul 2004 09:33:57 +0200 (CEST)

Hi Steve,

When you set a breakpoint with the ice and step through,
for each step the ICE set's a breakpoint on the next instruction:
e.g.:
- modifies next instruction in memory (via CPU !!!)
  with a breakpoint instruction,
- and update the cache so that the breakpoint instruction is really in
memory and that i-cache is invalid.
(or something like that)

So indead you have a cache problem which is explanable solved/disapeared
by steppig through with the ICE.

Maybe a stupid question from me but why flushing an icache ?:
r4k_flush_icache_range

regards,

Niels

---

From: Ralf Baechle <[email-masked]>
Date: Sat, 10 Jul 2004 12:04:12 +0200

> the kernel via the Tx4938 inbuilt ethernet controller, it crashes!

If you're using a Montavista kernel you should report to Montavista.  We
don't have the source so any comment here is speculation.

> I tried 'flush -i' and 'flush -d' on YAMON after the download but before 
> the 'go', but that didn't help. I also tried completely disabling caches 
> and loading/running uncached, but it gave the same error.
> 
> r4k_flush_icache_range function and then did a 'cont'. The kernel now 
> booted fine!

As already pointed out by the other poster Niels Sterrenburg using a
debugger unavoidably changes the state of the system to be debugged.

For at least some of the TX49xx processors there is a problem under certain
circumstances if a flush of an I-cache line flushes that cache instruction
itself.  Make sure you're not getting hit by that one.

  Ralf

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Mon, 12 Jul 2004 17:16:31 +0200

[snip]
> itself.  Make sure you're not getting hit by that one.

It's not just the TX49xx series.  While many MIPS-compatible processors 
do handle the special case of flushing the active CACHE instruction itself, 
not all of them do, and the MIPS32 spec calls it out as having an "UNPREDICTABLE"
result.

A truly safe and general I-cache flush routine should itself run uncached,
but a cursory glance at the linux-mips.org sources makes me think
that we do not take that precaution by default - the flush_icache_range
pointer looks to be set to the address of r4k_flush_icache_range()
function, rather than its (uncacheable) alias in kseg1.  Is this something
that's fixed in a linker script, or are we just living dangerously?

            Regards,

            Kevin K.

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 13 Jul 2004 02:33:17 +0200

> that's fixed in a linker script, or are we just living dangerously?

That's a new restriction in MIPS32 v2.0 and you're right, we're not trying
to deal with it yet except for the TX49xx.

  Ralf

---

From: "Collin Baillie" <[email-masked]>
Date: Tue, 13 Jul 2004 15:49:30 +0800

Hi Guys,

I'm trying to install linux-mips on a DECsation 5000/240 I have in my
posession. It has the 5.1b rom so tftp boot is apparently out.

I've setup mopd on a linux (i386) box here and I'm getting the following on
my DECstation:

>>boot 3/mop

???
? PC:  0xa0010aa4<vtr=UTLBM>
? CR:  0x8000200c<BD,CE=0,IP6,EXC=TLBS>
? SR:  0x30080000<CU1,CU0,CM,IPL=8>
? VA:  0x1000
? ER: 0xe7d43000<VALID,CPU,WRITE,ADR=1F50C000>
? CK: 0xef00ffe2<VLDHI,CHKHI=6F,SYNHI=0,VLDLO,CHKLO=7F,SNGLO,SYNLO=62>

In /var/log/messages I'm seeing:

Jul 13 15:44:36 phoenix mopd[10437]: 8:0:2b:2a:fe:c0 (1) Do you have
08002b2afec0? (Yes)
Jul 13 15:44:36 phoenix mopd[10437]: 8:0:2b:2a:fe:c0 Send me 08002b2afec0

and using moptrace I get the following:

Dst          : ab:0:0:1:0:0      MOP Dump/Load Multicast
Src          : 8:0:2b:2a:fe:c0
Proto        : 6001 MOP Dump/Load
Length       : 000b (11)
Code         :   08 Request program
Device Type  :   76 MNE '3MIN (KN02-BA)'
Format       :   01
Program Type :   02 Operating System
Software     :   00 ''
Processor    :   00 System Processor
DL Buff Size : 041c (1052)

Dst          : ab:0:0:2:0:0      MOP Remote Console Multicast
Src          : 8:0:2b:2a:fe:c0
Proto        : 6002 MOP Remote Console
Length       : 001c (28)
Code         :   07 System ID
Reserved     :   00
Receipt Nbr  : 0000
Hardware Addr: 8:0:2b:2a:fe:c0
Maint Version: 3.0.0
Maint Funcion: 004b ( Loop Dump MLdr DLC )
Comm Device  :   76 MNE '3MIN (KN02-BA)'

Dst          : 0:80:ad:72:e3:6f
Src          : 8:0:2b:2a:fe:c0
Proto        : 6001 MOP Dump/Load
Length       : 000b (11)
Code         :   08 Request program
Device Type  :   76 MNE '3MIN (KN02-BA)'
Format       :   01
Program Type :   02 Operating System
Software     :   00 ''
Processor    :   00 System Processor
DL Buff Size : 041c (1052)

Dst          : 0:80:ad:72:e3:6f
Src          : 8:0:2b:2a:fe:c0
Proto        : 6001 MOP Dump/Load
Length       : 0002 (2)
Code         :   0a Request memory load
Load Number  :   01
Error        :   00 (no error)

Dst          : 0:80:ad:72:e3:6f
Src          : 8:0:2b:2a:fe:c0
Proto        : 6001 MOP Dump/Load
Length       : 0002 (2)
Code         :   0a Request memory load
Load Number  :   02
Error        :   00 (no error)

Dst          : 0:80:ad:72:e3:6f
Src          : 8:0:2b:2a:fe:c0
Proto        : 6001 MOP Dump/Load
Length       : 0002 (2)
Code         :   0a Request memory load
Load Number  :   03
Error        :   00 (no error)

I've tried with both the ecoff and the elf kernels (2.4.18) listed on
Karel's web pages.

I was wondering if anyone on the list has had any success installing via MOP
onto a DECstation 5000/240 and would be able to offer me any assistance.

Cheers,

Collin Baillie

---

From: Jan-Benedict Glaw <[email-masked]>
Date: Tue, 13 Jul 2004 10:03:21 +0200

On Tue, 2004-07-13 15:49:30 +0800, Collin Baillie <[email-masked]>
wrote in message <000701c468ae$141c3e50$0a9913ac@swift>:

[Thanks for *not* hijacking threads]

> I've setup mopd on a linux (i386) box here and I'm getting the following on
[...]
> I've tried with both the ecoff and the elf kernels (2.4.18) listed on

So it seems to try to get a file some times and gives up on it.

> onto a DECstation 5000/240 and would be able to offer me any assistance.

Maybe you'd try Debian's install image?

By the way, which mopd are you using? There are several of them around,
some quite unuseable...

MfG, JBG

-- 
   Jan-Benedict Glaw       [email-masked]    . +49-172-7608481
   "Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg
    fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!
   ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Tue, 13 Jul 2004 17:31:42 +0200

> to deal with it yet except for the TX49xx.

I'm pretty sure that restriction is not new to MIPS32 v2.0.  In any
case, there are pre-MIPS32/MIPS64 chips in current mass production
and use, under Linux among other OSes, which specify in their user
manuals that one should not invalidate the Icache line from which one
is currently executing.  The clause about unpredictable behavior in
that case went into the MIPS32 spec because it was known that such
parts existed, and we wanted to make it as easy as possible for such 
designs to be made compliant

Invalidating the entire Icache with a routine executing out of the Icache
is a Bad Idea, and will almost certainly cause problems some of the time
on some MIPS processors.  Reasonable people could disagree on whether
we want to handle that in the generic code, or create a variant icache flush 
routine which gets plugged in only for those parts that really need it.

            Regards,

            Kevin K.

---

From: "Collin Baillie" <[email-masked]>
Date: Wed, 14 Jul 2004 14:57:52 +0800

> [Thanks for *not* hijacking threads]

Sorry *blush*

> So it seems to try to get a file some times and gives up on it.

Oh.. I think it asks for the file, but the mopd server is not sending it. I
am only guessing though.

> Maybe you'd try Debian's install image?

Maybe, but on a _shared_ 31.2k dialup link, it takes a while to download...
and other people tend to get upset... I am using jigdo to get the 4 - 6 ISO
images.. if there's a better (smaller / faster to download) method, I'd love
to hear about it. I really would like to get to know Debian as I'm a
Slackware man and have had to use RedHat at work.. Debian would be another
nice addition to my Linux skillset.

> By the way, which mopd are you using? There are several of them around,

Umm.. 2.5.3. I downloaded one from linux-mips.org, and applied all the
patches in the order listed in the spec file, but it doesn't compile. So I
compiled another 2.5.3 (79k as opposed to the 48k tgz file I got from
linux-mips.org) and it compiles and responds, but still no file transfer. (I
am compiling/running on i386 arch, so I am wondering if all those patches
are necessary...)

I've read that MOP images usually have some special header in them (NetBSD
website) and someone mentioned that mopd-linux will fudge those headers if
the kernel doesn't have them... or something...

I am perservering with it, and will eventually get there... but for now, I
just thought someone might have more of a clue than I do.

Thanks,

Collin Baillie

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Wed, 14 Jul 2004 11:54:23 +0200 (CEST)

> Oh.. I think it asks for the file, but the mopd server is not sending it. I

 It looks so.  You may try to verify with `tcpdump', too.

> patches in the order listed in the spec file, but it doesn't compile. So I

 Hmm, there's no mopd at linux-mips.org.  Do you refer to one at my site,
i.e. "ftp://ftp.ds2.pg.gda.pl/pub/macro/"?  If so, then please report
compiler errors to me.

> am compiling/running on i386 arch, so I am wondering if all those patches

 They are.  They are not processor-dependent.

> the kernel doesn't have them... or something...

 You've been misled.  The MOP protocol sends raw data annotated with
addresses.  It's up to the MOP server to obtain both of them.  For example
they can be retrieved from ordinary ELF images.

> just thought someone might have more of a clue than I do.

 Try running `mopchk <your-image-file>' to check if it's interpreted 
correctly.

  Maciej

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Wed, 14 Jul 2004 14:02:15 +0200 (CEST)

> I'm pretty sure that restriction is not new to MIPS32 v2.0.  In any

 The restriction was apparently added in revision 1.00 of the MIPS32
architecture vol.II document.  I don't have that revision -- I have
versions 0.95 and 2.00 only -- without looking at the revision history in
2.00 I'd expect the original MIPS32 spec not to enforce such a
restriction, either.

> designs to be made compliant

 Ugh, although I can imagine valid arguments for such a decision.

> routine which gets plugged in only for those parts that really need it.

 As executing code from an uncached space is terribly slow, there are at
least two points of optimization:

1. The Icache invalidation handler should run cached on processors known
to handle it gracefully.

2. For others, as you suggest, it should attempt to figure out whether its
code may invalidate itself and run uncached then, perhaps for the
problematic lines only.

  Maciej

---

From: Jan-Benedict Glaw <[email-masked]>
Date: Wed, 14 Jul 2004 14:43:18 +0200

On Wed, 2004-07-14 14:57:52 +0800, Collin Baillie <[email-masked]>
> and other people tend to get upset... I am using jigdo to get the 4 - 6 ISO

It's only a couple of megabytes, not a number of CD images.

> the kernel doesn't have them... or something...

Right, eg. Maciej's MOPD does that.

MfG, JBG

---

From: Jan-Benedict Glaw <[email-masked]>
Date: Wed, 14 Jul 2004 14:44:35 +0200

On Wed, 2004-07-14 11:54:23 +0200, Maciej W. Rozycki <[email-masked]>
> i.e. "ftp://ftp.ds2.pg.gda.pl/pub/macro/"?  If so, then please report

While we are at it. I'll have to re-verify that, but my mopd is loosing
file descriptors if you ^A-F your box during a load.

MfG, JBG

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Wed, 14 Jul 2004 14:51:35 +0200 (CEST)

> file descriptors if you ^A-F your box during a load.

 Hmm, while I get what you mean, what is "^A-F" specifically?

 Anyway, this may be true -- probably the server is still waiting for
following requests to come.  A timeout might be a good thing to add.  
Unfortunately I don't have time to work on mopd ATM.  It would be good to
do a serious rewrite and I plan to do that in the future.  No established 
plan, though.

 Another problem which is already known is mopd dying when one of
interfaces it's listening on goes down.

  Maciej

---

From: Jan-Benedict Glaw <[email-masked]>
Date: Wed, 14 Jul 2004 15:30:39 +0200

On Wed, 2004-07-14 14:51:35 +0200, Maciej W. Rozycki <[email-masked]>
>  Hmm, while I get what you mean, what is "^A-F" specifically?

Sending a break from minicom :)   That is, I just ask the MOP client to
stop loading.

> do a serious rewrite and I plan to do that in the future.  No established 

Eventually I'll re-get all the sources and compile again. Adding a
timeout shouldn't be all that hard. It should be a matter of extending
the "connection" table by "last packet's recv/send time" and check this
table entry upon each new request.

> interfaces it's listening on goes down.

Haven't seen that, but my interfaces tend to not go down (at least not
until the whole machine goes down...).

MfG, JBG

---

From: Dominic Sweetman <[email-masked]>
Date: Wed, 14 Jul 2004 17:35:19 +0100

Ralf Baechle ([email-masked]) writes:

> > A truly safe and general I-cache flush routine should itself run
> > uncached... 

It depends what you mean by general, and uncached is not the only
option.  The spec says:

 "The operation of the instruction is UNPREDICTABLE if the cache line
  that contains the CACHE instruction is the target of an
  invalidate..." 

If you use hit-type cache operations in a kernel routine, then you're
safe.  I can't envisage any circumstance in which Linux would try to
invalidate kernel mainline code locations from the I-cache (well, you
might be doing something fabulous with debugging the kernel, but
that's not normal and you'd hardly expect to be able to support such
an activity with standard cache management calls).

So this problem can only arise on index-type I-cache invalidation.  I
claim that a running kernel on a MIPS CPU should only use index-type
invalidation when it is necessary to invalidate the entire I-cache.
(If you use index-type operations for a range which doesn't resolve to
"the whole cache" then that should be fixed).

That implies that a MIPS32-paranoid "invalidate-whole-I-cache" routine
should:

1. Identify which indexes might alias to cache lines 
   containing the routines's own 'cache invalidate' instruction(s),
   and thus hit the problem.  There won't be that many of them.

2. Arrange to skip those indexes when zapping the cache, then do
   something weird to invalidate that handful of lines.  You could 
   do that by running uncached, but you could also do it just by using
   some auxiliary routine which is known to be more than a cache line
   but much less than a whole I-cache span distant, so can't possibly
   alias to the same thing...

This is fiddly, but not terribly difficult and should have a
negligible performance impact.

Does that make sense?  Am I now, having named the solution,
responsible for figuring out a patch (yeuch, I never wanted to be a
kernel programmer again...).

--
Dominic Sweetman
MIPS Technologies

---

From: "Michael Uhler" <[email-masked]>
Date: Wed, 14 Jul 2004 10:45:15 -0700

Dom's proposed solution is probably the right thing to do.  We've got some
code in MIPS that does exactly this, and I've suggested that we convert this
to provide to the Linux community.

/gmu

---
Michael Uhler, Chief Technology Officer
MIPS Technologies, Inc.   Email: [email-masked]
1225 Charleston Road      Voice:  (650)567-5025   FAX:   (650)567-5225
Mountain View, CA 94043   Mobile: (650)868-6870   Admin: (650)567-5085

> -----Original Message-----
> From: [email-masked] 
> [mailto:[email-masked]] On Behalf Of 
> Dominic Sweetman
> Sent: Wednesday, July 14, 2004 9:35 AM
> To: Ralf Baechle
> Cc: Kevin D. Kissell; S C; [email-masked]
> Subject: Re: Strange, strange occurence
> 
> 
> 
> It depends what you mean by general, and uncached is not the 
> only option.  The spec says:
> 
> If you use hit-type cache operations in a kernel routine, 
> then you're safe.  I can't envisage any circumstance in which 
> Linux would try to invalidate kernel mainline code locations 
> from the I-cache (well, you might be doing something fabulous 
> with debugging the kernel, but that's not normal and you'd 
> hardly expect to be able to support such an activity with 
> standard cache management calls).
> 
> So this problem can only arise on index-type I-cache 
> invalidation.  I claim that a running kernel on a MIPS CPU 
> should only use index-type invalidation when it is necessary 
> to invalidate the entire I-cache. (If you use index-type 
> operations for a range which doesn't resolve to "the whole 
> cache" then that should be fixed).
> 
> responsible for figuring out a patch (yeuch, I never wanted 
> to be a kernel programmer again...).
> 
> --
> Dominic Sweetman
> MIPS Technologies
> 
>

---

From: Atsushi Nemoto <[email-masked]>
Date: Thu, 15 Jul 2004 10:34:44 +0900 (JST)

>>>>> On Wed, 14 Jul 2004 17:35:19 +0100, Dominic Sweetman <[email-masked]> said:
dom> 2. Arrange to skip those indexes when zapping the cache, then do
dom> something weird to invalidate that handful of lines.  You could
dom> do that by running uncached, but you could also do it just by
dom> using some auxiliary routine which is known to be more than a
dom> cache line but much less than a whole I-cache span distant, so
dom> can't possibly alias to the same thing...

dom> This is fiddly, but not terribly difficult and should have a
dom> negligible performance impact.

Yes.  The cache routines for TX49XX surely do it (2 phase
invalidating).  Please look at tx49_blast_icache32() in c-r4k.c.

---
Atsushi Nemoto

---

From: Ralf Baechle <[email-masked]>
Date: Thu, 15 Jul 2004 03:53:28 +0200

> kernel programmer again...).

You don't have to :-)  What became a architectural restriction for MIPS32
did already show up earlier as an erratum for the TX49/H2 core.  This is
the solution which we currently have in the kernel code:

#define JUMP_TO_ALIGN(order) \
	__asm__ __volatile__( \
		"b\t1f\n\t" \
		".align\t" #order "\n\t" \
		"1:\n\t" \
		)
#define CACHE32_UNROLL32_ALIGN	JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */
#define CACHE32_UNROLL32_ALIGN2	JUMP_TO_ALIGN(11)

static inline void mips32_blast_icache32(void)
{
	unsigned long start = INDEX_BASE;
	unsigned long end = start + current_cpu_data.icache.waysize;
	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
	unsigned long ws_end = current_cpu_data.icache.ways <<
	                       current_cpu_data.icache.waybit;
	unsigned long ws, addr;

	CACHE32_UNROLL32_ALIGN2;
	/* I'm in even chunk.  blast odd chunks */
	for (ws = 0; ws < ws_end; ws += ws_inc) 
		for (addr = start + 0x400; addr < end; addr += 0x400 * 2) 
			cache32_unroll32(addr|ws,Index_Invalidate_I);
	CACHE32_UNROLL32_ALIGN;
	/* I'm in odd chunk.  blast even chunks */
	for (ws = 0; ws < ws_end; ws += ws_inc) 
		for (addr = start; addr < end; addr += 0x400 * 2) 
			cache32_unroll32(addr|ws,Index_Invalidate_I);
}

All it takes is using this for all MIPS32 / MIPS64 or maybe even all
processors and some tuning of constants to make this suitable for
all possible I-cache configurations.

  Ralf

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Thu, 15 Jul 2004 13:33:17 +0200 (CEST)

> table entry upon each new request.

 But you probably have to take resumption into account -- a client may
restart sending requests from the point it stopped.  It may happen after a
link is restored somewhere on the way after a break, for example.  Though
I haven't checked if there's any timeout defined in the MOP spec or
imposed by specific MOP download clients -- perhaps there is.

> until the whole machine goes down...).

 Mine tend to do that after I do `ifconfig <iface> down', which is what I
sometimes do.  I need to remember to restart mopd then.  Perhaps mopd
should monitor interfaces appearing and disappearing in general, taking
the restriction on the command line into account, of course.

  Maciej

---

From: Ralf Baechle <[email-masked]>
Date: Fri, 16 Jul 2004 14:24:09 +0200

> kernel programmer again...).

No and yes - but here is a simpler solution.  Below patch solves the
problem and adds just 32 bytes of code but removes the special case for
TX49/H2 entirely.

  Ralf

 arch/mips/mm/c-r4k.c        |   59 -------------------------------------------- include/asm-mips/r4kcache.h |   18 ++++++++-----
 include/asm-mips/war.h      |   14 ----------
 3 files changed, 13 insertions(+), 78 deletions(-)

Index: arch/mips/mm/c-r4k.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/c-r4k.c,v
retrieving revision 1.88
diff -u -r1.88 c-r4k.c
--- arch/mips/mm/c-r4k.c	16 Jul 2004 12:06:13 -0000	1.88
+++ arch/mips/mm/c-r4k.c	16 Jul 2004 12:17:05 -0000
@@ -96,16 +96,6 @@
 		r4k_blast_dcache = blast_dcache32;
 }
 
-/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */
-#define JUMP_TO_ALIGN(order) \
-	__asm__ __volatile__( \
-		"b\t1f\n\t" \
-		".align\t" #order "\n\t" \
-		"1:\n\t" \
-		)
-#define CACHE32_UNROLL32_ALIGN	JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */
-#define CACHE32_UNROLL32_ALIGN2	JUMP_TO_ALIGN(11)
-
 static inline void blast_r4600_v1_icache32(void)
 {
 	unsigned long flags;
@@ -115,27 +105,6 @@
 	local_irq_restore(flags);
 }
 
-static inline void tx49_blast_icache32(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.icache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	CACHE32_UNROLL32_ALIGN2;
-	/* I'm in even chunk.  blast odd chunks */
-	for (ws = 0; ws < ws_end; ws += ws_inc) 
-		for (addr = start + 0x400; addr < end; addr += 0x400 * 2) 
-			cache32_unroll32(addr|ws,Index_Invalidate_I);
-	CACHE32_UNROLL32_ALIGN;
-	/* I'm in odd chunk.  blast even chunks */
-	for (ws = 0; ws < ws_end; ws += ws_inc) 
-		for (addr = start; addr < end; addr += 0x400 * 2) 
-			cache32_unroll32(addr|ws,Index_Invalidate_I);
-}
-
 static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page)
 {
 	unsigned long flags;
@@ -145,27 +114,6 @@
 	local_irq_restore(flags);
 }
 
-static inline void tx49_blast_icache32_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	CACHE32_UNROLL32_ALIGN2;
-	/* I'm in even chunk.  blast odd chunks */
-	for (ws = 0; ws < ws_end; ws += ws_inc) 
-		for (addr = start + 0x400; addr < end; addr += 0x400 * 2) 
-			cache32_unroll32(addr|ws,Index_Invalidate_I);
-	CACHE32_UNROLL32_ALIGN;
-	/* I'm in odd chunk.  blast even chunks */
-	for (ws = 0; ws < ws_end; ws += ws_inc) 
-		for (addr = start; addr < end; addr += 0x400 * 2) 
-			cache32_unroll32(addr|ws,Index_Invalidate_I);
-}
-
 static void (* r4k_blast_icache_page)(unsigned long addr);
 
 static inline void r4k_blast_icache_page_setup(void)
@@ -190,10 +138,7 @@
 	if (ic_lsize == 16)
 		r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
 	else if (ic_lsize == 32) {
-		if (TX49XX_ICACHE_INDEX_INV_WAR)
-			r4k_blast_icache_page_indexed =
-				tx49_blast_icache32_page_indexed;
-		else if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+		if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
 			r4k_blast_icache_page_indexed =
 				blast_icache32_r4600_v1_page_indexed;
 		else
@@ -214,8 +159,6 @@
 	else if (ic_lsize == 32) {
 		if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
 			r4k_blast_icache = blast_r4600_v1_icache32;
-		else if (TX49XX_ICACHE_INDEX_INV_WAR)
-			r4k_blast_icache = tx49_blast_icache32;
 		else
 			r4k_blast_icache = blast_icache32;
 	} else if (ic_lsize == 64)
Index: include/asm-mips/r4kcache.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/r4kcache.h,v
retrieving revision 1.22
diff -u -r1.22 r4kcache.h
--- include/asm-mips/r4kcache.h	5 Jan 2004 01:56:01 -0000	1.22
+++ include/asm-mips/r4kcache.h	16 Jul 2004 12:17:05 -0000
@@ -192,7 +192,7 @@
 
 static inline void blast_icache16(void)
 {
-	unsigned long start = INDEX_BASE;
+	unsigned long start = (unsigned long) &&body + 0x100;
 	unsigned long end = start + current_cpu_data.icache.waysize;
 	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
 	unsigned long ws_end = current_cpu_data.icache.ways <<
@@ -200,8 +200,10 @@
 	unsigned long ws, addr;
 
 	for (ws = 0; ws < ws_end; ws += ws_inc) 
-		for (addr = start; addr < end; addr += 0x200) 
+		for (addr = start; addr < end; addr += 0x200) {
+body:
 			cache16_unroll32(addr|ws,Index_Invalidate_I);
+		}
 }
 
 static inline void blast_icache16_page(unsigned long page)
@@ -335,7 +337,7 @@
 
 static inline void blast_icache32(void)
 {
-	unsigned long start = INDEX_BASE;
+	unsigned long start = (unsigned long) &&body + 0x200;
 	unsigned long end = start + current_cpu_data.icache.waysize;
 	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
 	unsigned long ws_end = current_cpu_data.icache.ways <<
@@ -343,8 +345,10 @@
 	unsigned long ws, addr;
 
 	for (ws = 0; ws < ws_end; ws += ws_inc) 
-		for (addr = start; addr < end; addr += 0x400) 
+		for (addr = start; addr < end; addr += 0x400)  {
+body:
 			cache32_unroll32(addr|ws,Index_Invalidate_I);
+		}
 }
 
 static inline void blast_icache32_page(unsigned long page)
@@ -439,7 +443,7 @@
 
 static inline void blast_icache64(void)
 {
-	unsigned long start = INDEX_BASE;
+	unsigned long start = (unsigned long) &&body + 0x400;
 	unsigned long end = start + current_cpu_data.icache.waysize;
 	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
 	unsigned long ws_end = current_cpu_data.icache.ways <<
@@ -447,8 +451,10 @@
 	unsigned long ws, addr;
 
 	for (ws = 0; ws < ws_end; ws += ws_inc) 
-		for (addr = start; addr < end; addr += 0x800) 
+		for (addr = start; addr < end; addr += 0x800) {
+body:
 			cache64_unroll32(addr|ws,Index_Invalidate_I);
+		}
 }
 
 static inline void blast_icache64_page(unsigned long page)
Index: include/asm-mips/war.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/war.h,v
retrieving revision 1.18
diff -u -r1.18 war.h
--- include/asm-mips/war.h	5 Mar 2004 02:47:19 -0000	1.18
+++ include/asm-mips/war.h	16 Jul 2004 12:17:05 -0000
@@ -158,17 +158,6 @@
 #endif
 
 /*
- * From TX49/H2 manual: "If the instruction (i.e. CACHE) is issued for
- * the line which this instruction itself exists, the following
- * operation is not guaranteed."
- *
- * Workaround: do two phase flushing for Index_Invalidate_I
- */
-#ifdef CONFIG_CPU_TX49XX
-#define TX49XX_ICACHE_INDEX_INV_WAR 1
-#endif
-
-/*
  * On the RM9000 there is a problem which makes the CreateDirtyExclusive
  * cache operation unusable on SMP systems.
  */
@@ -203,9 +192,6 @@
 #ifndef MIPS_CACHE_SYNC_WAR
 #define MIPS_CACHE_SYNC_WAR		0
 #endif
-#ifndef TX49XX_ICACHE_INDEX_INV_WAR
-#define TX49XX_ICACHE_INDEX_INV_WAR	0
-#endif
 #ifndef RM9000_CDEX_SMP_WAR
 #define RM9000_CDEX_SMP_WAR		0
 #endif

---

From: "Collin Baillie" <[email-masked]>
Date: Fri, 16 Jul 2004 22:41:01 +0800

> It's only a couple of megabytes, not a number of CD images.

Ok, I found a 4.5MB boot.img file which is supposed to be the netboot debian
installer for r3k-kn03 mipsel. mopd doesn't seem to like it's a.out-ness.
mopchk gives (I named it DEBIAN.SYS for the purpose of mop booting):

Checking: DEBIAN.SYS
Some failure in GetAOutFileInfo

Does mopd work with a.out files? I read somewhere it doesn't. Is this the
install image you speak of? There doesn't seem to be a cd-rom version. I
really have difficulties with Debian's site. Any help you guys could offer
me would be appreciated.

Cheers,

Collin

---

From: Jan-Benedict Glaw <[email-masked]>
Date: Fri, 16 Jul 2004 17:04:15 +0200

On Fri, 2004-07-16 22:41:01 +0800, Collin Baillie <[email-masked]>
> Does mopd work with a.out files? I read somewhere it doesn't. Is this the

Depends on your mopd:) There are several mopds around...

> install image you speak of? There doesn't seem to be a cd-rom version. I

Most probably.

> really have difficulties with Debian's site. Any help you guys could offer

Use a proper mopd like that one from Maciej (he replied earlier in this
thread, containing an URL for it.

MfG, JBG

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 16 Jul 2004 17:08:42 +0200 (CEST)

> really have difficulties with Debian's site. Any help you guys could offer

 This is supposedly an ECOFF image for booting with TFTP.  If you can't 
get the ELF image it was converted from, you may try converting it back to 
ELF like this:

$ mipsel-linux-objcopy -O elf32-tradlittlemips boot.img DEBIAN.SYS

I have never used that, though, so I can't say if it works.  Actually
objcopy from more or less current binutils emits a bogus warning when 
executing the above command.

  Maciej

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 16 Jul 2004 17:13:59 +0200 (CEST)

> Depends on your mopd:) There are several mopds around...

 I don't think any version supports MIPS ECOFF.  COFF and ECOFF are nasty
formats defined differently for different processors, so generic support,
similar to one for ELF, is impossible.  Just don't use ECOFF unless you
absolutely have to.

  Maciej

---

From: Atsushi Nemoto <[email-masked]>
Date: Sat, 17 Jul 2004 01:05:21 +0900 (JST)

>>>>> On Fri, 16 Jul 2004 14:24:09 +0200, Ralf Baechle <[email-masked]> said:

ralf> No and yes - but here is a simpler solution.  Below patch solves
ralf> the problem and adds just 32 bytes of code but removes the
ralf> special case for TX49/H2 entirely.

Hmm... Does this patch really solves the problem?

Here is a disassemble list of blast_icache32 (gcc 3.3.3).  The
comments on CACHE instructions are indices of cachelines which the
instruction invalidates.  (for 4 way 16KB cache --- 4KB waysize).

80039ca0 <blast_icache32>:
80039ca0:       3c048038        lui     a0,0x8038
80039ca4:       8c849e2c        lw      a0,-25044(a0)
80039ca8:       3c028038        lui     v0,0x8038
80039cac:       94429e22        lhu     v0,-25054(v0)
80039cb0:       3c038038        lui     v1,0x8038
80039cb4:       8c639e28        lw      v1,-25048(v1)
80039cb8:       00824004        sllv    t0,v0,a0
80039cbc:       24020001        li      v0,1
80039cc0:       3c018004        lui     at,0x8004
80039cc4:       24219ef4        addiu   at,at,-24844	# 80039ef4
80039cc8:       00231821        addu    v1,at,v1
80039ccc:       00823804        sllv    a3,v0,a0
80039cd0:       11000031        beqz    t0,80039d98 <blast_icache32+0xf8>
80039cd4:       00002821        move    a1,zero
80039cd8:       3c028004        lui     v0,0x8004
80039cdc:       24429ef4        addiu   v0,v0,-24844	# 80039ef4
80039ce0:       0043302b        sltu    a2,v0,v1
80039ce4:       3c048004        lui     a0,0x8004
80039ce8:       24849ef4        addiu   a0,a0,-24844	# 80039ef4
80039cec:       50c00027        beqzl   a2,80039d8c <blast_icache32+0xec>
80039cf0:       00a72821        addu    a1,a1,a3
80039cf4:       00851025        or      v0,a0,a1
80039cf8:       bc400000        cache   0x0,0(v0)	# ee0 2e0 6e0 ae0
80039cfc:       bc400020        cache   0x0,32(v0)	# f00 300 700 b00
80039d00:       bc400040        cache   0x0,64(v0)
80039d04:       bc400060        cache   0x0,96(v0)
80039d08:       bc400080        cache   0x0,128(v0)
80039d0c:       bc4000a0        cache   0x0,160(v0)
80039d10:       bc4000c0        cache   0x0,192(v0)
80039d14:       bc4000e0        cache   0x0,224(v0)
80039d18:       bc400100        cache   0x0,256(v0)
80039d1c:       bc400120        cache   0x0,288(v0)	# 000 400 800 c00
80039d20:       bc400140        cache   0x0,320(v0)
80039d24:       bc400160        cache   0x0,352(v0)
80039d28:       bc400180        cache   0x0,384(v0)
80039d2c:       bc4001a0        cache   0x0,416(v0)
80039d30:       bc4001c0        cache   0x0,448(v0)
80039d34:       bc4001e0        cache   0x0,480(v0)
80039d38:       bc400200        cache   0x0,512(v0)
80039d3c:       bc400220        cache   0x0,544(v0)	# 100 500 900 d00
80039d40:       bc400240        cache   0x0,576(v0)	# 120 520 920 d20
80039d44:       bc400260        cache   0x0,608(v0)	# 140 540 940 d40 !!!
80039d48:       bc400280        cache   0x0,640(v0)
80039d4c:       bc4002a0        cache   0x0,672(v0)
80039d50:       bc4002c0        cache   0x0,704(v0)
80039d54:       bc4002e0        cache   0x0,736(v0)
80039d58:       bc400300        cache   0x0,768(v0)
80039d5c:       bc400320        cache   0x0,800(v0)	# 200 600 a00 e00
80039d60:       bc400340        cache   0x0,832(v0)
80039d64:       bc400360        cache   0x0,864(v0)
80039d68:       bc400380        cache   0x0,896(v0)
80039d6c:       bc4003a0        cache   0x0,928(v0)
80039d70:       bc4003c0        cache   0x0,960(v0)
80039d74:       bc4003e0        cache   0x0,992(v0)
80039d78:       24840400        addiu   a0,a0,1024
80039d7c:       0083102b        sltu    v0,a0,v1
80039d80:       1440ffdd        bnez    v0,80039cf8 <blast_icache32+0x58>
80039d84:       00851025        or      v0,a0,a1
80039d88:       00a72821        addu    a1,a1,a3
80039d8c:       00a8102b        sltu    v0,a1,t0
80039d90:       1440ffd4        bnez    v0,80039ce4 <blast_icache32+0x44>
80039d94:       00000000        nop
80039d98:       03e00008        jr      ra
80039d9c:       00000000        nop

The target address of the first CACHE instruction is 0x80039ef4.  It
invalidates index 0xee0 line.  The CACHE instruction on 0x80039d44
invalidates index 0xd40 line which may contains the
instruction... Ouch!!!

I suppose "two-phase invalidating" must be required to solve this
problem.

---
Atsushi Nemoto

---

From: Thiemo Seufer <[email-masked]>
Date: Fri, 16 Jul 2004 18:31:41 +0200

Maciej W. Rozycki wrote:
[snip]
> get the ELF image it was converted from, you may try converting it back to 

It isn't converted ELF but the output of the t-rex utility, which combines
ECOFF header, ELF stub, kernel and ramdisk into one file.

Thiemo

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 16 Jul 2004 18:51:26 +0200 (CEST)

> ECOFF header, ELF stub, kernel and ramdisk into one file.

 I stand corrected.  The image should still work if converted to ELF and
then loaded, though, shouldn't it?

  Maciej

---

From: Thiemo Seufer <[email-masked]>
Date: Fri, 16 Jul 2004 20:56:41 +0200

> then loaded, though, shouldn't it?

At least I don't see a reason for it to break. I've never tried to
convert it to ELF, though, and binutils support for format conversion
generally isn't as reliable as it should be.

Thiemo