All of lore.kernel.org
 help / color / mirror / Atom feed
* Tips on inspecting / debuging cache
@ 2003-03-14  2:13 Wayne Gowcher
  2003-03-14  8:22   ` Kevin D. Kissell
  2003-03-14 19:26 ` Ralf Baechle
  0 siblings, 2 replies; 6+ messages in thread
From: Wayne Gowcher @ 2003-03-14  2:13 UTC (permalink / raw)
  To: linux-mips

Dear List,

I am wondering if someone could point me towards
articles / source code that would give me a little
insight into how to debug cache problems in mips.

For example , how do I inspect the contents of the
cache ? Are there routines to dump out the contents of
the cache ?

Any help, tips , pointers would be appreciated.

TIA

Wayne 



__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tips on inspecting / debuging cache
@ 2003-03-14  8:22   ` Kevin D. Kissell
  0 siblings, 0 replies; 6+ messages in thread
From: Kevin D. Kissell @ 2003-03-14  8:22 UTC (permalink / raw)
  To: Wayne Gowcher, linux-mips

> I am wondering if someone could point me towards
> articles / source code that would give me a little
> insight into how to debug cache problems in mips.
> 
> For example , how do I inspect the contents of the
> cache ? 

Which MIPS CPU are you using?  The CACHE instruction
was introduced with the R4000 CPU as an implementation
dependent feature, and was finally standardized in the MIPS32
and MIPS64 architecture specs.  See
http://www.mips.com/publications/processor_architecture.html
In MIPS32, to be able to properly inspect the cache, one needs
a CPU which implements the optional Index_Load_Tag CACHE 
operation and has both TagHi/TagLo (required) DataHi/DataLo 
(optional) registers. Pre-MIPS32 CPUs may offer the ability
to inspect the cache with variant mechanisms (see your chip
spec), or not at all.

>Are there routines to dump out the contents of
> the cache ?

People write them from time to time, but so far I don't
think anyone has written a "standard" cache dump API
or implementation in the Linux kernel.

            Kevin K.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tips on inspecting / debuging cache
@ 2003-03-14  8:22   ` Kevin D. Kissell
  0 siblings, 0 replies; 6+ messages in thread
From: Kevin D. Kissell @ 2003-03-14  8:22 UTC (permalink / raw)
  To: Wayne Gowcher, linux-mips

> I am wondering if someone could point me towards
> articles / source code that would give me a little
> insight into how to debug cache problems in mips.
> 
> For example , how do I inspect the contents of the
> cache ? 

Which MIPS CPU are you using?  The CACHE instruction
was introduced with the R4000 CPU as an implementation
dependent feature, and was finally standardized in the MIPS32
and MIPS64 architecture specs.  See
http://www.mips.com/publications/processor_architecture.html
In MIPS32, to be able to properly inspect the cache, one needs
a CPU which implements the optional Index_Load_Tag CACHE 
operation and has both TagHi/TagLo (required) DataHi/DataLo 
(optional) registers. Pre-MIPS32 CPUs may offer the ability
to inspect the cache with variant mechanisms (see your chip
spec), or not at all.

>Are there routines to dump out the contents of
> the cache ?

People write them from time to time, but so far I don't
think anyone has written a "standard" cache dump API
or implementation in the Linux kernel.

            Kevin K.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tips on inspecting / debuging cache
  2003-03-14  2:13 Tips on inspecting / debuging cache Wayne Gowcher
  2003-03-14  8:22   ` Kevin D. Kissell
@ 2003-03-14 19:26 ` Ralf Baechle
  2003-03-14 21:53   ` Wayne Gowcher
  1 sibling, 1 reply; 6+ messages in thread
From: Ralf Baechle @ 2003-03-14 19:26 UTC (permalink / raw)
  To: Wayne Gowcher; +Cc: linux-mips

On Thu, Mar 13, 2003 at 06:13:08PM -0800, Wayne Gowcher wrote:

> I am wondering if someone could point me towards
> articles / source code that would give me a little
> insight into how to debug cache problems in mips.
> 
> For example , how do I inspect the contents of the
> cache ? Are there routines to dump out the contents of
> the cache ?

Frankly, such code isn't to useful.  The problems in the cache code can
be fairly subtle.  The only thing that has worked halfway well is reading
the code 1,000 times more after having read it 1,000 times.  And because
it's such a nice job, read it another 1000 times when finished.

If you're refering to the current round of cache problems introduced about
three days ago when I eleminated flush_page_to_ram() and replace it
with flush_dcache_page() - the untested quickfix is changing the
definitions of clear_user_page() and copy_user_page() in <asm/page.h> to
flush the data cache after the operation, for example by invoking
flush_cache_all().  This particular problem affects all processors with
virtually indexed data caches except the R4000 and R4000 SC and MC
versions and the R10000 family.

And everybody's favorite question, was this necessary that late in 2.4?
Yes, it was.  The new mechanism deals is not only more efficient it also
deals better with aliases between the pagecache and userspace mappings.

  Ralf

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tips on inspecting / debuging cache
  2003-03-14 19:26 ` Ralf Baechle
@ 2003-03-14 21:53   ` Wayne Gowcher
  0 siblings, 0 replies; 6+ messages in thread
From: Wayne Gowcher @ 2003-03-14 21:53 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips

Ralf,

Thanks for the feedback.

I believe my problem is not due to your recent
changes. But thanks for the heads up :)



__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Tips on inspecting / debuging cache
@ 2003-03-14 23:23 Adam Kiepul
  0 siblings, 0 replies; 6+ messages in thread
From: Adam Kiepul @ 2003-03-14 23:23 UTC (permalink / raw)
  To: 'Wayne Gowcher', linux-mips

Hi Wayne,

Enclosed please find routines that I developed for PMC-Sierra RM52x1 and RM7000 processors.
Enjoy!

Adam


# Cache Dump - will dump the cache contents from I or D cache.
# Arguments:
# a0 is 0 for I Cache or 1 for D Cache
# a1 is the pointer to the Tag/States Array. Size is Cache Size / 4. There are 2 words per line.
# a2 is the pointer to the Data Array (size equal to the Cache size, MUST be Set Size aligned)
# Note: For user's convenience the pointers can be in KSeg1 or KSeg0.
#
# The TagHi/TagLo registers are stored in an array pointed to by the 2nd argument.
#
# TagHi_Address(Set, Index) = a1 + Set*(SET_SIZE/4) + 8*Index
# TagLo_Address(Set, Index) = a1 + Set*(SET_SIZE/4) + 8*Index + 4
#
# In case of RM52x1 Caches are 32KB total, 2-way set-associative so SET_SIZE is 16KB.
# With 32B line size there are 16KB/32B = 512 lines per Set.
# Thus:
#
# TagHi_Address(Set, Index) = a1 + Set*4096 + 8*Index
# TagLo_Address(Set, Index) = a1 + Set*4096 + 8*Index + 4
#
# Where Set is 0..1 and Index is 0..511.
#
# Cache Data fields are stored in an array pointed to by the 3rd argument.
#
# Line_Data_Address(Set, Index) = a2 + Set*SET_SIZE + Index*32
#
# In case of RM52x1 it is:
#
# Line_Data_Address(Set, Index) = a2 + Set*16384 + Index*32
#
# Note: The Original Physical Address of a cache line has to be calculated based on Tag and Index.
#
# In case of RM52x1 the Physical Address of the cache line is calculated as follows:
#
# PA = ((TagLo & 0xffffff00) << 4) | ((Index*32) & 0x00000fff)
#
# Note: The PA and Data Field are only valid if the line is marked Valid in the TagLo.
# This means that the State field (TagLo[7:6]) must be 3 for D Cache or 2 for I Cache.



#define C0_TAGLO			$28
#define C0_TAGHI			$29

#define Index_Load_Tag_I		4
#define Index_Load_Tag_D		5
#define Index_Store_Tag_I		8
#define Index_Store_Tag_D		9
#define Hit_Writeback_I			24
#define Hit_Writeback_D			25
#define Create_Dirty_Exclusive_D	13

#define ICACHE_VALID			2
#define DCACHE_VALID			3


# Now: 1 is for RM52x1 and 0 is for RM7000

#define RM52x1				1

#if RM52x1
#define CACHE_SIZE			0x00008000
#else
#define CACHE_SIZE			0x00004000
#endif


	.text

	.set noreorder
	.set noat

	.globl cachedmp
	.ent	cachedmp

	.align 5

cachedmp:

# Switch to K1 (optional for D Cache dumping)

	la	t0, 1f
	li	t1, 0x20000000
	or	t0, t1
	jr	t0
	nop
1:

# Read and Modify the Tags/States

	li	t0, 0x80000000				# base address for Index cache ops in t0
	li	t1, 0x80000000+CACHE_SIZE-32		# end address in t1
	li	at, 0x20000000
	or	t2, a1, at				# convert a1 to a K1 address and put to t2
	or	a2, at
	xor	a2, at					# make sure pointer in a2 is a K0 address
	or	t3, a2, zero				# copy a2 to t3
L1:	bne	a0, zero, 1f
	nop
	cache	Index_Load_Tag_I, (t0)
	b	2f
	nop
1:	cache	Index_Load_Tag_D, (t0)
2:	nop ; nop ; nop ; nop
	mfc0	t4, C0_TAGHI
	mfc0	t5, C0_TAGLO
	sw	t4, 0(t2)				# preserve the original Tags/States
	sw	t5, 4(t2)
	li	t7, 0x1ffff000				# mask for PA[28:12]
	and	t7, t3					# mask bits of the pointer in t3
	srl	t7, 4					# t7 is now a Tag for the pointer
#if RM52x1
	li	t6, 0x0000003f
	and	t6, t5					# mask off the PTagLo and PState
	or	t6, t7					# "paste" the Tag value to t6
#else
	mtc0	t7, C0_TAGHI				# in RM7k the Tag is in TAGHI
	li	t6, 0xfff0003f
	and	t6, t5					# mask off the PState
#endif
	bne	a0, zero, 1f				# now set the PState field as valid
	nop
	b	2f
	ori	t6, ICACHE_VALID<<6
1:	ori	t6, DCACHE_VALID<<6
2:	mtc0	t6, C0_TAGLO				# write the new value to TAGLO
	nop ; nop ; nop ; nop
	bne	a0, zero, 1f
	nop
	cache	Index_Store_Tag_I, (t0)			# write back to the cache line states
	b	2f
	nop
1:	cache	Index_Store_Tag_D, (t0)
2:	addiu	t2, 8
	addiu	t3, 32
	bne	t0, t1, L1
	addiu	t0, 32

# For D Cache need to touch the lines in order to set the W bits (make them Dirty)
# We can not use Create_Dirty_Exclusive because it would clear the data fields.
# Therefore we read and store back a word in every line.

	beq	a0, zero, 1f				# Skip for I Cache
	nop

	or	t0, a2, zero
	li	t1, CACHE_SIZE-32
	addu	t1, t0
L2:	lw	t2, (t0)
	sw	t2, (t0)
	bne	t0, t1, L2
	addiu	t0, 32
1:

# Now Write Back the cache contents

	or	t0, a2, zero
	li	t1, CACHE_SIZE-32
	addu	t1, t0
L3:	bne	a0, zero, 1f
	nop
	cache	Hit_Writeback_I, (t0)
	b	2f
	nop
1:	cache	Hit_Writeback_D, (t0)
2:	bne	t0, t1, L3
	addiu	t0, 32

	jr	ra
	nop

	.end	cachedmp

##############################

/* Now: 1 is for RM52x1 and 0 is for RM7000 */

#define RM52x1				1


#if RM52x1
#define CACHE_SIZE	0x00008000
#define SET			2
#else
#define CACHE_SIZE	0x00004000
#define SET			4
#endif

#define SET_SIZE		(CACHE_SIZE/SET)
#define INDEX		SET_SIZE/32

#define Tag_Array_1	0xa0208000
#define Data_Array_1	0xa0200000
#define Tag_Array_2	0xa0218000
#define Data_Array_2	0xa0210000

unsigned char serial_buffer[250];

CacheDisplay(unsigned long TagsAddr, unsigned long DataAddr)
{ int Set, Index, i;
  unsigned long TAGHI, TAGLO, PA, State, Word, *CurrentTags, *CurrentWord;

CurrentTags=(unsigned long *)TagsAddr;

#if RM52x1
CurrentWord=(unsigned long *)DataAddr;
#else
CurrentWord=(unsigned long *)(DataAddr&0xdfffffff);
#endif
/* For RM7k we need to read the written-back data cached just in case it ends up in L2 */

for(Set=0; Set<SET; Set++)
    for(Index=0; Index<INDEX; Index++)
        { sprintf(serial_buffer, "\n\rSet: %d, Index: %03d", Set, Index);
          dumpstr(serial_buffer);
          TAGHI=*CurrentTags++;
          TAGLO=*CurrentTags++;
          sprintf(serial_buffer, "\n\rTAGHI=0x%08x, TAGLO=0x%08x", TAGHI, TAGLO);
          dumpstr(serial_buffer);
#if RM52x1
          PA=((TAGLO & 0xffffff00) << 4) | ((Index*32) & 0x00000fff);
#else
          PA=((TAGHI & 0xffffff00) << 4) | ((Index*32) & 0x00000fff);
#endif
          State=(TAGLO & 0x000000c0)>>6;
          sprintf(serial_buffer, "\n\rPA=0x%08x, State=0x%x, Data Words:\n\r", PA, State);
          dumpstr(serial_buffer);
          for(i=0; i<8; i++)
             { Word=*CurrentWord++;
               sprintf(serial_buffer, "%08x ", Word);
               dumpstr(serial_buffer);
             }
          dumpstr("\n\r");
        }
}

main()
{ 
dumpstr("\n\rRunning the cachedmp for D Cache\n\r");
cachedmp(1, Tag_Array_1, Data_Array_1);
CacheDisplay(Tag_Array_1, Data_Array_1);
dumpstr("\n\rRunning the cachedmp for I Cache\n\r");
cachedmp(0, Tag_Array_2, Data_Array_2);
CacheDisplay(Tag_Array_2, Data_Array_2);
}




-----Original Message-----
From: Wayne Gowcher [mailto:wgowcher@yahoo.com]
Sent: Thursday, March 13, 2003 6:13 PM
To: linux-mips@linux-mips.org
Subject: Tips on inspecting / debuging cache


Dear List,

I am wondering if someone could point me towards
articles / source code that would give me a little
insight into how to debug cache problems in mips.

For example , how do I inspect the contents of the
cache ? Are there routines to dump out the contents of
the cache ?

Any help, tips , pointers would be appreciated.

TIA

Wayne 



__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-03-14 23:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-03-14  2:13 Tips on inspecting / debuging cache Wayne Gowcher
2003-03-14  8:22 ` Kevin D. Kissell
2003-03-14  8:22   ` Kevin D. Kissell
2003-03-14 19:26 ` Ralf Baechle
2003-03-14 21:53   ` Wayne Gowcher
  -- strict thread matches above, loose matches on Subject: below --
2003-03-14 23:23 Adam Kiepul

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.