现在的位置: 首页 > 综合 > 正文

DTS草稿之三

2013年01月11日 ⁄ 综合 ⁄ 共 9704字 ⁄ 字号 评论关闭

三、8572 DTS文件情景分析

1.根节点

    为了更清晰的说明怎样针对硬件平台编写一个dts文件,下面我们从8572的dts文件入手,进行一下仔细分析。dts的语法有些类似C语言的语法,我们在下面将看到这种相似性。

首先看到的是第12行有个“/ {”的标志,我们在dts文件的最后一行还会看到一个“};”,这里定义的就是我们前面提到的根节点,它定义的是单板级。“model”指定单板硬件平台的名字,#address-cells = <1>和#size-cells = <1>代表单板总线级地址为32位(1个cell),内存大小为32位(1个cell)。

2.CPU和MEMORY节点

接下来进行cpu节点的配置

    #cpus = <2>代表cpu子节点的个数为2。#address-cells = <1>代表cpu的地址为32位(1个cell)。

在cpu节点的下面还包含两个cpu子节点,其中第0号cpu子节点为

    device_type必须填为“cpu”,reg = <0>代表该节点是0号cpu,d-cache-line-size =<20> 和i-cache-line-size =<20>表示数据和指令的cache line的大小为0x20,cache每次和内存交换数据都是以cache line为单位的。d-cache-size = <8000>和i-cache-size = <8000>代表数据和指令cache的大小为0x8000。“32-bit”属性代表cpu是32位的。另外,第23行“PowerPC,8572”是cpu的名字,“@0”指定该cpu为0号cpu。合起来“PowerPC,8572@0”代表0号cpu的unit
name。下面的1号cpu的描述也是一样的格式,这里不再叙述。接下来看看内存的配置情况。

这里是内存节点的表述,device_type必须填为“memory”,reg = <0000000000000000>代表的是内存的位置和大小,reg的格式是<mem_addr mem_size>,分别表示内存区的起始地址和大小,mem_addr和mem_size本身的数据长度延用上面根节点#address-cells = <1>和#size-cells = <1>的配置,即各用一个32位的数据来表示。这里填的都是00000000,是留给UBOOT初始化完内存区后填入的。

3.SOC子系统节点

    SOC子系统将分为根节点、I2C节点、MDIO节点、eTSEC节点、UART节点、PIC节点、SEC和UTILITIES节点。下面分别描述。

1)SOC子系统的根节点

表示是片上系统(SOC)的配置情况,它还将包含很多子节点如I2C、eTSEC、UART、PIC等。SOC总的配置为#address-cells = <1>和#size-cells = <1>表示SOC子系统内部的地址为32位,空间大小也为32位。#interrupt-cells = <2>表示每个中断属性“interrupts”将使用两个cell(每个cell为32位)表示,前一个32位表示中断号(对应中断控制器的输入),后一个32位表示中断触发模式的选择情况。对于和openPIC兼容的中断控制器,中断触发模式的设置为

对于普通ISA中断控制器(如i8259),中断触发模式的设置为

这里8572的SOC中使用的是openPIC,使用前一种中断触发模式的设置,这在后面设备中断具体设置中会用到。

另外,SOC子系统的device_type属性必须设置为"soc",ranges = <0 ffe0000000100000>由3个32位的数组成,它们各自代表的意义在前文中也有叙述,分别是“本设备的总线起始地址(bus address)”、“上一级父设备对应的总线起始地址(parent bus address)”、“本设备和父设备相互对应的总线地址大小(size)”。ranges = <0 ffe0000000100000>就表示SOC内部总线0x0~0x00100000的地址空间和CPU总的地址空间0xffe00000~(0xffe00000+0x00100000)相对应。我们将看到SOC内部的子设备的寄存器空间都是相对于SOC的基地址描述的偏移地址,实际上它们在CPU访问的时候还要加上SOC总的基地址0xffe00000。reg
= <ffe0000000100000>描述的就是SOC子系统的寄存器是在CPU地址空间0xffe00000~(0xffe00000+0x00100000)。bus-frequency = <0>,这里的SOC总线频率将留给UBOOT进行填充。

现在讲完ranges和reg属性,应该好理解第55行soc8572@ffe00000,soc8572是设备名,@ffe00000是单元名,用其基地址表示该SOC是唯一的。

这里要补充一句,有人要问SOC的基地址为什么是0xffe00000,为什么不是其它的值?这里就要提到8572一个重要的寄存器CCSRBAR,这个寄存器指定了SOC的基地址,它的配置可以让8572的1M的配置控制状态寄存器组的地址实现动态设置。而寄存器CCSRBAR的值是在UBOOT中进行了设置的,显然我们这块板子的CCSRBAR=0xffe00000。其它板子也要根据具体的UBOOT设置修改我们的dts文件。

2)I2C节点

    8572的SOC有两个I2C节点,分别对应两个I2C控制器,以前一个为例

这里device_type和compatible是规定设置。reg = <3000 100>表示I2C控制器的寄存器地址在SOC子系统内的偏移地址为0x3000~0x3100,别忘了在转成CPU对应的全局总线地址时,偏移量还要加上SOC的基址0xffe00000。

interrupts = <2b 2>,这就要用到我们前面提到的SOC根节点的#interrupt-cells,还记得那里的#interrupt-cells=<2>,就是说interrupts属性需要两个32字节来分别描述中断号和中断触发模式,2b代表I2C控制器的中断接到中断控制器的0x2b线上,2代表中断为高电平触发。interrupt-parent =<&mpic>的用意就是指定中断控制器,8572的板子上可以有若干个中断控制器,而I2C的中断接到哪个PIC的输入管脚上,就由这条语句来决定。mpic实际上是一个标号(和C语言差不多),可以看到203行

interrupt-parent= <&mpic>就是指明I2C的中断接到203行声明的中断控制器上。另外,一个属性“dfsrr”,意思就是使用一个寄存器名字叫digital filter sampling rateregister。

    第2个I2C控制器这里就不介绍了,和第1个样。只是这里只是注意一下两个控制器的单元名不一样,一个是@3000,另一个是@3100,以它们的基地址来区分两个不同的控制器。

3)MDIO节点

    首先MDIO是我们虚拟出的一个设备总线,它使用来连接MAC和PHY的,我们看到在上面这个虚拟的MDIO设备上挂了4个子设备。从8572的CPU手册第932页的“Table15-4”中我们可以发现MDIO的控制寄存器分布在0x24520起始的0x20大小内,因此,设备单元名为mdio@24520应该很好理解了,同样,reg = <24520 20>就是MDIO的寄存器地址范围,同时注意这也是相对于SOC的基地址来说的。device_type和compatible属性不用讲了这是定死的。#address-cells
= <1>表示MDIO总线上的地址都是32位的,#size-cells = <0>这里表示不定义MDIO总线上的空间大小。

    接下来看MDIO虚拟设备下连接的4个PHY设备,先以第0个PHY设备为例进行一下介绍。ethernet-phy@0是它的设备单元名,前面的标号“phy0:”将被引用,后面我们将会看到。interrupt-parent =<&mpic>前面我们介绍I2C控制器的时候已经说过了,这里代表PHY-0设备的中断将统一接到SOC中的PIC中断控制器的输入端。interrupts = <4a 1>代表PHY-0所用的中断号为0x4a(可以看到4个PHY的中断采用共享方式都接到0x4a号PIC中断上),而中断触发方式为低电平触发。reg
= <0>指名该子设备为PHY-0。device_type固定设置为“ethernet-phy”。

    以上分析了PHY-0的子设备节点,PHY-1,2,3三个节点也用同样方法分析,这里略过不讲。

4)eTSEC节点

    8572的SOC中共包含4个eTSEC以太网控制器,下面将对其设备子节点进行描述。这里先以第一个控制器eTSEC-0为例进行介绍。

我们查看8572的CPU手册可以看到eTSEC-0的寄存器地址相对于SOC的基址来说是在0x24000~0x25000之间,因此,设备单元名ethernet@24000和reg = <24000 1000>就很好理解了。device_type和compatible属性是针对设备定死的。因为我们这里描述的是8572的eTSEC以太网控制器,所以model = "TSEC"。#address-cells = <1>表示eTSEC子模块内的总线宽度为32位,#size-cells = <0>表示eTSEC子模块内不具有空间大小的定义。local-mac-address属性是我们对以太网控制器的MAC地址的设置,我们这里配的是全0:[
00 00 00 00 00 00 ]。

下面再看一下余下的三个属性。首先,interrupts = <1d 2 1e 222 2>,这里的interrupts属性和和前面遇到的有所不同,改为由6个数来决定。实际上它们分别组成3个entry,每个entry还是2个cell组成(前一个是中断号,后一个是中断触发模式)。为什么每个eTSEC要定义3个中断呢?这里可以参见8572手册的第529页Table10-2,可以看到每个eTSEC包含3个中断分别是transmit、receive和error中断,实际上在上面“interrupts”的三个entry中也是这样的排列顺序,但是有一点要注意,这里的三个中断号0x1d0x1e0x22和表Table10-2给出的中断号是有一个数值为16的偏移的。另外,我们可以看到,这三个中断使用的中断触发模式都是高电平触发。interrupt-parent
=<&mpic>不用说了,又一次指定连接的中断控制器。下面是指定描述的PHY设备子节点,phy-handle =<&phy0>,也就是把我们这里描述的eTSEC-0和我们前面描述的PHY-0子节点关联起来。

    接下来dts中也描述了另外3个eTSEC的子节点,属性和上面的eTSEC-0类似,只是要注意interrupts属性中描述的中断号也同样和Table10-2有一个数值为16的偏移。

5)UART节点

8572有两个UART,它们的寄存器基地址分别为0x4500和0x 4600,大小都是0x100。因此不难理解设备单元名为serial@4500和serial@4600。device_type和compatible这里是定死的。reg = <4500 100>同样说明了UART寄存器的地址范围。clock-frequency = <0>这里没有定义时钟频率。interrupts = <2a 2>定义UART0的中断号是0x2a(同样和Table10-2有一个数值为16的偏移),中断是高电平触发模式。interrupt-parent
=<&mpic>同样是指定连接的中断控制器。UART1的中断使用的相同的中断号,采用中断共享方式,具体UART1的情况这里略过,可以参考UART0。

6)UTILITIES节点和SEC节点

    因为这两个节点的功能我们用不到,已经验证过去掉这两个节点是可以的,所以具体的代码解释可以参见文档《booting-without-of.txt》。

7)PIC节点

    8572的中断控制器的类型是openPIC,因此不难理解属性compatible和device_type的设置。设置属性interrupt-controller告诉系统这里描述的是一个中断控制器,clock-frequency = <0>时钟频率为0。#address-cells = <0>表示PIC和子设备的连接线上没有地址的概念。#interrupt-cells = <2>表示和PIC连接的子设备的中断描述为2个cell,一个表示中断号,一个表示中断触发模式。reg = <40000 40000>表示PIC的地址范围相对于SOC的基址为0x40000~0x80000。built-in和big-endian是8572
openPIC的默认属性。interrupt-parent =<&mpic>表示该PIC本身就是系统的顶极PIC,它将直接向CPU上报接收到的中断。

4.PEX系统节点

图-2 8572 demo机的硬件连接图

    要了解系统PEX(PCI Express)子系统的配置,先要说明一下8572 demo机的硬件连接图,如图-2所示。我们在图中可以看到有三个红色标出的PCI Express总线接口,它们分别是从8572内部的三个PEX控制器1~3,它们的内部寄存器地址分别相对于0xffe00000(SOC的基地址)分别偏移0xA000、0x9000、0x8000。如图所示,控制器3将和桥片1575连接,由1575内部的PCIE-PCI桥转接后连接到两个PCI插槽上(如图中下方绿色所示)。因此下面我们将重点介绍控制器3的设置情况,因为象USB等设备都是连接在其通过PCIE-PCI桥出的PCI总线上(未来将采用8112
PCIE-PCI桥)。我们将了解在选定IDSEL号的情况下,怎样在dts中设置一个PCI设备。而PEX控制器1和2直接接出PCIE接口,将和有PCIE接口的设备连接,我们将在稍后介绍设置情况。下面先从PCIE控制器3开始。

    这里说明一下,上面我们只贴到第244行,从245到333行是涉及demo机上其它PCI设备和桥片1575内部设备的节点描述,和我们的系统没有关系,这里将略去,只介绍PCIE控制器3节点和它对应PCI接口的设置。

    第218行“pcie@ffe08000 {”,我们前面也提到了PCIE控制器的寄存器偏移地址是SOC的基地址0xffe00000加上0x8000,大小是0x1000,因此这里的设备单元名很好理解。另外,寄存器地址范围reg = <ffe08000 1000>也可以理解了。Compatible和device_type属性对于8572来说有默认设置。#interrupt-cells = <1>,这里设置的是与接在PCIE总线上的所有PCI设备的中断表示的cell数,也就是说用一个32位的cell表示一个PCI设备的中断。每一个PCI设备有4个中断INTA~INTD,因此可以用1~4四个数来表示INTA~INTD。

#address-cells = <3>,这个并不是简单的说PCI的地址都是32×3位的,PCI的地址使用3个cell来表示具有一定的格式(请参见文档《PCI Bus Binding to:IEEE Std1275-1994 Standard for Boot Firmware》)。这里不进行详细说明,只将3个cell的图贴在下面。

图-3 PCI地址格式

    #size-cells = <2>代表PCI的地址范围为64位。bus-range = <0 ff>表示在PEX控制器3接出的PCI总线上,总线号的范围为0到0xff。

接下来介绍PCI总线下ranges属性的设置,ranges描述了PCI总线地址和父节点CPU地址空间的具体映射关系。

                        ranges= <02000000 0 80000000
80000000 0 20000000

                                        01000000 0 00000000
ffc000000 00010000>;

    首先要把上面一长串数字分成两个entry(每行对应一个entry)。我们还记得ranges的每个entry需要三个元素来表示:bus address, parent busaddress, size,在上面已经将三个区域用三种颜色区分开了。可以看到,bus address有3个cell,这就是我们刚刚提到的PEX控制器3的#address-cells = <3>规定的,代表的是PCI总线的地址;parent bus address是1个cell,这是在根节点#address-cells = <1>属性中规定的,代表的是CPU的地址;size有2个cell,这是在PEX控制器3的#size-cells
= <2>规定的。我们从《PCI Bus Binding to:IEEE Std1275-1994 Standard for Boot Firmware》对PCI地址格式的说明可看出上面ranges属性的两个entry想要说明的配置信息如下:

1)PCI mem地址0x80000000映射到CPU的地址0x80000000,空间大小0x20000000

2)PCI I/O地址空间0x0000000映射到CPU的地址0xffc00000,空间大小0x10000

由于PPC架构只有mem空间,可以看出以上两块空间PCI mem和IO空间都是映射到CPU的memory空间来统一处理的。

    clock-frequency = <1fca055>即为设置PCI总线频率为33MHz。interrupt-parent =<&mpic>指明的是PEX控制器3本身的中断将接到8572的片内openPIC处理。【注意:这里描述的不是每个设备的INTA~INTD和openPIC的连接关系】。interrupts = <18 2>表明PEX控制器3本身的中断将和openPIC的中断线0x18接在一起,并且是高电平触发。(对照8572的手册Table10-2,这里出现的中断号与表中相比也要做加16处理)。

    下面介绍两个跟PCI总线下连接的PCI设备中断设置相关的两个重要属性:interrupt-map-mask和interrupt-map。具体这两个属性对于PCI设备的格式请参见文档《Open Firmware RecommendedPractice Interrupt Mapping Version 0.9》。interrupt-map-mask和interrupt-map两个属性是结合使用的。概括而言,interrupt-map-mask =<f800 0 0 7>的用意就是在Linux内核使用interrupt-map进行配置的时候,它只使用图-3中phys.hi的ddddd五位和PCI设备中断(1~4)的低3位。下面解析interrupt-map:

                        //IDSEL 0x11  PCI slot #1 J21

                                    8800 0 01&mpic
42 1

                                    8800 0 0
2
&mpic 43 1

                                    8800 0 0
3
&mpic 44 1

                                    8800 0 0
4
&mpic 41 1

这是interrupt-map的4个entry,共同表述的是一个PCI设备(对应一个PCI插槽,如图-2)。紫色的一列1~4分别对应这个PCI设备的INTA~INTD管脚,这里每个entry的红色部分3个cell就是前面描述的PCI地址的3个cell(格式如图-3),又因为前面interrupt-map-mask的设置是只取phys.hi的ddddd五位,因此对于phys.hi=0x8800来说,该槽位对应的设备号为0x11,也就是说硬件上早已经把设备号0x11对应的那个IDSEL(从PCI AD[31..11]中选一根)接到图-2中的那个PCI槽位上了。【比如我们将来在处理MPUF板子上PCI设备的时候(如USB控制器),就可以先获取对应的设备号再在dts文件中将此设备照这样的格式添加进入】。黑色的一列是代表这个设备号为0x11的PCI设备的所有INTA~INTD中断都被接到8572的openPIC上进行处理。绿色两列分别对应openPIC上所接的中断号和中断触发模式,这里看到PCI设备0x11的INTA~INTD分别接到openPIC的中断42、43、44、41线上。中断触发模式都为低电平触发。

    下面看另外一个槽位:

                        //IDSEL 0x12  PCI slot #2 J20

                                    90000 0 1 &mpic 43 1

                                    90000 0 2 &mpic 44 1

                                    90000 0 3 &mpic 41 1

                                    90000 0 4 &mpic 42 1

    按照我们前面分析的方法,不难看出这里是描述一个设备号为0x12的PCI设备,它的四个中断管脚INTA~INTD分别被接到openPIC的43、44、41、42中断线上。中断触发模式都为低电平触发。

    下面介绍另外两个PEX控制器1和2,由于这两个控制器差不多,我们只选取控制器1来说明一下。

    这里设置的大部分和前面的PEX1控制器基本一致,但是由于PEX1和PEX2两个控制器与PEX3控制器不同,它们接出的PCIE总线没有转成PCI总线,而是直接出PCIE接口。因此它的interrupt-map也就是中断设置方面由些不同。这里推测有可能跟PCIE是用过MSI方式传递中断的有关。从上面的代码中我们看到对于PCIE设备来说,interrupt-map中只是对设备号为0的设备的INTA~INTD和openPIC的中断线40~43做了连接处理。【该例子可以作为我们以后在PPC板上直接接PCIE设备的参考】。

5.FLASH节点

    首先,8572的demo机上的NOR flash芯片是挂在8572的Local bus上,其起始地址0xe8000000跟硬件片选的连接关系以及相应段的ORx/BRx寄存器的设置有关系。我们看到device_type设置为"rom",compatible设置为"direct-mapped",probe-type设置为"CFI"模式。reg = <e800000008000000>,flash的地址空间设置为128M,起始地址为0xe8000000。bank-width = <2>规定flash的数据总线宽度为2个bytes,即16位。Partitions属性的每个entry描述一个flash的分区,每个entry由2个cell组成,分别表示分区起始地址和大小。partition-names则规定了每个flash分区的分区名。

    虽然在这里flash节点的描述中没有提供中断的描述信息,但是以此为例,为我们树立了一个描述挂接在8572 Local Bus上设备的方法,由于我们的很多设备(比如EPLD、1655x)都是挂在Local bus上的,我们可以比照flash节点的描述创建EPLD设备节点的描述(包括描述其中断属性等)。

抱歉!评论已关闭.