Contribute
Register

[Guide] Using Clover to "hotpatch" ACPI

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?
 
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.
 
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.
 
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.
 
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.
 
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).
 
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!
 
Best way is "rename/replace" pattern as per hotpatch guide...
Yes. But experimenting and trying to find new ways is always fun! :)
 
Back
Top