One detail: volatile is needed not only because of cacheability, but also
because of the unwanted compiler optimization that may result. A loop such
as
while (*t & MY_BIT) wait_for_that_interrupt_to_clear();
may be optimized to a single test, and that makes things misbehave. Using
“volatile” when declaring variable t takes care of that problem.
Alberto.
-----Original Message-----
From: Sathyanarayanan Srinivasan
[mailto:xxxxx@wipro.com]
Sent: Friday, December 06, 2002 1:33 AM
To: NT Developers Interest List
Subject: [ntdev] RE: port IO and MEMORY IO
Excellent Explanation…!
-----Original Message-----
From: McCrory, Duane [mailto:xxxxx@infiniconsys.com]
Sent: Wednesday, December 04, 2002 8:14 PM
Subject: Re: port IO and MEMORY IO
Port IO and Memory IO are systems programming mechanisms usually
associated with accessing device registers.
Port IO is an x86 legacy implementation relating to x86 IN and OUT
instructions. These could address a 64KB address space.
Memory IO is now the preferred method (which was how most processors
(e.g. 68000)) attached to their IO peripheral registers. With Memory IO
a portion of the memory address space maps to IO device register
accesses. Base VGA memory is an example of Memory IO.
Port IO had the advantage that it didn’t consume an address range from
your memory space (which was important when 8086 designs were beginning
in the early 80’s and the memory address space was only 1MB). The
drawback with Port IO is that its address space is extremely small, and
thus limits the number of devices and device registers that can be
directly addressed by it.
Early PCI had the requirement that a device support both Port IO and
Memory IO addressable registers (i.e. you could use either access
method). I believe PCI has shifted its preference to Memory IO
addressable registers only. Port and Memory IO accesses are differrent
transaction types on the PCI bus. Often non-x86 style systems reserve a
portion of their Memory IO space for Port IO (i.e. the host bridge
converts the Memory IO access into a Port IO access instead). On x86
based systems the host bridges normally do not provide this capabilily,
rather support Port IO requests from the CPU(s) and pass them down the
PCI bus directly.
With Memory IO you learn that a device can actually have addressable
memory (along with device registers). VGA memory is an example of this.
However, it is important to remember that device memory almost always
needs to be accessed using non-cacheable memory reads and writes. This
is especially important if the device has a processor that is modifying
or reading the device memory, because the non-cacheable writes by the
host processor allow changes to become visible to the device processor.
Similarly writes by the device processor can be observed by the host
processor by doing a non-cacheable read since its local caches and
memory subsystem are bypassed.
Programmers often confuse the use of the volatile attribute because of
Memory IO. If you do Memory IO, the OS or BIOS/HAL has usually already
setup the address range to be non-cacheable for you (e.g. via the
processors MTRR registers on Pentiums). With Memory IO you don’t usually
need to use volatile, because the accesses are already non-cacheable.
You sometimes need to use volatile when your host code shares “host
memory” (as opposed to device memory) with your device. The volatile
tells the compiler that it cannot optimize the access to the variable
(e.g. stuff it away in a register), but it needs to fetch the true value
from memory on each access. Fortunately with x86 based systems when your
device writes host memory, the processor caches maintain coherency, so
your code will see the updated data value correctly.
You may also need to use volatile for variables in a multi-threaded
application (e.g. if one thread is decrementing/polling a variable
incremented by a separate thread) and no lock is used to serialize these
accesses.
The other mistake that is often made involves the use of volatile and
pointer variables. For instance the following give distinctly different
behaviors.
char *volatile pChar;
volatile char *pChar;
The first one indicates that the pointer variable is volatile. The
second indicates that what it is pointing to is volatile.
Duane J. McCrory
InfiniCon Systems
-----Original Message-----
From: Shiva Prasad T.S. [mailto:xxxxx@rassit.com]
Sent: Tuesday, December 03, 2002 10:52 PM
To: NT Developers Interest List
Subject: [ntdev] Re: port IO and MEMORY IO
Hi,
I have some doubts about port I/O space and memory I/O space.
What is it that differenciates these 2??
with respect to drivers S/W , u access port IO using functions like
READ_PORT_UCHAR( ),READ_PORT_USHORT( ),READ_PORT_ULONG()…and
WRITE_PORT_XXX()…
Where as Memory mapped device registers are accessed using functions
like
READ_REGISTER_UCHAR( ), READ_REGISTER_USHORT( ),ETC…
h/w wise, the device are given R/w control in PORT IO device using IOR,
IOW
signals…and use IN and OUT instructions
in Memory IO device using MEMR, MEMW signals… they use LOAD and STORE
instructions…
>Also if a device’s memory area is in memory spce then I guess we have
to
use
mmmapiospace() routine to get the kernel virtual address. Please let
me
know
why
this is needed
READ_REGISTER_XXX(Device’s Virtual Address);
this function takes a parameter of the device’s virtual address…so the
physical address space of the device needs to get mapped to the virtual
address space…
u may refer Walter Oney’s “programming the Microsoft Windows Driver
Model”
book, or Cris cant’s “writing windows device drivers”
regards,
shiva prasad
----- Original Message -----
From: “sankar”
To: “NT Developers Interest List”
Sent: Wednesday, December 04, 2002 3:31 AM
Subject: [ntdev] port IO and MEMORY IO
> HI Experts,
> I have some doubts about port I/O space and memory I/O space.
> What is it that differenciates these 2??
> Also if a device’s memory area is in memory spce then I guess we have
to
use
> mmmapiospace() routine to get the kernel virtual address. Please let
me
know
> why
> this is needed.I am totally unaware of these concepts and any tips in
this
> will be of
> great help.If u can point me to some articles regarding this,that
would
also
> be helpful.
>
> thanks in advance
> Sankarshana M
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@rassit.com
> To unsubscribe send a blank email to %%email.unsub%%
>
>
—
You are currently subscribed to ntdev as: xxxxx@infinicon.com
To unsubscribe send a blank email to %%email.unsub%%
—
You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to %%email.unsub%%
The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.