Mappage d’adresses Bus-Relative à des adresses virtuelles
Certains processeurs implémentent des espaces d’adressage de mémoire et d’E/S distincts, contrairement à d’autres processeurs. En raison de ces différences dans les plateformes matérielles, les mécanismes utilisés par les pilotes pour accéder aux ressources d’appareil d’E/S ou de mémoire diffèrent d’une plateforme à l’autre.
Un pilote demande des ressources d’E/S et de mémoire de périphérique en réponse à l’IRP IRP_MN_QUERY_RESOURCE_REQUIREMENTS du gestionnaire PnP. Selon l’architecture matérielle, hal peut affecter des ressources d’E/S dans l’espace d’E/S ou dans l’espace mémoire, et peut affecter des ressources mémoire dans l’espace d’E/S ou dans l’espace mémoire.
Si hal utilise l’espace mémoire relatif du bus pour accéder aux ressources de périphérique (telles que les registres de périphériques), un pilote doit mapper l’espace d’E/S dans la mémoire virtuelle afin qu’il puisse accéder à ces ressources. Le pilote peut déterminer si les ressources résident en mémoire ou en E/S en inspectant les ressources traduites transmises au pilote par le gestionnaire PnP au démarrage de l’appareil. Si la hal utilise l’espace d’E/S, aucun mappage n’est requis.
Plus précisément, lorsqu’un pilote reçoit une demande de IRP_MN_START_DEVICE, il doit examiner les structures dans IrpSp-Parameters.StartDevice.AllocatedResources> et IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated>, qui décrivent les ressources brutes (relatives au bus) et traduites, respectivement, que le gestionnaire PnP a affectées à l’appareil. Les pilotes doivent enregistrer une copie de chaque liste de ressources dans l’extension de périphérique pour faciliter le débogage.
Les listes de ressources sont associées CM_RESOURCE_LIST structures, dans lesquelles chaque élément de la liste brute correspond au même élément de la liste traduite. Par exemple, si AllocatedResources.List[0] décrit une plage de ports d’E/S brutes, AllocatedResourcesTranslated.List[0] décrit la même plage après la traduction. Chaque ressource traduite inclut une adresse physique et le type de la ressource.
Si un pilote se voit attribuer une ressource de mémoire traduite (CmResourceTypeMemory), il doit appeler MmMapIoSpace pour mapper l’adresse physique à une adresse virtuelle via laquelle il peut accéder aux registres d’appareils. Pour qu’un pilote fonctionne de manière indépendante de la plateforme, il doit case activée chaque ressource retournée, traduite et la mapper, si nécessaire.
Un pilote en mode noyau doit effectuer les étapes suivantes, en réponse à une demande de IRP_MN_START_DEVICE, pour garantir l’accès à toutes les ressources d’appareil
Copiez IrpSp-Parameters.StartDevice.AllocatedResources> dans l’extension d’appareil.
Copiez IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated> dans l’extension de l’appareil.
Dans une boucle, inspectez chaque élément de descripteur dans AllocatedResourcesTranslated. Si le type de ressource de descripteur est CmResourceTypeMemory, appelez MmMapIoSpace en passant l’adresse physique et la longueur de la ressource traduite.
Lorsque le pilote reçoit une demande IRP_MN_STOP_DEVICE ou IRP_MN_REMOVE_DEVICE du gestionnaire PnP, il doit libérer les mappages en appelant MmUnmapIoSpace dans une boucle similaire. Le pilote doit également appeler MmUnmapIoSpace s’il doit échouer à la demande IRP_MN_START_DEVICE .
Le type de ressource brute indique la routine d’accès HAL qu’un pilote doit appeler (READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX). La plupart des pilotes n’ont pas besoin d’case activée la liste des ressources brutes pour déterminer quelles routines utiliser, car le pilote lui-même a demandé la ressource ou l’enregistreur de pilotes connaît le type requis compte tenu de la nature du matériel de l’appareil.
Pour une ressource dans l’espace d’E/S (CmResourceTypePort, CmResourceTypeInterrupt, CmResourceTypeDma), le pilote doit utiliser les 32 bits de bas ordre de l’adresse physique retournée pour accéder à la ressource de périphérique, par exemple, via les routines de lecture et d’écriture de HAL READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXXWRITE_PORT_XXX .