gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > NDS ARM9 Cache, strange behaviour with NO$GBA

#158495 - sverx - Thu Jun 12, 2008 10:17 am

Hi there... I'm back once more with my newbie questions.

This time I've got to ask the forum about the ARM9 Cache.
I've already read the really interesting (and clear!) topic here, and I've read, mainly, about flushing the data cache
Code:
DC_FlushAll()

and/or ORing 0x400000 to a memory address to 'bypass' the cache so really accessing the memory content.

In my little program they both work but on the NO$GBA emulator, when I use the 'ORing 0x400000' system, the numbers of Total Errors (you know, the F3 key...) immediatly goes from the 0 I had before to some thousand... and I see no reasons at all :|

You see... I would like not to use the DC_FlushAll() because I just need -sometimes- to access a memory area where -constantly- the ARM7 writes different values, so I guess I shouldn't disturb the cache for that... I hope you understand what I mean... :|
(yes, I had to study English better when in high school...)

Any help/hint will be appreciated! :)

Thanks! Ciao :)

#158497 - Maxxie - Thu Jun 12, 2008 10:28 am

DC_Flush*() would overwrite the values the ARM7 put there.
DC_Invalidate*() on the otherhand lose some other data you've had in the arm9 datachache


On such situations, you should avoid intermixing cached and noncached memory access. Do this by allocating your shared buffer with memalign to the size of a cacheline (32 Bytes). Make sure to allocate full cachelines (only multiples of 32 Bytes) otherwise access to the cached version of the mem could happen through other malloced.
Read/Write from the mirror.

Then you can safely access the non cached mirror of that memory after an initial flush.
This is because other then your access to the mirror noone access the cahed version and therefor the cache is never again used for that memory.

#158500 - sverx - Thu Jun 12, 2008 10:54 am

Thanks for the answer... still I've got some doubts...

Maxxie wrote:
DC_Flush*() would overwrite the values the ARM7 put there.


mmm... I never write (with ARM9) to that location... could overwrite happen? :|

Maxxie wrote:
On such situations, you should avoid intermixing cached and noncached memory access.


The reason isn't clear to me. I obviously want that the ARM9 cache to work, i just don't want it to cache while reading from that specific memory location where ARM7 writes values... I would like to avoid flushing/invalidating caches, instead...

Thanks :)

#158501 - Maxxie - Thu Jun 12, 2008 11:02 am

sverx wrote:
Thanks for the answer... still I've got some doubts...

Maxxie wrote:
DC_Flush*() would overwrite the values the ARM7 put there.


mmm... I never write (with ARM9) to that location... could overwrite happen? :|


There might be other data changed in the same cacheline. This will cause the whole cacheline to be written back.

Quote:

Maxxie wrote:
On such situations, you should avoid intermixing cached and noncached memory access.


The reason isn't clear to me. I obviously want that the ARM9 cache to work, i just don't want it to cache while reading from that specific memory location where ARM7 writes values... I would like to avoid flushing/invalidating caches, instead...

Thanks :)


This is exactly what i suggest (The flush is only once on init, and only needed for the the affected cachelines). You reserve whole cacheline-blocks, so they are not shared with other data, and thus will never be flagged (by access) to be written back due to other data "near" your shared.

#158508 - sverx - Thu Jun 12, 2008 1:34 pm

Maxxie wrote:
There might be other data changed in the same cacheline. This will cause the whole cacheline to be written back.


... that's interesting! But this could happen only if ARM9 did a write operation on a memory address close enough to the data that shouldn't be overwritten, right? (it seems to me I've read that a cache line is only 32 bytes...)

and about that:
Maxxie wrote:
You reserve whole cacheline-blocks, so they are not shared with other data, and thus will never be flagged (by access) to be written back due to other data "near" your shared.


I'm not really sure I understand... it's that related to what I said before? You mean I should reserve a block which should be 32*n bytes? And what about alignment? Should I check that malloc() returns me a 'cache line aligned' block?

Thanks once more :)

#158509 - Maxxie - Thu Jun 12, 2008 1:40 pm

Yes that's right.

Use memalign(32,desiredSize) instead of malloc(desiredSize) to align the data at cacheline borders.

#158510 - sverx - Thu Jun 12, 2008 2:01 pm

Maxxie wrote:
Use memalign(32,desiredSize) instead of malloc(desiredSize) to align the data at cacheline borders.


Wonderful, I didn't know about that :) Thanks :)

BTW, does anybody has an idea about why happens that?
Quote:
In my little program they both work but on the NO$GBA emulator, when I use the 'ORing 0x400000' system, the numbers of Total Errors (you know, the F3 key...) immediatly goes from the 0 I had before to some thousand... and I see no reasons at all :|


Thanks once more :)

#158569 - sverx - Fri Jun 13, 2008 3:03 pm

... just two more questions, to be sure...

1) Are
Code:
malloc (k)

and
Code:
memalign (4,k)

always the same thing on NDS, right? (Both ARM9 and ARM7 I guess...)

2) Does the cache interfere when reading/writing to the OAM and the OAM_SUB? I mean, if I write to the OAM, should I flush to ensure data gets really written there?

#158570 - Maxxie - Fri Jun 13, 2008 3:13 pm

The effect of both should be the same.

You do not need to care about cache for OAM and such. The ds9 crt0 only sets the cacheable bit for region 1 and 6, which are
Code:

   @-------------------------------------------------------------------------
   @ Region 1 - Main Memory
   @-------------------------------------------------------------------------
   ldr   r0,=( PAGE_4M | 0x02000000 | 1)   
[...]
   @-------------------------------------------------------------------------
   @ Region 6 - System ROM
   @-------------------------------------------------------------------------
   ldr   r0,=( PAGE_32K | 0xFFFF0000 | 1)   


Every other memory location does not include cache.