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
<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:
mv162lx and NI-1014 Geoff Savage
- Next:
MEDM widgets Pierre MATTEI
- Index:
1994
1995
1996
1997
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
|