Здравствуйте, LaptevVV, Вы писали:
LVV>>>Регистры внешних устройств адресовались адресами памяти — это блеск!
LVV>>>Командой пересылки осуществляется ввод-вывод!
K>>А где сейчас это не так?
LVV>В Интеле — отдельная адресация портов.
Далеко не во всём и не везде, и есть заметная тяга в сторону адресации в памяти (коллега koandrew объявил это требование абсолютным, но это не так). Преимущества адресации по памяти:
1. Прямой доступ как к куску памяти, чтобы там складывать структуры данных. Особенно ценно для видеопамяти (для которой даже на первых PC был доступ именно как к памяти), но также для сетевых адаптеров, USB, AHCI и многих прочих, где высокоскоростной I/O требует работы в стиле "сформировали связанный список дескрипторов запрошенных операций и пнули адаптер выполнять их".
Для I/O это неудобно — потребовалась бы поддержка компилятора (как в Borland Pascal — IO изображалось массивом), а ещё на x86 дико неудобная и потому медленная адресация I/O (один регистр DX, без индексного регистра и без смещения в команде — то есть на любой чих надо этот DX перезаписывать).
2. Возможность постраничного управления доступом к ресурсу. Например, Linux мапит области таймеров (APIC и HPET) как readonly в юзерские процессы, чтобы операции даже высокоточного чтения таймера не требовали переключения в ядро. IOMMU для виртуалок также позволяет легко пробросить устройство в гостевую систему, если оно выделено в блок 4K-страниц и не соседствует с другими, которых не надо пробрасывать.
Адресация через I/O остаётся, как минимум, для специальных применений:
1. Собственно управление конфигурационным пространством PCI (порты 0CF8, 0CFC). PCI Express повторил этот механизм (как рекомендованный, но на x86 так делают, считаем, все).
2. Совместимость с ISA-стилем, где требуется (поставьте SATA контроллер в IDE режим и увидите, как он всякие 1F0 начнёт аллоцировать).
Но при этом всё равно есть много тех, кто использует хотя бы частично старое. Вот видяха (GT710):
Memory at f2000000 (32-bit, non-prefetchable) [size=16M]
Memory at e8000000 (64-bit, prefetchable) [size=128M]
Memory at f0000000 (64-bit, prefetchable) [size=32M]
I/O ports at e000 [size=128]
Видеопамять одним куском... но и порты рядом. А вот AHCI контроллер — 5 отдельных кусков (!)
I/O ports at f090 [size=8]
I/O ports at f080 [size=4]
I/O ports at f070 [size=8]
I/O ports at f060 [size=4]
I/O ports at f020 [size=32]
Memory at f3126000 (32-bit, non-prefetchable) [size=2K]
Странные люди эти Intel.
И вдогонку: часть I/O проводится сейчас вообще через конфигурационное пространство PCI! Это относится к подавляющей части настроек чипсета. Можно посмотреть в интеловской доке по мостам (северный — в процессоре последние 10 лет), все базовые настройки — только через PCI конфигурацию. I/O порты после этого остаются в основном для внутренней логики устройств, которые в зависимости от поставки могут быть встроенными или дискретными. Но при этом доступ в конфигурационное пространство PCI всё равно идёт через I/O порты, которые тут же перехватывает корневой хаб северного моста
То есть на типичном x86 сейчас не два, а
три таких пространства, каждое чуть для своей роли