1) Могу ли я добавить устройство к этой шине ввода-вывода, не используя PCI или любую другую шину?
В теории; да. Однако для современных систем отсутствует общая / общая шина (теперь это «точка-точка»); Контроллеры памяти и хосты PCI встроены в тот же чип, что и ЦП, что означает, что (если вы не являетесь сотрудником поставщика ЦП, такого как Intel), вам придется иметь дело с высокоскоростными последовательными каналами (Quick-path, Гипертранспорт, PCIe или DMI), которые недешевы или просты в интерфейсе (другими словами, это не то, что в 1980-х, когда у вас есть хорошая и медленная шина ISA, чтобы подключиться).
Если да, как назначаются адреса ввода / вывода? Разве они не конфликтуют?
Устаревшие устройства используют фиксированные порты ввода-вывода, которые были назначены историей / совместимостью. Все остальное назначается динамически с помощью своего рода «распределителя диапазона портов ввода-вывода» (встроенного в микропрограмму и / или операционную систему), который настраивает BAR (регистры «Base Address Range») в пространстве конфигурации PCI. Существовали некоторые (ныне устаревшие / несуществующие) альтернативы - назначаемые вручную физическими перемычками или микропереключателями на картах ISA, спецификация ISA «включай и работай», которая в основном заменялась PCI, прежде чем многие устройства ее поддерживали, и функции, которые существовали в другие виды автобусов (MCA и EISA) для динамического распределения ресурсов. Конечно, большинство современных устройств вообще не используют порты ввода-вывода (а вместо этого используют регистры с отображением в памяти).
2-) Если мой процессор поддерживает PCI и I²C (да, некоторые делают!), Как процессор различает их адреса ввода-вывода? Как он узнает, что адрес ввода / вывода принадлежит PCI или I²C.
Для I²C, вероятно, где-то будет пара регистров (либо в адресном пространстве порта IO, либо в физическом адресном пространстве) для отправки и получения байта в / из шины I²C. Все на шине I²C будут доступны через эти 2 регистра, и ничто на шине I²C не будет иметь доступа ко всему, что не находится на шине I²C (включая отсутствие доступа к любым портам ввода-вывода и отсутствие доступа к каким-либо физическим адреса).
В основном (например, Ethernet, видео, USB, ...) у вас есть контроллер (который имеет регистры, к которым процессор может получить прямой доступ), который управляет чем-то, к чему процессор не может получить прямой доступ (LAN, сигналы на монитор, USB устройства, подключенные к шине USB, ...).
(упрощенный) Пример
Предположим, что (из-за инструкции out dx,al
) ЦП отправляет сообщение на общей шине или ссылку, которая говорит "command = WRITE, space = IO port space, address = 0x1234, size = 1 byte, data = 0x56
". Это сообщение может быть перехвачено хост-контроллером PCI, который просматривает детали (какой адрес в каком адресном пространстве) и решает переслать сообщение на устройство «PCI-LPC-мост» на шине PCI. Когда «мост PCI-LPC» получает сообщение, он может посмотреть детали (какой адрес в каком адресном пространстве) и понять, что он соответствует контроллеру шины I²C, и направить его на контроллер шины I²C. Контроллер шины I²C может декодировать сообщение и отправлять байт 0x56 (из части «данные» сообщения) на шину I²C. Затем, возможно, устройство, которое прослушивает шину I²C, видит этот байт 0x56 и отвечает, отправляя байт 0x78 через шину I²C на контроллер шины I²C, где контроллер сохраняет значение 0x78 во внутреннем регистре буфера.
Далее; (биз-за указания in al,dx
) ЦП может послать другое сообщение с надписью "command = READ, space = IO port space, address = 0x1234, size = 1 byte
". Это сообщение будет следовать тому же пути, что и предыдущий (потому что адрес и адресное пространство одинаково), и в конечном итоге будет на контроллере шины I²C. Контроллер шины I²C может декодировать сообщение и понять, что сообщение запрашивается для чтения из внутреннего регистра буфера контроллера шины I²C (который содержит значение 0x78 от ранее); поэтому контроллер шины I²C отправляет обратно сообщение «command = READ_REPLY, space = IO port space, address = 0x1234, size = 1 byte, data = 0x78
». Это ответное сообщение будет возвращено в ЦП (снова используя тот же путь, но в противоположном направлении - например, к мосту PCI-LPC, затем к хост-контроллеру PCI, затем к ЦП). Когда процессор получает ответ, он может выполнить исходную инструкцию, которая его вызвала (например, установить al
в значение, которое было в сообщении «READ_reply», чтобы завершить инструкцию in al,dx
).
Дело в том, что ЦП не может отправлять что-либо напрямую на устройство на шине I²C (ЦП может общаться только с контроллером шины I²C); и никакое устройство на шине I²C также не может отправлять что-либо напрямую в ЦП (они также могут общаться только с контроллером шины I²C). На шине I²C ничего не нужно знать о портах ввода-вывода; и ничто на шине / каналах процессора не должно ничего знать о байтах на шине I²C.
Также; процессор просто отправляет и получает сообщения. Он не знает, что с ними происходит после их отправки, и не знает, как (например) сообщение «command = READ
» будет перенаправлено с того, что куда, и не знает, какое устройство отправит обратно «. command = READ_REPLY
"сообщение. Маршрутизация в основном зависит от логики на каждом этапе пути, по которому проходит сообщение. Например, хост-контроллер PCI может быть настроен на пересылку всех сообщений для доступа к портам ввода-вывода в диапазоне от 0x0000 до 0x2000 на шину PCI, а мост PCI-LPC может быть настроен на пересылку всех сообщений для доступа к портам ввода-вывода в диапазоне 0x1234. 0x1235 к контроллеру шины I²C.