Поделиться через


Сопоставление адресов Bus-Relative с виртуальными адресами

Некоторые процессоры реализуют отдельные адресные пространства памяти и ввода-вывода, а другие процессоры этого не делают. Из-за этих различий на аппаратных платформах механизмы, используемые для доступа к ресурсам устройств ввода-вывода или памяти, отличаются от платформы к платформе.

Драйвер запрашивает ресурсы ввода-вывода и памяти устройства в ответ на IRP_MN_QUERY_RESOURCE_REQUIREMENTS IRP диспетчера PnP. В зависимости от архитектуры оборудования HAL может назначать ресурсы ввода-вывода в пространстве ввода-вывода или в пространстве памяти, а также назначать ресурсы памяти в пространстве ввода-вывода или в пространстве памяти.

Если HAL использует относительное пространство памяти шины для доступа к ресурсам устройства (например, регистры устройств), драйвер должен сопоставить пространство ввода-вывода с виртуальной памятью, чтобы получить доступ к этим ресурсам. Драйвер может определить, являются ли ресурсы резидентами ввода-вывода или памяти, проверяя переведенные ресурсы, переданные водителю диспетчером PnP при запуске устройства. Если в HAL используется пространство ввода-вывода, сопоставление не требуется.

В частности, когда драйвер получает запрос IRP_MN_START_DEVICE, он должен проверить структуры на IrpSp->Parameters.StartDevice.AllocatedResources и IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated, которые описывают необработанные (относительные шины) и переведенные ресурсы, соответственно, которые диспетчер PnP назначил устройству. Драйверы должны сохранять копию каждого списка ресурсов в расширении устройства в качестве помощи в отладке.

Списки ресурсов связаны CM_RESOURCE_LIST структурами, в которых каждый элемент необработанного списка соответствует одному элементу преобразованного списка. Например, если AllocatedResources.List[0] описывает необработанный диапазон портов ввода-вывода, AllocatedResourcesTranslated.List[0] описывает тот же диапазон после перевода. Каждый переведенный ресурс включает физический адрес и тип ресурса.

Если драйверу назначен переведённый ресурс памяти (CmResourceTypeMemory), необходимо вызвать MmMapIoSpace, чтобы сопоставить физический адрес с виртуальным адресом, через который можно получить доступ к регистрам устройства. Чтобы драйвер работал независимо от платформы, он должен проверять каждый возвращенный, переведенный ресурс и сопоставлять его при необходимости.

Драйвер в режиме ядра должен выполнить следующие действия в ответ на запрос IRP_MN_START_DEVICE, чтобы обеспечить доступ ко всем ресурсам устройства

  1. Скопируйте IrpSp->Parameters.StartDevice.AllocatedResources в расширение устройства.

  2. Скопируйте IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated в расширение устройства.

  3. В цикле проверьте каждый элемент дескриптора в AllocatedResourcesTranslated. Если тип ресурса дескриптора — CmResourceTypeMemory, вызовите MmMapIoSpace, передав физический адрес и размер отображаемого ресурса.

Когда драйвер получает запрос IRP_MN_STOP_DEVICE или IRP_MN_REMOVE_DEVICE от диспетчера PnP, он должен освободить сопоставления путем вызова MmUnmapIoSpace в аналогичном цикле. Драйвер также должен вызвать MmUnmapIoSpace, если необходимо отказать в выполнении запроса IRP_MN_START_DEVICE.

Тип необработанного ресурса указывает, какую подпрограмму доступа HAL должен вызывать драйвер (READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX). Большинству драйверов не нужно проверять список необработанных ресурсов, чтобы определить, какие из этих подпрограмм следует использовать, так как сам драйвер запрашивал ресурс или модуль записи драйверов знает необходимый тип, учитывая характер оборудования устройства.

Для ресурса в пространстве ввода-вывода (CmResourceTypePort, CmResourceTypeInterrupt, CmResourceTypeDma) драйвер должен использовать младшие 32 бита возвращаемого физического адреса для доступа к ресурсу устройства, например через функции HAL, такие как READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX.