CtxInit

English/EspaƱol

How to create a context init code for some cards (mostly for nv4x)

This page refers to nv4X cards and up (NV4X/G7X/G8X). Almost all information was gathered from the Irclog. The process of new context init code consists from few steps:

Get ctx_voodoo

You can see example of ctx_voodoo in nv40_graph.c. It is, probably, some kind of microcode used in Nvidia cards, and you can get it from MmioTrace. In a parsed mmio trace you have to search for a single write to register 0x400324, followed by multiple writes to register 0x400328. Notice that the write to 0x00400324 is (almost always) zero. It is probably an index register that sets the starting writing position for the 0x00400328 register. Also, the register at 0x00400324 is probably auto incremented for each data write.

write32 #1 0x00400324 <- 0x00000000
write32 #1 0x00400328 <- 0x00400889
write32 #1 0x00400328 <- 0x00200000
write32 #1 0x00400328 <- 0x0060000a
write32 #1 0x00400328 <- 0x00200000
write32 #1 0x00400328 <- 0x00300000
...

Take all writes to 0x00400328 and store them in an array named static uint32_t nvXX_ctx_voodoo[] (XX is your card type). Put ~0 (0xFFFF) at the end of the array.

If you cannot find the voodoo, try doing the mmio-tracing again after a fresh cold boot. Keep the machine off for at last 30 seconds before power-on, and do not start X before you trace.

Get INSTANCE_WR writes

I have no idea what these writes means, I only guess how to get them. First get REnouveau and apply patch. One of these could work for nv4X. However it may not. In that case look at them and try to come up with custom one. Also read the Irclog from 19:20.

If you apply the patch and run Renouveau, grep your card_stdout.txt (or maybe *graph_ctx_dump.txt if it exists) for GRCTX[0x. If you find it, just ignore all the 0 values (a lot of them will be 0) and convert the repeated writes of the same value into loops. You just got your INSTANCE_WR!

Graphics context at RAMIN+0x00083340
GRCTX[0x00000000] = 0x00008334
GRCTX[0x00000004] = 0x00000000
GRCTX[0x00000008] = 0x00000000
GRCTX[0x0000000c] = 0x00000000
GRCTX[0x00000010] = 0x00000000
GRCTX[0x00000014] = 0x00000000
GRCTX[0x00000018] = 0x00000000
GRCTX[0x0000001c] = 0x00000000
GRCTX[0x00000020] = 0x00000000
GRCTX[0x00000024] = 0x0000ffff
GRCTX[0x00000028] = 0x0000ffff
GRCTX[0x0000002c] = 0x00000000
GRCTX[0x00000030] = 0x00000001
GRCTX[0x00000034] = 0x00000000
GRCTX[0x00000038] = 0x00000000
GRCTX[0x0000003c] = 0x00000000

The irc log of for nv44 card and http://users.on.net/~darktama/renouveau-dump-nv44-grctx.diff patch.
19:40 < stillunknown> You say the nv44 method works always?
19:40 < darktama> no, it can still fail in quite a number of ways
19:41 < darktama> stillunknown: it'll fail if renouveau doesn't get assigned channel 2.. or if the context is in a part of instance memory not accesible through the "main" mmio regs
19:41 < mg> Graphics context at RAMIN+0x00409050... *not* a graphics context
19:41 < mg> Graphics context at RAMIN+0x00409050... *not* a graphics context
19:41 < pq> mg, it might or might not crash, look for Xid messages in kernel log
19:43 < mg> anyhow i have xis
19:47 < darktama> yup, got it.. can you add a printf("0x%08x\n", all_regs[0x2220/4]); somewhere please?
19:48 < darktama> just before the "ramfc_offset = " line will do.. doesn't really matter.
19:48 < darktama> the same for all_regs[0x0072000c/4]
19:54 < mg> darktama: all_regs[0x2220/4]:     0x00030002
19:55 < mg> darktama: all_regs[0x0072000c/4]: 0x00005029
19:55 < darktama> mg: ok, nvidia weren't being helpful :)  the 0x72000c value looks promising though.. so..
19:56 < darktama> change the "ramfc = " line to "ramfc = &all_regs[(0x00700000 + 0x20000 + (CTX_DUMP_CHANNEL * 128))/4];"
20:00 < mg> ok I got a dump now

If your card_stdout.txt contains ... *not* a graphics context, you'll have to try to adjust the patch. Probably ask in IRC.

Keep in mind that that some GRCTX do not belong to initilization. Sometimes this is easily seen, when the values become random. Also look for a jump in register address, this is a good indication.

NV44_GRCTX_SIZE

It is size of INSTANCE_WR writes... more or less. As long as you make it big enough(256x1024), it should be ok. If you want to get correct size, you should identify when another grctx starts and calculate the difference.

Now you should have enough information for creating new context init. Just look at the source code (DRM nv40_graph.c and similar) or ask in the channel. New developers are always welcome and the channel is a very friendly place.