EPICS Controls 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  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  <19961997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

From: Peregrine McGehee <[email protected]>
To: [email protected]
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  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
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  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 10 Aug 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·