搜索
bottom↓
回复: 8

PCI地址映射的疑问(欢迎熟悉的DX进来指教)

[复制链接]

出0入0汤圆

发表于 2009-12-17 15:25:49 | 显示全部楼层 |阅读模式
对于地址映射我是这么理解的,不知道是不是正确?
--------------------------------------------------------------------------------------------------------------------------------------------
对于PCI来说地址分为两部分地址,一个是系统地址,这个地址是对驱动开发人员来说的。一个是本地存储地址,这个是对本地端用户来说的(例如FPGA控制9054,FPGA就是本地用户),对驱动开发人员来说只有系统地址可见,本地地址是不可见的,对于本地端用户来说,系统地址是不可见的,他只管本地地址,这中间就存在一个映射的问题,或者还有操作系统按资源分配的问题??
对于这些映射9054有三个寄存器来完成,分别是系统配置寄存器BAR,本地配置寄存器LASxRR,LASxBA,(为了方便说明,用BAR2,LAS0RR,LAS0BA)。
LAS0RR是本地端地址的范围,里面的值是地址范围取反加一,最低4位(对于memory),或者最低2位(对于IO)是固定属性,这个由系统分配(BIOS),只能读不能写。
LAS0BA的值是LASORR的倍数,如果LAS0RR是1M的地址范围,那么LAS0BA就是0M,1M,2M,3M等等
BAR2是系统地址的偏移地址

在应用程序开发操作硬件的时候,开发人员通过BAR2+offset对9054进行操作,这个地址可以找到PCI9054芯片的内部,然后,PCI9054芯片再把这个PCI地址进行重映射到Local端的内存空间地址,这一步根据LAS0RR寄存器的设置,然后把Local端基址寄存器的高位替换即所谓的重映射。
例如对1M大小的memory进行操作,BAR2里设置的值是7890 0000,那么对于开发人员来说他所知道的地址是0x7890 0000h + offset,9054会根据LAS0RR的值把高12位替换掉,LAS0RR里有多少个1就替换多少位。假设LAS0BA的值为FFE0 0000那么对于本地端用户能看见的地址就是FFE0 0000 + offset
从7890 0000 + offset -------- FFE0 0000 + offset就完成了映射
------------------------------------------------------------------------------------------------------------------------------------------
不知道是不是这样映射的?欢迎各位指教,另外还有一个问题

PCI可以映射本地两个空间,space0,space1,当这两个空间都要用到时,本地端地址总线上改怎么译码呢?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2009-12-17 16:54:46 | 显示全部楼层
桥片技术实际就是REMAP技术&开窗技术
CPU 地址 <=> PCI 地址 <=> LOCAL 地址
在一般系统里 CPU 地址 等于 PCI 地址
你可参考我若干年前做的,早忘了具体定义,得自己芯片看PDF.


-> sysPciShow with PMC
0 0 ID 0x00041057 Motorola, Rev. 1.3
0 5 ID 0x826010e3 Tundra Semiconductor Corp., Rev. 0.1
0 6 ID 0x00061000 SYM 53C860 Ultra SCSI/Narrow, Rev. 0.2
0 8 ID 0x000010e3 Tundra CA91C042 VMEbus Bridge, Rev. 0.2
0 9 0 ID 0x056510ad Symphony W83C553F ISA bridge, Rev. 1.0
0 9 1 ID 0x010510ad Symphony W83C553F IDE controller, Rev. 0.5
0 11 ID 0x00191011 DEC DC21143 PCI/CardBus 10/100 Mbit Ethernet Ctlr, Rev. 4.1
0 14 ID 0x965610b5 PLX Technology, Rev. b.a
value = 0 = 0x0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-> k0
--------------------------------
sysClkRateGet = 60 , sysAuxClkRateGet = 60
--------------------------------
PLX 9656 PCI card found!
busNo    = 0x00000000
deviceNo = 0x0000000e
funcNo   = 0x00000000
pDp      = 0x01aa17c0
--------------------------------
base address 0 =         PCI(0x80110000) CPU(0x80110000)
base address 1 =         PCI(0x04000001) CPU(0xf4000000)
base address 2 =         PCI(0x80100000) CPU(0x80100000)
base address 3 =         PCI(0x80000000) CPU(0x80000000)
base address 4 =         PCI(0x00000000) CPU(0x00000000)
base address 5 =         PCI(0x00000000) CPU(0x00000000)
interrupt line =         0x09
interrupt pin =          0x01
--------------------------------
PCI Local configuration
--------------------------------
P9656_BIGEND  = 0x00300500
P9656_CNTRL   = 0x100d767e
P9656_INTCSR  = 0x0f0c0800
P9656_LBRD0   = 0x4a03014f
P9656_LBRD1   = 0x000001c3
P9656_MARBR   = 0x012300ff
P9656_DMAARB  = 0x012300ff
value = 0 = 0x0
-> pmce2read(&pD)
--------------------------------
Access serial EERPOM
--------------------------------
00: 965610b5  ff0000ba  80400109  00000000  
10: 00000000  ffff0000  00000001  012300ff  
20: 00300500  00000000  00000000  4a03014f  
30: 00000000  00000000  00000000  00000000  
40: 00000000  965610b5  fff00000  00100001  
50: 000001c3  00004c06  00000000  00024801  
60: 00000000  00000000  00000000  00000000  
70: 00000000  00000000  00000000  00000000  
80: 00000000  00000000  00000000  00000000  
90: 00000000  00000000  00000000  00000000  
a0: 00000000  00000000  00000000  00000000  
b0: 00000000  00000000  00000000  00000000  
c0: 00000000  00000000  00000000  00000000  
d0: 00000000  00000000  00000000  00000000  
e0: 00000000  00000000  00000000  00000000  
f0: 00000000  00000000  00000000  00000000  
value = 0 = 0x0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-> speedit
--------------------------------
sysClkRateGet = 60 , sysAuxClkRateGet = 60
--------------------------------
PLX 9656 PCI card found!
busNo    = 0x00000000
deviceNo = 0x0000000e
funcNo   = 0x00000000
pDp      = 0x01aa17c0
--------------------------------
base address 0 =         PCI(0x80110000) CPU(0x80110000)
base address 1 =         PCI(0x04000001) CPU(0xf4000000)
base address 2 =         PCI(0x80100000) CPU(0x80100000)
base address 3 =         PCI(0x80000000) CPU(0x80000000)
base address 4 =         PCI(0x00000000) CPU(0x00000000)
base address 5 =         PCI(0x00000000) CPU(0x00000000)
interrupt line =         0x09
interrupt pin =          0x01
--------------------------------
PCI Local configuration
--------------------------------
P9656_BIGEND  = 0x00300500
P9656_CNTRL   = 0x100d767e
P9656_INTCSR  = 0x0f0c0980
P9656_LBRD0   = 0x4a03014f
P9656_LBRD1   = 0x000001c3
P9656_MARBR   = 0x012300ff
P9656_DMAARB  = 0x012300ff
--------------------------------

--------------------------------
PMC DMA1 speed test
--------------------------------
writebuf:0x002d6d50(PCI 0x402d6d50) offset:0-0xffff
readbuf :0x002e6fc0(PCI 0x402e6fc0) offset:0-0xffff
900.0ms 65536.0KB 72.818MB/s for DMA Write Block
433.3ms 65536.0KB 151.237MB/s for DMA Read Block
--------------------------------
PMC DMA0 speed test
--------------------------------
writebuf:0x002d6d50(PCI 0x402d6d50) offset:0-0xffff
readbuf :0x002e6fc0(PCI 0x402e6fc0) offset:0-0xffff
900.0ms 65536.0KB 72.818MB/s for DMA Write Block
450.0ms 65536.0KB 145.635MB/s for DMA Read Block
value = 49 = 0x31 = '1'






翻出老掉压的FPGA程序,可以看出PLX9656的PCI和LOCAL对应地址关系(PLX9054是PLX9656的简化版)

--PCI PCIBAR2~PCIBAR2+0x0000ffff <=> Local 0x00000000~0x0000ffff        64KBytes
--LAS0RR=0xffff0000
--LAS0BA=0x00000001
--
--ADDR[31..28] ADDR[27..24] ADDR[23..20]
--ADDR[31..20]=H"000" decode BAR2
CONSTANT         BAR2_                                = H"000";
--ADDR[19..16] must = H"0" , ADDR[15..12]
CONSTANT         BAR2_H0                                = H"00";                --decode for FPGA's inner reg
CONSTANT         BAR2_H1                                = H"01";                --decode for Z16C30 reg
--BAR2_H0 & ADDR[11..2]                                                        --ADDR[11..0]
CONSTANT         LED_CNTR_OFFSET                = H"000";                --H"000"        D[13..0]                 W/R , default bit ERRFLAG_OKFLAG_HPSEL[3..0]_LEDSEL[3..0]_LED3_LED2_LED1_LED0 is 00_0000_0000_0000
CONSTANT         CH1_DIR_OFFSET                = H"001";                --H"004"        D[5..0]                  W/R , default bit DCD_CTS_TXD_TXC_RXD_RXC is 001100 ("0" RS422 in;"1" RS422 out)
CONSTANT         CH2_DIR_OFFSET                = H"002";                --H"008"        D[5..0]                  W/R , default bit DCD_CTS_TXD_TXC_RXD_RXC is 001100 ("0" RS422 in;"1" RS422 out)       
CONSTANT         SIMP_N_OFFSET                = H"003";                --H"00c"        D[15..0]                 W/R , default send 256 SIMP
CONSTANT         SIMP_TIME_OFFSET        = H"004";                --H"010"        D[15..0]                 W/R , default 5156*0.9697us=5ms SIMP
CONSTANT         INT_EN_OFFSET                = H"005";                --H"014"        D[7..0]                  W/R , default is 0
CONSTANT         INT_VECT_OFFSET                = H"006";                --H"018"        D[6..0]                  R   , read bit USC2RX_USC2TX_USC1RX_USC1TX_FPDPRM_FPDPTM_SIMP
CONSTANT         INT_CLR_OFFSET                = H"007";                --H"01c"        D[6..0]                  W   , write BITx="1" will clear INTx
--FPDP output clk(CLK20M->CLK20M1->SEL0CLK) delay selector
CONSTANT         FPDP_SEL0D_OFFSET        = H"008";                --H"020"        D[5..0]                  W/R , default bit CLK20MD5_CLK20MD4_CLK20MD3_CLK20MD2_CLK20MD1_CLK20M1 is 111110 ("0" SEL Enable;"1" SEL Disable)
--FPDP input clk(SEL2CLK->EXT20M->SEL1CLK)  delay selector
CONSTANT         FPDP_SEL1D_OFFSET        = H"009";                --H"024"        D[5..0]                  W/R , default bit EXT20MD5_EXT20MD4_EXT20MD3_EXT20MD2_EXT20MD1_EXT20M  is 111110 ("0" SEL Enable;"1" SEL Disable)
--FPDP input  , SEL2D[1..0] set SEL2CLK source , default bit PECLCLK_TTLCLK  is 10 ("0" SEL Enable;"1" SEL Disable)
--FPDP i/o    , SEL2D[3..2] set FPDPCLK source , default bit SEL1CLK_CLK20M2 is 01 ("0" SEL Enable;"1" SEL Disable)
----FPDP o          , OSC->CLK20M->CLK20M2->FPDPCLK->FPGA             , SEL2D[3..2]="10"
----FPDP i          , STROBE->SEL2CLK->EXT20M->SEL1CLK->FPDPCLK->FPGA , SEL2D[3..2]="01" , default
CONSTANT         FPDP_SEL2D_OFFSET        = H"00a";                --H"028"        D[3..0]  W/R , default is 0110
--FPDP output , SEL3D[0] set TTLCLK out  , default bit is 1 ("0" EN)
--FPDP output , SEL3D[1] set PECLCLK out , default bit is 1 ("0" EN)
--FPDP i/o    , SEL3D[4..2] set PECL termination method , default bit METHOD3_METHOD2_METHOD1 is 110 ("0" SEL Enable;"1" SEL Disable)
----term method 1 : 167/250 by FPDP/TM or FPDP/RM
----term method 2 : 330 by FPDP/TM
----term method 3 : 110 by FPDP/RM
CONSTANT         FPDP_SEL3D_OFFSET        = H"00b";                --H"02c"        D[4..0]                  W/R , default is 11011
--SEL4D[0] set FPDP/TM SUSPEND* term ("0" EN) , SUSPEND* asserted by FPDP/R or FPDP/RM
--SEL4D[1] set FPDP/TM NRDY*    term ("0" EN) , NRDY*    asserted by FPDP/R or FPDP/RM
--SEL4D[2] set FPDP/RM DIR*     term ("0" EN) , DIR*     asserted by FPDP/TM
--SEL4D[3] set FPDP/RM STROB    term ("0" EN) , STROB    asserted by FPDP/TM
----FPDP/RM , SEL4D[3..0] = "0011"
----FPDP/TM , SEL4D[3..0] = "1100"
CONSTANT         FPDP_SEL4D_OFFSET        = H"00c";                --H"030"        D[3..0]                  W/R , default is 0011
--FPDP_CNTR[1..0]        FPDP_MODE                        (W/R , default is 00 , mode0)
--                                        mode0 : FIFO loopback  , FPDP_CNTR[1..0] = "00"
--                                        mode1 : FPDP/RM input  , FPDP_CNTR[1..0] = "01"
--                                        mode2 : FPDP/TM output , FPDP_CNTR[1..0] = "10"
--FPDP_CNTR[2]                RM_NRDYn_OUT                (W/R , default is 0 , NRDY* output 0)
--FPDP_CNTR[3]                TM_SYNCn_OUT                (W          , default is 1 , SYNC* output no 0 pulse)
--FPDP_CNTR[4]                TM_SUSPENDn_EN                (W/R , default is 0 , FPDP/RM's SUSPEND* will not suspend FPDP/TM send)
--FPDP_CNTR[5]                TM_NRDYn_EN                        (W/R , default is 0 , FPDP/RM's NRDY*    will not suspend FPDP/TM send)
--FPDP_CNTR[6]                RM_SYNCn_EN                        (W/R , default is 0 , FPDP/TM's SYNC*    will not use as frame begin)
--FPDP_CNTR[7]                FPDP_FIFO_RST                (W/R , default is 1 , FPDP fifo will not aclr by reg)
--FPDP_CNTR[8]                FPDP_RST_DVEN                (W/R , default is 0 , FPDP fifo will not aclr after DVALIDn"1" 350us)
--
--FPDP_CNTR[9]                RM_DIRn_STATUS                (  R , FPDP/RM's DIR*           is input)
--FPDP_CNTR[10]                TM_SUSPENDn_STATUS        (  R , FPDP/TM's SUSPEND* is input)
--FPDP_CNTR[11]                TM_NRDYn_STATUS                (  R , FPDP/TM's NRDY*    is input)
CONSTANT         FPDP_CNTR_OFFSET        = H"00d";                --H"034"        D[11..0]                 W/R , default is XXX010001000 (D[11..9] R only)
--FPDP/RM FIFO HALF FULL
CONSTANT         FPDP_FIFOHF_OFFSET        = H"00e";                --H"038"        D[FPDP_N..0]        W/R
--FPDP/TM DMA SEND COUNT for fifo empty ok
CONSTANT         FPDP_SENDCT_OFFSET        = H"00f";                --H"03c"        D[FPDP_N..0]        W/R
--FPDP FIFO STATUS
CONSTANT         FPDP_FIFOS_OFFSET        = H"010";                --H"040"        D[7..0]                    R
--USC1_CNTR[0]                USC1_DMAW_EN                (W/R , default is 0 , USC1 fifo will not DMAW for TxREQn)
--USC1_CNTR[1]                USC1_DMAR_EN                (W/R , default is 0 , USC1 fifo will not DMAR for RxREQn)
--USC1_CNTR[6]                USC1_FIFORX_RST                (W/R , default is 1 , USC1 rxfifo will not aclr)
--USC1_CNTR[7]                USC1_FIFOTX_RST                (W/R , default is 1 , USC1 txfifo will not aclr)
CONSTANT         USC1_CNTR_OFFSET        = H"011";                --H"044"        D[7..0]                  W/R , default is 10000000
--USCRX1 FIFO HALF FULL
CONSTANT         USC1_FIFOHF_OFFSET        = H"012";                --H"048"        D[USC_N..0]         W/R
--USCTX1 DMA SEND COUNT for fifo empty ok
CONSTANT         USC1_SENDCT_OFFSET        = H"013";                --H"04c"        D[USC_N..0]         W/R
--USC1 FREQ DIV
CONSTANT         USC1_FREQ_OFFSET        = H"014";                --H"050"        D[3..0]                  W/R
--USC1 FIFO STATUS
CONSTANT         USC1_FIFOS_OFFSET        = H"015";                --H"054"        D[7..0]            R
--USC2_CNTR[0]                USC2_DMAW_EN                (W/R , default is 0 , USC2 fifo will not DMAW for TxREQn)
--USC2_CNTR[1]                USC2_DMAR_EN                (W/R , default is 0 , USC2 fifo will not DMAR for RxREQn)
--USC2_CNTR[6]                USC2_FIFORX_RST                (W/R , default is 1 , USC2 rxfifo will not aclr)
--USC2_CNTR[7]                USC2_FIFOTX_RST                (W/R , default is 1 , USC2 txfifo will not aclr)
CONSTANT         USC2_CNTR_OFFSET        = H"016";                --H"058"        D[7..0]                  W/R , default is 10000000
--USCRX2 FIFO HALF FULL
CONSTANT         USC2_FIFOHF_OFFSET        = H"017";                --H"05c"        D[USC_N..0]         W/R
--USCTX2 DMA SEND COUNT for fifo empty ok
CONSTANT         USC2_SENDCT_OFFSET        = H"018";                --H"060"        D[USC_N..0]                W/R
--USC2 FREQ DIV
CONSTANT         USC2_FREQ_OFFSET        = H"019";                --H"064"        D[3..0]                  W/R
--USC2 FIFO STATUS
CONSTANT         USC2_FIFOS_OFFSET        = H"01a";                --H"068"        D[7..0]                    R
--FPDP DV RST FIFO DELAY TIME
CONSTANT         FPDP_DVRST_OFFSET        = H"01b";                --H"06c"        D[15..0]            W/R


--BAR2_H1 & ADDR[11..2]
--Z16C30's AD[0] is U/Ln = 0
--Z16C30's AD[5..1] <=>  DLA[6..2]
--Z16C30's AD[6] is B/Wn = 0
--Z16C30's D/Cn     <=>  DLA[7]
--Z16C30's A/Bn     <=> !DLA[8]


--PCI PCIBAR3~PCIBAR3+0x000fffff <=> Local 0x00100000~0x001fffff        1024KBytes
--LAS1RR=0xfff00000
--LAS1BA=0x00100001
--
--ADDR[31..20]=H"001" decode BAR3
CONSTANT         BAR3_                                = H"001";
--ADDR[19..16]
CONSTANT         BAR3_H0                                = H"0";                --decode for FPDP's t/r FIFO (ADDR[15..2] space is 16K*32bit/64Kbytes)
CONSTANT         BAR3_H1                                = H"1";                --decode for USCx's t/r FIFO
--ADDR[15..14]
CONSTANT         BAR3_H1_H0                        = B"00";        --decode for USC1's t/r FIFO (ADDR[13..2] space is 4K*32bit/16Kbytes)
CONSTANT         BAR3_H1_H1                        = B"01";        --decode for USC2's t/r FIFO (ADDR[13..2] space is 4K*32bit/16Kbytes)
CONSTANT         BAR3_H1_H2                        = B"10";        --NC
CONSTANT         BAR3_H1_H3                        = B"11";        --NC

出0入0汤圆

发表于 2009-12-17 17:20:38 | 显示全部楼层
Access serial EERPOM
--------------------------------
00: 965610b5  ff0000ba  80400109  00000000   
10: 00000000  ffff0000  00000001  012300ff   
20: 00300500  00000000  00000000  4a03014f   
30: 00000000  00000000  00000000  00000000   
40: 00000000  965610b5  fff00000  00100001   
50: 000001c3  00004c06  00000000  00024801   

--PCI PCIBAR2~PCIBAR2+0x0000ffff <=> Local 0x00000000~0x0000ffff 64KBytes
--LAS0RR=0xffff0000
--LAS0BA=0x00000001

--PCI PCIBAR3~PCIBAR3+0x000fffff <=> Local 0x00100000~0x001fffff 1024KBytes
--LAS1RR=0xfff00000
--LAS1BA=0x00100001
--
看到这些你就应该明白了.至于PCI侧的地址,是OS自动配出来的

出0入0汤圆

 楼主| 发表于 2009-12-17 17:29:19 | 显示全部楼层
看您的EEPROM里的值
BAR0 00000000
BAR1 FFFF0000
BAR2 00000001
BAR3 012300FF
BAR4 00300500

BAR4不是保留寄存器,怎么还有值呢?

另外
--PCI PCIBAR2~PCIBAR2+0x0000ffff <=> Local 0x00000000~0x0000ffff 64KBytes  
--LAS0RR=0xffff0000  
--LAS0BA=0x00000001  

--PCI PCIBAR3~PCIBAR3+0x000fffff <=> Local 0x00100000~0x001fffff 1024KBytes  
--LAS1RR=0xfff00000  
--LAS1BA=0x00100001  

您LAS0BA,LAS1BA的最低为都设为1,那都map到I/O space了吧。

您的代码里是用[31:20]作为space0,space1空间的译码,本地端要知道LAS0BA,LAS1BA的值才能译码,但是本地端应该是不会去读这些寄存器的,那么怎么知道这些值呢?是不是开发之前就协商好了,LASOBA,BAS1BA设置什么样的值会告诉本地控制端?

非常感谢!

出0入0汤圆

 楼主| 发表于 2009-12-17 18:19:34 | 显示全部楼层
我看9656DMA的时序图,DMA操作时,写地址为0x128的寄存器DMACSRO,地址总线上的值是[31:2] 0x0800004a,那么BAR0的值是不是设置为0x08000000?

出0入0汤圆

发表于 2009-12-17 22:31:03 | 显示全部楼层
“本地端应该是不会去读这些寄存器的,那么怎么知道这些值呢?”

你应该去了解PCI协议,PCI侧的地址空间(-----PCI的BAR-----)是OS自动分配的。
--LAS0RR=0xffff0000   
--LAS0BA=0x00000001   
--LAS1RR=0xfff00000   
--LAS1BA=0x00100001   等都是------局部总线-----的,决定局部总线REMAP的关系及窗口大小。

“您LAS0BA,LAS1BA的最低为都设为1,那都map到I/O space了吧。 ”此BAR非PCI的BAR,1含义不是那样的,建议认真看PDF

出0入0汤圆

 楼主| 发表于 2009-12-18 10:04:48 | 显示全部楼层
LASxBA最低位是我记错了,应该是enable。
非常感谢!!!

出0入0汤圆

发表于 2012-6-5 14:44:05 | 显示全部楼层
嗯,很详细。

出0入0汤圆

发表于 2012-6-5 21:58:50 | 显示全部楼层
~~~~看下王齐的那本PCIe的书 讲的不错
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 09:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表