This is my first post :) I am using VxWorks 6.9 and an Intel Sandy Bridge board. I would like to know how to map a PCIe memory area in my application. The PCIe memory area is a part of the Graphic memory and it's physical address is 0x80000000.
I’m trying with the vmMap function which doesn’t return the virtual address. In that case, I set the virtual address with the same value than the physical address but I don’t know if it’s the good behavior. How can I get the virtual address from the physical address? If no function exists, what’s virtual address I have to use?
When I’ve mapped the area in my application, I’m benching the access to this area. I’m trying to change the cache state with the function vmStateSet but only COPYBACK, WRITETHRU and DEFAULT can be set (setting other cache values fail). I’ve got a low throughput for all cache states. In Intel Sandybridge, it is possible to set the MMU to write combining. How can I do it in VxWorks?
This is what I have tried so far:
int test_appli_pci (void) {
struct timeval start, end;
uint64_t time_us = 0;
VIRT_ADDR buffer_virt_dest = ADDR_PHYS_GRAPHIC_PCI;
void* buffer_virt_src = NULL;
int i;
int j;
UINT state;
UINT states[] = {MMU_ATTR_CACHE_OFF, MMU_ATTR_CACHE_COPYBACK, MMU_ATTR_CACHE_WRITETHRU, MMU_ATTR_CACHE_DEFAULT, MMU_ATTR_CACHE_GUARDED, MMU_ATTR_CACHE_COHERENCY};
/* Mapping on physical address */
if(vmMap(NULL, ADDR_PHYS_GRAPHIC_PCI, ADDR_PHYS_GRAPHIC_PCI, MWTEST_BUFFER_SIZE) == ERROR) {
return -1;
}
/* Allocate buffer */
buffer_virt_src = (uint8_t*)malloc(MWTEST_BUFFER_SIZE);
/* bench depending on cache state */
for(i = 0; i < NELEMENTS(states); i++) {
if(vmStateSet(NULL, ADDR_PHYS_GRAPHIC_PCI, MWTEST_BUFFER_SIZE, MMU_ATTR_CACHE_MSK, states[i]) == ERROR) {
printf("set state %d error\n", i);
continue;
}
vmStateGet(NULL, buffer_virt_dest, &state);
printf("state: %x\n", state);
/* memcpy */
gettimeofday(&start, NULL);
for(j = 0; j < NB_LOOP; j++) {
memcpy((void*)buffer_virt_dest, buffer_virt_src, MWTEST_BUFFER_SIZE);
}
gettimeofday(&end, NULL);
time_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
printf("mean transfer time:%lld us, throughput:%lld MB/s\n", time_us / NB_LOOP, (MWTEST_BUFFER_SIZE * 1000000ull * NB_LOOP) / (1024 * 1024) / time_us);
}
/* free buffer */
free(buffer_virt_src);
return (0);
}
Thank you for your help !!