PIC32 sleep mode with watchdog wakeup failing
Ok, I now have this working properly.  And here's how:


Read the manual.
Throw the manual away.
Write a working program in a different IDE / compiler.
Disassemble the resultant program and see how it should be done.


XC32 builds in code to handle the NMI into its reset handler for you, and the code it generates bears no resemblance to what the manual says you should do.  Instead it examines the NMI status of C0.  If it was an NMI then do an eret, otherwise start the program normally.

Here's the relevant bits of the program disassembled:

bfc00000:   401a6000    mfc0    k0,c0_status
bfc00004:   7f5a04c0    ext k0,k0,0x13,0x1
bfc00008:   13400005    beqz    k0,bfc00020 &lt;_no_nmi&gt;
bfc0000c:   00000000    nop
bfc00010:   3c1a9d00    lui k0,0x9d00
bfc00014:   275a02a8    addiu   k0,k0,680
bfc00018:   03400008    jr  k0 &lt;_nmi_handler&gt;
bfc0001c:   00000000    nop

9d0002a8 &lt;_nmi_handler&gt;:
9d0002a8:   401a6000    mfc0    k0,c0_status
9d0002ac:   3c1bffbf    lui k1,0xffbf
9d0002b0:   377bffff    ori k1,k1,0xffff
9d0002b4:   035bd024    and k0,k0,k1
9d0002b8:   409a6000    mtc0    k0,c0_status
9d0002bc:   42000018    eret


So you see it doesn't care why the NMI happened - it just erets regardless.

With that style of doing it in my startup routine it now works!