共6条
1/1 1 跳转至页
访问PCI MEMORY SPACE的问题!

近日在x86上作PCI设备的开发,遇到一些问题, 急需各位xdjm帮助: 我用pciFindDevice()找到了该设备, 并用pciConfigInLong()读出了它向系统申请的3个MEMORY SPACE BASE ADDRESS, 现在我需要通过第一个MEMORY SPACE 读写PCI设备上的寄存器, 我以前用的PCI卡都是申请的I/O空间, 用sysInWord()和sysOutWord()就可以了, 但这次再用这两个就不行了, sysInword()老是返回0xffff!
该怎样访问PCI MEMORY空间呢??? 会不会是因为MMU的原因造成的? 我的代码如下:
-------------------------------------------------------------------------------------------------------------------
#define PCI_VENDOR_ID_VWEB 0x16F4
#define PCI_DEVICE_ID_VWEB_2010 0x8000
#define PCI_BASE_ADDR0_OFFSET 0x10
#define PCI_INT_LINE 0x3c
#define RD_VW_REG 0x05
#define WR_VW_REG 0x06
#define REG_MEM1 0xD7
#define NUM_MAX_CHANNELS 1
static inline unsigned int HIUCTLCODE (unsigned short a, unsigned short b)
{
return ( ((unsigned int) (( a << 11 | b) & 0x1F9FF)) << 1 );
}
struct pci_dev
{
unsigned int base_address[6];
unsigned char irqNo;
}mpegHandle[NUM_MAX_CHANNELS];
void initTest(void)
{
int busNo=0;
int deviceNo=0;
int funcNo=0;
struct pci_dev *dev;
int i, index;
unsigned short status;
UINT8 irqNum=0;
char offset=0;
unsigned long int HIUCMD;
for ( index = 0; index< NUM_MAX_CHANNELS; index++ )
{
if(pciFindDevice(PCI_VENDOR_ID_VWEB, PCI_DEVICE_ID_VWEB_2010, index, &busNo, &deviceNo, &funcNo) != OK)
{
return;
}
for(i=0; i<6; i++)
{
if(pciConfigInLong(busNo,deviceNo, funcNo, PCI_BASE_ADDR0_OFFSET+4*i, &(mpegHandle[index].base_address[i])) != OK)
{
printf("can't get base addressd \n", i);
continue;
}
}
if(pciConfigInByte(busNo,deviceNo, funcNo, PCI_INT_LINE, &mpegHandle[index].irqNo) != OK)
{
printf("can't read irq_no \n");
continue;
}
}
HIUCMD = HIUCTLCODE(WR_VW_REG, REG_MEM1); //Now test vweb2010 register write and read .
sysOutWord((mpegHandle[0]->base_address[0] + HIUCMD), 0x0c00); // write 0x0c00 to REG_MEM1.
taskDelay(1);
HIUCMD = HIUCTLCODE(RD_VW_REG, REG_MEM1); //read from REG_MEM1...
status = 0;
status = sysInWord((mpegHandle[0]->base_address[0] + HIUCMD)); // here, status value is 0xffff, not 0x0c00!!! why?
-------------------------------------------------------------------------------------------------------------------
先谢了!!!
[align=right][color=#000066][此贴子已经被作者于2003-5-6 9:19:20编辑过][/color][/align]
关键词: 访问 MEMORY SPACE 问题

谢谢楼上诸位的大力帮助, 问题现在基本解决了: sysMmuMapAdd()只能在sysLib.c中调用, 在运用程序中调用不起作用. 原因好象是系统起来之前必须分配好MEMORY空间. 然后就可以直接用指针来操作PCI MEMORY空间了.
修改方法: 在sysHwInit()的最后加入类似于如下的代码就可以了(基于pc486):
---------------------------------------------------------------------------------------------------------------------
#define DBG(fmt, args...) printf(fmt, ## args)
#define VENDOR_ID 0x16F4
#define DEVICE_ID 0x8000
#define PCI_DEV_MMU_MSK (~(VM_PAGE_SIZE - 1)) /* Mask MMU page */
int initwebvideo()
{
int i, j, bus, dev, func, baseaddr, mask, type, ret, cmd;
int offset = 0x6154;
if (pciFindDevice(VENDOR_ID, DEVICE_ID, 0, &bus, &dev, &func) == -1)
{
DBG("cannot find device\n");
break;
}
DBG("bus=%x dev=%x func=%x\n", bus, dev, func);
ret = 0;
pciConfigInWord(bus, dev, func, PCI_CFG_VENDOR_ID, (short unsigned int *)&ret);
DBG("VendorID=%x\n", ret);
ret = 0;
pciConfigInWord(bus, dev, func, PCI_CFG_DEVICE_ID, (short unsigned int *)&ret);
DBG("DeviceID=%x\n", ret);
for (j = PCI_CFG_BASE_ADDRESS_0; j < PCI_CFG_BASE_ADDRESS_5; j += 4)
{
pciConfigInLong (bus, dev, func, j, &baseaddr);
pciConfigOutLong(bus, dev, func, j, ~0);
pciConfigInLong (bus, dev, func, j, &mask);
pciConfigOutLong(bus, dev, func, j, baseaddr);
if (mask == 0)
break;
if (mask & 0x01)
{
/* io */
baseaddr &= (~0x03UL);
mask &= (~0x03UL);
type = 1;
}
else
{
/* mem */
mask &= PCI_MEMBASE_MASK;
mask = ~mask + 1;
type = 0;
baseaddr &= PCI_MEMBASE_MASK;
}
cmd = 0;
pciConfigInWord(bus, dev, func, PCI_CFG_COMMAND, (short unsigned int *)&cmd);
DBG("%s======>baseaddress=%x range=%x cmd=%x\n",
type == 1 ? "[IO]" : "[Mem]",
baseaddr, mask, cmd);
ret = sysMmuMapAdd((void *)(baseaddr & PCI_DEV_MMU_MSK),
(void *)mask,
VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE,
VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE_NOT);
DBG("Mmn return=%d\n", ret);
pciConfigOutWord(bus, dev, func, PCI_CFG_COMMAND, PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE);
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------
[align=right][color=#000066][此贴子已经被作者于2003-5-7 14:17:27编辑过][/color][/align]
共6条
1/1 1 跳转至页
回复
打赏帖 | |
---|---|
【STM32F769】AI之与本地deepseek对接被打赏50分 | |
Buck电路工作在CCM模式下电感电流的计算公式是什么?被打赏5分 | |
buck电路工作原理被打赏5分 | |
基于MSPM0L1306的MODBUS-RTU协议通讯实验被打赏100分 | |
我想要一部加热台+多合一调试工具被打赏18分 | |
每周了解几个硬件知识+485硬件知识分享被打赏10分 | |
【换取手持数字示波器】树莓派PICO调试器官方固件本地化部署实践被打赏24分 | |
【换取手持数字示波器】分享一个KEIL无法识别CMSIS-DAP调试器的解决办法被打赏20分 | |
【换取手持数字示波器】分享一个自制的ArduinoNano扩展板底板被打赏23分 | |
【换取手持示波器】树莓派PICOW网页烟花被打赏18分 |