Skocz do zawartości

Rozpoznawanie stanu baterii


Rekomendowane odpowiedzi

Jak niektórzy pewnie zauważyli, w Mac OS X 10.7.x Apple dokonało pewnych wewnętrznych zmian, przez które sprawdzony kext AppleACPIBatteryManager przestał działać. Problem można było obejść, przywracając kexty ze Snow Leoparda, jednak nie wszystkich takie połowiczne rozwiązanie zadowala, zwłaszcza że rollback trzeba wykonywać po każdej aktualizacji systemu.

 

Problem tkwi w DSDT, dokładniej w sekcji urządzenia EC. Lion pobiera informacje o statusie baterii w porcjach ośmiobitowych, zaś w większości laptopów dane te są przechowywane w polach szesnastobitowych. Efekt? Przekreślona ikona baterii lub jej zupełny brak - nieważne, czy używamy AppleACPIBattery czy VoodooBattery. Na szczęście ktoś mądry stworzył kext kombatybilny z Lionem. Na nieszczęście trzeba modyfikować DSDT, żeby kext ten zadziałał, dokładniej trzeba podzielić większe pola na fragmenty po 8 bitów każdy, żeby nasze DSDT nie kłóciło się z nową filozofią Liona. Modyfikacja, choć czasochłonna, jest naprawdę prosta.

 

Na początku w DefinitionBlock (zaraz po pierwszej klamrze otwierającej) dodajemy metody, które wykorzystamy później:

	//Metody na użytek rozpoznawania statusu bateryjki
Method (B1B2, 2, NotSerialized) 
   { 
	Or (ShiftLeft(Arg1,0x08), Arg0, Local0) 
       Return (Local0) 
   } //pola 16-bitowe 

Method (B1B4, 4, NotSerialized)      
{ 
       Or (ShiftLeft(Arg1,0x08), Arg0, Local0) 
       Or (ShiftLeft(Arg2,0x10), Local0, Local0) 
       Or (ShiftLeft(Arg3,0x18), Local0, Local0) 
   	Return (Local0) 
} //pola 32-bitowe

Method (L1L4, 4, NotSerialized)//32*4=128
{ 
       Or (ShiftLeft(Arg1,0x20), Arg0, Local0) 
       Or (ShiftLeft(Arg2,0x40), Local0, Local0) 
       Or (ShiftLeft(Arg3,0x60), Local0, Local0) 
       Return (Local0) 
}//pola 128-bitowe

Następnie oszukujemy w DSDT sekcję urządzenia EC (Device (EC) - może się ona nazywać różnie, np. EC0, H_EC itp. Zwykle znajduje się wewnątrz sekcji LPC. Następnie przewijamy w dół aż natrafimy na coś, co wygląda m/w tak:

                    OperationRegion (ECR, EmbeddedControl, 0x00, 0xFF) 
   Field (ECR, ByteAcc, Lock, Preserve) 
   { 
           Offset (0x18), 
       SPTR,   8, 
       SSTS,   8, 
       SADR,   8, 
       ...

Przy czym nazwy pól ani nazwa sekcji wcale nie muszą się pokrywać z powyższym przykładem!

Teraz należy każde pole 16-bitowe zmienić na dwa pola 8-bitowe, każde 32-bitowe na cztery 8-bitowe, a 128-bitowe na 16(!) 8-bitowych. Poniżej przykłady dokonywanych zmian.

 

Pole 16-bitowe

	SBTI,   16,

zastępujemy

	BTI0,    8,
BTI1, 	8,

 

Pole 32-bitowe

	B1AF,   32,

zastępujemy

	BAF0,	8,
   BAF1,	8,
   BAF2,	8,
   BAF3,	8,

 

Pole 128-bitowe

	SBMN,    128,

	BMN0,   8, 
   BMN1,   8, 
   BMN2,   8, 
   BMN3,   8, 
   BMN4,   8, 
   BMN5,   8, 
   BMN6,   8, 
   BMN7,   8, 
   BMN8,   8, 
   BMN9,   8,
   BMNA,   8, 
   BMNB,   8, 
   BMNC,   8, 
   BMND,   8, 
   BMNE,   8, 
BMNF,   8,

 

Nazewnictwo

Ponieważ specyfikacja ACPI nie pozwala na nazwy pól dłuższe niż cztery znaki, rozbijając dane pole, np. ABCD musimy zrobić miejsce dla indeksu i skasować którąś literę. W przykładzie dla 16 i 128 bitów zdecydowałem się na usunięcie pierwszej, co dla pola ABCD dałoby nam BCD + indeks. Indeks to po prostu cyfra rozróżniająca poszczególne fragmenty danego pola. Dla 16 bitów mamy BCD0 oraz BCD1 (komputery liczą od zera).

 

Dla pola 128-bitowego braknie nam "normalnych" cyfr do indeksowania, więc musimy wykorzystać również litery (lub jak kto woli – cyfry szesnastkowe). Gdybyśmy pole ABCD rozbili na 16 składowych, moglibyśmy nadać im następujące nazwy:

BCD0, BCD1, BCD2, BCD3, BCD3, BCD4, BCD5, BCD6, BCD7, BCD8, BCD9, BCDA, BCDB, BCDC, BCDD, BCDE, BCDF

Wyżej przytoczony przykład dla pola 32-bitowego jest nieco inny, ponieważ drugi znak w jego nazwie, to cyfra. Gdybyśmy po prostu usunęli pierwszy znak, zostałaby ona umieszczona na pierwszym miejscu, a taka nazwa pola mogłaby się nie spodobać kompilatorowi, dlatego też w tym przykładzie usunąłem właśnie ową cyfrę. Dla hipotetycznego pola 32-bitowego o nazwie A1BC podział mógłby wyglądać tak:

ABC0, ABC1, ABC2, ABC3

Co począć w sytuacji, gdy gdzieś dalej w kodzie pojawi się pole o niemalże identycznej nazwie, różniącej się tylko cyfrą, np. A2BC? Można po prostu "liczyć dalej", a więc przyjąć następujący podział:

ABC4, ABC5, ABC6, ABC7

Oczywiście można stosować właściwie dowolne nazewnictwo, jednakże pola muszą być rozróżnialne, to znaczy nazwy nie mogą się powtarzać - sugeruję każdorazowe sprawdzanie przed dokonaniem podziału - warto jest jednak przyjąć pewien w miarę konsekwentny schemat nadawania nazw, który ułatwi niepogubienie się ;)

 

 

Teraz trochę trudniejsza część: trzeba zmienić wszystkie odwołania do pól, bo inaczej nie dość, że bateria nie zadziała, to jeszcze DSDT się nie skompiluje :D Do tego posłużą nam dodane wcześniej metody.

 

Odwołania do pól 16-bitowych, np:

Store (SBTI, Local0)

zastępujemy

Store (B1B2(BTI0, BTI1), Local0)

 

Odwołania do pól 32-bitowych, np:

Store (B1AF, Local0)

zastępujemy

Store (B1B4(BAF0, BAF1, BAF2, BAF3), Local0)

 

Odwołania do pól 128-bitowych, np:

Store (SBMN, Local0)

zastępujemy

Store (L1L4 (B1B4 (BMN0, BMN1, BMN2, BMN3),
B1B4 (BMN4, BMN5, BMN6, BMN7),
B1B4 (BMN8, BMN9, BMNA, BMNB),
B1B4 (BMNC, BMND, BMNE, BMNF)), Local0)

 

Na koniec kompilujemy DSDT i umieszczamy je w stosownym miejscu (zwykle /Extra/) oraz instalujemy kext z załącznika pochodzący z forum pcbeta (najwygodniej za pomocą programu KextWizard). Jeszcze raz przypominam, że stary AppleACPIBatteryManager nie będzie działać, powyższa modyfikacja przeznaczona jest wyłącznie dla nowej wersji!

 

Korzystałem z tego tematu:

http://www.insanelymac.com/forum/index.php?showtopic=272459&st=0

Podziękowania:

oswaldini – za podlinkowanie w/w tematu na naszym forum, dokładniej tutaj

man_of_the_oak – za znalezienie AppleACPIBatteryManager, na którym nie występują opóźnienia po odłączeniu zasilacza

MietasSR - za przetestowanie DSDT zmodyfikowanego wg w/w metody na Mountain Lionie z pozytywnym skutkiem :D

AppleACPIBatteryManager_10.7.3_no_delay.kext.zip

Odnośnik do komentarza
Udostępnij na innych stronach

  • Odpowiedzi 61
  • Dodano
  • Ostatniej odpowiedzi

Top użytkownicy w tym temacie

Top użytkownicy w tym temacie

Opublikowane grafiki

Należy w ten sposób zamienić wszystkie sekcje z rejestrami, czy tylko jakąś konkretną? Na przykład ja mam coś takiego (zaraz za Device (EC)):

                    OperationRegion (ECOR, EmbeddedControl, 0x00, 0x0100) 
                   Field (ECOR, ByteAcc, NoLock, Preserve) 
                   { 
                       HDBM,   1, 
                           ,   1, 
                           ,   1, 
                       ...
                               Offset (0xB0), 
                       HDEN,   32, 
                       HDEP,   32, 
                       HDEM,   8, 
                       HDES,   8, 
                       ...
                               Offset (0xED), 
                           ,   4, 
                       HDDD,   1
                   }

 

Kilkadziesiąt linijek dalej mam np. takie sekcje:

                    Method (_Q25, 0, NotSerialized) 
                   { 
                       If (And (^BAT1.B1ST, ^BAT1.XB1S)) 
                       { 
                           CLPM () 
                           Notify (BAT1, 0x80) 
                       } 
                   } 

                   Field (ECOR, ByteAcc, NoLock, Preserve) 
                   { 
                               Offset (0xA0), 
                       SBRC,   16, 
                       ...
                       SBBS,   16
                   } 

                   Field (ECOR, ByteAcc, NoLock, Preserve) 
                   { 
                               Offset (0xA0), 
                           ,   15, 
                       SBCM,   1, 
                       SBMD,   16, 
                       SBCC,   16
                   } 

                   Field (ECOR, ByteAcc, NoLock, Preserve) 
                   { 
                               Offset (0xA0), 
                       SBDC,   16, 
                       ...
                       SBSN,   16
                   } 

                   Field (ECOR, ByteAcc, NoLock, Preserve) 
                   { 
                               Offset (0xA0), 
                       SBCH,   32
                   } 

                   Field (ECOR, ByteAcc, NoLock, Preserve) 
                   { 
                               Offset (0xA0), 
                       SBMN,   128
                   } 

                   Field (ECOR, ByteAcc, NoLock, Preserve) 
                   { 
                               Offset (0xA0), 
                       SBDN,   128
                   }

Odnośnik do komentarza
Udostępnij na innych stronach

Masakra, przecież to bite 2-3 godziny roboty non stop, ale łatwe do zrobienia - ciekawe czy działa :D
Trochę przejaskrawiasz, ale istotnie - sporo roboty. Tyle dobrego, że nie do wszystkich pól są odwołania ;)
Należy w ten sposób zamienić wszystkie sekcje z rejestrami, czy tylko jakąś konkretną? Na przykład ja mam coś takiego (zaraz za Device (EC)):
Zmieniasz wszystkie sekcje z rejestrami wewnątrz EC. Jak testowałem moda u siebie, niechcący jedną pominąłem. Zgadnij, co się stało... Śliczne kp!
Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 tygodnie później...

Postanowiłem się za to zabrać aby już nie robić rollbacka szczególnie, że DP2 z kextem z 10.6.7 jakoś długo się uruchamia a z oryginalnym o wiele lepiej. Mam małe pytanie odnośnie tej modyfikacji :

 

...
SPTR,   8, 
                       SSTS,   8, 
                       SADR,   8, 
                       SCMD,   8, 
                       SBFR,   256, 
                       SCNT,   8, 
...

 

Jak zmodyfikować SBFR ? Jak widać ma wartość 256, mam z tego zrobić 32 sekcje po 8 ? Czy może modyfikacja ogranicza się tylko do 16,32,64 i 128 ?

Odnośnik do komentarza
Udostępnij na innych stronach

Rany julek ludzie czytać.

 

Ehh.. Rany julek :) czytam i to dokładnie. W sekcji którą dodaje się zaraz po DefinitionBlock nie ma kodu dla wartości 256bit. Dlatego zadałem pytanie o konieczność dzielenia tej wartości na 8 tym samym proponując rozwiązanie które Ty potwierdziłeś więc : 1. Czytam. 2. Pytam aby się upewnić.

 

Poległem na 2 liniach - nie mam pojęcia jak je zmodyfikować :

 

If (LNotEqual (\_SB.PCI0.LPCB.H_EC.B1DF, \_SB.BFCC))

 

Nie ma już B1DF bo jak wiadomo wartość została rozbita na BDF0 i BDF1

 

Store (\_SB.PCI0.LPCB.H_EC.B1DF, \_SB.BFCC)

 

Ta sama sytuacja...

Odnośnik do komentarza
Udostępnij na innych stronach

W sekcji którą dodaje się zaraz po DefinitionBlock nie ma kodu dla wartości 256bit.
To dlatego, że na 99% do pola 256-bitowego, nawet jeśli takowe wystąpi w DSDT, nie ma nigdzie odwołań. Sprawdź, czy ta nazwa jest gdzieś używana, ale obstawiam, że nie jest.
Poległem na 2 liniach - nie mam pojęcia jak je zmodyfikować :
Nie wiem, w czym masz problem... zastąp odwołanie do pola wywołaniem odpowiedniej metody i po krzyku.
Odnośnik do komentarza
Udostępnij na innych stronach

1. Nie rozbijałem tej wartości 256bitowej - zostawiłem jak była. (brak odwołań)

2.

If (LNotEqual (\_SB.PCI0.LPCB.H_EC.B1DF, \_SB.BFCC))

=

If (LNotEqual (B1B2 (\_SB.PCI0.LPCB.H_EC.BDF0, \_SB.PCI0.LPCB.H_EC.BDF1), \_SB.BFCC))

3.

Store (\_SB.PCI0.LPCB.H_EC.B1DF, \_SB.BFCC)

=

Store (B1B2 (\_SB.PCI0.LPCB.H_EC.BDF0, \_SB.PCI0.LPCB.H_EC.BDF1), \_SB.BFCC)

4. Bateria działa jak marzenie :) Lion oraz M. Lion DP2 - Dzięki za pomoc i poradnik !!

 

[ Komentarz dodany przez: 314TeR: 2012-03-19, 10:52 ]

Tak będzie czytelniej, a przy okazji będzie dobry przykład jak modyfikować kod.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 miesiące temu...

Spróbuj dodaj jeszcze jedną metodę, np:

    Method (D1D2, 2, NotSerialized)//128*2=256
   { 
       Or (ShiftLeft(Arg1,0x80), Arg0, Local0) 
       Return (Local0) 
   }//pola 128-bitowe	

Jako argumenty musisz podać wynik L1L4, więc całe wywołanie będzie dość długie. Niemniej spróbować musisz, bo ja nie posiadam dostępu do OS X i sam tego sprawdzić nie mogę ;)

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 miesiące temu...

No to wszystko jasne :) Sobie wymyślę jakiś pattern i wyedytuję co trzeba :)

 

EDIT

Pierwszy KP za mną - na bank coś poknociłem. Niby plik się skompilował (kompilowałem przez Chameleon Wizzard) ale może coś zapomniałem :)

Sprawdziłem sobie, że XX** , XY** i XZ** nie są nigdzie w pliku używane, więc teraz polecę sobie XXA0,XXA1, XXB0, XXB1 itp :) W swoim DSDT mam tylko 16bit

 

 OperationRegion (ECOR, EmbeddedControl, Zero, 0xFF) 
           Field (ECOR, ByteAcc, Lock, Preserve) 
           { 
               Offset (0x04), 
               CMD1,   8, 
               CDT1,   8, 
               CDT2,   8, 
               CDT3,   8, 
               Offset (0x80), 
               EPWS,   8, 
               EB0S,   8, 
               EB1S,   8, 
               EB0R,   8, 
               EB1R,   8, 
               EPWF,   8, 
               Offset (0x87), 
               EB0T,   8, 
               EB1T,   8, 
               Offset (0x8A), 
               HKEN,   1, 
               Offset (0x93), 
               TAH0,   16, 
               TAH1,   16, 
               TSTP,   8, 
               Offset (0x9C), 
               CDT4,   8, 
               CDT5,   8, 
               Offset (0xA0), 
               ECPU,   8, 
               ECRT,   8, 
               EPSV,   8, 
               EACT,   8, 
               TH1R,   8, 
               TH1L,   8, 
               TH0R,   8, 
               TH0L,   8, 
               Offset (0xB0), 
               B0PN,   16, 
               B0VL,   16, 
               B0RC,   16, 
               B0FC,   16, 
               B0MD,   16, 
               B0ST,   16, 
               B0CC,   16, 
               B0TM,   16, 
               B0C1,   16, 
               B0C2,   16, 
               B0C3,   16, 
               B0C4,   16, 
               Offset (0xD0), 
               B1PN,   16, 
               B1VL,   16, 
               B1RC,   16, 
               B1FC,   16, 
               B1MD,   16, 
               B1ST,   16, 
               B1CC,   16, 
               B1TM,   16, 
               B1C1,   16, 
               B1C2,   16, 
               B1C3,   16, 
               B1C4,   16, 
               Offset (0xF0), 
               B0DC,   16, 
               B0DV,   16, 
               B0SN,   16, 
               Offset (0xF8), 
               B1DC,   16, 
               B1DV,   16, 
               B1SN,   16
           }

Mam rozumieć, że tylko te mam pozamieniać na 2 pary 8 bitowe a potem w każdym miejscu, gdzie te zmienne występują muszę je zastąpić funkcją?

 

EDIT2

Mam problem ... wcześniej jest napisane, że muszę wszystkie wartości w sekcji EC "zdegradować" do 8 bitowych.

Zatem zaraz pod sekcją przytoczoną poniżej mam to:

 

Name (SMBF, Zero) 
           OperationRegion (SMBX, EmbeddedControl, 0x18, 0x28) 
           Field (SMBX, ByteAcc, NoLock, Preserve) 
           { 
               PRTC,   8, 
               SSTS,   5, 
                   ,   1, 
               ALFG,   1, 
               CDFG,   1, 
               ADDR,   8, 
               CMDB,   8, 
               BDAT,   256, 
               BCNT,   8, 
                   ,   1, 
               ALAD,   7, 
               ALD0,   8, 
               ALD1,   8
           } 

Jest tu wartość 256bit ... niby jak nie ma odwołań w pliku to nie muszę nic zmieniać, ale ... u mnie ta zmienna występuje

 

Method (ASBR, 2, NotSerialized) 
       { 
           If (LLess (Arg1, 0x30)) 
           { 
               Return (0x02) 
           } 

           OperationRegion (\F112, SystemMemory, Arg0, Arg1) 
           Field (F112, DWordAcc, NoLock, Preserve) 
           { 
               Offset (0x08), 
               BATN,   8, 
               BATA,   8, 
               REGS,   8, 
               BDAT,   16, 
               BLEN,   8, 

 

If (LEqual (BATA, Zero)) 
           { 
               Store (^^PCI0.SBRG.EC0.SMBR (^^PCI0.SBRG.EC0.RDWD, ^^PCI0.SBRG.EC0.BADR, REGS), Local0) 
               Store (DerefOf (Index (Local0, 0x02)), BDAT) 

 

If (LEqual (BATA, One)) 
           { 
               Store (^^PCI0.SBRG.EC0.SMBW (^^PCI0.SBRG.EC0.WRWD, ^^PCI0.SBRG.EC0.BADR, REGS, 0x02, BDAT), Local0) 

 

Field (F113, DWordAcc, NoLock, Preserve) 
           { 
               Offset (0x08), 
               BATN,   8, 
               BATA,   8, 
               REGS,   8, 
               BDAT,   8
           } 

 

If (LEqual (BATA, Zero)) 
           { 
               Store (^^PCI0.SBRG.EC0.RBEP (REGS), Local2) 
               And (Local2, 0xFF, Local3) 
               Store (Local3, BDAT) 

 

If (LEqual (BATA, One)) 
           { 
               Store (^^PCI0.SBRG.EC0.WBEP (REGS, BDAT), Local2) 

 

Store (Zero, BDAT) 

 

 Store (BDAT, Index (Local0, 0x02))

 

I klika innych ... skołowany jestem ... :/

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 miesiąc temu...

Hmmm... zrobiłem tak jak opisałeś i jedyne co, to działa wyświetlanie baterii na pasku, ale samo rozpoznawanie baterii nie

http://cl.ly/image/1l2Z0x0m1V2h

 

[ Dodano: 2012-12-04, 06:18 ]

O, po którymś reboocie się pojawiła ^^

Także potwierdzam działanie w/w metody na 10.8.2 ;)

 

[ Dodano: 2012-12-04, 12:46 ]

No dobra, koniec końców: raz działa, raz nie działa, w zależności od kaprysu systemu... any ideas?

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 tygodnie później...

Nie wiem, czy to działanie na okrętkę, ale na czystym Mountain Lion zainstalowałem to:

http://www.osx86.net/downloads.php?do=file&id=3169

 

O dziwo pojawiła się ikona baterii ... wyczuwa podłączenie kabla, odłączenie kabla oraz poziom naładowania w %

 

W DSDT nie było fixa, bo nie znalazłem nigdzie odpowiedzi na 256 bitową wartość

Odnośnik do komentarza
Udostępnij na innych stronach

Tam jest napisane, że trzeba rozbić na 32 sekcje 8bit - to jest proste ...

Ale niżej w postach osoba pytająca pisze, że w metodach dodanych zaraz po sekcji EC nie ma dla 256bit - jest dla 16, 32 i 128. Dalej dostaje info, że do 256bit nie trzeba, bo najczęściej nie ma do nich odwołań a ta osoba to potwierdza więc nie musiała nic więcej robić.

U mnie jest inaczej, gdyż do pola 256bit mam odwołanie i muszę te wartości połączyć ...

Pisałem zresztą o tym kilka postów wyżej.

Po prostu jak wpiszę w wyszukiwarkę BDAT to jest tego kilka w pliku ...

 

Dziś jeszcze korzystając z wolnego czasu i tego, że mam dwa dyski (jeden w kieszeni) i na obu działa ML to się pobawię. Jak będzie KP to bootuje z drugiego dysku i przywracam.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 miesiąc temu...

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie
 Udostępnij


×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Korzystanie z tej witryny, wymaga zakceptowanie naszych warunków Warunki użytkowania.