Subject: Re: personal impression of issues on netbsd/macppc
To: Tim Kelly <hockey@dialectronics.com>
From: Michael <macallan18@earthlink.net>
List: port-macppc
Date: 11/19/2004 20:58:45
Hello,

> > > Having to _get_ a video card with I/O space to run X strikes me as
> > > not true support for the hardware. 
> > Well, that's not the case - we don't have to /get/  video hardware
> > into IO space. It's already there and sometimes that's the only way to
> > talk to it.
Argh, I misread you. We have to get video cards with IO space to work because virtually all graphics cards you get today are VGA compatible.
 
> Ok, perhaps this is a lack of understanding on my part. Here are the
> three registers and two assigned addresses (configuration registers
> don't get assigned an address) for the video device on my 7300:
...
> Which is the I/O register?
Umm, now I'm lost - why shoult the onboard video of your 7300 have an IO range?

...
> indicates that the iot on a PCI-Host device comes from the host cell. In
> the case of /chaos, this is
> 
> ff83dcd0: /chaos@f0000000
> 
> name                    6368616f 7300.... ........ ........   "chaos"
> <snip>
> ranges            
>               02000000 00000000 f1000000 f1000000   00000000 01000000 
>               01000000 00000000 00000000 f0000000  00000000 00800000
>               02000000 00000000 90000000 90000000 00000000 10000000
> 
> or 0xf0000000. 
> 
> When you are writing to the I/O space on this type of model, where are
> you writing to?
Why should I write to it? if it doesn't have registers in IO space then I don't have to write to it.

> I haven't had the chance to translate in my head how
> OpenBSD does memory mapping to how NetBSD does it, but if you could tell
> me where in memory you're writing to when you say you write to I/O
> space, I can probably work it through so that I can tie it back to the
> device.
Simple - when writing into PCI IO space through the first bandit I write to physical address 0xf2000000+BAR+offset ( where BAR is a config register pointing to an IO range and offset is the actual register ). An x86 would just do outb(BAR+offset,some_byte) without any mapping. Are you at all familiar with the way x86 ( and some others like the Z80 ) access IO space? This might clear things up a little.

So - a little x86ism:
the 8080 and descendants ( like the Z80 and as remote cousins the x86s ) have special instructions to access IO registers. Usually these cover an address space that's a lot smaller than the memory address space ( 8 bit on a 8080, a Z80 can use full 16 bit for most instructions, on x86 it's more ambiguous, it used to be 12 bit, later 16 bit ). The difference is that the processor issues an additional signal to distinguish IO accesses from memory access, the reason to do that is that 8bit processors usually only address 64kB RAM and we don't want to waste any of that for IO devices. The x86 uses a very similar scheme.
PCish PCI bridges simply forward IO cycles generated by the processor as PCI IO cycles so access is easy and convenient, you don't have to mmap() anything, you may only need to tell the MMU to allow access ( I'm not sure if it can translate/remap IO accesses at all, it can certainly trap them though ), so an x86 doesn't need to worry about anything besides some pesky privilege if it wants to access IO registers on PCI cards - reading the right BAR of the resp. card is all the information it needs. 
PowerPCs don't have these IO instructions so the processor doesn't generate these special cycles so the PCI bridge needs to translate memory accesses to a special address range into PCI IO cycles - on a bandit that's hard wired to 0xf2000000 or 0xf4000000 ( according to Apple ) so we need to do a lot more work than an x86 - we need to know through which bandit we talk to the card so we can pick the right address range. We also need to map this address range into user space - unnecessary on x86. 
NetBSD hides all this behind a lot of clever bus_space_* functions and macros so kernel drivers don't need to worry about these pesky details - XFree can't do that so it had to come up with its own abstraction scheme which allows to remap IO accesses to memory accesses but it still assumes a single, uniform IO space so it can't deal with more than one bandit.

I hope that helped a little :)

have fun
Michael