summaryrefslogtreecommitdiff
path: root/NVC0_Firmware.mdwn
blob: cf5bf7eac44f1a53fcf514d54a8e34dbbeb2797a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<meta name="google-translate-customization" content="38b387022ed0f4d4-a4eb7ef5c10c8ae0-g2870fab75904ce51-18"></meta>
<div id="google_translate_element"></div>
<script type="text/javascript" src="/wiki/translate.js"></script>

# Context Switching Firmware


## Status

You basically never need to do the mmiotrace, unless you're a nouveau developer. There is a script that will extract all the known (useful) firmware from the blob directly. See the [[VideoAcceleration]] page for instructions. If you have a Maxwell card, or want to attempt using firmware from blob versions not supported by the script, the instructions are below.


## Instructions

1. Do an [[MmioTrace]] of the blob. You just need to trace X starting (or a CUDA app). See [[these instructions|https://wiki.ubuntu.com/X/MMIOTracing]] for more details.

2. Extract the firmware into separate files. The below perl script will do so with the help of demmio, available as part of [EnvyTools](https://github.com/envytools/envytools).

        demmio -f mmiotrace.log.xz | perl -e '
        open($fh409c, ">fuc409c"); open($fh409d, ">fuc409d"); open($fh41ac, ">fuc41ac"); open($fh41ad, ">fuc41ad");
        %m = ("0x409184" => $fh409c, "0x4091c4" => $fh409d, "0x41a184" => $fh41ac, "0x41a1c4" => $fh41ad);
        while (<>) { exit if (/0x409840/); next if (!/W (0x4(?:09|1a)1[c8]4) .* <= (?:.*0x)?(.*)/); print { $m{$1} } pack "I", hex($2);}'

3. Rename the files to have a `nvXX_` prefix. For example if you have a NVE6 (as determined by 'Chipset' in dmesg), the files would be `nve6_fuc409c`, `nve6_fuc409d`, `nve6_fuc41ac`, and `nve6_fuc41ad`. (c = code, d = data)

Note: These instructions were tested with 340.32. Other versions should work fine too, but if the firmware upload mechanism is too different, it will fail. If you want to extract Maxwell's firmwares, please use the 340.32.

---


# Video firmware

Note that there is a script which performs the extraction from the blob directly, see [[VideoAcceleration|VideoAcceleration#firmware]]. To extract from a blob version that is not supported by the script, you can try the below:

## Extracting kernel video firmware on VP3/4/5:

There are 2 sets of firmware for video decoding, one for kernel and one for userspace. Only VP3/4 series have the userspace firmware. VP5 does not have userspace firmware. (So, pre-GF117 has userspace firmware, post GF117 and later does not.)

The kernel parts can be obtained by doing a mmiotrace of a program using vdpau for video decoding, for example mplayer -vc ffmpeg12vdpau,ffh264vdpau,ffwmv3vdpau,ffvc1vdpau,ffodivxvdpau, somefile.mkv

After you obtained the mmiotrace, look for the base offsets used by the firmware:

    $ demmio -f vdpau-mmiotrace | grep P.*P.*XFER_EXT_BASE
    [0] 437.753081 MMIO32 W 0x084110 0x004de400 PBSP.XFER_EXT_BASE <= 0x4de40000
    [0] 445.278672 MMIO32 W 0x085110 0x004dde00 PVP.XFER_EXT_BASE <= 0x4dde0000
    [0] 445.938745 MMIO32 W 0x086110 0x004dd800 PPPP.XFER_EXT_BASE <= 0x4dd80000

    $ demmio -f vdpau-mmiotrace | less
    /RAMIN32.*4de40000 (i.e. search for the PBSP offset)

would get you to the start of the mmiotrace, from my log I could see the RAMIN32 writes end at 4de50918, so I need to grab 4de[45].* for BSP firmware:

    $ demmio -f vdpau-mmiotrace | grep 'RAMIN32 .* 4de[45].* <=' | awk '{ print $7 }' | perl -ne 'print pack "I", hex($_)' > nvXX_fuc084

This was just for PBSP, but the same applies to PVP with fuc085, and PPPP with fuc086. Put the resulting files in /lib/firmware/nouveau/

Offsets may differ, and it is recommended to check you don't end up with too big or too small a file. Sometimes the addresses in memory will not lend themselves nicely to regular expressions. In that case, you can just manually extract the portion of the mmiotrace that you would like to end up in the fuc file and adjust the command above accordingly (i.e. start at `awk`).

---


## Extracting userspace video firmware (pre-GF117)

Requirements:

* libvdpau-dev, libpciaccess-dev, libx11-dev
* [[Valgrind-mmt]]
* build a recent envytools.git, and go to envytools.git/vdpow directory
* with nvidia drivers enabled and X server running, do:
* `/usr/local/bin/valgrind --tool=mmt --mmt-trace-file=/dev/nvidia0 --mmt-trace-nvidia-ioctls ./mmt_ufw 2>&1 | ./dumpstruct -m 10`
* Note: dumpstruct is not designed to work with the new binary logging format of mmt. But this firmware hasn't changed in a long time, just use the one output by the firmware extraction script.

Copy the resulting `vuc-*` files to `/lib/firmware/nouveau/`