Limited graphics support has long been a problem to Solaris x86 users since it is hard to get solaris drivers from graphics vendors. With the integration of the Xorg X server into Solaris, support in this area has been greatly improved, because Solaris can easily leverage the X.Org community maintained graphics drivers now with no modifications or only few modifications. Of course, Sun will also putback the modifications it makes to the X.Org CVS trees. From this perspective, it demonstrates once again the double-win benefits of an open source project. Perhaps that is also what each Solaris developer in Sun expects through OpenSolaris project - We love Solaris and we'd like to make Solaris grow faster.
Well, a bit far from the topic. Let me now explain what AGPgart driver is and why it is needed for Solaris x86. The Xorg server is ported to Solaris x86, but not necessarily mean every feature can work. Some features depend on kernel support. AGPgart driver is among one of the kernel dependencies. It is a kernel module to allocate system memory and manage AGP devices for Xorg graphics drivers. There are two cases graphics drivers will need to use system memory. One is for the AGP graphics which needs more video memory in addition to its local memory for better 3D performance. The other is for Intel i810/830 series integrated graphics which doesn't have local memory. The system memory allocated is usually not physically contiguous and not suitable to be directly used by graphics devices. The AGP graphics uses the GART(Graphics Address Remapping Table) device on AGP chipset to make the memory appear contiguous. And the Intel i810/830 graphics uses a similar hardware mechanism GTT(Graphics Translation Table) to fulfull this. These are the two situations AGPgart driver is required to support.
The AGPgart driver for Solaris x86 adopts the same APIs Xorg used for other operating systems, like FreeBSD. If you take a look at the agpgart.h file in the OpenSolaris tree, you will see the following ioctls supported:
AGPIOC_INFO
AGPIOC_ACQUIRE
AGPIOC_RELEASE
AGPIOC_SETUP
AGPIOC_ALLOCATE
AGPIOC_DEALLOCATE
AGPIOC_BIND
AGPIOC_UNBIND
AGPIOC_ACQUIRE
AGPIOC_RELEASE
AGPIOC_SETUP
AGPIOC_ALLOCATE
AGPIOC_DEALLOCATE
AGPIOC_BIND
AGPIOC_UNBIND
Accordingly, the Xorg agpgart wrapper functions are implemented in sun_agp.c in the X.Org CVS tree, which was newly committed from Sun by Alan.
Bool
xf86GARTCloseScreen(int
screenNum);
static Bool GARTInit(int screenNum);
Bool xf86AgpGARTSupported(void);
AgpInfoPtr xf86GetAGPInfo(int screenNum);
Bool xf86AcquireGART(int screenNum);
Bool xf86ReleaseGART(int screenNum);
int xf86AllocateGARTMemory(int screenNum, unsigned long size, int type, unsigned long *physical);
Bool xf86BindGARTMemory(int screenNum, int key, unsigned long offset);
Bool xf86UnbindGARTMemory(int screenNum, int key);
Bool xf86EnableAGP(int screenNum, CARD32 mode);
static Bool GARTInit(int screenNum);
Bool xf86AgpGARTSupported(void);
AgpInfoPtr xf86GetAGPInfo(int screenNum);
Bool xf86AcquireGART(int screenNum);
Bool xf86ReleaseGART(int screenNum);
int xf86AllocateGARTMemory(int screenNum, unsigned long size, int type, unsigned long *physical);
Bool xf86BindGARTMemory(int screenNum, int key, unsigned long offset);
Bool xf86UnbindGARTMemory(int screenNum, int key);
Bool xf86EnableAGP(int screenNum, CARD32 mode);
AGPIOC_RESERVE and AGPIOC_PROTECT ioctls are not implemented in Solaris since actually there are no calls to the ioctls in Xorg implementation. And Solaris would use the least privilege model to protect accesses to the agpgart device. PRIV_GART_ACCESS is needed for processes doing AGPIOC_* ioctls other than AGPIOC_INFO. PRIV_GART_MAP is needed for processes doing mmap on the agpgart device. So if a non-root process is about to access the agpgart device, it may have to get privilege authorization from the system administrator.
The Sun AGPgart driver incorporates some codes of Philip's driver in agpgart.c. But most of the implementation has been re-written, because the architectures of the AGP systems are much more complex. On an AGP system supported by Solaris AGPgart driver, one can see three device nodes or more associated with agp. They are something like this on an Intel system:
-bash-3.00# ls -l
/dev/agp*
lrwxrwxrwx 1 root root 26 May 18 15:19 /dev/agpgart -> ../devices
/agpgart:agpgart
/dev/agp:
total 4
lrwxrwxrwx 1 root root 56 Apr 15 18:38 agpmaster0 -> ../../device
s/pci@0,0/pci8086,2571@1/display@0:agpmaster
lrwxrwxrwx 1 root sys 45 May 18 17:42 agptarget0 -> ../../device
s/pci@0,0/pci1028,155@0:agptarget
lrwxrwxrwx 1 root root 26 May 18 15:19 /dev/agpgart -> ../devices
/agpgart:agpgart
/dev/agp:
total 4
lrwxrwxrwx 1 root root 56 Apr 15 18:38 agpmaster0 -> ../../device
s/pci@0,0/pci8086,2571@1/display@0:agpmaster
lrwxrwxrwx 1 root sys 45 May 18 17:42 agptarget0 -> ../../device
s/pci@0,0/pci1028,155@0:agptarget
On an Opteron system, there will be more nodes under /dev/agp: cpugart0, cpugart1,..., depending on how many CPUs the Opteron system has.
lrwxrwxrwx
1 root
root 52 Jun
7 17:26 cpugart0 -> ../../devices/
pci@0,0/pci1022,1103@18,3:amd64_gart-0
lrwxrwxrwx 1 root root 52 Jun 7 17:26 cpugart1 -> ../../devices/
pci@0,0/pci1022,1103@19,3:amd64_gart-1
pci@0,0/pci1022,1103@18,3:amd64_gart-0
lrwxrwxrwx 1 root root 52 Jun 7 17:26 cpugart1 -> ../../devices/
pci@0,0/pci1022,1103@19,3:amd64_gart-1
The /dev/agpgart node is the only accessing point for users, which is controlled by agpgart pseudo driver. However, it depends on the other drivers to work properly. When a user wishes to enable agpgart support, he must make sure the above device nodes have been created successfully. Among the other nodes, agpmaster0 is controlled by vgatext driver and it should be attached be the graphics device; agptarget0 is controlled by agptarget driver and it should be attached to the AGP corelogic device where the AGP target registers locate or the Intel memory controller device for i810/830 support; cpugart[n] exist only on Opteron/Athlon64 platforms, which are controlled by adm64_gart driver and should be attached to the CPU GART devices.
Why has there to be so many drivers and device nodes in Solaris? It is due to the requirement for a clean Solaris driver that one driver should only access one type of device it claims to own and not peer to other devices. However, to support the AGP system, multiple devices have to be accessed. So multiple drivers are needed. Then how can the agpgart pseudo driver communicate with other drivers? An important feature introduced in Solaris 10 helps on this - Layered Driver Interface(LDI). The LDI interfaces make agpgart pseudo driver able to open other drivers and make ioctls to them.
Though AGPgart driver has been designed to support both i810/830 driver and 3D display of AGP graphics for Xorg server, the 3D graphics support is still not enabled for Solaris x86 yet. So the main function of the driver is to support Xorg i810/830 driver to allocate video memory now. Before agpgart support is enabled for Solaris, the old i810 devices fail to load Xorg driver and i830 devices may only display at a resolution of 800x600 with a depth of 8. But with agpgart support, these devices can work at much higher resolutions, which should be a delightful news for Intel graphics users.
Due to the limitation of the resources we have, the supported Intel graphics now limits to i810/i830/i845/i855. The AGP chipsets are also limited, which include Intel 845/855/865 and AMD8151. More device support needs to be added. We are expecting to work with the OpenSolaris community to make it better.
[Technorati Tag: Solaris] [Technorati Tag: OpenSolaris] [Technorati Tag: Xorg]
