diff options
Diffstat (limited to 'xorg-server/hw/xfree86/doc/devel/RAC.Notes')
-rw-r--r-- | xorg-server/hw/xfree86/doc/devel/RAC.Notes | 696 |
1 files changed, 0 insertions, 696 deletions
diff --git a/xorg-server/hw/xfree86/doc/devel/RAC.Notes b/xorg-server/hw/xfree86/doc/devel/RAC.Notes deleted file mode 100644 index 0aec9d795..000000000 --- a/xorg-server/hw/xfree86/doc/devel/RAC.Notes +++ /dev/null @@ -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 |