RE Blog

Documenting the reverse engineering process

13: hwtest and vector instructions, part 1

It’s time to finally take a look at the vector instructions. Some quick testing reveals that 0×81, 0×82, 0×87-0x8e, 0×90-0×92, 0×94, 0×95, 0×97-0x9f, 0xa1, 0xa2, 0xa4, 0xa5, 0xa7-0xaf, 0xb1-0xb3, 0xb6-0xbe are valid opcodes. First, let’s look at 0xad. It’s used to clear the $v registers in the “init” microcode piece, so there’s a high chance […]

Posted in VP1 | No Comments

12: hwtest and scalar instructions, part 2

First of all, I did one minor error in the previous episode: I reset the VP1 unit on every test, causing the $c registers to be cleared every time (rememeber we have no means of setting it arbitrarily). Allowing them to keep the old value between tests reveals that all 0×60-0x7f operands that we though […]

Posted in VP1 | No Comments

11: hwtest and scalar instructions, part 1.

Given that we now have a simple and reliable way of executing a single instruction, it’s time to start using automated testing to verify we got the semantics right. We’ll integrate the VP1 tests as part of envytools’ hwtest framework. The test will work like that: Randomize all VP1 state we can easily write (ie. […]

Posted in VP1 | No Comments

10: Manually submitting single instructions

Back in the beginning, we did a register scan and noticed two sets of registers that, by default, have values strangely similiar to the NOP encodings for the 4 execution units: 00f448: df000000 ffffffff 00000000 * 00f44c: 4f000000 ffffffff 00000000 * 00f450: bf000000 ffffffff 00000000 * 00f454: ef000000 ffffffff 00000000 * 00f510: df000000 df000000 df000000 […]

Posted in VP1 | No Comments

9: The FIFO interface

In the last episode we had a brief look at the nv44 mthd microcode – the only thing it did was handling the DMA object setting methods. The nv50 version of this microcode is even simpler – only method 0 is handled. This strongly suggests there are some other handlers for methods. Let’s scan the […]

Posted in VP1 | No Comments

8: The *actual* $a instructions, pt. 2

Time to think about the data store a bit. The d0/d2/d4/d6 opcodes are very likely just ld/st instructions targetting it. However, the channel switch sequence is supposed to read/write the context DMA object, and the VP architecture diagram shows a line connecting the data store to the memory interface. This means we should likely be […]

Posted in VP1 | 1 Comment

7: the *actual* $a instructions, pt. 1

Today I’ll attempt to look at the channel switch microcode. Its only tasks should be loading/storing the context data and some administrative stuff. Since so far we’ve only worked on NV50, let’s look at the NV50 version. 00000000: 6a0000c7 mov $y0 $a0 00000000: 6a0840c7 mov $y1 $a1 00000000: 6a1080c7 mov $y2 $a2 00000000: 6a18c0c7 mov […]

Posted in VP1 | No Comments

6: Branches, pt. 2

Let’s continue REing the branch instructions. 0xe0   2897    2330     branch if predicate 0xe1   1036     913     branch ? 0xe2   1707    1188     branch if not predicate 0xe3    120      89     ??? [XXX] 0xe4   2020     695     call if predicate 0xe6     92      84     call if not predicate 0xe8    694     552     ret 0xea    248       1     abra 0xef  23932   13521     bnop 0xf0    […]

Posted in VP1 | No Comments

5: Branches, pt. 1

Today my goal is to look into an issue I’ve briefly mentioned at the beginning, but ignored afterwards: the code fetch and execution process. The initial guess was that the ISA is VLIW with a bundle size of 16 bytes, containing 4 32-bit opcodes. The known branches certainly can only aim at targets aligned to […]

Posted in VP1 | No Comments

4: $a instructions, pt. 2

Today’s aim is to RE the remaining $a-related opcodes. That is, boring but required stuff before we can get to looking at the microcode. First, let’s look at the pXX.2 code again: mwk@nightmare ~/microcode/vp1/p1 $ envydis -m vp1 -w part-00.2 00000000: 6b0fc0af mov $a1 $x63 00000000: 7e087f80 shr $a1 $c0 $a1 -0×10 00000000: 7e084080 shr […]

Posted in VP1 | No Comments