“ATTENZIONE : Quanto di seguito esposto può provocare gravi danni al proprio PC. Non mi ritengo responsabile di guasti e/o perdita di dati in conseguenza, diretta o indiretta, dall’esecuzione delle operazione suggerite in questa mini guida. Questa guida è in gran parte ispirata da Jetblack di gentoo.org che ha scritto “HOWTO: Fix Common ACPI Problems (DSDT, ECDT, etc.)”
Nonostante in rete ci siano delle buone guide sull’argomento, mi sono imbattuto in alcuni problemi finora risolti da nessun’altro (a quanto pare) e così voglio rendere partecipe la rete della mia esperienza, caso mai possa essere utile ad altri.
Ho un portatile HP Omnibook XE3 GF ma quanto segue può essere utilizzato come linea guida per altri portatili.
L’ACPI è suportato, infatti dmidecode mi riporta
(scaricabile da http://www.nongnu.org/dmidecode/)
…
BIOS Information
Vendor: Phoenix Technologies LTD
Version: GF.M1.14
…
ACPI Supported
…
Ho abilitato il supporto ACPI da kernel ma, riavviato il PC, dai messaggi del kernel comparivano nefasti “Warning”
ACPI-0178: *** Warning: The ACPI AML in your computer contains errors, please nag the manufacturer to correct it.
ACPI-0181: *** Warning: Allowing relaxed access to fields; turn on CONFIG_ACPI_DEBUG for details.
Ho eseguito un pò di ricerche e i risultati mi hanno inizialmente avvilito. Si trattava di dover disassemblare il DSDT e ricostruirne uno nuovo con le opportune modifiche/aggiunte.
Per risolvere il problema mi hanno aiutato 4 ottime guide.
HOWTO: Fix Common ACPI Problems (DSDT, ECDT, etc.)
http://forums.gentoo.org/viewtopic.php?t=122145&highlight=acpi+dsdt+aml
Linux ACPI Howto (Advanced Configuration and Power Interface)
http://www.cpqlinux.com/acpi-howto.html
ACPI Component Architecture Programmer Reference
http://www.intel.com/technology/iapc/acpi/downloads/ACPICA-ProgRef.pdf
Advanced Configuration and Power Interface Specification
http://www.acpi.info/DOWNLOADS/ACPIspec-2-0c.pdf
Le prime due sono un “must”, in particolare l’HOWTO postato sul forum di gentoo è essenziale.
Le altre due sono molto tecniche e interessanti dal punto di vista accademico, ma nella maggior parte dei casi potrebbe non essere utile studiarsele. Io le ho trovate gustose 🙂
– DEBUG
Prima di tutto occorre capire quli sono i problemi e per farlo è fondamentale che abilitiate l’ACPI dal kernel 😉
Procuratevi il compilatore Intel iasl, nella sezione “Tool” all’indirizzo
http://developer.intel.com/technology/iapc/acpi/downloads.htm
Createvi una directory di appoggio e posizionatevi al suo interno.
tar -xvzf iasl-linux-20030228.tar.gz
cd iasl-linux-20030228
ls >> AslCompiler.pdf iasl
A questo punto facciamo un pò di “hack” al nostro dsdt:
cat /proc/acpi/dsdt > dsdt.dat
Avrete un file dsdt.dat compilato del vostro attuale ACPI bacato.
Per disassemblarlo digitate
iasl -d dsdt.dat
E otterrete così dsdt.dsl.
Per vedere dove stanno i problemi si procede con il provare a ricompilarlo.
iasl -tc dsdt.dsl
Otterrete dsdt.hex e DSDT.aml.
Ecco fatto se il vostro dsdt è bacato otterrete un’ output come il seguente (il mio nell’esempio).
Intel ACPI Component Architecture
ASL Optimizing Compiler / AML Disassembler version 20030918 [Sep 18 2003]
Copyright (C) 2000 – 2003 Intel Corporation
Supports ACPI Specification Revision 2.0b
dsdt.dsl 173: Method (_WAK, 1, NotSerialized)
Warning 2026 – ^ Reserved method must return a value (_WAK)
dsdt.dsl 806: Method (_DOD, 0, NotSerialized)
Warning 2019 – ^ Not all control paths return avalue (_DOD)
dsdt.dsl 806: Method (_DOD, 0, NotSerialized)
Warning 2026 – ^ Reserved method must return a value (_DOD)
dsdt.dsl 1443: SRST, 1,
Error 1051 – ^ Access width of Field Unit extends beyond region limit dsdt.dsl 1446: ACPW, 1
Error 1051 – ^ Access width of Field Unit extends beyond region limit dsdt.dsl 2959: Field (ERAM, AnyAcc, Lock, preserve)
Error 1048 – ^ Host Operation Region requires ByteAcc access dsdt.dsl 3714: Name (PBUF, Buffer (0x14)
Warning 2079 – Statement is unreachable ^
ASL Input: dsdt.dsl – 4486 lines, 160784 bytes, 2090 keywords
Compilation complete. 3 Errors, 4 Warnings, 0 Remarks, 480 Optimizations
iasl vi dice molte cose interessanti.
Ha riscontarto 3 errori, 4 warning, 0 Remarks e ha identificato 480 possibili ottimizzazioni (le fa in automatico)
Inoltre per ogni Warning e Error avete il dettaglio, messaggio di errore più il numero della linea che restituisce l’errore.
Iniziamo a correggere il dsdt.dsl
Warning 2026 : Nella procedura indicata manca un “Return Package…”.
Questo è un errore molto comune, la soluzione è di aggiungere
Return(Package(0x02){0x00, 0x00}) appena prima della fine del metodo
Method (_WAK, 1, NotSerialized)
{
…
…
Return(Package(0x02){0x00, 0x00})
}
####################################################
Warning 2019 – ^ Not all control paths return avalue (_DOD)
Warning 2026 – ^ Reserved method must return a value (_DOD)
Come sopra si sono dimenticati di un pezzo, non avendo trovato riscontri in rete ho dovuto andare particolarmente a fondo.
_DOD viene utilizzato per descrive e “istanziare” le uscite video della scheda grafica, Nel mio caso LCD, CRT e TV.
Quindi ho estrapolato dal codice i valori corretti e ho aggiunto in fondo al metodo
Return (Package (0x03)
{
0x00010400,
0x00010100,
0x00010200
})
Non è una soluzione propriamente brillante, infatti ho eliminato il Warning ma non ho eliminato i problemi che avevo con la gestione delle uscite video (se qualcuno avesse qualche idea…).
####################################################
SRST, 1,
Error 1051 – ^ Access width of Field Unit extends beyond region limit
ACPW, 1
Error 1051 – ^ Access width of Field Unit extends beyond region limit
Qui c’è un errore di concetto.
OperationRegion (GPIO, SystemIO, 0x1180, 0x3B)
Field (GPIO, WordAcc, Lock, Preserve)
{
AccessAs (DWordAcc, 0x00),
Offset (0x0F),
, 4,
LV28, 1,
Offset (0x2D),
, 5,
LPOL, 1,
Offset (0x38),
, 1,
SRST, 1,
Offset (0x39),
, 2,
ACPW, 1
}
L’ OperationRegion è troppo piccola e quindi SRST e ACPW lavorano al di fuori di essa, essendo praticamnte impossibile, questa è una delle fonti rpincipali dei miei problemi e della maggiorparte dei possessori di un portatile.
Per risolvere entrambi i problemi con il minimo sforzo basta aumentare la dimensione della OP da 0x3B a 0x3C
OperationRegion (GPIO, SystemIO, 0x1180, 0x3C)
####################################################
Field (ERAM, AnyAcc, Lock, Preserve)
Error 1048 – ^ Host Operation Region requires ByteAcc access
Questo il più semplice (ma fonte di grossi problemi)
OP vuole ByteAcc e noi gli diamo ByteAcc
(ERAM, ByteAcc, Lock, Preserve)
####################################################
Name (PBUF, Buffer (0x14)
Warning 2079 – Statement is unreachable ^
Qui le cose sono state complicate per me, non ho trovato riscontri in rete e il tipo di errore non è documentato quanto basta.
Method (_GTM, 0, NotSerialized)
{
Return (Buffer (0x14)
{
0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00
})
Name (PBUF, Buffer (0x14)
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
})
…
Appena prima di “Name (PBUF, Buffer (0x14)” c’è un Return di troppo e quindi è bastato togliere
Return (Buffer (0x14)
{
0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00
})
####################################################
Ecco fatto le correzioni sono state fatte…
Durante la fase di correzione potete lanciare iasl -tc dsdt.dsl per verificare come procedono le cose.
Alla fine dovreste ottenere:
Intel ACPI Component Architecture
ASL Optimizing Compiler / AML Disassembler version 20030918 [Sep 18 2003]
Copyright (C) 2000 – 2003 Intel Corporation
Supports ACPI Specification Revision 2.0b
ASL Input: dsdt.dsl – 4487 lines, 160622 bytes, 2091 keywords
AML Output: DSDT.aml – 19330 bytes 584 named objects 1507 executable opcodes
Compilation complete. 0 Errors, 0 Warnings, 0 Remarks, 482 Optimizations
Bene dsdt e aml corretti come si fà a sfruttarli?
Io ho preferito usare initrd, in quanto già lo uso per il bootsplash, se non usate initrd vi rimando alle due guide iniziali… Sono molto chiare.
1) Abilitare “relaxed aml” nel kernel
Occorre scaricare una patch appropriata al proprio kernel da http://gaugusch.at/kernel.shtml
La patch è molto semplice e quindi, se avete un kernel ultra patchato, aprite la patch con un editor (vim, nano, emacs, kate, etc.) e apportate le modifiche a mano.
cd /usr/src/linux
patch -p1 < /path/to/acpi-dsdt-initrd-patch-v0.3-2.4.22-acpi-2003-09-18.diff E abilitate quanto segue dal kernel. Device Drivers --->
Block Devices —>
<*> RAM disk support
[*] Initial RAM disk (initrd) support
Power management options (ACPI, APM) —>
ACPI (Advanced Configuration and Power Interface) Support —>
[*] Read DSDT from initrd
make dep && make clean bzImage modules modules_install
Come ho detto sopra uso bootsplash e quindi mi è bastato fare
cp /boot/initrd-1024×768 /boot/initrd-1024×768-dsdt
echo “INITRDDSDT123DSDT123” >> /boot/initrd-1024×768-dsdt
cat /path/to/DSDT.aml >> /boot/initrd-1024×768-dsdt
e modificare /etc/lilo.conf (o grub.conf) per il nuovo initrd
initrd=/boot/initrd-1024×768-dsdt
Infine ho eseguito
lilo
Se non avete un bootsplash ma volete usare initrd
cp /path/to/DSDT.aml /boot
e aggiungere a /etc/lilo.conf (o grub.conf)
initrd=/boot/DSDT.aml
eseguire
lilo
Incrociate le dita e riavviate.
Ho postato il dsdt.dsl a acpi.sourceforge.net e ho reso partecipe HP delle fix (sono molto propensi ad appoggiare questo tipo di iniziative)