Contribute
Register

<< Solved >> OpenCore battery patch

Status
Not open for further replies.
@BlvckBytes

that’s awesome !, I tried it with a bunch of dsdt and seems to work just fine, I think the next step is to make it exclude all registers that’s not used in the dsdt
 
@moh.96

Exactly, that will be easy tho. Search occurrances, and if it only occurs once, remove. Awesome that I am making progress, this thread also motivates a lot.

My dream is to create a website where people can just upload their dsdt and they will get everything they need in a few seconds. Also, create a database of already done hotpatches. And maybe even config merger tools. Ugh, that makes me excited :p.
 
Thanks a ton @moh.96 , battery patch should work now. Still can not boot but I'm working on that.
How did you figure out the patches?

EDIT: Just checked your latest files. It boots but I have a lot of ECRD error messages as you have removed that part from the patch, right? Gonna try around a bit with your first renames and my old patch.

EDIT2: My old aml and your first set of patches work like charm, gonna work further on this, thanks a bunch!

@BlvckBytes
I checked a bunch of different chinese repos for similar Huawei Laptops. The 2019 Matebook uses the same structure,
so I found Lhaoziangs unfinished repo. He had different stages of DSDT patching which made it easy to follow what he did
in order to patch the battery in DSDT. I don't know why exactly the changes are necessary but not making these changes
ends with a lot of ECRD errors in verbose. In the end THIS Magicbook patch was pretty much exactly the one that I needed,
I still did this one on my own to learn how to do it though.
 

Attachments

  • WhatsApp Image 2020-09-21 at 15.48.44.jpeg
    WhatsApp Image 2020-09-21 at 15.48.44.jpeg
    148.2 KB · Views: 54
Last edited:
@Killuminati91

you are welcome !

So I recreated the patch with the method changes (to avoid ECRD errors in verbose mode)
Could you try them ?

I'm not sure if your SSDT-BAT will work 100% with my patches since you got some offset calculated wrong so I believe your battery will stuck at 100% or doesn't work

How did I figure out the patches, well you can read [Guide] Using Clover to "hotpatch" ACPI by Rehabman, when you rename a certain method (_INI for example) you can't just use 5F 49 4E 49 to 58 49 4E 49 cause this will rename every _INI to XINI, causing your system to not boot, you will have to specify the method you wanna rename by including few bytes before or after the method name so the patch will only rename this specific method
so in our case _INI in Device (ALSD) should be renamed to XINI
Find 14 43 06 5F 49 4E 49 00 70 45 43 52 44
Replace 14 43 06 58 49 4E 49 00 70 45 43 52 44
(check the screenshot in attachment)
(I hope that make sense since I'm bad at explaining something I don't 100% understand)
 

Attachments

  • Matebook X Pro 2020-Battery.zip
    7 KB · Views: 55
  • Screen Shot 2020-09-21 at 5.37.20 PM.png
    Screen Shot 2020-09-21 at 5.37.20 PM.png
    641.3 KB · Views: 49
Last edited:
@moh.96

Small update I'd like to share. I implemented unused field filtering and OperationRegion override code generation.

I only used this example DSDT to try it out, looks like it works. Again, would be happy if you could test it too. It sometimes may be hard to know which field in the generated code corresponds to what field in the original DSDT, since the non-colliding names get kind of "brute forced", but I hope you can still somewhat make it out.

This is what I used to test with:
Code:
OperationRegion (ECW1, EmbeddedControl, Zero, 0xFF)
Field (ECW1, ByteAcc, Lock, Preserve)
{
    Offset (0x3A),
    CMDR,   8, // <= 8
    Offset (0x40),
    UPDV,   16, // unused
    URDC,   16, // unused
    MAXP,   16, // unused
    SUSP,   16, // unused
    Offset (0x80),
    LDET,   1, // <= 8
    LDST,   1, // <= 8
    Offset (0x81),
    EPWS,   8, // <= 8
    EB0S,   8, // <= 8
    Offset (0x90),
    ATES,   16, // unused
    BTES,   16, // unused   
    CTES,   16, // unused
    DTES,   16, // unused
    LOLO,   32, // unused
    C1ES,   8, // <= 8
    B0PN,   16, // unused
    B0VL,   16, // used
    B0RC,   16, // used
    B0FC,   16, // used
    B0ST,   16, // used
    B0CC,   16, // used
    B0TM,   16, // unused
    B0C1,   16, // unused
    B0CV,   16, // unused
    B0DC,   16, // used
    B0DV,   16, // used
    B0SN,   16, // used
    B0MD,   16, // unused
    B0CT,   16, // used
    Offset (0xE7),
    EKVA,   16,
    EALS,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
    BALS,   1, // <= 8
    EULV,   16, // used
    ELLV,   16, // used
    CALS,   16, // used
    ELUX,   16 // used
}

And this is the output:
Code:
----------- AcpiHelper -----------
> An experimental tool by BlvckBytes
----------- AcpiHelper -----------

EcField(offset=0x9F, name=B0VL, size=16):
> EcField(offset=0x9F, name=00VL, size=8)
> EcField(offset=0xA0, name=10VL, size=8)
end of field

EcField(offset=0xA1, name=B0RC, size=16):
> EcField(offset=0xA1, name=00RC, size=8)
> EcField(offset=0xA2, name=10RC, size=8)
end of field

EcField(offset=0xA3, name=B0FC, size=16):
> EcField(offset=0xA3, name=00FC, size=8)
> EcField(offset=0xA4, name=10FC, size=8)
end of field

EcField(offset=0xA5, name=B0ST, size=16):
> EcField(offset=0xA5, name=00ST, size=8)
> EcField(offset=0xA6, name=10ST, size=8)
end of field

EcField(offset=0xA7, name=B0CC, size=16):
> EcField(offset=0xA7, name=B00C, size=8)
> EcField(offset=0xA8, name=B01C, size=8)
end of field

EcField(offset=0xAF, name=B0DC, size=16):
> EcField(offset=0xAF, name=B0D0, size=8)
> EcField(offset=0xB0, name=B0D1, size=8)
end of field

EcField(offset=0xB1, name=B0DV, size=16):
> EcField(offset=0xB1, name=00DV, size=8)
> EcField(offset=0xB2, name=10DV, size=8)
end of field

EcField(offset=0xB3, name=B0SN, size=16):
> EcField(offset=0xB3, name=00SN, size=8)
> EcField(offset=0xB4, name=10SN, size=8)
end of field

EcField(offset=0xB7, name=B0CT, size=16):
> EcField(offset=0xB7, name=00CT, size=8)
> EcField(offset=0xB8, name=10CT, size=8)
end of field

EcField(offset=0xE7, name=EKVA, size=16):
> EcField(offset=0xE7, name=0KVA, size=8)
> EcField(offset=0xE8, name=1KVA, size=8)
end of field

EcField(offset=0xEA, name=EULV, size=16):
> EcField(offset=0xEA, name=0ULV, size=8)
> EcField(offset=0xEB, name=1ULV, size=8)
end of field

EcField(offset=0xEC, name=ELLV, size=16):
> EcField(offset=0xEC, name=0LLV, size=8)
> EcField(offset=0xED, name=1LLV, size=8)
end of field

EcField(offset=0xEE, name=CALS, size=16):
> EcField(offset=0xEE, name=0ALS, size=8)
> EcField(offset=0xEF, name=1ALS, size=8)
end of field

EcField(offset=0xF0, name=ELUX, size=16):
> EcField(offset=0xF0, name=0LUX, size=8)
> EcField(offset=0xF1, name=1LUX, size=8)
end of field

Generating OperationRegion overrides...

OperationRegion (ECOR, EmbeddedControl, Zero, 0xFF)
Field (ECOR, ByteAcc, NoLock, Preserve)
{
Offset (0x9F),
00VL, 8,
10VL, 8,
00RC, 8,
10RC, 8,
00FC, 8,
10FC, 8,
00ST, 8,
10ST, 8,
B00C, 8,
B01C, 8,
Offset (0xAF),
B0D0, 8,
B0D1, 8,
00DV, 8,
10DV, 8,
00SN, 8,
10SN, 8,
Offset (0xB7),
00CT, 8,
10CT, 8,
Offset (0xE7),
0KVA, 8,
1KVA, 8,
Offset (0xEA),
0ULV, 8,
1ULV, 8,
0LLV, 8,
1LLV, 8,
0ALS, 8,
1ALS, 8,
0LUX, 8,
1LUX, 8,
}

Goodbye!

Looks promising, but definitely needs testing. Thank you for all your effort!
BTW, oops, there is a trailing semicolon after the last field in the code, :p. Will fix that on the next update.
 
@moh.96

Small update I'd like to share. I implemented unused field filtering and OperationRegion override code generation.

I only used this example DSDT to try it out, looks like it works. Again, would be happy if you could test it too. It sometimes may be hard to know which field in the generated code corresponds to what field in the original DSDT, since the non-colliding names get kind of "brute forced", but I hope you can still somewhat make it out.

This is what I used to test with:
Code:
OperationRegion (ECW1, EmbeddedControl, Zero, 0xFF)
Field (ECW1, ByteAcc, Lock, Preserve)
{
    Offset (0x3A),
    CMDR,   8, // <= 8
    Offset (0x40),
    UPDV,   16, // unused
    URDC,   16, // unused
    MAXP,   16, // unused
    SUSP,   16, // unused
    Offset (0x80),
    LDET,   1, // <= 8
    LDST,   1, // <= 8
    Offset (0x81),
    EPWS,   8, // <= 8
    EB0S,   8, // <= 8
    Offset (0x90),
    ATES,   16, // unused
    BTES,   16, // unused  
    CTES,   16, // unused
    DTES,   16, // unused
    LOLO,   32, // unused
    C1ES,   8, // <= 8
    B0PN,   16, // unused
    B0VL,   16, // used
    B0RC,   16, // used
    B0FC,   16, // used
    B0ST,   16, // used
    B0CC,   16, // used
    B0TM,   16, // unused
    B0C1,   16, // unused
    B0CV,   16, // unused
    B0DC,   16, // used
    B0DV,   16, // used
    B0SN,   16, // used
    B0MD,   16, // unused
    B0CT,   16, // used
    Offset (0xE7),
    EKVA,   16,
    EALS,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
        ,   1, // <= 8
    BALS,   1, // <= 8
    EULV,   16, // used
    ELLV,   16, // used
    CALS,   16, // used
    ELUX,   16 // used
}

And this is the output:
Code:
----------- AcpiHelper -----------
> An experimental tool by BlvckBytes
----------- AcpiHelper -----------

EcField(offset=0x9F, name=B0VL, size=16):
> EcField(offset=0x9F, name=00VL, size=8)
> EcField(offset=0xA0, name=10VL, size=8)
end of field

EcField(offset=0xA1, name=B0RC, size=16):
> EcField(offset=0xA1, name=00RC, size=8)
> EcField(offset=0xA2, name=10RC, size=8)
end of field

EcField(offset=0xA3, name=B0FC, size=16):
> EcField(offset=0xA3, name=00FC, size=8)
> EcField(offset=0xA4, name=10FC, size=8)
end of field

EcField(offset=0xA5, name=B0ST, size=16):
> EcField(offset=0xA5, name=00ST, size=8)
> EcField(offset=0xA6, name=10ST, size=8)
end of field

EcField(offset=0xA7, name=B0CC, size=16):
> EcField(offset=0xA7, name=B00C, size=8)
> EcField(offset=0xA8, name=B01C, size=8)
end of field

EcField(offset=0xAF, name=B0DC, size=16):
> EcField(offset=0xAF, name=B0D0, size=8)
> EcField(offset=0xB0, name=B0D1, size=8)
end of field

EcField(offset=0xB1, name=B0DV, size=16):
> EcField(offset=0xB1, name=00DV, size=8)
> EcField(offset=0xB2, name=10DV, size=8)
end of field

EcField(offset=0xB3, name=B0SN, size=16):
> EcField(offset=0xB3, name=00SN, size=8)
> EcField(offset=0xB4, name=10SN, size=8)
end of field

EcField(offset=0xB7, name=B0CT, size=16):
> EcField(offset=0xB7, name=00CT, size=8)
> EcField(offset=0xB8, name=10CT, size=8)
end of field

EcField(offset=0xE7, name=EKVA, size=16):
> EcField(offset=0xE7, name=0KVA, size=8)
> EcField(offset=0xE8, name=1KVA, size=8)
end of field

EcField(offset=0xEA, name=EULV, size=16):
> EcField(offset=0xEA, name=0ULV, size=8)
> EcField(offset=0xEB, name=1ULV, size=8)
end of field

EcField(offset=0xEC, name=ELLV, size=16):
> EcField(offset=0xEC, name=0LLV, size=8)
> EcField(offset=0xED, name=1LLV, size=8)
end of field

EcField(offset=0xEE, name=CALS, size=16):
> EcField(offset=0xEE, name=0ALS, size=8)
> EcField(offset=0xEF, name=1ALS, size=8)
end of field

EcField(offset=0xF0, name=ELUX, size=16):
> EcField(offset=0xF0, name=0LUX, size=8)
> EcField(offset=0xF1, name=1LUX, size=8)
end of field

Generating OperationRegion overrides...

OperationRegion (ECOR, EmbeddedControl, Zero, 0xFF)
Field (ECOR, ByteAcc, NoLock, Preserve)
{
Offset (0x9F),
00VL, 8,
10VL, 8,
00RC, 8,
10RC, 8,
00FC, 8,
10FC, 8,
00ST, 8,
10ST, 8,
B00C, 8,
B01C, 8,
Offset (0xAF),
B0D0, 8,
B0D1, 8,
00DV, 8,
10DV, 8,
00SN, 8,
10SN, 8,
Offset (0xB7),
00CT, 8,
10CT, 8,
Offset (0xE7),
0KVA, 8,
1KVA, 8,
Offset (0xEA),
0ULV, 8,
1ULV, 8,
0LLV, 8,
1LLV, 8,
0ALS, 8,
1ALS, 8,
0LUX, 8,
1LUX, 8,
}

Goodbye!

Looks promising, but definitely needs testing. Thank you for all your effort!
BTW, oops, there is a trailing semicolon after the last field in the code, :p. Will fix that on the next update.
That’s great ! That will definitely make things more easier, I’ll use it in my next patches and verify it manually, I think it can save some time and reduce errors, keep it up

I’m the one who should thank you for your effort
 
@BlvckBytes Hi,
few pages early @moh.96 helped me to create a working battery patch for my battery. It is working but there is a delay to acknoledge when the power plug is connected or disconnected. Now i don't mind the delay but i'm not able to configure the trackpad using VoodooI2C and i feel like i should solve this battery issue first because trackpad and battery are related in some way ... Would you be so nice to check my files and try to understand why i have this delay ?

Thanks !!

I don't think that the delay will mess with your trackpad, tbh. All the trackpad needs is a registered BAT0, AFAIK. What issue do you face with the trackpad?
 
@Killuminati91

you are welcome !

So I recreated the patch with the method changes (to avoid ECRD errors in verbose mode)
Could you try them ?

I'm not sure if your SSDT-BAT will work 100% with my patches since you got some offset calculated wrong so I believe your battery will stuck at 100% or doesn't work

How did I figure out the patches, well you can read [Guide] Using Clover to "hotpatch" ACPI by Rehabman, when you rename a certain method (_INI for example) you can't just use 5F 49 4E 49 to 58 49 4E 49 cause this will rename every _INI to XINI, causing your system to not boot, you will have to specify the method you wanna rename by including few bytes before or after the method name so the patch will only rename this specific method
so in our case _INI in Device (ALSD) should be renamed to XINI
Find 14 43 06 5F 49 4E 49 00 70 45 43 52 44
Replace 14 43 06 58 49 4E 49 00 70 45 43 52 44
(check the screenshot in attachment)
(I hope that make sense since I'm bad at explaining something I don't 100% understand)

Thanks again! Indeed my battery was stuck at 100%, now it is working great with your latest files. Just need the Darwin If-Statement and its pretty much perfect. On another note: How did you open that view in maciasl? No idea what the "-l" option is or how to run it?!

@tmbt: did you try geni2c? It has a function to automatically generate patches.
 
Last edited:
@BlvckBytes
Hello, so I was messing around with HP OMEN 15 DSDT (it was kinda tricky to patch and I couldn't test the patch) and I spot that this dsdt has multiple Fields called ERAM under EmbeddedControl, AcpiHelper was able to detect the first field only leaving six fields behind so I thought I'd share that with you.
 

Attachments

  • Screen Shot 2020-09-22 at 5.08.18 PM.png
    Screen Shot 2020-09-22 at 5.08.18 PM.png
    809 KB · Views: 57
  • Screen Shot 2020-09-22 at 5.08.25 PM.png
    Screen Shot 2020-09-22 at 5.08.25 PM.png
    790.1 KB · Views: 42
  • dsdt.aml
    316 KB · Views: 42
  • Screen Shot 2020-09-22 at 6.08.44 PM.png
    Screen Shot 2020-09-22 at 6.08.44 PM.png
    414.8 KB · Views: 50
@moh.96

Thank you a lot for sharing this! So to summarize... The first OperationRegion field block was parsed correctly, with the patch output matching? That's something xD.

And of course, I totally forgot about that messed up case, where they define new fields in the same region later on, instead of all at once. I will try to implement this and release it as soon as possible. Working on the method patching already, too :).

// EDIT:
Oh, and I see one unnecessary Offset-Instruction at the top, wonder how that happened.
Fixed that. I forgot to filter out the non 16 or 32 fields at the code generation process.
 
Last edited:
Status
Not open for further replies.
Back
Top