Mapeando endereços de Bus-Relative para endereços virtuais
Alguns processadores implementam espaços de endereço de E/S e memória separados, enquanto outros processadores não. Devido a essas diferenças nas plataformas de hardware, os drivers de mecanismo usados para acessar recursos de dispositivo residentes em memória ou de E/S diferem de plataforma para plataforma.
Um driver solicita recursos de E/S e memória do dispositivo em resposta ao IRP IRP_MN_QUERY_RESOURCE_REQUIREMENTS do gerenciador PnP. Dependendo da arquitetura de hardware, o HAL pode atribuir recursos de E/S no espaço de E/S ou no espaço de memória e pode atribuir recursos de memória no espaço de E/S ou no espaço de memória.
Se o HAL usar espaço de memória relativo ao barramento para acessar recursos do dispositivo (como registros de dispositivo), um driver deverá mapear o espaço de E/S para a memória virtual para que ele possa acessar esses recursos. O driver pode determinar se os recursos são residentes de E/S ou memória inspecionando os recursos traduzidos passados para o driver pelo gerenciador PnP na inicialização do dispositivo. Se o HAL usar espaço de E/S, nenhum mapeamento será necessário.
Especificamente, quando um driver recebe uma solicitação IRP_MN_START_DEVICE, ele deve examinar as estruturas em IrpSp-Parameters.StartDevice.AllocatedResources> e IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated>, que descrevem os recursos brutos (relativos ao barramento) e traduzidos, respectivamente, que o gerenciador PnP atribuiu ao dispositivo. Os drivers devem salvar uma cópia de cada lista de recursos na extensão do dispositivo como um auxílio à depuração.
As listas de recursos são emparelhadas CM_RESOURCE_LIST estruturas, nas quais cada elemento da lista bruta corresponde ao mesmo elemento da lista traduzida. Por exemplo, se AllocatedResources.List[0] descreve um intervalo de portas de E/S bruto, AllocatedResourcesTranslated.List[0] descreve o mesmo intervalo após a tradução. Cada recurso traduzido inclui um endereço físico e o tipo do recurso.
Se um driver receber um recurso de memória traduzido (CmResourceTypeMemory), ele deverá chamar MmMapIoSpace para mapear o endereço físico em um endereço virtual por meio do qual ele pode acessar registros de dispositivo. Para que um driver opere de maneira independente da plataforma, ele deve marcar cada recurso retornado, traduzido e mapeá-lo, se necessário.
Um driver no modo kernel deve seguir as etapas a seguir, em resposta a uma solicitação de IRP_MN_START_DEVICE, para garantir o acesso a todos os recursos do dispositivo
Copie IrpSp-Parameters.StartDevice.AllocatedResources> para a extensão do dispositivo.
Copie IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated> para a extensão do dispositivo.
Em um loop, inspecione cada elemento descritor em AllocatedResourcesTranslated. Se o tipo de recurso do descritor for CmResourceTypeMemory, chame MmMapIoSpace, passando o endereço físico e o comprimento do recurso traduzido.
Quando o driver recebe uma solicitação IRP_MN_STOP_DEVICE ou IRP_MN_REMOVE_DEVICE do gerenciador PnP, ele deve liberar os mapeamentos chamando MmUnmapIoSpace em um loop semelhante. O driver também deve chamar MmUnmapIoSpace se ele precisar falhar na solicitação de IRP_MN_START_DEVICE .
O tipo de recurso bruto indica qual rotina de acesso HAL um driver deve chamar (READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX). A maioria dos drivers não precisa marcar a lista de recursos brutos para determinar qual dessas rotinas usar, pois o próprio driver solicitou o recurso ou o gravador de driver sabe o tipo necessário dada a natureza do hardware do dispositivo.
Para um recurso no espaço de E/S (CmResourceTypePort, CmResourceTypeInterrupt, CmResourceTypeDma), o driver deve usar os 32 bits de ordem baixa do endereço físico retornado para acessar o recurso do dispositivo, por exemplo, por meio das rotinas de leitura e gravação do HAL READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX .