11.16 Usare e Debuggare ACPI di FreeBSD

Scritto da Nate Lawson. Contributo di Peter Schultz e Tom Rhodes.

ACPI è un modo fondamentalmente nuovo di utilizzare dispositivi, gestire le risorse elettriche, e fornire accesso standardizzato all'hardware gestito precedentemente dal BIOS. Si stanno facendo progressi per far funzionare ACPI su tutti i sistemi, ma continuano ad apparire bachi nel codice del Linguaggio Macchina ACPI (AML), incompletezza nel sottosistema kernel di FreeBSD, e bachi nell'interprete ACPI-CA di Intel®.

Questo documento è creato per aiutarti ad assistere i manutentori di ACPI di FreeBSD nell'identificare le cause primarie dei problemi che riscontri e debuggare e sviluppare una soluzione. Grazie per l'attenzione e speriamo di poter risolvere i problemi del tuo sistema.

11.16.1 Fornire Informazione di Debug

Nota: Prima di sottomettere un problema, accertati di avere in esecuzione l'ultima versione del BIOS e, se disponibile, la versione del firmware del controller integrato.

Per quelli di voi che vogliono sottomettere un problema subito, per favore inviate la seguente informazione a freebsd-acpi@FreeBSD.org:

Molti degli sviluppatori seguono la mailing list su FreeBSD-CURRENT ma per favore sottomettete i vostri problemi a freebsd-acpi per essere sicuri che siano visti. Per favore siate pazienti, abbiamo tutti lavori full-time altrove. Se i vostri bachi non sono chiarissimi, vi chiederemo di sottomettere un PR attraverso send-pr(1). Quando si invia un PR, per favore includete le stesse informazioni sopracitate. Questo aiuterà a tracciare il problema e risolverlo. Non inviare un PR senza prima inviare una email a freebsd-acpi, dato che noi usiamo PR come promemoria di problemi esistenti, non come meccanismo di reporting. È probabile che i vostri problemi siano stati riportati da qualcun altro prima.

11.16.2 Background

ACPI è presente su tutti i computer moderni che conformi all'architettura ia32(x86), ia64 (Itanium), e amd64 (AMD). L'intero standard ha molte caratteristiche che includono la gestione della performance della CPU, il controllo dei piani energetici, delle zone termiche, delle batterie del sistema, controller incorporati, ed enumerazione dei bus. Molti sistemi implementano meno dello standard completo. Per esempio, un sistema desktop di solito implementa le parti di enumerazione dei bus mentre un laptop potrebbe avere il raffreddamento ed anche il supporto alla gestione della batteria. I laptop hanno anche sospensioni e riavvii, con la loro complessità associata.

Un sistema ACPI-compliant ha molte componenti. Il BIOS ed i venditori di chipset forniscono varie tabelle fisse in memoria (ad esempio FADT) che specificano cose come la mappa APIC (usata per SMP), i registri di configurazione, e semplici valori di configurazione. Inoltre viene fornita una tabella di codici di byte (la Differentiated System Description Table DSDT) per specificare uno spazio dei nomi ad albero di dispositivi e metodi.

Il driver ACPI deve fare il parse delle tabelle fisse, implementare un interprete per il codice di byte, e modificare i device driver ed il kernel per accettare informazioni dal sottosistema ACPI. Per FreeBSD, Intel ha fornito un interprete (ACPI-CA) che è condiviso fra Linux e NetBSD. Il path al codice sorgente ACPI-CA è src/sys/contrib/dev/acpica. Il codice che permette ad ACPI-CA di lavorare con FreeBSD è in src/sys/dev/acpica/Osd. Finalmente, i driver che implementano vari dispositivi ACPI si trovano in src/sys/dev/acpica.

11.16.3 Problemi Comuni

Affincè ACPI funzioni correttamente tutte le parti devono funzionare correttamente. Ci sono alcuni problemi comuni, in ordine di frequenza di apparizione, ed alcuni possibili workaround o mezzi per aggiustarli.

11.16.3.1 Questioni di Mouse

In alcuni casi, ripartire dopo una operazione di sospensione, fa sì che il mouse non riparta. Un noto workaround è aggiungere hint.psm.0.flags="0x3000" al file /boot/loader.conf. Se questo non funziona allora per favore considera l'invio di un report del baco come descritto in precedenza.

11.16.3.2 Sospensione/Riavvio

ACPI ha tre stati di sospensione RAM (STR), S1-S3 ed un stato di sospensione disco (STD), chiamato S4. S5 è il “soft off” ed è il normale stato in cui il tuo sistema si trova quando è collegato ma non acceso. S4 può essere implementato in due modi separati. S4 BIOS è una sospensione BIOS-assistita da disco. S4OS è implementato direttamente dal sistema operativo.

Inizia a controllare sysctl hw.acpi per le entry relative alla sospensione. Questi sono i risultati per un Thinkpad:

hw.acpi.supported_sleep_state: S3 S4 S5
hw.acpi.s4bios: 0

Questo significa che possiamo usare acpiconf -s per testare S3, S4OS, S5. Se s4bios fosse stato uno (1), avremmo supporto a S4BIOS invece di S4OS.

Quando si testa la sospensione/riavvio, inizia con S1, se supportato. È più probabile che funzioni questo stato dato che non richiede molto supporto dal driver. Nessuno ha implementato S2, ma se tu lo hai, è simile a S1. La prossima cosa da provare è S3. Questo è lo stato più profondo STR e richiede molto supporto dal driver per reinizializzare il tuo hardware. Se hai problemi a riavviarlo, sentiti libero di segnalarlo via mail alla lista freebsd-acpi ma non aspettarti che il problema sia risolto dato che ci sono molti driver/hardware che hanno bisogno di test e di lavoro aggiuntivo.

Per aiutare ad isolare il problema, rimuovi quanti più driver possibile dal tuo kernel. Se funziona, puoi scoprire quale driver causa il problema caricando dei driver fino a che il problema si ripresenta. Tipicamente i driver binari come nvidia.ko, i driver di display di X11, e USB avranno la maggior parte dei problemi mentre interfacce Ethernet funzioneranno bene. Se puoi caricare/scaricare driver correttamente, puoi automatizzare questo piazzando i comandi appropriati in /etc/rc.suspend e /etc/rc.resume. C'è un esempio commentato su come caricare e scaricare un driver. Prova a impostare hw.acpi.reset_video a zero (0) se il tuo display è confuso dopo il riavvio. Prova a impostare valori più lunghi o corti per hw.acpi.sleep_delay per vedere se aiuta.

Un'altra cosa da provare è caricare una distribuzione Linux recente con supporto ACPI e testare il loro supporto sospensione/riavvio sullo stesso hardware. Se funziona su Linux, è probabile che sia un problema driver relativo a FreeBSD e restringere il campo di indagine su quale driver causi il problema può aiutare a risolvere il problema. Notate che i manutentori di ACPI non mantengono altri driver (ad esempio suono, ATA, etc.) così ogni lavoro fatto sull'identificazione del problema del driver dovrebbe alla fine essere risolto dalla lista freebsd-current e inviato via mail al manutentore del driver. Se ti senti avventuroso, vai avanti e inizia a porre qualche printf(3) in un driver che dà problemi per tracciare in quale driver nella sua funzione di resume vada in palla.

Alla fine, cerca di disabilitare ACPI ed ad abilitare APM invece. Se la sospensione ed il riavvio funziona con APM, è meglio che tu continui con APM, specialmente su hardware vecchio (pre-2000). Ci vuole un pò di tempo per i venditori per ottenere un supporto corretto all'ACPI e l'hardware più vecchio è più probabile che abbia problemi BIOS con ACPI.

11.16.3.3 Blocco del Sistema (temporanea o permanente)

La maggior parte dei blocchisono causati da interrupt persi o da una tempesta di interrupt. I chipset hanno un sacco di problemi su come il BIOS configuri gli interrupt prima del boot, la correttezza delle tabelle ACPI (MADT) ed il routing del System Control Interrupt (SCI).

Le tempeste di interrupt possono essere distinte da interrupt persi controllando l'output di vmstat -i e guardando alla linea che riguarda acpi0. Se il contatore sta avanzando più di un paio di secondi per volta, hai una tempesta di interrupt. Se il sistema si blocca, cerca di di entrare in DDB (CTRL+ALT+ESC sulla console) e digita show interrupts.

Il modo migliore in caso di problemi di interrupt è provare a disabilitare il supporto APIC con hint.apic.0.disabled="1" in loader.conf.

11.16.3.4 Panici

I panici sono relativamente rari per ACPI e sono il primo problema ad essere corretto. Il primo passo da fare è riprodurre il panico (se possibile) ed ottenere un backtrace. Segui l'avvertimento per abilitare options DDB e imposta una console seriale (vedi la Sezione 24.6.5.3) o imposta una partizione di dump(8). Puoi ottenere un backtrace in DDB con tr. Se hai scritto a mano il backtrace, accertati di ottenere le ultime cinque (5) e le prime cinque (5) linee nella traccia.

Poi, prova ad isolare il problema facendo boot con ACPI disabilitato. Se funziona, puoi isolare il sottosistema ACPI usando vari valori di debug.acpi.disable. Leggi la pagina di manuale di acpi(4) per alcuni esempi.

11.16.3.5 Riavvii di sistema dopo Sospensioni o Spegnimenti

Prima, cerca di impostare hw.acpi.disable_on_poweroff="0" in loader.conf(5). Questo fa sì che ACPI abbia disabilitato alcuni eventi durante il processo di shutdown. Alcuni sistemi hanno bisogno di impostare questo valore a 1 (il default) per la stessa ragione. Questo di solito aggiusta il problema di un sistema che si accende spontaneamente dopo una sospensione o uno spegnimento.

11.16.3.6 Altri problemi

Se hai altri problemi con ACPI (lavorare con un docking station, dispositivi non trovati, ecc.), per favore invia via mail una descrizione anche alla mailing list; comunque, alcune di queste questioni possono essere correlate a parti del sottosistema ACPI così può volerci un pò prima che siano implementate. Per favore sii paziente e preparato a testare le patch che ti vengono inviate.

11.16.4 ASL, acpidump, e IASL

Il più comune problema è il BIOS di venditori che forniscono bytecode incorretto (o addirittura con bachi). Questo si deduce usualmente da messaggi del kernel come questo:

ACPI-1287: *** Error: Method execution failed [\\_SB_.PCI0.LPC0.FIGD._STA] \\
(Node 0xc3f6d160), AE_NOT_FOUND

Spesso puoi risolvere questi problemi aggiornando il tuo BIOS all'ultima versione. La maggior parte dei messaggi di console non indica nulla di notevole, ma se hai altri problemi come lo stato della batteria non funzionante, questi sono un buon inizio per iniziare a cercare problemi in AML. Il bytecode, noto come AML, è compilato da un insieme di codici sorgenti chiamato ASL. L'AML, è trovato nella tabella nota come come DSDT. Per trovare una copia del tuo ASL usa acpidump(8). Dovresti usare entrambe le opzioni -t (mostra i contenuti della tabella fissa) e la -d (disassembla AML ad ASL). Vedi la sezione Fornire Informazione di Debug per un esempio della sintassi.

Il tuo primo controllo che puoi fare è ricompilare il tuo ASL per controllare errori. Possono essere ignorati i 'warning' ma gli errori sono bachi che impediranno all'ACPI di funzionare correttamente. Per ricompilare il tuo ASL, usa il comando seguente:

# iasl your.asl

11.16.5 Aggiustare il tuo ASL

Alla lunga, il nostro obiettivo è avere ACPI che funzioni per tutti senza intervento. A questo punto, comunque stiamo ancora sviluppando workaround per errori comuni fatti dal venditore del BIOS. L'interprete Microsoft® (acpi.sys e acpiec.sys) non è strettamente conforme agli standard, e così molti venditori BIOS che testano solo ACPI sotto Windows® non aggiustano mai il loro ASL. Vogliamo continuare a identificare e documentare esattamente quali comportamenti non standard sono concessi dall'interprete Microsoft e replicarlo cosicchè FreeBSD può funzionare senza forzare gli utenti ad usare ASL. Come workaround e per aiutarci ad identificare il comportamento puoi fissare la ASL manualmente. Se questo funziona per favore invia un diff(1) del vecchio e del nuovo ASL, cosicchè possiamo lavorare attorno al comportamento bacato di ACPI-CA e così rimettere a posto il necessario.

Qui c'è una lista di messaggi di errori comuni, le loro cause e come fissarli:

11.16.5.1 Dipendenze OS

Alcuni AML assumono che il mondo consiste di varie versioni Windows. Puoi far sì che FreeBSD simuli qualsiasi OS per vedere se questo risolve il problema che hai. Un modo facile per sovrascrivere questo è porre hw.acpi.osname="Windows 2001" in /boot/loader.conf o altre stringhe simili che trovi nella ASL.

11.16.5.2 Valori di Ritorno Mancanti

Alcuni metodi non ritornano esplicitamente un valore come i requisiti standard. Mentre ACPI-CA non gestisce questo, FreeBSD ha un workaround che permette di ritornare i valori implicitamente. Puoi anche aggiungere espliciti Valori di Ritorno dove si richiede se sai quale valore dovrebbe essere ritornato. Per forzare iasl a compilare l'ASL usa il flag -f.

11.16.5.3 Sovrascrivere il Default AML

Dopo che personalizzi il tuo your.asl, potresti volerlo compilare, esegui:

# iasl your.asl

Puoi aggiungere il flag -f per forzare la creazione dell'AML, anche se ci sono errori durante la compilazione. Ricorda che alcuni errori (ad esempio valori di Ritorno mancanti) sono automaticamente riaggiustati dall'interprete.

DSDT.aml è il nome del file di default del comando iasl. Puoi caricare questo invece della copia difettosa del tuo BIOS (che è ancora presente in memoria) editando il file /boot/loader.conf come segue:

acpi_dsdt_load="YES"
acpi_dsdt_name="/boot/DSDT.aml"

Assicurati di copiare il tuo file DSDT.aml nella directory /boot.

11.16.6 Ottenere Output di Debug da ACPI

Il driver ACPI ha una facility di debug molto utile. Permette di specificare un insieme di sottosistemi come anche un livello di verbosità. I sottosistemi che desideri debuggare sono specificati come “strati” e sono divisi in componenti ACPI-CA (ACPI_ALL_COMPONENTS) e supporto hardware ACPI (ACPI_ALL_DRIVERS). La verbosità dell'output di debug è specificata come “livello” e varia da ACPI_LV_ERROR (riporta solo gli errori) ad ACIP_LV_VERBOSE (tutto). Il “livello” è una bitmask che fa sì che molte opzioni possano essere impostate una alla volta, separate da spazi. In pratica, puoi usare una console seriale per loggare l'output se è così lungo da riempire il buffer di messaggi della console. Una lista completa degli strati individuali e dei livelli è disponibile nella pagina man acpi(4).

L'output di debug non è abilitato di default. Per abilitarlo, aggiungi options ACPI_DEBUG al tuo file di configurazione del kernel se ACPI è compilato nel kernel. Puoi aggiungere ACPI_DEBUG=1 al tuo /etc/make.conf per abilitarlo in modo globale. Se è un modulo, puoi ricompilare soltanto il tuo modulo acpi.ko come segue:

# cd /sys/modules/acpi/acpi
&& make clean &&
make ACPI_DEBUG=1

Installa acpi.ko in /boot/kernel ed aggiungi il tuo livello desiderato e gli strati in loader.conf. Questo esempio abilita i messaggi per tutti i componenti ACPI-CA e tutti i driver hardware ACPI (CPU, LID, etc.). Produrrà solo messaggi di errore, i meno verbosi.

debug.acpi.layer="ACPI_ALL_COMPONENENTS ACPI_ALL_DRIVERS"
debug.acpi.level="ACPI_LV_ERROR"

Se l'informazione che vuoi ottenere è prodotta da un evento specifico (ad esempio, una sospensione ed un riavvio), puoi tralasciare i cambiamenti di loader.conf ed invece usare sysctl per specificare lo strato ed il livello dopo il boot e preparare il tuo sistema per l'evento specifico. I sysctl sono nominati allo stesso modo dei parametri in loader.conf.

11.16.7 Riferimenti

Maggiori informazioni su ACPI possono essere trovate nei seguenti posti:

Questo, ed altri documenti, possono essere scaricati da ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

Per domande su FreeBSD, leggi la documentazione prima di contattare <questions@FreeBSD.org>.
Per domande su questa documentazione, invia una e-mail a <doc@FreeBSD.org>.