Re: Accessing MMIO PCI space - crossplatform (fwd)

Jon M. Taylor (taylorj@ecs.csus.edu)
Fri, 13 Nov 1998 14:00:41 -0800 (PST)


More notes....

Jon

---
'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 <s.seeger@physik.tu-chemnitz.de> To: ggi-develop@eskimo.com 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())' mapping.

> > > > 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)cip.e-technik.uni-erlangen.de > http://cip2.e-technik.uni-erlangen.de:8080/hyplan/niemann/index_en.html [/ggi]

Steffen

----------------- e-mail: seeger@physik.tu-chemnitz.de ----------------- ------------- The GGI Project: http://www.ggi-project.org ------------- ----------------- http: http://www.tu-chemnitz.de/~sse -----------------

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/