From bc950e878a06243e272493eff8a9509b4e416483 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 19 Nov 1998 16:02:06 +0000 Subject: Applied updates from remote work while doing class. --- doc/bsp_howto/shmsupp.t | 259 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 258 insertions(+), 1 deletion(-) (limited to 'doc/bsp_howto/shmsupp.t') diff --git a/doc/bsp_howto/shmsupp.t b/doc/bsp_howto/shmsupp.t index 96e0f31ab2..1e619ae2dc 100644 --- a/doc/bsp_howto/shmsupp.t +++ b/doc/bsp_howto/shmsupp.t @@ -8,5 +8,262 @@ @chapter Shared Memory Support Driver -XXX FILL ME IN +The Shared Memory Support Driver is responsible for providing glue +routines and configuration information required by the Shared +Memory Multiprocessor Communications Interface (MPCI). The +Shared Memory Support Driver tailors the portable Shared +Memory Driver to a particular target platform. + +This driver is only required in shared memory multiprocessing +systems that use the RTEMS mulitprocessing support. For more +information on RTEMS multiprocessing capabilities and the +MPCI, refer to the @b{Multiprocessing Manager} chapter +of the @b{RTEMS Application C User's Guide}. + +@section Shared Memory Configuration Table + +The Shared Memory Configuration Table is defined in the following +structure: + +@example +@group +typedef volatile rtems_unsigned32 vol_u32; + +typedef struct @{ + vol_u32 *address; /* write here for interrupt */ + vol_u32 value; /* this value causes interrupt */ + vol_u32 length; /* for this length (0,1,2,4) */ +@} Shm_Interrupt_information; + +struct shm_config_info @{ + vol_u32 *base; /* base address of SHM */ + vol_u32 length; /* length (in bytes) of SHM */ + vol_u32 format; /* SHM is big or little endian */ + vol_u32 (*convert)(); /* neutral conversion routine */ + vol_u32 poll_intr; /* POLLED or INTR driven mode */ + void (*cause_intr)( rtems_unsigned32 ); + Shm_Interrupt_information Intr; /* cause intr information */ +@}; + +typedef struct shm_config_info shm_config_table; +@end group +@end example + +where the fields are defined as follows: + +@table @b +@item base +is the base address of the shared memory buffer used to pass +messages between the nodes in the system. + +@item length +is the length (in bytes) of the shared memory buffer used to pass +messages between the nodes in the system. + +@item format +is either SHM_BIG or SHM_LITTLE to indicate that the neutral format +of the shared memory area is big or little endian. The format +of the memory should be chosen to match most of the inter-node traffic. + +@item convert +is the address of a routine which converts from native format to +neutral format. Ideally, the neutral format is the same as the +native format so this routine is quite simple. + +@item poll_intr +is either INTR_MODE or POLLED_MODE to indicate how the node will be +informed of incoming messages. + +@item cause_intr + +@item Intr +is the information required to cause an interrupt on a node. This +structure contains the following fields: +@table @b +@item address +is the address to write at to cause an interrupt on that node. +For a polled node, this should be NULL. + +@item value +is the value to write to cause an interrupt. + +@item length +is the length of the entity to write on the node to cause an interrupt. +This can be 0 to indicate polled operation, 1 to write a byte, 2 to +write a sixteen-bit entity, and 4 to write a thirty-two bit entity. +@end table +@end table + +@section Primitives + +@subsection Convert Address + +The @code{Shm_Convert_address} is responsible for converting an address +of an entity in the shared memory area into the address that should be +used from this node. Most targets will simply return the address +passed to this routine. However, some target boards will have a special +window onto the shared memory. For example, some VMEbus boards have +special address windows to access addresses that are normally reserved +in the CPU's address space. + +@example +@group +void *Shm_Convert_address( void *address ) +@{ + return the local address version of this bus address +@} +@end group +@end example + +@subsection Get Configuration + +The @code{Shm_Get_configuration} routine is responsible for filling in the +Shared Memory Configuration Table passed to it. + +@example +@group +void Shm_Get_configuration( + rtems_unsigned32 localnode, + shm_config_table **shmcfg +) +@{ + fill in the Shared Memory Configuration Table +@} +@end group +@end example + +@subsection Locking Primitives + +This is a collection of routines that are invoked by the portable +part of the Shared Memory Driver to manage locks in the shared +memory buffer area. Accesses to the shared memory must be +atomic. Two nodes in a multiprocessor system must not be manipulating +the shared data structures simultaneously. The locking primitives +are used to insure this. + +To avoid deadlock, local processor interrupts should be disabled the entire +time the locked queue is locked. + +The locking primitives operate on the lock +@code{field} of the @code{Shm_Locked_queue_Control} +data structure. This structure is defined as follows: + +@example +@group +typedef struct @{ + vol_u32 lock; /* lock field for this queue */ + vol_u32 front; /* first envelope on queue */ + vol_u32 rear; /* last envelope on queue */ + vol_u32 owner; /* receiving (i.e. owning) node */ +@} Shm_Locked_queue_Control; +@end group +@end example + +where each field is defined as follows: + +@table @b +@item lock +is the lock field. Every node in the system must agree on how this +field will be used. Many processor families provide an atomic +"test and set" instruction that is used to manage this field. + +@item front +is the index of the first message on this locked queue. + +@item rear +is the index of the last message on this locked queue. + +@item owner +is the node number of the node that currently has this structure locked. + +@end table + +@subsubsection Initializing a Shared Lock + +The @code{Shm_Initialize_lock} routine is responsible for +initializing the lock field. This routines usually is implemented +as follows: + +@example +@group +void Shm_Initialize_lock( + Shm_Locked_queue_Control *lq_cb +) +@{ + lq_cb->lock = LQ_UNLOCKED; +@} +@end group +@end example + +@subsubsection Acquiring a Shared Lock + +The @code{Shm_Lock} routine is responsible for +acquiring the lock field. Interrupts should be +disabled while that lock is acquired. If the lock +is currently unavailble, then the locking routine +should delay a few microseconds to allow the other +node to release the lock. Doing this reduces bus contention +for the lock. This routines usually is implemented as follows: + +@example +@group +void Shm_Lock( + Shm_Locked_queue_Control *lq_cb +) +@{ + disable processor interrupts + set Shm_isrstat to previous interrupt disable level + + while ( TRUE ) @{ + atomically attempt to acquire the lock + if the lock was acquired + return + delay some small period of time + @} +@} +@end group +@end example + +@subsubsection Releasing a Shared Lock + +The @code{Shm_Unlock} routine is responsible for +releasing the lock field and reenabling processor +interrupts. This routines usually is implemented as follows: + +@example +@group +void Shm_Unlock( + Shm_Locked_queue_Control *lq_cb +) +@{ + set the lock to the unlocked value + reenable processor interrupts to their level prior + to the lock being acquired. This value was saved + in the global variable Shm_isrstat +@} +@end group +@end example + +@section Installing the MPCI ISR + +The @code{Shm_setvec} is invoked by the portable portion +of the shared memory to install the interrupt service routine +that is invoked when an incoming message is announced. Some +target boards support an interprocessor interrupt or mailbox +scheme and this is where the ISR for that interrupt would be +installed. + +On an interrupt driven node, this routine would be implemented +as follows: + +@example +@group +void Shm_setvec( void ) +@{ + install the interprocessor communications ISR +@} +@end group +@end example + +On a polled node, this routine would be empty. -- cgit v1.2.3