Contribute
Register

[Guide] How to patch DSDT for working battery status

How to patch DSDT for working battery status

In that code there are several ways to have a result of 0xFFFFFFFF. You will need to determine which one is happening and why. Use ACPIDebug to insert debug tracing as necessary.

My UPBS Method doesn't look like acpi standards may be the problem?
 
How to patch DSDT for working battery status

My UPBS Method doesn't look like acpi standards may be the problem?

Not sure what you mean. ACPI standard is just to return the 4-values as required by _BST. Yours does that, but for some reason it is returning 0xFFFFFFFF for amperage.

You need to debug it via ACPIDebug to find out why.
 
How to patch DSDT for working battery status

Hello RehabMan, or any other that could help;


I attempted this, and found the guide really useful. After reading several times, I guess I might be able to suceed (I also did programming in different languages, AS3, Javascript, PHP, Objective-C, did programming, but never was really good at it). Fortunately for me, I don't seem to have several bits to patch. Counting the bits that are accessed, I only have 2 16 bits, and 2 32 bits (That seem.. abnormally small, or I just got lucky).

So if I start from the beggining of your tutorial:

1. Search for EmbeddedControl. I have 2 results. Result 2 is this, seems like I have nothing to patch, because these bytes are not accessed:

Code:
                    OperationRegion (ECRM, EmbeddedControl, Zero, 0xFF)
                    Field (ECRM, ByteAcc, Lock, Preserve)
                    {
                                Offset (0x94), 
                        ERIB,   16, 
                        ERBD,   8, 
                                Offset (0xAC), 
                                Offset (0xAD), 
                            ,   4, 
                                Offset (0xAE), 
                            ,   3, 
                            ,   4, 
                                Offset (0xAF), 
                                Offset (0xBC), 
                                Offset (0xBD), 
                                Offset (0xBE), 
                                Offset (0xF9), 
                        RFRD,   16
                    }

There are 2 16 bits, and searching for "ERIB" returns nothing else, so it's never accessed. And also, searching for "RFRD" return nothing else neither. Lucky?

2. Search for EmbeddedControl again, I had 2 results. Result #2 was just checked, so I'll have to modify result #1:

Code:
                    OperationRegion (ECOR, EmbeddedControl, Zero, 0x0100)
                    Field (ECOR, ByteAcc, NoLock, Preserve)
                    {
                        HDBM,   1, 
                            ,   1, 
                            ,   1, 
                        HFNE,   1, 
                            ,   1, 
                            ,   1, 
                        HLDM,   1, 
                                Offset (0x01), 
                        BBLS,   1, 
                        BTCM,   1, 
                            ,   1, 
                            ,   1, 
                            ,   1, 
                        HBPR,   1, 
                        BTPC,   1, 
                                Offset (0x02), 
                        HDUE,   1, 
                            ,   4, 
                        SNLK,   1, 
                                Offset (0x03), 
                            ,   5, 
                        HAUM,   2, 
                                Offset (0x05), 
                        HSPA,   1, 
                                Offset (0x06), 
                        HSUN,   8, 
                        HSRP,   8, 
                                Offset (0x0C), 
                        HLCL,   8, 
                            ,   4, 
                        CALM,   1, 
                                Offset (0x0E), 
                        HFNS,   2, 
                                Offset (0x0F), 
                            ,   6, 
                        NULS,   1, 
                                Offset (0x10), 
                        HAM0,   8, 
                        HAM1,   8, 
                        HAM2,   8, 
                        HAM3,   8, 
                        HAM4,   8, 
                        HAM5,   8, 
                        HAM6,   8, 
                        HAM7,   8, 
                        HAM8,   8, 
                        HAM9,   8, 
                        HAMA,   8, 
                        HAMB,   8, 
                        HAMC,   8, 
                        HAMD,   8, 
                        HAME,   8, 
                        HAMF,   8, 
                                Offset (0x23), 
                        HANT,   8, 
                                Offset (0x26), 
                            ,   2, 
                        HANA,   2, 
                                Offset (0x27), 
                                Offset (0x2A), 
                        HATR,   8, 
                        HT0H,   8, 
                        HT0L,   8, 
                        HT1H,   8, 
                        HT1L,   8, 
                        HFSP,   8, 
                            ,   6, 
                        HMUT,   1, 
                                Offset (0x31), 
                            ,   2, 
                        HUWB,   1, 
                                Offset (0x32), 
                        HWWL,   1, 
                        HWLB,   1, 
                        HWLO,   1, 
                        HWDK,   1, 
                        HWFN,   1, 
                        HWBT,   1, 
                        HWAO,   1, 
                        HWBU,   1, 
                        HWLU,   1, 
                                Offset (0x34), 
                            ,   3, 
                        PIBS,   1, 
                            ,   3, 
                        HPLO,   1, 
                                Offset (0x36), 
                                Offset (0x38), 
                        HB0S,   7, 
                        HB0A,   1, 
                        HB1S,   7, 
                        HB1A,   1, 
                        HCMU,   1, 
                            ,   2, 
                        OVRQ,   1, 
                        DCBD,   1, 
                        DCWL,   1, 
                        DCWW,   1, 
                        HB1I,   1, 
                            ,   1, 
                        KBLT,   1, 
                        BTPW,   1, 
                        BTDT,   1, 
                        HUBS,   1, 
                        BDPW,   1, 
                        BDDT,   1, 
                        HUBB,   1, 
                                Offset (0x46), 
                            ,   1, 
                        BTWK,   1, 
                        HPLD,   1, 
                            ,   1, 
                        HPAC,   1, 
                        BTST,   1, 
                                Offset (0x47), 
                        HPBU,   1, 
                            ,   1, 
                        HBID,   1, 
                            ,   3, 
                        HBCS,   1, 
                        HPNF,   1, 
                            ,   1, 
                        GSTS,   1, 
                            ,   2, 
                        HLBU,   1, 
                        DOCD,   1, 
                        HCBL,   1, 
                                Offset (0x49), 
                        SLUL,   1, 
                                Offset (0x4C), 
                        HTMH,   8, 
                        HTML,   8, 
                        HWAK,   16, 
                        HMPR,   8, 
                            ,   7, 
                        HMDN,   1, 
                                Offset (0x78), 
                        TMP0,   8, 
                                Offset (0x80), 
                                Offset (0x81), 
                        HIID,   8, 
                                Offset (0x83), 
                        HFNI,   8, 
                        HSPD,   16, 
                                Offset (0x88), 
                        TSL0,   7, 
                        TSR0,   1, 
                        TSL1,   7, 
                        TSR1,   1, 
                        TSL2,   7, 
                        TSR2,   1, 
                        TSL3,   7, 
                        TSR3,   1, 
                                Offset (0x8D), 
                        HDAA,   3, 
                        HDAB,   3, 
                        HDAC,   2, 
                                Offset (0xB0), 
                        HDEN,   32, 
                        HDEP,   32, 
                        HDEM,   8, 
                        HDES,   8, 
                                Offset (0xBB), 
                        PLSL,   8, 
                        PLMS,   8, 
                        PLLS,   8, 
                        PLTU,   8, 
                                Offset (0xC8), 
                        ATMX,   8, 
                        HWAT,   8, 
                                Offset (0xCC), 
                        PWMH,   8, 
                        PWML,   8, 
                                Offset (0xED), 
                            ,   4, 
                        HDDD,   1
                    }

Counting the bits, I believe I was right, and have only 4 lines to patch (!). HWAK 16 bits, HSPD 16 bits, HDEN 32 bits and HDEP 32 bits. So I thought I might suceed, that's not much...

Starting from searching HWAK, I obviously get the line HWAK, 16, into device label EC0 (According to the lateral bar of MaciASL, like in your example):

Capture d’écran 2014-06-19 à 16.56.35.jpg

I also get 8 others results, that probably refer to when the bit gets returned, and these results look like this. I won't modify these manually, and I start patching right now:

Code:
            Store (\_SB.PCI0.LPCB.EC0.HWAK, Local0)
            If (And (Local0, 0x04))
            {
                Notify (\_SB.PWRB, 0x02)
            }

I want to break HWAK in two parts, so I change the name. Here's the patch I want to apply:

Capture d’écran 2014-06-19 à 16.39.06.jpg

This look correct, the patch is accepted. I patch it.
At this point, I get pretty much lost. :|

That patch says, look at the code in a device with label H_EC, search for "BDC0,<spaces>16," and replace it with "DC00,8,DC01,8," This effectively breaks the field into two parts. If you apply this patch, and attempt to compile the modified DSDT, you will get errors because the code is still accessing BDC0. These errors actually help us identify what code needs to change:

Code:
   Store (BDC0, Index (DerefOf (Index (Local0, 0x02)), Zero))    Store (ShiftRight (BDC0, 0x08), Index (DerefOf (Index (Local0, 0x02)), One))

I was supposed to get errors at this point. You recommend us to look at the errors of when the bits are accessed, to find out what to change. I followed the example DSDT, and as planned, I got just 2 errors, but when I apply the patch I showed above, on my own DSDT..

Why do I end up with 121 errors? :eek:

Capture d’écran 2014-06-19 à 16.40.09.jpg


"Object does not exist" 100+ times... How am I suppose to fix all these 121 errors, caused by a single patch that was accepted by MaciASL ?
I'm not sure if I done anything wrong, I gave you exactly the steps I made. When I first opened MaciASL with my extracted DSDT, no errors showed up during compiling, just 4 warnings, and 14 remarks.

I've joined my extracted DSDT (without errors) to this post, I tried the patching like 3 times.
This doesn't look so hard, since I apparently have only 4 items to change (2 * 16 bits and 2 * 32 bits). But yet, I don't see how I can find the problem with 100+ errors (Even if errors are normal at this point - your file had 2, I have 121).


Thank you for your help, I appreciate it.
 

Attachments

  • dsdt_e420.aml
    46.2 KB · Views: 124
How to patch DSDT for working battery status

Your identifiers DWAK1 and DWAK2 are too long. ACPI names are limited to 4 characters max. Those errors cause errors in the rest of the code as the entire Field definition is ignored.
 
How to patch DSDT for working battery status

Your identifiers DWAK1 and DWAK2 are too long. ACPI names are limited to 4 characters max. Those errors cause errors in the rest of the code as the entire Field definition is ignored.

Ha ok, cool;
The point was just to get a unique identifier, so pretty simple. I changed the first letter, limiting the identifier to 3 caracthers. I now get only 8 errors, which all refer to "Object does not exist (\_SB.PCI0.LPCB.EC0.HWAK). Way better.

I should be able to continue the tutorial at this point. =)

Will post back if I need additional help, thanks.
 
How to patch DSDT for working battery status

Ha ok, cool;
The point was just to get a unique identifier, so pretty simple. I changed the first letter, limiting the identifier to 3 caracthers. I now get only 8 errors, which all refer to "Object does not exist (\_SB.PCI0.LPCB.EC0.HWAK). Way better.

I should be able to continue the tutorial at this point. =)

Will post back if I need additional help, thanks.

Also, when searching for fields to patch don't forget to search for multiple Field definitions using the same EmbeddedControl OperationRegion. Search for 'Field (ECOR' and you'll see what I mean.
 
How to patch DSDT for working battery status

Also, when searching for fields to patch don't forget to search for multiple Field definitions using the same EmbeddedControl OperationRegion. Search for 'Field (ECOR' and you'll see what I mean.

I'm still thinking how to fix the first one, HWAK. XD Actually, thanks for noting the remaining, I did forgot. Noted all these that needed to be patched, now I have this:

Code:
HWAK,   16, 
HSPD,   16,
HDEN,   32,
HDEP,   32, 


SBRC, 16
SBFC, 16
SBAE, 16
SBRS, 16
SBAC, 16
SBV0, 16
SBAF, 16
SBBS, 16

SBMD, 16
SBCC, 16

SBDC, 16
SBDV, 16
SBOM, 16
SBSI, 16
SBDT, 16
SBSN, 16

SBCH, 32
    
SBMN, 128

SBDN, 128


Still at HWAK patching.. I've been thinking and reading that example for maybe 2 hours, I.. I never liked programming. XD But yeah, I do have a little experience (None with DSDT), well.

My first patch look like this. Of course, it's incorrect for now:
Code:
into method label _L23 code_regex \(HWAK, replaceall_matched begin (B1B2(WAK0,WAK1), end;

I did figured out MaciASL does not find the location, he's searching for the method with _L23 as a label...
Here's the part I need to fix, HWAK, at the very bottom:

Code:
    Scope (_GPE)
    {
        Method (_L0D, 0, NotSerialized)
        {
            Notify (\_SB.PCI0.EHC1, 0x02)
            Notify (\_SB.PCI0.EHC2, 0x02)
            Notify (\_SB.PCI0.HDEF, 0x02)
        }

        Method (_L01, 0, NotSerialized)
        {
            Add (L01C, One, L01C)
            P8XH (Zero, One)
            P8XH (One, L01C)
            If (LAnd (LEqual (RP1D, Zero), \_SB.PCI0.RP01.HPSX))
            {
                Sleep (0x64)
                If (\_SB.PCI0.RP01.PDCX)
                {
                    Store (One, \_SB.PCI0.RP01.PDCX)
                    Store (One, \_SB.PCI0.RP01.HPSX)
                    If (LNot (\_SB.PCI0.RP01.PDSX))
                    {
                        Store (Zero, \_SB.PCI0.RP01.L0SE)
                    }

                    Notify (\_SB.PCI0.RP01, Zero)
                }
                Else
                {
                    Store (One, \_SB.PCI0.RP01.HPSX)
                }
            }

            If (LAnd (LEqual (RP3D, Zero), \_SB.PCI0.RP03.HPSX))
            {
                Sleep (0x64)
                If (\_SB.PCI0.RP03.PDCX)
                {
                    Store (One, \_SB.PCI0.RP03.PDCX)
                    Store (One, \_SB.PCI0.RP03.HPSX)
                    If (LNot (\_SB.PCI0.RP03.PDSX))
                    {
                        Store (Zero, \_SB.PCI0.RP03.L0SE)
                    }

                    Notify (\_SB.PCI0.RP03, Zero)
                }
                Else
                {
                    Store (One, \_SB.PCI0.RP03.HPSX)
                }
            }

            If (LAnd (LEqual (RP4D, Zero), \_SB.PCI0.RP04.HPSX))
            {
                Sleep (0x64)
                If (\_SB.PCI0.RP04.PDCX)
                {
                    Store (One, \_SB.PCI0.RP04.PDCX)
                    Store (One, \_SB.PCI0.RP04.HPSX)
                    If (LNot (\_SB.PCI0.RP04.PDSX))
                    {
                        Store (Zero, \_SB.PCI0.RP04.L0SE)
                    }

                    Notify (\_SB.PCI0.RP04, Zero)
                }
                Else
                {
                    Store (One, \_SB.PCI0.RP04.HPSX)
                }
            }
        }

        Method (_L02, 0, NotSerialized)
        {
            Store (Zero, GPEC)
            If (CondRefOf (\_SB.PCI0.IEIT.EITV))
            {
                \_SB.PCI0.IEIT.EITV ()
            }

            Notify (\_TZ.TZ01, 0x80)
            If (CondRefOf (TNOT))
            {
                TNOT ()
            }
        }

        Method (_L06, 0, NotSerialized)
        {
            If (\_SB.PCI0.VID.GSSE)
            {
                \_SB.PCI0.VID.GSCI ()
            }
            Else
            {
                Store (One, SCIS)
            }
        }

        Method (_L07, 0, NotSerialized)
        {
            Store (0x20, \_SB.PCI0.SBUS.HSTS)
        }

        Method (_L23, 0, NotSerialized)
        {
            Store (\_SB.PCI0.LPCB.EC0.HWAK, Local0)
            If (And (Local0, One)) {}
            If (And (Local0, 0x02)) {}
            If (And (Local0, 0x04)) {}
            If (And (Local0, 0x10)) {}
            If (And (Local0, 0x40)) {}
        }
    }

What contain HWAK is the method with the label (It's a label, right?) _L23.
Not sure why this patch is not working, I might spend more time thinking about it (That was 2 hours already for the very first 16-bit method XD). Sure is a really easy thing. XD


Thanks for your support.
 
How to patch DSDT for working battery status

My first patch look like this. Of course, it's incorrect for now:
Code:
into method label _L23 code_regex \(HWAK, replaceall_matched begin (B1B2(WAK0,WAK1), end;

It is not found, because the text you're searching for, \(HWAK, in _L23 does not exist... The code is:
Code:
 Store (\_SB.PCI0.LPCB.EC0.HWAK, Local0)

So you should be looking for:
Code:
\(\\_SB\.PCI0\.LPCB\.EC0\.HWAK,

Patch would look like:
Code:
into method label _L23 code_regex \(\\_SB\.PCI0\.LPCB\.EC0\.HWAK replaceall_matched begin (B1B2(\_SB.PCI0.LPCB.EC0.WAK0,\_SB.PCI0.LPCB.EC0.WAK1), end;
 
How to patch DSDT for working battery status

This is the method

Code:
Method (_BST, 0, NotSerialized)  // _BST: Battery Status
            {
                If (^^PCI0.LPCB.EC.ECOK)
                {
                    UPBS ()
                }
                Else
                {
                    IVBS ()
                }


                Return (PBST)
            }

And UPBS and IVBS

Code:
 Method (UPBS, 0, NotSerialized)
            {
                If (^^PCI0.LPCB.EC.BAT0)
                {
                    Store (Zero, Local0)
                    Store (Zero, Local1)
                    If (^^PCI0.LPCB.EC.ADP)
                    {
                        If (LEqual (And (B1B4 (^^PCI0.LPCB.EC.ST00, ^^PCI0.LPCB.EC.ST01, ^^PCI0.LPCB.EC.ST02, ^^PCI0.LPCB.EC.ST03), 0x02), 
                            0x02))
                        {
                            Or (Local0, 0x02, Local0)
                            And (B1B4 (^^PCI0.LPCB.EC.PR00, ^^PCI0.LPCB.EC.PR01, ^^PCI0.LPCB.EC.PR02, ^^PCI0.LPCB.EC.PR03), 0xFFFF, Local1)
                        }
                    }
                    Else
                    {
                        Or (Local0, One, Local0)
                        And (B1B4 (^^PCI0.LPCB.EC.PR00, ^^PCI0.LPCB.EC.PR01, ^^PCI0.LPCB.EC.PR02, ^^PCI0.LPCB.EC.PR03), 0xFFFF, Local1)
                    }


                    And (Local1, 0x8000, Local7)
                    If (LEqual (Local7, 0x8000))
                    {
                        Store (0xFFFFFFFF, Local1)
                    }


                    And (B1B4 (^^PCI0.LPCB.EC.RC00, ^^PCI0.LPCB.EC.RC01, ^^PCI0.LPCB.EC.RC02, ^^PCI0.LPCB.EC.RC03), 0xFFFF, Local2)
                    And (B1B4 (^^PCI0.LPCB.EC.PV00, ^^PCI0.LPCB.EC.PV01, ^^PCI0.LPCB.EC.PV02, ^^PCI0.LPCB.EC.PV03), 0xFFFF, Local3)
                    Store (Local0, Index (PBST, Zero))
                    Store (Local1, Index (PBST, One))
                    Store (Local2, Index (PBST, 0x02))
                    Store (Local3, Index (PBST, 0x03))
                    If (LNotEqual (BFCC, B1B4 (^^PCI0.LPCB.EC.FC00, ^^PCI0.LPCB.EC.FC01, ^^PCI0.LPCB.EC.FC02, ^^PCI0.LPCB.EC.FC03)))
                    {
                        Notify (BAT0, 0x81)
                    }
                }
                Else
                {
                    IVBS ()
                }

 Method (IVBS, 0, NotSerialized)
            {
                Store (Zero, Index (PBST, Zero))
                Store (0xFFFFFFFF, Index (PBST, One))
                Store (0xFFFFFFFF, Index (PBST, 0x02))
                Store (0x2710, Index (PBST, 0x03))
            }

Here is the 0xFFFFFFFF value

should i replace it or erase it all?

I doubt you are falling into the IVBS case. But you should verify by using ACPIDebug. For example, the following instrumentation will tell you for sure what is happening in _BST:
Code:
Method (_BST, 0, NotSerialized)  // _BST: Battery Status
            {
                If (^^PCI0.LPCB.EC.ECOK)
                {
\rmdt.p1("calling UPBS from _BST")
                    UPBS ()
                }
                Else
                {
\rmdt.p1("calling IVBS from _BST")
                    IVBS ()
                }

\rmdt.p2("_BST returns", PBST)
                Return (PBST)
            }

Not a clue, i got here by asking for help and trying to repeat what others already did. I'm not saying i'll give up. On the contrary i keep working and learning all i can to improve and challenge myself.
Thanks for encouraging everybody, its very important thing to do

And you could instrument UPBS:
Code:
 Method (UPBS, 0, NotSerialized)
            {
\rmdt.p1("UPBS enter")
                If (^^PCI0.LPCB.EC.BAT0)
                {
\rmdt.p1("UPBS EC.BAT0 true")
                    Store (Zero, Local0)
                    Store (Zero, Local1)
                    If (^^PCI0.LPCB.EC.ADP)
                    {
\rmdt.p1("UPBS EC.ADP true")
                        If (LEqual (And (B1B4 (^^PCI0.LPCB.EC.ST00, ^^PCI0.LPCB.EC.ST01, ^^PCI0.LPCB.EC.ST02, ^^PCI0.LPCB.EC.ST03), 0x02), 
                            0x02))
                        {
                            Or (Local0, 0x02, Local0)
                            And (B1B4 (^^PCI0.LPCB.EC.PR00, ^^PCI0.LPCB.EC.PR01, ^^PCI0.LPCB.EC.PR02, ^^PCI0.LPCB.EC.PR03), 0xFFFF, Local1)
                        }
                    }
                    Else
                    {
\rmdt.p1("UPBS EC.ADP false")
                        Or (Local0, One, Local0)
                        And (B1B4 (^^PCI0.LPCB.EC.PR00, ^^PCI0.LPCB.EC.PR01, ^^PCI0.LPCB.EC.PR02, ^^PCI0.LPCB.EC.PR03), 0xFFFF, Local1)
                    }


                    And (Local1, 0x8000, Local7)
                    If (LEqual (Local7, 0x8000))
                    {
\rmdt.p3("Force store 0xFFFFFFFF due to Local7", Local7, Local1)
                        Store (0xFFFFFFFF, Local1)
                    }


                    And (B1B4 (^^PCI0.LPCB.EC.RC00, ^^PCI0.LPCB.EC.RC01, ^^PCI0.LPCB.EC.RC02, ^^PCI0.LPCB.EC.RC03), 0xFFFF, Local2)
                    And (B1B4 (^^PCI0.LPCB.EC.PV00, ^^PCI0.LPCB.EC.PV01, ^^PCI0.LPCB.EC.PV02, ^^PCI0.LPCB.EC.PV03), 0xFFFF, Local3)
                    Store (Local0, Index (PBST, Zero))
                    Store (Local1, Index (PBST, One))
                    Store (Local2, Index (PBST, 0x02))
                    Store (Local3, Index (PBST, 0x03))
                    If (LNotEqual (BFCC, B1B4 (^^PCI0.LPCB.EC.FC00, ^^PCI0.LPCB.EC.FC01, ^^PCI0.LPCB.EC.FC02, ^^PCI0.LPCB.EC.FC03)))
                    {
                        Notify (BAT0, 0x81)
                    }
                }
                Else
                {
\rmdt.p1("calling IVBS from UPBS!!")
                    IVBS ()
                }

I CAME into this (from acpi.info)

I am well aware of what is written in the ACPI spec.
 
How to patch DSDT for working battery status

Background
(...)

Generally I recommend you use ACPIBatteryManager.kext, available here: https://github.com/RehabMan/OS-X-ACPI-Battery-Driver

Later releases of AppleACPIPlatform are unable to correctly access fields within the EC (embedded controller). This causes problems for ACPIBatteryManager as the various ACPI methods for battery fail (_BIF, _STA, _BST, etc). Although it is possible to use an older version of AppleACPIPlatform (from Snow Leopard), it is desirable to use the latest version of AppleACPIPlatform because with computers that have Ivy Bridge CPUs it enables native power management for those computers. To use the latest version, DSDT must be changed to comply with the limitations of Apple's AppleACPIPlatform.

(...)

I have a i5-3210m proccessor, do i have to patch it? Or just use your ACPIBatteryManager.kext?
 
Back
Top