GP2X Flushing The 920t's Data Cache


Firefox

Member
Joined
Dec 7, 2005
Messages
443
Location
Sheffield, England
Website
Visit site
Hi everyone! I'm in need of a bit of caching-related assistance!

I've got a small assembly language loop running on the 940T, and it's incrementing a counter in a register and writing the value to a location in shared memory.

On the 920T I'm running a C program and I've got the shared memory mmap()ed.

I'm reading the location that's being written by the 940T using a volatile unsigned long*. I do that once a second in a loop, sleep()ing inbetween reads.

The problem is that whatever count value my C program sees first is the value it sees forever more.

I've tried msync(), running a loop that reads 16kB from somewhere else via another volatile unsigned long *, and even munmap()ing and re-mmap()ing the data memory between reads. And all three together. But whatever I do I can't get rid of whatever value it reads first!

How can I flush the 920T's data cache without upsetting Linux, or declare my shared memory region uncached? :unsure:

I'm running my 940T code at 0x03000000 and my shared data memory is inside a 512kB block at 0x03500000.
 
I think you'll find that rlyeh's minimal lib has inter-processor shared memory working. I know he talked about it. Perhaps you could look at his source and see what he did?
 
Okay, it turns out that the top 32MB is uncached, the problem is that that the GNU assembler apparently can't calculate relative branches! :angry:

Here's my loop as it was originally:

Code:
        ldr     a1,data_location
        ldr     a2,pattern
loop:
        str     a2,[a1]
        add     a2,a2,#1
        b       loop

data_location:
        .word   0x100000 + 200

pattern:
        .word   0xfeed0000

But if you look at the output:

Code:
  7c:   e59f000c        ldr     r0, [pc, #12]  ; 90 <data_location>
  80:   e59f100c        ldr     r1, [pc, #12]  ; 94 <pattern>
  84:   e5801000        str     r1, [r0]
  88:   e2811001        add     r1, r1, #1     ; 0x1
  8c:   ea00001f        b       84 <loop>
  90:   001000c8        andeqs  r0, r0, r8, asr #1
  94:   feed0000        cdp2    0, 14, cr0, cr13, cr0, {0}

See how the branch is jumping forward, not backwards like it should be! :eek:

So I changed my code slightly and encoded the branch myself:

Code:
        ldr     a1,data_location
        ldr     a2,pattern
loop:
        str     a2,[a1]
        add     a2,a2,#1
@@@        b       loop
        .word   (-4 & 0x00ffffff) | 0xea000000

data_location:
        .word   0x100000 + 200

pattern:
        .word   0xfeed0000

and now all is well:

Code:
  7c:   e59f000c        ldr     r0, [pc, #12]  ; 90 <data_location>
  80:   e59f100c        ldr     r1, [pc, #12]  ; 94 <pattern>
  84:   e5801000        str     r1, [r0]
  88:   e2811001        add     r1, r1, #1     ; 0x1
  8c:   eafffffc        b       84 <loop>
  90:   001000c8        andeqs  r0, r0, r8, asr #1
  94:   feed0000        cdp2    0, 14, cr0, cr13, cr0, {0}

I've no idea why the GNU assembler is doing that... I can't see any command-line switches that seem equivalent to "--dont-screw-up-relative-branches"... :rolleyes:

Oh well, mystery solved! Sorry for the noise everyone.
 
Maybe you've got a buggy version... certainly doesn't seem right.
 
It's a Devkitpro GNU tools build for Linux, built about a week and a half ago.

Actually I've got another GNU tools build for the GP2X somewhere (I switched to the Devkitpro build because it seemed to be the standard that everyone was using). I'll try the other one and see what happens.
 
Okay, I've found out how to fix this GNU assembler weirdness.

Basically you just need to run the output of the assembler through the linker, even if you're not linking it with anything. This causes the linker to calculate the branch offsets correctly and all is well.

I suspect that this is a side-effect of the GNU tools being what they are, multi-platform and multi-target. Even though ARM branches are always relative and have a range of +/-32MB I suspect it's just easier for the GNU tools to do the calculations at the link stage for all targets.

Oh well, important lesson learned! :)
 
Back
Top