Digital I/O (DIO)
Программируемый GPIO: 10-pin гребёнка на I2C GPIO-экспандере NXP PCA9554PW. Сидит на SMBus PCH, который общий с BMC (AST2500) — поэтому управляется и из хост ОС, и из BMC (даже при выключенном хосте). В BIOS setup и веб-морде BMC отдельных настроек нет. Единственная дока из мануала — Appendix D (только регистры).
Механизм
- Шина: SMBus PCH (Intel C620
i801, IOBASE0x0780). Шина общая с BMC: на BMC она видна какi2c-0(i2c-as-0), там видны те же устройства, и BMC управляет DIO даже при выключенном хосте - I2C адрес:
0x22(7-bit). В мануале дефолт0b0100100x=0x24, но на плате A0..A2 припаяны как010 - Логика: 5В (чип питается от 5В, pull-up входов тоже на 5В)
- Выходы push-pull, регистр input отражает реальное состояние пинов (включая выходы) — удобно как readback
- По-умолчанию (после сброса) все пины — входы с подтяжкой вверх (
config = 0xff)
Распиновка
| 1 | DIO1 | GPIO0 | out | 2 | DIO8 | GPIO7 | in |
| 3 | DIO2 | GPIO1 | out | 4 | DIO7 | GPIO6 | in |
| 5 | DIO3 | GPIO2 | out | 6 | DIO6 | GPIO5 | in |
| 7 | DIO4 | GPIO3 | out | 8 | DIO5 | GPIO4 | in |
| 9 | NC | — | — | 10 | GND | — | — |
Ряд выходов (1,3,5,7) — нечётные пины, ряд входов (2,4,6,8) — чётные, но пронумерованы «назад» (DIO8→pin2 … DIO5→pin8).
Регистры
Командный байт — первый байт после адреса, указатель на регистр:
| Cmd | Регистр | Доступ |
|---|---|---|
| 0 | Input port | Read only |
| 1 | Output port | R/W |
| 2 | Polarity inversion | R/W |
| 3 | Configuration | R/W (0=out, 1=in) |
Дефолты: config=0xff (всё входы), output=0xff, polarity=0x00.
Примеры
Все примеры требуют i2c-tools и sudo.
Прочитать входы (биты 7:4)
$ i2cget -y 0 0x22 0
0xf0
Настроить GPIO3:0 как выходы и включить все
$ i2cset -y 0 0x22 3 0xf0 # GPIO7:4 = in, GPIO3:0 = out
$ i2cset -y 0 0x22 1 0x0f # все 4 выхода в 1 (5В)
Включить конкретные пины
Маска выхода = биты 0..3 → пины 1,3,5,7:
$ i2cset -y 0 0x22 1 0x05 # пины 1 (GPIO0) и 5 (GPIO2)
$ i2cset -y 0 0x22 1 0x00 # все выходы в 0
Readback выходов
Input port отражает и выходы — записали, прочитали:
$ i2cset -y 0 0x22 1 0x0f && i2cget -y 0 0x22 0
0xff
Вернуть в стоковое состояние
$ i2cset -y 0 0x22 3 0xff # всё входы
$ i2cset -y 0 0x22 1 0xff
Управление из BMC
Шина общая, так что DIO можно дёргать с BMC. ВАЖНО: чип запитывается только при включённом хосте — без хоста запись ioctl-ом проходит, но пины остаются 0В (проверено на стенде). Так что для «джампер ресета BIOS» это не годится — для удалённого сброса BIOS используй IPMI boot flags.
В нашем моде dio лежит в payload-слоте, busybox-апплеты в /var/applets:
$ /var/payload/dio/dio.sh status # out=.. in=.. cfg=..
$ /var/payload/dio/dio.sh on 0x05 # GPIO0 и GPIO2 в 1 (пины 1 и 5)
$ /var/payload/dio/dio.sh pulse 0x01 2 # GPIO0 в 1 на 2 сек, потом в 0
$ /var/payload/dio/dio.sh off # все выходы в 0
$ /var/payload/dio/dio.sh reset # вернуть в сток
Прямые команды: /var/payload/dio/dio r /dev/i2c-0 0x22 <reg> / w. Проверено: запись с BMC видна с хоста и наоборот (при включённом хосте).
Заметки
- Чтобы определить направление/землю гребёнки без мануала: включить все выходы (
0x0f) — 0В останется только на GND (pin 10) и NC (pin 9). - Выходы реально дёргают пины (проверено на стенде: input-port меняется за записями).
- Без включённого хоста чип (PCA9554) обесточен — записи «проходят» (ACK), но напряжения на пинах нет; чтения с общей шины при выключенном хосте падают (известный баг host-off I2C).
0x48на той же шине — не DIO (весь регистр-флаг0xff, похоже на EEPROM/другое устройство);0x2f— термомониторnct7802.