g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  <19961997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  Index 1994  1995  <19961997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013 
<== Date ==> <== Thread ==>

From: Peregrine McGehee <mcgehee@cfht.hawaii.edu>
To: tech-talk@epics.aps.anl.gov
Date: Tue, 20 Feb 1996 13:10:55 -1000
At the Canada-France-Hawaii Telescope we have ported the EPICS IOC code to the 
Force Sparc 5 VME-based processor and have been running this version
for the past three months.

These notes are being posted to tech-talk due to their potential relevance for
the porting of EPICS IOC core to other RISC processors.

The version of EPICS we worked with is R3.12.0Beta13 1995/04/28 11:01:32.
Some of the changes mentioned here _may_ have been incorporated into the 
current release. [I haven't checked yet].

The major porting issues have been in the alignment of several buffers used in
Channel Access. The general approach taken was to force the buffer whose access
was generating a 'Memory Address Not Aligned' error to be aligned as a double.
This is usually accomplished by making use of the CA_MESSAGE_ALIGN() macro
defined in $EPICS/base/src/ca/iocmsg.h during the allocation of the buffer.

Four buffers in the $EPICS/base/src/ directories had to be aligned. They
are:

File		Routine				Buffer
----		-------				------
[IOC CA Server Code]
rsrv/server.h	N/A				message_buffer.buf
[IOC CA Client Code]
ca/access.c	ca_search_and_connect()		chix->id.paddr
ca/access.c	ca_array_put()			user supplied argument 'pvalue'
ca/access.c	ca_array_put_callback()		ppn->dbPutNotify.pbuffer

The rest of this posting provides additional details of each case.


File:	rsrv/server.h
Buffer:	message_buffer.buf
Notes:	This is a case in which we had to change the definition of a data
structure. Quoting from Jeff Hill:
	I see one possible cause of problems. If the message buffer starts
	at a proper boundary then all protocol items will be properly
	aligned because each item's length is an integer multiple of the 
	largest data item passed - a double. The structure below has 3 long's 
 	before the protocol buffer (which is an array of characters).
	Long's are 4 bytes on the SPARC so we end up with the protocol buffer 
	potentially on a 4 byte boundary. This is a problem.
 
 	struct message_buffer{
         	unsigned long           stk;
         	unsigned long           maxstk;
        	long           		cnt;
        	char                    buf[MAX_MSG_SIZE];
        };  

	Try making the following change to the structure:
 
 	 /*
	  * !! align and buf must be next to each other !!
	  *
	  * The dbr_double_t pad guarantees buf will have
	  * proper alignment because dbr_double_t is currently 
	  * the largest atomic data type passed in the CA protocol 
	  * (I really should malloc the buffer)
	  */
	struct message_buffer{
	 	const dbr_double_t	align;
	        char                    buf[MAX_MSG_SIZE];
		unsigned long           stk;
		unsigned long           maxstk;
		long           		cnt;
	};

	With a double immediately preceding the buffer the compiler
	will force proper alignment. Of course this is ugly and I 
	should malloc the buffer however I am looking for a simple
	reliable fix that will not require extensive changes on your part.


File:	ca/access.c	ca_search_and_connect()
Buffer:	chix->id.paddr
Notes: (struct db_addr *)chix->id.paddr is not properly aligned as
a result of the calloc() that creates (chid) chix. A memory alignment error 
is generated when (struct db_addr) tmp_paddr is copied to *chix->id.paddr.
Here's the source code listing to illustrate the technique used to align:

int APIENTRY ca_search_and_connect
(
 char *name_str,
 chid *chixptr,
 void (*conn_func) (struct connection_handler_args),
 void *puser
)
{
<stuff deleted>

	/* 
	 * only for IOCs 
	 */
#ifdef vxWorks
	{
		struct db_addr  tmp_paddr;
		int size;

		/* Find out quickly if channel is on this node  */
		status = db_name_to_addr(name_str, &tmp_paddr);
		if (status == OK) {
			/*
			 * allocate CHIU (channel in use) block
			 *
			 * also allocate enough for the channel name & paddr
			 * block
			 */
			size = sizeof(*chix) + strcnt + sizeof(struct db_addr);
/* Adjust size to include proper alignment of id.paddr field */
			size = CA_MESSAGE_ALIGN(size);

			*chixptr = chix = (chid) calloc(1,size);

			if (!chix){
				return ECA_ALLOCMEM;
			}

/*******************************************
 * Force chix->id.paddr to be 8-byte aligned 
********************************************/
			chix->id.paddr = (struct db_addr *) 
			CA_MESSAGE_ALIGN((strcnt + (char *) (chix + 1)));
	
			*chix->id.paddr = tmp_paddr;
<rest of routine deleted>


File:	ca/access.c	ca_array_put()
Buffer:	user supplied argument 'pvalue'
Notes:	This is sensistive to the alignment of the user supplied
argument 'pvalue'. I'm currently forcing alignment in the client
programs.


File:	ca/access.c	ca_array_put_callback()
Buffer:	ppn->dbPutNotify.pbuffer
Notes:
	if(!ppn){
                    int fill;
                    
                    /*
			ppn = (CACLIENTPUTNOTIFY *) 
				calloc(1, sizeof(*ppn)+size);
                    */
                        fill = CA_MESSAGE_ALIGN(sizeof(*ppn)) -
                            sizeof(*ppn);
                  
                        ppn = (CACLIENTPUTNOTIFY *)
                            calloc(1, sizeof(*ppn)+fill+size);
                        
			if(!ppn){
				UNLOCK;
				return ECA_ALLOCMEM;
			}
			chix->ppn = ppn;
			ppn->pcas = ca_static;
			ppn->dbPutNotify.userCallback = 
				ca_put_notify_action;
			ppn->dbPutNotify.usrPvt = chix;
			ppn->dbPutNotify.paddr = chix->id.paddr;
/*			ppn->dbPutNotify.pbuffer = (ppn+1);
 */
                        ppn->dbPutNotify.pbuffer = (char *)((int)ppn + fill);
		}


Aloha,
	Peregrine

-------------------------------------------------------------------------------
Peregrine M. McGehee			http://www.cfht.hawaii.edu/~mcgehee
Telescope Control Systems Group 	Canada-France-Hawaii Telescope
(808) 885-3178				P.O. Box 1597, Kamuela, Hawaii 96743	


Navigate by Date:
Prev: Re: Policy on C++ compilers Jeff Hill
Next: [Q] X-window's Graphics context Noboru Yamamoto
Index: 1994  1995  <19961997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013 
Navigate by Thread:
Prev: description for archive record Matthias Clausen DESY -MKV2/KRYK-
Next: [Q] X-window's Graphics context Noboru Yamamoto
Index: 1994  1995  <19961997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013 
ANJ, 10 Aug 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·