- 17th December 2016 at 10:11 am #64032
In my project, based on PIC32MZ (EF), i make extensive use of nearly all available shadow register sets. While switching them back and forth i stumbled upon something that looks like a bug in the MIPS core. The code in question is:
The above happens in a syscall, so i first change PSS to whatever register set i want to write to, and then restore the original PSS value. If the above executes as per the documentation i should end up with ‘v0’ equal to ‘s2’ in the register set pointed to by ‘v1’. What actually happens is that ‘wrpgpr’ reliably(*) writes in the PSS pointed to by ‘s1’, which is in the _next_ instruction.
Adding ‘ehb’ or even a single ‘nop’ between ‘wrpgpr’ and ‘mtc0’ seems to fix the issue. The above behavior is not documented so it took me a while to figure out what happens. I am not overly familiar with the MIPS pipeline, but it looks to me that ‘wrpgpr’ takes more than one cycle to complete and the subsequent ‘mtc0’ finishes before it. In this particular case these two instructions create a dependency, which the core does not detect. The presence or absence of the last ‘ehb’ does not seem to make any difference.
(*) This happens each time i execute a particular code sequence. A few smaller and simpler test cases that i wrote does not hit the bug.18th December 2016 at 12:06 pm #64039
Forgot to mention that TLB and both L1 caches (in write back with write allocate mode) are on. This may help explain the strangeness.28th April 2017 at 10:31 pm #64038
It is documented in the software users manual:
See Table 2.9 Execution Hazards29th April 2017 at 8:36 am #64037
Hey Chris. Thanks for the reply.
This is how i read table 2.9: If there’s mtc0 to SRSCtl(pss) the _next_ instruction should not be rd/wrpgpr. IOW the hazard continues into the future few clocks.
In my code example the hazard appears to happen _back_ in time. wrpgpr fails if the _following_ instruction is mtc0. I realized that this issue manifests itself more reliably if there’s a long loop before wrpgpr.
My (maybe naive) take on the problem is this: wrpgpr depends on SRSCtl(pss) just as mtc0 to the same location. For some reason and at certain conditions (cpu pipeline feature) wrpgpr executes after the following instruction. If the next instruction happen to be “mtc0 SRSCtl(pss)” we hit the race.
All execution hazards are supposed to affect the following instruction. In this case it appears that execution hazard may also affects the _preceding_ instruction.
Petko1st June 2017 at 8:44 pm #64036
Sorry for not getting back to you sooner I had some thinking to do about this and it does seem strange. I’m reaching out to the designers and will get back to you.
Chris1st June 2017 at 10:28 pm #64035
Thanks Chris. I’ve worked around the issue, but I am really curious about what the designers have to say. 🙂
Petko2nd June 2017 at 1:28 am #64034
The designers said the right thing to do for this version of the processor is ehb or nop or another instruction between the wrpgpr and access to srsctl.
Chris2nd June 2017 at 9:44 am #64033
I figured that much, but was hoping for a little bit more details. 🙂 I prefer ‘ehb’ as it gives better pipeline protection against execution hazards.
Offtopic: is there M6250 based device i can buy to play with?
You must be logged in to reply to this topic.