G5: (And G4) Nouveau Modesetting Bug and Fix Explained

This is an expansion of the bug report Dan linked to in the previous post here at the PowerPC Liberation blog regarding a specific PPC bug which happened to break nouveau modesetting for PPC Nvidia card users. Much of what I am about to discuss is a already covered in relevant bug report, but I thought I would put it out here with the hope that more individuals would learn about the bug, what it consisted of, the workaround, and how it was fixed.  So with these goals in mind, let us move to the meat of this post.

The Bug

The same Debian user, Peter Saisanas, who reported on the page size and MSI interrupt issue with nouveau on G5 PowerMacs and supplied a working kernel for it, was also the individual who reported on the broken modesetting bug I am discussing in this post. Kernel versions starting after 3.18.16 started to showcase problems attempting to extract the FCODE ROM / DCB block for PPC machines' GPUs through the machine's Open Firmware (OF) device tree.

What are these FCODE ROMs and DCBs?  FCODE ROMs are essentially Open Firmware expansion image ROMs containing bytecode as well as PPC native code that include the necessary graphics device drivers and information for both boot-up and run time. It is one of the ways Apple closely tied the hardware with its software back in the day.

On the other hand, DCB stands for Data Control Block, which is at its very core just a type of data structure that describes the dataset in a program. In the context of our situation, it is just essentially the information about the graphics card's VBIOS and how and where to load it.

This is only part of the story though.  The question was why was it not extracting these two things properly? Turns out that the VBIOS within OF on PowerMacs does not contain a PCIR section (this holds information about the PCI expansion ROM), which the nouveau driver's VBIOS parser now requires by default.  The actual GPU PROM contains a PCIR section, but that is still separate from the OF VBIOS.

So with a PPC system unable to load this data, the kernel has a hard time communicating properly with your graphics card.  Which in turns means the Nvidia card's power and capabilities are not being fully utilized. And as a result of that, the end user ends up still using the nouveau driver, but with completely software rendered graphics.  This can be and usually is quite the disappointment in terms of performance on our old PPC machines.

The Workaround

The work around is quite simple and straightforward fortunately and will likely be the means for several users to at least have the 2D driver working until the patch hits mainline nouveau and works it way down into a later release of nouveau in Debian.  That is unless you want to try and install the patch of which I will discuss later.

Essentially, all that is needed is for you to download the x86 VGA BIOS ROM for your specific Nvidia card and configure (force) your system to load that firmware for your graphics card at boot up.  I will break it down in a few more steps though for the sake of simplicity.

1. Shutdown your system and pull out the graphics card to see exactly what manufacturer and BIOS your card consists of so you know what version you should download.

2.  Browse out to Tech Power Up's VGA BIOS database.  Search for and download the appropriate firmware for your card using the info you obtained earlier from the markings on the card.

3.  Once downloaded, rename it to something simple and related to your Nvidia card version.  For example, I used GeForce_7800_GS.fw for my Nvidia card. 
mv BFG.7800GS.256.051221.rom GeForce_7800_GS.fw

4.  Copy this file to your /lib/firmware/ directory.  You will need root permissions to do this.
sudo mv GeForce_7800_GS.fw /lib/firmware/

5. Add a line similar to below to your desired kernel(s) in your /etc/yaboot.conf file.
append="options nouveau config="NvBIOS=GeForce_7800_GS.fw"

6.  Apply the changes per usual.
sudo ybin -v

6. Reboot and once again enjoy 2D acceleration.

The Fix

Peter Saisanas reported a few days ago that a patch was created via a cloned code repository of the existing nouveau driver that should hopefully eventually hit mainline soon.  I thought it would be sort of interesting to view what changes were made in the commit to resolve the issue.

A direct link to the specific patch can be found here.  From the developer Ilia Mirkin's notes, the patch essentially forces the system to always accept the OF VBIOS.  The only changes made according to the commit were within the priv.h, shadow.c, and shadowof.c files. I thought it would be interesting to look and dissect some of those changes (mostly the ones I can figure out with a quick glance). Follow along with the highlighted changes you see within the link to the patch/commit above and you should be able to see some of what I am talking about.  I was going to post the code, but could not make it format and display in a clean and easily readable fashion as it would just squish everything into one line.

For the header file, two easily noticeable changes are two bool (true or false) variables that were added for the nouveau driver to be aware of whether or not the VBIOS it is parsing contains a PCIR section and another indicating whether the VBIOS checksum should be ignored or not.  A third size variable is declared as well that as we will see later holds the size of the OF VBIOS and image it has read. Pretty straightforward.

As for the edits in the other two files they are a bit more complex, but not much.  In shadow.c, an additional if statement is added to handle the situation where a PCIR section is NOT present. Also, an if statement below that was moved so that it was nested in the else statement in the above if else logic that is there for handling different situations that would result in debugging and error reporting.  After that you can see some additional logic added to an if statement to tell the nouvea driver to ignore invalid checksums.

Last, but not least, there is shadowof.c, which is probably the most difficult in terms of understanding the changes. First, a new header file (core/pci.h) was included. Based on name alone, I have a feeling this header defines the interface through which linux can communicate with the PCI bus and devices on a system. I am not entirely positive about the length calculation addition, but I do know a new of_size function has been created that simply returns the size of the data that has been extracted from OF and set inside of a size variable later on in the code.  Here, the two bools referenced earlier are set to true, which again basically forces the nouveau driver to always accept the image extracted from OF.  The rest is not as straightforward.  It would probably help tremendously to peruse some of the other code within the driver.

According to Peter, he was able to install the patch, but not without some additional edits to shadowof.c.  I have yet to attempt it myself, but will do so here in the next few days and post the required changes needed to install this latest patch.

Hopefully, you, the readers, have read this post and are taking away some new knowledge of nouveau, loading of roms, and reading code, as well as learned some new terms related to your PPC computers.  Once again, it is encouraging that these bugs are receiving attention and being fixed. I still strongly believe we can eventually reach a point where we can have 3D acceleration fully working on our Nvidia cards with the nouveau driver. It just involves us using our voice on the web, filing bug reports, testing the latest and greatest, and learning other ways we can help with and in development.

If you have any questions or additional comments about what I have covered here, I encourage you to drop a comment or email me directly.  Or if I am just flat out wrong about something, tell me as well as I would hate to be spreading false information.


  1. I really like the detail you went into for this. Great work, as always.

    1. As always, I appreciate the kind words! Seems progress on the nouveau driver for PPC is coming along nicely as can be read from Peter's comments below. I'm stoked.

  2. Awesome! I cannot wait to do this on my iMac G5. Thank you very much!

  3. Nice post B-Rock!
    Sounds like someone's been reading my posts on the Debian PPC Mailing lists! :)
    Great job detailing the info.

    I have great news for nouveau & ppc.
    Vanilla kernels > 4.3.0-rc6 have the fix in mainline to extract the NVidia BIOS / DCB block from FCODE correctly.
    I have compiled a mainline kernel and can create debs for G5 users if required.

    I believe from Mesa 11.0.3, it has a fix to translate display formats for BE arch machines for nVidia NV30+ class GPU's.
    Using Debian Sid repos, install mesa 11.0.4 and OpenGL is now working with G5 Quad and Quadro FX4500. Confirmed working with glxinfo and glxgears.

    Now us G5 + NVidia GPU users need a fix for 64kB kernel pagesize and MSI interrupts and general performance improvements and optimisations.

    Just wondering if anyone has thought about creating their own repository with recompiled debian packages with processor optimisations i.e. a g4 + altivec repo and g5 + altivec repo for key apps, libs & kernel's ?


  4. Thanks Peter. Much appreciated. I hope you don't mind me regurgitating your posts for others to read here on this blog. It seems many Linux users are interested in making nouveau work on their PPC machines, myself included.

    The news you shared is freaking fantastic and I'm excited to try these out as soon as I can this weekend on both my G5 and G4 machines. I dropped a few comments in the 64k page size bug and did hear back from one of the developers there stating he was going to try and unravel that mess. However, that was 3 months ago already, so I may poke that bug again.

    I do really like your idea of a dedicated repo. Perhaps its something a few of us over here at this blog would be able to help bring together. Either way, I'll look into it.

    Anyways, thanks again for all the work you do with your G5 PPC machine and the nouveau driver. Feel free to drop by anytime with any other updates, news, or even corrections to something I have said.


    1. No problem, I don't mind at all. Its actually nice to have someone confirm that the workarounds did indeed work for others!
      PPC Liberation blog posts are a great resource for people to get their PPC Macs running with Linux. Much better than wading through mailing list posts.

      From my understanding, typically official Debian PPC repo packages are just targeted for a generic 32 bit PPC target (at least the userland), everything from embedded uControllers to Power8.
      I suppose it is more or less just trying to figure out what apps & libs could benefit from optimised packages if recompiled for a specific CPU target (i.e. g4 and g5) and would they provide a measured worthwhile performance benefit?

      In theory, Gentoo would be great for this...


  5. Count another G5/Nvidia guy among you! I was almost at the end of the line with this machine, and the only functional gui I was able to get was through Yellow Dog. This machine was supposed to replace my Rasberry Pi as an arcade but it's an uphill battle so far!

  6. Cool! Nice to have a few more G5 / Nvidia users.
    If your running Debian with the testing repo's (stretch), mesa 11.0.6 also seems to work out of the box now (at least with nv47 anyway). Also if required, i have a newer precompiled Debian kernel package for the pmac 11.2 machines (4.4.0-rc2).

    Feel free to ask for help here or if running Debian on the Debian PPC mailing list.

    Lets try and level that hill out for you ! :)

  7. Richard,

    Are you using an affected kernel version as mentioned in the post above? If you are just using the stock kernel provided by Debian with the Jessie installer, you would not be affected by the FCODE ROM extraction bug. What issues are you having at the moment? Any one of us would love to help!

  8. I tried everything, nothing works on my power mac G5 Quad. No acceleration or 2d or 3d.

    [ 0.000000] Kernel command line: root=UUID=9279862b-d1be-4949-90f4-5881f2a82458 ro options nouveau config=NvBIOS=Nvidia_7800_GT.fw
    [ 12.653110] fb: switching to nouveaufb from OFfb NVDA,Displ
    [ 12.661746] nouveau 0000:0a:00.0: enabling device (0006 -> 0007)
    [ 12.662108] nouveau [ DEVICE][0000:0a:00.0] BOOT0 : 0x047200a1
    [ 12.662114] nouveau [ DEVICE][0000:0a:00.0] Chipset: G70 (NV47)
    [ 12.662119] nouveau [ DEVICE][0000:0a:00.0] Family : NV40
    [ 12.662224] nouveau [ VBIOS][0000:0a:00.0] checking OpenFirmware for image...
    [ 12.662252] nouveau [ VBIOS][0000:0a:00.0] ... checksum invalid
    [ 12.662257] nouveau [ VBIOS][0000:0a:00.0] checking PRAMIN for image...
    [ 12.662264] nouveau [ VBIOS][0000:0a:00.0] ... signature not found
    [ 12.662269] nouveau [ VBIOS][0000:0a:00.0] checking PROM for image...
    [ 12.753778] nouveau [ VBIOS][0000:0a:00.0] ... checksum invalid
    [ 12.753784] nouveau [ VBIOS][0000:0a:00.0] checking ACPI for image...
    [ 12.753793] nouveau [ VBIOS][0000:0a:00.0] ... signature not found
    [ 12.753798] nouveau [ VBIOS][0000:0a:00.0] checking PCIROM for image...
    [ 12.753828] nouveau 0000:0a:00.0: Invalid ROM contents
    [ 12.753840] nouveau [ VBIOS][0000:0a:00.0] ... signature not found
    [ 12.753844] nouveau [ VBIOS][0000:0a:00.0] checking PLATFORM for image...
    [ 12.753850] nouveau [ VBIOS][0000:0a:00.0] ... signature not found
    [ 12.753854] nouveau [ VBIOS][0000:0a:00.0] using image from OpenFirmware
    [ 12.753884] nouveau [ VBIOS][0000:0a:00.0] BIT signature found
    [ 12.753890] nouveau [ VBIOS][0000:0a:00.0] version
    [ 12.754233] nouveau [ PFB][0000:0a:00.0] RAM type: GDDR3
    [ 12.754239] nouveau [ PFB][0000:0a:00.0] RAM size: 256 MiB
    [ 12.754243] nouveau [ PFB][0000:0a:00.0] ZCOMP: 294912 tags
    [ 12.779188] nouveau [ VOLT][0000:0a:00.0] GPU voltage: 1200000uv
    [ 12.809571] nouveau [ PTHERM][0000:0a:00.0] FAN control: PWM
    [ 12.809593] nouveau [ PTHERM][0000:0a:00.0] fan management: automatic
    [ 12.809599] nouveau [ PTHERM][0000:0a:00.0] internal sensor: yes
    [ 12.829432] nouveau [ CLK][0000:0a:00.0] 20: core 275 MHz shader 275 MHz memory 1000 MHz
    [ 12.829441] nouveau [ CLK][0000:0a:00.0] 21: core 375 MHz shader 400 MHz memory 1000 MHz
    [ 12.829461] nouveau [ CLK][0000:0a:00.0] --: core 275 MHz shader 275 MHz memory 700 MHz
    [ 12.829596] nouveau 0000:0a:00.0: Using 32-bit DMA via iommu
    [ 12.829748] nouveau [ DRM] VRAM: 250 MiB
    [ 12.829753] nouveau [ DRM] GART: 512 MiB
    [ 12.829778] nouveau [ DRM] TMDS table version 1.1
    [ 12.829783] nouveau [ DRM] DCB version 3.0
    [ 12.829789] nouveau [ DRM] DCB outp 00: 01000100 00000028
    [ 12.829795] nouveau [ DRM] DCB outp 01: 03000102 00000000
    [ 12.829800] nouveau [ DRM] DCB outp 02: 04011210 00000028
    [ 12.829805] nouveau [ DRM] DCB outp 03: 04011212 00000000
    [ 12.829810] nouveau [ DRM] DCB conn 00: 1030
    [ 12.829815] nouveau [ DRM] DCB conn 01: 2130
    [ 12.832125] nouveau [ DRM] 0x1634: Parsing digital output script table
    [ 12.881648] nouveau [ DRM] 0x16B0: Parsing digital output script table
    [ 12.982570] nouveau [ DRM] allocated 1680x1050 fb: 0x8000, bo c00000017a51e400
    [ 13.002949] nouveau [ DRM] 0x1634: Parsing digital output script table
    [ 13.061508] nouveau 0000:0a:00.0: fb0: nouveaufb frame buffer device
    [ 13.061558] nouveau 0000:0a:00.0: registered panic notifier
    [ 13.061607] [drm] Initialized nouveau 1.2.1 20120801 for 0000:0a:00.0 on minor 0

  9. I think you should read this post first:

    You only need to load vga bios externally from file if using an affected kernel version on ppc with nouveau.
    This bug has been fixed however the post i mentioned before still applies!


  10. hi there,

    I want to report, that the fix does not work on my system (PowerMac G5 Dual 2.0 with NVIDIA FX4500 card)

    I downloaded the cards BIOS from the page you linked, but I got a ".rom" file, instead of a ".fw" file, like you did.

    I tried it anyways, by copy it to /lib/firmware and added the line in yaboot, pointing to that .rom file.

    When restarting, I got just some funny colored pixels and system freezes. Shortly before that, you can see something like "switch to fbcon" (something alike) and then the crazy scree comes up...

    I managed to switch back to "nouveau.noaccel=1" again in yaboot, and I got my desktop back - but withour 2D acceleration :(

    Really a shame, regarding this card inside my Mac...

    (I am on Kernel 4.4 ubuntu MATE 16.04LTS btw)

    Anyways, thanks for you blog - post !