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
00f514: 4f000000 4f000000 4f000000
00f518: bf000000 bf000000 bf000000
00f51c: ef000000 ef000000 ef000000

f448+ are writable, though only from MMIO side. f510 are read-only, but back in episode 3 we've seen them read out as the most recently executed instruction of the corresponding type. This strongly suggests that they represent the current state of branch unit -> execution unit opcode path.

The f448+ ones are more interesting. Being writable strongly suggests that we can use them to manually launch an instruction, without going through the trouble of setting up and executing a microcode piece. Let's try setting $r0 to 0xdead. Since f44c appears to hold the scalar path NOP, we'll try poking the opcode to that one:

$ nvapoke f44c 6500dead
$ nvapeek f448 10
0000f448: df000000 6500dead bf000000 ef000000
$ nvapeek f780
0000f780: 6df5e6ef

Nope, but there may be a trigger register in the f400+ range that launches the instruction. Let's see.

$ nvascan f400 200
$ nvapeek f780
0000f780: 0000dead
$ nvapeek f448 10
0000f448: df000000 4f000000 bf000000 ef000000

Yeah. That did it. And the opcode registers got reset to NOPs again, how convenient. After a bit of binary searching to narrow it down, we deduce that register f458 has to be written with a value that has bit 0 set to 1 to trigger the launch and clear to NOP.

So we can now launch instructions without bothering with the upload stuff. That'll be quite useful for REing the vector/scalar and maybe address instructions.

Elapsed time: 30m.

Currently unrated


There are currently no comments

New Comment


required (not published)