Blank Display when HD 4000 Loads

So despite my efforts so far, i’m plagued by this problem of the screen going blank when the Intel HD 4000 Framebuffer driver loads. even in safe mode.

This has nothing to do with the Intel HD4000 Graphics kext it seems, instead it the AppleIntelFrameBufferCapri.kext.

 

The problem exists in the following versions so far…

  • Lion 10.7.5
  • Mountain Lion 10.8.1
  • Mountain Lion 10.8.2
  • Mountain Lion 10.8.3
  • Mountain Lion 10.8.4
  • Mountain Lion 10.8.5 (Beta 12F13)
  • Mavericks 10.9 DP2

..which at the time of updating, it every version.

There are many posts around the internet from people having no display, but this almost always turns out to be people not using the correct platform id on their laptop. It normally ends with a post saying ‘i fixed it by injecting this string (which actually injects the correct platform id) or “i ended up using chimera 1.11.something” (which again actually just injects the correct platform id).

Instead my problem is that the display IS detected, but the output to the panel isn’t being activated. It seems that the driver outputs the display on AAPL,DisplayPipe 00 00 00 00 which is where it expects the display on port 04 06 to be.

Display Detected

The only other output port available on this All-in-One is, oddly, VGA. So I plugged a monitor into this port to see what happened, and as soon as the display enables, garbage is output onto the VGA screen! The reason for this, I can only assume, is that display pipe 00 00 00 00 is actually the VGA port, not the internal display, and its garbled because its sending the wrong signal type, DisplayPort.

By searching around the internet, and thanks to various hackintosh folks around the forums eep357, toledo, bcc7 et al, i’ve been able to crack on with some tests.

The Apple driver has VGA support, but its not enabled in any of the Platform IDs, which means i needed to edit the file with a Hex Editor for the platform ID i am using.

I’ve found the tables in the file by searching for ‘05006201’ and changed the entries to that the first port so 0602 (VGA) the second is 0406 (DisplayPort) and the third is 0304, which i think is HDMI, i just shuffled it there to fill up the space.

original before edit mod vga

So with that change made, it made no difference to the output on both screens, even though both displays are now detected.

VGA Built-in

It’s worth noting that the first entry is always seen as ‘built-in’. I’ve tried swapping the devices around and it doesn’t fix my issue.

but, from here i can see that the VGA uses AAPL,DisplayPipe 01 00 00 00.

DisplayPipe1

For my next experiment, I decided to edit out the internal display 0406, and just try and run on VGA only. the resulted in the internal display suddenly  coming to life! sadly, it was the garbled VGA display pipe I was seeing. but…it’s something!

So from this I can conclude, that its sending the displayport signal down pipe 0 which is physically the VGA output, and the VGA signal down pipe 1 which is the display port output. This currently explains everything.

Windows has no such issues, so i thought i would give a Linux install a go, seen what happens. At the time, only Ubuntu 12.10 and Mint 14 have support for HD4000 out of the box. Lo and behold, as soon as they load up, the screen goes off in exactly the same way. It does appear that both drivers seem to make an incorrect assumption that the display will be on pipe 0. in fact i think this All in one is the only computer i’ve used so far configured in this odd way with the pipes inverted.

Now, the chances of Apple changing their driver for me are pretty much zero, so i’m now trying to establish how this pipe to port layout is defined, is it hardwired into the motherboard design? or is set in the bios somewhere?

According to the ACPI specs, the _DOD method defines what is connected to what pipe and port:

Method (_DOD, 0) {
    Return (
Package()
{
0x00000110, // Primary LCD panel, not detectable by BIOS
0x80000100, // CRT type display, not detectable by BIOS
0x80000220, // TV type display, not detectable by the BIOS
0x80000411, // Secondary LCD panel, not detectable by BIOS</pre>
} )
}

Examples:
0x000xyyyy // Bit 31 = 0. Other proprietary scheme - 0x110 Device ID is an exception. (See Note 3)
0x00000110 // Integrated LCD Panel #1 using a common, backwards compatible ID
0x80000100 // Integrated VGA CRT or VESA compatible Monitor #1 on Port0
0x80000240 // Integrated TV #1 on Port4
0x80000410 // Integrated Internal LCD Panel #1 on Port1
0x80000421 // LVDS Panel #2 Dual-Link using Port2 & 3. (See Note 4)
0x80000131 // VGA CRT or VESA compatible Monitor #2 on Port3
0x80000121 // Dual-Link VGA CRT or VESA compatible Monitor #2 using Port2 & 3. (See Note 4.)
0x80000320 // DVI Monitor #1 on Port2 (shares Port2 with a Dual-Function DVI/TV Encoder). (See Note 5)
0x80000331 // DVI Monitor #2 on Port3
0x80000330 // Dual-Link DVI Monitor #1 using Port2 & 3
0x80000231 // TV #2 on Port2 (shares Port2 with a Dual-Function DVI/TV Encoder). (See Note 5)

ACPI DOD Spec

On the old MacBook here, the _DOD method looks nice and simple like this, but on this All-in-One computer its huge and complex, full of NDID sections and external checks. I’ve checked on a few other modern computers and they seem to follow the same template.

On the iMac 13,1 the HD 4000 isnt used at all, and the _DOD for the nVidia display matches this example above, it resides in the SSDT-5 table:

            Method (_DOD, 0, NotSerialized)
            {
                Return (Package (0x01)
                {
                    0x80002400
                })
            }

Which should equate to internal flat panel, on display port 0, with display index 0.

On the MacBookPro10,2, also in SSDT-5, we have the same complex layout I mentioned before:

  Method (_DOD, 0, NotSerialized)
    {
            If (CondRefOf (IDAB)) {}
            Else
            {
                Store (0x00, NDID)
                If (LNotEqual (DIDL, Zero))
                {
                    Store (SDDL (DIDL), DID1)
                }

                If (LNotEqual (DDL2, Zero))
                {
                    Store (SDDL (DDL2), DID2)
                }

                If (LNotEqual (DDL3, Zero))
                {
                    Store (SDDL (DDL3), DID3)
                }

                If (LNotEqual (DDL4, Zero))
                {
                    Store (SDDL (DDL4), DID4)
                }

                If (LNotEqual (DDL5, Zero))
                {
                    Store (SDDL (DDL5), DID5)
                }

                If (LNotEqual (DDL6, Zero))
                {
                    Store (SDDL (DDL6), DID6)
                }

                If (LNotEqual (DDL7, Zero))
                {
                    Store (SDDL (DDL7), DID7)
                }

                If (LNotEqual (DDL8, Zero))
                {
                    Store (SDDL (DDL8), DID8)
                }
            }

            If (LEqual (NDID, 0x01))
            {
                Name (TMP1, Package (0x01)
                {
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP1, 0x00))
                Return (TMP1)
            }

            If (LEqual (NDID, 0x02))
            {
                Name (TMP2, Package (0x02)
                {
                    0xFFFFFFFF,
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP2, 0x00))
                Store (Or (0x00010000, DID2), Index (TMP2, 0x01))
                Return (TMP2)
            }

            If (LEqual (NDID, 0x03))
            {
                Name (TMP3, Package (0x03)
                {
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP3, 0x00))
                Store (Or (0x00010000, DID2), Index (TMP3, 0x01))
                Store (Or (0x00010000, DID3), Index (TMP3, 0x02))
                Return (TMP3)
            }

            If (LEqual (NDID, 0x04))
            {
                Name (TMP4, Package (0x04)
                {
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP4, 0x00))
                Store (Or (0x00010000, DID2), Index (TMP4, 0x01))
                Store (Or (0x00010000, DID3), Index (TMP4, 0x02))
                Store (Or (0x00010000, DID4), Index (TMP4, 0x03))
                Return (TMP4)
            }

            If (LEqual (NDID, 0x05))
            {
                Name (TMP5, Package (0x05)
                {
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP5, 0x00))
                Store (Or (0x00010000, DID2), Index (TMP5, 0x01))
                Store (Or (0x00010000, DID3), Index (TMP5, 0x02))
                Store (Or (0x00010000, DID4), Index (TMP5, 0x03))
                Store (Or (0x00010000, DID5), Index (TMP5, 0x04))
                Return (TMP5)
            }

            If (LEqual (NDID, 0x06))
            {
                Name (TMP6, Package (0x06)
                {
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP6, 0x00))
                Store (Or (0x00010000, DID2), Index (TMP6, 0x01))
                Store (Or (0x00010000, DID3), Index (TMP6, 0x02))
                Store (Or (0x00010000, DID4), Index (TMP6, 0x03))
                Store (Or (0x00010000, DID5), Index (TMP6, 0x04))
                Store (Or (0x00010000, DID6), Index (TMP6, 0x05))
                Return (TMP6)
            }

            If (LEqual (NDID, 0x07))
            {
                Name (TMP7, Package (0x07)
                {
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP7, 0x00))
                Store (Or (0x00010000, DID2), Index (TMP7, 0x01))
                Store (Or (0x00010000, DID3), Index (TMP7, 0x02))
                Store (Or (0x00010000, DID4), Index (TMP7, 0x03))
                Store (Or (0x00010000, DID5), Index (TMP7, 0x04))
                Store (Or (0x00010000, DID6), Index (TMP7, 0x05))
                Store (Or (0x00010000, DID7), Index (TMP7, 0x06))
                Return (TMP7)
            }

            If (LEqual (NDID, 0x08))
            {
                Name (TMP8, Package (0x08)
                {
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF,
                    0xFFFFFFFF
                })
                Store (Or (0x00010000, DID1), Index (TMP8, 0x00))
                Store (Or (0x00010000, DID2), Index (TMP8, 0x01))
                Store (Or (0x00010000, DID3), Index (TMP8, 0x02))
                Store (Or (0x00010000, DID4), Index (TMP8, 0x03))
                Store (Or (0x00010000, DID5), Index (TMP8, 0x04))
                Store (Or (0x00010000, DID6), Index (TMP8, 0x05))
                Store (Or (0x00010000, DID7), Index (TMP8, 0x06))
                Store (Or (0x00010000, DID8), Index (TMP8, 0x07))
                Return (TMP8)
            }

            Return (Package (0x01)
            {
                0x0400
            })
        }

Underneath this is a few devices called (DD01), (DD02) and so forth, DD02 is the only one with _BCL, _BCM and _BQC methods, indicating that this is the device that relates the internal panel.

I get the feeling that I’m on another long path of understanding, only to end up understanding that this isn’t going to fix it anyway!

Trying to get HD 4000 Graphics working on the Mountain Lion (10.8) hackintosh

Firstly, I wanted to get the Graphics acceleration working correctly, it took me a while to find a 65W Ivy Bridge CPU with HD4000, and if this doesn’t work correctly then the rest of the build is mostly useless. After a quick google search, and thanks to a great post by proteinshake on the insanelymac forums, I was able get the AAPL,ig-platform-id info, which I’ve since been able to flesh out with some more info.

There are two main drivers involved here, the first is AppleIntelFrameBufferCapri,kext, and this is responsible for driving the monitor, so if we’re getting no picture at all, this is the likely cause.

The Second is AppleIntelHD4000Graphics.kext which seems to be responsible for the Graphics Acceleration.

In order to trigger these, we need to inject a property into the DSDT tables. This property is called “AAPL,ig-platform-id” are there are 12 possible values, which relate to various Mac models that can use this chipset.

AAPL,ig-platform-id Model Assigned RAM Pipes Ports FB Mem
01 66 00 00  <unknown> 96MB 3 4 3
01 66 00 01  MacBookPro10,2 96MB 3 4 3
01 66 00 02  MacBookPro10,1 64MB 3 1 1
01 66 00 03  MacBookPro9,2 64MB 3 4 2
01 66 00 04  MacBookPro9,1 32MB 3 1 1
01 62 00 05  iMac13,1 (Edu) 32MB 2 3 2
01 62 00 06  iMac13,1 0MB 0 0 0
01 62 00 07  iMac13,2 0MB 0 0 0
01 66 00 08  MacBookAir5,1 64MB 3 3 3
01 66 00 09  MacBookAir5,2 64MB 3 3 3
01 66 00 0A  MacMini6,1 32MB 2 3 2
01 66 00 0B  MacMini6,2 32MB 2 3 2

The device propery is injected into DSDT in the IGPU (or GFX0) Section, and it looks something  like this:

Device (IGPU)
          {
          Name (_ADR, 0x00020000)
          Method (_DSM, 4, NotSerialized)
                    {
                    Store (Package (0x02)
                              {
                              &amp;quot;AAPL,ig-platform-id&amp;quot;,
                              Buffer (0x04)
                                       {
                                       0x05, 0x00, 0x62, 0x01
                                       }

                              }, Local0)
                     DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                     Return (Local0)
                     }
          }

I chose Platform ID 01620005, which seems to be for the low-end education model iMac using the processor’s HD4000 for its graphics. Also, my BIOS has the graphics memory locked at 64MB, so the first two platform ID types just crash. when using this my display gets detected on framebuffer @2…

displaydetected displayinfo…meaning that my Display gets detected on any of the ones that have 04 06 present.  Below is a table of which ports each platform ID is configured with. You’ll often see this referred to as a ‘connector table’

AAPL,ig-platform-id @0 @1 @2 @3
01 66 00 00 01 00 (LVDS) 02 05 (DisplayPort) 03 04 (DisplayPort) 04 06 (DisplayPort)
01 66 00 01 01 00 (LVDS) 02 05 (HDMI) 03 04 (DisplayPort) 04 06 (DisplayPort)
01 66 00 02 01 00 (LVDS)
01 66 00 03 05 03 (LVDS) 02 05 (DisplayPort) 03 04 (DisplayPort) 04 06 (DisplayPort)
01 66 00 04 05 03 (LVDS)
01 62 00 05 02 05 (DisplayPort) 03 04 (DisplayPort) 04 06 (DisplayPort)
01 62 00 06
01 62 00 07
01 66 00 08 01 00 (LVDS) 02 05 (DisplayPort) 03 04 (DisplayPort)
01 66 00 09 01 00 (LVDS) 02 05 (DisplayPort) 03 04 (DisplayPort)
01 66 00 0A 02 05 (DisplayPort) 03 04 (DisplayPort) 04 06 (HDMI)
01 66 00 0B 02 05 (DisplayPort) 03 04 (DisplayPort) 04 06 (HDMI)

Despite this tried and tested method, for some odd reason, on this All in One computer, the internal display just goes off! I had to take these screen shots via screen sharing on my MacBook. and yet I know this method works, and that it should be working normally here.

After a few months on and off (mostly off) I finally worked out what is going on, which i’ll put in my next post.

Image

Building a hackintosh All in One with Mountain Lion

Apple don’t (yet) make an iMac that I want to buy, nor do they seem interested in doing so. Previously there were several reasons, but to date the only thing left is the ability to use the iMac as a display for my games console or any other HDMI device I wish to use it with.

Earlier ones had target display, but this was only available on the 27″ model ,which is far too big for me, and the only way to use HDMI on it was via an adaptor that would only support 720p and was reported to be not that reliable anyway.

The fun finally started when barebone AIO chassis started to appear with the Thin Mini-ITX standard, meaning you could build yourself a decent AIO and upgrade later also. Then came the Ivy Bridge processors with built-in graphics that I would consider just about good enough to use.

Moving away from my self built windows PC, which was a Core 2 Quad and Radeon 4830, which I was happy with performance wise, I set out to build an AIO hackintosh, as closely powerful as I could make it. The result so far:

  • Quad Core i5 3475S Ivy Bridge CPU (HD 4000)
  • 8 GB RAM
  • AIO Chassis with H61 chipset motherboard including HDMI Input
  • OS X Mountain Lion 10.8
  • Broadcom 4322AG a/b/g/n half size Wi-Fi

The target is, to use the software with no changes to the OS. Additional Kexts to make it work are acceptable.