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

Be Sociable, Share!