diff --git a/docs/vendor-crossref-aura-re.md b/docs/vendor-crossref-aura-re.md new file mode 100644 index 0000000..055483e --- /dev/null +++ b/docs/vendor-crossref-aura-re.md @@ -0,0 +1,159 @@ +# Cross-check col reverse engineering vendor ASUS (`aura-re`) — 2026-08-26 + +> **Esito: nessuna divergenza. Il binario ASUS usa la stessa mappa registri del driver, +> registro per registro.** Il valore di questo confronto non è una correzione: è la +> **seconda conferma indipendente** su un'interfaccia che il datasheet Intel non documenta +> per la PCU function 5 — la prima era PawnIO.Modules (`SmbusIntelSkylakeIMC.p`, +> `TODO.md` §Notes) — più tre dati che nei nostri doc non c'erano. + +| | | +|---|---| +| **Fonte** | `/media/simone/OS/Users/Simone/Desktop/aura-re` — analisi statica dei binari Armoury Crate, prodotta il **2026-08-26** (cartella non-git, sulla partizione Windows) | +| **Grado di fiducia** | claim di terzi, ma **verificabile**: `raw/` ha i binari, `disasm/` il disassemblato completo | +| **Spot-check fatto** | 2 su 2 riscontrati sul disassemblato primario, non sul solo testo — vedi §4 | +| **Ricaduta sul codice** | **nessuna modifica necessaria** | + +--- + +## 1. Confermato — mappa registri identica + +Confronto fra `aura-re/03-smbus-backends.md` (classe `gs::IntelSKLXSmbus`) e +`i2c-imc-skylake.c`. + +| Elemento | ASUS `gs::IntelSKLXSmbus` | Nostro driver | Esito | +|---|---|---|---| +| Device PCI | DID `0x2085` | `PCU_DEVICE 0x2085` (`:95`) | identico | +| Canale 0 — CMD / STAT / DATA | `0x9C` / `0xA8` / `0xB4` | `:110-112` | identico | +| Canale 1 — CMD / STAT / DATA | `0xA0` / `0xAC` / `0xB8` | `:113-115` | identico | +| CMD `[7:0]` | BA, offset nel device | `GENMASK(15,0)` low byte (`:132`) | identico | +| CMD `[14:8]` | SA, indirizzo 7 bit | `:130-131` | identico | +| CMD `[15]` | WRT, 1 = scrittura | `WRITE_OPERATION BIT(15)` (`:154`) | identico | +| CMD `[17]` | WORD, accesso 16 bit | `WORD_BIT BIT(17)` (`:138`) | identico | +| CMD `[19]` | TRIGGER | `GO_BIT BIT(19)` (`:136`) | identico | +| CMD `[20]` | TSOD poll *(loro: `[inferenza]`)* | `TSOD_ACTIVE_BIT BIT(20)` (`:137`) | concorde | +| STATUS, letto come **byte** | `[0]` BUSY `[1]` ERROR `[2]` read done `[3]` write done | `:164-167` | identico | +| DATA — scrittura byte | `[23:16]` | `raw << 16` con `raw` a 8 bit (`:571-572`) | identico | +| DATA — scrittura word | `[31:16]` | `swab16(*value) << 16` (`:571-572`) | identico | +| DATA — lettura | `[15:0]` | `raw & 0xffff` / `& 0xff` (`:599-600`) | identico | + +> **Perché conta.** La cover letter dice che il datasheet Intel (rif. 614073 §3.1.8) +> descrive un'altra interfaccia, sulla channel function, e **non** copre la function 5. +> Il HAL ASUS pilota la function 5 esattamente con la nostra codifica: la mappa non è più +> solo "misurata sul mio hardware". + +## 2. Differenze di condotta — nessuna è un difetto nostro + +- **Bit 29** — ASUS **non lo scrive mai**: legge il CMD e lo maschera con + `and dword ptr [r8], 0xfffe0000`, cioè conserva tutti i bit ≥ 17 e ricostruisce solo + `[16:0]`. Il bit 29 sopravvive perché **lo ha già messo il firmware**. Noi lo scriviamo + esplicitamente (`COMMAND_PREFIX`, `:155`) e abbiamo misurato che azzerandolo la + transazione fallisce con ERROR. Le due osservazioni sono coerenti; è un secondo dato per + la domanda "cos'è il bit 29" se un reviewer la fa. +- **Gate TSOD** — ASUS si limita a **rifiutare** la transazione se `CMD bit20 == 1` + (funzione `0x14001D720`, chiamata una sola volta via `std::call_once`). Noi facciamo di + più: check di `SMBCNTL.TSOD_POLL_EN` a probe (`:783`) **e** azzeramento + ripristino del + bit 20 su tutti i canali per ogni transfer (`imc_prepare_xfer`, `:517-548`). Il nostro + è strettamente più cauto — niente da importare. +- **`PNTR_SEL` (bit 18)** — ASUS non lo usa affatto. La scoperta del 27/07 resta solo + nostra: nessuna conferma, ma nemmeno contraddizione. +- **Timeout** — ASUS: 1000 iterazioni con attesa di ~237 µs (`0xED`) ≈ 237 ms. + Noi: poll 10 µs, timeout 50 ms idle / 200 ms GO / 50 ms done. Nessuna azione. + +## 3. Dati nuovi, che nei nostri doc non c'erano + +- 🚨 **Tabella CPUID → Device ID del vendor** (`0x140001510`, tab. in + `03-smbus-backends.md`): + + | CPUID `>>4` | Famiglia | DID cercato | + |---|---|---| + | `0x306F` | Haswell-E / EP | `0x2FA8` | + | `0x406F` | Broadwell-E / EP | `0x6FA8` | + | `0x5065` | Skylake-X / Cascade Lake-X | `0x2085` | + +- **Il vendor conferma che i due layout non sono intercambiabili.** Il ramo + `gs::IntelImcSmbus` (Haswell/Broadwell) usa `SMBSTAT 0x180` / `SMBCMD 0x184` / + `SMBCNTL 0x188` con TRIGGER a `[31]`, PNTR_SEL a `[30]`, WORD a `[29]`, WRITE a `[27]` — + **identico a `i2c-imc` di Lutomirski**; il ramo SKL-X è la codifica compatta che usiamo + noi. È l'argomento tecnico del perché serve un driver nuovo e non un'estensione di + `i2c-imc` (fonte: `aura-re/08-domande-aperte.md`, §"`IntelImcSmbus` contro `i2c-imc`"). +- **ENE a `0x27`: il percorso vendor è write-only**, e ora lo si legge nel codice ASUS, + non in un commento di OpenRGB. Sessione `0xE1=0x01` + `0xE4=0x09`, colori + `0xEC`/`0xED`/`0xEE`, commit `0xDD=0x64`, **50 µs di attesa attiva fra una scrittura e + l'altra**, `Sleep(1 ms)` attorno all'apertura/chiusura, chiusura `0xE1=0x02` poi `0x03`. + Corrobora **P2** (chiusa il 10/08) da una fonte indipendente. +- **Gli indirizzi RGB dei moduli vengono *assegnati*, non sono di fabbrica** + (`EneRGBSDK::Dram_AssignAddress`, base `0x48`; `GskillLogic::ChangeAddress`). Quindi + `0x27` è "l'indirizzo dopo l'inizializzazione", non un dato di targa — da tenere + presente in ogni futura misura sull'ENE. + +## 4. Spot-check sul disassemblato primario + +Due claim presi a campione e riscontrati sul `.asm`, non sul testo del doc: + +``` +disasm/AacKingstonDramHal_x64.asm:337 + 0x000140001550 b885200000 mov eax, 0x2085 # tabella CPUID->DID, voce SKL-X + +disasm/AacKingstonDramHal_x64.asm:33438 + 0x00014001d29f 4181200000feff and dword ptr [r8], 0xfffe0000 # ReadByte: conserva + # i bit >=17 (29 e 20) +``` + +## 5. 🚨 Vincolo: questo materiale non va su LKML + +Deriva dal disassemblato di binari ASUS proprietari. Le affermazioni della patch e della +cover letter restano fondate **sulle nostre misure su hardware**, che ci sono già e bastano. +Il cross-check serve internamente (e in `docs/submission/review-answers.md`, gitignored), +non come citazione nel thread upstream. + +## 6. Ricadute fuori da questo progetto + +- **furyrs** — Kingston FURY: RGB a `0x58` (DDR4, base `0x57`+1) e `0x60` (DDR5, base + `0x5F`+1); mode register `0x08`: `0x53` `'S'` = controllo software, `0x44` `'D'` = + default; detect = ReadWord `0x05`/`0x06`/`0x88`/`0x26` con 20 ms fra i passi. Detect + del modulo RGB via SPD: manufacturer `0x0198` in `SPD[0x140/0x141]`, flag RGB = + **`SPD[0x168] bit 4`** (pagina 1, SPA1 `0x37`). Fonte: `aura-re/04-dram-kingston.md`. +- **tuf-x299-aura** — i LED della mobo **non stanno sull'i801**: stanno sul controller + SMBus del Super I/O **Nuvoton** (`0x2E`/`0x2F`, LDN `0x0B`, base da `0x62`/`0x63`), con + controller **AURA82** a `0x9C` 8 bit = **`0x4E` 7 bit** e pacchetti da 65 byte con marker + `0xEC`. Spiegherebbe sia lo scan i801 muto sia OpenRGB a zero controller. + Fonte: `aura-re/05-mobo-aura.md`, `06-porting-linux.md`. + +## 7. Cosa ho già letto nel disassemblato (per non rifarlo) + +Analisi mia del 26/08 sulla vtable di `gs::IntelSKLXSmbus` +(`disasm/AacKingstonDramHal_x64.rtti.txt:17-30`, 13 slot, base `gs::Smbus` ne ha 11 con +7 `_purecall`): + +| Slot | VA | Cosa fa davvero | Ricaduta sul driver | +|---|---|---|---| +| 1-4 | `0x14001D310` / `D240` / `D3E0` / `D4A0` | read/write byte e word | già nostri | +| 6 | `0x14001CD60` | **block read emulata**: ciclo che chiama lo slot 4 (`call [rax+0x20]` = ReadWord) e impila 2 byte per giro in uno `std::vector` | **niente block hardware** | +| 7 | `0x14001CEB0` | **block write emulata**: ciclo che chiama lo slot 3 (`call [rax+0x18]` = WriteWord), impacchettando 2 byte per giro | idem | +| 8 | `0x14001D560` | write "nuda": `CMD &= 0xfffc00ff` (azzera `[17:8]`, **conserva BA `[7:0]`, bit 18, 20, 29**), poi `SA` in `[14:8]`, `WRT` in `[15]`, `GO` in `[19]`; nessun dato messo in DATA; indirizzo = `arg1 + arg2` a 8 bit; chiude con `WaitDone(isWrite=1)`. È il **page-select SPD** (SPA0/SPA1) che serve a leggere gli offset > `0xFF` | equivalente al nostro Send Byte, ma **senza** usare `PNTR_SEL` | +| 12 | `0x14001D5D0` | `slot % 6` → indice in tabella a `0x14007F938`, passo 4 | mappa slot logico → indirizzo | + +Costruttore (`0x14001A3C5`-`0x14001A496`): crea **esattamente due** istanze, con +`(status, cmd, data)` = `(0xA8, 0x9C, 0xB4)` e `(0xAC, 0xA0, 0xB8)`. 🚨 **Nessun altro +offset del config space della function 5 viene toccato** in questo percorso: niente +registro nascosto da aggiungere al driver. + +**Conclusione: dal materiale letto finora non esce nessuna feature hardware che ci +manchi.** Le domande che potrebbero ancora cambiare il driver sono in `TODO.md` §V, +item `V3`. + +## 8. 🚨 Un claim di `aura-re` è sbagliato — verificato sul primario + +`aura-re/06-porting-linux.md` §"Percorso 1" dice che *«esiste già un'implementazione Linux +funzionante: OpenRGB ha un driver SMBus per il Super I/O Nuvoton»* e cita +`i2c_smbus/i2c_smbus_nuvoton_nct6775.cpp`. **Quel file non esiste.** Su +`hw/OpenRGB-src` a `master` `8c19428b` (2026-08-08) l'unico backend Nuvoton è +`i2c_smbus/MacOS/i2c_smbus_nct6775.cpp` — **solo macOS**, esattamente come dice già +`hw/tuf-x299-aura/TODO.md` **B2**. Su Linux la strada resta il modulo out-of-tree +`i2c-nct6775` (`openrgb-dkms`) che espone un adapter i2c, non un backend interno di +OpenRGB: meccanismo diverso, e in `tuf-x299-aura` è bloccato per decisione di Simone +finché `W27` è aperta. + +Morale operativa: `aura-re` è forte dove disassembla (i claim con indirizzo VA reggono lo +spot-check), debole dove riassume l'ecosistema Linux. Prendere i primi, verificare i +secondi.