Contribute
Register

[Guide] Intel Framebuffer patching using WhateverGreen

Maybe it is because I dumped prior to the original code being called (where the platform table is initialized). Duh!

Come to think of it, why does wrapGetOSInformation even work at all?

Shouldn't it be more like this?
Code:
uint64_t IGFX::wrapGetOSInformation(void *that) {
   // call original first!
   uint64_t r = FunctionCast(wrapGetOSInformation, callbackIGFX->orgGetOSInformation)(that);

#ifdef DEBUG
   if (callbackIGFX->dumpFramebufferToDisk) {
       char name[64];
       snprintf(name, sizeof(name), "/AppleIntelFramebuffer_%d_%d.%d", callbackIGFX->cpuGeneration, getKernelVersion(), getKernelMinorVersion());
       FileIO::writeBufferToFile(name, callbackIGFX->framebufferStart, callbackIGFX->framebufferSize);
       SYSLOG("igfx", "dumping framebuffer information to %s", name);
   }
#endif

   if (callbackIGFX->dumpPlatformTable)
       writePlatformListData("platform-table-native");

   if (callbackIGFX->applyFramebufferPatch)
       callbackIGFX->applyFramebufferPatches();
   else if (callbackIGFX->hdmiAutopatch)
       callbackIGFX->applyHdmiAutopatch();

   if (callbackIGFX->dumpPlatformTable)
       writePlatformListData("platform-table-patched");

   return r;
}
 
Shouldn't it be more like this?

I don't know I didn't write the dumping code. Thing is the dumping works for me so it must be initialized earlier on. Not sure exactly where?

EDIT: Maybe it's done in AppleIntelFramebufferController::start? I can see that AppleIntelFramebufferController::getOSInformation is called from there. I'm thinking that AppleIntelFramebufferController::start might be a better method to wrap now?
 
Last edited:
I don't know I didn't write the dumping code. Thing is the dumping works for me so it must be initialized earlier on. Not sure exactly where?

EDIT: Maybe it's done in AppleIntelFramebufferController::start? I can see that AppleIntelFramebufferController::getOSInformation is called from there. I'm thinking that AppleIntelFramebufferController::start might be a better method to wrap now?

Fixed with a new commit to platform_dump.
I don't see how the patching was working before. Need to call original getOSInformation before patching, then patch... (with dumps surrounding).

Now I get reasonable diffs from native->patched.
This is from my Skylake NUC6i7KYK:
Screen Shot 2018-10-01 at 9.51.50 AM.png


Please give my branch a try... Will it help you with your app to have the platform list right in ioreg?
 
Fixed with a new commit to platform_dump.
I don't see how the patching was working before. Need to call original getOSInformation before patching, then patch... (with dumps surrounding).

Perhaps the init is done earlier on for some FB kexts? I'm not sure. The thing is getOSInformation is called from AppleIntelFramebufferController::start so perhaps we should just wrap that instead?

Please give my branch a try... Will it help you with your app to have the platform list right in ioreg?

As long as the file dumping is working I'm not sure if we need the ioreg option?
 
Perhaps the init is done earlier on for some FB kexts? I'm not sure. The thing is getOSInformation is called from AppleIntelFramebufferController::start so perhaps we should just wrap that instead?

I think wrapping the getOSInformation is good...

As long as the file dumping is working I'm not sure if we need the ioreg option?

File dumping is not reliable. Never had it work here.
Plus I don't want the entire kext... I want just the ig-platform table.
And I want native vs. patched, both for verification the patches are doing what I want and as a diagnostic tool.

FYI: Not sure what my code does on SNB... need to check.. the SNB table is different than all the others.
 
I think wrapping the getOSInformation is good...

Well here are the signatures if you want to give ::start a try. I think it might be best.

Code:
auto fbStart = "__ZN31AppleIntelFramebufferController5startEP9IOService";
if (cpuGeneration == CPUInfo::CpuGeneration::SandyBridge)
    fbStart = "__ZN23AppleIntelSNBGraphicsFB5startEP9IOService";
else if (cpuGeneration == CPUInfo::CpuGeneration::IvyBridge)
    fbStart = "__ZN25AppleIntelCapriController5startEP9IOService";
else if (cpuGeneration == CPUInfo::CpuGeneration::Haswell)
    fbStart = "__ZN24AppleIntelAzulController5startEP9IOService";
else if (cpuGeneration == CPUInfo::CpuGeneration::Broadwell)
    fbStart = "__ZN22AppleIntelFBController5startEP9IOService";

File dumping is not reliable. Never had it work here.

Even after moving the dump after calling the original getOSInformation?

Plus I don't want the entire kext... I want just the ig-platform table.
And I want native vs. patched, both for verification the patches are doing what I want and as a diagnostic tool.

FYI: Not sure what my code does on SNB... need to check.. the SNB table is different than all the others.

If you think it's a worthy addition then by all means do a PR on it. If file dumping is not reliable I'll add support for it to Intel FB-Patcher.
 
Well here are the signatures if you want to give ::start a try. I think it might be best.

Code:
auto fbStart = "__ZN31AppleIntelFramebufferController5startEP9IOService";
if (cpuGeneration == CPUInfo::CpuGeneration::SandyBridge)
    fbStart = "__ZN23AppleIntelSNBGraphicsFB5startEP9IOService";
else if (cpuGeneration == CPUInfo::CpuGeneration::IvyBridge)
    fbStart = "__ZN25AppleIntelCapriController5startEP9IOService";
else if (cpuGeneration == CPUInfo::CpuGeneration::Haswell)
    fbStart = "__ZN24AppleIntelAzulController5startEP9IOService";
else if (cpuGeneration == CPUInfo::CpuGeneration::Broadwell)
    fbStart = "__ZN22AppleIntelFBController5startEP9IOService";

Hooking start doesn't help... we need to patch the platformlist after it is initialized, but before start finishes.

Even after moving the dump after calling the original getOSInformation?

Haven't tried it with my current code...
But even before, it should have dumped a file full of data. But instead I get zero length.

If you think it's a worthy addition then by all means do a PR on it. If file dumping is not reliable I'll add support for it to Intel FB-Patcher.

Will do... (but need to test [and fix] on Sandy Bridge first)...

The ioreg with just the platformlist saves a lot of time. (no need to hunt through a giant file for the platform data).
I wrote a little script to extract as separate files each dump.
Save as dump_platformlist.sh, then mark executable:
Code:
#!/bin/bash
#set -x

function capture_ioreg_data
# $1 is node name to search/capture
# $2 is file name to save XML to
{
    ioreg -n $1 -arxw0>$2
}

function extract_bin_property
# $1 is plist file name
# $2 is path within
# $3 is file name for binary output
{
    local data=$(/usr/libexec/PlistBuddy -x -c "Print :$2" $1 2>&1)
    data=$([[ "$data" =~ \<data\>(.*)\<\/data\> ]] && echo ${BASH_REMATCH[1]})
    echo "$data" | base64 --decode >$3
}

plist=/tmp/org.rehabman.platformlist.plist
capture_ioreg_data WhateverGreen $plist
if [[ ! -s /tmp/org.rehabman.platformlist.plist ]]; then
    echo "Error capturing WhateverGreen registry data (WhateverGreen not installed?)"
    exit 1
fi

for x in preinit native patched; do
    extract_bin_property $plist :0:platform-table-$x $x.bin
    xxd <$x.bin >$x.txt
done

#EOF

So, after booting, you can do this to see the effects of WhateverGreen patching:
Code:
./dump_platformlist.sh
diffmerge native.txt patched.txt

Or to just look at native data:
Code:
./dump_platformlist.sh
open -a "hex fiend" native.bin
 
Ok thanks to WhateverGreen Lilu and FBPatcher I know have a working accelerated UHD 630 running on B360 Coffee Lake with 2 HDMI and 1 VGA monitor running together on Mojave including HDMI audio and Realtek AC662 audio, and sleep works too. The only issue I still am having is I don't get a selection for 4k @ 30. I do get 4k @ 30 when the machine is not running with framebuffer so it might be possible. Does anyone have a suggestion on to make those options appear in the Display Options?

The only combination that has got this work for me is 18,1 device-id 0x3E920009 with this (note I am not sure where FB Patcher is finding 3E9B0007 for the ID I don't get the connections showing for it. Is it possibly a question of flags?

Screen Shot 2018-10-01 at 9.04.08 PM.png


Code:
igfx @ (DBG) patching framebufferId 0x3E920009
igfx @ (DBG) mobile: 0x00000001
igfx @ (DBG) patching framebufferId 0x3E920009 connector [1] busId: 0x01, pipe: 9, type: 0x00000800, flags: 0x000003C7
igfx @ (DBG) patching framebufferId 0x3E920009 connector [2] busId: 0x02, pipe: 10, type: 0x00000800, flags: 0x000003C7
igfx @ (DBG) patching framebufferId 0x3E920009 connector [3] busId: 0x05, pipe: 8, type: 0x00000010, flags: 0x000001C7
igfx @ (DBG) Patching framebufferId 0x3E920009 successful

If you need further info let me know

Martin
 
The only issue I still am having is I don't get a selection for 4k @ 30.

Try to set Patch->Advanced->Enable HDMI20 (4K) and then export your patch again.

note I am not sure where FB Patcher is finding 3E9B0007 for the ID I don't get the connections showing for it.

Intel FB-Patcher displays your current Platform Id under General->System Info->Platform Id. Are you saying it's detecting it incorrectly?
 
Try to set Patch->Advanced->Enable HDMI20 (4K) and then export your patch again.

It is there already and shows in ioreg

Intel FB-Patcher displays your current Platform Id under General->System Info->Platform Id. Are you saying it's detecting it incorrectly?
If I select the real ID I don't get the proper connection view.

Martin
 
Back
Top