This page serves to document information about the NUI Camera DSP, its architecture, instruction set, firmware, and capabilities.
With these, you can extract the NuiCam.bin file from the archives and use segher's dis-nui (below) to start understanding the camera firmware.
Segher figured out the instruction set, and wrote a disassembler: http://git.infradead.org/users/segher/dis-nui.git
< segher> http://git.infradead.org/users/segher/dis-nui.git < segher> have fun :-) < segher> the code in that NuiCam.bin starts at 2*0f14 < segher> so cut it, and then run it through the disassembler < segher> it should start: < segher> 0000: 25d7 mov r5l,#d7 < segher> 0001: 35a6 mov r5h,#a6 < segher> 0002: bb05 mov pc,r5 < segher> (which jumps to a6d7, this is the reset vector)
There are 16 general purpose registers, denoted r0 through r15. Each is 16 bits wide.
There may also be as many as 16 "s" registers and 16 "t" registers, although we don't see them all getting used, so some may not actually exist. Known special usages are noted below.
- Call params are r4, r5, r6, and then stack
- Return register is r4 of r5:4
- r4, r5, r6, r13, and flags are callee-clobbered
- All other registers are callee-saved
|r4||ABI: first return value goes here. Obviously, callee may modify.|
|r5||ABI: Callee may modify|
|r6||ABI: Callee may modify|
|r9||ABI: Callee must preserve|
|r12||ABI: stack pointer (nothing special in hardware, just ABI)|
|r13||ABI: Callee may modify. Generally used as a temp register, gets used for long calls a lot|
|s2||ilr||interrupt link register|
|s8||Unused, as far as we know|
|s11||Unused, as far as we know|
|s12||Unused, as far as we know|
|s13||Unused, as far as we know|
|s14||Unused, as far as we know|
|s15||Unused, as far as we know|
|t1||Unused by Primesense firmware|
|t3||Unused by primesense firmware|
|t4||Unused by primesense firmware|
|t5||ctr||Counter, used for loops|
|t10||Unused by primesense firmware|
|t11||Unused by primesense firmware|
Info about semantics of particular instructions goes here
- What does the "bloop $ARG" instruction do? decrement ctr, branch if not zero to $ARG?
- answer goes here
Put outstanding questions here.
Random disorganized notes/quotes
Feel free to merge these into above sections where appropriate, they're written down so they won't be forgotten.
On 32-bit handling:
04:03 < zarvox> segher: the std r4, (r12)- syntax - does that mean "load r4 with the data pointed to by r12, then decrement r12"? # wow, that was a dumb question <_< 04:04 < segher> it means "store r5 to where r12 points to ; decrement r12 ; store r4 where r12 points to ; decrement r12 04:05 < zarvox> okay, so that's done with implied register pairs? 04:05 < zarvox> that's the 32-bit handling? 04:05 < segher> yeah 04:05 < segher> that's the "d" thing
00:13 < segher> cmp/bcc is "unsigned smaller than" 00:13 < segher> cmp/bcs is "unsigned greater or equal"
00:58 < zarvox> segher: shrd = shift right double; any guess as to if there's rotation or sign extension involved? 01:01 < segher> zarvox: shr is unsigned right shift, dropping the bits that are shifted out 01:01 < segher> and shifting zeroes in at the top end\ 01:02 < segher> asr is arith right shift; shifting sign bits in, and rounding 01:02 < segher> i'm not sure what exactly rounding does; i think it depends on some mode bits