Contribute
Register

[Guide] How to patch DSDT for working battery status

How to patch DSDT for working battery status

I don't think there is a need for dynamic patching. As DSDT is patched once only. It does not change with new updates of OS X. I believe only the kext might need to be updated but I am not sure.

You would need to re-patch DSDT after any BIOS update, or any hardware change. The kext will survive OS X updates.
 
How to patch DSDT for working battery status

Nice/clean work. I will definitely add it to the repo for others.

The kext estimates cycle count (as it is not provided usually by ACPI methods) by this formula: (DesignCapacity-MaxCapacity)/6.

If you can determine where (if available) the EC stores battery cycle count, you can change the _BIF to return an extra entry in the result at position 13 in the array (position 14 can be for temperature).

Thanks. I will look into it. I will let you know if I find something.

- - - Updated - - -

You would need to re-patch DSDT after any BIOS update, or any hardware change. The kext will survive OS X updates.

So unless any change in hardware or bios is made, your solution is full-proof. Thanks!
 
How to patch DSDT for working battery status

Background

Because the battery hardware in PCs is not compatible with Apple SMbus hardware, we use ACPI to access battery state when running OS X on laptops. 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.

In particular, any fields in the EC larger than 8-bit, must be changed to be accessed 8-bits at one time. This includes 16, 32, 64, and larger fields.

Existing Patches

First of all, it could be that there is patch already available for your laptop. See my patches at: https://github.com/RehabMan/Laptop-DSDT-Patch

In order to match your DSDT with a patch, it is often necessary to understand how the patches are made in the first place, so you know what to look for in your DSDT and can match what you see with the patches already available.

*** Note: Do not use DSDT Editor or any program other than MaciASL. I do not test my patches with DSDT Editor. I test only with MaciASL.

Skills Required

DSDT is a "program." As such, it is helpful to have some programming/computer skills when modifying it. Also, DSDT patches themselves have their own language (described briefly in the MaciASL wiki, available at here: http://sourceforge.net/projects/maciasl/). Finally, the patches themselves are basically scoped regular expression search/replace, so it is helpful to understand regular expressions (regex). Familiarity with compilers, compiler errors, and an ability to determine what the compiler is telling you about errors in the code is also useful.

Also, it is a good idea to be familiar with ACPI. You can download the specification here: https://www.acpica.org/

It is not the purpose of this guide to teach you basic programming skills, regular expressions, or the ACPI language.

The patching process

I use a rather 'mechanical' process to patching DSDT for battery status. I simply look for the parts that OS X finds offensive and mechanically convert it. I don't try too hard to determine what sections of the code are actually going to execute, I just convert everything that I see.

To follow along, download the example DSDT from this post and follow along. This particular example DSDT is for an HP Envy 14. The final, complete patch, is available from my patch repo as "HP Envy 14."

First start by identifing the areas of the DSDT that are likely to need changes. Load the DSDT into MaciASL and search for 'EmbeddedControl'. There can be several 'EmbeddedControl' sections in a single DSDT, each with field declarations attached to it.

So, I always start out looking for 'embeddedcontrol' in order to find this declaration.

In the example DSDT, you will find this single EC region:
Code:
   OperationRegion (ECF2, EmbeddedControl, Zero, 0xFF)

The above code defines a 255 byte EC region.

We know it is called ECF2, so now we want to search for 'Field (ECF2'. As you can see in the example DSDT, there is only one Field definition referring to this region. Sometimes there are many.

The Field definition describes a breakdown of that 255 byte EC region above. You can tell it is related because the name ECF2 is referred to by the Field. Think of this as a structure (struct for C programmers) into the EC.

The next step is to examine the items in the Field definition, looking for items which are larger than 8-bit. For example, the first field declared is BDN0, 56:
Code:
   Field (ECF2, ByteAcc, Lock, Preserve)
   {
       Offset (0x10), 
       BDN0,   56, 
...

It is a 56-bit field. Larger than 8-bit and if it is accessed in the DSDT, the code there will need edits as will the definition of this field. In the example DSDT, if you search the rest of the DSDT for "BDN0", you will find:

Code:
   Store (BDN0, BDN)

This is intended to store the value at BDN0 (in the EC) into BDN. When fields larger than 32-bit are accessed, they are accessed as type Buffer. Fields 32-bit or under are accessed as Integers. This is important to realize as you change the code. Buffers are a bit more work to change. Also, realize this code is "reading" from the EC. Reads and writes must be handled differently.

So, for this particular line of code, the goal is to read this 56-bit field (7 bytes) 8-bits at time into a buffer, so the resulting buffer can be stored into BDN. We will get back to how this is accomplished later, for now let's explore the rest of the fields in this EC.

Looking through the rest of the the EC, we look for all fields larger than 8-bit, and for each one, search the rest of the DSDT to see if they are accessed. It is common that some fields are not accessed and for those we don't have to do anything. So, the next field we see is BMN0:
Code:
   BMN0,   32,

If we search the DSDT for 'BMN0' we find only this declaration, so it is not accessed. We can ignore this one. Same with BMN4. BCT0, on the other hand, is 128 bit and is accessed, much like BDN0:
Code:
   Store (BCT0, CTN)

Further searching leads to this comprehensive list:
Code:
                        BDN0,   56, 
                        BCT0,   128, 
                        BDN1,   56, 
                        BCT1,   128, 
...
                        BDC0,   16, 
                        BDC1,   16, 
                        BFC0,   16, 
                        BFC1,   16, 
...
                        BDV0,   16, 
                        BDV1,   16, 
...
                        BPR0,   16, 
                        BPR1,   16, 

                        BRC0,   16, 
                        BRC1,   16, 
                        BCC0,   16, 
                        BCC1,   16, 
                        CV01,   16, 
                        CV02,   16, 
                        CV03,   16, 
                        CV04,   16, 
                        CV11,   16, 
                        CV12,   16, 
                        CV13,   16, 
                        CV14,   16, 
...
                        BMD0,   16, 
                        BMD1,   16, 
                        BPV0,   16, 
                        BPV1,   16, 
                        BSN0,   16, 
                        BSN1,   16, 
                        BCV0,   16, 
                        BCV1,   16, 
                        CRG0,   16, 
                        CRG1,   16, 
                        BTY0,   32, 
                        BTY1,   32, 
...
                        CBT0,   16, 
                        CBT1,   16,

As you can see, there are quite a few fields in this DSDT that need work, and all of various sizes. 16-bit, 32-bit, 56-bit and 128-bit.

Fields sized 16-bit and 32-bit

Fields that are 16-bit and 32-bit are the easiest to deal with, so let's start there. Let's take for example, the first 16-bit field in the list above, BDC0. What we want to do is change this field so it is broken into two peices (low-byte, high-byte). To do that we need to come up with a 4-character name that does not conflict with any other names in the DSDT. It is often easy to remove the first letter and use the following three.
Code:
   // was: BDC0, 16
   DC00, 8, 
   DC01, 8,

A patch for this would look like:
Code:
into device label H_EC code_regex BDC0,\s+16, replace_matched begin DC00,8,DC01,8, end;

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))

As you can see this code is reading from BDC0, which is now in two parts. To make a patch easier to construct, we use a utility method called B1B2, which we insert into DSDT with this patch:
Code:
into method label B1B2 remove_entry;
into definitionblock code_regex . insert
begin
Method (B1B2, 2, NotSerialized) { Return(Or(Arg0, ShiftLeft(Arg1, 8))) }\n
end;

This method takes two arguments (low-byte, high-byte), and returns a 16-bit value from the two 8-bit values.

For the code above, we want to translate it to:
Code:
   Store (B1B2(DC00,DC01), Index (DerefOf (Index (Local0, 0x02)), Zero))
   Store (ShiftRight (B1B2(DC00,DC01), 0x08), Index (DerefOf (Index (Local0, 0x02)), One))

A patch can be constructed to automate this, and as you will see patches for other 16-bit fields follow this same pattern:
Code:
into method label GBTI code_regex \(BDC0, replaceall_matched begin (B1B2(DC00,DC01), end;

An astute reader will note that this code could be optimized:
Code:
   Store (DC00, Index (DerefOf (Index (Local0, 0x02)), Zero))
   Store (DC01, Index (DerefOf (Index (Local0, 0x02)), One))

Such optimizations can only be made by using your brain, and generally it is not worth it. The goal here is to come up with an automated method of fixing this code and not to attempt to use our brain too much as we could introduce bugs into the code if we change it too drastically. Also, this kind of code is rare (I have only seen it only in two DSDTs out of more than 20 that I've written patches for).

Now that you understand how to deal with 16-bit registers, it is probably easiest to just convert all of them. Here is the comprehensive patch for the 16-bit EC fields:
Code:
# 16-bit registers
into device label H_EC code_regex BDC0,\s+16 replace_matched begin DC00,8,DC01,8 end;
into device label H_EC code_regex BDC1,\s+16 replace_matched begin DC10,8,DC11,8 end;
into device label H_EC code_regex BFC0,\s+16 replace_matched begin FC00,8,FC01,8 end;
into device label H_EC code_regex BFC1,\s+16 replace_matched begin FC10,8,FC11,8 end;
into device label H_EC code_regex BDV0,\s+16 replace_matched begin DV00,8,DV01,8 end;
into device label H_EC code_regex BDV1,\s+16 replace_matched begin DV10,8,DV11,8 end;
into device label H_EC code_regex BPR0,\s+16 replace_matched begin PR00,8,PR01,8 end;
into device label H_EC code_regex BPR1,\s+16 replace_matched begin PR10,8,PR11,8 end;
into device label H_EC code_regex BRC0,\s+16 replace_matched begin RC00,8,RC01,8 end;
into device label H_EC code_regex BRC1,\s+16 replace_matched begin RC10,8,RC11,8 end;
into device label H_EC code_regex BCC0,\s+16 replace_matched begin CC00,8,CC01,8 end;
into device label H_EC code_regex BCC1,\s+16 replace_matched begin CC10,8,CC11,8 end;
into device label H_EC code_regex CV01,\s+16 replace_matched begin CV10,8,CV11,8 end;
into device label H_EC code_regex CV02,\s+16 replace_matched begin CV20,8,CV21,8 end;
into device label H_EC code_regex CV03,\s+16 replace_matched begin CV30,8,CV31,8 end;
into device label H_EC code_regex CV04,\s+16 replace_matched begin CV40,8,CV41,8 end;
into device label H_EC code_regex CV11,\s+16 replace_matched begin CV50,8,CV51,8 end;
into device label H_EC code_regex CV12,\s+16 replace_matched begin CV60,8,CV61,8 end;
into device label H_EC code_regex CV13,\s+16 replace_matched begin CV70,8,CV71,8 end;
into device label H_EC code_regex CV14,\s+16 replace_matched begin CV80,8,CV81,8 end;
into device label H_EC code_regex HPBA,\s+16 replace_matched begin PBA0,8,PBA1,8 end;
into device label H_EC code_regex HPBB,\s+16 replace_matched begin PBB0,8,PBB1,8 end;
into device label H_EC code_regex BMD0,\s+16 replace_matched begin MD00,8,MD01,8 end;
into device label H_EC code_regex BMD1,\s+16 replace_matched begin MD10,8,MD11,8 end;
into device label H_EC code_regex BPV0,\s+16 replace_matched begin PV00,8,PV01,8 end;
into device label H_EC code_regex BPV1,\s+16 replace_matched begin PV10,8,PV11,8 end;
into device label H_EC code_regex BSN0,\s+16 replace_matched begin SN00,8,SN01,8 end;
into device label H_EC code_regex BSN1,\s+16 replace_matched begin SN10,8,SN11,8 end;
into device label H_EC code_regex BCV0,\s+16 replace_matched begin BV00,8,BV01,8 end;
into device label H_EC code_regex BCV1,\s+16 replace_matched begin BV10,8,BV11,8 end;
into device label H_EC code_regex CRG0,\s+16 replace_matched begin RG00,8,RG01,8 end;
into device label H_EC code_regex CRG1,\s+16 replace_matched begin RG10,8,RG11,8 end;
into device label H_EC code_regex CBT0,\s+16 replace_matched begin BT00,8,BT01,8 end;
into device label H_EC code_regex CBT1,\s+16 replace_matched begin BT10,8,BT11,8 end;

And all the code which accesses those registers needs to be fixed:
Code:
# fix 16-bit methods
into method label GBTI code_regex \(BDC0, replaceall_matched begin (B1B2(DC00,DC01), end;
into method label GBTI code_regex \(BDC1, replaceall_matched begin (B1B2(DC10,DC11), end;
into method label GBTI code_regex \(BFC0, replaceall_matched begin (B1B2(FC00,FC01), end;
into method label GBTI code_regex \(BFC1, replaceall_matched begin (B1B2(FC10,FC11), end;
into method label BTIF code_regex \(BFC0, replaceall_matched begin (B1B2(FC00,FC01), end;
into method label BTIF code_regex \(BFC1, replaceall_matched begin (B1B2(FC10,FC11), end;
into method label ITLB code_regex \(BFC1, replaceall_matched begin (B1B2(FC10,FC11), end;
into method label ITLB code_regex \sBFC0, replaceall_matched begin B1B2(FC00,FC01), end;
into method label _Q09 code_regex \(BRC0, replaceall_matched begin (B1B2(RC00,RC01), end;
into method label _Q09 code_regex \sBFC0\) replaceall_matched begin B1B2(FC00,FC01)) end;
into method label GBTI code_regex \(BDV0, replaceall_matched begin (B1B2(DV00,DV01), end;
into method label GBTI code_regex \(BDV1, replaceall_matched begin (B1B2(DV10,DV11), end;
into method label BTIF code_regex \(BDV0, replaceall_matched begin (B1B2(DV00,DV01), end;
into method label BTIF code_regex \(BDV1, replaceall_matched begin (B1B2(DV10,DV11), end;
into method label GBTI code_regex \(BPR0, replaceall_matched begin (B1B2(PR00,PR01), end;
into method label GBTI code_regex \(BPR1, replaceall_matched begin (B1B2(PR10,PR11), end;
into method label BTST code_regex \sBPR0, replaceall_matched begin B1B2(PR00,PR01), end;
into method label BTST code_regex \sBPR1, replaceall_matched begin B1B2(PR10,PR11), end;
into method label BTST code_regex \(BPR0, replaceall_matched begin (B1B2(PR00,PR01), end;
into method label BTST code_regex \(BPR1, replaceall_matched begin (B1B2(PR10,PR11), end;
into method label BTST code_regex \(BRC0, replaceall_matched begin (B1B2(RC00,RC01), end;
into method label BTST code_regex \(BRC1, replaceall_matched begin (B1B2(RC10,RC11), end;
into method label GBTI code_regex \(BRC0, replaceall_matched begin (B1B2(RC00,RC01), end;
into method label GBTI code_regex \(BRC1, replaceall_matched begin (B1B2(RC10,RC11), end;
into method label _Q09 code_regex \(BRC0, replaceall_matched begin (B1B2(RC00,RC01), end;
into method label GBTI code_regex \(BCC0, replaceall_matched begin (B1B2(CC00,CC01), end;
into method label GBTI code_regex \(BCC1, replaceall_matched begin (B1B2(CC10,CC11), end;
into method label GBTI code_regex \(CV01, replaceall_matched begin (B1B2(CV10,CV11), end;
into method label GBTI code_regex \(CV02, replaceall_matched begin (B1B2(CV20,CV21), end;
into method label GBTI code_regex \(CV03, replaceall_matched begin (B1B2(CV30,CV31), end;
into method label GBTI code_regex \(CV04, replaceall_matched begin (B1B2(CV40,CV41), end;
into method label GBTI code_regex \(CV11, replaceall_matched begin (B1B2(CV50,CV51), end;
into method label GBTI code_regex \(CV12, replaceall_matched begin (B1B2(CV60,CV61), end;
into method label GBTI code_regex \(CV13, replaceall_matched begin (B1B2(CV70,CV71), end;
into method label GBTI code_regex \(CV14, replaceall_matched begin (B1B2(CV80,CV81), end;
into method label BTIF code_regex \(BMD0, replaceall_matched begin (B1B2(MD00,MD01), end;
into method label BTIF code_regex \(BMD1, replaceall_matched begin (B1B2(MD10,MD11), end;
into method label GBTI code_regex \sBMD0\) replaceall_matched begin B1B2(MD00,MD01)) end;
into method label GBTI code_regex \(BMD0, replaceall_matched begin (B1B2(MD00,MD01), end;
into method label GBTI code_regex \sBMD1\) replaceall_matched begin B1B2(MD10,MD11)) end;
into method label GBTI code_regex \(BMD1, replaceall_matched begin (B1B2(MD10,MD11), end;
into method label BTST code_regex \(BPV0, replaceall_matched begin (B1B2(PV00,PV01), end;
into method label BTST code_regex \(BPV1, replaceall_matched begin (B1B2(PV10,PV11), end;
into method label GBTI code_regex \(BPV0, replaceall_matched begin (B1B2(PV00,PV01), end;
into method label GBTI code_regex \(BPV1, replaceall_matched begin (B1B2(PV10,PV11), end;
into method label BTIF code_regex \(BSN0, replaceall_matched begin (B1B2(SN00,SN01), end;
into method label BTIF code_regex \(BSN1, replaceall_matched begin (B1B2(SN10,SN11), end;
into method label GBTI code_regex \(BSN0, replaceall_matched begin (B1B2(SN00,SN01), end;
into method label GBTI code_regex \(BSN1, replaceall_matched begin (B1B2(SN10,SN11), end;
into method label GBTI code_regex \(BCV0, replaceall_matched begin (B1B2(BV00,BV01), end;
into method label GBTI code_regex \(BCV1, replaceall_matched begin (B1B2(BV10,BV11), end;
into method label GBTI code_regex \(CRG0, replaceall_matched begin (B1B2(RG00,RG01), end;
into method label GBTI code_regex \(CRG1, replaceall_matched begin (B1B2(RG10,RG11), end;
into method label GBTI code_regex \(CBT0, replaceall_matched begin (B1B2(BT00,BT01), end;
into method label GBTI code_regex \(CBT1, replaceall_matched begin (B1B2(BT10,BT11), end;


Now, what about the 32-bit registers, BTY0, and BTY1? These are handled similarly to 16-bit, except we need a B1B4 method that can construct a 32-bit value out of four 8-bit values:
Code:
into method label B1B4 remove_entry;
into definitionblock code_regex . insert
begin
Method (B1B4, 4, NotSerialized)\n
{\n
    Store(Arg3, Local0)\n
    Or(Arg2, ShiftLeft(Local0, 8), Local0)\n
    Or(Arg1, ShiftLeft(Local0, 8), Local0)\n
    Or(Arg0, ShiftLeft(Local0, 8), Local0)\n
    Return(Local0)\n
}\n
end;

And we need to convert BTY0 and BTY1 into four 8-bit registers:
Code:
# 32-bit registers
into device label H_EC code_regex BTY0,\s+32 replace_matched begin TY00,8,TY01,8,TY02,8,TY03,8 end;
into device label H_EC code_regex BTY1,\s+32 replace_matched begin TY10,8,TY11,8,TY12,8,TY13,8 end;

And the code in GBTI needs fixing:
Code:
   Store (BTY0, BTY)
...
   Store (BTY1, BTYB)

Similar to the patches for 16-bit, but instead we use B1B4:
Code:
# fix 32-bit methods
into method label GBTI code_regex \(BTY0, replaceall_matched begin (B1B4(TY00,TY01,TY02,TY03), end;

Which changes the above code, as follows:
Code:
   Store (B1B4(TY00,TY01,TY02,TY03), BTY)
...
   Store (B1B4(TY10,TY11,TY12,TY13), BTYB)


Buffer Fields (fields larger than 32-bit

Back to our original search for fields larger than 8-bit, we had these fields larger than 32-bit:
Code:
   BDN0,   56, 
   BCT0,   128, 
   BDN1,   56, 
   BCT1,   128,

To access these fields 8-bit at a time is rather tedious, so I like to access them by offset, and to make sure no existing code accesses them directly, we rename them:
Code:
into device label H_EC code_regex (BDN0,)\s+(56) replace_matched begin BDNX,%2,//%1%2 end;
into device label H_EC code_regex (BDN1,)\s+(56) replace_matched begin BDNY,%2,//%1%2 end;
into device label H_EC code_regex (BCT0,)\s+(128) replace_matched begin BCTX,%2,//%1%2 end;
into device label H_EC code_regex (BCT1,)\s+(128) replace_matched begin BCTY,%2,//%1%2 end;

Next we need to determine the offsets within the EC that these fields are placed. Keep in mind the sizes are in bits, but the offsets are in bytes. The offsets I have in the comments below are in hex. See if you can come up with the same numbers.

Code:
   Field (ECF2, ByteAcc, Lock, Preserve)
   {
            Offset (0x10), 
       BDN0,   56,     //!!0x10
            Offset (0x18), 
       BME0,   8, 
            Offset (0x20), 
       BMN0,   32,     //0x20
       BMN2,   8,     //0x24
       BMN4,   88,    //0x25
       BCT0,   128,     //!! 0x30
       BDN1,   56,     //!! 0x40
            Offset (0x48), 
       BME1,   8, 
            Offset (0x50), 
       BMN1,   32,     //0x50
       BMN3,   8,     //0x54
       BMN5,   88,     //0x55
       BCT1,   128,     //!!0x60

Once you run the patch for renaming, and then compile, the compiler will tell you what code needs attention. In our case, we see this code with errors:
Code:
...
   Store (BCT0, CTN)
...
   Store (BDN0, BDN)
...
   Store (BCT1, CTNB)
...
   Store (BDN1, BDNB)
...

There are errors because we renamed them from BCT0, BDN0, BCT1, BDN1 to BCTX, BDNX, BCTY, BDNY, respectively.

As you can see this code is reading from these EC buffer fields and storing them somewhere else. In order to read these items 8-bits at at time, we need a utility method:
Code:
# utility methods to read/write buffers from/to EC
into method label RE1B parent_label H_EC remove_entry;
into method label RECB parent_label H_EC remove_entry;
into device label H_EC insert
begin
Method (RE1B, 1, NotSerialized)\n
{\n
    OperationRegion(ERAM, EmbeddedControl, Arg0, 1)\n
    Field(ERAM, ByteAcc, NoLock, Preserve) { BYTE, 8 }\n
    Return(BYTE)\n
}\n
Method (RECB, 2, Serialized)\n
{\n
    ShiftRight(Arg1, 3, Arg1)\n
    Name(TEMP, Buffer(Arg1) { })\n
    Add(Arg0, Arg1, Arg1)\n
    Store(0, Local0)\n
    While (LLess(Arg0, Arg1))\n
    {\n
        Store(RE1B(Arg0), Index(TEMP, Local0))\n
        Increment(Arg0)\n
        Increment(Local0)\n
    }\n
    Return(TEMP)\n
}\n
end;

"RECB" stands for "Read EC Buffer". It takes two parameters indicating the offset within the EC and the size in bits of the field you wish to read. The size in bits must be a multiple of eight (8). The code does not check.

These helper methods must be defined in the EC device, in the case of this DSDT, named H_EC:
Code:
                Device (H_EC)
                {
                    Name (_HID, EisaId ("PNP0C09"))

You will need to change the patches that create RECB/RE1B if the name of your EC device is different. Common names are EC, EC0, and as in this example H_EC.

To handle the first case of BCT0, we want to do the equivalent of this:
Code:
   Store(RECB(0x30,128), CTN)

The 0x30 is the offset of the BTC0 field (now called BCTX) and the 128 is the number of bits.

These edits can be accomplished with these patches:
Code:
into method label GBTI code_regex \(BCT0, replaceall_matched begin (RECB(0x30,128), end;
into method label GBTI code_regex \(BCT1, replaceall_matched begin (RECB(0x60,128), end;
into method label GBTI code_regex \(BDN0, replaceall_matched begin (RECB(0x10,56), end;
into method label GBTI code_regex \(BDN1, replaceall_matched begin (RECB(0x40,56), end;

This DSDT does not have any writes to EC buffers, but if it did this utility method is useful:
Code:
into method label WE1B parent_label H_EC remove_entry;
into method label WECB parent_label H_EC remove_entry;
into device label H_EC insert
begin
Method (WE1B, 2, NotSerialized)\n
{\n
    OperationRegion(ERAM, EmbeddedControl, Arg0, 1)\n
    Field(ERAM, ByteAcc, NoLock, Preserve) { BYTE, 8 }\n
    Store(Arg1, BYTE)\n
}\n
Method (WECB, 3, Serialized)\n
{\n
    ShiftRight(Arg1, 3, Arg1)\n
    Name(TEMP, Buffer(Arg1) { })\n
    Store(Arg2, TEMP)\n
    Add(Arg0, Arg1, Arg1)\n
    Store(0, Local0)\n
    While (LLess(Arg0, Arg1))\n
    {\n
        WE1B(Arg0, DerefOf(Index(TEMP, Local0)))\n
        Increment(Arg0)\n
        Increment(Local0)\n
    }\n
}\n
end;


Contributing

If you do come up with a patch for your battery methods, you are encouraged to contribute to my patch repository, so please share your patch along with information about your computer, so I can add the patch to my laptop DSDT patch repository.

Rehabman, I have Lenovo Z580 (signature). Put your kexts + DSDT made ​​a patch on the battery, you take a patch on github for your laptop. Bred normally displays everything except the number of charge cycles, I have it is always 0 Снимок экрана 2014-05-08.png. Adjusts DSDT.
 

Attachments

  • DSDT.aml.zip
    16.5 KB · Views: 70
How to patch DSDT for working battery status

Rehabman, I have Lenovo Z580 (signature). Put your kexts + DSDT made ​​a patch on the battery, you take a patch on github for your laptop. Bred normally displays everything except the number of charge cycles, I have it is always 0View attachment 92127. Adjusts DSDT.

Number of charge cycles is not in the ACPI standard (_BIF). See ACPI spec.

This question was just asked. See post #456.
 
How to patch DSDT for working battery status

Number of charge cycles is not in the ACPI standard (_BIF). See ACPI spec.

This question was just asked. See post #456.
I counted ((3913-4400) / 6 = -81.1666666667), but I did not understand where all still fit. Understood only in BIF, but what and how ...
 
How to patch DSDT for working battery status

I counted ((3913-4400) / 6 = -81.1666666667), but I did not understand where all still fit. Understood only in BIF, but what and how ...

DesignCapacity should be larger than MaxCapacity. Since your estimated cycle count is zero, yours must be close to equal (eg. battery is not degraded).

As for actual cycle count, you'd have to scour DSDT for clues...

On the ProBook, we have managed to determine where both cycle count and battery temperature are stored. See: https://github.com/RehabMan/HP-ProBook-4x30s-DSDT-Patch
 
How to patch DSDT for working battery status

Hi,

I tried to patch my dsdt for battery.
This is my dsdt:
And my patch is this:
Is this OK?
I notified when I tried to compile I get a lot of errors.
I'm new to maciasl, in DSDTSE I don't get these errors.
Any help?

Thx
 

Attachments

  • dsdt.aml.zip
    13.5 KB · Views: 70
  • battery patch Samsung R780.txt
    1.4 KB · Views: 150
How to patch DSDT for working battery status

Hi,

I tried to patch my dsdt for battery.
This is my dsdt:
And my patch is this:
Is this OK?
I notified when I tried to compile I get a lot of errors.
I'm new to maciasl, in DSDTSE I don't get these errors.
Any help?

Thx

The patch is not complete. Use ACPI 4.0. Try existing patch for "Samsung RF411"
 
How to patch DSDT for working battery status

Thx Rehabman,

It is working now.
I used the patch for the Samsung RF-411.
I use the original AppleSmartBatteryManager.kext and your ACPIBatteryManager.kext.
However, I noticed I need to use the AppleACPIPlatform.kext from Voodoobattery to have a working sleep.
And I also need the original AppleACPIPlatform.kext (2.0) to have my App Store working (otherwise I can't login).
Any clue for this?
 
How to patch DSDT for working battery status

Thx Rehabman,

It is working now.
I used the patch for the Samsung RF-411.
I use the original AppleSmartBatteryManager.kext and your ACPIBatteryManager.kext.
However, I noticed I need to use the AppleACPIPlatform.kext from Voodoobattery to have a working sleep.
And I also need the original AppleACPIPlatform.kext (2.0) to have my App Store working (otherwise I can't login).
Any clue for this?

Something is broken with your power management such that sleep doesn't work with current AppleACPIPlatform. Off-topic for here, open separate thread.
 
Back
Top