Contribute
Register

[Guide] Using Clover to "hotpatch" ACPI

the-braveknight

Moderator
Joined
Nov 24, 2015
Messages
1,222
Motherboard
Lenovo Legion Y520 (Clover)
CPU
i7-7700HQ
Graphics
HD 630 (1920x1080) + Nvidia GTX 1060
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
I don't know what you mean by "break the EC code in _OFF".
Well the problem is that _OFF is being called before EC is initialized, right? I was thinking if it's possible to rename the relevant EC code to something arbitrary such that the renamed EC is never reachable?

For example, we can change this in the _OFF method:
Code:
Method (_OFF, 0, Serialized)
{
...
    If (\ECON)
    {
        Store (Zero, \_SB.PCI0.LPCB.EC0.GATY)
    }
...
}

To:

Code:
Method (_OFF, 0, Serialized)
{
...
    If (\ECON)
    {
        Store (Zero, \_SB.PCI0.LPCB.EX0.GATY)
    }
...
}

Is this possible?
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Well the problem is that _OFF is being called before EC is initialized, right?

Normally, _OFF is not called at all.
But when we patch _INI to call _OFF it is called at the time all _INI methods are executed.
Which is *before* EC._REG is called, which means that any EC access must be removed from _OFF or anything _OFF calls. Such code is then moved to _REG where it is safe to execute.

I was thinking if it's possible to rename the relevant EC code to something arbitrary such that the renamed EC is never reachable?

You could replace all the EC related code with Noop op-codes, but the patching for that would be rather unwieldy.
Better to replace the _OFF method entirely (using "rename/replace" pattern).

For example, we can change this in the _OFF method:
Code:
Method (_OFF, 0, Serialized)
{
...
    If (\ECON)
    {
        Store (Zero, \_SB.PCI0.LPCB.EC0.GATY)
    }
...
}

To:

Code:
Method (_OFF, 0, Serialized)
{
...
    If (\ECON)
    {
        Store (Zero, \_SB.PCI0.LPCB.EX0.GATY)
    }
...
}

Is this possible?

Well... if the code was actually coded with the ECON conditional, assuming ECON is *not* in the EC, nothing need be patched in the _OFF as the EC related code will not execute (it is being protected with the If (ECON) conditional).

And if the Store-op to GATY that you meantion was actually being executed (for some reason ECON is non-zero), changing it to EX0.GATY will not work. It would cause ACPI abort, as the EX0.GATY will not be found in ACPI namespace. The execution of the _OFF method would stop at that point and further code after it will not be executed.
 

the-braveknight

Moderator
Joined
Nov 24, 2015
Messages
1,222
Motherboard
Lenovo Legion Y520 (Clover)
CPU
i7-7700HQ
Graphics
HD 630 (1920x1080) + Nvidia GTX 1060
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Normally, _OFF is not called at all.
But when we patch _INI to call _OFF it is called at the time all _INI methods are executed.
Which is *before* EC._REG is called, which means that any EC access must be removed from _OFF or anything _OFF calls. Such code is then moved to _REG where it is safe to execute.



You could replace all the EC related code with Noop op-codes, but the patching for that would be rather unwieldy.
Better to replace the _OFF method entirely (using "rename/replace" pattern).



Well... if the code was actually coded with the ECON conditional, assuming ECON is *not* in the EC, nothing need be patched in the _OFF as the EC related code will not execute (it is being protected with the If (ECON) conditional).

And if the Store-op to GATY that you meantion was actually being executed (for some reason ECON is non-zero), changing it to EX0.GATY will not work. It would cause ACPI abort, as the EX0.GATY will not be found in ACPI namespace. The execution of the _OFF method would stop at that point and further code after it will not be executed.
Thanks for the information. I kinda have a better understanding of how it all works now.

So, I’ll need to check if ECON is zero, then I wouldn’t need to replace the _OFF since it’s being protected by the conditional. But if it does, how about creating a 'dummy' EX0 device that contains a 'GATY' property? Will that work?

Also, if I wanted to use ACPIDebug, I can simply add a p1 call from inside that if conditional just to verify if it’s zero, I might add and else statement to be sure [that it’s not zero], is that how it’s usually done?
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
So, I’ll need to check if ECON is zero, then I wouldn’t need to replace the _OFF since it’s being protected by the conditional.

Yes.
ECON is likely set in _REG.
You can verify with ACPIDebug.

But if it does, how about creating a 'dummy' EX0 device that contains a 'GATY' property? Will that work?

That gets it closer to working, but then if you need to call _OFF from _WAK, you're left with an _OFF that is only doing part of what it used to do. Same with patched _OFF, but you can take care of that by calling XOFF instead.

Also, if I wanted to use ACPIDebug, I can simply add a p1 call from inside that if conditional just to verify if it’s zero, I might add and else statement to be sure [that it’s not zero], is that how it’s usually done?

Or you can just print the value of ECON before the conditional.
 

the-braveknight

Moderator
Joined
Nov 24, 2015
Messages
1,222
Motherboard
Lenovo Legion Y520 (Clover)
CPU
i7-7700HQ
Graphics
HD 630 (1920x1080) + Nvidia GTX 1060
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Yes.
ECON is likely set in _REG.
You can verify with ACPIDebug.



That gets it closer to working, but then if you need to call _OFF from _WAK, you're left with an _OFF that is only doing part of what it used to do. Same with patched _OFF, but you can take care of that by calling XOFF instead.



Or you can just print the value of ECON before the conditional.

Interesting... ECON value is 0x1, which means the code inside the if conditional is being executed, not sure why that conditional exists in the first place... Any ideas?

How can I check where it's being initialized?

Well I do not need to call _OFF from _WAK so that shouldn't be a problem.
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
How can I check where it's being initialized?

Code:
# ACPI/origin files in current directory
iasl -da -dl DSDT.aml SSDT*.aml
grep ECON *.dsl

Well I do not need to call _OFF from _WAK so that shouldn't be a problem.

As per post #1, sometimes it is needed (also calling _ON from _PTS).
It really depends on hardware.
Such is coding.
 

the-braveknight

Moderator
Joined
Nov 24, 2015
Messages
1,222
Motherboard
Lenovo Legion Y520 (Clover)
CPU
i7-7700HQ
Graphics
HD 630 (1920x1080) + Nvidia GTX 1060
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Code:
# ACPI/origin files in current directory
iasl -da -dl DSDT.aml SSDT*.aml
grep ECON *.dsl

That's what I get:
Code:
Zaids-macOS:ACPI zaid$ grep ECON *.dsl
DSDT.dsl:        ECON,   8,
DSDT.dsl:                        If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                                    If (ECON)
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:        If (LAnd (LEqual (OSYS, 0x07D9), LEqual (ECON, One)))
DSDT.dsl:            If (LEqual (ECON, One))
DSDT.dsl:        If (LEqual (ECON, One))
SSDT-5.dsl:    External (ECON, FieldUnitObj)
SSDT-5.dsl:            If (\ECON)
SSDT-5.dsl:            If (\ECON)
SSDT-5.dsl:                    If (\ECON)
SSDT-5.dsl:                    If (\ECON)

Not sure I can find where exactly it's being set or initialized with a value.
 

RehabMan

Moderator
Joined
May 3, 2012
Messages
186,689
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
That's what I get:
Code:
Zaids-macOS:ACPI zaid$ grep ECON *.dsl
DSDT.dsl:        ECON,   8,
DSDT.dsl:                        If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                                    If (ECON)
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:                            If (LEqual (ECON, One))
DSDT.dsl:        If (LAnd (LEqual (OSYS, 0x07D9), LEqual (ECON, One)))
DSDT.dsl:            If (LEqual (ECON, One))
DSDT.dsl:        If (LEqual (ECON, One))
SSDT-5.dsl:    External (ECON, FieldUnitObj)
SSDT-5.dsl:            If (\ECON)
SSDT-5.dsl:            If (\ECON)
SSDT-5.dsl:                    If (\ECON)
SSDT-5.dsl:                    If (\ECON)

Not sure I can find where exactly it's being set or initialized with a value.

It must be set by the EC itself (probably is in shared SystemMemory, or in another way accessible by both the EC and the CPU).
 

the-braveknight

Moderator
Joined
Nov 24, 2015
Messages
1,222
Motherboard
Lenovo Legion Y520 (Clover)
CPU
i7-7700HQ
Graphics
HD 630 (1920x1080) + Nvidia GTX 1060
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
It must be set by the EC itself (probably is in shared SystemMemory, or in another way accessible by both the EC and the CPU).
Then I’ll probably try something else and see where I can get.

Thanks!
 
Top