Nicholas Clark writes:
> The second relates to PC being the destination of LDM and LDR instructions,
> where the LDM or LDR is on the last word of a page. The pipeline read for
> the instruction following the LDM or LDR causes a prefect abort to be
> scheduled, but the K chip doesn't realise that the PC was altered in the LDM
> or LDR, still generates the abort, which upon return causes execution to
> carry on with the instruction at the memory location after the LDM or LDR,
> rather than at the address that was loaded into the PC by the LDM or LDR.

>From what you describe, there is a very specific case where this occurs:

1. LDM or LDR towards the end of the page.
2. The next page is not present.
3. The LDM and LDR loads the PC.

>From the kernel point of view, there is very little it can do.  Ok, it can
detect all three conditions, but once they have occurred, the situation is
not recoverable.  Eg, take the following code:

page+0x0ffc     ldmea   fp, {fp, sp, pc}
page+0x1000     <not present>

The state of the stack before the ldmea is executed might be:

        register        stack
        old_fp  ->      pc
                        sp
        old_sp  ->      fp
                        r3
                        r2
                        r1
                        r0
        fp      ->      PC (old_pc)
                        SP (old_sp)
                        FP (old_fp)
        sp      ->      <any other function-local data>
        <<< everything below this is no longer valid >>>

After the ldmea, the stack looks like:

        register        stack
        fp      ->      pc
                        sp
        sp      ->      fp
        <<< everything below this is no longer valid >>>
                        r3
                        r2
                        r1
                        r0
                        PC
                        SP
                        FP

However, due to this bug, PC isn't old_pc.  There would be the chance
of fixing this up, if you knew where the PC was stored, or had a copy
of it else where.

One possible solution to this could be to have a -mstrongarmrevk flag, which
changes the APCS epilogue to be:

        ldmea   fp, {fp, sp, lr}
        mov     pc, lr

This would cause an extra cycle to be inserted into each function, but would
cleanly get around the problem in each and every case.

Phil did say in a later mail about how far to bend the toolset.  The problem
is that unfortunately the Rev. K is not rare.  I think that most RiscPCs with
200MHz StrongARMs are using Rev. K.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [EMAIL PROTECTED]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [EMAIL PROTECTED]

Reply via email to