[TOC]
****
# 【指南】使用Clover來熱修補ACPI
> 英文原文:[Using Clover to "hotpatch" ACPI](https://www.tonymacx86.com/threads/guide-using-clover-to-hotpatch-acpi.200137/)
> 本文出處:http://bbs.pcbeta.com/viewthread-1745275-1-1.html
# 前言
hotpatch在RehabMan大神維護的 elitebook 系列機型方面體現得很完美,我是翻elitebook機型的hotpatch后發現的,所以我決定來翻譯這個教程,水平有限(大部分東西看不懂,靠有道翻譯對付的,湊合吧),錯漏之處請各位指出,謝謝。
先貼上國內的幾個帖子,都寫得很好,方便大家理解,版權歸原作者。
1.華碩 VM510LEFI分享9CC3筆記本主板芯片通用 :
https://blog.neroxps.cn/blog/macOS/9CC3-EFI-README.html
2.hotpatch學習筆記:
http://bbs.pcbeta.com/forum.php?mod=viewthread&tid=1733965
3.暗影精靈2代Pro安裝macOS Sierra 10.12.5全記錄(hotpatch):
http://bbs.pcbeta.com/viewthread-1742550-1-1.html
目前我認為第三篇帖子和RehabMan的hotpatch方法是比較接近的,不過只是個人主觀意見。
最好之前先去看看**SSDT/DSDT**的部分。
# 介紹
在接近MAC配置的非MAC硬件上修補`ACPI`使之啟用(接近)MAC的完整功能。
在這里有一份完整的指導:[guide-patching-laptop-dsdt-ssdts](http://www.tonymacx86.com/threads/guide-patching-laptop-dsdt-ssdts.152573/),這里的指導使用所謂的“ **靜態修補(static patching)** ”,為了注入ACPI補丁文件,我們提取本機 ACPI ,將他們拆開,進行修改,然后重新編譯放到`\EFI\Clover\ACPI\patched`目錄下,這是使用 clover 注入修補 ACPI,而不是修改硬件 ACPI。使用本指南中詳細介紹的技術,可以直接對 BIOS 提供的ACPI 二進制文件進行更改,而無需執行提取,反匯編和重新編譯步驟。
在嘗試進行 hotpatch 之前,您應該對 靜態 ACPI 補丁有深入的了解。 您還應該了解 ACPI 規范,二進制修補程序,編程和 ACPI 概念。
# Clover的修補機制
Clover提供了一些方法來完成 ACPI hotpatch:
- `config.plist/ACPI/DSDT/Fixes`(在 config.plist 文件 ACPI/DSDT/ 下添加修復)
- `config.plist/ACPI/DSDT/Patches`(在 config.plist 文件ACPI/DSDT/ 下添加補丁)
- `ability to inject additional SSDTs`(在ssdt 文件下注入額外的 SSDTs)
(這一部分體現得最好的是在elitebook機型下面,elitebook機型的 hotpatch詳見:https://github.com/RehabMan/HP-ProBook-4x30s-DSDT-Patch)
DSDT/Fixes 提供了固定功能的ACPI修補。 每個 `Fixes` 都可以執行一種特定類型的修補程序,可以代替MaciASL和靜態修補程序執行的典型修補程序。 例如,可以使用“ FixHPET”,“ FixIPIC”,“ FixRTC”和“ FixTMR”來完成“ IRQ Fix”。 作為另一個示例,可以使用“ FixWAK”完成 `Fix _WAK Arg0 v2`。 您可以閱讀 Clover Wiki ,以獲取有關每個補丁的更多信息。 大多數時候,基本功能不需要很多DSDT "Fixes”。 DSDT "Fixes" 對于實現難以或無法通過 `ACPI/DSDT/Patches` 或 additional SSDTs(其他SSDTS)實現的補丁程序很有用。
Clover允許在 `config.plst/DSDT/Patches`下搜索和替換二進制,Clove 加載本地ACPI文件時,會應用`config.plst/DSDT/Patches`下的 Patches 二進制文件進行搜索/替換,然后注入修補 ACPI。你需要了解AM L的二進制格式和常用的 ACPI規范。
ACPI 命名空間是通過在加載時合并 DSDT 和SSDTs 來構建的。 通過將其他 SSDTs 放入 `ACPI/patched`,可以從本質上向此 ACPI集 添加代碼。 由于許多OS X 補丁程序都涉及通過 `_DSM`方法向 `ioreg`添加屬性,因此只需添加包含附加 `_DSM`方法的 SSDT 通常就足夠了,而不是修補本機 ACPI 文件。 您已經熟悉的一個完美示例是Pike的 `ssdtPRgen.sh` 生成的 SSDT.aml。
在某些情況下,必須使用多種機制來實現一個目標。 例如,您可以使用二進制補丁程序禁用或重命名本機 ACPI 集中的組件,然后將其替換為附加的 SSDTs。
# 重命名ACPI對象(Renaming ACPI objects)
因為OS X 可以依賴于mac使用的特定的ACPI對象名稱,一個常見的補丁是在原始ACPI集合中重命名一個對象。例如,大多數PC筆記本電腦使用`GFX0`來表示集成的 Intel GPU 對象(Intel HD Graphics)。在OS X中,除非該設備被命名為`IGPU`,否則不會啟用英特爾圖形的電源管理。使用靜態補丁,我們應用“Rename IGPU to GFX0”來重命名這個對象。補丁必須應用到DSDT和所有引用它的SSDTs。
有了 hotpatch,我們可以在 `ACPI/DSDT/Patches`中使用簡單的 Clover 補丁將`GFX0`重命名為`IGPU`。這些補丁適用于DSDT 和所有本地 SSDTs(`DSDT/Patches`不適用于通過`ACPI/patched`添加的SSDTs)。重新命名的補丁將是
```
Comment: Rename GFX0 to IGPU
Find: <4746 5830>
Replace: <4947 5055>
```
查找和替換的十六進制值分別是 GFX0 和 IGPU 的 ASCII碼。
注意:
```
u430:~ RehabMan$ echo -n GFX0|xxd
0000000: 4746 5830 GFX0
u430:~ RehabMan$ echo -n IGPU|xxd
0000000: 4947 5055 IGPU
```
常見的重命名有很多,大多數在我的 `Clover/hoptpatch` 項目的 config.plist 中:
https://github.com/RehabMan/OS-X-Clover-Laptop-Config/tree/master/hotpatch
事實上,同一項目的一部分的hotpatch SSDTs依賴于那些被實現的重命名。
常見的重命名:
```
GFX0 -> IGPU
SAT0 -> SATA
EHC1 -> EH01
EHC2 -> EH02
XHCI -> XHC
HECI -> IMEI
MEI -> IMEI
LPC -> LPCB
HDAS -> HDEF
AZAL -> HDEF
```
注意:所有 ACPI 標識符都是4個字符。短名稱是用下劃線填充的。例如,XHC 在 A ML二進制中表示為 `XHC_`,EC 為`EC__`,EC0 為 `EC_`,MEI 為 `MEI_`,等等。
# 刪除方法(Removing methods)
使用 Clover 二進制補丁來刪除 ACPI對象(方法、名稱、設備等)非常困難。通常,我們必須添加 `_DSM` 方法來注入屬性來描述各種硬件的屬性。但是,添加的 `_DSM` 方法可能會與現有的 `_DSM` 方法相沖突,這些方法可能已經存在于本地 ACPI 文件中。進行靜態修補時,將使用 `Remove _DSM methods`。
由于很難刪除這些方法,但是我們不希望原始方法與添加的新 `_DSM` 方法相沖突,修復方法是將原始方法重命名為其他方法。
所以…同樣,我們使用一個簡單的重命名補丁:
~~~
Comment: Rename _DSM to XDSM
Find: <5f44534d>
Replace: <5844534d>
~~~
有時,您可以重命名一個對象,以有效地禁用它,這樣它就不會產生問題。例如,我的Intel DH67GD DSDT定義了一個`APSS`對象。如果這個對象留在DSDT中,它會干擾電源管理(引起恐慌)。我使用`APSS -> APXX`的重命名。因為AppleIntelCPUPowerManagement 正在尋找 APSS,它改名為`APXX`不會引起問題。
# 重定向和替換(Redirect and Replace)
在某些情況下,我們希望替換代碼來改變行為。為此,我們可以重命名對象,并在SSDT中提供一個可替換的實現。
一個常見的解決方法是欺騙DSDT和SSDTs中的 ACPI 代碼,這樣它的行為就表現得像特定的 windows的 ACPI 代碼。當靜態修補時,我們可以使用“OS Check Fix (Windows 8)”。應用時,它會更改代碼從:
~~~
If (_OSI("Windows 2012"))
~~~
變為:
~~~
If (LOr(_OSI("Darwin"),_OSI("Windows 2012"))
~~~
由于OS X中的 `_OSI` 實現只響應 “Darwin”,所以代碼被更改,因此這個特定的`_OSI`檢查也可以滿足“Darwin”。
hotpatching 采取相反的方法,我們不使用 `_OSI`更改代碼,而是更改代碼,因此它調用了一個不同的方法來模擬Windows ACPI主機上的`_OSI`實現。
這項技術依賴于兩種技術……一個補丁來改變所有從`_OSI`到`XOSI`的調用…以及`XOSI`的實現,它模仿Windows對一個特定Windows版本的操作。
首先,更改代碼來 調用`XOSI` 而不是`_OSI`:
~~~
Comment: Change _OSI to XOSI
Find: <5f4f 5349>
Replace: <584f 5349>
~~~
上面的十六進制編碼不應該是神秘的(它們分別是`_OSI`和`XOSI`的ASCII碼)。以上所述的代碼,經過Clover的修補后,將會:
~~~
If (XOSI("Windows 2012"))
~~~
現在我們需要一個實現`XOSI`的`SSDT`。您將在 rep 中找到這樣的實現(`SSDT-XOSI.dsl`)。注意,如果沒有實現`XOSI`方法的`SSDT`,對`XOSI`的調用會導致**ACPI中止**(ACPI abort導致ACPI方法的執行立即被錯誤終止)。如果沒有`XOSI`方法,不要使用`_OSI -> XOSI`補丁。
# 重命名和替換(Rename and Replace)
第二種模式,類似于“重定向和替換”是“重命名和替換”。在這種情況下,我們將更改方法定義,以使該方法的名稱與原始名稱有所不同,而不是更改所有調用位置,而是將原始方法名稱保留在調用位置。 這允許替換作為調用目標的方法。
例如,USB設備的“瞬間喚醒”非常常見。作為一種變通方案,在USB上喚醒可以被禁用。大多數筆記本電腦都沒有BIOS選 項,所以控制這個特性的 `_PRW` 方法被修補了。
例如,原始的`_SB.PCI0.EHC1._PRW`方法可能被讀取:
```
Method (_PRW, 0, NotSerialized) // _PRW: Power Resources for Wake
{
Return (GPRW (0x6D, 0x03))
}
```
為了修補它,使USB設備在 EHCI#1 不會造成喚醒,它將被改變:
```
Method (_PRW, 0, NotSerialized) // _PRW: Power Resources for Wake
{
Return (GPRW (0x6D, 0))
}
```
通常,有幾個這樣的調用站點需要更改`GPRW`(同時,請記住,并不是所有ACPI集都使用特定的名稱`GPRW`)。相反,我們可以改為修補`GPRW`的方法定義,而不是像上面那樣修補所有的調用站點:
原始代碼:
```
Method (GPRW, 2, NotSerialized)
{
...
}
```
如果我們改成:
```
Method (XPRW, 2, NotSerialized)
{
...
}
```
由于您不希望更改任何調用站點,因此必須構造該補丁,以便它只影響方法本身,而不影響調用站點。根據 ACPI 規范,方法定義從字節碼 14 開始,然后是方法大小、方法名稱、參數計數/標志。您可以在`iasl`中使用“`- l`”選項來生成ACPI 文件的混合列表。例如,聯想u430 `GPRW` 混合列表:
```
4323: Method (GPRW, 2, NotSerialized)
00003F95: 14 45 08 47 50 52 57 02 ".E.GPRW."
4324: {
4325: Store (Arg0, Index (PRWP, Zero))
00003F9D: 70 68 .................. "ph"
00003F9F: 88 50 52 57 50 00 00 ... ".PRWP.."
```
我們可以使用方法**頭字節**來代替查找:
```
Find: <14 45 08 47 50 52 57 02>
Replace: <14 45 08 58 50 52 57 02>
```
但是,如果不同版本的BIOS或相似但不完全相同的型號之間的方法略有不同,會發生什么? 在這種情況下,由于方法長度的變化,14之后的字節將發生變化。
我的想法是,開始的方法體不太可能與方法的總長度不同,因此有助于將方法主體中的一些額外字節添加到查找/替換規范中:
~~~
Find: <47 50 52 57 02 70 68>
Replace: <58 50 52 57 02 70 68>
~~~
您使用的后續字節數取決于進行查找/替換所需要的字節數僅影響方法定義。 您可以通過在Hex Fiend等十六進制編輯器中查看本機AML二進制文件進行驗證(它是一個不錯的十六進制編輯器,也是開源的)。
注意:盡管您只能搜索方法名稱+ `arg count/ flags`,但相同的模式可能會找到您不想更改的方法的調用站點。 在u430 并非如此的情況下,因此我僅用方法名+標志即可查找/替換。
```
Find: <47505257 02>
Replace: <58505257 02>
```
在ProBook UPRW 的情況下,需要使用方法主體部分的后續字節:
```
Find: <55505257 0a7012>
Replace: <58505257 0a7012>
```
現在,任何調用`GPRW`(或ProBook示例中的UPRW)的代碼都不會調用 `XPRW`中的實現,因為它的名稱不匹配。原始的XPRW現在是不可到達的代碼。這意味著`GPRW` 的實現可以根據我們的目的而改變:
```
Method(GPRW, 2)
{
If (0x6d == Arg0) { Return(Package() { 0x6d, 0, }) }
External(\XPRW, MethodObj)
Return(XPRW(Arg0, Arg1))
}
```
解釋該代碼:對于任何調用`GPRW`,將第一個參數設置為`0x6d` (我們正在嘗試禁用的`GPE`),而不是返回原來的`GPRW`,我們返回的包為 `0x6d` 和 `0`(禁用喚醒),而不是返回原始 `GPRW` 的內容 。 對于其他 `GPE` 值,該代碼僅調用原來的 `GPRW` 方法(現在稱為 `XPRW` )。
另一個簡單的例子是 修補 EC查詢方法來修復亮度鍵。只需將所涉及的 `_Qxx`方法簡單地重命名為 `XQxx`,并使用原始名稱重新定義方法即可。
例如,在HP Envy Haswell 的 repo 中:
```
// _Q13 called on brightness/mirror display key
Method (_Q13, 0, Serialized) // _Qxx: EC Query
{
External(\HKNO, FieldUnitObj)
Store(HKNO, Local0)
If (LEqual(Local0,7))
{
// Brightness Down
Notify(\_SB.PCI0.LPCB.PS2K, 0x0405)
}
If (LEqual(Local0,8))
{
// Brightness Up
Notify(\_SB.PCI0.LPCB.PS2K, 0x0406)
}
If (LEqual(Local0,4))
{
// Mirror toggle
Notify(\_SB.PCI0.LPCB.PS2K, 0x046e)
}
}
```
和相關的補丁:
```
Comment: change Method(_Q13,0,S) to XQ13
Find: <5f513133 08>
Replace: <58513133 08>
```
同樣的 “Rename and Rep lace”機制也可以用于比這復雜得多的情況。例如,它通常用于修補電池方法,需要對這些方法進行修補,以避免訪問多字節EC字段。
# 對于復雜的重命名和替換的建議
您可能已經知道,修補電池狀態(多字節的EC字段)可能非常復雜,并且可能涉及許多代碼更改到許多方法。
本節將詳細介紹一些用于電池修補的技術和程序,用于給電池打補丁。
最好先給電池打補丁,而不要先用hotpatch。工作完成后,嘗試使用hotpatch。另外,未修補得電池代碼和已修補電池代碼之間的區別也很有幫助。您可以使用“diffmerge”這樣的工具來比較它們。如果你的筆記本型號在我的筆記本電腦庫里已經有了一個靜態電池補丁,這一點尤其正確。
一般流程:
——從本地ACPI開始
——使用靜態修補電池狀態(驗證效果)
——使用diffmerge來比較未修補的代碼與補丁代碼
——對于不同的方法,實現“重命名和替換”模式
——對于EC字段,創建另一個EC OperationRegion(使用與原始的名稱不同的名稱)和字段定義作為一種“覆蓋”,它只包含您需要修補的EC字段
——要創建EC層,您可以在修補的DSDT中使用修補的`Field/OperationRegion`,然后刪除未修補的字段
——在SSDT中允許通過替換方法使用外部 訪問ACPI集中其他地方定義的字段(通常是DSDT)
——讓編譯器指出需要使用外部的地方
——注意不同范圍內重復名稱的符號
該貼中的2樓中提供了一個示例。
您可能已經知道,對電池狀態(多字節EC字段)進行修補可能非常復雜,并且可能需要對許多方法進行大量代碼更改。
本節將詳細介紹一些用于電池修補的技術和步驟。
建議不先使用熱修補程序來修補電池。 當它開始工作后,請嘗試熱補丁。 另外,未為電池打補丁的代碼與為電池打補丁的代碼之間的區別非常有用。 您可以使用“ diffmerge”之類的工具進行比較。 如果我的筆記本電腦存儲庫中已經有筆記本電腦的靜電電池補丁,則尤其如此。
一般程序:
\-從本地ACPI開始
\-使用靜態修補程序修補電池狀態(驗證其是否有效)
\-使用diffmerge將未修補的代碼與修補的代碼進行比較
\-對于每個不同的方法,實施“重命名和替換”模式
\-對于EC字段,創建另一個EC OperationRegion(使用與原始名稱不同的名稱),并將Field定義作為一種“疊加”,其中僅包含您需要修補的EC字段
\-要創建EC疊加層,您可以在修補的DSDT中使用修補的Field / OperationRegion,然后消除未修補的字段
\-使用外部來允許SSDT中的替換方法訪問ACPI集中其他位置(通常是DSDT)定義的字段
\-讓編譯器指出您需要在哪里使用外部
\-注意在不同范圍內名稱重復的符號
此線程的帖子#2中提供了一個示例。
# 代碼值修補(Code value patching)
考慮“Fix Mutex with non-zero SyncLevel”的這個補丁例子。這個補丁找到所有的互斥對象(Mutex objects)并替換同步級別(SyncLevel)為0。我們使用這個補丁,因為 OS X 不支持對互斥對象正確的調試,還會終止對任何非零同步級別的互斥對象的捕獲。
舉個例子,u430的互斥對象是這樣的:
```
Mutex (MSMI, 0x07)
```
要使它與OS X兼容,必須更改:
```
Mutex (MSMI, 0)
```
ACPI規范定義了一個互斥對象如何在AML中編碼,但它可以幫助查看一個小ACPI文件的混合反編譯:
```
DefinitionBlock ("", "DSDT", 2, "test", "test", 0)
{
Mutex(ABCD, 7)
}
```
iasl編譯器可以使用“`- l`”選項創建混合列表文件。
如果我們用`iasl - l`測試來編譯上面的文件:`iasl -l test.dsl`,`test.lst` 包含如下:
```
1: DefinitionBlock ("", "DSDT", 2, "test", "test", 0)
00000000: 44 53 44 54 2B 00 00 00 "DSDT+..."
00000008: 02 36 74 65 73 74 00 00 ".6test.."
00000010: 74 65 73 74 00 00 00 00 "test...."
00000018: 00 00 00 00 49 4E 54 4C "....INTL"
00000020: 10 04 16 20 ............ "... "
2: {
3: Mutex(ABCD, 7)
00000024: 5B 01 41 42 43 44 07 ... "[.ABCD."
4: }
```
正如你所看到的;這個互斥對象`(ABCD, 7)`,被編碼為 `<5B 01 41 42 43 44 07>`。
現在很容易為它構建一個補丁:
```
Comment: Change Mutex(ABCD,7) to Mutex(ABCD,0)
Find: <5B 01 41 42 43 44 07>
Replace: <5B 01 41 42 43 44 00>
```
# Clover的ACPI 配置(Clover ACPI configuration)
使用靜態補丁,使用`DropOem = true`,并將DSDT和SSDTs添加到`ACPI / patched`中。使用hotpatch,使`DropOem = false`,并且只將附加SSDTs放在 `ACPI/patched`下。
需要注意`config.plist/ACPI/patches`只應用于原生的SSDTs,而不是`ACPI/patched`中的SSDTs。這意味著,如果您正在使用`config.plist`進行重命名對象,附加的SSDTs必須引用新的名稱,而不是舊的名稱。與`ACPI/patched`中的SSDTs不同,`ACPI/patched`中的二進制補丁對可能在`ACPI / patched`中的`DSDT.aml`有應用。如果您使用的是靜態和熱補丁的組合,你需要考慮到這一點。
另外,打靜態補丁,可以使用`SortedOrder`來指定`ACPI/patched`中SSDTs的順序。有了hotpatch,順序就不是必要的,因為可以在每個SSDT中構造代碼,這樣代碼就不依賴于順序。特別是如果你將所有的附加代碼放在一個SSDT中,比如關于我的筆記本電腦的git庫中的許多例子。除非您的附加SSDTs是順序相關的,否則您不必按`SortedOrder`方式命名每一個。
對于每個SSDT,也沒有必要選擇“數字編號的名稱”。相反,你可以使用有意義的名字,比如"SSDT-USB.aml", SSDT-XOSI.aml"。使用數字名稱會讓你迷惑,請不要這樣做。
# 解決問題
你可以使用補丁來查看你的完整的ACPI設置,如在修補后的Clover注射。通過運行 '`patchmatic -extract`',patchmatic將寫入所有注入的`DSDT.aml`和`SSDT*.aml`按照他們被Clover注射的順序。你可以用`iasl -da -dl *. aml`把它們拆開。如果`iasl`顯示了反編譯的錯誤(例如,重復符號),這就像OS X也在拒絕沖突的SSDTs。
如果您是一個新手,使用這種技術,一次實現一個補丁是一個好主意,并且慢慢地將它構建到一組完整的working patches + SSDTs中。試圖一次做所有的事情會使你很難找到你的錯誤。
# 問題報告
下載 patchmatic: https://bitbucket.org/RehabMan/os-x-maciasl-patchmatic/downloads/RehabMan-patchmatic-2015-0107.zip
解壓下載的patchmatic.zip 文件,把它復制到`/usr/bin`,這樣二進制文件就是`/usr/bin/patchmatic`這樣了。
在終端:
```
if [ -d ~/Downloads/RehabMan ]; then rm -R ~/Downloads/RehabMan; fi
mkdir ~/Downloads/RehabMan
cd ~/Downloads/RehabMan
patchmatic -extract
```
注意:為了簡單,你可以直接復制/粘貼而不是手動輸入上面的命令。
附上`Downloads/RehabMan`目錄的內容(如ZIP)。
同時,附上`ioreg`:http://www.tonymacx86.com/audio/58368-guide-how-make-copy-ioreg.html 。請使用附件中的IORegistryExplorer v2.1!不要使用`ioregistryexplorer.app`的其他版本然后回復我~。
```
kextstat|grep -y acpiplat
kextstat|grep -y appleintelcpu
kextstat|grep -y applelpc
```
同時,在收集之前,附加上你的`EFI/Clover`文件夾(你可以在主Clover屏幕上按下`F4`提取)。請刪除“themes”目錄,特別是如果你安裝了過多的主題。只提供`EFI/Clover`,而不是整個EFI文件夾。
也可以附上重建緩存日志:
```
sudo touch /System/Library/Extensions && sudo kextcache -u /
```
翻譯到此結束。但是后面是一些示例。
附上RehabMan大神的github:
1.OSX clover laptop config:https://github.com/RehabMan/OS-X-Clover-Laptop-Config
這里面提供了一些常見的補丁和說明,還有筆記本的通用config.plist。
2.elitebook/probook/zbook系列機型:https://github.com/RehabMan/HP-ProBook-4x30s-DSDT-Patch
3.Inter NUC 5/6/7系列:https://github.com/RehabMan/Intel-NUC-DSDT-Patch
4.Lenovo U330/U430/U530系列:https://github.com/RehabMan/Lenovo-U430-Touch-DSDT-Patch
5.HP envy J/K/Q/RHaswell系列:https://github.com/RehabMan/HP-Envy-DSDT-Patch
6.Lenovo Z50-70/Z40-70系列:https://github.com/RehabMan/Lenovo-Z50
7.Lenovo Y50/Y40-70系列:[url]https://github.com/RehabMan/Lenovo-Y50-DSDT-Patch
# 參考
[祝賀遠景開放,開啟完美黑蘋果新天地!(拋棄傳統DSDT方法,完美黑蘋果)](https://weibo.com/p/23041874f0e4330102x1sy)
https://blog.daliansky.net/hotpatch-detailed-solution.html
# [小小總結](http://bbs.pcbeta.com/viewthread-1766329-1-1.html)
傳統 DSDT 方式,是提取機器的 DSDT,反編譯后進行改錯、編輯、打補丁,然后再次編譯,最后把編譯好的 DSDT 拿來用。
原理上來說沒啥毛病,但是這個反編譯和編譯卻是問題所在,否則為什么要排錯啊。
然后,大神就提出這種方法,可以不提取 DSDT,免去了反編譯帶來的問題。
這種方法是其實可以理解為外掛。基于 Clover的 DSDT 二進制 patch 也就是二進制字符替換,再配合ssdt來實現的。
我們知道,對 DSDT 修改,總結來說就是改名、刪除、修改代碼,有些 DSDT 簡單修改,在 Clover 里可以直接通過勾選相應 Fix 功能實現。
另外對于其他的改名和刪除,還可以利用 clover 的 patch 功能,實現一些字符替換,直接實現對dsdt重命名和刪除的修改。
但是還有一些是要修改對象和方法里的代碼。這個怎么辦。沒關系,在上面的基礎上,然后把要需改的代碼放到單獨的 SSDT 里,二進制字符替換和 SSDT 配合使用即可實現修改代碼的操作。
更改調用時的方法名或者對象名,指向新 SSDT 里用新名字定義的對象或者方法,這叫重定向和替換。
直接把 DSDT 里的對象或方法的名字改掉,然后在SSDT 里重寫該對象或方法的定義,這就是重命名和替換。
上面幾點對應到Rehabman的教程里,就是hotpatch的四種修改類型:
1. 重命名ACPI對象(Renaming ACPI objects)
2. 刪除方法(Removingmethods)
3. 重定向和替換(Redirectand Replace)
4. 重命名和替換Rename andReplace)
(具體細節的在上面??的教程里說的很清楚,我就不展開贅述了。)
這種方式免去了 DSDT 提取、反編譯和編譯的過程,從而減少了這幾個過程出現的錯誤。
而且從方式上來說,hotpatch這種方式也比較“科學”。
# =======================
# 電池狀態的Hotpatch
這第二篇文章致力于用Clover補丁修補電池狀態。為了演示這個過程,我們將通過一個示例DSDT來工作。使用的示例文件來自于禁用獨立顯卡的指南,即“Asus UX303LN”:https://www.tonymacx86.com/threads/guide-disabling-discrete-graphics-in-dual-gpu-laptops.163772/ (我打算翻譯)
您應該下載附加到該指南的 `ACPI/origin`文件, 以便您跟著我一起做。
如上面1樓的文章所發布的,一般操作流程如下:
——從原生的ACPI補丁開始。
——使用靜態打補丁方式修補電池狀態(驗證其效果)
——使用`diffmerge`比較修改代碼與修補代碼
——為每個方法都是不同的,實現“Rename and Replace”模式
——對于EC字段,創建另一個EC OperationRegion(操作區域)(使用與原來不同的名稱)和字段定義作為一種“覆蓋層”,它只包含您需要修補的EC字段
——創建EC覆蓋層,您可以在修補的DSDT中使用修補的Field/OperationRegion(字段/操作區域),然后刪除未修補的字段。
——使用外部(External)來允許SSDT中的替換方法訪問ACPI集合中定義的字段(通常是DSDT)。
——讓編譯器指出需要使用外部(External)的地方
——注意不同范圍(scopes)內重復名稱的符號
## 使用diffmerge來發現 打補丁的(patched)和原生的(native) 之間的差異
首先分解源文件:`iasl -da -dl *.aml`(你應該熟悉這個部分,因為它是正常ACPI打補丁的一部分)
接下來,只需要使用`MaciASL`和`dsdt.dsl`就可以應用電池補丁。在這種情況下,我們應用“ASUS N55SL/VivoBook”。沒有必要修改任何錯誤,因為我們只關心應用電池補丁所產生的差異。將補丁文件保存為`dsdt_patch.dsl`。
現在您可以運行`diffmerge`以查看`DSDT.dsl` 和 `DSDT_patched.dsl`之間的區別。我通常是從終端來做這個的:
```
diffmerge DSDT.dsl DSDT_patched.dsl
```
初始的diffmerge窗口將會是這樣的:

從這里里,我們可以通過點擊左邊欄中的標記來檢查那些發生變化的部分。
在這些例子中,你會發現:
- 第1組: 是否對`EC`字段進行了更改 (多字節 VS 單一字節)
- 第2組: 加入`RDBA`,`WRBA`,`RDBB`,`WRBB`方法
- 第3組: 打補丁的 `FBST`, `_BIX`, `B1FA `方法
- 第4組: 打補丁的 `SMBR`, `SMBW`, `ECSB` 方法
- 第5組: 打補丁的 `TACH` 方法
- 最后一組: 額外添加的 `B1B2` 方法
## 構建初始SSDT
用 MaciASL開始一個空的SSDT:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
}
```
接下來,添加補丁中添加的所有方法。在這個示例中,這包括`RDBA、WRBA、RDBB、WRBB`和`B1B2`方法。您可以直接從`dsdt_patch.dsl`中復制它們。
你要確定每個方法都放在同一個作用域(scope)內。例如,這里是“第2組”的方法:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
Scope (_SB.PCI0.LPCB.EC0)
{
Scope (EC0)
{
Method (RDBA, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BA00, Index(TEMP, 0x00))
Store (BA01, Index(TEMP, 0x01))
Store (BA02, Index(TEMP, 0x02))
Store (BA03, Index(TEMP, 0x03))
Store (BA04, Index(TEMP, 0x04))
Store (BA05, Index(TEMP, 0x05))
Store (BA06, Index(TEMP, 0x06))
Store (BA07, Index(TEMP, 0x07))
Store (BA08, Index(TEMP, 0x08))
Store (BA09, Index(TEMP, 0x09))
Store (BA0A, Index(TEMP, 0x0A))
Store (BA0B, Index(TEMP, 0x0B))
Store (BA0C, Index(TEMP, 0x0C))
Store (BA0D, Index(TEMP, 0x0D))
Store (BA0E, Index(TEMP, 0x0E))
Store (BA0F, Index(TEMP, 0x0F))
Store (BA10, Index(TEMP, 0x10))
Store (BA11, Index(TEMP, 0x11))
Store (BA12, Index(TEMP, 0x12))
Store (BA13, Index(TEMP, 0x13))
Store (BA14, Index(TEMP, 0x14))
Store (BA15, Index(TEMP, 0x15))
Store (BA16, Index(TEMP, 0x16))
Store (BA17, Index(TEMP, 0x17))
Store (BA18, Index(TEMP, 0x18))
Store (BA19, Index(TEMP, 0x19))
Store (BA1A, Index(TEMP, 0x1A))
Store (BA1B, Index(TEMP, 0x1B))
Store (BA1C, Index(TEMP, 0x1C))
Store (BA1D, Index(TEMP, 0x1D))
Store (BA1E, Index(TEMP, 0x1E))
Store (BA1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBA, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BA00)
Store (DerefOf(Index(TEMP, 0x01)), BA01)
Store (DerefOf(Index(TEMP, 0x02)), BA02)
Store (DerefOf(Index(TEMP, 0x03)), BA03)
Store (DerefOf(Index(TEMP, 0x04)), BA04)
Store (DerefOf(Index(TEMP, 0x05)), BA05)
Store (DerefOf(Index(TEMP, 0x06)), BA06)
Store (DerefOf(Index(TEMP, 0x07)), BA07)
Store (DerefOf(Index(TEMP, 0x08)), BA08)
Store (DerefOf(Index(TEMP, 0x09)), BA09)
Store (DerefOf(Index(TEMP, 0x0A)), BA0A)
Store (DerefOf(Index(TEMP, 0x0B)), BA0B)
Store (DerefOf(Index(TEMP, 0x0C)), BA0C)
Store (DerefOf(Index(TEMP, 0x0D)), BA0D)
Store (DerefOf(Index(TEMP, 0x0E)), BA0E)
Store (DerefOf(Index(TEMP, 0x0F)), BA0F)
Store (DerefOf(Index(TEMP, 0x10)), BA10)
Store (DerefOf(Index(TEMP, 0x11)), BA11)
Store (DerefOf(Index(TEMP, 0x12)), BA12)
Store (DerefOf(Index(TEMP, 0x13)), BA13)
Store (DerefOf(Index(TEMP, 0x14)), BA14)
Store (DerefOf(Index(TEMP, 0x15)), BA15)
Store (DerefOf(Index(TEMP, 0x16)), BA16)
Store (DerefOf(Index(TEMP, 0x17)), BA17)
Store (DerefOf(Index(TEMP, 0x18)), BA18)
Store (DerefOf(Index(TEMP, 0x19)), BA19)
Store (DerefOf(Index(TEMP, 0x1A)), BA1A)
Store (DerefOf(Index(TEMP, 0x1B)), BA1B)
Store (DerefOf(Index(TEMP, 0x1C)), BA1C)
Store (DerefOf(Index(TEMP, 0x1D)), BA1D)
Store (DerefOf(Index(TEMP, 0x1E)), BA1E)
Store (DerefOf(Index(TEMP, 0x1F)), BA1F)
}
Method (RDBB, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BB00, Index(TEMP, 0x00))
Store (BB01, Index(TEMP, 0x01))
Store (BB02, Index(TEMP, 0x02))
Store (BB03, Index(TEMP, 0x03))
Store (BB04, Index(TEMP, 0x04))
Store (BB05, Index(TEMP, 0x05))
Store (BB06, Index(TEMP, 0x06))
Store (BB07, Index(TEMP, 0x07))
Store (BB08, Index(TEMP, 0x08))
Store (BB09, Index(TEMP, 0x09))
Store (BB0A, Index(TEMP, 0x0A))
Store (BB0B, Index(TEMP, 0x0B))
Store (BB0C, Index(TEMP, 0x0C))
Store (BB0D, Index(TEMP, 0x0D))
Store (BB0E, Index(TEMP, 0x0E))
Store (BB0F, Index(TEMP, 0x0F))
Store (BB10, Index(TEMP, 0x10))
Store (BB11, Index(TEMP, 0x11))
Store (BB12, Index(TEMP, 0x12))
Store (BB13, Index(TEMP, 0x13))
Store (BB14, Index(TEMP, 0x14))
Store (BB15, Index(TEMP, 0x15))
Store (BB16, Index(TEMP, 0x16))
Store (BB17, Index(TEMP, 0x17))
Store (BB18, Index(TEMP, 0x18))
Store (BB19, Index(TEMP, 0x19))
Store (BB1A, Index(TEMP, 0x1A))
Store (BB1B, Index(TEMP, 0x1B))
Store (BB1C, Index(TEMP, 0x1C))
Store (BB1D, Index(TEMP, 0x1D))
Store (BB1E, Index(TEMP, 0x1E))
Store (BB1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBB, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BB00)
Store (DerefOf(Index(TEMP, 0x01)), BB01)
Store (DerefOf(Index(TEMP, 0x02)), BB02)
Store (DerefOf(Index(TEMP, 0x03)), BB03)
Store (DerefOf(Index(TEMP, 0x04)), BB04)
Store (DerefOf(Index(TEMP, 0x05)), BB05)
Store (DerefOf(Index(TEMP, 0x06)), BB06)
Store (DerefOf(Index(TEMP, 0x07)), BB07)
Store (DerefOf(Index(TEMP, 0x08)), BB08)
Store (DerefOf(Index(TEMP, 0x09)), BB09)
Store (DerefOf(Index(TEMP, 0x0A)), BB0A)
Store (DerefOf(Index(TEMP, 0x0B)), BB0B)
Store (DerefOf(Index(TEMP, 0x0C)), BB0C)
Store (DerefOf(Index(TEMP, 0x0D)), BB0D)
Store (DerefOf(Index(TEMP, 0x0E)), BB0E)
Store (DerefOf(Index(TEMP, 0x0F)), BB0F)
Store (DerefOf(Index(TEMP, 0x10)), BB10)
Store (DerefOf(Index(TEMP, 0x11)), BB11)
Store (DerefOf(Index(TEMP, 0x12)), BB12)
Store (DerefOf(Index(TEMP, 0x13)), BB13)
Store (DerefOf(Index(TEMP, 0x14)), BB14)
Store (DerefOf(Index(TEMP, 0x15)), BB15)
Store (DerefOf(Index(TEMP, 0x16)), BB16)
Store (DerefOf(Index(TEMP, 0x17)), BB17)
Store (DerefOf(Index(TEMP, 0x18)), BB18)
Store (DerefOf(Index(TEMP, 0x19)), BB19)
Store (DerefOf(Index(TEMP, 0x1A)), BB1A)
Store (DerefOf(Index(TEMP, 0x1B)), BB1B)
Store (DerefOf(Index(TEMP, 0x1C)), BB1C)
Store (DerefOf(Index(TEMP, 0x1D)), BB1D)
Store (DerefOf(Index(TEMP, 0x1E)), BB1E)
Store (DerefOf(Index(TEMP, 0x1F)), BB1F)
}
}
}
}
```
并且 `B1B2`被添加:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
Method (B1B2, 2, NotSerialized) { Return (Or (Arg0, ShiftLeft (Arg1, 8))) }
// added methods (group 2)
Scope (_SB.PCI0.LPCB.EC0)
{
Scope (EC0)
{
Method (RDBA, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BA00, Index(TEMP, 0x00))
Store (BA01, Index(TEMP, 0x01))
Store (BA02, Index(TEMP, 0x02))
Store (BA03, Index(TEMP, 0x03))
Store (BA04, Index(TEMP, 0x04))
Store (BA05, Index(TEMP, 0x05))
Store (BA06, Index(TEMP, 0x06))
Store (BA07, Index(TEMP, 0x07))
Store (BA08, Index(TEMP, 0x08))
Store (BA09, Index(TEMP, 0x09))
Store (BA0A, Index(TEMP, 0x0A))
Store (BA0B, Index(TEMP, 0x0B))
Store (BA0C, Index(TEMP, 0x0C))
Store (BA0D, Index(TEMP, 0x0D))
Store (BA0E, Index(TEMP, 0x0E))
Store (BA0F, Index(TEMP, 0x0F))
Store (BA10, Index(TEMP, 0x10))
Store (BA11, Index(TEMP, 0x11))
Store (BA12, Index(TEMP, 0x12))
Store (BA13, Index(TEMP, 0x13))
Store (BA14, Index(TEMP, 0x14))
Store (BA15, Index(TEMP, 0x15))
Store (BA16, Index(TEMP, 0x16))
Store (BA17, Index(TEMP, 0x17))
Store (BA18, Index(TEMP, 0x18))
Store (BA19, Index(TEMP, 0x19))
Store (BA1A, Index(TEMP, 0x1A))
Store (BA1B, Index(TEMP, 0x1B))
Store (BA1C, Index(TEMP, 0x1C))
Store (BA1D, Index(TEMP, 0x1D))
Store (BA1E, Index(TEMP, 0x1E))
Store (BA1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBA, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BA00)
Store (DerefOf(Index(TEMP, 0x01)), BA01)
Store (DerefOf(Index(TEMP, 0x02)), BA02)
Store (DerefOf(Index(TEMP, 0x03)), BA03)
Store (DerefOf(Index(TEMP, 0x04)), BA04)
Store (DerefOf(Index(TEMP, 0x05)), BA05)
Store (DerefOf(Index(TEMP, 0x06)), BA06)
Store (DerefOf(Index(TEMP, 0x07)), BA07)
Store (DerefOf(Index(TEMP, 0x08)), BA08)
Store (DerefOf(Index(TEMP, 0x09)), BA09)
Store (DerefOf(Index(TEMP, 0x0A)), BA0A)
Store (DerefOf(Index(TEMP, 0x0B)), BA0B)
Store (DerefOf(Index(TEMP, 0x0C)), BA0C)
Store (DerefOf(Index(TEMP, 0x0D)), BA0D)
Store (DerefOf(Index(TEMP, 0x0E)), BA0E)
Store (DerefOf(Index(TEMP, 0x0F)), BA0F)
Store (DerefOf(Index(TEMP, 0x10)), BA10)
Store (DerefOf(Index(TEMP, 0x11)), BA11)
Store (DerefOf(Index(TEMP, 0x12)), BA12)
Store (DerefOf(Index(TEMP, 0x13)), BA13)
Store (DerefOf(Index(TEMP, 0x14)), BA14)
Store (DerefOf(Index(TEMP, 0x15)), BA15)
Store (DerefOf(Index(TEMP, 0x16)), BA16)
Store (DerefOf(Index(TEMP, 0x17)), BA17)
Store (DerefOf(Index(TEMP, 0x18)), BA18)
Store (DerefOf(Index(TEMP, 0x19)), BA19)
Store (DerefOf(Index(TEMP, 0x1A)), BA1A)
Store (DerefOf(Index(TEMP, 0x1B)), BA1B)
Store (DerefOf(Index(TEMP, 0x1C)), BA1C)
Store (DerefOf(Index(TEMP, 0x1D)), BA1D)
Store (DerefOf(Index(TEMP, 0x1E)), BA1E)
Store (DerefOf(Index(TEMP, 0x1F)), BA1F)
}
Method (RDBB, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BB00, Index(TEMP, 0x00))
Store (BB01, Index(TEMP, 0x01))
Store (BB02, Index(TEMP, 0x02))
Store (BB03, Index(TEMP, 0x03))
Store (BB04, Index(TEMP, 0x04))
Store (BB05, Index(TEMP, 0x05))
Store (BB06, Index(TEMP, 0x06))
Store (BB07, Index(TEMP, 0x07))
Store (BB08, Index(TEMP, 0x08))
Store (BB09, Index(TEMP, 0x09))
Store (BB0A, Index(TEMP, 0x0A))
Store (BB0B, Index(TEMP, 0x0B))
Store (BB0C, Index(TEMP, 0x0C))
Store (BB0D, Index(TEMP, 0x0D))
Store (BB0E, Index(TEMP, 0x0E))
Store (BB0F, Index(TEMP, 0x0F))
Store (BB10, Index(TEMP, 0x10))
Store (BB11, Index(TEMP, 0x11))
Store (BB12, Index(TEMP, 0x12))
Store (BB13, Index(TEMP, 0x13))
Store (BB14, Index(TEMP, 0x14))
Store (BB15, Index(TEMP, 0x15))
Store (BB16, Index(TEMP, 0x16))
Store (BB17, Index(TEMP, 0x17))
Store (BB18, Index(TEMP, 0x18))
Store (BB19, Index(TEMP, 0x19))
Store (BB1A, Index(TEMP, 0x1A))
Store (BB1B, Index(TEMP, 0x1B))
Store (BB1C, Index(TEMP, 0x1C))
Store (BB1D, Index(TEMP, 0x1D))
Store (BB1E, Index(TEMP, 0x1E))
Store (BB1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBB, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BB00)
Store (DerefOf(Index(TEMP, 0x01)), BB01)
Store (DerefOf(Index(TEMP, 0x02)), BB02)
Store (DerefOf(Index(TEMP, 0x03)), BB03)
Store (DerefOf(Index(TEMP, 0x04)), BB04)
Store (DerefOf(Index(TEMP, 0x05)), BB05)
Store (DerefOf(Index(TEMP, 0x06)), BB06)
Store (DerefOf(Index(TEMP, 0x07)), BB07)
Store (DerefOf(Index(TEMP, 0x08)), BB08)
Store (DerefOf(Index(TEMP, 0x09)), BB09)
Store (DerefOf(Index(TEMP, 0x0A)), BB0A)
Store (DerefOf(Index(TEMP, 0x0B)), BB0B)
Store (DerefOf(Index(TEMP, 0x0C)), BB0C)
Store (DerefOf(Index(TEMP, 0x0D)), BB0D)
Store (DerefOf(Index(TEMP, 0x0E)), BB0E)
Store (DerefOf(Index(TEMP, 0x0F)), BB0F)
Store (DerefOf(Index(TEMP, 0x10)), BB10)
Store (DerefOf(Index(TEMP, 0x11)), BB11)
Store (DerefOf(Index(TEMP, 0x12)), BB12)
Store (DerefOf(Index(TEMP, 0x13)), BB13)
Store (DerefOf(Index(TEMP, 0x14)), BB14)
Store (DerefOf(Index(TEMP, 0x15)), BB15)
Store (DerefOf(Index(TEMP, 0x16)), BB16)
Store (DerefOf(Index(TEMP, 0x17)), BB17)
Store (DerefOf(Index(TEMP, 0x18)), BB18)
Store (DerefOf(Index(TEMP, 0x19)), BB19)
Store (DerefOf(Index(TEMP, 0x1A)), BB1A)
Store (DerefOf(Index(TEMP, 0x1B)), BB1B)
Store (DerefOf(Index(TEMP, 0x1C)), BB1C)
Store (DerefOf(Index(TEMP, 0x1D)), BB1D)
Store (DerefOf(Index(TEMP, 0x1E)), BB1E)
Store (DerefOf(Index(TEMP, 0x1F)), BB1F)
}
}
}
}
```
不要擔心,代碼現在沒有編譯。由于在這個文件中沒有定義的`EC`字段(和其他標識符),在這一點上它是不被期望的。它們需要通過外部(最終)被定義或引用。
現在讓我們添加補丁方法。就像那些添加了方法的方法一樣,補丁方法也只是從`DSDT_patched.dsl`中復制的:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
// patched methods
Scope (_SB.PCI0)
{
Scope (BAT0)
{
Method (FBST, 4, NotSerialized)
{
And (Arg1, 0xFFFF, Local1)
Store (Zero, Local0)
If (^^LPCB.EC0.ACAP ())
{
Store (One, Local0)
}
If (Local0)
{
If (CHGS (Zero))
{
Store (0x02, Local0)
}
Else
{
Store (Zero, Local0)
}
}
Else
{
Store (One, Local0)
}
If (BLLO)
{
ShiftLeft (One, 0x02, Local2)
Or (Local0, Local2, Local0)
}
If (And (^^LPCB.EC0.EB0S, 0x08))
{
ShiftLeft (One, 0x02, Local2)
Or (Local0, Local2, Local0)
}
If (LGreaterEqual (Local1, 0x8000))
{
Subtract (0xFFFF, Local1, Local1)
}
Store (Arg2, Local2)
If (LEqual (PUNT, Zero))
{
Multiply (Local1, ^^LPCB.EC0.B0DV, Local1)
Multiply (Local2, 0x0A, Local2)
}
And (Local0, 0x02, Local3)
If (LNot (Local3))
{
Subtract (LFCC, Local2, Local3)
Divide (LFCC, 0xC8, Local4, Local5)
If (LLess (Local3, Local5))
{
Store (LFCC, Local2)
}
}
Else
{
Divide (LFCC, 0xC8, Local4, Local5)
Subtract (LFCC, Local5, Local4)
If (LGreater (Local2, Local4))
{
Store (Local4, Local2)
}
}
If (LNot (^^LPCB.EC0.ACAP ()))
{
Divide (Local2, MBLF, Local3, Local4)
If (LLess (Local1, Local4))
{
Store (Local4, Local1)
}
}
Store (Local0, Index (PBST, Zero))
Store (Local1, Index (PBST, One))
Store (Local2, Index (PBST, 0x02))
Store (Arg3, Index (PBST, 0x03))
}
Method (_BIX, 0, NotSerialized) // _BIX: Battery Information Extended
{
If (LNot (^^LPCB.EC0.BATP (Zero)))
{
Return (NBIX)
}
If (LEqual (^^LPCB.EC0.GBTT (Zero), 0xFF))
{
Return (NBIX)
}
_BIF ()
Store (DerefOf (Index (PBIF, Zero)), Index (BIXT, One))
Store (DerefOf (Index (PBIF, One)), Index (BIXT, 0x02))
Store (DerefOf (Index (PBIF, 0x02)), Index (BIXT, 0x03))
Store (DerefOf (Index (PBIF, 0x03)), Index (BIXT, 0x04))
Store (DerefOf (Index (PBIF, 0x04)), Index (BIXT, 0x05))
Store (DerefOf (Index (PBIF, 0x05)), Index (BIXT, 0x06))
Store (DerefOf (Index (PBIF, 0x06)), Index (BIXT, 0x07))
Store (DerefOf (Index (PBIF, 0x07)), Index (BIXT, 0x0E))
Store (DerefOf (Index (PBIF, 0x08)), Index (BIXT, 0x0F))
Store (DerefOf (Index (PBIF, 0x09)), Index (BIXT, 0x10))
Store (DerefOf (Index (PBIF, 0x0A)), Index (BIXT, 0x11))
Store (DerefOf (Index (PBIF, 0x0B)), Index (BIXT, 0x12))
Store (DerefOf (Index (PBIF, 0x0C)), Index (BIXT, 0x13))
If (LEqual (DerefOf (Index (BIXT, One)), One))
{
Store (Zero, Index (BIXT, One))
Store (DerefOf (Index (BIXT, 0x05)), Local0)
Multiply (DerefOf (Index (BIXT, 0x02)), Local0, Index (BIXT, 0x02))
Multiply (DerefOf (Index (BIXT, 0x03)), Local0, Index (BIXT, 0x03))
Multiply (DerefOf (Index (BIXT, 0x06)), Local0, Index (BIXT, 0x06))
Multiply (DerefOf (Index (BIXT, 0x07)), Local0, Index (BIXT, 0x07))
Multiply (DerefOf (Index (BIXT, 0x0E)), Local0, Index (BIXT, 0x0E))
Multiply (DerefOf (Index (BIXT, 0x0F)), Local0, Index (BIXT, 0x0F))
Divide (DerefOf (Index (BIXT, 0x02)), 0x03E8, Local0, Index (BIXT, 0x02))
Divide (DerefOf (Index (BIXT, 0x03)), 0x03E8, Local0, Index (BIXT, 0x03))
Divide (DerefOf (Index (BIXT, 0x06)), 0x03E8, Local0, Index (BIXT, 0x06))
Divide (DerefOf (Index (BIXT, 0x07)), 0x03E8, Local0, Index (BIXT, 0x07))
Divide (DerefOf (Index (BIXT, 0x0E)), 0x03E8, Local0, Index (BIXT, 0x0E))
Divide (DerefOf (Index (BIXT, 0x0F)), 0x03E8, Local0, Index (BIXT, 0x0F))
}
Store (B1B2(^^LPCB.EC0.XC30,^^LPCB.EC0.XC31), Index (BIXT, 0x08))
Store (0x0001869F, Index (BIXT, 0x09))
Return (BIXT)
}
}
}
Scope (_SB.PCI0.LPCB.EC0)
{
Method (BIFA, 0, NotSerialized)
{
If (ECAV ())
{
If (BSLF)
{
Store (B1B2(B1S0,B1S1), Local0)
}
Else
{
Store (B1B2(B0S0,B0S1), Local0)
}
}
Else
{
Store (Ones, Local0)
}
Return (Local0)
}
}
Method (B1B2, 2, NotSerialized) { Return (Or (Arg0, ShiftLeft (Arg1, 8))) }
// added methods (group 2)
Scope (_SB.PCI0.LPCB.EC0)
{
Scope (EC0)
{
Method (RDBA, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BA00, Index(TEMP, 0x00))
Store (BA01, Index(TEMP, 0x01))
Store (BA02, Index(TEMP, 0x02))
Store (BA03, Index(TEMP, 0x03))
Store (BA04, Index(TEMP, 0x04))
Store (BA05, Index(TEMP, 0x05))
Store (BA06, Index(TEMP, 0x06))
Store (BA07, Index(TEMP, 0x07))
Store (BA08, Index(TEMP, 0x08))
Store (BA09, Index(TEMP, 0x09))
Store (BA0A, Index(TEMP, 0x0A))
Store (BA0B, Index(TEMP, 0x0B))
Store (BA0C, Index(TEMP, 0x0C))
Store (BA0D, Index(TEMP, 0x0D))
Store (BA0E, Index(TEMP, 0x0E))
Store (BA0F, Index(TEMP, 0x0F))
Store (BA10, Index(TEMP, 0x10))
Store (BA11, Index(TEMP, 0x11))
Store (BA12, Index(TEMP, 0x12))
Store (BA13, Index(TEMP, 0x13))
Store (BA14, Index(TEMP, 0x14))
Store (BA15, Index(TEMP, 0x15))
Store (BA16, Index(TEMP, 0x16))
Store (BA17, Index(TEMP, 0x17))
Store (BA18, Index(TEMP, 0x18))
Store (BA19, Index(TEMP, 0x19))
Store (BA1A, Index(TEMP, 0x1A))
Store (BA1B, Index(TEMP, 0x1B))
Store (BA1C, Index(TEMP, 0x1C))
Store (BA1D, Index(TEMP, 0x1D))
Store (BA1E, Index(TEMP, 0x1E))
Store (BA1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBA, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BA00)
Store (DerefOf(Index(TEMP, 0x01)), BA01)
Store (DerefOf(Index(TEMP, 0x02)), BA02)
Store (DerefOf(Index(TEMP, 0x03)), BA03)
Store (DerefOf(Index(TEMP, 0x04)), BA04)
Store (DerefOf(Index(TEMP, 0x05)), BA05)
Store (DerefOf(Index(TEMP, 0x06)), BA06)
Store (DerefOf(Index(TEMP, 0x07)), BA07)
Store (DerefOf(Index(TEMP, 0x08)), BA08)
Store (DerefOf(Index(TEMP, 0x09)), BA09)
Store (DerefOf(Index(TEMP, 0x0A)), BA0A)
Store (DerefOf(Index(TEMP, 0x0B)), BA0B)
Store (DerefOf(Index(TEMP, 0x0C)), BA0C)
Store (DerefOf(Index(TEMP, 0x0D)), BA0D)
Store (DerefOf(Index(TEMP, 0x0E)), BA0E)
Store (DerefOf(Index(TEMP, 0x0F)), BA0F)
Store (DerefOf(Index(TEMP, 0x10)), BA10)
Store (DerefOf(Index(TEMP, 0x11)), BA11)
Store (DerefOf(Index(TEMP, 0x12)), BA12)
Store (DerefOf(Index(TEMP, 0x13)), BA13)
Store (DerefOf(Index(TEMP, 0x14)), BA14)
Store (DerefOf(Index(TEMP, 0x15)), BA15)
Store (DerefOf(Index(TEMP, 0x16)), BA16)
Store (DerefOf(Index(TEMP, 0x17)), BA17)
Store (DerefOf(Index(TEMP, 0x18)), BA18)
Store (DerefOf(Index(TEMP, 0x19)), BA19)
Store (DerefOf(Index(TEMP, 0x1A)), BA1A)
Store (DerefOf(Index(TEMP, 0x1B)), BA1B)
Store (DerefOf(Index(TEMP, 0x1C)), BA1C)
Store (DerefOf(Index(TEMP, 0x1D)), BA1D)
Store (DerefOf(Index(TEMP, 0x1E)), BA1E)
Store (DerefOf(Index(TEMP, 0x1F)), BA1F)
}
Method (RDBB, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BB00, Index(TEMP, 0x00))
Store (BB01, Index(TEMP, 0x01))
Store (BB02, Index(TEMP, 0x02))
Store (BB03, Index(TEMP, 0x03))
Store (BB04, Index(TEMP, 0x04))
Store (BB05, Index(TEMP, 0x05))
Store (BB06, Index(TEMP, 0x06))
Store (BB07, Index(TEMP, 0x07))
Store (BB08, Index(TEMP, 0x08))
Store (BB09, Index(TEMP, 0x09))
Store (BB0A, Index(TEMP, 0x0A))
Store (BB0B, Index(TEMP, 0x0B))
Store (BB0C, Index(TEMP, 0x0C))
Store (BB0D, Index(TEMP, 0x0D))
Store (BB0E, Index(TEMP, 0x0E))
Store (BB0F, Index(TEMP, 0x0F))
Store (BB10, Index(TEMP, 0x10))
Store (BB11, Index(TEMP, 0x11))
Store (BB12, Index(TEMP, 0x12))
Store (BB13, Index(TEMP, 0x13))
Store (BB14, Index(TEMP, 0x14))
Store (BB15, Index(TEMP, 0x15))
Store (BB16, Index(TEMP, 0x16))
Store (BB17, Index(TEMP, 0x17))
Store (BB18, Index(TEMP, 0x18))
Store (BB19, Index(TEMP, 0x19))
Store (BB1A, Index(TEMP, 0x1A))
Store (BB1B, Index(TEMP, 0x1B))
Store (BB1C, Index(TEMP, 0x1C))
Store (BB1D, Index(TEMP, 0x1D))
Store (BB1E, Index(TEMP, 0x1E))
Store (BB1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBB, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BB00)
Store (DerefOf(Index(TEMP, 0x01)), BB01)
Store (DerefOf(Index(TEMP, 0x02)), BB02)
Store (DerefOf(Index(TEMP, 0x03)), BB03)
Store (DerefOf(Index(TEMP, 0x04)), BB04)
Store (DerefOf(Index(TEMP, 0x05)), BB05)
Store (DerefOf(Index(TEMP, 0x06)), BB06)
Store (DerefOf(Index(TEMP, 0x07)), BB07)
Store (DerefOf(Index(TEMP, 0x08)), BB08)
Store (DerefOf(Index(TEMP, 0x09)), BB09)
Store (DerefOf(Index(TEMP, 0x0A)), BB0A)
Store (DerefOf(Index(TEMP, 0x0B)), BB0B)
Store (DerefOf(Index(TEMP, 0x0C)), BB0C)
Store (DerefOf(Index(TEMP, 0x0D)), BB0D)
Store (DerefOf(Index(TEMP, 0x0E)), BB0E)
Store (DerefOf(Index(TEMP, 0x0F)), BB0F)
Store (DerefOf(Index(TEMP, 0x10)), BB10)
Store (DerefOf(Index(TEMP, 0x11)), BB11)
Store (DerefOf(Index(TEMP, 0x12)), BB12)
Store (DerefOf(Index(TEMP, 0x13)), BB13)
Store (DerefOf(Index(TEMP, 0x14)), BB14)
Store (DerefOf(Index(TEMP, 0x15)), BB15)
Store (DerefOf(Index(TEMP, 0x16)), BB16)
Store (DerefOf(Index(TEMP, 0x17)), BB17)
Store (DerefOf(Index(TEMP, 0x18)), BB18)
Store (DerefOf(Index(TEMP, 0x19)), BB19)
Store (DerefOf(Index(TEMP, 0x1A)), BB1A)
Store (DerefOf(Index(TEMP, 0x1B)), BB1B)
Store (DerefOf(Index(TEMP, 0x1C)), BB1C)
Store (DerefOf(Index(TEMP, 0x1D)), BB1D)
Store (DerefOf(Index(TEMP, 0x1E)), BB1E)
Store (DerefOf(Index(TEMP, 0x1F)), BB1F)
}
}
}
}
```
注意,如何將`FBST`和`_BIX`添加到 `_SB.PCI0.BAT0`作用范圍(scope)中。而`BIFA`被添加到`_SB.PCI0.LPCB.EC0`。把所有的方法都注入到原來的作用范圍(scope)是很重要的。
現在,我們添加`SMBR`、`SMBW`、`ECSB`和`TACH`:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
// patched methods
Scope (_SB.PCI0)
{
Scope (BAT0)
{
Method (FBST, 4, NotSerialized)
{
And (Arg1, 0xFFFF, Local1)
Store (Zero, Local0)
If (^^LPCB.EC0.ACAP ())
{
Store (One, Local0)
}
If (Local0)
{
If (CHGS (Zero))
{
Store (0x02, Local0)
}
Else
{
Store (Zero, Local0)
}
}
Else
{
Store (One, Local0)
}
If (BLLO)
{
ShiftLeft (One, 0x02, Local2)
Or (Local0, Local2, Local0)
}
If (And (^^LPCB.EC0.EB0S, 0x08))
{
ShiftLeft (One, 0x02, Local2)
Or (Local0, Local2, Local0)
}
If (LGreaterEqual (Local1, 0x8000))
{
Subtract (0xFFFF, Local1, Local1)
}
Store (Arg2, Local2)
If (LEqual (PUNT, Zero))
{
Multiply (Local1, ^^LPCB.EC0.B0DV, Local1)
Multiply (Local2, 0x0A, Local2)
}
And (Local0, 0x02, Local3)
If (LNot (Local3))
{
Subtract (LFCC, Local2, Local3)
Divide (LFCC, 0xC8, Local4, Local5)
If (LLess (Local3, Local5))
{
Store (LFCC, Local2)
}
}
Else
{
Divide (LFCC, 0xC8, Local4, Local5)
Subtract (LFCC, Local5, Local4)
If (LGreater (Local2, Local4))
{
Store (Local4, Local2)
}
}
If (LNot (^^LPCB.EC0.ACAP ()))
{
Divide (Local2, MBLF, Local3, Local4)
If (LLess (Local1, Local4))
{
Store (Local4, Local1)
}
}
Store (Local0, Index (PBST, Zero))
Store (Local1, Index (PBST, One))
Store (Local2, Index (PBST, 0x02))
Store (Arg3, Index (PBST, 0x03))
}
Method (_BIX, 0, NotSerialized) // _BIX: Battery Information Extended
{
If (LNot (^^LPCB.EC0.BATP (Zero)))
{
Return (NBIX)
}
If (LEqual (^^LPCB.EC0.GBTT (Zero), 0xFF))
{
Return (NBIX)
}
_BIF ()
Store (DerefOf (Index (PBIF, Zero)), Index (BIXT, One))
Store (DerefOf (Index (PBIF, One)), Index (BIXT, 0x02))
Store (DerefOf (Index (PBIF, 0x02)), Index (BIXT, 0x03))
Store (DerefOf (Index (PBIF, 0x03)), Index (BIXT, 0x04))
Store (DerefOf (Index (PBIF, 0x04)), Index (BIXT, 0x05))
Store (DerefOf (Index (PBIF, 0x05)), Index (BIXT, 0x06))
Store (DerefOf (Index (PBIF, 0x06)), Index (BIXT, 0x07))
Store (DerefOf (Index (PBIF, 0x07)), Index (BIXT, 0x0E))
Store (DerefOf (Index (PBIF, 0x08)), Index (BIXT, 0x0F))
Store (DerefOf (Index (PBIF, 0x09)), Index (BIXT, 0x10))
Store (DerefOf (Index (PBIF, 0x0A)), Index (BIXT, 0x11))
Store (DerefOf (Index (PBIF, 0x0B)), Index (BIXT, 0x12))
Store (DerefOf (Index (PBIF, 0x0C)), Index (BIXT, 0x13))
If (LEqual (DerefOf (Index (BIXT, One)), One))
{
Store (Zero, Index (BIXT, One))
Store (DerefOf (Index (BIXT, 0x05)), Local0)
Multiply (DerefOf (Index (BIXT, 0x02)), Local0, Index (BIXT, 0x02))
Multiply (DerefOf (Index (BIXT, 0x03)), Local0, Index (BIXT, 0x03))
Multiply (DerefOf (Index (BIXT, 0x06)), Local0, Index (BIXT, 0x06))
Multiply (DerefOf (Index (BIXT, 0x07)), Local0, Index (BIXT, 0x07))
Multiply (DerefOf (Index (BIXT, 0x0E)), Local0, Index (BIXT, 0x0E))
Multiply (DerefOf (Index (BIXT, 0x0F)), Local0, Index (BIXT, 0x0F))
Divide (DerefOf (Index (BIXT, 0x02)), 0x03E8, Local0, Index (BIXT, 0x02))
Divide (DerefOf (Index (BIXT, 0x03)), 0x03E8, Local0, Index (BIXT, 0x03))
Divide (DerefOf (Index (BIXT, 0x06)), 0x03E8, Local0, Index (BIXT, 0x06))
Divide (DerefOf (Index (BIXT, 0x07)), 0x03E8, Local0, Index (BIXT, 0x07))
Divide (DerefOf (Index (BIXT, 0x0E)), 0x03E8, Local0, Index (BIXT, 0x0E))
Divide (DerefOf (Index (BIXT, 0x0F)), 0x03E8, Local0, Index (BIXT, 0x0F))
}
Store (B1B2(^^LPCB.EC0.XC30,^^LPCB.EC0.XC31), Index (BIXT, 0x08))
Store (0x0001869F, Index (BIXT, 0x09))
Return (BIXT)
}
}
}
Scope (_SB.PCI0.LPCB.EC0)
{
Method (BIFA, 0, NotSerialized)
{
If (ECAV ())
{
If (BSLF)
{
Store (B1B2(B1S0,B1S1), Local0)
}
Else
{
Store (B1B2(B0S0,B0S1), Local0)
}
}
Else
{
Store (Ones, Local0)
}
Return (Local0)
}
Method (SMBR, 3, Serialized)
{
Store (Package (0x03)
{
0x07,
Zero,
Zero
}, Local0)
If (LNot (ECAV ()))
{
Return (Local0)
}
If (LNotEqual (Arg0, RDBL))
{
If (LNotEqual (Arg0, RDWD))
{
If (LNotEqual (Arg0, RDBT))
{
If (LNotEqual (Arg0, RCBT))
{
If (LNotEqual (Arg0, RDQK))
{
Return (Local0)
}
}
}
}
}
Acquire (MUEC, 0xFFFF)
Store (PRTC, Local1)
Store (Zero, Local2)
While (LNotEqual (Local1, Zero))
{
Stall (0x0A)
Increment (Local2)
If (LGreater (Local2, 0x03E8))
{
Store (SBBY, Index (Local0, Zero))
Store (Zero, Local1)
}
Else
{
Store (PRTC, Local1)
}
}
If (LLessEqual (Local2, 0x03E8))
{
ShiftLeft (Arg1, One, Local3)
Or (Local3, One, Local3)
Store (Local3, ADDR)
If (LNotEqual (Arg0, RDQK))
{
If (LNotEqual (Arg0, RCBT))
{
Store (Arg2, CMDB)
}
}
WRBA(Zero)
Store (Arg0, PRTC)
Store (SWTC (Arg0), Index (Local0, Zero))
If (LEqual (DerefOf (Index (Local0, Zero)), Zero))
{
If (LEqual (Arg0, RDBL))
{
Store (BCNT, Index (Local0, One))
Store (RDBA(), Index (Local0, 0x02))
}
If (LEqual (Arg0, RDWD))
{
Store (0x02, Index (Local0, One))
Store (B1B2(T2B0,T2B1), Index (Local0, 0x02))
}
If (LEqual (Arg0, RDBT))
{
Store (One, Index (Local0, One))
Store (DAT0, Index (Local0, 0x02))
}
If (LEqual (Arg0, RCBT))
{
Store (One, Index (Local0, One))
Store (DAT0, Index (Local0, 0x02))
}
}
}
Release (MUEC)
Return (Local0)
}
Method (SMBW, 5, Serialized)
{
Store (Package (0x01)
{
0x07
}, Local0)
If (LNot (ECAV ()))
{
Return (Local0)
}
If (LNotEqual (Arg0, WRBL))
{
If (LNotEqual (Arg0, WRWD))
{
If (LNotEqual (Arg0, WRBT))
{
If (LNotEqual (Arg0, SDBT))
{
If (LNotEqual (Arg0, WRQK))
{
Return (Local0)
}
}
}
}
}
Acquire (MUEC, 0xFFFF)
Store (PRTC, Local1)
Store (Zero, Local2)
While (LNotEqual (Local1, Zero))
{
Stall (0x0A)
Increment (Local2)
If (LGreater (Local2, 0x03E8))
{
Store (SBBY, Index (Local0, Zero))
Store (Zero, Local1)
}
Else
{
Store (PRTC, Local1)
}
}
If (LLessEqual (Local2, 0x03E8))
{
WRBA(Zero)
ShiftLeft (Arg1, One, Local3)
Store (Local3, ADDR)
If (LNotEqual (Arg0, WRQK))
{
If (LNotEqual (Arg0, SDBT))
{
Store (Arg2, CMDB)
}
}
If (LEqual (Arg0, WRBL))
{
Store (Arg3, BCNT)
WRBA(Arg4)
}
If (LEqual (Arg0, WRWD))
{
Store(Arg4,T2B0) Store(ShiftRight(Arg4,8),T2B1)
}
If (LEqual (Arg0, WRBT))
{
Store (Arg4, DAT0)
}
If (LEqual (Arg0, SDBT))
{
Store (Arg4, DAT0)
}
Store (Arg0, PRTC)
Store (SWTC (Arg0), Index (Local0, Zero))
}
Release (MUEC)
Return (Local0)
}
Method (ECSB, 7, NotSerialized)
{
Store (Package (0x05)
{
0x11,
Zero,
Zero,
Zero,
Buffer (0x20){}
}, Local1)
If (LGreater (Arg0, One))
{
Return (Local1)
}
If (ECAV ())
{
Acquire (MUEC, 0xFFFF)
If (LEqual (Arg0, Zero))
{
Store (PRTC, Local0)
}
Else
{
Store (PRT2, Local0)
}
Store (Zero, Local2)
While (LNotEqual (Local0, Zero))
{
Stall (0x0A)
Increment (Local2)
If (LGreater (Local2, 0x03E8))
{
Store (SBBY, Index (Local1, Zero))
Store (Zero, Local0)
}
ElseIf (LEqual (Arg0, Zero))
{
Store (PRTC, Local0)
}
Else
{
Store (PRT2, Local0)
}
}
If (LLessEqual (Local2, 0x03E8))
{
If (LEqual (Arg0, Zero))
{
Store (Arg2, ADDR)
Store (Arg3, CMDB)
If (LOr (LEqual (Arg1, 0x0A), LEqual (Arg1, 0x0B)))
{
Store (DerefOf (Index (Arg6, Zero)), BCNT)
WRBA(DerefOf (Index (Arg6, One)))
}
Else
{
Store (Arg4, DAT0)
Store (Arg5, DAT1)
}
Store (Arg1, PRTC)
}
Else
{
Store (Arg2, ADD2)
Store (Arg3, CMD2)
If (LOr (LEqual (Arg1, 0x0A), LEqual (Arg1, 0x0B)))
{
Store (DerefOf (Index (Arg6, Zero)), BCN2)
WRBB(DerefOf (Index (Arg6, One)))
}
Else
{
Store (Arg4, DA20)
Store (Arg5, DA21)
}
Store (Arg1, PRT2)
}
Store (0x7F, Local0)
If (LEqual (Arg0, Zero))
{
While (PRTC)
{
Sleep (One)
Decrement (Local0)
}
}
Else
{
While (PRT2)
{
Sleep (One)
Decrement (Local0)
}
}
If (Local0)
{
If (LEqual (Arg0, Zero))
{
Store (SSTS, Local0)
Store (DAT0, Index (Local1, One))
Store (DAT1, Index (Local1, 0x02))
Store (BCNT, Index (Local1, 0x03))
Store (RDBA(), Index (Local1, 0x04))
}
Else
{
Store (SST2, Local0)
Store (DA20, Index (Local1, One))
Store (DA21, Index (Local1, 0x02))
Store (BCN2, Index (Local1, 0x03))
Store (RDBB(), Index (Local1, 0x04))
}
And (Local0, 0x1F, Local0)
If (Local0)
{
Add (Local0, 0x10, Local0)
}
Store (Local0, Index (Local1, Zero))
}
Else
{
Store (0x10, Index (Local1, Zero))
}
}
Release (MUEC)
}
Return (Local1)
}
Method (TACH, 1, Serialized)
{
If (ECAV ())
{
Switch (Arg0)
{
Case (Zero)
{
Store (B1B2(TH00,TH01), Local0)
Break
}
Case (One)
{
Store (B1B2(TH10,TH11), Local0)
Break
}
Default
{
Return (Ones)
}
}
Multiply (Local0, 0x02, Local0)
If (LNotEqual (Local0, Zero))
{
Divide (0x0041CDB4, Local0, Local1, Local0)
Return (Local0)
}
Else
{
Return (Ones)
}
}
Else
{
Return (Ones)
}
}
}
Method (B1B2, 2, NotSerialized) { Return (Or (Arg0, ShiftLeft (Arg1, 8))) }
// added methods (group 2)
Scope (_SB.PCI0.LPCB)
{
Scope (EC0)
{
Method (RDBA, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BA00, Index(TEMP, 0x00))
Store (BA01, Index(TEMP, 0x01))
Store (BA02, Index(TEMP, 0x02))
Store (BA03, Index(TEMP, 0x03))
Store (BA04, Index(TEMP, 0x04))
Store (BA05, Index(TEMP, 0x05))
Store (BA06, Index(TEMP, 0x06))
Store (BA07, Index(TEMP, 0x07))
Store (BA08, Index(TEMP, 0x08))
Store (BA09, Index(TEMP, 0x09))
Store (BA0A, Index(TEMP, 0x0A))
Store (BA0B, Index(TEMP, 0x0B))
Store (BA0C, Index(TEMP, 0x0C))
Store (BA0D, Index(TEMP, 0x0D))
Store (BA0E, Index(TEMP, 0x0E))
Store (BA0F, Index(TEMP, 0x0F))
Store (BA10, Index(TEMP, 0x10))
Store (BA11, Index(TEMP, 0x11))
Store (BA12, Index(TEMP, 0x12))
Store (BA13, Index(TEMP, 0x13))
Store (BA14, Index(TEMP, 0x14))
Store (BA15, Index(TEMP, 0x15))
Store (BA16, Index(TEMP, 0x16))
Store (BA17, Index(TEMP, 0x17))
Store (BA18, Index(TEMP, 0x18))
Store (BA19, Index(TEMP, 0x19))
Store (BA1A, Index(TEMP, 0x1A))
Store (BA1B, Index(TEMP, 0x1B))
Store (BA1C, Index(TEMP, 0x1C))
Store (BA1D, Index(TEMP, 0x1D))
Store (BA1E, Index(TEMP, 0x1E))
Store (BA1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBA, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BA00)
Store (DerefOf(Index(TEMP, 0x01)), BA01)
Store (DerefOf(Index(TEMP, 0x02)), BA02)
Store (DerefOf(Index(TEMP, 0x03)), BA03)
Store (DerefOf(Index(TEMP, 0x04)), BA04)
Store (DerefOf(Index(TEMP, 0x05)), BA05)
Store (DerefOf(Index(TEMP, 0x06)), BA06)
Store (DerefOf(Index(TEMP, 0x07)), BA07)
Store (DerefOf(Index(TEMP, 0x08)), BA08)
Store (DerefOf(Index(TEMP, 0x09)), BA09)
Store (DerefOf(Index(TEMP, 0x0A)), BA0A)
Store (DerefOf(Index(TEMP, 0x0B)), BA0B)
Store (DerefOf(Index(TEMP, 0x0C)), BA0C)
Store (DerefOf(Index(TEMP, 0x0D)), BA0D)
Store (DerefOf(Index(TEMP, 0x0E)), BA0E)
Store (DerefOf(Index(TEMP, 0x0F)), BA0F)
Store (DerefOf(Index(TEMP, 0x10)), BA10)
Store (DerefOf(Index(TEMP, 0x11)), BA11)
Store (DerefOf(Index(TEMP, 0x12)), BA12)
Store (DerefOf(Index(TEMP, 0x13)), BA13)
Store (DerefOf(Index(TEMP, 0x14)), BA14)
Store (DerefOf(Index(TEMP, 0x15)), BA15)
Store (DerefOf(Index(TEMP, 0x16)), BA16)
Store (DerefOf(Index(TEMP, 0x17)), BA17)
Store (DerefOf(Index(TEMP, 0x18)), BA18)
Store (DerefOf(Index(TEMP, 0x19)), BA19)
Store (DerefOf(Index(TEMP, 0x1A)), BA1A)
Store (DerefOf(Index(TEMP, 0x1B)), BA1B)
Store (DerefOf(Index(TEMP, 0x1C)), BA1C)
Store (DerefOf(Index(TEMP, 0x1D)), BA1D)
Store (DerefOf(Index(TEMP, 0x1E)), BA1E)
Store (DerefOf(Index(TEMP, 0x1F)), BA1F)
}
Method (RDBB, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BB00, Index(TEMP, 0x00))
Store (BB01, Index(TEMP, 0x01))
Store (BB02, Index(TEMP, 0x02))
Store (BB03, Index(TEMP, 0x03))
Store (BB04, Index(TEMP, 0x04))
Store (BB05, Index(TEMP, 0x05))
Store (BB06, Index(TEMP, 0x06))
Store (BB07, Index(TEMP, 0x07))
Store (BB08, Index(TEMP, 0x08))
Store (BB09, Index(TEMP, 0x09))
Store (BB0A, Index(TEMP, 0x0A))
Store (BB0B, Index(TEMP, 0x0B))
Store (BB0C, Index(TEMP, 0x0C))
Store (BB0D, Index(TEMP, 0x0D))
Store (BB0E, Index(TEMP, 0x0E))
Store (BB0F, Index(TEMP, 0x0F))
Store (BB10, Index(TEMP, 0x10))
Store (BB11, Index(TEMP, 0x11))
Store (BB12, Index(TEMP, 0x12))
Store (BB13, Index(TEMP, 0x13))
Store (BB14, Index(TEMP, 0x14))
Store (BB15, Index(TEMP, 0x15))
Store (BB16, Index(TEMP, 0x16))
Store (BB17, Index(TEMP, 0x17))
Store (BB18, Index(TEMP, 0x18))
Store (BB19, Index(TEMP, 0x19))
Store (BB1A, Index(TEMP, 0x1A))
Store (BB1B, Index(TEMP, 0x1B))
Store (BB1C, Index(TEMP, 0x1C))
Store (BB1D, Index(TEMP, 0x1D))
Store (BB1E, Index(TEMP, 0x1E))
Store (BB1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBB, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BB00)
Store (DerefOf(Index(TEMP, 0x01)), BB01)
Store (DerefOf(Index(TEMP, 0x02)), BB02)
Store (DerefOf(Index(TEMP, 0x03)), BB03)
Store (DerefOf(Index(TEMP, 0x04)), BB04)
Store (DerefOf(Index(TEMP, 0x05)), BB05)
Store (DerefOf(Index(TEMP, 0x06)), BB06)
Store (DerefOf(Index(TEMP, 0x07)), BB07)
Store (DerefOf(Index(TEMP, 0x08)), BB08)
Store (DerefOf(Index(TEMP, 0x09)), BB09)
Store (DerefOf(Index(TEMP, 0x0A)), BB0A)
Store (DerefOf(Index(TEMP, 0x0B)), BB0B)
Store (DerefOf(Index(TEMP, 0x0C)), BB0C)
Store (DerefOf(Index(TEMP, 0x0D)), BB0D)
Store (DerefOf(Index(TEMP, 0x0E)), BB0E)
Store (DerefOf(Index(TEMP, 0x0F)), BB0F)
Store (DerefOf(Index(TEMP, 0x10)), BB10)
Store (DerefOf(Index(TEMP, 0x11)), BB11)
Store (DerefOf(Index(TEMP, 0x12)), BB12)
Store (DerefOf(Index(TEMP, 0x13)), BB13)
Store (DerefOf(Index(TEMP, 0x14)), BB14)
Store (DerefOf(Index(TEMP, 0x15)), BB15)
Store (DerefOf(Index(TEMP, 0x16)), BB16)
Store (DerefOf(Index(TEMP, 0x17)), BB17)
Store (DerefOf(Index(TEMP, 0x18)), BB18)
Store (DerefOf(Index(TEMP, 0x19)), BB19)
Store (DerefOf(Index(TEMP, 0x1A)), BB1A)
Store (DerefOf(Index(TEMP, 0x1B)), BB1B)
Store (DerefOf(Index(TEMP, 0x1C)), BB1C)
Store (DerefOf(Index(TEMP, 0x1D)), BB1D)
Store (DerefOf(Index(TEMP, 0x1E)), BB1E)
Store (DerefOf(Index(TEMP, 0x1F)), BB1F)
}
}
}
}
```
在MaciASL中擴展了所有的節點,我們的工作如下:

## 解決錯誤(Resolving errors)
現在,我們需要開始使用外部的方法來解決錯誤,或者根據需要定義修補的EC字段。我們可以使用編譯器來提供幫助。單擊Compile將顯示第一個錯誤:“`3, 6085, Object not found or not accessible from scope (_SB.PCI0)`“,在這一行:
```
Scope (_SB.PCI0)
```
編譯器表明`_SB.PCI0`沒有被聲明,所以您不能在作用域操作符(Scope operator)中使用它。
我們需要向外部聲明它,因為作用域實際上是在另一個文件(`dsdt.aml`)中定義的:將它添加到文件的頂部
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
Scope (_SB.PCI0)
{
...
```
現在,下一個錯誤是“`Scope(BAT0)`”,因此,再一次:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
Scope (_SB.PCI0)
{
Scope (BAT0)
{
...
```
下一個錯誤是“`13, 6085, Object not found or not accessible from scope (^^LPCB.EC0.ACAP)`",我們可以從引用ACAP的代碼中看出它是一個方法:
```
If (^^LPCB.EC0.ACAP ())
```
注意:方法調用由`()`表示(本例中為空參數列表)。因此,我們知道我們可以添加一個外部的方法:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
...
}
```
注意:路徑`^^LPCB.EC0.ACAP`等于`_SB.PCI0.LPCB.EC0.ACAP`,因為引用在`_SB.PCI0.BAT0.FBST`(`FBST`方法的路徑)的范圍。每個`^`(父)操作符將當前的范圍由一個項向上移動,所以`^`表示了`_SB.PCI0.BAT0`。 `^^`表示了`_SB.PCI0`。
在某些情況下,您需要查看DSDT來查找給定標識符的路徑和/或類型。例如,下一個錯誤與`CHGS`有關。同樣,我們知道它是一個方法,因為它是方法調用的目標,但是對于路徑,我們必須參考`DSDT`:
```
Scope (\)
{
Method (CHGS, 1, Serialized)
{
Store (\_SB.PCI0.LPCB.EC0.BCHG (Arg0), Local0)
Return (Local0)
}
```
所以,它在根(root)中:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
...
```
下一個未定義的符號`BLLO`,是一種方法以外的東西:
```
If (BLLO)
{
```
在DSDT中,我們發現它是用名稱定義的(它恰好在根范圍(root scope)內):
```
Name (BLLO, Zero)
```
這使得它成為了一種IntObj:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
External(BLLO, IntObj)
...
```
修正`FBST`方法中的所有錯誤:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
External(BLLO, IntObj)
External(_SB.PCI0.LPCB.EC0.EB0S, FieldUnitObj)
External(_SB.PCI0.BAT0.PUNT, IntObj)
External(_SB.PCI0.LPCB.EC0.B0DV, FieldUnitObj)
External(_SB.PCI0.BAT0.LFCC, IntObj)
External(MBLF, IntObj)
External(_SB.PCI0.BAT0.PBST, PkgObj)
...
```
現在繼續這個過程。
最終,得到:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
External(BLLO, IntObj)
External(_SB.PCI0.LPCB.EC0.EB0S, FieldUnitObj)
External(_SB.PCI0.BAT0.PUNT, IntObj)
External(_SB.PCI0.LPCB.EC0.B0DV, FieldUnitObj)
External(_SB.PCI0.BAT0.LFCC, IntObj)
External(MBLF, IntObj)
External(_SB.PCI0.BAT0.PBST, PkgObj)
External(_SB.PCI0.LPCB.EC0.BATP, MethodObj)
External(_SB.PCI0.BAT0.NBIX, PkgObj)
External(_SB.PCI0.LPCB.EC0.GBTT, MethodObj)
External(_SB.PCI0.BAT0._BIF, MethodObj)
External(_SB.PCI0.BAT0.PBIF, PkgObj)
External(_SB.PCI0.BAT0.BIXT, PkgObj)
...
```
將會出現`XC30/XC31`的錯誤:“153, 6085, Object not found or not accessible from scope (^^LPCB.EC0.XC30)”
這是一個被一分為二的16位字段之一。
這就是創建EC覆蓋層(the EC overlay)的必要地方。
為此,我們在EC范圍內使用另一個OperationRegion,它的名稱與我們在DSDT中發現的名稱不同:
```
External(_SB.PCI0.LPCB, DeviceObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
Scope(_SB.PCI0.LPCB.EC0)
{
OperationRegion (ERM2, EmbeddedControl, Zero, 0xFF)
Field(ERM2, ByteAcc, NoLock, Preserve)
{
}
}
```
從`DSDT_patched.dsl`,我們可以得到各種補丁的字段(再次提到`diffmerge`)。這是`DSDT_patched.dsl`中來自`EC`的整個集合:
```
Offset (0x04),
CMD1, 8,
CDT1, 8,
CDT2, 8,
CDT3, 8,
Offset (0x80),
Offset (0x81),
Offset (0x82),
Offset (0x83),
EB0R, 8,
EB1R, 8,
EPWF, 8,
Offset (0x87),
Offset (0x88),
Offset (0x89),
Offset (0x8A),
HKEN, 1,
Offset (0x93),
TH00,8,TH01,8,
TH10,8,TH11,8,
TSTP, 8,
Offset (0x9C),
CDT4, 8,
CDT5, 8,
Offset (0xA0),
Offset (0xA1),
Offset (0xA2),
Offset (0xA3),
EACT, 8,
TH1R, 8,
TH1L, 8,
TH0R, 8,
TH0L, 8,
Offset (0xB0),
B0PN, 16,
Offset (0xB4),
Offset (0xB6),
Offset (0xB8),
Offset (0xBA),
Offset (0xBC),
Offset (0xBE),
B0TM, 16,
B0C1, 16,
B0C2, 16,
XC30,8,XC31,8,
B0C4, 16,
Offset (0xD0),
B1PN, 16,
Offset (0xD4),
Offset (0xD6),
Offset (0xD8),
Offset (0xDA),
Offset (0xDC),
Offset (0xDE),
B1TM, 16,
B1C1, 16,
B1C2, 16,
YC30,8,YC31,8,
B1C4, 16,
Offset (0xF0),
Offset (0xF2),
Offset (0xF4),
B0S0,8,B0S1,8,
Offset (0xF8),
Offset (0xFA),
Offset (0xFC),
B1S0,8,B1S1,8
```
如果我們去掉未修補的標識符,但是保持偏移量(offsets)正確(非常重要!):
```
Offset (0x93),
TH00,8,TH01,8,
TH10,8,TH11,8,
Offset (0xBE),
/*B0TM*/, 16,
/*B0C1*/, 16,
/*B0C2*/, 16,
XC30,8,XC31,8,
Offset (0xDE),
/*B1TM*/, 16,
/*B1C1*/, 16,
/*B1C2*/, 16,
YC30,8,YC31,8,
Offset (0xF4),
B0S0,8,B0S1,8,
Offset (0xFC),
B1S0,8,B1S1,8
```
同樣的事情可以寫成如下:
```
Offset (0x93),
TH00,8,TH01,8,
TH10,8,TH11,8,
Offset (0xc4),
XC30,8,XC31,8,
Offset (0xe4),
YC30,8,YC31,8,
Offset (0xF4),
B0S0,8,B0S1,8,
Offset (0xFC),
B1S0,8,B1S1,8
```
所以,加入到SSDT:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
External(BLLO, IntObj)
External(_SB.PCI0.LPCB.EC0.EB0S, FieldUnitObj)
External(_SB.PCI0.BAT0.PUNT, IntObj)
External(_SB.PCI0.LPCB.EC0.B0DV, FieldUnitObj)
External(_SB.PCI0.BAT0.LFCC, IntObj)
External(MBLF, IntObj)
External(_SB.PCI0.BAT0.PBST, PkgObj)
External(_SB.PCI0.LPCB.EC0.BATP, MethodObj)
External(_SB.PCI0.BAT0.NBIX, PkgObj)
External(_SB.PCI0.LPCB.EC0.GBTT, MethodObj)
External(_SB.PCI0.BAT0._BIF, MethodObj)
External(_SB.PCI0.BAT0.PBIF, PkgObj)
External(_SB.PCI0.BAT0.BIXT, PkgObj)
External(_SB.PCI0.LPCB, DeviceObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
Scope(_SB.PCI0.LPCB.EC0)
{
OperationRegion (ERM2, EmbeddedControl, Zero, 0xFF)
Field(ERM2, ByteAcc, NoLock, Preserve)
{
Offset (0x93),
TH00,8,TH01,8,
TH10,8,TH11,8,
Offset (0xc4),
XC30,8,XC31,8,
Offset (0xe4),
YC30,8,YC31,8,
Offset (0xF4),
B0S0,8,B0S1,8,
Offset (0xFC),
B1S0,8,B1S1,8
}
}
```
然后在修正更多錯誤的時候,我們增加了一些外部(External)的:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
External(BLLO, IntObj)
External(_SB.PCI0.LPCB.EC0.EB0S, FieldUnitObj)
External(_SB.PCI0.BAT0.PUNT, IntObj)
External(_SB.PCI0.LPCB.EC0.B0DV, FieldUnitObj)
External(_SB.PCI0.BAT0.LFCC, IntObj)
External(MBLF, IntObj)
External(_SB.PCI0.BAT0.PBST, PkgObj)
External(_SB.PCI0.LPCB.EC0.BATP, MethodObj)
External(_SB.PCI0.BAT0.NBIX, PkgObj)
External(_SB.PCI0.LPCB.EC0.GBTT, MethodObj)
External(_SB.PCI0.BAT0._BIF, MethodObj)
External(_SB.PCI0.BAT0.PBIF, PkgObj)
External(_SB.PCI0.BAT0.BIXT, PkgObj)
External(_SB.PCI0.LPCB.EC0.ECAV, MethodObj)
External(BSLF, IntObj)
External(_SB.PCI0.LPCB.EC0.RDBL, IntObj)
External(_SB.PCI0.LPCB.EC0.RDWD, IntObj)
External(_SB.PCI0.LPCB.EC0.RDBT, IntObj)
External(_SB.PCI0.LPCB.EC0.RCBT, IntObj)
External(_SB.PCI0.LPCB.EC0.RDQK, IntObj)
External(_SB.PCI0.LPCB.EC0.MUEC, MutexObj)
External(_SB.PCI0.LPCB.EC0.PRTC, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SBBY, IntObj)
External(_SB.PCI0.LPCB.EC0.ADDR, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.CMDB, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SWTC, MethodObj)
External(_SB.PCI0.LPCB.EC0.BCNT, FieldUnitObj)
External(_SB.PCI0.LPCB, DeviceObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
Scope(_SB.PCI0.LPCB.EC0)
{
...
```
然后我們有T2B0和T2B1的錯誤。這些又被分解為16位的`EC`字段,需要在我們的`EC`覆蓋層中定義。事實上,不妨定義我們所需要的剩余部分(來自diffmerge的數據)。
在SMBX中的補丁數據:
```
OperationRegion (SMBX, EmbeddedControl, 0x18, 0x28)
```
因此,我們創建了一個類似的覆蓋層,并有一個唯一的名稱:
```
OperationRegion (RMB1, EmbeddedControl, 0x18, 0x28)
Field (RMB1, ByteAcc, NoLock, Preserve)
{
/* Note: disabling these fields (already defined in DSDT, referenced with External if needed,
but keeping the correct offset! (very important!) */
/*
PRTC, 8,
SSTS, 5,
, 1,
ALFG, 1,
CDFG, 1,
ADDR, 8,
CMDB, 8, */
Offset(4), // the data above is 4 bytes offset from the start of this region!
//BDAT, 256,
BA00,8,BA01,8,BA02,8,BA03,8,
BA04,8,BA05,8,BA06,8,BA07,8,
BA08,8,BA09,8,BA0A,8,BA0B,8,
BA0C,8,BA0D,8,BA0E,8,BA0F,8,
BA10,8,BA11,8,BA12,8,BA13,8,
BA14,8,BA15,8,BA16,8,BA17,8,
BA18,8,BA19,8,BA1A,8,BA1B,8,
BA1C,8,BA1D,8,BA1E,8,BA1F,8
}
```
與 SMB2有類似的作用域:
```
OperationRegion(RMB2, EmbeddedControl, 0x40, 0x28)
Field (RMB2, ByteAcc, NoLock, Preserve)
{
/*
PRT2, 8,
SST2, 5,
, 1,
ALF2, 1,
CDF2, 1,
ADD2, 8,
CMD2, 8, */
Offset(4),
//BDA2, 256,
BB00,8,BB01,8,BB02,8,BB03,8,
BB04,8,BB05,8,BB06,8,BB07,8,
BB08,8,BB09,8,BB0A,8,BB0B,8,
BB0C,8,BB0D,8,BB0E,8,BB0F,8,
BB10,8,BB11,8,BB12,8,BB13,8,
BB14,8,BB15,8,BB16,8,BB17,8,
BB18,8,BB19,8,BB1A,8,BB1B,8,
BB1C,8,BB1D,8,BB1E,8,BB1F,8
}
```
`T2B0`和`T2B1` 存在于 原生的`SMBX`中,但現在`RMB1`是:
```
Field (RMB1, ByteAcc, NoLock, Preserve)
{
Offset (0x04),
T2B0,8,T2B1,8
}
```
就得到:
```
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
External(BLLO, IntObj)
External(_SB.PCI0.LPCB.EC0.EB0S, FieldUnitObj)
External(_SB.PCI0.BAT0.PUNT, IntObj)
External(_SB.PCI0.LPCB.EC0.B0DV, FieldUnitObj)
External(_SB.PCI0.BAT0.LFCC, IntObj)
External(MBLF, IntObj)
External(_SB.PCI0.BAT0.PBST, PkgObj)
External(_SB.PCI0.LPCB.EC0.BATP, MethodObj)
External(_SB.PCI0.BAT0.NBIX, PkgObj)
External(_SB.PCI0.LPCB.EC0.GBTT, MethodObj)
External(_SB.PCI0.BAT0._BIF, MethodObj)
External(_SB.PCI0.BAT0.PBIF, PkgObj)
External(_SB.PCI0.BAT0.BIXT, PkgObj)
External(_SB.PCI0.LPCB.EC0.ECAV, MethodObj)
External(BSLF, IntObj)
External(_SB.PCI0.LPCB.EC0.RDBL, IntObj)
External(_SB.PCI0.LPCB.EC0.RDWD, IntObj)
External(_SB.PCI0.LPCB.EC0.RDBT, IntObj)
External(_SB.PCI0.LPCB.EC0.RCBT, IntObj)
External(_SB.PCI0.LPCB.EC0.RDQK, IntObj)
External(_SB.PCI0.LPCB.EC0.MUEC, MutexObj)
External(_SB.PCI0.LPCB.EC0.PRTC, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SBBY, IntObj)
External(_SB.PCI0.LPCB.EC0.ADDR, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.CMDB, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SWTC, MethodObj)
External(_SB.PCI0.LPCB.EC0.BCNT, FieldUnitObj)
External(_SB.PCI0.LPCB, DeviceObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
Scope(_SB.PCI0.LPCB.EC0)
{
OperationRegion (ERM2, EmbeddedControl, Zero, 0xFF)
Field(ERM2, ByteAcc, NoLock, Preserve)
{
Offset (0x93),
TH00,8,TH01,8,
TH10,8,TH11,8,
Offset (0xc4),
XC30,8,XC31,8,
Offset (0xe4),
YC30,8,YC31,8,
Offset (0xF4),
B0S0,8,B0S1,8,
Offset (0xFC),
B1S0,8,B1S1,8
}
OperationRegion (RMB1, EmbeddedControl, 0x18, 0x28)
Field (RMB1, ByteAcc, NoLock, Preserve)
{
/* Note: disabling these fields (already defined in DSDT, referenced with External if needed,
but keeping the correct offset! (very important!) */
/*
PRTC, 8,
SSTS, 5,
, 1,
ALFG, 1,
CDFG, 1,
ADDR, 8,
CMDB, 8, */
Offset(4), // the data above is 4 bytes offset from the start of this region!
//BDAT, 256,
BA00,8,BA01,8,BA02,8,BA03,8,
BA04,8,BA05,8,BA06,8,BA07,8,
BA08,8,BA09,8,BA0A,8,BA0B,8,
BA0C,8,BA0D,8,BA0E,8,BA0F,8,
BA10,8,BA11,8,BA12,8,BA13,8,
BA14,8,BA15,8,BA16,8,BA17,8,
BA18,8,BA19,8,BA1A,8,BA1B,8,
BA1C,8,BA1D,8,BA1E,8,BA1F,8
}
OperationRegion(RMB2, EmbeddedControl, 0x40, 0x28)
Field (RMB2, ByteAcc, NoLock, Preserve)
{
/*
PRT2, 8,
SST2, 5,
, 1,
ALF2, 1,
CDF2, 1,
ADD2, 8,
CMD2, 8, */
Offset(4),
//BDA2, 256,
BB00,8,BB01,8,BB02,8,BB03,8,
BB04,8,BB05,8,BB06,8,BB07,8,
BB08,8,BB09,8,BB0A,8,BB0B,8,
BB0C,8,BB0D,8,BB0E,8,BB0F,8,
BB10,8,BB11,8,BB12,8,BB13,8,
BB14,8,BB15,8,BB16,8,BB17,8,
BB18,8,BB19,8,BB1A,8,BB1B,8,
BB1C,8,BB1D,8,BB1E,8,BB1F,8
}
Field (RMB1, ByteAcc, NoLock, Preserve)
{
Offset (0x04),
T2B0,8,T2B1,8
}
}
```
然后,通過添加這些外部聲明,繼續處理更多的外部錯誤(它最終會結束!):
```
External(_SB.PCI0.LPCB.EC0.DAT0, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.WRBL, IntObj)
External(_SB.PCI0.LPCB.EC0.WRWD, IntObj)
External(_SB.PCI0.LPCB.EC0.WRBT, IntObj)
External(_SB.PCI0.LPCB.EC0.SDBT, IntObj)
External(_SB.PCI0.LPCB.EC0.WRQK, IntObj)
External(_SB.PCI0.LPCB.EC0.PRT2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.DAT1, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.ADD2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.CMD2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.BCN2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.DA20, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.DA21, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SSTS, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SST2, FieldUnitObj)
```
注意:使用`DAT0`時,不要在不同的作用域內對“其他”的`DAT0`感到迷惑!
此時,SSDT編譯沒有任何錯誤:
```
DefinitionBlock("", "SSDT", 2, "hack", "batt", 0)
{
External(_SB.PCI0, DeviceObj)
External(_SB.PCI0.BAT0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.ACAP, MethodObj)
External(CHGS, MethodObj)
External(BLLO, IntObj)
External(_SB.PCI0.LPCB.EC0.EB0S, FieldUnitObj)
External(_SB.PCI0.BAT0.PUNT, IntObj)
External(_SB.PCI0.LPCB.EC0.B0DV, FieldUnitObj)
External(_SB.PCI0.BAT0.LFCC, IntObj)
External(MBLF, IntObj)
External(_SB.PCI0.BAT0.PBST, PkgObj)
External(_SB.PCI0.LPCB.EC0.BATP, MethodObj)
External(_SB.PCI0.BAT0.NBIX, PkgObj)
External(_SB.PCI0.LPCB.EC0.GBTT, MethodObj)
External(_SB.PCI0.BAT0._BIF, MethodObj)
External(_SB.PCI0.BAT0.PBIF, PkgObj)
External(_SB.PCI0.BAT0.BIXT, PkgObj)
External(_SB.PCI0.LPCB.EC0.ECAV, MethodObj)
External(BSLF, IntObj)
External(_SB.PCI0.LPCB.EC0.RDBL, IntObj)
External(_SB.PCI0.LPCB.EC0.RDWD, IntObj)
External(_SB.PCI0.LPCB.EC0.RDBT, IntObj)
External(_SB.PCI0.LPCB.EC0.RCBT, IntObj)
External(_SB.PCI0.LPCB.EC0.RDQK, IntObj)
External(_SB.PCI0.LPCB.EC0.MUEC, MutexObj)
External(_SB.PCI0.LPCB.EC0.PRTC, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SBBY, IntObj)
External(_SB.PCI0.LPCB.EC0.ADDR, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.CMDB, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SWTC, MethodObj)
External(_SB.PCI0.LPCB.EC0.BCNT, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.DAT0, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.WRBL, IntObj)
External(_SB.PCI0.LPCB.EC0.WRWD, IntObj)
External(_SB.PCI0.LPCB.EC0.WRBT, IntObj)
External(_SB.PCI0.LPCB.EC0.SDBT, IntObj)
External(_SB.PCI0.LPCB.EC0.WRQK, IntObj)
External(_SB.PCI0.LPCB.EC0.PRT2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.DAT1, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.ADD2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.CMD2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.BCN2, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.DA20, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.DA21, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SSTS, FieldUnitObj)
External(_SB.PCI0.LPCB.EC0.SST2, FieldUnitObj)
External(_SB.PCI0.LPCB, DeviceObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
Scope(_SB.PCI0.LPCB.EC0)
{
OperationRegion (ERM2, EmbeddedControl, Zero, 0xFF)
Field(ERM2, ByteAcc, NoLock, Preserve)
{
Offset (0x93),
TH00,8,TH01,8,
TH10,8,TH11,8,
Offset (0xc4),
XC30,8,XC31,8,
Offset (0xe4),
YC30,8,YC31,8,
Offset (0xF4),
B0S0,8,B0S1,8,
Offset (0xFC),
B1S0,8,B1S1,8
}
OperationRegion (RMB1, EmbeddedControl, 0x18, 0x28)
Field (RMB1, ByteAcc, NoLock, Preserve)
{
/* Note: disabling these fields (already defined in DSDT, referenced with External if needed,
but keeping the correct offset! (very important!) */
/*
PRTC, 8,
SSTS, 5,
, 1,
ALFG, 1,
CDFG, 1,
ADDR, 8,
CMDB, 8, */
Offset(4), // the data above is 4 bytes offset from the start of this region!
//BDAT, 256,
BA00,8,BA01,8,BA02,8,BA03,8,
BA04,8,BA05,8,BA06,8,BA07,8,
BA08,8,BA09,8,BA0A,8,BA0B,8,
BA0C,8,BA0D,8,BA0E,8,BA0F,8,
BA10,8,BA11,8,BA12,8,BA13,8,
BA14,8,BA15,8,BA16,8,BA17,8,
BA18,8,BA19,8,BA1A,8,BA1B,8,
BA1C,8,BA1D,8,BA1E,8,BA1F,8
}
OperationRegion(RMB2, EmbeddedControl, 0x40, 0x28)
Field (RMB2, ByteAcc, NoLock, Preserve)
{
/*
PRT2, 8,
SST2, 5,
, 1,
ALF2, 1,
CDF2, 1,
ADD2, 8,
CMD2, 8, */
Offset(4),
//BDA2, 256,
BB00,8,BB01,8,BB02,8,BB03,8,
BB04,8,BB05,8,BB06,8,BB07,8,
BB08,8,BB09,8,BB0A,8,BB0B,8,
BB0C,8,BB0D,8,BB0E,8,BB0F,8,
BB10,8,BB11,8,BB12,8,BB13,8,
BB14,8,BB15,8,BB16,8,BB17,8,
BB18,8,BB19,8,BB1A,8,BB1B,8,
BB1C,8,BB1D,8,BB1E,8,BB1F,8
}
Field (RMB1, ByteAcc, NoLock, Preserve)
{
Offset (0x04),
T2B0,8,T2B1,8
}
}
Scope (_SB.PCI0)
{
Scope (BAT0)
{
Method (FBST, 4, NotSerialized)
{
And (Arg1, 0xFFFF, Local1)
Store (Zero, Local0)
If (^^LPCB.EC0.ACAP ())
{
Store (One, Local0)
}
If (Local0)
{
If (CHGS (Zero))
{
Store (0x02, Local0)
}
Else
{
Store (Zero, Local0)
}
}
Else
{
Store (One, Local0)
}
If (BLLO)
{
ShiftLeft (One, 0x02, Local2)
Or (Local0, Local2, Local0)
}
If (And (^^LPCB.EC0.EB0S, 0x08))
{
ShiftLeft (One, 0x02, Local2)
Or (Local0, Local2, Local0)
}
If (LGreaterEqual (Local1, 0x8000))
{
Subtract (0xFFFF, Local1, Local1)
}
Store (Arg2, Local2)
If (LEqual (PUNT, Zero))
{
Multiply (Local1, ^^LPCB.EC0.B0DV, Local1)
Multiply (Local2, 0x0A, Local2)
}
And (Local0, 0x02, Local3)
If (LNot (Local3))
{
Subtract (LFCC, Local2, Local3)
Divide (LFCC, 0xC8, Local4, Local5)
If (LLess (Local3, Local5))
{
Store (LFCC, Local2)
}
}
Else
{
Divide (LFCC, 0xC8, Local4, Local5)
Subtract (LFCC, Local5, Local4)
If (LGreater (Local2, Local4))
{
Store (Local4, Local2)
}
}
If (LNot (^^LPCB.EC0.ACAP ()))
{
Divide (Local2, MBLF, Local3, Local4)
If (LLess (Local1, Local4))
{
Store (Local4, Local1)
}
}
Store (Local0, Index (PBST, Zero))
Store (Local1, Index (PBST, One))
Store (Local2, Index (PBST, 0x02))
Store (Arg3, Index (PBST, 0x03))
}
Method (_BIX, 0, NotSerialized) // _BIX: Battery Information Extended
{
If (LNot (^^LPCB.EC0.BATP (Zero)))
{
Return (NBIX)
}
If (LEqual (^^LPCB.EC0.GBTT (Zero), 0xFF))
{
Return (NBIX)
}
_BIF ()
Store (DerefOf (Index (PBIF, Zero)), Index (BIXT, One))
Store (DerefOf (Index (PBIF, One)), Index (BIXT, 0x02))
Store (DerefOf (Index (PBIF, 0x02)), Index (BIXT, 0x03))
Store (DerefOf (Index (PBIF, 0x03)), Index (BIXT, 0x04))
Store (DerefOf (Index (PBIF, 0x04)), Index (BIXT, 0x05))
Store (DerefOf (Index (PBIF, 0x05)), Index (BIXT, 0x06))
Store (DerefOf (Index (PBIF, 0x06)), Index (BIXT, 0x07))
Store (DerefOf (Index (PBIF, 0x07)), Index (BIXT, 0x0E))
Store (DerefOf (Index (PBIF, 0x08)), Index (BIXT, 0x0F))
Store (DerefOf (Index (PBIF, 0x09)), Index (BIXT, 0x10))
Store (DerefOf (Index (PBIF, 0x0A)), Index (BIXT, 0x11))
Store (DerefOf (Index (PBIF, 0x0B)), Index (BIXT, 0x12))
Store (DerefOf (Index (PBIF, 0x0C)), Index (BIXT, 0x13))
If (LEqual (DerefOf (Index (BIXT, One)), One))
{
Store (Zero, Index (BIXT, One))
Store (DerefOf (Index (BIXT, 0x05)), Local0)
Multiply (DerefOf (Index (BIXT, 0x02)), Local0, Index (BIXT, 0x02))
Multiply (DerefOf (Index (BIXT, 0x03)), Local0, Index (BIXT, 0x03))
Multiply (DerefOf (Index (BIXT, 0x06)), Local0, Index (BIXT, 0x06))
Multiply (DerefOf (Index (BIXT, 0x07)), Local0, Index (BIXT, 0x07))
Multiply (DerefOf (Index (BIXT, 0x0E)), Local0, Index (BIXT, 0x0E))
Multiply (DerefOf (Index (BIXT, 0x0F)), Local0, Index (BIXT, 0x0F))
Divide (DerefOf (Index (BIXT, 0x02)), 0x03E8, Local0, Index (BIXT, 0x02))
Divide (DerefOf (Index (BIXT, 0x03)), 0x03E8, Local0, Index (BIXT, 0x03))
Divide (DerefOf (Index (BIXT, 0x06)), 0x03E8, Local0, Index (BIXT, 0x06))
Divide (DerefOf (Index (BIXT, 0x07)), 0x03E8, Local0, Index (BIXT, 0x07))
Divide (DerefOf (Index (BIXT, 0x0E)), 0x03E8, Local0, Index (BIXT, 0x0E))
Divide (DerefOf (Index (BIXT, 0x0F)), 0x03E8, Local0, Index (BIXT, 0x0F))
}
Store (B1B2(^^LPCB.EC0.XC30,^^LPCB.EC0.XC31), Index (BIXT, 0x08))
Store (0x0001869F, Index (BIXT, 0x09))
Return (BIXT)
}
}
}
Scope (_SB.PCI0.LPCB.EC0)
{
Method (BIFA, 0, NotSerialized)
{
If (ECAV ())
{
If (BSLF)
{
Store (B1B2(B1S0,B1S1), Local0)
}
Else
{
Store (B1B2(B0S0,B0S1), Local0)
}
}
Else
{
Store (Ones, Local0)
}
Return (Local0)
}
Method (SMBR, 3, Serialized)
{
Store (Package (0x03)
{
0x07,
Zero,
Zero
}, Local0)
If (LNot (ECAV ()))
{
Return (Local0)
}
If (LNotEqual (Arg0, RDBL))
{
If (LNotEqual (Arg0, RDWD))
{
If (LNotEqual (Arg0, RDBT))
{
If (LNotEqual (Arg0, RCBT))
{
If (LNotEqual (Arg0, RDQK))
{
Return (Local0)
}
}
}
}
}
Acquire (MUEC, 0xFFFF)
Store (PRTC, Local1)
Store (Zero, Local2)
While (LNotEqual (Local1, Zero))
{
Stall (0x0A)
Increment (Local2)
If (LGreater (Local2, 0x03E8))
{
Store (SBBY, Index (Local0, Zero))
Store (Zero, Local1)
}
Else
{
Store (PRTC, Local1)
}
}
If (LLessEqual (Local2, 0x03E8))
{
ShiftLeft (Arg1, One, Local3)
Or (Local3, One, Local3)
Store (Local3, ADDR)
If (LNotEqual (Arg0, RDQK))
{
If (LNotEqual (Arg0, RCBT))
{
Store (Arg2, CMDB)
}
}
WRBA(Zero)
Store (Arg0, PRTC)
Store (SWTC (Arg0), Index (Local0, Zero))
If (LEqual (DerefOf (Index (Local0, Zero)), Zero))
{
If (LEqual (Arg0, RDBL))
{
Store (BCNT, Index (Local0, One))
Store (RDBA(), Index (Local0, 0x02))
}
If (LEqual (Arg0, RDWD))
{
Store (0x02, Index (Local0, One))
Store (B1B2(T2B0,T2B1), Index (Local0, 0x02))
}
If (LEqual (Arg0, RDBT))
{
Store (One, Index (Local0, One))
Store (DAT0, Index (Local0, 0x02))
}
If (LEqual (Arg0, RCBT))
{
Store (One, Index (Local0, One))
Store (DAT0, Index (Local0, 0x02))
}
}
}
Release (MUEC)
Return (Local0)
}
Method (SMBW, 5, Serialized)
{
Store (Package (0x01)
{
0x07
}, Local0)
If (LNot (ECAV ()))
{
Return (Local0)
}
If (LNotEqual (Arg0, WRBL))
{
If (LNotEqual (Arg0, WRWD))
{
If (LNotEqual (Arg0, WRBT))
{
If (LNotEqual (Arg0, SDBT))
{
If (LNotEqual (Arg0, WRQK))
{
Return (Local0)
}
}
}
}
}
Acquire (MUEC, 0xFFFF)
Store (PRTC, Local1)
Store (Zero, Local2)
While (LNotEqual (Local1, Zero))
{
Stall (0x0A)
Increment (Local2)
If (LGreater (Local2, 0x03E8))
{
Store (SBBY, Index (Local0, Zero))
Store (Zero, Local1)
}
Else
{
Store (PRTC, Local1)
}
}
If (LLessEqual (Local2, 0x03E8))
{
WRBA(Zero)
ShiftLeft (Arg1, One, Local3)
Store (Local3, ADDR)
If (LNotEqual (Arg0, WRQK))
{
If (LNotEqual (Arg0, SDBT))
{
Store (Arg2, CMDB)
}
}
If (LEqual (Arg0, WRBL))
{
Store (Arg3, BCNT)
WRBA(Arg4)
}
If (LEqual (Arg0, WRWD))
{
Store(Arg4,T2B0) Store(ShiftRight(Arg4,8),T2B1)
}
If (LEqual (Arg0, WRBT))
{
Store (Arg4, DAT0)
}
If (LEqual (Arg0, SDBT))
{
Store (Arg4, DAT0)
}
Store (Arg0, PRTC)
Store (SWTC (Arg0), Index (Local0, Zero))
}
Release (MUEC)
Return (Local0)
}
Method (ECSB, 7, NotSerialized)
{
Store (Package (0x05)
{
0x11,
Zero,
Zero,
Zero,
Buffer (0x20){}
}, Local1)
If (LGreater (Arg0, One))
{
Return (Local1)
}
If (ECAV ())
{
Acquire (MUEC, 0xFFFF)
If (LEqual (Arg0, Zero))
{
Store (PRTC, Local0)
}
Else
{
Store (PRT2, Local0)
}
Store (Zero, Local2)
While (LNotEqual (Local0, Zero))
{
Stall (0x0A)
Increment (Local2)
If (LGreater (Local2, 0x03E8))
{
Store (SBBY, Index (Local1, Zero))
Store (Zero, Local0)
}
ElseIf (LEqual (Arg0, Zero))
{
Store (PRTC, Local0)
}
Else
{
Store (PRT2, Local0)
}
}
If (LLessEqual (Local2, 0x03E8))
{
If (LEqual (Arg0, Zero))
{
Store (Arg2, ADDR)
Store (Arg3, CMDB)
If (LOr (LEqual (Arg1, 0x0A), LEqual (Arg1, 0x0B)))
{
Store (DerefOf (Index (Arg6, Zero)), BCNT)
WRBA(DerefOf (Index (Arg6, One)))
}
Else
{
Store (Arg4, DAT0)
Store (Arg5, DAT1)
}
Store (Arg1, PRTC)
}
Else
{
Store (Arg2, ADD2)
Store (Arg3, CMD2)
If (LOr (LEqual (Arg1, 0x0A), LEqual (Arg1, 0x0B)))
{
Store (DerefOf (Index (Arg6, Zero)), BCN2)
WRBB(DerefOf (Index (Arg6, One)))
}
Else
{
Store (Arg4, DA20)
Store (Arg5, DA21)
}
Store (Arg1, PRT2)
}
Store (0x7F, Local0)
If (LEqual (Arg0, Zero))
{
While (PRTC)
{
Sleep (One)
Decrement (Local0)
}
}
Else
{
While (PRT2)
{
Sleep (One)
Decrement (Local0)
}
}
If (Local0)
{
If (LEqual (Arg0, Zero))
{
Store (SSTS, Local0)
Store (DAT0, Index (Local1, One))
Store (DAT1, Index (Local1, 0x02))
Store (BCNT, Index (Local1, 0x03))
Store (RDBA(), Index (Local1, 0x04))
}
Else
{
Store (SST2, Local0)
Store (DA20, Index (Local1, One))
Store (DA21, Index (Local1, 0x02))
Store (BCN2, Index (Local1, 0x03))
Store (RDBB(), Index (Local1, 0x04))
}
And (Local0, 0x1F, Local0)
If (Local0)
{
Add (Local0, 0x10, Local0)
}
Store (Local0, Index (Local1, Zero))
}
Else
{
Store (0x10, Index (Local1, Zero))
}
}
Release (MUEC)
}
Return (Local1)
}
Method (TACH, 1, Serialized)
{
If (ECAV ())
{
Switch (Arg0)
{
Case (Zero)
{
Store (B1B2(TH00,TH01), Local0)
Break
}
Case (One)
{
Store (B1B2(TH10,TH11), Local0)
Break
}
Default
{
Return (Ones)
}
}
Multiply (Local0, 0x02, Local0)
If (LNotEqual (Local0, Zero))
{
Divide (0x0041CDB4, Local0, Local1, Local0)
Return (Local0)
}
Else
{
Return (Ones)
}
}
Else
{
Return (Ones)
}
}
}
Method (B1B2, 2, NotSerialized) { Return (Or (Arg0, ShiftLeft (Arg1, 8))) }
Scope (_SB.PCI0.LPCB)
{
Scope (EC0)
{
Method (RDBA, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BA00, Index(TEMP, 0x00))
Store (BA01, Index(TEMP, 0x01))
Store (BA02, Index(TEMP, 0x02))
Store (BA03, Index(TEMP, 0x03))
Store (BA04, Index(TEMP, 0x04))
Store (BA05, Index(TEMP, 0x05))
Store (BA06, Index(TEMP, 0x06))
Store (BA07, Index(TEMP, 0x07))
Store (BA08, Index(TEMP, 0x08))
Store (BA09, Index(TEMP, 0x09))
Store (BA0A, Index(TEMP, 0x0A))
Store (BA0B, Index(TEMP, 0x0B))
Store (BA0C, Index(TEMP, 0x0C))
Store (BA0D, Index(TEMP, 0x0D))
Store (BA0E, Index(TEMP, 0x0E))
Store (BA0F, Index(TEMP, 0x0F))
Store (BA10, Index(TEMP, 0x10))
Store (BA11, Index(TEMP, 0x11))
Store (BA12, Index(TEMP, 0x12))
Store (BA13, Index(TEMP, 0x13))
Store (BA14, Index(TEMP, 0x14))
Store (BA15, Index(TEMP, 0x15))
Store (BA16, Index(TEMP, 0x16))
Store (BA17, Index(TEMP, 0x17))
Store (BA18, Index(TEMP, 0x18))
Store (BA19, Index(TEMP, 0x19))
Store (BA1A, Index(TEMP, 0x1A))
Store (BA1B, Index(TEMP, 0x1B))
Store (BA1C, Index(TEMP, 0x1C))
Store (BA1D, Index(TEMP, 0x1D))
Store (BA1E, Index(TEMP, 0x1E))
Store (BA1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBA, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BA00)
Store (DerefOf(Index(TEMP, 0x01)), BA01)
Store (DerefOf(Index(TEMP, 0x02)), BA02)
Store (DerefOf(Index(TEMP, 0x03)), BA03)
Store (DerefOf(Index(TEMP, 0x04)), BA04)
Store (DerefOf(Index(TEMP, 0x05)), BA05)
Store (DerefOf(Index(TEMP, 0x06)), BA06)
Store (DerefOf(Index(TEMP, 0x07)), BA07)
Store (DerefOf(Index(TEMP, 0x08)), BA08)
Store (DerefOf(Index(TEMP, 0x09)), BA09)
Store (DerefOf(Index(TEMP, 0x0A)), BA0A)
Store (DerefOf(Index(TEMP, 0x0B)), BA0B)
Store (DerefOf(Index(TEMP, 0x0C)), BA0C)
Store (DerefOf(Index(TEMP, 0x0D)), BA0D)
Store (DerefOf(Index(TEMP, 0x0E)), BA0E)
Store (DerefOf(Index(TEMP, 0x0F)), BA0F)
Store (DerefOf(Index(TEMP, 0x10)), BA10)
Store (DerefOf(Index(TEMP, 0x11)), BA11)
Store (DerefOf(Index(TEMP, 0x12)), BA12)
Store (DerefOf(Index(TEMP, 0x13)), BA13)
Store (DerefOf(Index(TEMP, 0x14)), BA14)
Store (DerefOf(Index(TEMP, 0x15)), BA15)
Store (DerefOf(Index(TEMP, 0x16)), BA16)
Store (DerefOf(Index(TEMP, 0x17)), BA17)
Store (DerefOf(Index(TEMP, 0x18)), BA18)
Store (DerefOf(Index(TEMP, 0x19)), BA19)
Store (DerefOf(Index(TEMP, 0x1A)), BA1A)
Store (DerefOf(Index(TEMP, 0x1B)), BA1B)
Store (DerefOf(Index(TEMP, 0x1C)), BA1C)
Store (DerefOf(Index(TEMP, 0x1D)), BA1D)
Store (DerefOf(Index(TEMP, 0x1E)), BA1E)
Store (DerefOf(Index(TEMP, 0x1F)), BA1F)
}
Method (RDBB, 0, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (BB00, Index(TEMP, 0x00))
Store (BB01, Index(TEMP, 0x01))
Store (BB02, Index(TEMP, 0x02))
Store (BB03, Index(TEMP, 0x03))
Store (BB04, Index(TEMP, 0x04))
Store (BB05, Index(TEMP, 0x05))
Store (BB06, Index(TEMP, 0x06))
Store (BB07, Index(TEMP, 0x07))
Store (BB08, Index(TEMP, 0x08))
Store (BB09, Index(TEMP, 0x09))
Store (BB0A, Index(TEMP, 0x0A))
Store (BB0B, Index(TEMP, 0x0B))
Store (BB0C, Index(TEMP, 0x0C))
Store (BB0D, Index(TEMP, 0x0D))
Store (BB0E, Index(TEMP, 0x0E))
Store (BB0F, Index(TEMP, 0x0F))
Store (BB10, Index(TEMP, 0x10))
Store (BB11, Index(TEMP, 0x11))
Store (BB12, Index(TEMP, 0x12))
Store (BB13, Index(TEMP, 0x13))
Store (BB14, Index(TEMP, 0x14))
Store (BB15, Index(TEMP, 0x15))
Store (BB16, Index(TEMP, 0x16))
Store (BB17, Index(TEMP, 0x17))
Store (BB18, Index(TEMP, 0x18))
Store (BB19, Index(TEMP, 0x19))
Store (BB1A, Index(TEMP, 0x1A))
Store (BB1B, Index(TEMP, 0x1B))
Store (BB1C, Index(TEMP, 0x1C))
Store (BB1D, Index(TEMP, 0x1D))
Store (BB1E, Index(TEMP, 0x1E))
Store (BB1F, Index(TEMP, 0x1F))
Return (TEMP)
}
Method (WRBB, 1, Serialized)
{
Name (TEMP, Buffer(0x20) { })
Store (Arg0, TEMP)
Store (DerefOf(Index(TEMP, 0x00)), BB00)
Store (DerefOf(Index(TEMP, 0x01)), BB01)
Store (DerefOf(Index(TEMP, 0x02)), BB02)
Store (DerefOf(Index(TEMP, 0x03)), BB03)
Store (DerefOf(Index(TEMP, 0x04)), BB04)
Store (DerefOf(Index(TEMP, 0x05)), BB05)
Store (DerefOf(Index(TEMP, 0x06)), BB06)
Store (DerefOf(Index(TEMP, 0x07)), BB07)
Store (DerefOf(Index(TEMP, 0x08)), BB08)
Store (DerefOf(Index(TEMP, 0x09)), BB09)
Store (DerefOf(Index(TEMP, 0x0A)), BB0A)
Store (DerefOf(Index(TEMP, 0x0B)), BB0B)
Store (DerefOf(Index(TEMP, 0x0C)), BB0C)
Store (DerefOf(Index(TEMP, 0x0D)), BB0D)
Store (DerefOf(Index(TEMP, 0x0E)), BB0E)
Store (DerefOf(Index(TEMP, 0x0F)), BB0F)
Store (DerefOf(Index(TEMP, 0x10)), BB10)
Store (DerefOf(Index(TEMP, 0x11)), BB11)
Store (DerefOf(Index(TEMP, 0x12)), BB12)
Store (DerefOf(Index(TEMP, 0x13)), BB13)
Store (DerefOf(Index(TEMP, 0x14)), BB14)
Store (DerefOf(Index(TEMP, 0x15)), BB15)
Store (DerefOf(Index(TEMP, 0x16)), BB16)
Store (DerefOf(Index(TEMP, 0x17)), BB17)
Store (DerefOf(Index(TEMP, 0x18)), BB18)
Store (DerefOf(Index(TEMP, 0x19)), BB19)
Store (DerefOf(Index(TEMP, 0x1A)), BB1A)
Store (DerefOf(Index(TEMP, 0x1B)), BB1B)
Store (DerefOf(Index(TEMP, 0x1C)), BB1C)
Store (DerefOf(Index(TEMP, 0x1D)), BB1D)
Store (DerefOf(Index(TEMP, 0x1E)), BB1E)
Store (DerefOf(Index(TEMP, 0x1F)), BB1F)
}
}
}
}
//EOF
```
最后文件可以保存為AML(建議名稱:`SSDT-BATT.aml`),并放置在`ACPI/patched`中。
但是你不能期望電池狀態與原生的DSDT一起工作。
## 重新命名現有的方法(Renaming existing methods)
在DSDT和這個`SSDT-BATT.aml`中有重復的方法。對于DSDT中的每個方法,`SSDT-BATT.aml`版本將替換,我們必須將DSDT中的方法重命名為其他的,來允許SSDT版本進行重載(override)。
就像在第一篇文章中一樣,這個部分遵循“Rename/Replace”模式。
需要替換的方法有FBST、_BIX、BIFA、SMBR、SMBW、ECSB和TACH。
對于這個步驟,為原生的`dsdt.aml`創建一個混合字節碼列表非常有用。
它可以用:“`iasl -l -dl DSDT`”來創建,會在在`dsdt.dsl`中創建一個混合列表。
FBST的方法:
```
Method (FBST, 4, NotSerialized)
{
And (Arg1, 0xFFFF, Local1)
Store (Zero, Local0)
FF74: 14 43 12 46 42 53 54 04 7B 69 0B FF FF 61 70 00 // .C.FBST.{i...ap.
FF84: 60
```
一個可能的重命名補丁 (`FBST->XBST`):
~~~
Find: <46 42 53 54 04>
Replace: <58 42 53 54 04>
~~~
通過在`hex Fiend`這樣的hex編輯器中搜索,驗證找到的十六進制數據只有一個匹配,這是一個好主意。
因為這個補丁**只**適用于方法定義,而不是其他可能出現在`DSDT`(或原生的`SSDTs`)中的代碼。
您選擇的目標名稱必須在該方法所在的范圍內惟一。創建重復的方法會引起內核恐慌(kernel panic)。把第一個字母改成' X '通常是可以的,但不能保證。
其他方法的補丁:
~~~
_BIX->XBIX:
Find: <5F 42 49 58 00>
Replace: <58 42 49 58 00>
BIFA->XIFA:
Find: <42 49 46 41 00>
Replace: <58 49 46 41 00>
SMBR->XMBR:
Find: <53 4D 42 52 0B>
Replace: <58 4D 42 52 0B>
SMBW->XMBW:
Find: <53 4D 42 57 0D>
Replace: <58 4D 42 57 0D>
ECSB->XCSB:
Find: <45 43 53 42 07>
Replace: <58 43 53 42 07>
TACH->XACH:
Find: <54 41 43 48 09>
Replace: <58 41 43 48 09>
~~~
將這些補丁添加到`config.plist/ACPI/DSDT/Patches`,原生的DSDT的方法將被Clover重命名。由于重命名,所以會使在`SSDT-BATT.aml`中定義的已經打了補丁的方法被重載(override)。
## 總結(Conclusion)
電池狀態的熱修補可能是最復雜的熱補丁操作之一。寫所有“外部”參考的過程是冗長乏味的。
這需要一些時間(你在這里閱讀的文本要花上幾個小時)。慢慢看吧~。
# =======================
# 使用Hotpatch 來禁用獨顯(Disabling discrete)/切換GPU
這第三個帖子專門用于在一個切換的雙GPU筆記本中禁用獨顯,使用的是相同的示例ACPI 文件作為靜態補丁指南:https://www.tonymacx86.com/threads/guide-disabling-discrete-graphics-in-dual-gpu-laptops.163772/ 。
您應該下載附加到該指南的 ACPI/origin文件, 以便您跟著我一起做。
與靜態補丁指南一樣,目的是相對簡單:在ACPI初始化過程中,為獨立的GPU調用`_OFF`方法(來自`_INI`方法)。
但是由于`_OFF`可以包含`EC`相關的代碼,而這些代碼需要在`_REG`中執行,而不是`_INI`,所以這些細節使得它更加復雜。
## 構建替換`_INI/_OFF/_REG`方法(Building the replacement _INI/_OFF/_REG methods)
在這個例子中,目標`_INI`方法在`SSDT-7`中,`_OFF`方法在`SSDT-8`中。這個獨顯設備的路徑是`_SB.PCI0.RP05.PEGP`。在示例文件中,`_OFF`包含的`EC`相關代碼必須移動到`_REG`。為了完成這個補丁程序,我們需要替換`_INI`、`_OFF`和`_REG`,因此每個都需要重新命名為`XINI`、`XOFF`和`XREG`。
注意:實際上您需要修補的方法可能是不同的。這完全取決于`_OFF`路徑中的代碼。例如,在其他ACPI集合中,碰巧地`SGOF`(可能是其他名稱)有`EC`相關的代碼,而這些代碼又必須移動到`_REG`。在這種情況下,您需要為這個`SGOF`使用rename/replace,也許不需要使用`_OFF`方法。仔細分析你現有的代碼。
Clover的`config.plist`中補丁將會在后面進行。現在,讓我們來看一下替換方法的SSDT:
這SSDT將包括打了補丁的方法:
```
DefinitionBlock("", "SSDT", 2, "hack", "D-GPU", 0)
{
External(_SB.PCI0.RP05.PEGP, DeviceObj)
External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
External(_SB.PCI0.RP05.PEGP.XOFF, MethodObj)
External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.XREG, MethodObj)
External(_SB.PCI0.LPCB.EC0.SPIN, MethodObj)
Scope(_SB.PCI0.RP05.PEGP)
{
Method(_INI)
{
XINI() // call original _INI, now renamed XINI
_OFF() // call (patched) _OFF
}
Method(_OFF, 0, Serialized)
{
If (LEqual (CTXT, Zero))
{
/* \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) */
If (LNotEqual (GPRF, One))
{
Store (VGAR, VGAB)
}
Store (One, CTXT)
}
SGOF ()
}
}
Scope(_SB.PCI0.LPCB.EC0)
{
Method(_REG, 2)
{
XREG(Arg0, Arg1) // call original _REG, now renamed XREG
If (3 == Arg0 && 1 == Arg1) // EC ready?
{
\_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) // code that was removed from _OFF
}
}
}
}
```
此時,代碼不會編譯,因為在`_OFF`中引用的一些符號是不可用的。就像電池打補丁指南一樣,我們必須添加適當的外部聲明。
使用編譯器產生的錯誤來確定需要查找的符號,然后添加適當的外部聲明。在這個示例案例:
```
External(_SB.PCI0.RP05.PEGP.CTXT, IntObj)
External(_SB.PCI0.RP05.PEGP.GPRF, IntObj)
External(_SB.PCI0.RP05.PEGP.VGAR, FieldUnitObj)
External(_SB.PCI0.RP05.PEGP.VGAB, BuffObj)
External(_SB.PCI0.RP05.PEGP.SGOF, MethodObj)
```
然后結果的SSDT:
```
DefinitionBlock("", "SSDT", 2, "hack", "D-GPU", 0)
{
External(_SB.PCI0.RP05.PEGP, DeviceObj)
External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
External(_SB.PCI0.RP05.PEGP.XOFF, MethodObj)
External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.XREG, MethodObj)
External(_SB.PCI0.LPCB.EC0.SPIN, MethodObj)
External(_SB.PCI0.RP05.PEGP.CTXT, IntObj)
External(_SB.PCI0.RP05.PEGP.GPRF, IntObj)
External(_SB.PCI0.RP05.PEGP.VGAR, FieldUnitObj)
External(_SB.PCI0.RP05.PEGP.VGAB, BuffObj)
External(_SB.PCI0.RP05.PEGP.SGOF, MethodObj)
Scope(_SB.PCI0.RP05.PEGP)
{
Method(_INI)
{
XINI() // call original _INI, now renamed XINI
_OFF() // call (patched) _OFF
}
Method(_OFF, 0, Serialized)
{
If (LEqual (CTXT, Zero))
{
/* \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) */
If (LNotEqual (GPRF, One))
{
Store (VGAR, VGAB)
}
Store (One, CTXT)
}
SGOF ()
}
}
Scope(_SB.PCI0.LPCB.EC0)
{
Method(_REG, 2)
{
XREG(Arg0, Arg1) // call original _REG, now renamed XREG
If (3 == Arg0 && 1 == Arg1) // EC ready?
{
\_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) // code that was removed from _OFF
}
}
}
}
```
現在編譯沒有錯誤,但是有一個警告:"`39, 3079, _REG has no corresponding Operation Region`"。這個警告很重要。除非我們添加一個假冒的EC操作區域(EC OperationRegion),否則不會調用`_REG`。
我們來添加它:
```
...
Scope(_SB.PCI0.LPCB.EC0)
{
OperationRegion(RME3, EmbeddedControl, 0x00, 0xFF)
Method(_REG, 2)
{
...
```
然后完整的SSDT:
```
DefinitionBlock("", "SSDT", 2, "hack", "D-GPU", 0)
{
External(_SB.PCI0.RP05.PEGP, DeviceObj)
External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
External(_SB.PCI0.RP05.PEGP.XOFF, MethodObj)
External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
External(_SB.PCI0.LPCB.EC0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.XREG, MethodObj)
External(_SB.PCI0.LPCB.EC0.SPIN, MethodObj)
External(_SB.PCI0.RP05.PEGP.CTXT, IntObj)
External(_SB.PCI0.RP05.PEGP.GPRF, IntObj)
External(_SB.PCI0.RP05.PEGP.VGAR, FieldUnitObj)
External(_SB.PCI0.RP05.PEGP.VGAB, BuffObj)
External(_SB.PCI0.RP05.PEGP.SGOF, MethodObj)
Scope(_SB.PCI0.RP05.PEGP)
{
Method(_INI)
{
XINI() // call original _INI, now renamed XINI
_OFF() // call (patched) _OFF
}
Method(_OFF, 0, Serialized)
{
If (LEqual (CTXT, Zero))
{
/* \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) */
If (LNotEqual (GPRF, One))
{
Store (VGAR, VGAB)
}
Store (One, CTXT)
}
SGOF ()
}
}
Scope(_SB.PCI0.LPCB.EC0)
{
OperationRegion(RME3, EmbeddedControl, 0x00, 0xFF)
Method(_REG, 2)
{
XREG(Arg0, Arg1) // call original _REG, now renamed XREG
If (3 == Arg0 && 1 == Arg1) // EC ready?
{
\_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) // code that was removed from _OFF
}
}
}
}
```
此時,您可以保存SSDT(建議:`SSDT-DGPU.aml`)。
準備好放入`ACPI/patched`。
但是我們仍然需要在原生的`ACPI`中重命名原始方法。
## 重命名方法
如前所述,以下方法需要重新命名:
~~~
_SB.PCI0.RP05.PEGP._INI -> XINI
_SB.PCI0.RP05.PEGP._OFF -> XOFF
_SB.PCI0.LPCB.EC0._REG -> XREG
~~~
為了確定所需的二進制補丁,我們需要一個DSDT的混合列表`DSDT.aml`, `SSDT-7.aml`, 和 `SSDT-8.aml`。
用下面的方法創建:
~~~
iasl -dl -l DSDT.aml SSDT-7.aml SSDT-8.aml
~~~
產生的混合列表在`DSDT.dsl`, `SSDT-7.dsl`, 和 `SSDT-8.dsl`中。
這里是`DSDT.dsl`中的`_REG`的混合清單
```
Method (_REG, 2, NotSerialized) // _REG: Region Availability
{
D2B8: 14 12 5F 52 45 47 02 // .._REG.
If (LEqual (Arg0, 0x03))
{
D2BF: A0 0B 93 68 0A 03 // ...h..
Store (Arg1, ECFL)
}
}
}
}
D2C5: 70 69 45 43 46 4C
```
使用的補丁應該只重命名這個`_REG`,而不是ACPI集中的其他`_REG`方法。我們可以通過從代碼中獲取名稱/頭(name/header )加上幾個字節(bytes)來重命名它。
這個模式可以獲取足夠的字節來唯一確定:
```
Find: <5F 52 45 47 02 A0 0B 93 68 0A 03 70 69 45 43 46 4C>
Replace: <58 52 45 47 02 A0 0B 93 68 0A 03 70 69 45 43 46 4C>
```
`SSDT-7.dsl`的`_INI`方法的混合列表:
```
Method (_INI, 0, NotSerialized) // _INI: Initialize
{
03D1: 14 1F 5F 49 4E 49 00 // .._INI.
Store (Zero, \_SB.PCI0.RP05.PEGP._ADR)
}
03D8: 70 00 5C 2F 05 5F 53 42 5F 50 43 49 30 52 50 30 // p.\/._SB_PCI0RP0
03E8: 35 50 45 47 50 5F 41 44 52 // 5PEGP_ADR
```
產生的補丁...
~~~
Find: <5F 49 4E 49 00 70 00 5C 2F 05 5F 53 42 5F 50 43 49 30 52 50 30 35 50 45 47 50>
Replace: <58 49 4E 49 00 70 00 5C 2F 05 5F 53 42 5F 50 43 49 30 52 50 30 35 50 45 47 50>
~~~
再來看`SSDT-8.dsl`中的`_OFF`:
```
Method (_OFF, 0, Serialized) // _OFF: Power Off
{
032B: 14 45 04 5F 4F 46 46 08 // .E._OFF.
If (LEqual (CTXT, Zero))
{
\_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero)
0333: A0 39 93 43 54 58 54 00 5C 2F 05 5F 53 42 5F 50 // .9.CTXT.\/._SB_P
0343: 43 49 30 4C 50 43 42 45 43 30 5F 53 50 49 4E 0A // CI0LPCBEC0_SPIN.
0353: 96 00
```
產生的補丁...
~~~
Find: <5F 4F 46 46 08 A0 39 93 43 54 58 54>
Replace: <58 4F 46 46 08 A0 39 93 43 54 58 54>
~~~
注意:每個補丁都可能會被減少,但是您需要仔細檢查所有原生的DSDT和SSDTs中的**查找**模式,因為您不想和除了目標方法外的其他方法進行匹配。因為`_REG`、`_INI`和`_OFF`是其他作用域中方法的常用名稱,所以我們需要小心。
## 簡單例子
由于需要修補 `_OFF`, `_INI`, 和`_REG`,所以上面提到的ASUS文件是相對復雜的。
讓我們看一個簡單得多的例子。這些是用于`Asus K550VX-DM406T`的文件,并附在這個帖子上。請下載他們,以便你能一起實踐。
當我們在`SSDT-14`中查看`_OFF`方法時,沒有與`EC`相關的代碼。它調用這個`PGOF`,但是這個在`SSDT-3`中定義的`PGOF`方法也沒有與`EC`相關的代碼:
```
Method (_OFF, 0, Serialized) // _OFF: Power Off
{
If (LEqual (CTXT, Zero))
{
If (LNotEqual (GPRF, One))
{
Store (VGAR, VGAB)
}
Store (One, CTXT)
}
PGOF (Zero)
}
```
這意味著`_OFF`方法可以直接在`_INI`中被調用。
如果你查看在ACPI集合中的所有`_INI`方法,你會發現在`_OFF`的路徑(`_SB.PCI0.PEG0.PEGP`)中是沒有`_INI`的。
這意味著我們可以簡單地在正確的路徑上添加一個帶有`_INI`的`SSDT`,而`_INI`只需調用`_OFF`。
這是一種簡單的方法:
```
DefinitionBlock("", "SSDT", 2, "hack", "DGPU", 0)
{
External(_SB.PCI0.PEG0.PEGP._OFF, MethodObj)
Method(_SB.PCI0.PEG0.PEGP._INI) { _OFF() }
}
```
正如在主要的禁用獨顯指南(靜態補丁)中所提到的,有時您需要調用`_PS3`而不是`_OFF`。這是一個嘗試和誤差處理,以確定哪個是最好的。
和上面相同的代碼,但是調用` _PS3`:
```
DefinitionBlock("", "SSDT", 2, "hack", "DGPU", 0)
{
External(_SB.PCI0.PEG0.PEGP._PS3, MethodObj)
Method(_SB.PCI0.PEG0.PEGP._INI) { _PS3() }
}
```
保存為`SSDT-DGPU.aml` 并且 NVIDIA應該被禁用。
## 簡單的例子變得沒那么簡單了
盡管上面提到的方法通常會在這個場景中使用(即使是在其他出現相同場景的筆記本上:在`_OFF`路徑中沒有`EC`訪問,在該路徑中不存在`_INI`),為了關掉專用的Nvidia風扇,這臺特定的筆記本電腦需要額外的補丁。
所以需要進行一些調查。通過查看`_OFF`代碼可以看到,它調用`PGOF(0)`來完成大部分工作。如果我們搜索通過`Arg0==Zero`參數調用`PGOF`的其他示例,我們會在`SSDT-3.dsl`中找到這段代碼:
```
ElseIf (LAnd (LGreater (OSYS, 0x07D9), PEGS ()))
{
FAOF ()
PGOF (Zero)
...
```
注意`FAOF`的調用。這是為了“FAN OFF(風扇關閉)”嗎?似乎是可能的。
再看,`SSDT-3`中的`FAOF`和`FAON`:
```
Method (FAON, 0, Serialized)
{
\_SB.PCI0.LPCB.EC0.WRAM (0x052B, 0x9E)
\_SB.PCI0.LPCB.EC0.WRAM (0x0520, 0x8B)
Store (\_SB.PCI0.LPCB.EC0.RRAM (0x0521), Local0)
And (Local0, 0xCF, Local0)
Or (Local0, 0x20, Local0)
\_SB.PCI0.LPCB.EC0.WRAM (0x0521, Local0)
}
Method (FAOF, 0, Serialized)
{
Store (\_SB.PCI0.LPCB.EC0.RRAM (0x0521), Local0)
And (Local0, 0xCF, Local0)
\_SB.PCI0.LPCB.EC0.WRAM (0x0521, Local0)
\_SB.PCI0.LPCB.EC0.WRAM (0x0520, 0x89)
\_SB.PCI0.LPCB.EC0.WRAM (0x03A4, Zero)
\_SB.PCI0.LPCB.EC0.WRAM (0x03A5, Zero)
}
```
你可以看到它做了很多EC操作(manipulations)。典型的`EC`控制系統的風扇,所以這似乎證實這些方法是為了“FAN ON(風扇打開)”和“FAN OFF(風扇關閉)”。
由于這些方法操作了`EC`,所以我們不能在沒有`EC`的情況下調用`FAOF`。要做到這一點,我們需要修補`_REG`。
因此,將必要的代碼添加到我們的`SSDT`中:
```
DefinitionBlock("", "SSDT", 2, "hack", "DGPU", 0)
{
External(_SB.PCI0.PEG0.PEGP._OFF, MethodObj)
Method(_SB.PCI0.PEG0.PEGP._INI) { _OFF() }
External(_SB.PCI0.LPCB.EC0, DeviceObj)
External(_SB.PCI0.LPCB.EC0.XREG, MethodObj)
External(_SB.PCI0.PEG0.FAOF, MethodObj)
Scope(_SB.PCI0.LPCB.EC0)
{
OperationRegion(RME3, EmbeddedControl, 0x00, 0xFF)
Method(_REG, 2)
{
XREG(Arg0, Arg1) // call original _REG, now renamed XREG
If (3 == Arg0 && 1 == Arg1) // EC ready?
{
\_SB.PCI0.PEG0.FAOF() // turn dedicated Nvidia fan off
}
}
}
}
```
我們需要重命名`_REG to XREG`的補丁(同樣,是基于`DSDT.aml`的混合清單):
~~~
Find: <5F 52 45 47 02 A0 0B 93 68 0A 03>
Replace: <58 52 45 47 02 A0 0B 93 68 0A 03>
~~~
通過`config.plist`中的該補丁,`EC0._REG`更名為`XREG`。系統最終調用我們修改的`_REG`,反過來它將調用原始的`_REG`(重命名為`XREG`)并且調用`FAOF`來關閉風扇。
## 總結
與電池狀態相比,通過熱修補來禁用獨顯,代碼要簡單一些,但涉及到的概念都是類似的。
# ~~4樓為未來預留~~
# =======================
# 如果你還看不懂?
[Acer VN7-591G-50LW拋棄傳統靜態dsdt使用hotpatch方式配置](http://bbs.pcbeta.com/viewthread-1753771-1-1.html)
[Hotpatch簡易教程(修復聲卡、屏蔽獨顯、驅動核顯、快捷鍵調節亮度)](http://bbs.pcbeta.com/viewthread-1766329-1-1.html)
# 常用 hotpatch
1. SSDT-Disable-DGPU.aml
屏蔽獨顯
2. SSDT-PluginType1.dsl
intel 4代及更高平臺變頻使用,或者你可以使用ssdtPRGen來生成,論壇找,不多說。
3. SSDT-PNLF.dsl
有了這個才能實現快捷鍵亮度調節
4. SSDT-HDAU.dsl
聲卡相關,SSDT-Config.dsl中寫入了ID,這里也要寫,config.plist中就不需要聲卡id了
- 簡介
- 基本命令
- 高效操作
- 命令操作
- 常用軟件
- 問題設置
- 命令行神器
- 開發配置
- 開發環境配置
- brew
- git
- Karabiner-Elements
- iTerm2
- MacVim
- aria2
- LaunchBar
- zsh
- Tmux
- Charles
- Emacs(感覺不需要了)
- 常用工具
- Alfred
- mac 詞典增強
- Mac 高級操作
- mac 資源
- 黑蘋果
- 個人配置
- 黑蘋果資源
- 驅動集合
- 工具集合
- 黑蘋果指南
- [FAQ] 開始必讀!筆記本電腦常見問題
- [指南] hackintosh之SSDT/DSDT
- [指南] hackintosh之hotpatch
- [指南] 為Sierra(以及后來的版本)進行USB電源屬性注入
- [指南] 10.11+ USB的變化和解決方案
- [指南] 為USBInjectAll.kext創建一個自定義的SSDT
- [指南] Intel IGPU HDMI/DP audio (Sandy/Ivy/Haswell/Broadwell/Skylake)
- [指南] 怎么給DSDT打補丁來顯示電池狀態
- [指南]在雙GPU筆記本電腦中禁用獨立顯卡.md
- [指南]
- OpenCore
- 多系統引導
- hotpatch
- 黑蘋果裝機
- 刷BIOS大法
- dd