xfree86: remove RAC/resource doc
Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com>
This commit is contained in:
parent
c553161e17
commit
6089d9cfde
|
@ -1,696 +0,0 @@
|
||||||
I. Abstract
|
|
||||||
===========
|
|
||||||
|
|
||||||
Graphics devices are accessed thru ranges in I/O or memory space. While
|
|
||||||
most modern graphics devices allow relocation of such ranges many of
|
|
||||||
them still require the use of well established interfaces such as VGA
|
|
||||||
memory and IO ranges or 8514/A IO ranges. Up to version 3.3 of
|
|
||||||
XFree86 only a single graphics device could be driven. Therfore there
|
|
||||||
was no need to address the issue of sharing such memory or I/O ranges
|
|
||||||
among several devices. Starting with version 4.0 XFree86 is capable of
|
|
||||||
driving more than one graphics interface in a multi-head environment.
|
|
||||||
Therefore a mechanism needed to be designed which was capable of
|
|
||||||
controlling the sharing the access to memory and I/O ranges. In this
|
|
||||||
document we describe to use of the RAC (Resource Access Control)
|
|
||||||
system in the XFree86 server which provides the service of controlling
|
|
||||||
access to interface resources.
|
|
||||||
|
|
||||||
II. Introduction
|
|
||||||
================
|
|
||||||
|
|
||||||
Terms and definitions:
|
|
||||||
|
|
||||||
II.1. Bus
|
|
||||||
---------
|
|
||||||
|
|
||||||
'Bus' is ambiguous as it is used for different things: It may refer to
|
|
||||||
physical incompatible extension connectors in a computer system. The
|
|
||||||
RAC system knows two such systems: The ISA bus and the PCI bus. (On
|
|
||||||
the software level EISA, MC and VL buses are currently treated like
|
|
||||||
ISA buses). 'Bus' may always refer to logically different entities on
|
|
||||||
a single bus system which are connected via bridges. A PCI system may
|
|
||||||
have several distinct PCI buses connecting each other by PCI-PCI
|
|
||||||
bridges or to the host CPU by HOST-PCI bridges.
|
|
||||||
|
|
||||||
Systems that host more than one bus system link these together using
|
|
||||||
bridges. Bridges are a concern to RAC as they might block or pass
|
|
||||||
specific resources. PCI-PCI bridges may be set up to pass VGA
|
|
||||||
resources to the secondary bus. PCI-ISA buses pass any resources not
|
|
||||||
decoded on the primary PCI bus to the ISA bus. This way VGA resources
|
|
||||||
(although exclusive on the ISA bus) can be shared by ISA and PCI
|
|
||||||
cards. Currently HOST-PCI bridges are not yet handled by RACY as they
|
|
||||||
require specific drivers.
|
|
||||||
|
|
||||||
II.2. Entity
|
|
||||||
------------
|
|
||||||
|
|
||||||
The smallest independently addressable unit on a system bus is
|
|
||||||
referred to as an entity. So far we know ISA and PCI entities. PCI
|
|
||||||
entities can be located on the PCI bus by an unique ID consisting of
|
|
||||||
the bus, card and function number.
|
|
||||||
|
|
||||||
II.3. Resource
|
|
||||||
--------------
|
|
||||||
|
|
||||||
'Resource' refers to a range of memory or I/O addresses an entity
|
|
||||||
can decode.
|
|
||||||
|
|
||||||
If a device is capable of disabling this decoding the resource is
|
|
||||||
called sharable. For PCI devices a generic method is provided to
|
|
||||||
control resource decoding. Other devices will have to provide a device
|
|
||||||
specific function to control decoding.
|
|
||||||
|
|
||||||
If the entity is capable of decoding this range at a different
|
|
||||||
location this resource is considered relocatable. Resource which start
|
|
||||||
at a specific address and occupy a single continuous range are called
|
|
||||||
block resources.
|
|
||||||
|
|
||||||
Alternatively resource addresses can be decoded in a way that they
|
|
||||||
satisfy the condition:
|
|
||||||
|
|
||||||
address & mask == base
|
|
||||||
|
|
||||||
with base & mask == base. Resources addressed in such a way are
|
|
||||||
considered sparse resources.
|
|
||||||
|
|
||||||
|
|
||||||
II.4. Server States
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The resource access control system knows two server states: the SETUP
|
|
||||||
and the OPERATING state. The setup state is entered whenever a mode
|
|
||||||
change takes place or the server exits or does VT switching. During
|
|
||||||
this state any entity resource is under resource access control.
|
|
||||||
During OPERATING state only those entities are controlled which
|
|
||||||
actually have shared resources that conflict with others. The
|
|
||||||
determination which entity is to be placed under RAC during OPERATING
|
|
||||||
state takes place after ScreenInit() during the first server
|
|
||||||
generation. This doesn't apply if only one screen is active: in this
|
|
||||||
case no RAC is needed and the screen is simply left enabled while the
|
|
||||||
server is active.
|
|
||||||
|
|
||||||
|
|
||||||
III. Theory of operation
|
|
||||||
========================
|
|
||||||
|
|
||||||
III.1. General
|
|
||||||
--------------
|
|
||||||
|
|
||||||
The common level has knowledge of generic access control mechanisms
|
|
||||||
for devices on certain bus systems (currently the PCI bus) as well as
|
|
||||||
of methods to enable or disable access to the buses
|
|
||||||
itself. Furthermore it can access information on resources decoded by
|
|
||||||
these devices and if necessary modify it.
|
|
||||||
|
|
||||||
When first starting the Xserver collects all this information, saves
|
|
||||||
it for restoration checks it for consistency and if necessary corrects
|
|
||||||
it. Finally it disables all resources on a generic level prior to
|
|
||||||
calling any driver function.
|
|
||||||
|
|
||||||
The user should provide a device section in XF86Config for each
|
|
||||||
graphics device installed in his system. Each such entity which is
|
|
||||||
never to be used as X display device might be marked as inactive by
|
|
||||||
adding the keyword "Inactive" to the device section.
|
|
||||||
|
|
||||||
When the Probe() function of each driver is called the device sections
|
|
||||||
are matched against the devices found in the system. The driver may
|
|
||||||
probe devices at this stage that cannot be identified by using device
|
|
||||||
independent methods. Access to all resources that can be controlled in
|
|
||||||
a device independent way is disabled. The Probe() function should
|
|
||||||
register all non-relocatable resources at this stage. If a resource
|
|
||||||
conflict is found between exclusive resources the driver will fail
|
|
||||||
immediately. Optionally the driver might specify an EntityInit(),
|
|
||||||
EntityLeave() and EntityEnter() function.
|
|
||||||
|
|
||||||
EntityInit() can be used to disable any shared resources that are not
|
|
||||||
controlled by the generic access control functions. It is called prior
|
|
||||||
to the PreInit phase regardless if an entity is active or not. When
|
|
||||||
calling the EntityInit(), EntityEnter() and EntityLeave() functions
|
|
||||||
the common level will disable access to all other entities on a
|
|
||||||
generic level. Since the common level has no knowledge of device
|
|
||||||
specific methods to disable access to resources it cannot be
|
|
||||||
guaranteed that certain resources are not decoded by any other entity
|
|
||||||
until the EntityInit() or EntityEnter() phase is finished. Device
|
|
||||||
drivers should therefore register all those resources which they are
|
|
||||||
going to disable. If these resources are never to be used by any
|
|
||||||
driver function they may be flagged 'ResInit' so that they can be
|
|
||||||
removed from the resource list after processing all EntityInit()
|
|
||||||
functions. EntityEnter() should disable decoding of all resources
|
|
||||||
which are not registered as exclusive and which are not handled by the
|
|
||||||
generic access control in the common level. The difference to
|
|
||||||
EntityInit() is that the latter one is only called once during
|
|
||||||
lifetime of the server. It can therefore be used to set up variables
|
|
||||||
prior to disabling resources. EntityLeave() should restore the
|
|
||||||
original state when exiting the server or switching to a different vt.
|
|
||||||
It also needs to disable device specific access functions if they need
|
|
||||||
to be disabled on server exit or VT switch. The default state is to
|
|
||||||
enable them before giving up the VT.
|
|
||||||
|
|
||||||
In PreInit() phase each driver should check if any sharable resources
|
|
||||||
it has registered during Probe() has been denied and take appropriate
|
|
||||||
action which could simply be to fail. If it needs to access resources
|
|
||||||
it has disabled during EntitySetup() it can do so provided it has
|
|
||||||
registered these and will disable them before returning from
|
|
||||||
PreInit(). This also applies to all other driver functions. Several
|
|
||||||
functions are provided to request resource ranges, register these,
|
|
||||||
correct PCI config space and add replacements for the generic access
|
|
||||||
functions. Resources may be marked 'disabled' or 'unused' during
|
|
||||||
OPERATING stage. Although these steps could also be performed in
|
|
||||||
ScreenInit(), this is not desirable.
|
|
||||||
|
|
||||||
Following PreInit() phase the common level determines if resource
|
|
||||||
access control is needed. This is the case if more than one screen is
|
|
||||||
used. If necessary the RAC wrapper module is loaded. In ScreenInit()
|
|
||||||
the drivers can decide which operations need to be placed under
|
|
||||||
RAC. Available are the frame buffer operations, the pointer operations
|
|
||||||
and the colormap operations. Any operation that requires resources
|
|
||||||
which might be disabled during OPERATING state should be set to use
|
|
||||||
RAC. This can be specified separately for memory and IO resources.
|
|
||||||
|
|
||||||
When ScreenInit() phase is done the common level will determine which
|
|
||||||
shared resources are requested by more than one driver and set the
|
|
||||||
access functions accordingly. This is done following these rules:
|
|
||||||
|
|
||||||
a. The sharable resources registered by each entity are compared. if
|
|
||||||
a resource is registered by more than one entity the entity will be
|
|
||||||
marked to need to share this resources type (IO or MEM).
|
|
||||||
|
|
||||||
b. A resource marked 'disabled' during OPERATING state will be ignored
|
|
||||||
entirely.
|
|
||||||
|
|
||||||
c. A resource marked 'unused' will only conflicts with an overlapping
|
|
||||||
resource of an other entity if the second is actually in use during
|
|
||||||
OPERATING state.
|
|
||||||
|
|
||||||
d. If an 'unused' resource was found to conflict however the entity
|
|
||||||
does not use any other resource of this type the entire resource
|
|
||||||
type will be disabled for that entity.
|
|
||||||
|
|
||||||
The driver has the choice among different ways to control access to
|
|
||||||
certain resources:
|
|
||||||
|
|
||||||
a. It can relay on the generic access functions. This is probably the
|
|
||||||
most common case. Here the driver only needs to register any
|
|
||||||
resource it is going to use.
|
|
||||||
|
|
||||||
b. It can replace the generic access functions by driver specific
|
|
||||||
ones. This will mostly be used in cases where no generic access
|
|
||||||
functions are available. In this case the driver has to make sure
|
|
||||||
these resources are disabled when entering the PreInit() stage.
|
|
||||||
Since the replacement functions are registered in PreInit() the
|
|
||||||
driver will have to enable these resources itself if it needs to
|
|
||||||
access them during this state. The driver can specify if the
|
|
||||||
replacement functions can control memory and/or I/O resources
|
|
||||||
separately.
|
|
||||||
|
|
||||||
c. The driver can enable resources itself when it needs them. Each
|
|
||||||
driver function enabling them needs to disable them before it will
|
|
||||||
return. This should be used if a resource which can be controlled
|
|
||||||
in a device dependent way is only required during SETUP state. This
|
|
||||||
way it can be marked 'unused' during OPERATING state.
|
|
||||||
|
|
||||||
A resource which is decoded during OPERATING state however never
|
|
||||||
accessed by the driver should be marked unused.
|
|
||||||
|
|
||||||
Since access switching latencies are an issue during Xserver
|
|
||||||
operation, the common level attempts to minimize the number of
|
|
||||||
entities that need to be placed under RAC control. When a wrapped
|
|
||||||
operation is called, the EnableAccess() function is called before
|
|
||||||
control is passed on. EnableAccess() checks if a screen is under
|
|
||||||
access control. If not it just establishes bus routing and returns. If
|
|
||||||
the screen needs to be under access control, EnableAccess() determines
|
|
||||||
which resource types (MEM,IO) are required. Then it tests if this
|
|
||||||
access is already established. If so it simply returns. If not it
|
|
||||||
disables the currently established access, fixes bus routing and
|
|
||||||
enables access to all entities registered for this screen.
|
|
||||||
|
|
||||||
Whenever a mode switch or a vt-switch is performed the common level
|
|
||||||
will return to SETUP state.
|
|
||||||
|
|
||||||
III.3. Resource Types
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Resource have certain properties. When registering resources each
|
|
||||||
range is accompanied by a flag consisting of the or'ed flags of the
|
|
||||||
different properties the resource has. Each resource range may be
|
|
||||||
classified according to
|
|
||||||
|
|
||||||
- its physical properties ie. if it addresses
|
|
||||||
memory (ResMem) or
|
|
||||||
I/O space (ResIo),
|
|
||||||
- if it addresses a
|
|
||||||
block (ResBlock) or
|
|
||||||
sparse (ResSparse)
|
|
||||||
range,
|
|
||||||
- its access properties.
|
|
||||||
|
|
||||||
There are two known access properties:
|
|
||||||
|
|
||||||
- ResExclusive
|
|
||||||
for resources which may not be shared with any other device and
|
|
||||||
- ResShared
|
|
||||||
for resources which can be disabled and therefore can be shared.
|
|
||||||
|
|
||||||
If it is desirable to test a resource against any type a generic
|
|
||||||
access type 'ResAny' is provided. If this is set the resource will
|
|
||||||
conflict with any resource of a different entity intersecting its
|
|
||||||
range. Further it can be specified that a resource is decoded however
|
|
||||||
never used during any stage (ResUnused) or during OPERATING state
|
|
||||||
(ResUnusedOpr). A resource only visible during the init functions (ie.
|
|
||||||
EntityInit(), EntityEnter() and EntityLeave() should be registered
|
|
||||||
with the flag 'ResInit'. A resource that might conflict with
|
|
||||||
background resource ranges may be flagged with 'ResBios'. This might
|
|
||||||
be useful when registering resources ranges that were assigned by the
|
|
||||||
system Bios.
|
|
||||||
|
|
||||||
Several predefined resource lists are available for VGA and 8514/A
|
|
||||||
resources in common/sf86Resources.h.
|
|
||||||
|
|
||||||
IV. Available Functions
|
|
||||||
=======================
|
|
||||||
|
|
||||||
The functions provided for resource management will be listed in order
|
|
||||||
of use in the driver.
|
|
||||||
|
|
||||||
IV.1. Probe phase
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
In this stage each driver detects those resources it is able to drive,
|
|
||||||
creates an entity record for each of them, registers non-relocatable
|
|
||||||
resources and allocates screens and adds the resources to screens.
|
|
||||||
|
|
||||||
Two helper functions are provided for matching device sections in the
|
|
||||||
XF86Config file to the devices:
|
|
||||||
|
|
||||||
int xf86MatchPciInstances(const char *driverName, int vendorID,
|
|
||||||
SymTabPtr chipsets, PciChipsets *PCIchipsets,
|
|
||||||
GDevPtr *devList, int numDevs, DriverPtr drvp,
|
|
||||||
int **foundEntities);
|
|
||||||
|
|
||||||
int xf86MatchIsaInstances(const char *driverName, SymTabPtr chipsets,
|
|
||||||
IsaChipsets *ISAchipsets, DriverPtr drvp,
|
|
||||||
FindIsaDevProc FindIsaDevice, GDevPtr *devList,
|
|
||||||
int numDevs, int **foundEntities);
|
|
||||||
|
|
||||||
Both functions return the number of matched entities and their indices
|
|
||||||
in foundEntities list.
|
|
||||||
|
|
||||||
They make use of several sub functions which are also available on the
|
|
||||||
driver level:
|
|
||||||
|
|
||||||
Bool xf86ComparePciBusString(const char *busID, int bus,
|
|
||||||
int device, int func);
|
|
||||||
|
|
||||||
and
|
|
||||||
|
|
||||||
Bool xf86ParseIsaBusString(const char *busID);
|
|
||||||
|
|
||||||
are called to interpret the busID in the device section. The functions:
|
|
||||||
|
|
||||||
int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
|
|
||||||
int chipset, GDevPtr dev, Bool active);
|
|
||||||
|
|
||||||
int xf86ClaimIsaSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool
|
|
||||||
active);
|
|
||||||
|
|
||||||
are used to allocate the entities and initialize their data
|
|
||||||
structures. Both functions return the index of the newly allocated
|
|
||||||
entity record or (-1) should the function fail. Before probing an ISA
|
|
||||||
card
|
|
||||||
|
|
||||||
Bool xf86IsPrimaryIsa();
|
|
||||||
|
|
||||||
gets called to determine if the primary card was not detected on the
|
|
||||||
PCI bus.
|
|
||||||
|
|
||||||
Two helper functions are provided to aid configuring entities:
|
|
||||||
|
|
||||||
Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
|
|
||||||
PciChipsets *p_chip, resList res,
|
|
||||||
EntityProc init, EntityProc enter,
|
|
||||||
EntityProc leave, pointer private);
|
|
||||||
Bool xf86ConfigActiveIsaEntity(ScrnInfoPtr pScrn, int entityIndex,
|
|
||||||
IsaChipsets *i_chip, resList res,
|
|
||||||
EntityProc init, EntityProc enter,
|
|
||||||
EntityProc leave, pointer private);
|
|
||||||
|
|
||||||
They are used to register the init/enter/leave functions described
|
|
||||||
above as well as the non-relocatable resources. Generally the list of
|
|
||||||
fixed resources is obtained from the Isa/PciChipsets lists. However
|
|
||||||
an additional list of resources may be passed. Generally this is not
|
|
||||||
required. The init/enter/leave functions have to be of type
|
|
||||||
|
|
||||||
typedef void (*EntityProc)(int entityIndex,pointer private);
|
|
||||||
|
|
||||||
They are passed the entity index and a pointer to a private scratch
|
|
||||||
area. This are can be set up during Probe() and its address can be
|
|
||||||
passed to xf86ConfigActiveIsaEntity() xf86ConfigActivePciEntity() as
|
|
||||||
the last argument.
|
|
||||||
|
|
||||||
These helper functions use:
|
|
||||||
|
|
||||||
void xf86ClaimFixedResources(resList list, int entityIndex);
|
|
||||||
|
|
||||||
To register the non relocatable resources which cannot be disabled
|
|
||||||
and which therefore would cause the server to fail immediately if
|
|
||||||
they were found to conflict. It also records non-relocatable but
|
|
||||||
sharable resources for processing after the Probe() phase.
|
|
||||||
|
|
||||||
Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
|
|
||||||
EntityProc enter, EntityProc leave, pointer);
|
|
||||||
|
|
||||||
This function registers the init/enter/leave() functions along with
|
|
||||||
the pointer to their private area to the entity.
|
|
||||||
|
|
||||||
void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
|
|
||||||
|
|
||||||
adds the entity to the screen.
|
|
||||||
|
|
||||||
These functions are also available on the driver level. A detailed
|
|
||||||
Probe() function is listed below. For most drivers this can be used
|
|
||||||
with little change.
|
|
||||||
|
|
||||||
Please note that VGA resources have to be claimed in Probe()
|
|
||||||
phase. Otherwise they are not routed to the bus.
|
|
||||||
|
|
||||||
IV.2. PreInit() phase
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
During this phase the remaining resource should be registered.
|
|
||||||
PreInit() should call
|
|
||||||
|
|
||||||
EntityInfoPtr xf86GetEntityInfo(int entityIndex);
|
|
||||||
|
|
||||||
To obtain a pointer to an EntityInfoRec for each entity it is able to
|
|
||||||
drive and check if any resource are listed in 'resources'. These have
|
|
||||||
been rejected in the post-Probe() phase. The driver should decide if
|
|
||||||
it can continue without using these or if it should fail. The pointer
|
|
||||||
to the EntityInfoRec should be freed if not needed any more.
|
|
||||||
|
|
||||||
Several functions are provided to simplify resource registration:
|
|
||||||
|
|
||||||
Bool xf86IsEntityPrimary(int entityIndex);
|
|
||||||
|
|
||||||
is used to determine if the entity is the display device that is used
|
|
||||||
during boot-up and text mode.
|
|
||||||
|
|
||||||
Bool xf86IsScreenPrimary(int scrnIndex);
|
|
||||||
|
|
||||||
finds out if the primary entity is registered for the screen with
|
|
||||||
specified index.
|
|
||||||
|
|
||||||
pciVideoPtr xf86GetPciInfoForEntity(int entityIndex);
|
|
||||||
|
|
||||||
returns a pointer to the pciVideoRec of the specified entity. If the
|
|
||||||
entity is not a PCI device NULL is returned.
|
|
||||||
|
|
||||||
The primary function for registration of resources is
|
|
||||||
|
|
||||||
resPtr xf86RegisterResources(int entityIndex, resList list, int access);
|
|
||||||
|
|
||||||
it tries to register the resources in 'list'. If list is NULL it tries
|
|
||||||
to determine the resources automatically. This only works for entities
|
|
||||||
that provide a generic way to read out the resource ranges they
|
|
||||||
decode. So far this is only the case for PCI devices. By default the
|
|
||||||
PCI resources are registered as shared (ResShared) if the driver wants
|
|
||||||
to set a different access type it can do so by specifying the access
|
|
||||||
flags in the third argument. A value of 0 means to use the default
|
|
||||||
settings. If for any reason the resource broker is not able to
|
|
||||||
register some of the requested resources the function will return a
|
|
||||||
pointer to a list of the failed ones. In this case the driver may move
|
|
||||||
the resource to different locations. In case of PCI bus entities this
|
|
||||||
is done by passing the list of failed resources to
|
|
||||||
|
|
||||||
resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes);
|
|
||||||
|
|
||||||
this function returns a list of reallocated resource. This list needs
|
|
||||||
to be passed to xf86RegisterResources() again to be registered with
|
|
||||||
the broker.
|
|
||||||
|
|
||||||
Two functions are provided to obtain a resource range of a given type:
|
|
||||||
|
|
||||||
resRange xf86GetBlock(long type, memType size,
|
|
||||||
memType window_start, memType window_end,
|
|
||||||
memType align_mask, resPtr avoid);
|
|
||||||
resRange xf86GetSparse(long type, unsigned long fixed_bits,
|
|
||||||
unsigned long decode_mask, unsigned long address_mask,
|
|
||||||
resPtr avoid);
|
|
||||||
|
|
||||||
The first one tries to find a block range of size 'size' and type
|
|
||||||
'type' in a window bound by window_start and window_end with the
|
|
||||||
alignment specified in alignment mask. Optionally a list of resource
|
|
||||||
ranges which should be avoided inside this window can be passed. On
|
|
||||||
failure it will return a zero range of type 'ResEnd'.
|
|
||||||
|
|
||||||
The latter function does the same for sparse resources. A spares range
|
|
||||||
is determined by to parameters: the mask and the base value. An
|
|
||||||
address satisfying
|
|
||||||
|
|
||||||
mask & address == base
|
|
||||||
|
|
||||||
belongs to the specific spares range. 'mask' and 'base' themselves
|
|
||||||
have to satisfy:
|
|
||||||
|
|
||||||
mask & base == base.
|
|
||||||
|
|
||||||
Here three values have to be specified: the address mask which marks
|
|
||||||
all bits of the mask part of the address, the decode_mask which masks
|
|
||||||
out the bits which are hard coded and are therefore not available for
|
|
||||||
relocation and the values of the fixed bits. The function tries to
|
|
||||||
find a base that satisfies the given condition. If the function fails
|
|
||||||
it will return a zero range of type 'ResEnd'. Optionally it might be
|
|
||||||
passed a list of resource ranges to avoid.
|
|
||||||
|
|
||||||
Certain PCI devices are broken in the sense that they return invalid
|
|
||||||
size information for a certain resource. In this case the driver can
|
|
||||||
supply the correct size and make sure that the resource range
|
|
||||||
allocated for the card is large enough to hold the address range
|
|
||||||
decoded by the card. The function:
|
|
||||||
|
|
||||||
Bool xf86FixPciResource(int entityIndex, unsigned int prt, CARD32 alignment,
|
|
||||||
long type);
|
|
||||||
|
|
||||||
is used for that. The parameter prt contains the number of the PCI
|
|
||||||
base register that needs to be modified. A value of 6 refers to the
|
|
||||||
BIOS base register. The size is specified in the alignment
|
|
||||||
register. Since PCI resources need to span an integral range of the
|
|
||||||
size 2^n the alignment also specifies the number of addresses that
|
|
||||||
will be decoded. If the driver specifies a type mask it can override
|
|
||||||
the default type for PCI resources which is 'ResShared'. The resource
|
|
||||||
broker needs to know that to find a matching resource range. This
|
|
||||||
function should be called before calling xf86RegisterResources().
|
|
||||||
|
|
||||||
Bool xf86CheckPciMemBase(pciVideoPtr pPci, unsigned long base);
|
|
||||||
|
|
||||||
checks that the memory base value specified in base matches one of the
|
|
||||||
PCI base address register values for the given PCI device.
|
|
||||||
|
|
||||||
The driver may replace the generic access control functions for an
|
|
||||||
entity by it's own ones.
|
|
||||||
|
|
||||||
void xf86SetAccessFuncs(EntityInfoPtr pEnt, xf86SetAccessFuncPtr funcs,
|
|
||||||
xf86SetAccessFuncPtr oldFuncs);
|
|
||||||
|
|
||||||
with:
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
xf86AccessPtr mem;
|
|
||||||
xf86AccessPtr io;
|
|
||||||
xf86AccessPtr io_mem;
|
|
||||||
} xf86SetAccessFuncRec, *xf86SetAccessFuncPtr;
|
|
||||||
|
|
||||||
is used for that. The driver can pass three functions: one for I/O
|
|
||||||
access, one for memory access and one for combined memory and I/O
|
|
||||||
access. If the memory access and combined access functions are
|
|
||||||
identical the common level assumes that the memory access cannot be
|
|
||||||
controlled independently of I/O access, if the I/O access function and
|
|
||||||
the combined access functions are the same it is assumed that I/O can
|
|
||||||
not be controlled independently. If memory and I/O have to be
|
|
||||||
controlled together all three values should be the same. If a non
|
|
||||||
NULL value is passed as third argument it is interpreted as an address
|
|
||||||
where to store the old access records. If the third argument is NULL
|
|
||||||
it will be assumed that the generic access should be enabled before
|
|
||||||
replacing the access functions. Otherwise it will be disabled. The
|
|
||||||
driver may enable them itself using the returned values. It should do
|
|
||||||
this from his replacement access functions as the generic access may
|
|
||||||
be disabled by the common level on certain occasions. If replacement
|
|
||||||
functions are specified they must control all resources of the
|
|
||||||
specific type registered for the entity.
|
|
||||||
|
|
||||||
To find out if specific resource range is conflicting with another
|
|
||||||
resource
|
|
||||||
|
|
||||||
memType xf86ChkConflict(resRange *rgp, int entityIndex);
|
|
||||||
|
|
||||||
may be called. If a non-zero value is returned a conflict is found.
|
|
||||||
|
|
||||||
resPtr xf86SetOperatingState(resList list, int entityIndex, int mask);
|
|
||||||
|
|
||||||
is used to set the state of a resource during OPERATING state. 'list'
|
|
||||||
holds a list to which 'mask' is to be applied. The parameter 'mask'
|
|
||||||
may have the value 'ResUnusedOpr' and 'ResDisableOpr'. The first one
|
|
||||||
should be used if a resource isn't used during OPERATING state however
|
|
||||||
decoded by the device while the latter one indicates that the resource
|
|
||||||
is not decoded during OPERATING state. Note that the resource ranges
|
|
||||||
have to match those specified during registration. If a range has been
|
|
||||||
specified starting at A and ending at B and suppose C us a value
|
|
||||||
satisfying A < C < B one may not specify the resource range (A,B) by
|
|
||||||
splitting it into two ranges (A,C) and (C,B).
|
|
||||||
|
|
||||||
Two functions are provided for special cases:
|
|
||||||
|
|
||||||
void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
|
|
||||||
|
|
||||||
may be used to remove an entity from a screen. This only makes sense
|
|
||||||
if a screen has more than one entity assigned or the screen is to be
|
|
||||||
deleted. No test is made if the screen has any entities left.
|
|
||||||
|
|
||||||
void xf86DeallocateResourcesForEntity(int entityIndex, long type);
|
|
||||||
|
|
||||||
deallocates all resources of a given type registered for a certain
|
|
||||||
entity from the resource broker list.
|
|
||||||
|
|
||||||
IV.3. ScreenInit() phase
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
Setting up the rac flags is all that remains to do in ScreenInit()
|
|
||||||
phase (Note that these flags might also be set up in PreInit() phase).
|
|
||||||
The ScrnInfoRec has separate flags for memory and PIO access:
|
|
||||||
racIoFlags and racMemFlags. They specifies which graphics operations
|
|
||||||
might require the use of resources which might be disabled for some
|
|
||||||
reason. Note that even exclusive resources might be disabled if they
|
|
||||||
are disabled along with shared resources. For example if a driver has
|
|
||||||
registered the VGA PIO resources and lets the common level disable
|
|
||||||
these by disabling PIO access in PCI config space (the standard way),
|
|
||||||
exclusive PCI PIO ranges will also be disabled. Therefore the driver
|
|
||||||
has to flag any operations requiring PCI PIO resources in racIoFlags.
|
|
||||||
The avaliable flags are defined in rac/xf86RAC.h. Available are:
|
|
||||||
|
|
||||||
RAC_FB for framebuffer operations (including hw acceleration)
|
|
||||||
RAC_CURSOR for Cursor operations
|
|
||||||
(??? I'm not sure if we need this for SW cursor it depends
|
|
||||||
on which level the sw cursor is drawn)
|
|
||||||
RAC_COLORMAP for colormap operations
|
|
||||||
RAC_VIEWPORT for the call to RACAdjustFrame()
|
|
||||||
|
|
||||||
The flags are or'ed.
|
|
||||||
|
|
||||||
V. Appendix
|
|
||||||
===========
|
|
||||||
|
|
||||||
A. Sample Probe() Function
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
XXXProbe(DriverPtr drv, int flags)
|
|
||||||
{
|
|
||||||
Bool foundScreen = FALSE;
|
|
||||||
int numDevSections, numUsed;
|
|
||||||
GDevPtr *devSections;
|
|
||||||
int *usedChips;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the config file Device sections that match this
|
|
||||||
* driver, and return if there are none.
|
|
||||||
*/
|
|
||||||
if ((numDevSections = xf86MatchDevice(CHIPS_DRIVER_NAME,
|
|
||||||
&devSections)) <= 0) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* PCI BUS */
|
|
||||||
/* test if PCI bus present */
|
|
||||||
if (xf86GetPciVideoInfo() ) {
|
|
||||||
/* match PCI instances with ones supported by the driver */
|
|
||||||
numUsed = xf86MatchPciInstances(XXX_NAME, PCI_VENDOR_XXX,
|
|
||||||
XXXChipsets, XXXPCIchipsets,
|
|
||||||
devSections,numDevSections, drv,
|
|
||||||
&usedChips);
|
|
||||||
if (numUsed > 0) {
|
|
||||||
for (i = 0; i < numUsed; i++) {
|
|
||||||
/* Allocate a ScrnInfoRec */
|
|
||||||
ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
|
|
||||||
pScrn->driverVersion = VERSION;
|
|
||||||
pScrn->driverName = XXX_DRIVER_NAME;
|
|
||||||
pScrn->name = XXX_NAME;
|
|
||||||
pScrn->Probe = XXXProbe;
|
|
||||||
pScrn->PreInit = XXXPreInit;
|
|
||||||
pScrn->ScreenInit = XXXScreenInit;
|
|
||||||
pScrn->SwitchMode = XXXSwitchMode;
|
|
||||||
pScrn->AdjustFrame = XXXAdjustFrame;
|
|
||||||
pScrn->EnterVT = XXXEnterVT;
|
|
||||||
pScrn->LeaveVT = XXXLeaveVT;
|
|
||||||
pScrn->FreeScreen = XXXFreeScreen;
|
|
||||||
pScrn->ValidMode = XXXValidMode;
|
|
||||||
foundScreen = TRUE;
|
|
||||||
/* add screen to entity */
|
|
||||||
xf86ConfigActivePciEntity(pScrn,usedChips[i],XXXPCIchipsets,
|
|
||||||
NULL,NULL,NULL,NULL,NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Isa Bus */
|
|
||||||
numUsed = xf86MatchIsaInstances(XXX_NAME,XXXChipsets,XXXISAchipsets,
|
|
||||||
drv,chipsFindIsaDevice,devSections,
|
|
||||||
numDevSections,&usedChips);
|
|
||||||
if(numUsed >= 0)
|
|
||||||
for (i = 0; i < numUsed; i++) {
|
|
||||||
ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
|
|
||||||
|
|
||||||
pScrn->driverVersion = VERSION;
|
|
||||||
pScrn->driverName = XXX_DRIVER_NAME;
|
|
||||||
pScrn->name = XXX_NAME;
|
|
||||||
pScrn->Probe = XXXProbe;
|
|
||||||
pScrn->PreInit = XXXPreInit;
|
|
||||||
pScrn->ScreenInit = XXXScreenInit;
|
|
||||||
pScrn->SwitchMode = XXXSwitchMode;
|
|
||||||
pScrn->AdjustFrame = XXXAdjustFrame;
|
|
||||||
pScrn->EnterVT = XXXEnterVT;
|
|
||||||
pScrn->LeaveVT = XXXLeaveVT;
|
|
||||||
pScrn->FreeScreen = XXXFreeScreen;
|
|
||||||
pScrn->ValidMode = XXXValidMode;
|
|
||||||
foundScreen = TRUE;
|
|
||||||
xf86ConfigActiveIsaEntity(pScrn,usedChips[i],XXXISAchipsets,
|
|
||||||
NULL,NULL,NULL,NULL,NULL);
|
|
||||||
}
|
|
||||||
xfree(devSections);
|
|
||||||
return foundScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
B. Porting Issues
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Here are some hints on porting code developed for RAC 1 to RAC 2.
|
|
||||||
|
|
||||||
1. a. Initialization of RAC is now entirely done on the common level.
|
|
||||||
Therefore the call to xf86RACInit() can be removed.
|
|
||||||
|
|
||||||
b. Also there is no need for the racSymbols list.
|
|
||||||
|
|
||||||
c. LoadSubModule(..,rac) should be removed.
|
|
||||||
|
|
||||||
d. racSymbols should be removed from LoaderRequestSymList(racSymbols,..)
|
|
||||||
|
|
||||||
2. a. if the driver uses the predefined resource lists xf86Resources.h
|
|
||||||
needs to be included.
|
|
||||||
|
|
||||||
b. RES_VGA should be changed to RES_EXCLUSIVE_VGA
|
|
||||||
|
|
||||||
3. The device list now belongs to the EntityInfoRec.
|
|
||||||
Change pScrn->device to xxx->pEnt->device.
|
|
||||||
|
|
||||||
4. Rewrite the Probe() function. The example given above should work
|
|
||||||
as a guideline.
|
|
||||||
|
|
||||||
5. Register all necessary resources in PreInit() by calling
|
|
||||||
xf86RegisterResources().
|
|
||||||
|
|
||||||
6. If applicable set the operating state of the registered resources
|
|
||||||
by calling xf86SetOperatingState(). This should be done during
|
|
||||||
PreInit(). If necessary it might still be done in ScreenInit()
|
|
||||||
|
|
||||||
7. Set up the racIoFlags and racMemFlags.
|
|
||||||
|
|
||||||
|
|
||||||
LocalWords: ISA
|
|
Loading…
Reference in New Issue