EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  <20002001  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  1996  1997  1998  1999  <20002001  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 ==>

Subject: Re: mv162lx and NI-1014
From: Andrew Johnson <[email protected]>
To: Geoff Savage <[email protected]>
Cc: tech-talk <[email protected]>
Date: Mon, 27 Mar 2000 15:28:14 -0600
Geoff Savage wrote:
> 
> After searching through the archives it appears that I need to modify my
> mv162lx BSP to handle A24 DMA correctly.  Has someone already made this
> modification?  Can I get a copy?  Are any changes to the driver
> (drvGpib.c) necessary?

Geoff,

the following routines are from the sysLib.c of my latest mv162 BSP in use
here at APS. I haven't looked at all the changes I made, but hopefully you
should get the idea and be able to use most of this code as is.  You'll
also have to modify sysProcNumSet() to disable the A24 VME window [clear
the VSAMSR2 bits of VMECHIP2_VSAMSR - the A24 window is set up later in
sysA24MapRam()], and change the A24 part of sysLocalToBusAdrs() as shown. 
You shouldn't need to change anything in the NI-1014 gpib driver, which
uses devLib routines that call sysA24Malloc() if it is present.

None of the code below was written by Wind River Systems.

- Andrew
-- 
Complexity comes for free, Simplicity you have to work for.


---- from sysLocalToBusAdrs: ------------------------------------------

        case VME_AM_STD_SUP_PGM:
        case VME_AM_STD_SUP_DATA:
        case VME_AM_STD_USR_PGM:
        case VME_AM_STD_USR_DATA:
            if (*VMECHIP2_VSAMSR & VSAMSR2_A24)
	        {
        	ULONG vsatr = *VMECHIP2_VSATR2;
		ULONG vsar  = *VMECHIP2_VSAR2;
		ULONG adrs = vsatr & (vsatr << 16);
		if (((ULONG)localAdrs < adrs) ||
		    ((ULONG)localAdrs > adrs + (vsar | 0x0000ffff)))
		    return (ERROR);
		adrs = (ULONG)localAdrs - adrs + ((vsar & 0xffff) << 16);
		*pBusAdrs = (char *)adrs;
		return (OK);
		}
	    return (ERROR);

---- other routines: -------------------------------------------------

/*******************************************************************************
*
* sysVmeMapShow - report mappings between VMEbus and local memory
*
* This routine displays the mapping between VMEbus and local memory 
* locations in both directions.
*
* RETURNS: OK
*
* NOMANUAL
*/

STATUS sysVmeMapShow(void)
    {
    unsigned int local, vme, size;
    
    printf("\nVMEbus viewed from CPU:\n");
    vme  = *VMECHIP2_LBSAR1 << 16;
    if (vme < 0x80000000) vme = 0x80000000;	/* dtt1 setting */
    size = *VMECHIP2_LBSAR1 | 0x0000ffff;
    printf("  CPU:\t0x%8.8X - 0x%8.8X  =>  A32: 0x%8.8X - 0x%8.8X\n",
	   vme, size, vme, size);
    printf("\t0xF0000000 - 0xF0FFFFFF  =>  A24:   0x000000 -  
0xFFFFFF\n");
    printf("\t0xFFFF0000 - 0xFFFFFFFF  =>  A16:     0x0000 -    
0xFFFF\n");
    
    printf("\nCPU viewed from VMEbus:\n");
    if (*VMECHIP2_VSAMSR & VSAMSR1_A32)
	{
	local = *VMECHIP2_VSATR1 & (*VMECHIP2_VSATR1 << 16);
	vme   = *VMECHIP2_VSAR1 << 16;
	size  = (*VMECHIP2_VSAR1 | 0x0000ffff) - vme;
	printf("  A32:\t0x%8.8X - 0x%8.8X  =>  CPU: 0x%8.8X - 0x%8.8X\n",
		vme, vme + size, local, local + size);
	}
    else
	printf("  A32:\t           -             =>                  -\n");
    
    if (*VMECHIP2_VSAMSR & VSAMSR2_A24)
	{
	local = *VMECHIP2_VSATR2 & (*VMECHIP2_VSATR2 << 16);
	vme   = *VMECHIP2_VSAR2 << 16;
	size  = (*VMECHIP2_VSAR2 | 0x0000ffff) - vme;
	printf("  A24:\t  0x%6.6X -   0x%6.6X  =>       0x%8.8X - 0x%8.8X\n",
		vme, vme + size, local, local + size);
	}
    else
	printf("  A24:\t           -             =>                  -\n");
    
    vme = (unsigned) (*VMECHIP2_LBTVCR >> 16) & 0xfff0;
    if ((vme & 0x00f0) != 0xf0)
	{
	printf("  A16:\t    0x%4.4X -     0x%4.4X  =>       Global Ctrl Status
Regs\n",
		vme, vme + 0x000f);
	}
    else
	printf("  A16:\t           -             =>                  -\n");

    return OK;
    }


#define MEM_PART_OVERHEAD 64
LOCAL PART_ID a24MemPartId;		/* VME A24 memory partition */

/*******************************************************************************
*
* sysA24MapRam - reserve memory for A24 DMA use
*
* Some VME Bus Master cards are not able to generate extended VME (A32) 
* addresses, thus the CPU board must export some of its memory in the
* standard (A24) address space.  This routine allows application software
* to specify a minimum size of memory to be reserved for use with such
* devices.  If successful, memory is subsequently obtained from the memory
* partition by calling sysA24Malloc() and returned with sysA24Free().
*
* If this routine is not called, the first use of sysA24Malloc() will
* cause a default minimum size of partition to be created, currently set
* to 64 Kbytes.  Requests are clipped to 8Mbytes to ensure that there will
* always be room in the A24 address space for I/O cards.
*
* RETURNS: OK, or ERROR if the partition has already been created or
* insufficient free memory is available to fulfil the request.
*
* SEE ALSO: sysA24Malloc(), sysA24Free()
*/

STATUS sysA24MapRam
    (
    unsigned long size		/* Minimum partition size */
    )
    {
    int mask;
    int bsize;
    char *mem;
    
    if (sysProcNumGet() != 0)
	return ERROR;
    if (a24MemPartId != NULL)
	return ERROR;
    
    if (size > 0x800000)
	{
	size  = 0x800000;
	bsize = size;
	mask  = 0xff80;
	}
    else if (size < 0x010000)
	{
	size  = 0x10000;
	bsize = size;
	mask  = 0xffff;
	}
    else
	{
	/* Work out the correct window size and mask */
	bsize = 0x400000;
	mask  = 0xffffc0;
	while (bsize > size)
	    {
	    bsize >>= 1;
	    mask  >>= 1;
	    }
	if (bsize != size)
	    {
	    bsize <<= 1;
	    mask  <<= 1;
	    }
	mask &= 0xffff;
	}
    
    /* Check alignment against A24 base address */
    if ((LOCAL_MEM_BUS_A24 >> 16) & ~mask)
	return ERROR;
    
    /* Create the memory pool aligned on a bsize boundary */
    mem = memalign(bsize, size); /* cacheDmaMalloc??? */
    if (mem == NULL) return ERROR;
    a24MemPartId = memPartCreate(mem, size);
    if (a24MemPartId == NULL)
	{
	free(mem);
	return ERROR;
	}
    
    *VMECHIP2_VSAR2   = (LOCAL_MEM_BUS_A24 >> 16) |
			((LOCAL_MEM_BUS_A24 + bsize - 1) & 0xffff0000);
    *VMECHIP2_VSATR2  = (int)mem | mask;
    *VMECHIP2_VSAMSR |= (VSAMSR2_SNP_WSD |
			 VSAMSR2_WP	|
			 VSAMSR2_SUP	|
			 VSAMSR2_USR	|
			 VSAMSR2_A24	|
			 VSAMSR2_D64	|
			 VSAMSR2_BLK	|
			 VSAMSR2_PGM	|
			 VSAMSR2_DAT);	/* all but A32 */
    return OK;
    }


/*******************************************************************************
*
* sysA24Malloc - allocate a memory block from the A24 partition
*
* This routine allocates a block of memory for use by VME devices that
* can only perform DMA in the standard (A24) address space. The size of
* the block will be equal to or greater than nBytes.  If the A24 memory
* partition has not already been created with sysA24MapRam() it will be
* allocated now if possible.
* 
* RETURNS: A pointer to the allocated block, or NULL if the buffer could
* not be allocated.
*
* SEE ALSO: sysA24MapRam(), sysA24Free()
*/

void *sysA24Malloc
    (
    unsigned nBytes	/* number of bytes to allocate */
    )
    {
    if (a24MemPartId == NULL)
	if (sysA24MapRam(nBytes + MEM_PART_OVERHEAD) != OK)
	    return NULL;
    
    return memPartAlloc(a24MemPartId, nBytes);
    }


/*******************************************************************************
*
* sysA24Free - free a block of memory from the A24 partition
*
* This routine returns to the A24 partition a block of memory that was
* previously allocated with sysA24Malloc().
*
* RETURNS: OK, or ERROR if the block is invalid.
*
* SEE ALSO: sysA24MapRam(), sysA24Malloc()
*/

STATUS sysA24Free
    (
    char *pBlock	/* pointer to block of memory to free */
    )
    {
    if (a24MemPartId == NULL)
	return ERROR;
    
    return memPartFree(a24MemPartId, pBlock);
    }


/*******************************************************************************
*
* sysA24MemShow - report status of the A24 memory partition
*
* This routine calls memPartShow for the A24 memory partition
*
* RETURNS: N/A
*
* SEE ALSO: sysA24MapRam(), sysA24Malloc(), sysA24Free()
*/

void sysA24MemShow(void)
    {
	if (a24MemPartId)
	    {
	    memPartShow(a24MemPartId, 0);
	    }
	else
	    puts("\nNo A24 memory currently reserved");
    }


References:
mv162lx and NI-1014 Geoff Savage

Navigate by Date:
Prev: mv162lx and NI-1014 Geoff Savage
Next: RE: CA gateway compile on Linux Hammonds, John
Index: 1994  1995  1996  1997  1998  1999  <20002001  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: mv162lx and NI-1014 Geoff Savage
Next: MEDM widgets Pierre MATTEI
Index: 1994  1995  1996  1997  1998  1999  <20002001  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 ·