diff --git a/content/posts/todo/bc250/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg b/content/posts/todo/bc-zero-board-testing/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg
similarity index 100%
rename from content/posts/todo/bc250/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg
rename to content/posts/todo/bc-zero-board-testing/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg
diff --git a/content/posts/todo/bc-zero-board-testing/images/01-not-fully-convinced.png b/content/posts/todo/bc-zero-board-testing/images/01-not-fully-convinced.png
new file mode 100644
index 0000000..91463ff
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/01-not-fully-convinced.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/02-40cu-unlocked-news.png b/content/posts/todo/bc-zero-board-testing/images/02-40cu-unlocked-news.png
new file mode 100644
index 0000000..19b2f90
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/02-40cu-unlocked-news.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/03-initial-setup.png b/content/posts/todo/bc-zero-board-testing/images/03-initial-setup.png
new file mode 100644
index 0000000..4170d2e
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/03-initial-setup.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/04-bios-flashing.png b/content/posts/todo/bc-zero-board-testing/images/04-bios-flashing.png
new file mode 100644
index 0000000..881d84c
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/04-bios-flashing.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/05-new-boot-logo.png b/content/posts/todo/bc-zero-board-testing/images/05-new-boot-logo.png
new file mode 100644
index 0000000..88a8eac
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/05-new-boot-logo.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/06-new-advanced-menu.png b/content/posts/todo/bc-zero-board-testing/images/06-new-advanced-menu.png
new file mode 100644
index 0000000..9fdcf68
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/06-new-advanced-menu.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/07-uma-512m.png b/content/posts/todo/bc-zero-board-testing/images/07-uma-512m.png
new file mode 100644
index 0000000..6aed3be
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/07-uma-512m.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/08-8-core-unlock.png b/content/posts/todo/bc-zero-board-testing/images/08-8-core-unlock.png
new file mode 100644
index 0000000..40e8f08
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/08-8-core-unlock.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/09-archinstall.png b/content/posts/todo/bc-zero-board-testing/images/09-archinstall.png
new file mode 100644
index 0000000..9f70a70
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/09-archinstall.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/10-fastfetch.png b/content/posts/todo/bc-zero-board-testing/images/10-fastfetch.png
new file mode 100644
index 0000000..9c58e7f
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/10-fastfetch.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/11-baseline-furmark.png b/content/posts/todo/bc-zero-board-testing/images/11-baseline-furmark.png
new file mode 100644
index 0000000..4ca697d
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/11-baseline-furmark.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/12-dead-psu.jpg b/content/posts/todo/bc-zero-board-testing/images/12-dead-psu.jpg
new file mode 100644
index 0000000..408767a
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/12-dead-psu.jpg differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/13-furmark-governor.png b/content/posts/todo/bc-zero-board-testing/images/13-furmark-governor.png
new file mode 100644
index 0000000..5bd5165
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/13-furmark-governor.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/14-furmark-40cu.png b/content/posts/todo/bc-zero-board-testing/images/14-furmark-40cu.png
new file mode 100644
index 0000000..5a928ca
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/14-furmark-40cu.png differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/15-before-heatsink-mod.jpg b/content/posts/todo/bc-zero-board-testing/images/15-before-heatsink-mod.jpg
new file mode 100644
index 0000000..efc40a1
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/15-before-heatsink-mod.jpg differ
diff --git a/content/posts/todo/bc-zero-board-testing/images/16-after-heatsink-mod.jpg b/content/posts/todo/bc-zero-board-testing/images/16-after-heatsink-mod.jpg
new file mode 100644
index 0000000..14ac4f7
Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/16-after-heatsink-mod.jpg differ
diff --git a/content/posts/todo/bc-zero-board-testing/index.it.md b/content/posts/todo/bc-zero-board-testing/index.it.md
new file mode 100644
index 0000000..b800b0e
--- /dev/null
+++ b/content/posts/todo/bc-zero-board-testing/index.it.md
@@ -0,0 +1,532 @@
++++
+title = "BC-Zero - Testing della scheda"
+summary = "Da vecchia scheda da mining a console e server AI"
+date = "2038-01-19"
+
+tags = ["BC-250", "PS5", "Sblocco", "BIOS", "CPU", "GPU"]
+categories = ["Progetti"]
+series = ["BC-Zero"]
+series_order = 1
+
+draft = true
++++
+
+Il 5 febbraio [Soffio](https://t.me/Soffioo), amico e socio
+[LUGMan](https://lugman.org/), mi ha fatto scoprire una scheda particolare: la
+**BC-250**.
+
+La BC-250 è una scheda proveniente da un [rig per il mining di criptovalute di
+ASRock](https://www.tomshardware.com/news/twelve-ps5-apus-power-asrocks-new-cryptomining-rig),
+che ne ospitava dodici.
+
+Dentro ognuna di queste schede c'è un chip *binned* derivato dall'APU AMD della
+PlayStation 5, con 6 degli 8 core CPU e 24 delle 36 CU GPU attivi, insieme a
+16GB di RAM GDDR6 **unificati** tra CPU e GPU, uno slot M.2 (PCIe 2.0x2 o SATA
+III) e poche porte: due USB 2.0, due USB 3.0, una Ethernet Gigabit e una
+DisplayPort. L'alimentazione è fornita da un connettore PCIe a 8 pin.
+
+All'inizio non ero proprio convinto, soprattutto nel vedere un terzo delle CU
+tagliate via così e nel sapere che è una scheda con un chip custom, parzialmente
+bloccato (oltre ai core bloccati, alcune funzionalità come l'enconding/decoding
+video non sono presenti), derivante dal mining e senza alcun tipo di supporto o
+community dietro. Ma il prezzo era decisamente interessante, e a quanto pare
+questa scheda ha una community molto attiva che si impegna per tirarne fuori il
+100% del potenziale su Linux.
+
+
+
+Le cose cambiano però quando la mattina del 30 maggio ricevo questo messaggio:
+
+
+
+E sempre il caro Soffio mi fa presente che da li a breve sarebbero iniziati i
+super sconti AliExpress. Incuriosito dalla faccenda gli chiedo se può prestarmi
+la sua scheda per un po' di giorni, giusto per provarla e vedere cosa si può
+fare.
+
+E *oh boy* se questa scheda mi ha convinto.
+
+## Step 0: Preparazione
+
+Una pecca della BC-250 è che non è proprio *plug-and-play*. Bisogna come minimo:
+
+1. Trovare un alimentatore in grado di fornire ***realmente*** almeno 300W sul
+ rail +12V e con dei cavi che sappiano gestire tutti quegli ampere;
+2. Avere un monitor con DisplayPort (o comprare un adattatore);
+3. Trovare un modo per raffreddare la maledetta;
+4. Flashare il BIOS.
+
+Il mio setup di prova era:
+
+1. Il primo alimentatore marchiato "*el cheapo*" che ho trovato sottomano (che
+ "sicuramente andrà bene, c'è scritto 500W");
+2. Adattatore passivo DP ➜ HDMI;
+3. Climatizzatore portatile per il raffreddamento (era estate e iniziava a fare
+ caldo);
+4. Programmatore SPI CH341 (che avevo già).
+
+
+
+Non proprio il setup migliore per testare la scheda, ma si lavora con quello che
+si ha.
+
+## Step 1: Flashare il BIOS
+
+Il [primo punto sulla documentazione della
+community](https://elektricm.github.io/amd-bc250-docs/getting-started/quick-start/#step-1-bios-flash-critical)
+è il flashing del BIOS. Senza un BIOS custom non si hanno funzionalità
+essenziali come l'allocazione dinamica della VRAM (voglio ricordare che i 16GB
+di RAM sono condivisi) e una corretta gestione delle ventole.
+
+All'inizio ho installato quello consigliato dalla guida, quello di
+[TuxThePenguin0](https://gitlab.com/TuxThePenguin0/bc250-bios), ma più avanti ho
+scoperto un altro BIOS, quello di [Forbidden
+Darkness](https://github.com/Forbidden-Darkness/AMD-BC-250-UEFI-v2.2-Firmware-Menu-Script)
+che, oltre allo sblocco del menù per l'allocazione dinamica offre una selezioni
+di immagini di splash custom e, soprattutto, **lo sblocco di tutti gli 8 core
+CPU**.
+
+"*Ma come, non erano bloccati?*" A quanto pare non abbastanza.
+
+L'APU ha tutti i core presenti sul silicio, sono solo disattivati via firmware.
+Un principio simile vale anche per le CU della GPU, ma lo vedremo dopo.
+
+---
+
+L'installazione è anche più semplice e non richiede un flasher BIOS: basta
+copiare i file contenuti nell'archivio `.7z` delle release in una chiavetta
+formattata in FAT32 e farci il boot. L'installer chiede che splash image
+vogliamo (la
+[`07`](https://github.com/user-attachments/assets/ca23ce6c-08ab-4293-9a70-0e55f66dc93c)
+è la migliore *imho*) e procede a flashare.
+
+
+
+{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557"
+textColor="#1d3557" >}}
+Il flashing del BIOS è un operazione pericolosa. Assicuratevi che la scheda non
+si spenga nel mentre.
+{{< /alert >}}
+
+Una volta terminato il flashing bisogna resettare tutte le impostazioni del
+BIOS. Per farlo basta staccare l'alimentazione e bridgare i pin 2 e 3
+dell'header `CLRCMOS1` per qualche secondo. Una volta fatto possiamo
+ripristinare l'header sui pin 1 e 2, ricollegare l'alimentazione ed entrando nel
+BIOS premendo `Canc` all'avvio vedremo molte più opzioni.
+
+
+
+
+Per prima cosa facciamo in modo che l'allocazione di VRAM sia automatica. Per
+farlo dobbiamo andare nella sezione `Chipset` > `GFX Configuration` > `GFX
+Configuration` e impostare `Integrated Graphics Controller` a `Forces`, poi `UMA
+Mode` a `UMA_SPECIFIED` e infine `UMA Frame buffer size` a `512M`.
+
+
+
+Poi in `NB Configuration` disabilitiamo l'IOMMU (su questa scheda sembra non
+essere funzionante)
+
+Infine abilitiamo tutti i core andando nella sezione `Advanced` > `MeiMeiDXEv3
+Menu` e abilitando tutto.
+
+
+
+{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557"
+textColor="#1d3557" >}}
+Nulla garantisce che i tutti core siano funzionanti. Core danneggiati potrebbero
+causare crash improvvisi.
+
+Per evitare ciò faremo uno stress-test su tutti i core e controlleremo che nei
+log del kernel non appaia nessun `Machine Check Exception` prima di abilitare
+questa impostazione in produzione
+{{< /alert >}}
+
+Una volta che abbiamo configurato correttamente il BIOS siamo pronti per
+installare un sistema operativo e testare per bene questa scheda.
+
+## Step 2: Installazione di un OS di prova
+
+Per fare un po' di stress testing CPU e per fare dei test con la GPU installerò
+Arch Linux.
+
+Non sarà la distro finale che andrò ad installare, ma la scelta non è casuale:
+lo sviluppo di questa scheda è bleeding-edge e per ora quasi tutti gli script
+assumono che sia installato Arch o Fedora per avere le ultime versioni dei
+pacchetti.
+
+
+
+
+### Test degli 8 core
+
+Per prima cosa testiamo se tutti gli 8 core funzionano come dovrebbero. Per
+farlo installiamo il pacchetto `stress-ng` e facciamo uno stress test:
+
+```sh
+stress-ng --cpu 16 --cpu-method all --verify --timeout 2h --metrics
+```
+
+Verifichiamo poi che non ci siano stati errori con:
+
+```sh
+sudo dmesg | grep -iE "mce|machine check|hardware error"
+```
+
+Se il kernel non segnala alcun errore siamo appena passati da 6 a 8 core
+gratuitamente. In caso di errore invece è possibile modificare quali core
+attivare e quali no dal BIOS.
+
+### Stress-testing della GPU
+
+Facciamo poi uno stress testing della GPU per avere una baseline delle
+performance prima di installare il governor o abilitare tutte le CU. Per farlo
+ho installato Furmark e ho fatto il test 1080p
+
+
+
+Direi che 70 FPS non sono *così* male per la scheda *out-of-the-box*, ma si può
+sicuramente fare di meglio, molto meglio.
+
+---
+
+Piccola nota che mi sento di aggiungere: se durante lo stess test lo schermo
+diventa nero e la scheda non risponde in alcun modo, controllate
+l'alimentazione. Il piccolo *foreshadowing* che ho fatto nello step 0 riguardo
+all'alimentatore riguarda il fatto che durante i miei test ho fatto girare
+Ollama e ho completamente bruciato la power supply dato che (a quanto pare) non
+riusciva a gestire davvero tutto il carico sul rail +12V. Ho successivamente
+comprato su AliExpress, insieme alla scheda, il PSU consigliato dalla community,
+il [Metalfish 500W
+FlexATX](https://elektricm.github.io/amd-bc250-docs/hardware/power#option-2-flexatx-psu-500w)
+e da li non ho più avuto problemi.
+
+
+
+### Installazione del Governor GPU
+
+Di default la GPU gira sempre a 1500MHz: un governor permette di alzare il clock
+quando la GPU è sotto carico e di abbassarlo quando non lo è per consumare meno.
+
+Installeremo `cyan-skillfish-governor-smu`, progetto della community che
+comunica direttamente con la System Management Unit della scheda. È anche già
+pacchettizzato nella AUR, quindi per installarlo basta lanciare un:
+
+```sh
+paru -S cyan-skillfish-governor-smu
+systemctl enable --now cyan-skillfish-governor-smu
+```
+
+Possiamo contollare che funzioni con:
+
+```
+$ cat /sys/class/drm/card1/device/pp_dpm_sclk # Se non funziona prova con card0
+0: 1000Mhz *
+1: 1500Mhz
+2: 2000Mhz
+```
+
+La prima e l'ultima riga sono rispettivamente la frequenza minima e massima
+della GPU, mentre il valore centrale è variabile. L'asterisco indica la
+frequenza attualmente in uso. Un esempio sotto sforzo:
+
+```
+$ cat /sys/class/drm/card1/device/pp_dpm_sclk
+0: 1000Mhz
+1: 1850Mhz *
+2: 2000Mhz
+```
+
+Dovremmo vedere che la GPU usa automaticamente una frequenza più alta sotto
+sforzo e più bassa a riposo.
+
+---
+
+**Piccola nota**: lo sblocco degli 8 core influisce sulla lettura dei valori
+dell'SMU. È un problema noto ed andremo a risolverlo più avanti, quando ci
+preoccuperemo del sistema operativo. Senza alcun fix i valori di frequenza
+risultano sbagliati, ad esempio:
+
+```
+$ cat /sys/class/drm/card1/device/pp_dpm_sclk
+0: 1000Mhz *
+1: 4575Mhz
+2: 2000Mhz
+
+# Per un chip che può andare al massimo a 2230MHz non è male come overclock
+```
+
+Detto ciò facciamo uno stress test adesso, con il governor installato.
+
+
+
+Adesso che riusciamo a scalare fino a 1850MHz la nostra GPU riesce ad arrivare a
+83 FPS in 1080p, niente male!
+
+1850MHz non è assolutamente il massimo che questo chip può gestire, ma per
+adesso ci accontenteremo di questo. Per i più curiosi la curva delle frequenze e
+delle tensioni è completamente personalizzabile e si trova in
+`/etc/cyan-skillfish-governor-smu/config.toml`. Con un po' di prove si può
+spingere al massimo l'hardware minimizzando i consumi, ma lo faremo sempre
+quando andremo a configurare il sistema operativo definitivo.
+
+### Sblocco delle 40 CU
+
+Come abbiamo detto all'inizio questa scheda presenta al kernel solamente 24 CU,
+nonostante nella PS5 ce ne siano 36 e sul silicio ce ne siano effettivamente 40.
+Possiamo verificarlo con:
+
+```
+$ sudo dmesg | grep active_cu_number
+[ 6.882856] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 24
+```
+
+Per testare e successivamente sbloccare tutte le CU useremo il [repository di
+duggasco](https://github.com/duggasco/bc250-40cu-unlock). Il meccanismo è simile
+a quello dello sblocco dei core: anche qui basta cambiare qualche valore, perché
+le CU non sono bloccate a livello hardware, ma solo disattivate dal firmware.
+
+A decidere quante CU sono attive sono due registri della GPU. Quello che fa
+questo script è patchare il driver `amdgpu` e scrivere i valori giusti nei
+registri mentre il driver si avvia, avviando le CU spente.
+
+```
+$ git clone https://github.com/duggasco/bc250-40cu-unlock.git
+$ cd bc250-40cu-unlock/
+$ sudo pacman -S linux-headers vulkan-headers
+$ sudo scripts/bc250-enable-40cu-arch.sh build
+
+# Attendi la ricompilazione del modulo `amdgpu`
+
+$ sudo scripts/bc250-enable-40cu-arch.sh enable
+```
+
+Una volta che la BC-250 si sarà riavviata possiamo verificare che la patch ha
+funzionato usando sempre il comando di prima:
+
+```
+$ sudo dmesg | grep active_cu_number
+[ 8.004012] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 24
+
+```
+
+A quanto pare il modulo custom non viene caricato in automatico dallo script.
+Non è un problema: rigeneriamo l'initramfs e riavviamo a mano:
+
+```
+$ sudo mkinitcpio -P
+$ reboot
+
+# Una volta che si è riavviato
+$ sudo dmesg | grep active_cu_number
+[ 8.058999] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 40
+```
+
+Molto meglio!
+
+---
+
+Una volta installato il modulo custom possiamo procedere con il testing delle
+CU:
+
+```
+$ sudo scripts/bc250-cu-health-test.sh start
+```
+
+Durante il test il PC si riavvierà automaticamente una ventina di volte. Una
+volta che il PC smette di riavviarsi in automatico possiamo vedere i risultati
+del test con:
+
+```
+$ scripts/cu_map.sh
+
+BC-250 CU Map + Health
+SE0 SH0: ■■■■■■■■■■
+SE0 SH1: ■■■■■■■■■■
+SE1 SH0: ■■■■■■■■■■
+SE1 SH1: ■■■■■■■■■■
+40/40 CUs active, 0 harvested
+
+BC-250 CU Map + Health
+SE0 SH0: ■■■■■■✓✓✓✓
+SE0 SH1: ■■■■■■✓✓✓✓
+SE1 SH0: ■■■■■■✓✓✓✓
+SE1 SH1: ■■■■■■✓✓✓✓
+40/40 CUs usable (0 defective, masked)
+```
+
+A quanto pare ho vinto la lotteria del silicio e ho 8 core e 40 CU funzionanti.
+Urrà! 🎉
+
+In caso però ci fossero state delle CU difettose avrei potuto mascherarle usando
+lo script `bc250-cu-mask.sh`.
+
+---
+
+Facendo l'ultimo stress test con Furmark:
+
+
+
+Siamo passati dalla scheda nuda e cruda, senza alcun software aggiuntivo, che
+girava mediamente a 70 FPS ad avere un governor e tutte le CU sbloccate per
+avere dei picchi da 138 FPS, il doppio!
+
+Ovviamente questo approccio per lo sblocco delle 40 CU ha un problema abbastanza
+evidente soprattutto su distribuzioni rolling come Arch: bisogna ricordarsi di
+ricompilare il modulo ogni volta che si aggiorna il kernel. Anche questo è un
+problema che risolveremo più avanti, quando smetteremo di usare un OS di prova,
+ma se dopo un aggiornamento la GPU non va più veloce quanto prima forse è meglio
+buttarci un occhio.
+
+### Sensori e altre configurazioni indispensabili
+
+Una volta sistemate le cose essenziali come CPU e GPU rimangono alcune piccole
+accortezze, come ad esempio la gestione dei sensori, delle ventole, la swap, lo
+split della VRAM, ecc...
+
+Potrei starne per ore a parlarne, ma rimando alla [documentazione della
+community](https://elektricm.github.io/amd-bc250-docs/), che è ben fornita.
+
+Quello che mi sento di fare adesso è far notare una cosa: usando il comando
+`sensors` abbiamo pochi dati OOTB:
+
+```
+$ sensors
+amdgpu-pci-0100
+Adapter: PCI adapter
+vddgfx: 799.00 mV
+vddnb: 799.00 mV
+edge: +39.0°C
+PPT: 41.41 W (avg = 40.85 W)
+sclk: 1000 MHz
+
+k10temp-pci-00c3
+Adapter: PCI adapter
+Tctl: +41.6°C
+```
+
+Per avere più dati abbiamo bisogno del modulo `nct6683` (read-only) o `nct6687`
+(si possono creare curve custom, ma è *out of tree*). Dato che `nct6683` è già
+disponibile possiamo abilitarlo con:
+
+```
+$ echo 'options nct6683 force=true' | sudo tee /etc/modprobe.d/sensors.conf
+$ echo 'nct6683' | sudo tee /etc/modules-load.d/99-sensors.conf
+$ sudo mkinitcpio -P
+$ reboot
+```
+
+Dopo aver riavviato vedremo molti più dati:
+
+```
+$ sensors
+k10temp-pci-00c3
+Adapter: PCI adapter
+Tctl: +46.9°C
+
+amdgpu-pci-0100
+Adapter: PCI adapter
+vddgfx: 799.00 mV
+vddnb: 799.00 mV
+edge: +41.0°C
+PPT: 42.61 W (avg = 40.75 W)
+sclk: 1000 MHz
+
+nct6686-isa-0a20
+Adapter: ISA adapter
+VIN0: 800.00 mV (min = +0.00 V, max = +0.00 V)
+VIN1: 1.01 V (min = +0.00 V, max = +0.00 V)
+VIN2: 992.00 mV (min = +0.00 V, max = +0.00 V)
+VIN6: 1.39 V (min = +0.00 V, max = +0.00 V)
+VIN7: 800.00 mV (min = +0.00 V, max = +0.00 V)
+VIN16: 896.00 mV (min = +0.00 V, max = +0.00 V)
+fan1: 0 RPM (min = 0 RPM)
+fan2: 1709 RPM (min = 0 RPM)
+fan3: 0 RPM (min = 0 RPM)
+fan4: 0 RPM (min = 0 RPM)
+fan5: 0 RPM (min = 0 RPM)
+AMD TSI Addr 98h: +47.0°C (low = +0.0°C)
+ (high = +0.0°C, hyst = +0.0°C)
+ (crit = +0.0°C) sensor = AMD AMDSI
+Thermistor 14: +37.0°C (low = +0.0°C)
+ (high = +0.0°C, hyst = +0.0°C)
+ (crit = +0.0°C) sensor = thermistor
+Thermistor 15: +37.0°C (low = +0.0°C)
+ (high = +0.0°C, hyst = +0.0°C)
+ (crit = +0.0°C) sensor = thermistor
+pwm1: 64%
+pwm2: 64%
+pwm3: 64%
+pwm4: 64%
+pwm5: 64%
+intrusion0: OK
+beep_enable: disabled
+```
+
+## Step 3: Modifiche hardware
+
+Vorrei ricordare che per tutti questi test stavo utilizzando la BC-250 di
+Soffio, giusto per vedere se mi potesse interessare. E dato che ormai ero
+abbastanza preso, decido di prendermi tutto l'occorrente da AliExpress.
+
+Per fortuna con i saldi e anche grazie a TopCashback riesco a portarmi a casa
+tutto il necessario per meno di 200€. Compro poi un paio di Arctic P12 Pro da
+Amazon.
+
+In data 24 giugno mi arriva il tutto, e quindi ci si mette all'opera per fare:
+
+* Cambio pasta e pad termici;
+* Installazione dei dissipatori sul pannello posteriore, in modo da raffreddare
+ le GDDR6;
+* Rimozione della linguetta metallica e dell'I/O shield (servono solo se la
+ scheda viene montata nel rig);
+* Rifare la suite di test sopracitati per vedere se avevo vinto la lotteria del
+ silicio per la seconda volta (per fortuna sì);
+* Modifica del dissipatore.
+
+La modifica del dissipatore mi permette di risolvere uno dei problemi che stavo
+avendo con la scheda, ovvero: come rimuovo 200W di calore? Per adesso avevo il
+pinguino, ma non potevo continuare ad usare una pompa di calore per raffreddare
+una singola scheda.
+
+Quando sono nel rig da mining, le BC-250 hanno tutti il dissipatore disposto
+longitudinalmente, quindi basta un array di ventole per raffreddare tutte e 12
+le schede contemporaneamente. Se si vuole usare una di queste schede
+indipendentemente bisogna diventare un po' più creativi per rimuovere il calore.
+
+La soluzione più comune nella community è la [heatsink
+mod](https://reddit.com/r/BC250Gaming/comments/1rjc3io/), che consiste di aprire
+letteralmente il dissipatore nella sezione sopra l'APU per avere un posto dove
+mettere la ventola.
+
+È un operazione un po' lunga e tediosa, ma nulla di impossibile. È anche un
+compito abbastanza ripetitivo, quindi una volta che si è presa la mano finisce
+presto. Alla fine mi ci è voluta solo una forbice, buona musica e un'ora del mio
+tempo.
+
+
+
+
+È un lavoro un po' *rough around the edges* (*literally*), ma funziona. E il
+foro è grande esattamente quando una ventola da 120mm, quindi una delle due
+ventole porta soffiare direttamente sopra all'APU.
+
+---
+
+Dato che questo articolo si è fatto abbastanza lungo mi sento di spezzettarlo in
+più parti. Nella prossima andremo a progettare un case custom per il mio use
+case.
diff --git a/content/posts/todo/bc-zero-board-testing/index.md b/content/posts/todo/bc-zero-board-testing/index.md
new file mode 100644
index 0000000..2915845
--- /dev/null
+++ b/content/posts/todo/bc-zero-board-testing/index.md
@@ -0,0 +1,525 @@
++++
+title = "BC-Zero - Board Testing"
+summary = "From an old mining board to a console and AI server"
+date = "2038-01-19"
+
+tags = ["BC-250", "PS5", "Unlock", "BIOS", "CPU", "GPU"]
+categories = ["Projects"]
+series = ["BC-Zero"]
+series_order = 1
+
+draft = true
++++
+
+On February 5th, [Soffio](https://t.me/Soffioo), a friend and fellow
+[LUGMan](https://lugman.org/) member, made me discover a peculiar board: the
+**BC-250**.
+
+The BC-250 is a board that comes from an [ASRock cryptocurrency mining
+rig](https://www.tomshardware.com/news/twelve-ps5-apus-power-asrocks-new-cryptomining-rig),
+which housed twelve of them.
+
+Inside each of these boards there's a *binned* chip derived from the AMD APU of
+the PlayStation 5, with 6 of the 8 CPU cores and 24 of the 36 GPU CUs enabled,
+along with 16GB of GDDR6 RAM **unified** between CPU and GPU, an M.2 slot (PCIe
+2.0x2 or SATA III), and just a few ports: two USB 2.0, two USB 3.0, one Gigabit
+Ethernet, and one DisplayPort. Power is supplied through an 8-pin PCIe
+connector.
+
+At first I wasn't really convinced, especially seeing a third of the CUs cut off
+and knowing that it's a board with a custom, partially locked chip (on top of
+the locked cores, some features like video encoding/decoding are missing),
+coming from cryptocurrency mining and with no support or community behind it.
+But the price was definitely interesting, and apparently this board has a very
+active community that works hard to squeeze 100% of its potential out of it on
+Linux.
+
+
+
+Things changed when, on the morning of May 30th, I got this message:
+
+
+
+And good old Soffio also pointed out that the AliExpress sales were about to
+start. Intrigued by the whole thing, I asked him if he could lend me his board
+for a few days, just to try it out and see what could be done.
+
+And *oh boy*, did this board convince me.
+
+## Step 0: Preparation
+
+One downside of the BC-250 is that it's not exactly *plug-and-play*. At the very
+least, you need to:
+
+1. Find a power supply that can ***really*** deliver at least 300W on the +12V
+ rail, with cables that can handle all those amperes;
+2. Have a monitor with DisplayPort (or buy an adapter);
+3. Find a way to cool the damn thing;
+4. Flash the BIOS.
+
+My test setup was:
+
+1. The first "*el cheapo*" power supply I could find lying around (which "will
+ surely be fine, it says 500W");
+2. A passive DP ➜ HDMI adapter;
+3. A portable air conditioner for cooling (it was summer and it was starting to
+ get hot);
+4. A CH341 SPI programmer (which I already had).
+
+
+
+Not exactly the best setup for testing the board, but you work with what you
+have.
+
+## Step 1: Flashing the BIOS
+
+The [first step in the community
+documentation](https://elektricm.github.io/amd-bc250-docs/getting-started/quick-start/#step-1-bios-flash-critical)
+is flashing the BIOS. Without a custom BIOS you don't get essential features
+like dynamic VRAM allocation (remember, the 16GB of RAM are shared) and proper
+fan control.
+
+At first I installed the one recommended by the guide, the one by
+[TuxThePenguin0](https://gitlab.com/TuxThePenguin0/bc250-bios), but later on I
+discovered another BIOS, the one by [Forbidden
+Darkness](https://github.com/Forbidden-Darkness/AMD-BC-250-UEFI-v2.2-Firmware-Menu-Script),
+which, on top of unlocking the dynamic allocation menu, offers a selection of
+custom splash images and, most importantly, **unlocks all 8 CPU cores**.
+
+"*Wait, weren't they locked down?*" Apparently not enough.
+
+The APU has all cores on the silicon, they're just disabled via firmware. A
+similar principle also applies to the GPU CUs, but we'll get to that later.
+
+---
+
+The installation is even simpler and doesn't require a BIOS flasher: just copy
+the files from the `.7z` archive in the releases to a USB stick formatted in
+FAT32 and boot from it. The installer asks which splash image we want (the
+[`07`](https://github.com/user-attachments/assets/ca23ce6c-08ab-4293-9a70-0e55f66dc93c)
+is the best one, *imho*) and proceeds with the flashing.
+
+
+
+{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557"
+textColor="#1d3557" >}}
+Flashing the BIOS is a dangerous operation. Make sure the board doesn't turn
+off.
+{{< /alert >}}
+
+Once the flashing is done, you need to reset all the BIOS settings. To do that,
+just unplug the power and bridge pin 2 and 3 of the `CLRCMOS1` header for a few
+seconds. Once that's done, we can put the header back on pins 1 and 2 and plug
+the power back in. By entering the BIOS with the `Del` key at boot we'll see a
+lot more options.
+
+
+
+
+First, let's make the VRAM allocation automatic. To do that, we need to go to
+`Chipset` > `GFX Configuration` > `GFX Configuration` and set `Integrated
+Graphics Controller` to `Forces`, then `UMA Mode` to `UMA_SPECIFIED`, and
+finally `UMA Frame buffer size` to `512M`.
+
+
+
+Then in `NB Configuration` disable the IOMMU (it doesn't seem to work on this
+board).
+
+Finally, we enable all the cores by going to `Advanced` > `MeiMeiDXEv3 Menu` and
+enabling everything.
+
+
+
+{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557"
+textColor="#1d3557" >}}
+There's no guarantee that all the cores will work. Damaged cores could cause
+sudden crashes.
+
+To avoid that, we'll run a stress test on all the cores and check that no
+`Machine Check Exception` shows up in the kernel logs before enabling this
+setting in production.
+{{< /alert >}}
+
+Once the BIOS is properly configured, we're ready to install an operating system
+and test this board for real.
+
+## Step 2: Installing a OS for testing
+
+To do some CPU stress testing and run some tests on the GPU, I'll install Arch
+Linux.
+
+It won't be the final distro I'll install, but the choice isn't random:
+development for this board is bleeding-edge, and for now almost all the scripts
+assume you're running Arch or Fedora, so you have the latest package versions.
+
+
+
+
+### Testing the 8 cores
+
+First of all, let's test whether all 8 cores work as they should. To do that,
+install the `stress-ng` package and run a stress test:
+
+```sh
+stress-ng --cpu 16 --cpu-method all --verify --timeout 2h --metrics
+```
+
+Then we check that there were no errors with:
+
+```sh
+sudo dmesg | grep -iE "mce|machine check|hardware error"
+```
+
+If the kernel doesn't report any errors, we've just gone from 6 to 8 cores for
+free. If there is an error you can change which cores to enable from the BIOS.
+
+### Stress-testing the GPU
+
+Next, let's stress test the GPU to get a performance baseline before installing
+the governor or enabling all the CUs. To do that, I installed Furmark and ran
+the 1080p test.
+
+
+
+I'd say 70 FPS isn't *that* bad for the board *out-of-the-box*, but we can
+definitely do better, much better.
+
+---
+
+A small note I feel I should add: if during the stress test the screen goes
+black and the board doesn't respond in any way, check your power supply. The
+little foreshadowing I did in step 0 about the power supply is because during my
+tests I ran Ollama and completely fried the PSU since (apparently) it couldn't
+really handle the whole load on the +12V rail. I then bought the PSU recommended
+by the community on AliExpress, along with the board, the [Metalfish 500W
+FlexATX](https://elektricm.github.io/amd-bc250-docs/hardware/power#option-2-flexatx-psu-500w),
+and I haven't had any problems since.
+
+
+
+### Installing the GPU Governor
+
+By default the GPU always runs at 1500MHz: a governor lets you raise the clock
+when the GPU is under load and lower it when it isn't, to save power.
+
+We'll install `cyan-skillfish-governor-smu`, a community project that talks
+directly to the board's System Management Unit. It's also already packaged in
+the AUR, so to install it you just need to run:
+
+```sh
+paru -S cyan-skillfish-governor-smu
+systemctl enable --now cyan-skillfish-governor-smu
+```
+
+We can check that it works with:
+
+```
+$ cat /sys/class/drm/card1/device/pp_dpm_sclk # If it doesn't work, try card0
+0: 1000Mhz *
+1: 1500Mhz
+2: 2000Mhz
+```
+
+The first and last lines are, respectively, the minimum and maximum GPU
+frequency, while the middle line can change. The asterisk marks the frequency
+currently in use. An example under load:
+
+```
+$ cat /sys/class/drm/card1/device/pp_dpm_sclk
+0: 1000Mhz
+1: 1850Mhz *
+2: 2000Mhz
+```
+
+We should see the GPU automatically use a higher frequency under load and a
+lower one when idle.
+
+---
+
+**Small note**: unlocking the 8 cores affects how the SMU values are read. It's
+a known issue and we'll fix it later on, when we'll deal with the operating
+system. Without any fix, the frequency values are wrong, for example:
+
+```
+$ cat /sys/class/drm/card1/device/pp_dpm_sclk
+0: 1000Mhz *
+1: 4575Mhz
+2: 2000Mhz
+
+# Not a bad overclock for a chip that tops out at 2230MHz
+```
+
+With that said, let's run a stress test now, with the governor installed.
+
+
+
+Now that we can scale up to 1850MHz, our GPU manages to reach 83 FPS at 1080p,
+not bad!
+
+1850MHz is by no means the most this chip can handle, but for now we'll settle
+for it. For the curious, the frequency and voltage curves are fully customizable
+and live in `/etc/cyan-skillfish-governor-smu/config.toml`. With a bit of trial
+and error you can push the hardware to its limits while minimizing power draw,
+but we'll do that when we set up the final operating system.
+
+### Unlocking the 40 CUs
+
+As we said at the beginning, this board only exposes 24 CUs to the kernel, even
+though the PS5 has 36 and there are actually 40 on the silicon. We can verify
+this with:
+
+```
+$ sudo dmesg | grep active_cu_number
+[ 6.882856] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 24
+```
+
+To test and then unlock all the CUs, we'll use [duggasco's
+repository](https://github.com/duggasco/bc250-40cu-unlock). The mechanism is
+similar to the core unlock: here too you just need to change a few values,
+because the CUs aren't locked at the hardware level, they're just disabled by
+the firmware.
+
+Two registers in the GPU decide how many CUs are active. What this script does
+is patch the `amdgpu` driver and write the right values into those registers
+while the driver starts up, waking up the disabled CUs.
+
+```
+$ git clone https://github.com/duggasco/bc250-40cu-unlock.git
+$ cd bc250-40cu-unlock/
+$ sudo pacman -S linux-headers vulkan-headers
+$ sudo scripts/bc250-enable-40cu-arch.sh build
+
+# Wait for the `amdgpu` module to be recompiled
+
+$ sudo scripts/bc250-enable-40cu-arch.sh enable
+```
+
+Once the BC-250 has rebooted, we can check that the patch worked using the same
+command as before:
+
+```
+$ sudo dmesg | grep active_cu_number
+[ 8.004012] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 24
+
+```
+
+Apparently the script doesn't load the custom module automatically. That's not a
+problem: let's regenerate the initramfs and reboot manually:
+
+```
+$ sudo mkinitcpio -P
+$ reboot
+
+# Once it has rebooted
+$ sudo dmesg | grep active_cu_number
+[ 8.058999] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 40
+```
+
+Much better!
+
+---
+
+Once the custom module is installed, we can move on to testing the CUs:
+
+```
+$ sudo scripts/bc250-cu-health-test.sh start
+```
+
+During the test the PC will automatically reboot twenty times. Once the PC stops
+rebooting on its own, we can see the test results with:
+
+```
+$ scripts/cu_map.sh
+
+BC-250 CU Map + Health
+SE0 SH0: ■■■■■■■■■■
+SE0 SH1: ■■■■■■■■■■
+SE1 SH0: ■■■■■■■■■■
+SE1 SH1: ■■■■■■■■■■
+40/40 CUs active, 0 harvested
+
+BC-250 CU Map + Health
+SE0 SH0: ■■■■■■✓✓✓✓
+SE0 SH1: ■■■■■■✓✓✓✓
+SE1 SH0: ■■■■■■✓✓✓✓
+SE1 SH1: ■■■■■■✓✓✓✓
+40/40 CUs usable (0 defective, masked)
+```
+
+Apparently I won the silicon lottery and have 8 cores and 40 working CUs.
+Hurray! 🎉
+
+If there had been any defective CUs I could have masked them using the
+`bc250-cu-mask.sh` script.
+
+---
+
+Running the last stress test with Furmark:
+
+
+
+We went from the bare board, without any additional software, running at an
+average of 70 FPS, to having a governor and all the CUs unlocked, with peaks of
+138 FPS, twice as much!
+
+Of course, this approach to unlocking the 40 CUs has a pretty obvious problem,
+especially on rolling distributions like Arch: you have to recompile the module
+every time you update the kernel. This is another problem we'll solve later on,
+when we stop using a test OS, but if after an update the GPU isn't as fast as
+before, it might be worth taking a look.
+
+### Sensors and Other Essential Configurations
+
+Once the essentials like CPU and GPU are sorted out, there are still a few small
+things to take care of, such as sensor management, fans, swap, VRAM split,
+etc...
+
+I could go on about it for hours, but I'll point you to the [community
+documentation](https://elektricm.github.io/amd-bc250-docs/), which is very
+thorough.
+
+What I'd like to do now is point out one thing: using the `sensors` command, we
+get very little data OOTB:
+
+```
+$ sensors
+amdgpu-pci-0100
+Adapter: PCI adapter
+vddgfx: 799.00 mV
+vddnb: 799.00 mV
+edge: +39.0°C
+PPT: 41.41 W (avg = 40.85 W)
+sclk: 1000 MHz
+
+k10temp-pci-00c3
+Adapter: PCI adapter
+Tctl: +41.6°C
+```
+
+To get more data we need the `nct6683` module (read-only) or `nct6687` (you can
+create custom curves with it, but it's *out of tree*). Since `nct6683` is
+already available, we can enable it with:
+
+```
+$ echo 'options nct6683 force=true' | sudo tee /etc/modprobe.d/sensors.conf
+$ echo 'nct6683' | sudo tee /etc/modules-load.d/99-sensors.conf
+$ sudo mkinitcpio -P
+$ reboot
+```
+
+After rebooting we'll see a lot more data:
+
+```
+$ sensors
+k10temp-pci-00c3
+Adapter: PCI adapter
+Tctl: +46.9°C
+
+amdgpu-pci-0100
+Adapter: PCI adapter
+vddgfx: 799.00 mV
+vddnb: 799.00 mV
+edge: +41.0°C
+PPT: 42.61 W (avg = 40.75 W)
+sclk: 1000 MHz
+
+nct6686-isa-0a20
+Adapter: ISA adapter
+VIN0: 800.00 mV (min = +0.00 V, max = +0.00 V)
+VIN1: 1.01 V (min = +0.00 V, max = +0.00 V)
+VIN2: 992.00 mV (min = +0.00 V, max = +0.00 V)
+VIN6: 1.39 V (min = +0.00 V, max = +0.00 V)
+VIN7: 800.00 mV (min = +0.00 V, max = +0.00 V)
+VIN16: 896.00 mV (min = +0.00 V, max = +0.00 V)
+fan1: 0 RPM (min = 0 RPM)
+fan2: 1709 RPM (min = 0 RPM)
+fan3: 0 RPM (min = 0 RPM)
+fan4: 0 RPM (min = 0 RPM)
+fan5: 0 RPM (min = 0 RPM)
+AMD TSI Addr 98h: +47.0°C (low = +0.0°C)
+ (high = +0.0°C, hyst = +0.0°C)
+ (crit = +0.0°C) sensor = AMD AMDSI
+Thermistor 14: +37.0°C (low = +0.0°C)
+ (high = +0.0°C, hyst = +0.0°C)
+ (crit = +0.0°C) sensor = thermistor
+Thermistor 15: +37.0°C (low = +0.0°C)
+ (high = +0.0°C, hyst = +0.0°C)
+ (crit = +0.0°C) sensor = thermistor
+pwm1: 64%
+pwm2: 64%
+pwm3: 64%
+pwm4: 64%
+pwm5: 64%
+intrusion0: OK
+beep_enable: disabled
+```
+
+## Step 3: Hardware Mods
+
+I want to remind you that for all these tests I was using Soffio's BC-250, just
+to see whether it was something I'd be interested in. And since I found myself
+pretty hooked I decided to get everything I needed from AliExpress.
+
+Luckily with the sales and also using TopCashback I managed to bring home
+everything I needed for less than €200. I then bought a couple of Arctic P12
+Pros from Amazon.
+
+Everything arrived on June 24th, so it was time to get to work on:
+
+* Replacing the thermal paste and pads;
+* Installing heatsinks on the back panel, to cool the GDDR6;
+* Removing the metal bracket and the I/O shield (they're only needed if the
+ board is mounted in the rig);
+* Re-running the test suite mentioned above to see if I had won the silicon
+ lottery a second time (luckily I did);
+* Modding the heatsink.
+
+The heatsink mod let me solve one of the problems I was having with the board:
+how do I get rid of 200W of heat? So far I had the portable AC, but I couldn't
+keep using a heat pump to cool a single board.
+
+When they're in the mining rig, the BC-250 all have their heatsinks laid out
+lengthwise, so a single array of fans is enough to cool all 12 boards at once.
+If you want to use one of these boards on its own, you need to get a bit more
+creative to get rid of the heat.
+
+The most common solution in the community is the [heatsink
+mod](https://reddit.com/r/BC250Gaming/comments/1rjc3io/), which consists of
+literally cutting open the heatsink in the section above the APU to make room
+for a fan.
+
+It's a somewhat long and tedious job, but it's not impossible to do. It's also a
+pretty repetitive task, so once you get the hang of it, it goes by farely
+quickly. In the end all it took was a pair of scissors, some good music, and an
+hour of my time.
+
+
+
+
+It's a bit *rough around the edges* (*literally*), but it works. And the hole is
+big exactly as a 120mm fan, so one of the two fans can blow directly onto the
+APU.
+
+---
+
+Since this article has gotten pretty long, I've decided to split it into
+multiple parts. In the next one, we'll design a custom case for my needs.
diff --git a/content/posts/todo/bc250/index.it.md b/content/posts/todo/bc250/index.it.md
deleted file mode 100644
index aec6fea..0000000
--- a/content/posts/todo/bc250/index.it.md
+++ /dev/null
@@ -1,12 +0,0 @@
-+++
-title = "BC-Zero"
-summary = "Da vecchia scheda da mining a console e server AI"
-date = "2038-01-19"
-
-tags = ["BC-250", "PS5", "AI", "AI Locale", "SteamOS", "CachyOS"]
-categories = ["Progetti"]
-
-draft = true
-+++
-
-> Hello, world!
diff --git a/content/posts/todo/bc250/index.md b/content/posts/todo/bc250/index.md
deleted file mode 100644
index 9f3fcc2..0000000
--- a/content/posts/todo/bc250/index.md
+++ /dev/null
@@ -1,12 +0,0 @@
-+++
-title = "BC-Zero"
-summary = "From an old mining card to a console and AI server"
-date = "2038-01-19"
-
-tags = ["BC-250", "PS5", "AI", "Local AI", "SteamOS", "CachyOS"]
-categories = ["Projects"]
-
-draft = true
-+++
-
-> Hello, world!