Subject: genfb and virtual addresses
To: NetBSD tech-kern mailing list <>
From: Michael Lorenz <>
List: tech-kern
Date: 11/10/2007 20:33:25
Hash: SHA1


when making genfb at pci work on sparc64 I ran into the following  
problem - OpenFirmware only supplies a virtual address for the  
framebuffer but in order to allow mmap()ing it genfb need a bus  
address it can pass to bus_space_mmap(). Just knowing which BAR maps  
the framebuffer isn't good enough - there's no guarantee that the  
framebuffer is at offset zero from whatever BAR maps it - many  
graphics controllers offer at least two views, usually with or  
without endian conversion. Some use the first few KB of video memory  
for their own purposes like some Rage 128 firmware for Macs.
Getting the physical address is no problem, pmap_extract() nicely  
does the job. In order to translate that to a bus address I need to  
know where the framebuffer's parent PCI bus maps its memory range.  
Unfortunately that's not as trivial as on macppc, even in machine  
dependent code - on some machines psycho maps 4GB memory, on the U10  
for instance, while on others like the U60 there are two psychos that  
map 2GB memory each so I can't just mask out the upper bits and run  
with what's left like on SBus.
In order to get around this I made psycho put its memory address into  
a device property, that way device_register() can just look at the  
bus device's parent's properties and that way put a bus address ( as  
in difference between the framebuffer's physical address and the PCI  
buses memory base ) into the console framebuffer's properties. I  
don't want to rely on the PCI controller being a psycho - at some  
point we will hopefully support schizo and the like.
So, the question is - am I missing some obvious way to translate a  
physical ( or kernel virtual ) address into a bus address using just  
what we get in pci_attach_args ? Or is there a nicer way to make the  
memory range's physical address available in a generic, PCI  
controller agnostic way? Most LP64 archs will likely need something  
like that in order to use genfb, even some 32bit ones might.
The reason I'm doing this is to allow PCI framebuffer console drivers  
without machine-dependent firmware calls and to let genfb handle  
otherwisely unsupported graphics devices as long as the firmware sets  
them up.

Genfb is intended to be a catch-all dumb framebuffer console driver  
which gets parameters like framebuffer geometry, address and so on  
passed in device properties, it relies on firmware to set up the  
graphics hardware and machine dependent code to extract those  
parameters from the firmware. A fallback to deal with firmware- 
supported graphics devices we don't have a driver for.

have fun
Version: GnuPG v1.4.7 (Darwin)