bytexu
驱动牛犊
驱动牛犊
  • 注册日期2001-03-23
  • 最后登录2018-05-30
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望130点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1259回复:0

Choosing the Correct HAL Function for Device Access

楼主#
更多 发布于:2002-06-20 10:30
Choosing the Correct HAL Function for Device Access

Ó 1997 OSR Open Systems Resources, Inc.

 

One of the most frequently misunderstood topics about writing NT device drivers seems to be how driver writers choose between using the HAL’s port access functions (such as READ_PORT_UCHAR) and the HAL’s register access functions (such as READ_REGISTER_UCHAR). Judging from the number of times we get this question in our kernel device driver seminars, and the number of times we see this question show up in news groups, there are plenty of people who are confused. Like so many things in NT, this isn’t a difficult or complex topic, it’s just that how to make the decision isn’t well documented. Let’s see if we can help.

When a controller or adapter card is designed, the hardware designer implements a set of registers that will be used to control and access the device. These registers will typically contain things like the device’s interrupt enable and status bit and (depending on the device type) even the registers to or from which data is moved. The address corresponding to each of these registers may reside in either memory space or port I/O space. When designing the board, the hardware designer will decide the address space in which each one of these registers resides.

The way in which this decision is implemented is straight forward. On the PCI bus, for example, if a particular register is to be located in port I/O space, the command type encoded on the PCI bus (on the C/BE#[3::0] signal lines) when accessing the register’s address will indicate that a port I/O space address is being accessed. If a register is to be located in memory space, the address decoding for that register will require the command type indicate a memory space access. The way port addresses are differentiated on the ISA, EISA, and MCA busses is similar.

As you can probably guess, Intel x86 architecture systems issue PCI bus port access commands when performing one of the special port I/O space access instructions (such as IN and OUT). But even on CPUs that do not support a separate port I/O space (such as the Alpha) a device on the PCI bus still require port access commands to access port space addresses. Without special I/O space instructions available on these systems, how do port access commands ever get built? The typical approach is that hardware system designer chooses some set of physical memory addresses that will be used on the system to correspond to port I/O addresses. For example, the hardware designer might choose to map port addresses to the physical address range 0xFFFF0000-0xFFFFFFFF. Thus, whenever the address 0xFFFF0180 is referenced on the system the support hardware on the system translates this reference to address 0x180 on the PCI bus, with a command indicating a port access. Of course, the HAL cooperates in this game. Neat, eh?

So the hardware designer of a particular controller or adapter board decides in which address space the board’s registers reside. Once this decision has been made, so has the driver writer’s decision about which of the HAL’s functions the driver writer will use to reference those registers. The driver writer will always use the HAL function that corresponds to the space in which the register(s) he wants to access resides.

If a device driver writer wants to access a register that a hardware designer has located in Port I/O space, the driver writer will code all accesses to this register from his driver using READ_PORT_xxx and WRITE_PORT_xxx functions. To access registers that the hardware designer has located in memory space, the driver writer will use the HAL’s READ_REGISTER_xxx and WRITE_REGISTER_xxx functions. Note that this is true whether or not the platform on which the driver is running has native support for a separate port I/O space.

That things work this way is the very point of NT having a HAL. The driver writer develops platform independent code, targeted to the HAL’s processor abstraction. The HAL \"does the right thing\" so that when a READ_PORT_xxx call is coded on an Intel x86 architecture system, the HAL issues an x86 IN instruction. Likewise, when that same call is coded on an Alpha architecture system the HAL issues a move (memory) instruction. In this way, platform independence is preserved
游客

返回顶部