fenglouto 发表于 2009-12-17 15:25:49

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

对于地址映射我是这么理解的,不知道是不是正确?
--------------------------------------------------------------------------------------------------------------------------------------------
对于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,当这两个空间都要用到时,本地端地址总线上改怎么译码呢?

dspsharc 发表于 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: 965610b5ff0000ba8040010900000000
10: 00000000ffff000000000001012300ff
20: 0030050000000000000000004a03014f
30: 00000000000000000000000000000000
40: 00000000965610b5fff0000000100001
50: 000001c300004c060000000000024801
60: 00000000000000000000000000000000
70: 00000000000000000000000000000000
80: 00000000000000000000000000000000
90: 00000000000000000000000000000000
a0: 00000000000000000000000000000000
b0: 00000000000000000000000000000000
c0: 00000000000000000000000000000000
d0: 00000000000000000000000000000000
e0: 00000000000000000000000000000000
f0: 00000000000000000000000000000000
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 ADDR ADDR
--ADDR=H"000" decode BAR2
CONSTANT         BAR2_                                = H"000";
--ADDR must = H"0" , ADDR
CONSTANT         BAR2_H0                                = H"00";                --decode for FPGA's inner reg
CONSTANT         BAR2_H1                                = H"01";                --decode for Z16C30 reg
--BAR2_H0 & ADDR                                                        --ADDR
CONSTANT         LED_CNTR_OFFSET                = H"000";                --H"000"        D                 W/R , default bit ERRFLAG_OKFLAG_HPSEL_LEDSEL_LED3_LED2_LED1_LED0 is 00_0000_0000_0000
CONSTANT         CH1_DIR_OFFSET                = H"001";                --H"004"        D                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                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                 W/R , default send 256 SIMP
CONSTANT         SIMP_TIME_OFFSET        = H"004";                --H"010"        D                 W/R , default 5156*0.9697us=5ms SIMP
CONSTANT         INT_EN_OFFSET                = H"005";                --H"014"        D                W/R , default is 0
CONSTANT         INT_VECT_OFFSET                = H"006";                --H"018"        D                R   , read bit USC2RX_USC2TX_USC1RX_USC1TX_FPDPRM_FPDPTM_SIMP
CONSTANT         INT_CLR_OFFSET                = H"007";                --H"01c"        D                W   , write BITx="1" will clear INTx
--FPDP output clk(CLK20M->CLK20M1->SEL0CLK) delay selector
CONSTANT         FPDP_SEL0D_OFFSET        = H"008";                --H"020"        D                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                W/R , default bit EXT20MD5_EXT20MD4_EXT20MD3_EXT20MD2_EXT20MD1_EXT20Mis 111110 ("0" SEL Enable;"1" SEL Disable)
--FPDP input, SEL2D set SEL2CLK source , default bit PECLCLK_TTLCLKis 10 ("0" SEL Enable;"1" SEL Disable)
--FPDP i/o    , SEL2D set FPDPCLK source , default bit SEL1CLK_CLK20M2 is 01 ("0" SEL Enable;"1" SEL Disable)
----FPDP o          , OSC->CLK20M->CLK20M2->FPDPCLK->FPGA             , SEL2D="10"
----FPDP i          , STROBE->SEL2CLK->EXT20M->SEL1CLK->FPDPCLK->FPGA , SEL2D="01" , default
CONSTANT         FPDP_SEL2D_OFFSET        = H"00a";                --H"028"        DW/R , default is 0110
--FPDP output , SEL3D set TTLCLK out, default bit is 1 ("0" EN)
--FPDP output , SEL3D set PECLCLK out , default bit is 1 ("0" EN)
--FPDP i/o    , SEL3D 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                W/R , default is 11011
--SEL4D set FPDP/TM SUSPEND* term ("0" EN) , SUSPEND* asserted by FPDP/R or FPDP/RM
--SEL4D set FPDP/TM NRDY*    term ("0" EN) , NRDY*    asserted by FPDP/R or FPDP/RM
--SEL4D set FPDP/RM DIR*   term ("0" EN) , DIR*   asserted by FPDP/TM
--SEL4D set FPDP/RM STROB    term ("0" EN) , STROB    asserted by FPDP/TM
----FPDP/RM , SEL4D = "0011"
----FPDP/TM , SEL4D = "1100"
CONSTANT         FPDP_SEL4D_OFFSET        = H"00c";                --H"030"        D                W/R , default is 0011
--FPDP_CNTR        FPDP_MODE                        (W/R , default is 00 , mode0)
--                                        mode0 : FIFO loopback, FPDP_CNTR = "00"
--                                        mode1 : FPDP/RM input, FPDP_CNTR = "01"
--                                        mode2 : FPDP/TM output , FPDP_CNTR = "10"
--FPDP_CNTR                RM_NRDYn_OUT                (W/R , default is 0 , NRDY* output 0)
--FPDP_CNTR                TM_SYNCn_OUT                (W        , default is 1 , SYNC* output no 0 pulse)
--FPDP_CNTR                TM_SUSPENDn_EN                (W/R , default is 0 , FPDP/RM's SUSPEND* will not suspend FPDP/TM send)
--FPDP_CNTR                TM_NRDYn_EN                        (W/R , default is 0 , FPDP/RM's NRDY*    will not suspend FPDP/TM send)
--FPDP_CNTR                RM_SYNCn_EN                        (W/R , default is 0 , FPDP/TM's SYNC*    will not use as frame begin)
--FPDP_CNTR                FPDP_FIFO_RST                (W/R , default is 1 , FPDP fifo will not aclr by reg)
--FPDP_CNTR                FPDP_RST_DVEN                (W/R , default is 0 , FPDP fifo will not aclr after DVALIDn"1" 350us)
--
--FPDP_CNTR                RM_DIRn_STATUS                (R , FPDP/RM's DIR*           is input)
--FPDP_CNTR                TM_SUSPENDn_STATUS        (R , FPDP/TM's SUSPEND* is input)
--FPDP_CNTR                TM_NRDYn_STATUS                (R , FPDP/TM's NRDY*    is input)
CONSTANT         FPDP_CNTR_OFFSET        = H"00d";                --H"034"        D                 W/R , default is XXX010001000 (D R only)
--FPDP/RM FIFO HALF FULL
CONSTANT         FPDP_FIFOHF_OFFSET        = H"00e";                --H"038"        D        W/R
--FPDP/TM DMA SEND COUNT for fifo empty ok
CONSTANT         FPDP_SENDCT_OFFSET        = H"00f";                --H"03c"        D        W/R
--FPDP FIFO STATUS
CONSTANT         FPDP_FIFOS_OFFSET        = H"010";                --H"040"        D                    R
--USC1_CNTR                USC1_DMAW_EN                (W/R , default is 0 , USC1 fifo will not DMAW for TxREQn)
--USC1_CNTR                USC1_DMAR_EN                (W/R , default is 0 , USC1 fifo will not DMAR for RxREQn)
--USC1_CNTR                USC1_FIFORX_RST                (W/R , default is 1 , USC1 rxfifo will not aclr)
--USC1_CNTR                USC1_FIFOTX_RST                (W/R , default is 1 , USC1 txfifo will not aclr)
CONSTANT         USC1_CNTR_OFFSET        = H"011";                --H"044"        D                W/R , default is 10000000
--USCRX1 FIFO HALF FULL
CONSTANT         USC1_FIFOHF_OFFSET        = H"012";                --H"048"        D         W/R
--USCTX1 DMA SEND COUNT for fifo empty ok
CONSTANT         USC1_SENDCT_OFFSET        = H"013";                --H"04c"        D         W/R
--USC1 FREQ DIV
CONSTANT         USC1_FREQ_OFFSET        = H"014";                --H"050"        D                W/R
--USC1 FIFO STATUS
CONSTANT         USC1_FIFOS_OFFSET        = H"015";                --H"054"        D            R
--USC2_CNTR                USC2_DMAW_EN                (W/R , default is 0 , USC2 fifo will not DMAW for TxREQn)
--USC2_CNTR                USC2_DMAR_EN                (W/R , default is 0 , USC2 fifo will not DMAR for RxREQn)
--USC2_CNTR                USC2_FIFORX_RST                (W/R , default is 1 , USC2 rxfifo will not aclr)
--USC2_CNTR                USC2_FIFOTX_RST                (W/R , default is 1 , USC2 txfifo will not aclr)
CONSTANT         USC2_CNTR_OFFSET        = H"016";                --H"058"        D                W/R , default is 10000000
--USCRX2 FIFO HALF FULL
CONSTANT         USC2_FIFOHF_OFFSET        = H"017";                --H"05c"        D         W/R
--USCTX2 DMA SEND COUNT for fifo empty ok
CONSTANT         USC2_SENDCT_OFFSET        = H"018";                --H"060"        D                W/R
--USC2 FREQ DIV
CONSTANT         USC2_FREQ_OFFSET        = H"019";                --H"064"        D                W/R
--USC2 FIFO STATUS
CONSTANT         USC2_FIFOS_OFFSET        = H"01a";                --H"068"        D                    R
--FPDP DV RST FIFO DELAY TIME
CONSTANT         FPDP_DVRST_OFFSET        = H"01b";                --H"06c"        D            W/R


--BAR2_H1 & ADDR
--Z16C30's AD is U/Ln = 0
--Z16C30's AD <=>DLA
--Z16C30's AD is B/Wn = 0
--Z16C30's D/Cn   <=>DLA
--Z16C30's A/Bn   <=> !DLA


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

dspsharc 发表于 2009-12-17 17:20:38

Access serial EERPOM
--------------------------------
00: 965610b5ff0000ba8040010900000000   
10: 00000000ffff000000000001012300ff   
20: 0030050000000000000000004a03014f   
30: 00000000000000000000000000000000   
40: 00000000965610b5fff0000000100001   
50: 000001c300004c060000000000024801   

--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自动配出来的

fenglouto 发表于 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了吧。

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

非常感谢!

fenglouto 发表于 2009-12-17 18:19:34

我看9656DMA的时序图,DMA操作时,写地址为0x128的寄存器DMACSRO,地址总线上的值是 0x0800004a,那么BAR0的值是不是设置为0x08000000?

dspsharc 发表于 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

fenglouto 发表于 2009-12-18 10:04:48

LASxBA最低位是我记错了,应该是enable。
非常感谢!!!

dbx12358 发表于 2012-6-5 14:44:05

嗯,很详细。

wangshaosh123 发表于 2012-6-5 21:58:50

~~~~看下王齐的那本PCIe的书 讲的不错
页: [1]
查看完整版本: PCI地址映射的疑问(欢迎熟悉的DX进来指教)