Skip to content

DSDT Patching

Curi0 edited this page Oct 5, 2024 · 122 revisions

DSDT Patching is required only on the following motherboards.

  • Sandy/Ivy Bridge motherboards which have applied UEFIPatch
  • ASRock Haswell/Broadwell/Skylake/Kabylake (excluding HEDT (X99/LGA2011-3 and X299/LGA2066)) because these often come with broken DSDT for 4G decoding
  • X79/LGA2011-0 systems which have applied UEFIPatch Extend MMIOH limit to fix Above 4G Decoding
  • Systems without 4G decoding even in hidden settings, this fix will only work in Linux for them though (atleast with GPUs)

If you do not have a motherboard which requires DSDT patching you can skip to Flashing modified UEFI.

Before opening any issues about iASL errors make sure you have read the bottom of the page explaining how to fix them.

All warnings output by iASL are safe to ignore and will not cause any issues.

Please be aware of pad file issue when modifying DSDT on ASUS motherboards. This page contains information about doing the workaround.

Sandy/Ivy Bridge DSDT patch

If you've applied patch Replace 16GB MMIO region with complete use of physical address space (Ivy Bridge) and have problems booting Windows or get an error about insufficient resources you'll need to patch the DSDT. You can both make Windows/Linux load a patched DSDT but we will be modifying it in the UEFI firmware.

Checking if patching is required

Make sure 4G decoding is enabled before doing the following. See Enabling hidden 4G decoding if you cannot find the option.

Windows

Open Device Manager, select View -> Resources by Type and expand Large Memory. If your Pci Bus range ends at FFFFFFFFF or above then DSDT modification isn't required. GPUs supporting Resizable BAR will only show under Large Memory after Resizable BAR is enabled.

large memory good

Linux

Run sudo dmesg | grep "root bus resource". If then last one ends at fffffffff or above then DSDT modification isn't required.

☁  ~  sudo dmesg | grep "root bus resource"
[    0.161520] pci_bus 0000:00: root bus resource [bus 00-3e]
[    0.161522] pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
[    0.161523] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
[    0.161525] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000effff window]
[    0.161526] pci_bus 0000:00: root bus resource [mem 0xdfa00000-0xfeafffff window]
[    0.161527] pci_bus 0000:00: root bus resource [mem 0x21e600000-0xfffffffff window]

DSDT Modification

  1. Use UEFITool to extract body from the AmiBoardInfo (GUID 9F3A0016-AE55-4288-829D-D22FD344C34) module PE32 image section to AmiBoardInfo.efi (make sure extension is .efi when saving). Both NE and the old version will work. Make sure to use the modified BIOS image created in the previous step.

    image

  2. Download AmiBoardInfoTool. If you're on Linux you will need to build it from source using CMake which also requires that you install the distorm3 development package.

  3. Run AmiBoardInfoTool -a AmiBoardInfo.efi -d DSDT.aml. This will extract the compiled DSDT from AmiBoardInfo to DSDT.aml

  4. Use iasl DSDT.aml to decompile the DSDT to DSDT.dsl. You can download iasl for Windows from Intel or on Ubuntu from acpica-tools.

  5. Rename DSDT.dsl to DSDTMod.dsl and open it in a text editor. Search for CreateQWordField you will find something like this (stock DSDT from my Gigabyte B75M-D3H F16d BIOS)

CreateQWordField (BUF0, \_SB.PCI0._Y0F._LEN, M2LN)  // _LEN: Length
CreateQWordField (BUF0, \_SB.PCI0._Y0F._MIN, M2MN)  // _MIN: Minimum Base Address
CreateQWordField (BUF0, \_SB.PCI0._Y0F._MAX, M2MX)  // _MAX: Maximum Base Address
M2LN = 0x0000000400000000
If ((TUUD >= 0x1000))
{
    M2MN = (TUUD << 0x14)
}
Else
{
    M2MN = 0x0000000100000000
}

M2MX = ((M2MN + M2LN) - One)

Change it to something like the following.

CreateQWordField (BUF0, \_SB.PCI0._Y0F._LEN, M2LN)  // _LEN: Length
CreateQWordField (BUF0, \_SB.PCI0._Y0F._MIN, M2MN)  // _MIN: Minimum Base Address
CreateQWordField (BUF0, \_SB.PCI0._Y0F._MAX, M2MX)  // _MAX: Maximum Base Address
// 36-bit / 64GB is highest supported by Sandy/Ivy Bridge
M2MX = 0xFFFFFFFFF

If ((TUUD >= 0x1000))
{
    M2MN = (TUUD << 0x14)
}
Else
{
    M2MN = 0x0000000100000000
}

M2LN = (M2MX - M2MN) + One
  1. Compile the modified DSDT by running iasl DSDTMod.dsl. If iasl reports any errors you will have to manually fix them.

  2. Create a new modified AmiBoardInfo using AmiBoardInfoTool -a AmiBoardInfo.efi -d DSDTMod.aml -o AmiBoardInfoMod.efi. If you get the error ERROR: PE32 has .ROM but not DYNAMIC_BASE set -> Unpatchable atm.. you'll need to remove unneeded code from the DSDTMod.dsl so that its compiled size is smaller than the original. See bottom of this page for more information about fixing this.

  3. Use UEFITool (non NE) to replace body on AmiBoardInfo module PE32 image section with our new AmiBoardInfoMod.efi image

Make sure to check for pad file issue and use the workaround if needed, see Pad file issue workaround. You can get the .ffs (for use in MMTool) of your modified AmiBoardInfo by using UEFITool Extract as-is on the DXE Driver after replacing the PE32 on a temporary copy of your BIOS.

  1. Save the modified BIOS

DSDT broken 4G Decoding fix (Haswell and up) / Linux no 4G Decoding fix

If you're unable to boot Windows or have non functioning GPU with 4G Decoding on then this modification will be required. Usually this issue is on ASRock boards.

This can also allow rebar on Linux for BIOS with missing 4G decoding (often Haswell) and may also work on Windows for compute GPUs. You can even override DSDT without any BIOS modification on Linux, just make sure to use DSDT from /sys/firmware/acpi/tables/DSDT as a base if you're using this method. This method may also require pci=realloc in Linux kernel command line if it doesn't work. On Linux NVIDIA GPUs will additionally require NVreg_EnableResizableBar=1 to make the driver resize them, Intel and AMD do it by default.

Checking if patching is required

Make sure 4G decoding is enabled before doing the following. See Enabling hidden 4G decoding if you cannot find the option. If Windows crashes/freezes on boot logo with 4G Decoding enabled then patching is required

Windows

Open Device Manager and select View -> Resources by Type. If you have Large Memory then this isn't needed. Only the Pci Bus Large memory needs to show, GPUs supporting Resizable BAR will only show under Large Memory after Resizable BAR is enabled.

Linux

Run sudo dmesg | grep "root bus resource" and see if the last root bus resource is larger than 0xffffffff, if so then this isn't needed.

Extracting DSDT (Haswell/Broadwell)

  1. Use UEFITool to extract body from the AmiBoardInfo (GUID 9F3A0016-AE55-4288-829D-D22FD344C34) module PE32 image section to AmiBoardInfo.efi (make sure extension is .efi when saving). Both NE and the old version will work. Make sure to use the modified BIOS image created in the previous step. If your module is called AmiBoardInfo2 then use the other DSDT modifying method for Skylake+ not this

    image

  2. Download AmiBoardInfoTool. If you're on Linux you will need to build it from source using CMake which also requires that you install the distorm3 development package.

  3. Run AmiBoardInfoTool -a AmiBoardInfo.efi -d DSDT.aml. This will extract the compiled DSDT from AmiBoardInfo to DSDT.aml

Extracting DSDT (Skylake and up)

  1. Use UEFITool NE to extract body from raw section of the DsdtAsl (GUID C118F50D-391D-45F4-B3D3-11BC931AA56D, search for it) module to DSDT.aml (make sure extension is .aml when saving). Make sure to use the modified BIOS image created in the previous step

  2. Use iasl DSDT.aml to decompile the DSDT to DSDT.dsl. You can download iasl for Windows from ACPICA or on Ubuntu from acpica-tools.

  1. Rename DSDT.dsl to DSDTMod.dsl and open it in a text editor. Search for DWordMemory and you should find multiple entries like this
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
    0x00000000,         // Granularity
    0x000EC000,         // Range Minimum
    0x000EFFFF,         // Range Maximum
    0x00000000,         // Translation Offset
    0x00004000,         // Length
    ,, _Y0C, AddressRangeMemory, TypeStatic)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
    0x00000000,         // Granularity
    0x000F0000,         // Range Minimum
    0x000FFFFF,         // Range Maximum
    0x00000000,         // Translation Offset
    0x00010000,         // Length
    ,, _Y0D, AddressRangeMemory, TypeStatic)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
    0x00000000,         // Granularity
    0x00000000,         // Range Minimum
    0xFEAFFFFF,         // Range Maximum
    0x00000000,         // Translation Offset
    0xFEB00000,         // Length
    ,, _Y0E, AddressRangeMemory, TypeStatic)

After the last one add the following

QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
    0x0000000000000000, // Granularity
    0x0000000000010000, // Range Minimum
    0x000000000001FFFF, // Range Maximum
    0x0000000000000000, // Translation Offset
    0x0000000000010000, // Length
    ,, _YAF, AddressRangeMemory, TypeStatic)

Next search for M1LN and you should find something like this

If ((PM0H == One))
{
    CreateBitField (BUF0, \_SB.PCI0._Y0D._RW, F0RW)  // _RW_: Read-Write Status
    F0RW = Zero
}

CreateDWordField (BUF0, \_SB.PCI0._Y0E._MIN, M1MN)  // _MIN: Minimum Base Address
CreateDWordField (BUF0, \_SB.PCI0._Y0E._MAX, M1MX)  // _MAX: Maximum Base Address
CreateDWordField (BUF0, \_SB.PCI0._Y0E._LEN, M1LN)  // _LEN: Length
M1MN = (TLUD << 0x14)
M1LN = ((M1MX - M1MN) + One)

Add the following below it

CreateQWordField (BUF0, \_SB.PCI0._YAF._LEN, M2LN)  // _LEN: Length
CreateQWordField (BUF0, \_SB.PCI0._YAF._MIN, M2MN)  // _MIN: Minimum Base Address
CreateQWordField (BUF0, \_SB.PCI0._YAF._MAX, M2MX)  // _MAX: Maximum Base Address

// 39-bit for Haswell and up
M2MX = 0x8000000000 - One
If ((TUUD >= 0x1000))
{
    M2MN = (TUUD << 0x14)
}
Else
{
    M2MN = 0x100000000
}

M2LN = ((M2MX - M2MN) + One)
  1. Compile the modified DSDT by running iasl DSDTMod.dsl. If iasl reports any errors you will have to manually fix them.

Replacing DSDT with modified (Haswell/Broadwell)

  1. Create a new modified AmiBoardInfo using AmiBoardInfoTool -a AmiBoardInfo.efi -d DSDTMod.aml -o AmiBoardInfoMod.efi. If you get the error ERROR: PE32 has .ROM but not DYNAMIC_BASE set -> Unpatchable atm.. you'll need to remove unneeded code from the DSDTMod.dsl so that its compiled size is smaller than the original.

  2. Use UEFITool (non NE) to replace body on AmiBoardInfo module PE32 image section with our new AmiBoardInfoMod.efi image

Replacing DSDT with modified (Skylake and up)

  1. Using UEFITool NE find the File GUID of DsdtAsl, in this case it is C118F50D-391D-45F4-B3D3-11BC931AA56D image

  2. Search for that GUID in UEFITool (non NE) and replace body on the Raw section with DSDTMod.aml

Make sure to check for pad file issue and use the workaround if needed, see Pad file issue workaround. You can get the .ffs (for use in MMTool) of your modified AmiBoardInfo or DsdtAsl by using UEFITool Extract as-is on the DXE Driver after replacing the PE32 on a temporary copy of your BIOS.

  1. Save the modified BIOS

X79 DSDT Patch

⚠ Please make sure you use MMTool 4.50.0.23 to replace the AmiBoardInfo module when doing this on X79, there have been reports of newer MMTool versions and UEFITool causing high voltages when using overclocking

Only use this patch if you have applied UEFIPatch Extend MMIOH limit to fix Above 4G Decoding.

Follow the regular Sandy/Ivy Bridge guide for extracting/recompiling the DSDT. These are the changes that need to be made to the DSDT instead.

  1. Search for If ((MALH || MALL)), there will most likely be two results.
  2. Replace the contents of the If statement for each result, it should look something like the following.

Make sure that CRS1 and _Y05 is instead the identifier that was there before, for example it can be CRS2 and _Y0B instead. For the second If statement that you replace make sure to use M3 instead of M2 or you will get error Name already exists in scope

If ((MALH || MALL))
{
	CreateQWordField (CRS1, \_SB.PCI0._Y05._LEN, M2LN)  // _LEN: Length
	CreateQWordField (CRS1, \_SB.PCI0._Y05._MIN, M2MN)  // _MIN: Minimum Base Address
	CreateQWordField (CRS1, \_SB.PCI0._Y05._MAX, M2MX)  // _MAX: Maximum Base Address
	// MMIOH range 56 - 64 TB
	M2MX = 0x00003FFFFFFFFFFF
	M2MN = 0x0000380000000000
	M2LN = (M2MX - M2MN) + One
}

Common DSDT errors and fixes

Most DSDT compilation errors can be solved easily but I've added these common ones here.

_HID suffix must be all hex digits (GH)

Replace ABCDEFGH with ABCDEFFF in the line it says.

Invalid object type for reserved name ^ (_CRS: found Integer, Buffer required)

Replace Return (Zero) with Return (ToBuffer(Zero))

syntax error, unexpected '}'

Go to the line it mentions and remove the previous lines containing Arg

Non-hex letters must be upper case ^

Change letters in string of the line mentioned to uppercase

Min/Max/Length/Gran are all zero, but no resource tag

Remove the IO (Decode16 variable mentioned.

_HID prefix must be all uppercase or decimal digits

Change _HID prefix to uppercase and remove X, eg Name (_HID, "Xpnp0c14") to Name (_HID, "PNP0C14").

_UID inside processor declaration must be an integer (found a string)

You will need to use regex to fix this, find Name\s+\(_UID,\s*\"PCI\d\-CP(.*)\"\) and replace with Name \(_UID, 0x0$1\). For example in Notepad++.

image

Invalid object type for reserved name (_PLD: found Integer

Again this uses regex, find (Name\s*\(_PLD,\s*)Package(\s\([^\)].*\)[^\)]*) and replace with $1Package() { Buffer$2}.

Length is larger than Min/Max window

Calculate the correct Length by subtracting Minimum from Maximum and adding one, in the following example the correct Length value would be 0xFDE00000 instead of incorrect 0xFDFC0000 which is causing the error. Replace it with the correct value.

DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
	0x00000000,         // Granularity
	0x02000000,         // Range Minimum
	0xFFDFFFFF,         // Range Maximum
	0x00000000,         // Translation Offset
	0xFDFC0000,         // Length
	,, _Y04, AddressRangeMemory, TypeStatic)

Invalid object type for reserved name ^ (_PLD: found Buffer, Package required)

See https://github.com/acpica/acpica/issues/122#issuecomment-604045199

AmiBoardInfoTool says ERROR: PE32 has .ROM but not DYNAMIC_BASE set -> Unpatchable atm..

Remove unneeded ACPI _OSI entries to reduce DSDT size. Thanks lyzzz on win-raid for figuring this out.

image

If DSDT still isn't small enough you can try

  • Remove all ADBG lines
  • Remove device BAT0 / BAT1 / BAT2
  • Remove device DOCK
  • Remove device LID0
  • Remove SLIC string if you don't use SLI
Clone this wiki locally