what is "preMem" in the output of pciConfigTopoShow() in VxWorks? - vxworks

What are 'mem' and 'preMem' in the output of pciConfigTopoShow(), for P2P BRIDGE's?
Here's the output of my target...
[1,0,0] type=P2P BRIDGE to [2,0,0]
base/limit:
mem= 0xa0000000/0x9fffffff
preMem=0x0000000080000000/0x00000000800fffff
I/O= 0xe8000000/0xe7ffffff
status=0x0010 ( CAP DEVSEL=0 )
command=0x0007 ( IO_ENABLE MEM_ENABLE MASTER_ENABLE )
[2,1,0] type=P2P BRIDGE to [3,0,0]
base/limit:
mem= 0xa0000000/0x9fffffff
preMem=0x0000000080000000/0x00000000800fffff
I/O= 0xe8000000/0xe7ffffff
status=0x0010 ( CAP DEVSEL=0 )
command=0x0007 ( IO_ENABLE MEM_ENABLE MASTER_ENABLE )
[3,0,0] type=P2P BRIDGE to [4,0,0]
base/limit:
mem= 0xa0000000/0x9fffffff
preMem=0x80100000/0x800fffff
I/O= 0x0000/0xffff
status=0x0010 ( CAP DEVSEL=0 )
command=0x0007 ( IO_ENABLE MEM_ENABLE MASTER_ENABLE )
bar0 in prefetchable 64-bit mem space # 0x80000000

The “mem” and preMem” values are produced from the pciConfigTopoShow() function by several layers of function calls. The “mem” is for the normal memory window that be mapped for the Bridge showing the memory base and the memory limit respectively, separated by “/”.
The “preMem” is for the pre-fetch-able Memory window if the device supports it, showing the memory base and memory limit for this device. If it is a 64-bit machine, then these values are shown as 64-bit quantities .
Ultimately, the pciConfigForeachShow() function found in the file WIND_BASE/target/src/drv/pci/pciConfigShow.c produces the output that shown with your question in the following code snippet:
if ( cmdReg & PCI_CMD_MEM_ENABLE )
{
pciConfigInWord(bus,device,function,
PCI_CFG_MEM_BASE, &memBase);
pciConfigInWord(bus,device,function,
PCI_CFG_MEM_LIMIT, &memLimit);
printf("\tbase/limit:\n");
printf("\t mem= 0x%04x0000/0x%04xffff\n",
memBase & 0xfff0, memLimit | 0x000f);
pciConfigInWord(bus,device,function,
PCI_CFG_PRE_MEM_BASE, &memBase);
pciConfigInWord(bus,device,function,
PCI_CFG_PRE_MEM_LIMIT, &memLimit);
if ( ( memBase & 0x000f ) == 0x0001 )
{
/* 64-bit memory */
pciConfigInLong(bus,device,function,
PCI_CFG_PRE_MEM_BASE_U,
&memBaseU);
pciConfigInLong(bus,device,function,
PCI_CFG_PRE_MEM_LIMIT_U,
&memLimitU);
printf("\t preMem=0x%08x%04x0000/"
"0x%08x%04xffff\n",
memBaseU, memBase & 0xfff0,
memLimitU, memLimit | 0x000f);
}
else
printf("\t preMem=0x%04x0000/0x%04xffff\n",
memBase & 0xfff0, memLimit | 0x000f);
}

Related

VxWorks change console port while running

Is there any way to change the console port on an iMX6 running VxWorks 7 while running? I know how to change it via kernel configuration, but that is a compile time setting. Is there any way I can change it while running?
The ioLib documentation explains how to redirect the stdio file descriptors at run-time either globally or on a per task basis, using ioGlobalStdSet() or ioTaskStdSet() respectively. You can set stdin, stout, and stderr independently, so you will need to set all three to redirect all console I/O.
So for example:
#include <ioLib.h>
int redirectStdio( const char* devname )
{
int new_io_fd = open( devname, O_RDWR, 0 ) ;
if( new_io_fd >= 0 )
{
ioGlobalStdSet( STD_IN, new_io_fd ) ;
ioGlobalStdSet( STD_OUT, new_io_fd ) ;
ioGlobalStdSet( STD_ERR, new_io_fd ) ;
}
return new_io_fd ;
}
Then you might have:
if( redirectStdio( "/tyCo/2" ) < 0 )
{
printf( "Redirect failed - still here!\n" ) ;
}
else
{
printf( "stdio now directs here\n" ) ;
}
There are also ioGlobalStdGet() and ioTaskStdGet() functions so it is possible to retain the original settings and restore them if necessary for example.

parameters for use_device() openACC

Is it allowed to pass objects instead of a pointer to the following directive
pragma acc host_data use_device(myobject)
here is the code , Pn is the object and Pn.P is the pointer to the array where data is stored
#pragma acc data pcopyin( rank,N )
{
#pragma acc host_data use_device( Pn )
{
cufftPlan1d( &plan, 1000 , CUFFT_Z2Z, 1 );
cufftExecZ2Z( plan, (cufftDoubleComplex*)Pn.P, (cufftDoubleComplex *)Pn.P, CUFFT_FORWARD );
}
}
runing gives Seg Fault
Try "host_data use_device( Pn.P )" so that "P"'s device address is used.
When you pass "Pn.P" as an argument, you're accessing "Pn" on the host to get the address of "P". Hence by putting "Pn" in the host_data region, the code is using the device address which in turn causes the segv.
using version PGI 18.1 solves this issue

programatic way to find ELF aux header (or envp) in shared library code?

I'm looking for a programatic way to find the powerpc cpu type on Linux. Performing some google searches associated an answer suggesting the mfpvr instruction I found that this is available in the ELF AUX header, and sure enough I can obtain the POWER5 string for the machine I'm running on with the following:
#include <stdio.h>
#include <elf.h>
int main( int argc, char **argv, char **envp )
{
/* walk past all env pointers */
while ( *envp++ != NULL )
;
/* and find ELF auxiliary vectors (if this was an ELF binary) */
#if 0
Elf32_auxv_t * auxv = (Elf32_auxv_t *) envp ;
#else
Elf64_auxv_t * auxv = (Elf64_auxv_t *) envp ;
#endif
char * platform = NULL ;
for ( ; auxv->a_type != AT_NULL ; auxv++ )
{
if ( auxv->a_type == AT_PLATFORM )
{
platform = (char *)auxv->a_un.a_val ;
break;
}
}
if ( platform )
{
printf( "%s\n", platform ) ;
}
return 0 ;
}
In the shared library context where I want to use this info I have no access to envp. Is there an alternate programatic method to find the beginning of the ELF AUX header?
You can get if from /proc/self/auxv file
According to man proc /proc/self/auxv is available since kernel level 2.6.0-test7.
Another option - get some (existing) environment variable - let say HOME,
or PATH, or whatever. Please note that you'll get it's ADDRESS. From here you can go back and find previous env variable, then one before it, etc. After that you can likewise skip all argv arguments. And then you get to the last AUXV entry. Some steps back - and you should be able find your AT_PLATFORM.
EDIT: It looks like glibc now provides a programatic method to get at this info:
glibc-headers-2.17-106: /usr/include/sys/auxv.h : getauxinfo()
Example:
#include <sys/auxv.h>
#include <stdio.h>
int main()
{
unsigned long v = getauxval( AT_PLATFORM ) ;
printf( "%s\n", (char *)v ) ;
return 0 ;
}

How does one read/write memory on a PCI device in VxWorks 653?

I'm using VxWorks 653, and my target is the wrSbc7457 Power PC.
I have a mezzanine card on my wrSbc7457, and I'm trying to write/read the memory on that mezzanine card.
For those of you familiar with VxWorks, I have the following in the usrAppInit() function of my ModuleOS:
printf ( "Entering ModuleOS, usrAppInit() ...\n" ) ;
printf ( "sysModel() returns %s\n", sysModel() ) ;
pciDeviceShow ( 0 ) ;
{
int pciBus, pciDevice, pciFunc ;
UINT32 BAR_0_contents, BAR_1_contents ;
printf
( "\npciFindDevice returns STATUS %d\n",
pciFindDevice ( my_VENDORID, my_PMC_DEVICEID, 0, &pciBus, &pciDevice, &pciFunc )
) ;
printf ( "\tand pciBus = %d, pciDevice = %d, pciFunc = %d\n", pciBus, pciDevice, pciFunc ) ;
printf ( "\npciConfigInLong returns STATUS %d\n",
pciConfigInLong ( pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_0, & BAR_0_contents ) ) ;
printf ( "\tand Base Address Register 0 contains 0x%X\n", BAR_0_contents ) ;
printf ( "\npciConfigInLong returns STATUS %d\n",
pciConfigInLong ( pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_1, & BAR_1_contents ) ) ;
printf ( "\tand Base Address Register 1 contains 0x%X\n", BAR_1_contents ) ;
My target outputs the following when the OS boot image is loaded:
Entering ModuleOS, usrAppInit() ...
sysModel() returns wrSbc7457 Power PC
Scanning function 0 of each PCI device on bus 0
Using configuration mechanism 0
bus device function vendorID deviceID class
00000000 00000000 00000000 0000---- 0000---- 000-----
00000000 00000001 00000000 0000---- 0000---- 00--0000
00000000 00000002 00000000 0000---- 0000---- 000-----
pciFindDevice returns STATUS 0 (OK)
and pciBus = 0, pciDevice = 1, pciFunc = 0
pciConfigInLong returns STATUS 0 (OK)
and Base Address Register 0 contains 0x50000000
pciConfigInLong returns STATUS 0 (OK)
and Base Address Register 1 contains 0x58000000
My question is: how do I map the memory of my mezzanine card into my host's address space, and then how do I write/read the memory on that mezzanine card?
Unfortunately, there is no universal answer. You have to program the PCI bridge.
Some of it depends if you use the PCI auto configuration or not.
You should look at the library references for pciConfig and/or pciAutoConfig.
Your device looks like it has two address spaces at 0x50000000 and 0x58000000, but I believe that's the PCI address space, not the host bridge mapping.

I have P & G-- how do I use the Wincrypt API to generate a Diffie-Hellman keypair?

There's an MSDN article here, but I'm not getting very far:
p = 139;
g = 5;
CRYPT_DATA_BLOB pblob;
pblob.cbData = sizeof( ULONG );
pblob.pbData = ( LPBYTE ) &p;
CRYPT_DATA_BLOB gblob;
gblob.cbData = sizeof( ULONG );
gblob.pbData = ( LPBYTE ) &g;
HCRYPTKEY hKey;
if ( ::CryptGenKey( m_hCryptoProvider, CALG_DH_SF,
CRYPT_PREGEN, &hKey ) )
{
::CryptSetKeyParam( hKey, KP_P, ( LPBYTE ) &pblob, 0 );
Fails here with NTE_BAD_DATA. I'm using MS_DEF_DSS_DH_PROV. What gives?
It may be that it just doesn't like the very short keys you're using.
I found the desktop version of that article which may help, as it has a full example.
EDIT:
The OP realised from the example that you have to tell CryptGenKey how long the keys are, which you do by setting the top 16-bits of the flags to the number of bits you want to use. If you leave this as 0, you get the default key length. This is documented in the Remarks section of the device documentation, and with the dwFlags parameter in the desktop documentation.
For the Diffie-Hellman key-exchange algorithm, the Base provider defaults to 512-bit keys and the Enhanced provider (which is the default) defaults to 1024-bit keys, on Windows XP and later. There doesn't seem to be any documentation for the default lengths on CE.
The code should therefore be:
BYTE p[64] = { 139 }; // little-endian, all other bytes set to 0
BYTE g[64] = { 5 };
CRYPT_DATA_BLOB pblob;
pblob.cbData = sizeof( p);
pblob.pbData = p;
CRYPT_DATA_BLOB gblob;
gblob.cbData = sizeof( g );
gblob.pbData = g;
HCRYPTKEY hKey;
if ( ::CryptGenKey( m_hCryptoProvider, CALG_DH_SF,
( 512 << 16 ) | CRYPT_PREGEN, &hKey ) )
{
::CryptSetKeyParam( hKey, KP_P, ( LPBYTE ) &pblob, 0 );
It looks to me that KP_P, KP_G, KP_Q are for DSS keys (Digital Signature Standard?). For Diffie-Hellman it looks like you're supposed to use KP_PUB_PARAMS and pass a DATA_BLOB that points to a DHPUBKEY_VER3 structure.
Note that the article you're pointing to is from the Windows Mobile/Windows CE SDK. It wouldn't be the first time that CE worked differently from the desktop/server.
EDIT: CE does not implement KP_PUB_PARAMS. To use this structure on the desktop, see Diffie-Hellman Version 3 Public Key BLOBs.