DIO Driver

I apologize if this is the wrong place to ask this question. I am
moving a driver from a framework called WinDK (which I was actually
very happy with) and trying to recode it in Kmdf. It’s a pretty
straightforward driver for a custom PCI card with memory, interrupt,
etc. I have been a fan of OSR for years and thought that looking
through the OSR Dio driver might be helpful. Anyways…

In the wdfdio.cpp file, DioEvtPrepareHardware function I see that it’s
iterating over the resource types, and in the CmResourceTypePort case
it is just setting the device context BaseAddress variable to the
LowPart of the translated resource. But why is it not necessary to
map the address? Like in the ResourceTypeMemory?

Thanks,
Michael

It is only necessary to map MEMORY space resources into virtual address space.

Port space is an entirely separate space that is accessed on x86 architecture machines using special instructions (“in” and “out”). It is not part of main memory. Resources that are identified as being in Port space by the HAL are usable directly via WRITE_PORT_xxxx calls, which use the port address and “do the right thing.”

BTW, this is a general Windows principle, not just a KMDF one.

Peter
OSR

>>

In the wdfdio.cpp file, DioEvtPrepareHardware function I see that it’s iterating over the resource types, and in the CmResourceTypePort case it is just setting the device context BaseAddress variable to the LowPart of the translated resource. But why is it not necessary to map the address? Like in the ResourceTypeMemory?
[rbk]
Conceptually, because port addresses (in a separate address space from memory in x86/x64 and accessed by different instructions (in…, out…) than memory) are never virtual- there is no physical-to-virtual translation done by the processor at all. So they can’t be mapped.

Ah. Thank you (and Bob). I think I understand. One other thing that
I am having trouble with is determining what is what in the resource
list. Using WinDK I was able to do something like:

CResource *pResources = new CResource( pTranslatedResourceList,
this );

// get the port-mapped AMCC Operations registers
if ((!pResources->GetPortResource(&m_Registers0, 0))) {
}
// get the memory regions we need
if (!pResources->GetMemoryResource(&m_MemoryAddress0, 0))
{
}
if (!pResources->GetMemoryResource(&m_MemoryAddress1, 1))
{
}
// get the memory regions we need
if ( !pResources->GetMemoryResource( &m_MemoryAddress2, 2 ) )
{
}
// get the interrupt resource
if ( !pResources->GetInterruptResource( &m_Interrupt ) )
{
}
Error checking deleted above. I know that our device has a single
port space and 3 memory resources. I indexed them by 0, 1, 2. Can I
assume (oh I hate that) the memory resources are in the same order
each time? So I can increment a variable (++NumberofMemAddrs) each
time we map one and do another switch based on that number? Or is
there some better way of handling this?

Thanks again,
Michael

On Mon, 13 Dec 2010 19:28:19 -0500 (EST), xxxxx@osr.com wrote:

It is only necessary to map MEMORY space resources into virtual address space.

Port space is an entirely separate space that is accessed on x86 architecture machines using special instructions (“in” and “out”). It is not part of main memory. Resources that are identified as being in Port space by the HAL are usable directly via WRITE_PORT_xxxx calls, which use the port address and “do the right thing.”

BTW, this is a general Windows principle, not just a KMDF one.

Peter
OSR

Michael Wade wrote:

In the wdfdio.cpp file, DioEvtPrepareHardware function I see that it’s
iterating over the resource types, and in the CmResourceTypePort case
it is just setting the device context BaseAddress variable to the
LowPart of the translated resource. But why is it not necessary to
map the address? Like in the ResourceTypeMemory?

At one time, it WAS necessary to map the I/O space, and some people
still do so out of habit. Way back in the mid-1990s, NT also ran on
Alpha, MIPS, and PowerPC processors. Those processors do not have the
concept of “I/O ports”, so PCI devices with I/O space had to be mapped
into part of physical memory.

x86 and x64 processors don’t have to worry about that.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

“Tim Roberts” wrote in message news:xxxxx@ntdev…

At one time, it WAS necessary to map the I/O space, and some people
still do so out of habit. Way back in the mid-1990s, NT also ran on
Alpha, MIPS, and PowerPC processors. Those processors do not have the
concept of “I/O ports”, so PCI devices with I/O space had to be mapped
into part of physical memory.

Just to clarify…This is still an issue on Windows due to the Itanium,
which doesn’t have I/O ports either
(all Itanium jokes aside).

The key then is that you have to dynamically determine *where* your ports
end up on a particular
platform at runtime, which is where the raw and translated resources come
in. Your raw resource
indicates that you have a port on your device and your translated resource
indicates that it’s either
in port space (x86/x64, you don’t have to map) or in memory space (IA64, you
*do* have to map).
The wdfdio driver demonstrates this.

Just want to make it clear that mapping or not mapping isn’t an arbitrary
decision up to the driver
writer.

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Tim Roberts” wrote in message news:xxxxx@ntdev…

Michael Wade wrote:

In the wdfdio.cpp file, DioEvtPrepareHardware function I see that it’s
iterating over the resource types, and in the CmResourceTypePort case
it is just setting the device context BaseAddress variable to the
LowPart of the translated resource. But why is it not necessary to
map the address? Like in the ResourceTypeMemory?

At one time, it WAS necessary to map the I/O space, and some people
still do so out of habit. Way back in the mid-1990s, NT also ran on
Alpha, MIPS, and PowerPC processors. Those processors do not have the
concept of “I/O ports”, so PCI devices with I/O space had to be mapped
into part of physical memory.

x86 and x64 processors don’t have to worry about that.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Agree with Tim Roberts.

PCI devices that have i/o ports are required by the standard to have also memory mapped BAR, and Windows will use the latter - so the drivers have no chance to ever see i/o resources.
IIRC, Microsoft discourages use of i/o ports in modern systems because they complicate deep nesting of PCI bridges.

I/O ports remain either on old ISA or internal chipset devices. Drivers for the latter are provided by platform vendors or MS, so it is Someone Else’s Problem.

Maybe because of this KMDF just does the simplest thing that works for 99.9% users.
If we ever have to deal with i/o port, we can safely assume the driver will not be needed for Itanium.

Regards,
– pa

>PCI devices that have i/o ports are required by the standard to have also

memory mapped BAR, and Windows will use the latter - so the >drivers have
no chance to ever see i/o resources.

We’re talking about a driver (wdfdio) for a PCI device that does indeed have
I/O ports and those are indeed used by the driver. I have written several
drivers for similar devices. Also, nothing in Windows actively prevents you
from using the I/O port instead of the memory resource if the device has
both.

I/O ports remain either on old ISA or internal chipset devices. Drivers for
the latter are provided by platform vendors or MS, so it is >Someone Else’s
Problem.

This is a function of where you sit, no? As mentioned, I’ve certainly
written several of these drivers.

Maybe because of this KMDF just does the simplest thing that works for
99.9% users.

KMDF doesn’t do anything but pass you the resources, this all needs to be
handled by your EvtDevicePrepareHardware event processing callback.

If we ever have to deal with i/o port, we can safely assume the driver will
not be needed for Itanium.

Why not just follow the contract? Who is to say what the processors of
tomorrow are going to do and I’d rather just do what the HAL asks and not
have to worry about going back and fixing that code.

BTW, this whole topic is explained much better than I could by Jake here:

http://blogs.msdn.com/b/doronh/archive/2010/05/05/arbitration-and-translation-part-1.aspx

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

> LowPart of the translated resource. But why is it not necessary to

map the address? Like in the ResourceTypeMemory?

Because IO ports have no notions of “virtual” and “physical” addresses.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Let’s be clear for the archives: The statement above is absolutely incorrect.

Let’s also be clear about THIS for the archives: This is NOT correct. There are LOTS of new devices that are produced today that are controlled by ports. This is not usually the best approach, and locating device registers in port space is rarely the highest performing choice, but it is not the least bit uncommon, and it is absolutely NOT restricted to “old ISA or internal chipset devices.”

You misunderstand how things work on Windows.

Let’s start from the beginning: The PCI bus supports access to devices with resources (a) in memory space, or (b) in port space. That means the designer of a PCI bus device is free to choose to put their devices in either memory space or port space or both.

When a device designer creates a device, they generally are not concerned with the processor architecture of the drivers or applications that will be talking to the device. They care about the details of the bus through which their device is attached to the system.

When a system designer creates a system (think mainboard here), that system is designed to support a specific set of buses and a specific processor architecture. If the system designer want to support the PCI bus (or PCIx or whatever), they need to determine if the processor architecture their mainboard is supporting has the native capacity to support port space (via a separate set of instructions or some other way), like the x86 does. If it does, then their task is pretty easy.

If the processor architecture supported by their mainboard does NOT support native access to port space (like, for example, the Mips or the Alpha), they need to determine how the port space address on the PCI bus will be supported. In THIS case the system designer will typically reserve a set of main memory addresses that will correspond to the port space addresses on the PCI bus.

When a device detected by the system, the driver for that device is called with two sets of resources: Raw Resources and Translated Resources.

If the device has registers in port space, the RAW resources will *always* indicate that the registers are in port space. If the processor architecture on which the driver is running has native support for port space, the corresponding TRANSLATED resources (for the registers that are physically located in port space) will also be listed in port space. If the driver is running on a processor architecture that does not natively support port space, the corresponding TRANSLATED resources (for the registers that are physically located in port space) will be listed in MEMORY space (in which case, as we said, the designer of the mainboard has reserved some memory addresses to correspond to port space). And, of course, because we DO need to map any MEMORY resource we wind up mapping these resources into kernel virtual address space.

In summary: LOTS of devices have designs that locate their registers in port space. These devices will work on any version of Windows, and irrespective of the processor architecture. The driver determines at runtime, via information provided by the HAL and the bus driver, whether these port space resources are located on the current system in port space or in memory space.

Peter
OSR

Thanks, Peter, I was getting terrified a bit there. Our PCI board definitely has I/O ports and memory. So from what you say it seems to me that I
should translate the Ports no matter what. The translation will do nothing on a standard x86 architecture, but with some other processor without
native port space support it might be translated. Is that correct?

Thanks again,
Michael

On Tue, 14 Dec 2010 15:16:08 -0500 (EST), xxxxx@osr.com wrote:

Let’s be clear for the archives: The statement above is absolutely incorrect.

Let’s also be clear about THIS for the archives: This is NOT correct. There are LOTS of new devices that are produced today that are controlled by ports. This is not usually the best approach, and locating device registers in port space is rarely the highest performing choice, but it is not the least bit uncommon, and it is absolutely NOT restricted to “old ISA or internal chipset devices.”

You misunderstand how things work on Windows.

Let’s start from the beginning: The PCI bus supports access to devices with resources (a) in memory space, or (b) in port space. That means the designer of a PCI bus device is free to choose to put their devices in either memory space or port space or both.

When a device designer creates a device, they generally are not concerned with the processor architecture of the drivers or applications that will be talking to the device. They care about the details of the bus through which their device is attached to the system.

When a system designer creates a system (think mainboard here), that system is designed to support a specific set of buses and a specific processor architecture. If the system designer want to support the PCI bus (or PCIx or whatever), they need to determine if the processor architecture their mainboard is supporting has the native capacity to support port space (via a separate set of instructions or some other way), like the x86 does. If it does, then their task is pretty easy.

If the processor architecture supported by their mainboard does NOT support native access to port space (like, for example, the Mips or the Alpha), they need to determine how the port space address on the PCI bus will be supported. In THIS case the system designer will typically reserve a set of main memory addresses that will correspond to the port space addresses on the PCI bus.

When a device detected by the system, the driver for that device is called with two sets of resources: Raw Resources and Translated Resources.

If the device has registers in port space, the RAW resources will *always* indicate that the registers are in port space. If the processor architecture on which the driver is running has native support for port space, the corresponding TRANSLATED resources (for the registers that are physically located in port space) will also be listed in port space. If the driver is running on a processor architecture that does not natively support port space, the corresponding TRANSLATED resources (for the registers that are physically located in port space) will be listed in MEMORY space (in which case, as we said, the designer of the mainboard has reserved some memory addresses to correspond to port space). And, of course, because we DO need to map any MEMORY resource we wind up mapping these resources into kernel virtual address space.

In summary: LOTS of devices have designs that locate their registers in port space. These devices will work on any version of Windows, and irrespective of the processor architecture. The driver determines at runtime, via information provided by the HAL and the bus driver, whether these port space resources are located on the current system in port space or in memory space.

Peter
OSR

Michael Wade wrote:

Thanks, Peter, I was getting terrified a bit there. Our PCI board definitely has I/O ports and memory. So from what you say it seems to me that I should translate the Ports no matter what. The translation will do nothing on a standard x86 architecture, but with some other processor without native port space support it might be translated. Is that correct?

That is definitely what I would call the “best practice”.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

And while you are being so kind with your time…

As I mentioned I am looking at your DIO driver as a reference, as well as some in the DDK (like PCIDRV). I am trying to write our driver in Kmdf but
the differences between old pre-WDM and Kmdf are a bit daunting. How does one return data in the XxxEvtDeviceControl routine? I couldn’t see it
being returned in the DIO driver, and it looks a bit buried in the PCIDRV code. I was thinking it would be something like:

VOID
TapEvtDeviceControl( WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode )
{

device = WdfIoQueueGetDevice( Queue );
context = TapGetContextFromDevice( device );

switch ( IoControlCode )
{
case MY_IOCTL:
WdfRequestRetrieveOutputBuffer( Request, MySize, Buffer, NULL );

Where Buffer is a pointer that now points to the output buffer? In the old days I would call it pIrp->AssociatedIrp.SystemBuffer; Is that correct?
Then I call
WdfRequestCompleteWithInformation(
Request,
status,
MySize
);
which in the old days would set pIrp->IoStatus.Information = MySize;

Is my thinking correct here?

Thanks,
Michael

“Translate” yes… map into kernel virtual address space… no.

You *always* want to use the translated resources that are passed to you at PrepareHardware. Always. Always. Always. You can CONSULT the raw resources, but you want to USE the translated resources.

If the resource type in the TRANSLATED configuration manager resource list is type MEMORY, call MmMapIoSpace on it, save the result from MmMapIoSpace, and talk to it using READ_REGISTER_xxxx or WRITE_REGISTER_xxxx.

If the resource type in the TRANSLATED configuration manager resource list is type PORT, save it and talk to it directly using READ_PORT_xxxx or WRITE_PORT_xxxx.

So, note that this will entail a run-time check on which flavor of function you call (REGISTER or PORT) in your driver.

(finishing your sentence above):

… and also call IoCompleteRequest.

Yes, that’s exactly right!!

You soooo want to take our KMDF class, don’t you? In Boston? The first week of February??

Peter
OSR

I am definitely planning on taking your kmdf course, but am waiting for your world tour to hit the west coast.

Thanks again,
Michael

On Tue, 14 Dec 2010 17:07:25 -0500 (EST), xxxxx@osr.com wrote:

“Translate” yes… map into kernel virtual address space… no.

You *always* want to use the translated resources that are passed to you at PrepareHardware. Always. Always. Always. You can CONSULT the raw resources, but you want to USE the translated resources.

If the resource type in the TRANSLATED configuration manager resource list is type MEMORY, call MmMapIoSpace on it, save the result from MmMapIoSpace, and talk to it using READ_REGISTER_xxxx or WRITE_REGISTER_xxxx.

If the resource type in the TRANSLATED configuration manager resource list is type PORT, save it and talk to it directly using READ_PORT_xxxx or WRITE_PORT_xxxx.

So, note that this will entail a run-time check on which flavor of function you call (REGISTER or PORT) in your driver.

(finishing your sentence above):

… and also call IoCompleteRequest.

Yes, that’s exactly right!!

You soooo want to take our KMDF class, don’t you? In Boston? The first week of February??

Peter
OSR

Actually, Scott, you’ve got the contract wrong. (See older posts by me on
this topic. I know that OSR has been teaching this for years, but with the
wrong contract.)

If your translated resources are in port space, you don’t map. Period.
(The exception was MIPS, which is gone. Alpha and PowerPC and Itanic all
followed the contract I’m describing now.) If the translated resources are
in memory space, you map. Period.

Jake Oshins
Hyper-V I/O Architect
Windows Kernel Group

This post implies no warranties and confers no rights.


“Scott Noone” wrote in message news:xxxxx@ntdev…

“Tim Roberts” wrote in message news:xxxxx@ntdev…

At one time, it WAS necessary to map the I/O space, and some people
still do so out of habit. Way back in the mid-1990s, NT also ran on
Alpha, MIPS, and PowerPC processors. Those processors do not have the
concept of “I/O ports”, so PCI devices with I/O space had to be mapped
into part of physical memory.

Just to clarify…This is still an issue on Windows due to the Itanium,
which doesn’t have I/O ports either
(all Itanium jokes aside).

The key then is that you have to dynamically determine *where* your ports
end up on a particular
platform at runtime, which is where the raw and translated resources come
in. Your raw resource
indicates that you have a port on your device and your translated resource
indicates that it’s either
in port space (x86/x64, you don’t have to map) or in memory space (IA64, you
*do* have to map).
The wdfdio driver demonstrates this.

Just want to make it clear that mapping or not mapping isn’t an arbitrary
decision up to the driver
writer.

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Tim Roberts” wrote in message news:xxxxx@ntdev…

Michael Wade wrote:

In the wdfdio.cpp file, DioEvtPrepareHardware function I see that it’s
iterating over the resource types, and in the CmResourceTypePort case
it is just setting the device context BaseAddress variable to the
LowPart of the translated resource. But why is it not necessary to
map the address? Like in the ResourceTypeMemory?

At one time, it WAS necessary to map the I/O space, and some people
still do so out of habit. Way back in the mid-1990s, NT also ran on
Alpha, MIPS, and PowerPC processors. Those processors do not have the
concept of “I/O ports”, so PCI devices with I/O space had to be mapped
into part of physical memory.

x86 and x64 processors don’t have to worry about that.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

No, there’s no such action as “translate the ports.” If your translated
resources are CmResourceTypePort, then you call READ_PORT_* and WRITE_PORT_*
and forget about the rest. There are no virtual addresses to create.

If your translated resources are of type CmResourceTypeMemory then you need
a virtual address and you call MmMapIoSpace. Then you use READ_REGISTER*
and WRITE_REGISTER*. That’s all. You’ll never see this happen on a
commodity PC so most driver writers skip this code, considering it
untestable.

Jake Oshins
Hyper-V I/O Architect
Windows Kernel Group

This post implies no warranties and confers no rights.


“Michael Wade” wrote in message news:xxxxx@ntdev…

Thanks, Peter, I was getting terrified a bit there. Our PCI board
definitely has I/O ports and memory. So from what you say it seems to me
that I
should translate the Ports no matter what. The translation will do nothing
on a standard x86 architecture, but with some other processor without
native port space support it might be translated. Is that correct?

Thanks again,
Michael

On Tue, 14 Dec 2010 15:16:08 -0500 (EST), xxxxx@osr.com wrote:

Let’s be clear for the archives: The statement above is absolutely
incorrect.

Let’s also be clear about THIS for the archives: This is NOT correct.
There are LOTS of new devices that are produced today that are controlled
by ports. This is not usually the best approach, and locating device
registers in port space is rarely the highest performing choice, but it is
not the least bit uncommon, and it is absolutely NOT restricted to “old ISA
or internal chipset devices.”

You misunderstand how things work on Windows.

Let’s start from the beginning: The PCI bus supports access to devices
with resources (a) in memory space, or (b) in port space. That means the
designer of a PCI bus device is free to choose to put their devices in
either memory space or port space or both.

When a device designer creates a device, they generally are not concerned
with the processor architecture of the drivers or applications that will be
talking to the device. They care about the details of the bus through
which their device is attached to the system.

When a system designer creates a system (think mainboard here), that system
is designed to support a specific set of buses and a specific processor
architecture. If the system designer want to support the PCI bus (or PCIx
or whatever), they need to determine if the processor architecture their
mainboard is supporting has the native capacity to support port space (via
a separate set of instructions or some other way), like the x86 does. If
it does, then their task is pretty easy.

If the processor architecture supported by their mainboard does NOT support
native access to port space (like, for example, the Mips or the Alpha),
they need to determine how the port space address on the PCI bus will be
supported. In THIS case the system designer will typically reserve a set
of main memory addresses that will correspond to the port space addresses
on the PCI bus.

When a device detected by the system, the driver for that device is called
with two sets of resources: Raw Resources and Translated Resources.

If the device has registers in port space, the RAW resources will *always*
indicate that the registers are in port space. If the processor
architecture on which the driver is running has native support for port
space, the corresponding TRANSLATED resources (for the registers that are
physically located in port space) will also be listed in port space. If
the driver is running on a processor architecture that does not natively
support port space, the corresponding TRANSLATED resources (for the
registers that are physically located in port space) will be listed in
MEMORY space (in which case, as we said, the designer of the mainboard has
reserved some memory addresses to correspond to port space). And, of
course, because we DO need to map any MEMORY resource we wind up mapping
these resources into kernel virtual address space.

In summary: LOTS of devices have designs that locate their registers in
port space. These devices will work on any version of Windows, and
irrespective of the processor architecture. The driver determines at
runtime, via information provided by the HAL and the bus driver, whether
these port space resources are located on the current system in port space
or in memory space.

Peter
OSR

Really Tim? What does your code generally look like? You pass I/O Port
addresses to MmMapIoSpace? If you do, what you get back is a virtual
address that points to some physical memory, not an I/O port.

Jake Oshins
Hyper-V I/O Architect
Windows Kernel Group

This post implies no warranties and confers no rights.


“Tim Roberts” wrote in message news:xxxxx@ntdev…

Michael Wade wrote:

Thanks, Peter, I was getting terrified a bit there. Our PCI board
definitely has I/O ports and memory. So from what you say it seems to me
that I should translate the Ports no matter what. The translation will do
nothing on a standard x86 architecture, but with some other processor
without native port space support it might be translated. Is that
correct?

That is definitely what I would call the “best practice”.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

“Jake Oshins” wrote in message news:xxxxx@ntdev…

If your translated resources are in port space, you don’t map. Period.
(The exception was MIPS, which is gone. Alpha and PowerPC and Itanic all
followed the contract I’m describing now.) If the translated resources are
in memory space, you map. Period.

Isn’t that the same thing that I had said?

“Your raw resource indicates that you have a port on your device and your
translated resource indicates that it’s either
in port space (x86/x64, you don’t have to map) or in memory space (IA64, you
*do* have to map).”

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

A long time ago, with a bit of Jake’s help, I wrote this up for the
now dormant WD3 Digest (and where is Walter Oney anyway?)

http://www.wd-3.com/archive/PioAccess.htm

Mark Roddy

On Wed, Dec 15, 2010 at 12:55 PM, Jake Oshins
wrote:
> No, there’s no such action as “translate the ports.” ?If your translated
> resources are CmResourceTypePort, then you call READ_PORT_* and WRITE_PORT_
> and forget about the rest. ?There are no virtual addresses to create.
>
> If your translated resources are of type CmResourceTypeMemory then you need
> a virtual address and you call MmMapIoSpace. ?Then you use READ_REGISTER

> and WRITE_REGISTER*. ?That’s all. ?You’ll never see this happen on a
> commodity PC so most driver writers skip this code, considering it
> untestable.
>
>
> Jake Oshins
> Hyper-V I/O Architect
> Windows Kernel Group
>
> This post implies no warranties and confers no rights.
>
> --------------------------------------------------------------
> “Michael Wade” ?wrote in message news:xxxxx@ntdev…
>
> Thanks, Peter, I was getting terrified a bit there. ?Our PCI board
> definitely has I/O ports and memory. ?So from what you say it seems to me
> that I
> should translate the Ports no matter what. ?The translation will do nothing
> on a standard x86 architecture, but with some other processor without
> native port space support it might be translated. ?Is that correct?
>
> Thanks again,
> Michael
>
>
> On Tue, 14 Dec 2010 15:16:08 -0500 (EST), xxxxx@osr.com wrote:
>
>>


>>
>> Let’s be clear for the archives: ?The statement above is absolutely
>> incorrect.
>>
>>


>>
>> Let’s also be clear about THIS for the archives: ?This is NOT correct.
>> There are LOTS of new devices that are produced today that are controlled by
>> ports. ?This is not usually the best approach, and locating device registers
>> in port space is rarely the highest performing choice, but it is not the
>> least bit uncommon, and it is absolutely NOT restricted to “old ISA or
>> internal chipset devices.”
>>
>>


>>
>> You misunderstand how things work on Windows.
>>
>> Let’s start from the beginning: ?The PCI bus supports access to devices
>> with resources (a) in memory space, or (b) in port space. ?That means the
>> designer of a PCI bus device is free to choose to put their devices in
>> either memory space or port space or both.
>>
>> When a device designer creates a device, they generally are not concerned
>> with the processor architecture of the drivers or applications that will be
>> talking to the device. ?They care about the details of the bus through which
>> their device is attached to the system.
>>
>> When a system designer creates a system (think mainboard here), that
>> system is designed to support a specific set of buses and a specific
>> processor architecture. ?If the system designer want to support the PCI bus
>> (or PCIx or whatever), they need to determine if the processor architecture
>> their mainboard is supporting has the native capacity to support port space
>> (via a separate set of instructions or some other way), like the x86 does.
>> ?If it does, then their task is pretty easy.
>>
>> If the processor architecture supported by their mainboard does NOT
>> support native access to port space (like, for example, the Mips or the
>> Alpha), they need to determine how the port space address on the PCI bus
>> will be supported. ?In THIS case the system designer will typically reserve
>> a set of main memory addresses that will correspond to the port space
>> addresses on the PCI bus.
>>
>> When a device detected by the system, the driver for that device is called
>> with two sets of resources: ?Raw Resources and Translated Resources.
>>
>> If the device has registers in port space, the RAW resources will always
>> indicate that the registers are in port space. ?If the processor
>> architecture on which the driver is running has native support for port
>> space, the corresponding TRANSLATED resources (for the registers that are
>> physically located in port space) will also be listed in port space. ?If the
>> driver is running on a processor architecture that does not natively support
>> port space, the corresponding TRANSLATED resources (for the registers that
>> are physically located in port space) will be listed in MEMORY space (in
>> which case, as we said, the designer of the mainboard has reserved some
>> memory addresses to correspond to port space). ?And, of course, because we
>> DO need to map any MEMORY resource we wind up mapping these resources into
>> kernel virtual address space.
>>
>> In summary: LOTS of devices have designs that locate their registers in
>> port space. ?These devices will work on any version of Windows, and
>> irrespective of the processor architecture. ?The driver determines at
>> runtime, via information provided by the HAL and the bus driver, whether
>> these port space resources are located on the current system in port space
>> or in memory space.
>>
>> Peter
>> OSR
>>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>