Как сказал Майкл Петч в своем комментарии это производитель, но он не всегда обладает полной свободой.
Стандарты и спецификации могут предписывать использование адресного пространства, некоторые стандарты являются общими (например,OHCI, USB 1.0, относится к «не кэшируемому адресному пространству», которое в x86 может быть как IO, так и MMIO), а другое - нет (например, спецификация TPM Client PC сопоставляет регистры TPM по месту на основе используемой области MMIO).
Насколько я знаю, и насколько мы заинтересованы в этом ответе, внедрение MMIO стало массовым с появлением PCI 1 .
PCI BARs (BaseАдресные регистры) имеют специальный формат, позволяющий программному обеспечению узнать, какое адресное пространство используется картой (и сколько его требуется):
Бит 0 доступен только для чтения (устанавливается производителем) и сообщает, какое адресное пространство используется картой.
Пространство ввода-вывода имеет преимущество перед MMIO в том, что не требует какой-либо настройки, MMIO требуется виртуальное сопоставление с физическим и правильный тип кэширования.
Однако пространство ввода-вывода составляет всего 64 КБ + 3B, оно очень маленький.
Фактически PCI 2.2 ограничивает максимальное пространство ввода-вывода, используемое одним BAR, 256 байтами.
Извините за изображение, копирование из спецификации PDF дает мне бред
Более того, указатели не работают в пространстве ввода-вывода, а некоторые устройства работают с указателями (например, USB-контроллеры, GBe и т. Д.).
IO, безусловно, используется для устаревших устройств (до того, как MMIO был чем-то особенным).
Я привык думать, что IO использовался для устройств, которые имеют небольшое количество регистров, но это не всегда так, дляНапример, регистры управления Power Manager PCH (чипсета) сопоставлены с IO и занимают 128B.
Иногда устройство поддерживает как IO, так и MMIO.Для этого требуются два BAR, например, контроллер SMBus PCH:
Он имеет два BAR (обратите внимание на значение по умолчанию, один для IOдругой для MMIO), который контролирует такой же набор регистров.
В документации указано, что могут использоваться оба.
Я не могу дать точное правило, когда используется IO против MMIO.
Я не думаю, что есть разница в производительности, различие лишь в бите в пакете TLP, отправляемом канальным уровнем PCIe..
Однако я никогда не исследовал этот вопрос, инструкции ввода-вывода сериализуются, поэтому на уровне программного обеспечения снижается производительность.
Мое эмпирическое правило заключается в том, что IO используется / может использоваться, если выполняется любое из следующих условий:
- Устройство является устаревшим (здесь действительно нет свободы выбора).
- Ваше устройство не использует указатели (потому что у IO нет указателей), а набор регистров невелик.
- Регистры в основном используются для управления и отчета о состоянии устройства илився система (потому что инструкции ввода-вывода сериализуются).
Это просто правило, основанное на моих чтениях и воспоминаниях, есть много исключений и встречных примеров для них.
Сегодня существует тенденция использовать MMIO, для этого может потребоваться больше логики декодирования (больше адресных линий для декодирования), но спецификация PCI упрощает ее, позволяя устройству округлять свое декодирование до 4 КБ.
Одним из примеров является пространство конфигурации PCIe, в PCI к нему был осуществлен доступ ввода-вывода (сЭтот метод похож на стек регистров, используемый, например, в контроллере VGA, но теперь отображен в памяти.
Нет необходимости рассматривать другие шины, поскольку PCIe является основной шиной на современных ПК, все остальное проходит через устройство PCIe (например, USB использует устройства PCI xHCI).
Единственным исключением из этого являются неосновные устройства (например, LAPIC, регистры TXT), доступ к которым осуществляется через IO с отображением в памяти, потому что он более производительный. Думаю, этот доступ не будет сделан системному агенту в любом случае, близко к их ядру и внутри пакета ЦП), поэтому использование (сериализационной) инструкции ввода-вывода существенно повлияет на них.
К тому же, в верхней части 4GiB есть отличное место, где Intel может восстанавливать память без особого давления на другие устройства.
Интересный факт: порты 0xf8-0xff зарезервированы из-за времен, когда FPU был сопроцессором (x87), и эти порты использовались процессором для связи с ним.
1 До этого обе другие шины PnP уже были доступны (например, PnP ISA и MCA), но декодирование обращений к памяти в основном осуществлялось для предоставления доступа к ПЗУ. и на карте памяти. Думаю, сопоставление регистров с памятью еще не было.