quarta-feira, 4 de março de 2015

[Guide] Patching LAPTOP DSDT/SSDTs

Overview

In order to make many OS X features work well on a laptop, you will always need a properly patched DSDT (and SSDTs). The purpose of this guide is to provide a foundation for proper patching of your OEM DSDT/SSDTs.

Although you may be tempted to use a DSDT from another computer, it will almost always end in failure. You simply cannot be certain it is valid to use ACPI files from another computer. Even minor differences in hardware configuration can make for differences that cause instability and weird bugs if you use foreign ACPI files.

The process of patching involves several steps:
- extracting native files
- disassembling the native files
- analysing and filtering the native files
- patching
- saving (compiling) and installing


Extracting native ACPI files

All BIOS implementations provide ACPI files to the OS. So, on any OS, you can extract them for patching later. Extraction can therefore be done on Linux, OS X, Windows, or even in the Clover bootloader. Native files extracted are generally identical, although because of the software used to extract, they may be named differently.

This guide will focus on three methods of extraction: Using patchmatic in OS X, using F4 with Clover, or using Linux.

Extracting with 'patchmatic':

If you've already installed OS X, provided you're not currently booting with any patched ACPI files, you can extract your native DSDT/SSDT with patchmatic. Download the patchmatic binary here:https://github.com/RehabMan/OS-X-MaciASL-patchmatic (be sure to read the README as the download location is linked from it). For ease of use in Terminal, you should copy the binary (inside the ZIP) to /usr/bin. 

After installing patchmatic, you can invoke it in Terminal, as such:

Code:
cd ~/Desktop
mkdir extract
cd extract
patchmatic -extract
The patchmatic binary will extract all loaded ACPI files and place them in the current directory. If you're using any options in the bootloader that affect the injected DSDT/SSDT, you will not get native ACPI files, so be sure you're not using those options. For example, if you're using (Chameleon) DropSSDT=Yes, or (Clover) DropOem=true, the native SSDTs are being dropped before OS X can load them, so you'll be missing them in the patchmatic output. Same goes for any Clover DSDT "Fixes" -- those fixes are patching the native DSDT, and to do your own DSDT patching, you don't want that. Options such as GeneratePStates/GenerateCStates=Yes, or with Clover /ACPI/SSDT/Generate/CStates /ACPI/SSDT/Generate/PStates will inject extra SSDTs which can cause complications with disassembly.

It is for all those reasons, it is often easier to extract via Linux or using Clover F4.

Note: Using 'patchmatic -extract' to confirm you're patching DSDT/SSDTs as you expect is a useful diagnostic tool.


Extracting with Clover F4:

At the main Clover bootloader screen, you can press F4 and Clover will dump the native ACPI files to EFI/Clover/ACPI/origin. You can then access them after you boot OS X to disassemble them and patch. Note that some BIOS implementations reverse the function of Fn+F4 with F4, so when in doubt, press both Fn+F4 and F4. There is no feedback during or after the dump, just a slight delay as the files are written. The delay is more noticeable if they are being written to USB, as would be the case when booting from a Clover USB.

Sometimes, Clover F4 will write duplicate SSDTs. These duplicates will cause problems during disassembly. If you run into issues (duplicate definitions) during disassembly, you will need to analyse all SSDTs to eliminate the files which are duplicate. For this reason, it is sometimes easier to extract via Linux, since I've never seen Linux show duplicate SSDTs.


Extracting with Linux:

In Linux, the native ACPI files are available directly from the file system. You can find them at /sys/firmware/acpi/tables and /sys/firmware/acpi/tables/dynamic. It is possible to copy the entire set with a single command in Terminal.

It is not necessary to install Linux. Simply run it from USB:http://www.ubuntu.com/download/deskt...ick-on-windows.

In Linux Terminal:
Code:
# substitute DEST with the mountpoint of a FAT32 formatted USB stick
sudo cp -R /sys/firmware/acpi/tables DEST
You should copy the files to a FAT32 formatted USB. Using FAT32 avoids permissions issues as FAT32 has no file permissions. The value of DEST for an auto-mounted USB will depend on the version of Linux you're using and how you booted it. You can see the mount-point by typing 'mount' in Terminal, or hover your mouse over the volume name in the Linux file explorer.


Disassembling ACPI files

Although the extracted native files can be opened directly in MaciASL, it is not recommended. Opening an AML file directly in MaciASL will cause MaciASL to disassemble the file (with iasl) standalone, and if the AML has complex references to other AMLs, it will not disassemble it correctly. You'll be left with many hard to fix errors.

As a result, it is better to disassemble all files as a group using iasl in Terminal. To prepare, place all DSDT and SSDT files in a single directory (DO NOT copy ACPI files that don't begin with DSDT or SSDT), and change the names such that they have an .aml extension. You will need a recent build of iasl to disassemble them properly. There is an appropriate version available here:https://bitbucket.org/RehabMan/acpica/downloads. It is a good idea to copy the iasl binary to your path (eg. /usr/bin), so it is easily accessed from Terminal.

In OS X Terminal:
Code:
cd "to directory where you placed all SSDT/DSDT"
iasl -da -dl *.aml
Note: Do NOT attempt to disassemble other ACPI files with the -da option. It will not work.

From this point onward, you will work exclusively with the resuling *.dsl files using MaciASL. Of course, to use them you must save as "ACPI Machine Language Binary" with an extension .aml and place them where they will be loaded by the bootloader. But keep your patched .dsl files in case you need to apply more patches in the future.


Filtering ACPI files

It is common to generate an SSDT for your CPU and native SSDTs for the CPU can cause conflicts with the generated SSDT. For this reason, most power management guides will include instructions for "dropping" OEM SSDTs. But dropping all OEM SSDTs, especially with newer computers where more ACPI content has been moved from DSDT to SSDTs, is a sledge hammer when you need a ballpeen hammer. Eliminating just the SSDTs that are CPU related and those that are not necessary (or SSDT likely to cause other problems), and keeping other important SSDTs for patching or inclusion unpatched is an important next step.

Note: The 'x' SSDTs from a Clover dump and likewise the SSDTs in the dynamic subdirectory from a Linux dump are loaded dynamic and are never included in ACPI/patched (they are SSDTs loaded on-demand with ACPI Load from SystemMemory).

After you successfully disassemble your files, look at each one in an attempt to determine the SSDT's purpose. If it is CPU related, set it aside, and don't include it in your final set for injection via the bootloader. For the most part, SSDTs with objects declared in Scope _PR.CPUx are likely CPU related and can be eliminated.

Side note: With my Lenovo u430, I'm experimenting with leaving the CPU SSDTs intact (fixing errors, of course). At this point, I'm not sure if there is any advantage, but it does avoid using certain DSDT patches such as "Fix PNOT/PPNT" and it does appear to be working just as well.

Here are some typical SSDTs you'll find:

- SATA: Can be excluded or included... your choice.
- PTID: Usually this file is useless for OS X and contains many errors. In rare cases, it may provide clues for how to read fan speed, temperature, or other system status.
- IAOE: If this SSDT is present, it is usually accessed from DSDT in _PTS and _WAK. Sleep may not work properly without it.
- GFX0: Usually the SSDT with 'Device GFX0' will be for integrated graphics. This is the SSDT you patch for backlight control. With older laptops, GFX0 is usually defined in DSDT. With newer Haswell laptops, it is usually defined in SSDT (although it can also be in DSDT).
- PEGP: PEGP usually corresponds to the discrete card in a switched dual-GPU configuration. There can be more than one, and usually you will need to include all of them as a group in order to accomplish any meaningful patching. These SSDTs should be patched if you wish to disable the discrete card when running OS X.

It is a good idea to keep notes on what the purpose of each SSDT is and which ones you plan to "drop", which ones you plan to keep unmodified, and those that you plan to patch.


Fixing Errors

Even by disassembling all at once (iasl with -da option), the native files can still have errors. The disassembled files have errors due to changes in iasl over time, imperfections in iasl itself, and differences in the compilation environment between our laptops and the OEM. A common cause of errors (my theory), for example, is that some of the methods referenced are actually inside Windows (MMTB and MDBG for example). There is also clearly cases where bugs are in the code or code was written uninitentionally (sometimes hard to tell the difference).

So.. after determining which files you need, you must patch them so they compile without errors. There are many common patches for such errors in my laptop patch repository for MaciASL.

MaciASL: https://github.com/RehabMan/OS-X-MaciASL-patchmatic
Laptop Patches: https://github.com/RehabMan/Laptop-DSDT-Patch

Note: I do not test my patches with DSDT Editor. It has too many bugs and a very old version of iasl. Please do not ask me about it.

Be certain to always read the README, in order to download from the correct location and in order to setup MaciASL correctly. The patches for syntax/error problems begin with "[syn]" in the name. Common examples for older DSDTs are "Fix _PLD Buffer/Package Error", "Fix TNOT Error", and "Fix FPED Parse Error". In order to determine which patch you need, you can look at the error message coming from the iasl compiler and the code at the line the error was detected. You can also attempt to apply a patch just to see if it makes changes as shown in the Preview window in MaciASL. If you're not familiar with each type of error, it can take some experimentation and trial/error.

For some errors, you can simply remove the line of code causing the error. But, it depends on whether the line is necessary for proper operation of the code or not. For example, errors caused by 'External' declarations can generally be removed to fix the error. If you wish, you can create automated patches of your own to remove these lines.

It helps to have some experience with the ACPI spec and some programming experience.

Your goal is to get each .dsl file to compile without errors (warnings/remarks/optimizations are ok). Once you have files that compile without errors, you can move on to patching them to fix issues you may have with your OS X installation.


Common Patches

Generally, a DSDT patch should only be applied after finding a need for that specific fix. But there are several patches that are commonly needed and that have only a small chance of causing a problem. They are in my laptop repo and are listed here:
"Fix _WAK Arg0 v2"
"HPET Fix"
"SMBUS Fix"
"IRQ Fix"
"RTC Fix"
"OS Check Fix"
"Fix Mutex with non-zero SyncLevel"
"Fix PNOT/PPNT"
"Add IMEI"

The USB patches can be used to fix "instant wake" where the laptop will not sleep without waking up seconds after sleep begins.

Apply the patch appropriate for your hardware:
"6-series USB"
"7-series/8-series USB"

The USB3 Mutliplex patch can assist in using AppleUSBXHCI.kext isntead of GenericUSBXCHI.kext. It is based on information published by Mieze. Most DSDTs will need modifications to use it. The ProBook, for example, uses a modified version of this patch. And the Lenovo u310/u410 can use it as-is:
"7-series USB3 Multiplex"

If you have a Haswell CPU/8-series chipset, and AppleLPC.kext is not loading, you should use this patch to inject a compatible ID that will allow it to load:
"Haswell LPC"

Note regarding renames: Renames must be "balanced." It is common to rename objects to better match what OS X expects (example "Rename GFX0 to IGPU" for proper IGPU power management). In such cases, all DSDT/SSDTs with references to that name must also be renamed.

Note regarding duplicate identifiers: You must be sure that your patched files do not contain duplicate identifiers. A common case would be adding a _DSM method to a given path in one SSDT, where the OEM has defined a _DSM at the same path in another SSDT. To avoid this problem, you can use the "Remove _DSM methods" patch as one of the first patches you do to all DSDT/SSDTs.


Problem specific patching

Battery status: [Guide] How to patch DSDT for working battery status

Backlight control: http://www.tonymacx86.com/yosemite-l...t-control.html

Disabling nVidia/Radeon discrete graphics: TBW

When following a guide for a specific laptop, it may instruct you to apply a patch that is provided in the post itself. You will recognize it as the syntax used will look similar to other patches you've seen in the repository (eg. 'into_all method label FOO code_regex xxyy removeall_matched;'). These patches are intended to be pasted directly into the patch window in MaciASL so they can be applied.

If you're interested in writing your own patches, read the documentation on MaciASL patch grammar:http://sourceforge.net/p/maciasl/wik...tax%20Grammar/

Note: In many cases, DSDT patches are used in conjunction with additional kexts, patched kexts, or Clover config.plist patches that patch the system kexts as they are loaded.


Patches for using patched AppleHDA

With patched AppleHDA, there are two patches that are needed in conjunction with the kext:
"Audio Layout 12" (change the layout-id from 12 to the one used by your DSDT)
"IRQ Fix"

Note that you must have an AppleHDA that matches your codec, and must determine which layout-id was chosen. The layout-id is an arbitrary choice by the creator of the patched AppleHDA.

To determine the layout-id used by a particular patched AppleHDA: First you need to know your codec id in decimal (eg. 0x10ec0269 = 283902569). Then look in the Info.plist for AppleHDAHardwareConfigDriver.kext (at AppleHDA.kext/Contents/PlugIns/AppleHDAHardwareConfigDriver.kext/Contents/Info.plist), find your codec id under HDAConfigDefault (there may be many entries in a sloppy patched AppleHDA or only one). The LayoutID that matches your codec id is the layout id you need. It is possible that a patched AppleHDA contains more than one layout-id for a given codec. In that case, choose the one you want to use.


Saving files for loading by the bootloader

In order to use your patched DSDT/SSDTs, you must save them where the bootloader can load them. Each bootloader location is unique and has different requirements for naming. Files must be saved in "ACPI Machine Language Binary" (MaciASL->Save As). Saving a text file (dsl) with an AML extension will likely cause panic or very strange behavior in OS X.

Clover: Files should be placed on the Clover bootloader partition (usually the EFI partition), in EFI/Clover/ACPI/patched. DSDT.aml, if present, will automatically replace the OEM DSDT. For versions of Clover prior to v3062, SSDTs must be named SSDT-x or SSDT-xx, where 'x' is a digit (up to SSDT-19). Clover allows gaps in the numbering (eg. SSDT-1.aml, SSDT-5.aml, SSDT-6.aml is allowed). Clover version v3062+ will load all *.aml files present in ACPI/patched, with no restrictions on the name. Keep in mind that SSDT loading order is important. The original order of the SSDTs must be maintained in the patched set.

Note regarding Clover v3062+: A change in the way SSDTs are loaded from ACPI/patched makes the order non-deterministic. You should specify the order explicitly with config.plist/ACPI/SortedOrder. See here for more info: http://www.projectosx.com/forum/inde...ndpost&p=43690. The SortedOrder option is implemented in Clover v3088+. More background information starts at this post here:http://www.projectosx.com/forum/inde...ndpost&p=43674

Chameleon(or Chimera): Files should be placed in /Extra on the system volume (or wherever your bootloader /Extra configuration is located). DSDT.aml, if present, will automatically replace the OEM DSDT. Chameleon requires there are no gaps in the names of SSDTs. It will load SSDT.aml, SSDT-1.aml, SSDT-2.aml, SSDT-3.aml, and so-on from /Extra until it does not find the file in the sequence. So, if you have SSDT.aml, SSDT-1.aml, SSDT-4.aml, SSDT-5.aml, only SSDT.aml and SSDT-1.aml will be loaded. SSDT-4.aml and SSDT-5.aml will be ignored.

Finally, keep in mind you cannot provide patched SSDTs without dropping the OEM SSDTs that they replace. The easiest way is to use DropSSDT=Yes (Chameleon) or ACPI/SSDT/DropOem=true (Clover) to drop all the SSDTs, then provide the patched (and unpatched) files for loading by the bootloader.


Floating regions

In ACPI, an OperationRegion can define a MMIO region, SystemMemory region, EmbeddedControl region, etc. These regions usually have fixed addresses dependent only on the machine configuration, BIOS version, or BIOS options. Sometimes, these regions can change randomly or unexpectedly. This is referred to as "floating regions".

Since by patching DSDT and/or SSDTs, we are providing a snapshot of these addresses at a given point in time, they may not match up should the BIOS decide to place such regions at a different address. If this is the case, you may notice that certain features are intermittently working, or other stability issues that appear to be random.

As a result, it is a good idea to use Clover and its FixRegions feature. You can find the details in the Clover Wiki. All of the config.plist files in the Clover laptop guide use this feature. Note: Only floating regions in DSDT can be fixed by FixRegions. Floating regions in SSDTs are problematic and there is no good solution other than to not provide patched SSDTs for SSDTs subject to randomly floating regions. Working around floating regions in patched SSDTs is beyond the scope of this guide.


Resources

MaciASL (RehabMan fork): https://github.com/RehabMan/OS-X-MaciASL-patchmatic
patchmatic: https://github.com/RehabMan/OS-X-MaciASL-patchmatic
iasl (RehabMan fork): https://bitbucket.org/RehabMan/acpica/downloads
ACPI spec: http://acpi.info/spec.htm

RehabMan github: https://github.com/RehabMan?tab=repositories

Clover laptop guide: [Guide] Booting the OS X installer on LAPTOPS with Clover UEFI
Clover config.plist files for laptops: https://github.com/RehabMan/OS-X-Clover-Laptop-Config

Clover thread: http://www.projectosx.com/forum/inde...showtopic=2562
Clover changes: http://www.projectosx.com/forum/inde...showtopic=2656
Clover installer discussion: http://www.projectosx.com/forum/inde...showtopic=3191

Nenhum comentário:

Postar um comentário