这是我的第一篇文章 :) 我正在使用 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);
}
谢谢您的帮助 !!