Asignación de direcciones Bus-Relative a direcciones virtuales
Algunos procesadores implementan espacios de direcciones de E/S y memoria independientes, mientras que otros procesadores no. Debido a estas diferencias en las plataformas de hardware, los controladores de mecanismo usan para acceder a los recursos de dispositivo residentes en memoria o E/S difieren de la plataforma a la plataforma.
Un controlador solicita recursos de E/S de dispositivo y memoria en respuesta a la IRP_MN_QUERY_RESOURCE_REQUIREMENTS IRP del administrador de PnP. Dependiendo de la arquitectura de hardware, HAL puede asignar recursos de E/S en espacio de E/S o en espacio de memoria, y puede asignar recursos de memoria en espacio de E/S o en espacio de memoria.
Si HAL usa espacio de memoria relativa al bus para acceder a los recursos del dispositivo (como los registros de dispositivos), un controlador debe asignar espacio de E/S a la memoria virtual para que pueda acceder a estos recursos. El controlador puede determinar si los recursos son residentes en memoria o E/S inspeccionando los recursos traducidos pasados al controlador por el administrador de PnP en el inicio del dispositivo. Si HAL usa espacio de E/S, no se requiere ninguna asignación.
En concreto, cuando un controlador recibe una solicitud de IRP_MN_START_DEVICE, debe examinar las estructuras en IrpSp-Parameters.StartDevice.AssignResources> e IrpSp-Parameters.StartDevice.AssignResourcesTranslated>, que describen los recursos sin procesar (relativos al bus) y traducidos, respectivamente, que el administrador de PnP ha asignado al dispositivo. Los controladores deben guardar una copia de cada lista de recursos en la extensión de dispositivo como ayuda para la depuración.
Las listas de recursos se emparejan CM_RESOURCE_LIST estructuras, en las que cada elemento de la lista sin procesar corresponde al mismo elemento de la lista traducida. Por ejemplo, si AllocatedResources.List[0] describe un intervalo de puertos de E/S sin procesar, AllocatedResourcesTranslated.List[0] describe el mismo intervalo después de la traducción. Cada recurso traducido incluye una dirección física y el tipo del recurso.
Si a un controlador se le asigna un recurso de memoria traducido (CmResourceTypeMemory), debe llamar a MmMapIoSpace para asignar la dirección física a una dirección virtual a través de la cual puede acceder a los registros del dispositivo. Para que un controlador funcione de forma independiente de la plataforma, debe comprobar cada recurso devuelto, traducido y asignarlo, si es necesario.
Un controlador en modo kernel debe realizar los pasos siguientes, en respuesta a una solicitud de IRP_MN_START_DEVICE, para garantizar el acceso a todos los recursos del dispositivo.
Copie IrpSp-Parameters.StartDevice.AllocatedResources> en la extensión del dispositivo.
Copie IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated> en la extensión del dispositivo.
En un bucle, inspeccione cada elemento descriptor en AllocatedResourcesTranslated. Si el tipo de recurso descriptor es CmResourceTypeMemory, llame a MmMapIoSpace y pase la dirección física y la longitud del recurso traducido.
Cuando el controlador recibe una solicitud de IRP_MN_STOP_DEVICE o IRP_MN_REMOVE_DEVICE del administrador de PnP, debe liberar las asignaciones llamando a MmUnmapIoSpace en un bucle similar. El controlador también debe llamar a MmUnmapIoSpace si debe producir un error en la solicitud de IRP_MN_START_DEVICE .
El tipo de recurso sin procesar indica a qué rutina de acceso HAL debe llamar un controlador (READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX). La mayoría de los controladores no tienen que comprobar la lista de recursos sin procesar para determinar cuál de estas rutinas usar, ya que el propio controlador solicitó el recurso o el escritor de controladores conoce el tipo necesario según la naturaleza del hardware del dispositivo.
Para un recurso en el espacio de E/S (CmResourceTypePort, CmResourceTypeInterrupt, CmResourceTypeDma), el controlador debe usar los 32 bits de orden bajo de la dirección física devuelta para acceder al recurso del dispositivo, por ejemplo, a través de las rutinas de lectura y escritura de HAL, READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX .