[lkml]   [1998]   [Nov]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
SubjectRe: Accessing MMIO PCI space - crossplatform (fwd)
	More notes....


'Cloning and the reprogramming of DNA is the first serious step in
becoming one with God.'
- Scientist G. Richard Seed

---------- Forwarded message ----------
Date: Fri, 13 Nov 1998 21:06:39 +0100 (MET)
From: Steffen Seeger <>
Subject: Re: Accessing MMIO PCI space - crossplatform (fwd)

> > > Steffen Seeger wrote:
> > >
> > > > /* ------------------------------------------------------------------------
> > > > ** hardware I/O layer definiton
> > > > ** ------------------------------------------------------------------------
> > >
> > > [snip]
> > >
> > > > typedef __ggi_sys_u32 pcicfg_vaddr; /* the virtual address type */
> > >
> > > AARGH!
> >
> > What else? [Counterproposal please]
> > Rationale: bus, device and function IDs are 8 bit, and each device config
> > space is IIRC 256 bytes (according to PCI specs I guess). This happily
> > fits into 32bit to address any bus, device, function and byte in
> > config space. If Intel ever decides to change this, we will have to
> > add another IO space (e.g. pcicfg2_) that uses a wider address.
> Steffen,
> after you explained it, I understand your rationale.
> The problem is: you wrote 'address', and you did not mean what normally
> is called a pointer or an address.
> So if you argue that for each and every PCI device the config address
> can fit into 32 bits, then *COMMENT THAT IN THE SOURCE* and do not
> write 'the virtual address type'.
> So a paragraph
> /* this contains the bus number (8 bits)
> device number (8 bits)
> function ID (8 bits)
> config space address (8 bits) according to PCI spec
> and is therefore sufficient for 256 busses of 256 devices with
> 256 functions with a standard config space each. That's enough, I hope.
> This might or might not have anything to do with physical or
> virtual addresses the system might use . */
> is in order.

There is a macro beside, that just takes these arguments...
You are right, I will add a clear(er) comment.

I am sorry the first mail went out without the documentation included.
Please forget the first, it was a stupid typing mistake by me.

The whole idea about the hardware layer proposed is that
the driver must not make assumptions about the mapping between the
'address handle' it passes to the in/out operations and any CPU
instruction or instruction parameter. Therefore the term 'virtual
address' for every handle passed to the CPU in/out functions.

When addressing main memory, the situation isn't any different. Before
you can write to a memory location, you will have first to obtain it's virtual
address and get access permissions. This virtual address is used to access
the memory via load/store operations.

I just generalized this to I/O: before accessing a device, you first
have to register the I/O region and in return you will get a virtual
address. This and only this virtual address is used with the in/out
functions. However, it doesn't make sense to register PCICFG regions,
as you don't know where the device is. You just __have__ to use the
bus, device and function id to address it. Therefore the hardcoded
'physical (bus,dev,fn,reg)' to 'virtual (to be used with pcicfg_in/out())'

> > > > typedef unsigned int io_addr; /* the physical address type */
> > > > typedef unsigned int io_vaddr; /* the virtual address type */
> > >
> > > DOH!
> >
> > What else? [Counterproposal please]
> > Rationale: ISA I/O space address range is by definition 16 bit, so I don't see
> > the use of having 64bit or wider values here. There might be several ISA bus'es
> > (PCI->ISA bridges) and which can be encoded in the upper (at least 16) bits.
> > int should be >= 32 bit, as I intend to target >=32 bit systems only.
> Think again.
> Is this an IO address?

Yes. It is an I/O address that names one location in the (__by definiton__)
16bit ISA-Intel8086 io-port address space. This thing is there, it
is specified and will never change. It is 16 bit. If it isn't, it is not the
ISA-Intel8086 io-port space.

> What IO address ranges are common?
> For memory mapped IO (like the 68k does) there is AFAIK no real difference
> *in hardware protocol* between memory and IO bus cycles, so ther e might
> not even be something like an IO space.

Again, this is not about any particular implementation. If a machine can
somehow work with an ISA extension card, it does have some means to generate
the I/O hardware access cycles to the card. I mean the electrical signals here.

And if it can do that, you can write an function that takes an 16bit int
and the data and does all the actions that are neccessary to generate these
cycles. This function implementation may need to get access to a memory
region before, but to address a ISA extension card in a machine you only need
to name the bus and the I/O address.

> So on some platforms there might *not* be a difference between a physical
> memory address and a physical IO address. So a physical IO address
> might be the same as a void (or byte) pointer, which may ar may not be
> shorter or longer than an int, and is certainly not exatly the same.
> Is this *not* and IO address, then what is it?

It is the 16bit address value that uniquely selects one register
(io-port) on a ISA-bus extension card. It is not the (probably 64bit)
value that is used to write to a physical IO address that will generate
the write cycle. Drivers must not make any assumptions on the mechanisms
used to finally make the hardware execute the extension-card-register access.

> Isa is not the end of the world, and while usually the IO area in address
> space is sort of contiguous, IO addresses *might* be scattered all over the
> address space.

Fine with me. The driver will not (have to) know, because the virtual
address it uses are defined to be continous. It will register it's
region, take the virtual base address returned and add it's offset.
The io_out8() function may then have to take that (phyiscal io-port)
address, get the lower 16bit, shift them, mask them, scatter them add
the result to a memory base address, merge the data into the upper
64bit and finally do a load instruction to some 'magic memory'.
I don't want to know these details from a driver writers
point of view...

> > > > typedef unsigned int mem_addr; /* the physical address type */
> > >
> > > OUCH!
> >
> > What else? [Counterproposal please]
> > Rationale: Want to avoid pointer arithmetics (void pointer arithmetic isn't
> > specified by ANSI). May be this should be long, but IIRC I took this from
> > some kernel include... Your PROPOSAL and rationale?
> But a void pointer and an int are different, in theory and on some hardware.

Mhmm... I should state that more clearly. The "addr" types are used to address
'physical' resources. You know how long they have to be just from the
specification of the bus system. It has (for memory I/O) just to be long enough
to hold a physical (memory) address value. So, in order to do that using
ANSI C types, what do I have to use? The virtual addresses (used with the
mem_in/mem_out functions) have to be long enough to hold a virtual
(memory) address value. You know how long these have to be from the
specification of the CPU hardware spec. And a (void *) or (u8 *) should be
perfect for that, shouldn't it?

> If you want to sell this typedef, give a reason *in the source code*.
> Or everybody lurking on linux.kernel will jump at you.
> And Geert :-)

Mhmm... I just sat down and typed this kind of spec, just because I didn't
want to bloat the io.h header with more comments than code. And I clearly
pointed to that spec in the beginning of the header. And code alone did
not seem enough to me to explain that concept to a driver writer.
I just wanted to have one document that _clearly_ states what function
is supposed to do what. This should help both when porting and using
the code. And most of all, you can spot if a driver or the I/O
functions are buggy (in case...)

> --
> Hartmut Niemann -- niemann(a)
> [/ggi]


----------------- e-mail: -----------------
------------- The GGI Project: -------------
----------------- http: -----------------

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
Please read the FAQ at

 \ /
  Last update: 2005-03-22 13:45    [W:0.032 / U:29.544 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site