[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.035 / U:18.420 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site