RE Blog

Documenting the reverse engineering process

16: hwtest and vector instructions, part 3

Today we’ll try to make some sense out of the hidden state instructions. We’ll start by assuming that 0xbb, which always reads the same value into destination register no matter what non-hidden inputs or opcode bits we change, is just a plain read of the hidden state. We’ll model it in hwtest like $c registers: […]

Posted in VP1 | No Comments

15: hwtest and vector instructions, part 2

Last time I’ve said there are three possibilities for the weird vector instructions. Let’s figure them out. First, we’ll look at the microcode samples looking for example usage. As it turns out, most of the unknown vector instructions are always used in pairs with unknown scalar instructions. A few common combinations are: 0f 85 0f […]

Posted in VP1 | No Comments

14: hwtest miscellany

Continuing with the vector instruction set, we run into a problem: the results of the python script are very irregular and suggest we’re pulling data from an unknown source. In particular, the 0×82 opcode is worrying: regardless of inputs, on first few dozen runs after running hwtest, it spits out some interesting values, then reverts […]

Posted in VP1 | 3 Comments

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