这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 访问PCI MEMORY SPACE的问题!

共6条 1/1 1 跳转至

访问PCI MEMORY SPACE的问题!

菜鸟
2003-05-06 17:18:04     打赏
近日在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     问题    

菜鸟
2003-05-06 20:55:00     打赏
2楼
直接当内存来访问会导致: Page Fault. 所以我估计是MMU在作怪.郁闷.......

菜鸟
2003-05-06 20:59:00     打赏
3楼
[quote][b]以下是引用[i]wl在2003-5-6 12:56:28[/i]的发言:[/b] 无内容!!! [/quote] 恕我愚钝, 兄台能否明示之??

菜鸟
2003-05-06 21:35:00     打赏
4楼
[quote][b]以下是引用[i]wl在2003-5-6 13:14:44[/i]的发言:[/b] 给你短消息了,你可以查看 这个论坛也真是的,有了标题回复还必须有内容,受不了! [/quote] 看PCI规范? 晕! 不过还是感谢你. 呵呵

菜鸟
2003-05-07 01:08:00     打赏
5楼
sysMmuMapAdd我也用了. 还是不行, 研究中.....

菜鸟
2003-05-07 22:14:00     打赏
6楼
谢谢楼上诸位的大力帮助, 问题现在基本解决了: 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 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]