Contribute
Register

[Guide] How to patch DSDT for working battery status

How to patch DSDT for working battery status

IOReg copy is attached below.

Thanks.

Battery shows 0x400 CurrentCapacity (1024) and 4640 (0x1220) MaxCapacity. About 22%... correct?
 
How to patch DSDT for working battery status

Battery shows 0x400 CurrentCapacity (1024) and 4640 (0x1220) MaxCapacity. About 22%... correct?

Yes, 22% but remaining time showed 0:00, with 100% charge it shows 4 mins.
 
How to patch DSDT for working battery status

Yes, 22% but remaining time showed 0:00, with 100% charge it shows 4 mins.

Probably because the Amperage reported (0xffffffffffff0000) is not correct.

Use the debug version to figure out what is wrong with your _BST method.
 
How to patch DSDT for working battery status

Probably because the Amperage reported (0xffffffffffff0000) is not correct.

Use the debug version to figure out what is wrong with your _BST method.

Using the debug version and looking in the console, I think the problem is with fCurrentRate it's reported firstly as 0xffffffff then as 'ACPI_UNKNOWN' and AppleSmartBattery automatically adjusts it to 0x10000 (65536).

.log file is attached below.

From what I've read, battery information is stored in the following section :

Code:
// Battery status storage

Name (PBST, Package (0x04)
{
    Zero,             // 0x00, Battery state
    0xFFFFFFFF,       // 0x01, Battery present rate
    0xFFFFFFFF,       // 0x02, Battery remaining capacity
    0x2710            // 0x03, Battery present voltage
})

And the _BST method is the one responsible of updating that status info. Here is the one implemented in my DSDT :
Code:
Method (_BST, 0, NotSerialized)
            {
                If (ECON)
                {
                    Store (^^PCI0.LPCB.EC0.MBTS, Local0)
                    If (Local0)
                    {
                        UPBS ()
                    }
                    Else
                    {
                        IVBS ()
                    }
                }
                Else
                {
                    IVBS ()
                }

And from what I understand from _BST, it's checking if the battery is present then it calls the UPBS method, and here it is :

Code:
Method (UPBS, 0, NotSerialized)
            {
                If (LGreaterEqual (PREV, 0x02))
                {
                    Store (B1B2 (^^PCI0.LPCB.EC0.CUR0, ^^PCI0.LPCB.EC0.CUR1), Local5)
                    Store (POSW (Local5), Index (PBST, One))
                }

                Store (B1B2 (^^PCI0.LPCB.EC0.BRM0, ^^PCI0.LPCB.EC0.BRM1), Local5)
                If (LNot (And (Local5, 0x8000)))
                {
                    ShiftRight (Local5, 0x05, Local5)
                    ShiftLeft (Local5, 0x05, Local5)
                    If (LNotEqual (Local5, DerefOf (Index (PBST, 0x02))))
                    {
                        If (LEqual (^^PCI0.LPCB.EC0.BACR, One))
                        {
                            Store (FABL, Index (PBST, 0x02))
                        }
                        Else
                        {
                            Store (Local5, Index (PBST, 0x02))
                        }
                    }
                }

                Store (B1B2 (^^PCI0.LPCB.EC0.BCV0, ^^PCI0.LPCB.EC0.BCV1), Index (PBST, 0x03))
                Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero))
            }

So IMHO, the problem lies within this UPBS method, which is not updating current rate field in PBST and somehow the ACPI_UNKNOWN is returned to AppleSmartBattery.

I'm still new to ASL so I'm not yet able to understand everything.

Also, there is another thing besides remaining time : battery percentage in the menu bar updates slowly, sometimes after 10 mins, 20 mins or even more, and it updates if I sleep and wakeup or restart.

But looking at the console, AppleSmartBatteryManager is calling for status updates every 30 seconds and getting correct current capacity and other values (aside from buggy current rate).

Any leads about this ?

Again, thank you for all your efforts here :D
 

Attachments

  • batterydischarge.log
    2.7 KB · Views: 113
How to patch DSDT for working battery status

Using the debug version and looking in the console, I think the problem is with fCurrentRate it's reported firstly as 0xffffffff then as 'ACPI_UNKNOWN' and AppleSmartBattery automatically adjusts it to 0x10000 (65536).

.log file is attached below.

You did not attach the system.log. Check it to be sure _BST is not returning an error...

From what I've read, battery information is stored in the following section :

Code:
// Battery status storage

Name (PBST, Package (0x04)
{
    Zero,             // 0x00, Battery state
    0xFFFFFFFF,       // 0x01, Battery present rate
    0xFFFFFFFF,       // 0x02, Battery remaining capacity
    0x2710            // 0x03, Battery present voltage
})

And the _BST method is the one responsible of updating that status info. Here is the one implemented in my DSDT :
Code:
Method (_BST, 0, NotSerialized)
            {
                If (ECON)
                {
                    Store (^^PCI0.LPCB.EC0.MBTS, Local0)
                    If (Local0)
                    {
                        UPBS ()
                    }
                    Else
                    {
                        IVBS ()
                    }
                }
                Else
                {
                    IVBS ()
                }

And from what I understand from _BST, it's checking if the battery is present then it calls the UPBS method, and here it is :

Code:
Method (UPBS, 0, NotSerialized)
            {
                If (LGreaterEqual (PREV, 0x02))
                {
                    Store (B1B2 (^^PCI0.LPCB.EC0.CUR0, ^^PCI0.LPCB.EC0.CUR1), Local5)
                    Store (POSW (Local5), Index (PBST, One))
                }

                Store (B1B2 (^^PCI0.LPCB.EC0.BRM0, ^^PCI0.LPCB.EC0.BRM1), Local5)
                If (LNot (And (Local5, 0x8000)))
                {
                    ShiftRight (Local5, 0x05, Local5)
                    ShiftLeft (Local5, 0x05, Local5)
                    If (LNotEqual (Local5, DerefOf (Index (PBST, 0x02))))
                    {
                        If (LEqual (^^PCI0.LPCB.EC0.BACR, One))
                        {
                            Store (FABL, Index (PBST, 0x02))
                        }
                        Else
                        {
                            Store (Local5, Index (PBST, 0x02))
                        }
                    }
                }

                Store (B1B2 (^^PCI0.LPCB.EC0.BCV0, ^^PCI0.LPCB.EC0.BCV1), Index (PBST, 0x03))
                Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero))
            }

So IMHO, the problem lies within this UPBS method, which is not updating current rate field in PBST and somehow the ACPI_UNKNOWN is returned to AppleSmartBattery.

I'm still new to ASL so I'm not yet able to understand everything.

Also, there is another thing besides remaining time : battery percentage in the menu bar updates slowly, sometimes after 10 mins, or does not update at all until I sleep and wakeup or restart, but looking at the console, AppleSmartBatteryManager is calling for status updates every 30 seconds and getting correct current capacity (aside from buggy current rate).

Any leads about this ?

You're on the right track. And you might consider debugging your DSDT methods. See what the execution path is. See here: https://github.com/RehabMan/OS-X-ACPI-Debug (note: github might be down right now).
 
How to patch DSDT for working battery status

You did not attach the system.log. Check it to be sure _BST is not returning an error...

It's now attached in my previous post, sorry I forgot about it.

You're on the right track. And you might consider debugging your DSDT methods. See what the execution path is. See here: https://github.com/RehabMan/OS-X-ACPI-Debug (note: github might be down right now).

Yes, it's down. I'll take a look once it's up.

Thank you.
 
How to patch DSDT for working battery status

It's now attached in my previous post, sorry I forgot about it.

Yup. Definitely a buggy DSDT. I'm sure you'll figure out what is missing with a little debugging.

You could also go here for ACPIDebug.kext: http://www.tonymacx86.com/dsdt/111868-dsdt-debugging-tracing-system-log.html

Problem is you need the patch:
Code:
#Maintained by: RehabMan for: Laptop Patches
#debug.txt

#
# Facility for writing trace output to system.log
#
# Use in conjunction with ACPIDebug.kext
#
# EXPERIMENTAL
#
# Written by RehabMan 2013-10-15
#

into device label RMDT remove_entry;
into definitionblock code_regex . insert
begin
Device (RMDT)\n
{\n
    Name (_HID, "RMD0000")\n
    Name (RING, Package(256) { })\n
    Mutex (RTMX, 0)\n
    Name (HEAD, 0)\n
    Name (TAIL, 0)\n
    // PUSH: Use to push a trace item into RING for ACPIDebug.kext\n
    Method (PUSH, 1, NotSerialized)\n
    {\n
        Acquire(RTMX, 0xFFFF)\n
        // push new item at HEAD\n
        Add(HEAD, 1, Local0)\n
        If (LGreaterEqual(Local0, SizeOf(RING))) { Store(0, Local0) }\n
        if (LNotEqual(Local0, TAIL))\n
        {\n
            Store(Arg0, Index(RING, HEAD))\n
            Store(Local0, HEAD)\n
        }\n
        Release(RTMX)\n
        Notify(RMDT, 0x80)
    }\n
    // FTCH: Used by ACPIDebug.kext to fetch an item from RING\n
    Method (FTCH, 0, NotSerialized)\n
    {\n
        Acquire(RTMX, 0xFFFF)\n
        // pull item from TAIL and return it\n
        Store(0, Local0)\n
        if (LNotEqual(HEAD, TAIL))\n
        {\n
            Store(DerefOf(Index(RING, TAIL)), Local0)\n
            Increment(TAIL)\n
            If (LGreaterEqual(TAIL, SizeOf(RING))) { Store(0, TAIL) }\n
        }\n
        Release(RTMX)\n
        Return(Local0)\n
    }\n
    // COUN: Used by ACPIDebug.kext to determine number of items in RING\n
    Method (COUN, 0, NotSerialized)\n
    {\n
        Acquire(RTMX, 0xFFFF)\n
        // return count of items in RING\n
        Subtract(HEAD, TAIL, Local0)\n
        if (LLess(Local0, 0)) { Add(Local0, SizeOf(RING), Local0) }\n
        Release(RTMX)\n
        Return(Local0)\n
    }\n
    // Helper functions for multiple params at one time\n
    Method (P1, 1, NotSerialized) { PUSH(Arg0) }\n
    Method (P2, 2, Serialized)\n
    {\n
        Name (TEMP, Package(2) { })\n
        Store(Arg0, Index(TEMP, 0))\n
        Store(Arg1, Index(TEMP, 1))\n
        PUSH(TEMP)\n
    }\n
    Method (P3, 3, Serialized)\n
    {\n
        Name (TEMP, Package(3) { })\n
        Store(Arg0, Index(TEMP, 0))\n
        Store(Arg1, Index(TEMP, 1))\n
        Store(Arg2, Index(TEMP, 2))\n
        PUSH(TEMP)\n
    }\n
    Method (P4, 4, Serialized)\n
    {\n
        Name (TEMP, Package(4) { })\n
        Store(Arg0, Index(TEMP, 0))\n
        Store(Arg1, Index(TEMP, 1))\n
        Store(Arg2, Index(TEMP, 2))\n
        Store(Arg3, Index(TEMP, 3))\n
        PUSH(TEMP)\n
    }\n
    Method (P5, 5, Serialized)\n
    {\n
        Name (TEMP, Package(5) { })\n
        Store(Arg0, Index(TEMP, 0))\n
        Store(Arg1, Index(TEMP, 1))\n
        Store(Arg2, Index(TEMP, 2))\n
        Store(Arg3, Index(TEMP, 3))\n
        Store(Arg4, Index(TEMP, 4))\n
        PUSH(TEMP)\n
    }\n
    Method (P6, 6, Serialized)\n
    {\n
        Name (TEMP, Package(6) { })\n
        Store(Arg0, Index(TEMP, 0))\n
        Store(Arg1, Index(TEMP, 1))\n
        Store(Arg2, Index(TEMP, 2))\n
        Store(Arg3, Index(TEMP, 3))\n
        Store(Arg4, Index(TEMP, 4))\n
        Store(Arg5, Index(TEMP, 5))\n
        PUSH(TEMP)\n
    }\n
    Method (P7, 7, Serialized)\n
    {\n
        Name (TEMP, Package(7) { })\n
        Store(Arg0, Index(TEMP, 0))\n
        Store(Arg1, Index(TEMP, 1))\n
        Store(Arg2, Index(TEMP, 2))\n
        Store(Arg3, Index(TEMP, 3))\n
        Store(Arg4, Index(TEMP, 4))\n
        Store(Arg5, Index(TEMP, 5))\n
        Store(Arg6, Index(TEMP, 6))\n
        PUSH(TEMP)\n
    }\n
}\n
end;
 
How to patch DSDT for working battery status

Yup. Definitely a buggy DSDT. I'm sure you'll figure out what is missing with a little debugging.

You could also go here for ACPIDebug.kext: http://www.tonymacx86.com/dsdt/111868-dsdt-debugging-tracing-system-log.html

Thank you, ACPIDebug is really helpful :D

Yes, it turned out that UPBS was buggy, and here is a patch to correct it's implementation.

It works for HP Pavilion dv6-3165sf and It should work for other dv models who have a similar problem (remaining time miscalculation)

Credits for gsly from Insanelymac for the correct implementation.

Code:
into method label UPBS remove_entry;
into device label BAT0 insert
begin
Method (UPBS, 0, NotSerialized)\n
{\n
    Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero))\n
    ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0A, RefOf (Local0))\n
    Store (Local0, Index (PBST, One))\n
    ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0F, RefOf (Local1))\n
    Store (Local1, Index (PBST, 0x02))\n
    ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x09, RefOf (Local2))\n
    Store (Local2, Index (PBST, 0x03))\n
}\n
end;
 
How to patch DSDT for working battery status

Thank you, ACPIDebug is really helpful :D

It has been more helpful (to me) than I ever expected. I wish I'd written it sooner...

Yes, it turned out that UPBS was buggy, and here is a patch to correct it's implementation.

It works for HP Pavilion dv6-3165sf and It should work for other dv models who have a similar problem (remaining time miscalculation)

Credits for gsly from Insanelymac for the correct implementation.

Code:
into method label UPBS remove_entry;
into device label BAT0 insert
begin
Method (UPBS, 0, NotSerialized)\n
{\n
    Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero))\n
    ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0A, RefOf (Local0))\n
    Store (Local0, Index (PBST, One))\n
    ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0F, RefOf (Local1))\n
    Store (Local1, Index (PBST, 0x02))\n
    ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x09, RefOf (Local2))\n
    Store (Local2, Index (PBST, 0x03))\n
}\n
end;

Nice.

So the rest of the battery_HP-G6-2221ss.txt plus this patch will work? If so, I will make a new file specifically for this HP dv6-3165sf split off from the G6 patch and add it to the repo with appropriate credit.
 
How to patch DSDT for working battery status

Nice.

So the rest of the battery_HP-G6-2221ss.txt plus this patch will work? If so, I will make a new file specifically for this HP dv6-3165sf split off from the G6 patch and add it to the repo with appropriate credit.

Yes, battery_HP-G6-2221ss.txt plus this patch works flawlessly with HP dv6-3165sf.
 
Back
Top