这是我的第一篇文章:)我正在使用VxWorks 6.9和Intel Sandy Bridge主板。我想知道如何在我的应用程序中映射PCIe内存区域。 PCIe存储区是图形存储器的一部分,它的物理地址是0x80000000。
我正在尝试使用不返回虚拟地址的vmMap函数。在这种情况下,我将虚拟地址设置为与物理地址相同的值,但我不知道它是否是良好的行为。 如何从物理地址获取虚拟地址?如果不存在任何功能,我必须使用什么虚拟地址?
当我在我的应用程序中映射该区域时,我正在访问该区域。 我正在尝试使用函数vmStateSet更改缓存状态,但只能设置COPYBACK,WRITETHRU和DEFAULT(设置其他缓存值失败)。 我的所有缓存状态的吞吐量都很低。在Intel Sandybridge中,可以将MMU设置为写入组合。我怎么能在VxWorks中做到这一点?
这是我到目前为止所尝试的:
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);
}
感谢您的帮助!!