,贾凡2
(1.南京理工大学 计算机科学与工程学院,南京 210094; 2.北京航天测控技术有限公司,北京 100041; 3.龙芯中科技术有限公司,北京 100095)
目前,龙芯处理器已广泛应用于航空、航天、装备、测控、通信等关键领域,作为支撑国家信息化、智能化战略的重要核心部件,在这些关键领域实现了国产化替代,保障了国家重大工程的核心自主和安全运行。在上述关键领域中,常面向恶劣环境,存在长期工作、高密度计算等关键性应用要求,对元器件、主板的可靠性提出了严苛的要求,这就需要在确保硬件高可靠的同时加强设备自检测和故障自诊断设计,从而保证故障实时定位、实时诊断,直至实现在线修复和无人维护,确保关键设备高可靠运行。
在特种应用领域中,电子产品面向的恶劣环境如: 高温、低温、震动、盐雾等环境,因此主板设计时关键器件一般采用板贴设计以提高可靠性,这为关键器件的维修和定位带来了挑战,比如内存。商用机器一般选用的内存条类型有:SO-DIMM、R-DIMM、U-DIMM,当机器的内存出故障时,仅通过逐一替换内存条的方法就可以排除故障内存;而对于加固计算机主板,由于内存颗粒直接焊接在主板上,相关标准对主板的同一器件维修的换焊次数要求不大于3次,这些条件限制了内存颗粒的维修不能像商用机器维修那样通过简单的替换和测试的方法进行,需要提供软件定位的方法,确定故障器件后再进行焊接维修。
加固计算机主板的成本高昂,按质量规范要求,出现故障后需要准确地定位问题,不允许反复维修。 龙芯的产品线齐全,品类丰富,提供了各种应用领域所需要的解决方案,其中龙芯3号系列处理器是面向桌面、高端嵌入式和服务器应用的多核处理器[1]。龙芯3号计算机主板如果外接冷板、散热片或加三防漆等,导致硬件一旦出现故障,通过测量信号等方式定位问题的难度大幅度提高。因此通过基本输入输出系统(basic input output system,BIOS)一组固化到主板上一个 ROM 芯片上的程序[2],通常称为固件,并结合硬件增加内建调试模块来对板卡故障进行诊断是最为高效、便捷的。
综上所述,提高主板自检测、自诊断能力已成为提高全国产信息化硬件可靠性和保障性的迫切要求,也是未来信息系统智能化无人化发展的需要。
现代的无内部互锁流水级(microprocessor without interlocked pipelined stages,MIPS) 处理器提供一定的硬件支持来协助开发人员[3]。龙芯3号计算机模块的硬件设计抽象图如图1所示。
图1 龙芯3号计算机硬件设计方案
龙芯3号CPU对外接口采用扩展的HT协议,既可用于实现外部设备连接,又可实现多芯片互联[4]。HT是系统级的总线,IO多指南北桥芯片,多芯片互联是指与多个龙芯3号互联,即在同一块主板上构建2路或4路CC-NUMA(Cache-coherent non-uniform memory access architecture:高速缓存相关的非一致性内存访问,是一种用于多处理器的电脑记忆体设计)系统。龙芯 7A1000 桥片(后文简称为桥片)是龙芯的第一款专用桥片组产品,目标是替代 AMDRS780+SB710 桥片组,为龙芯处理器提供南北桥功能。桥片通过 HT 高速总线接口与龙芯3 号系列处理器相连,一旦HT总线互联出现故障,将导致系统无法启动[5]。
内存作为计算机中重要的部件之一,内存的稳定运行决定了计算机能否稳定运行。内存是指能够按照处理器的访问粒度进行随机访问的存储器[6]。系统中常见的静默错误,即程序使用了有错误的内存,将会造成程序跑飞或者得到错误的运行结果,如果在装备类应用中出现此类错误将导致无法预估的损失。作为程序运行的载体,内存的稳定性以及内存故障调试与故障定位是计算机所有调试模块中最基础和重要的部分。近年来,随着芯片工艺水平的显著提升,内存中一个最小比特位存储单元所占的体积越来越小。而随着芯片密度的增加,内存芯片内部更容易受到因高温、射线辐射、剧烈振动、灰尘等外部因素的影响而出现损坏,导致数据存储错误。这些错误一般是因为内存单元中某个和多个bit位发生翻转造成的,这些损坏一般不可逆,调试内存稳定性等参数无效,必需更换内存颗粒才能解决问题。
根据故障诊断需求和龙芯开源软件的现状,基于PromMonitor(PMON,龙芯处理器的BIOS)在实现龙芯固件规范要求的软硬件初始化要求的基础上增加故障诊断功能模块。
PMON上电启动流程如图2所示。
图2 PMON上电启动流程
BIOS故障诊断设计主要包括HT链路链接问题故障诊断(位于PMON上电启动流程[3]阶段)和内存问题故障诊断(位于PMON上电启动流程[5])。基于龙芯3号系列的CPU计算机模块的上电自检流程,结合HT和内存两种常见故障,设计了HT和内存故障的诊断实现方法,并对HT故障实现可靠性增强设计,以期帮助用户快速发现故障、准确定位问题的目的。
龙芯3号板卡启动过程中出现故障,其故障故障树如图3所示。
图3 主板启动故障树
龙芯3号处理器主板启动故障跟软硬件均相关,硬件相关的问题包括电源、复位、时钟和取指,一般采用指示灯的做法进行故障指示。HT控制器是可编程器件,需要软件对其进行工作模式配置后才可以正常访问所连接的设备,出现问题可分为软件配置问题及硬件配置问题。内存控制器与HT类似,需要软件正确配置其工作模式才可能正常访问内存设备,出现问题的模式分为:地址线问题、数据线问题、控制线问题及颗粒问题。下文对每种故障分别进行描述。
开机启动,模块上电,电源按照设计的电源时序完成各级电源的上电,本方案设置了3个指示灯用于指示上电过程,第一个指示灯指示外部电源接入,第二个指示灯指示Standby域上电完成,最后一个电源指示灯指示所有电源上电完成。板卡使用过程可根据3个指示灯的状态来判断模块上电过程是否有异常,异常电源属于哪个电源域。
上电完成后,开始板上电路的复位操作,可根据复位指示灯观测模块复位是否正常,正常情况为上电后复位指示灯点亮,完成复位后指示灯熄灭。其它状态为复位异常。
CPU的取指是否正常关系到能否启动BIOS。当一个计算机系统通电以后,它会运行存储在闪存中的固件[7]。龙芯3号处理器从3A2000之后都支持SPI取指,为了便于板卡启动故障定位,除了电源指示灯以及复位指示灯,CPU的BIOS芯片片选引脚接有一个取指指示灯用于指示CPU是否有取指操作。正常情况模块完成复位后CPU会发起取指操作[8],取址指示灯在CPU取址过程会闪烁,取址完成后熄灭,其他状态为取址异常。
HT问题主要表现为HT互联故障,可能原因有硬件配置问题:如互联频率设置过高,HT总线电压过高或过低,HT工作模式设置错误等;软件配置问题:HT频率设置过高。启动过程中HT总线的建链过程分为两个阶段:第一阶段是按照硬件默认频率进行建链;第二阶段是HT复位后,按照软件配置的HT频率以及工作模式进行建链。板卡启动过程中常见的HT故障一般为第二阶段,故障排查方法详见第2章。
板卡启动故障、运行过程中系统或应用程序跑飞、运行测试程序结果不符合预期、网络DMA数据规律报错等情况,均可能是内存问题导致的系统稳定性问题,造成数据读或写错误,从而影响程序运行结果的正确性。
内存存储单元是按照行、列来组织的,对内存的寻址是通过Bank地址,行地址和列地址进行的[9]。常见的内存问题有:地址线问题,控制线问题,数据线问题,内存颗粒本身的问题。
1)对于控制线问题,包括时钟,片选信号等,如果控制线故障,内存训练是无法正常完成的,这里需要硬件参与定位。
2)地址线问题:若地址线问题,在内存测试中,会出现间隔固定地址段,对内存的读写内容完全相同,形成内容回绕的现象,可以根据错误规律即间隔地址空间的大小推算哪根地址线错误。
3)数据线问题及内存颗粒本身问题:在内存测试时都有可能表现为内存固定数据位错误。
由于龙芯3号处理器中集成了2个内存控制器,每个内存控制器上可以接2个片选,对于双路或四路计算机模块,内存连接更是复杂。已无法根据上述方法直接定位出哪个CPU的哪个内存控制器的数据线或内存颗粒故障,详细故障定位方法见第3章。
主板产品应用的统计数据显示,高质量等级的龙芯3号主板在生产、调试、维修保障过程中最常见的故障种类包括两类:HT互联故障和内存故障,两者之和约占维修总数量的80%以上。因此通过自动手段快速定位诊断这两类故障就成为提升主板故障维修效率的关键。
针对上述两种故障模式,设计了软件定位方法,以期达到提高维修效率、减少维修成本的效果。
龙芯3号对外接口采用扩展的HT协议,既可用于连接IO又可实现多芯片互联。HT是系统级的总线,IO多指南北桥芯片,多芯片互联是指与多个龙芯3号互联,即在同一块主板上构建2路或4路CC-NUMA系统。一旦HT总线互联出现故障,将导致系统无法启动。
为了简化描述,本文以龙芯3号处理器连接桥片为研究对象,提出一种HT链路故障的诊断及自修复方法。对于多处理器HT互联的情况,处理方法类似。
在大量的板卡维修过程中,我们发现有些机器在500次重启实验过程中总有几次启动死机的情况,通过调试串口及Ejtag进一步定位发现死机时机器卡在HT总线建链互联处,这种故障的典型现象是:调试串口输出“Waiting HyperTransport bus to be up.”或“Waiting HyperTransport bus to be up again.”的字样,随后机器死机,再也没有输出。
龙芯3号与桥片的HT总线的建链过程是:复位时序按照硬件配置的总线频率和总线位宽发起建链请求,软件查询建链完成位[10];建链成功后软件对桥片端进行接收窗口的配置;软件重新设置CPU和桥片两端的总线频率和总线位宽使其工作在最高的频率和最宽的位宽;复位HT总线等待重新建链;查询建链完成位;建链完成后把总线再次配置成刚上电的状态方便下次重启建链;以当前设置的总线频率和总线位宽进行IO读写通信。
调研发现,传统的龙芯3号主板软硬件对HT总线的建链失效有两种处理机制:一是使用硬件看门狗在此处监控建链过程是否失败,若失败则看门狗因超时会发出复位信号重启系统,一般情况下,多次重启都能解决HT握手的问题;二是放任不管,毕竟此故障是小概率事件,对于可靠性要求不高的场合,手动重启就可以解决问题。但对于安全应用领域,通常会面临无人值守,长期加电的应用场景,一次启动失败会造成灾难性的后果。另一方面,基于成本和PCB布局面积的考虑,不是所有的板卡在设计时都预留硬件看门狗电路,最好的解决办法是在不要求硬件的前提下通过CPU内部机制实现监控“HT总线的建链失效”的情况,并进行重启自我修复。
我们把BIOS阶段负责启动和初始化任务的处理器核称作主核(core0),其它核称为辅核或从核。本文利用龙芯3号的多核特性,使用从核(core1)对建链过程进行监控,若发现建链过程异常,则从核(core1)发挥看门狗的作用对系统进行复位,并记录当前复位次数至NVRAM中记为Fault,作为后期判断主板健康状态的依据,当重启次数超过重启门限时,BIOS驱动蜂鸣器报警,提示主板故障,硬件工程师进行检修。
具体的设计流程如下:
系统冷启动,Fault初始化为0;
当系统是热启动且从核没有收到主核发出的HTok通知时,会根据Fault的值产生如下行为:
Fault++<=3, 简单地复位重启;
Fault++ =4, 把HT总线位宽由16位设计成8位互联模式,重启互联;
Fault++ =5, 把HT总线频率由1600 MHz降到800 MHz,重启互联;
Fault++ =6, 把HT总线频率由800 MHz降到400 MHz,重启互联;
Fault++ =7, 把HT总线频率由400 MHz降到200 MHz,重启互联;
Fault++ =8, CORE1驱动蜂鸣器报警。
这种设计方法能解决绝大多数的HT总线偶发互联不上的问题,并且可以根据Fault的值或启动打印信息获取当前的HT总线配置信息,并对硬件故障进行报警指示,达到比较高的可靠性要求。
从图2可以看到,计算机模块启动过程中固件最初在FLASH芯片中运行,为了加块固件初始化速度,BIOS中增加锁CACHE操作,通过Cache As Ram(CAR)技术将高速缓存作为临时内存使用。在锁CACHE期间完成了内存的初始化与内存训练,内存故障检测等功能。
CAR技术是把CPU的Cache作为RAM使用。龙芯3号CPU均支持锁Cache机制,落在被锁区域中的共享Cache块会被锁住,读写操作到cache后不会向内存传递,因而不会被替换出共享Cache。此外当共享 Cache收到 Direct Memeory Access(DMA) 写请求时,如果被写的区域在共享 Cache 中命中且被锁住,那么 DMA 写将直接写入到共享 Cache而不是内存。
龙芯3A处理器提供了4组共享Cache锁窗口寄存器,通过窗口锁地址寄存器指定锁存地址,锁窗口掩码寄存器指定锁窗口地址的大小。
锁Cache完成后,程序将在Cache中完成内存的初始化及内存故障检测功能。
龙芯3A处理器的内存的组织形式,以双路为例如图4所示。
图4 龙芯3A双路计算机模块内存(x8位宽)逻辑连接图
在龙芯3A CPU中包含2个内存控制器(MC0、MC1),每个内存控制器最多支持两个PBANK,通过片选信号cs进行控制,每个PBANK可支持的数据位宽为64 bit。若我们使用X8位宽的内存颗粒,每个内存控制器都接满内存,那么一个龙芯3号 CPU 将外接32颗内存颗粒。如果龙芯3号使用多芯片互联模式,如双路系统,那么板载将最多接64颗x8的内存颗粒。
对于多路互联计算机模块,内存颗粒故障诊断流程如图5所示。
图5 龙芯3号板卡多路互联内存排查流程
图5内存故障诊断可以归纳为以下3点:
1)当内存出现读写错误时,首先确定是哪个CPU上的内存有问题;
对于CPU多路互联情况,BIOS通过诊断程序参数选择单路模式启动,若内存测试通过,说明CPU0的内存没问题;再设置成双路模式启动,做内存测试有问题说明是CPU1上的内存出错。对于四路服务器依此类推,找出内存颗粒所在的处理器编号。
2)当锁定处理器编号后,确定是此处理器的哪个内存控制器(MC0还是MC1)的内存问题;
一个CPU上的两个内存控制器分别进行初始化,内存初始化时,BIOS通过诊断程序参数选择初始化成单通道MC0,然后进行内存初始化,内存测试,若内存测试错误,则内存颗粒在MC0控制器所接内存上。否则在MC1上。
3)最后确定是上述内存控制器中哪个片选上内存颗粒有问题;
通过片选信号,只选择MC上的一个CS的内存进行初始化,并根据内存读写测试程序的测试结果,确定出错的内存所在的组,进而定位故障颗粒。
图5中内存读写测试环节是内存诊断程序的核心,内存诊断程序对内存地址空间进行反复读写访问,来判断内存是否有访问错误情况。如果读写信息不一致,程序将会打印出该内存的地址信息,写入和读出的数据信息。
内存诊断程序流程如图6所示。
图6 内存诊断程序流程
内存诊断程序的思想:对指定内存地址空间,通过UnCached地址先写值后读值,比较读出来的内容是否与写入值一致。
内存诊断程序划分为2个阶段:简单内存读写测试和复杂内存读写测试。简单内存读写测试主要对内存物理地址0x0-0x38进行简单的读写测试,用于判断读写时序的正确性,其测试case为依次对上述地址以8次节为长度为单位写入0x5555555555555555、0xaaaaaaaaaaaaaaa、0x3333333333333333、0xcccccccccccccccc、0x7777777777777777、0x8888888888888888、0x1111111111111111、0xeeeeeeeeeeeeeeee,并读出内容与写入内容进行比较,若一致刚通过,若不一致则优先解决时序问题。
复杂的内存测试,是对指定内存地址范围进行读写测试,读写的数据的case分为:
Case1:写全1;
Case2:写全0;
Case3:逐位写1,其余位为0;
Case4:逐位写0,其余位为1;
Case5:对所有奇数位写1,偶数位写0;
Case6: 对所有偶数位写0,奇数位写1;
Case7: 依次每个字节写入0x11、0x33、0x77
Case8: 依次每个字节写入0xee、0xcc、0x88
Case9: BASE + DATA*n;
其中 DATA,BASE均是一个固定数,例如,DATA=0x200,BASE = 0x9800000090100000; 起始地址写入的测试数据初值为0x9800000090100000,随着地址每增加8个字节,固定写入的测试数据值就增加DATA。
BIOS启动进入内存诊断程序,首先进入内存简单测试,测试场景包括case0,1,2,3。下面是简单测试读写均正确时的结果:
The uncache data is:
00000000: 5555555555555555
00000008: aaaaaaaaaaaaaaaa
00000010: 3333333333333333
00000018: cccccccccccccccc
00000020: 7777777777777777
00000028: 8888888888888888
00000030: 1111111111111111
00000038: eeeeeeeeeeeeeeee
The cache data is:
00000000: 5555555555555555
00000008: aaaaaaaaaaaaaaaa
00000010: 3333333333333333
00000018: cccccccccccccccc
00000020: 7777777777777777
00000028: 8888888888888888
00000030: 1111111111111111
00000038: eeeeeeeeeeeeeeee
内存简单测试包含了过cache的内存读写和不过cache的内存读写,每部分均只测试了0x38个字节范围,主要目的完成内存读写时序的简单调试与判断,以及内存数据线通路是否有问题的判断。
内存复杂测试在简单测试的基础上增加了更多、更复杂的内存读写场景,内存地址空间范围更大。复杂测试程序设计了交互界面,可以指定内存的测试地址范围。
内存复杂测试人机交互界面以及采用多种case时,案例出错的测试结果:
Do mem test?(Input 0xf skip ):16'h //是否进入内存复杂测试界面
Default test param S1 = 0x0010000080000000
Change test param S1? (Input 0xf skip):16'h //是否修改内存测试指定地址范围
Start Testing Memory...
Address Stuck Testing all space...
Test address range: 0x9800000090100000~0x9800000110000000
write done...
Stuck Testing done!
Pattern WalkOnes Test...
Test address range: 0x9800000090100000~0x9800000110000000 @@ address interval: 0x00000040
write done. begin to read and compare…
...
addr 0x98000000908bb0a0 expected: 1010101010101010 read: 101010ff10101010 reread: 1010101010101010 DDD
addr 0x98000000908bb0c0 expected: 0101010101010101 read: 0101010401010101 reread: 0101010101010101 DDD
addr 0x9800000090c9c180 expected: 0101010101010101 read: 0101014001010101 reread: 0101014001010101
addr 0x9800000090c9c188 expected: 0202020202020202 read: 0202028002020202 reread: 0202028002020202
addr 0x9800000090c9c190 expected: 0404040404040404 read: 0404040104040404 reread: 0404040104040404
addr 0x9800000090c9c198 expected: 0808080808080808 read: 0808080208080808 reread: 0808080208080808
addr 0x9800000090c9c1a0 expected: 1010101010101010 read: 1010100410101010 reread: 1010100410101010
针对HT互联故障的检测和恢复方法,我们选用5块龙芯1500+龙芯7A的板卡进行了每块主板500次重启的验证实验,对采用本文中的方法的前后实验情况做了对比分析。
表1中第二列表示在未采用本措施时,主板在做500次的重启实验过程中进行了第几次后无法完成重启实验,可以观察到主板编号为201703001S、201703007S的两块板卡成功完成了500次的重启实验,编号为:201703003S、201703011S、201703014S的主板分别在进行了127、308、
表1 HT互联故障检测方法比较
432次重启后出现了系统死机,表现为HT互联故障。表中第三列表示采用了本方法后,5块主板都可以完成500次的重启实验,并且通过获取NVRAM的Fault值(表中第四列)可以判断编号为201703003S的主板重启过2次,编号为201703011S的主板重启过1次,这个数据也可以作为预警信息提示这两块板卡的健康状态存在问题,主板维护人员需尽早检修,排除故障隐患。
这种方式比传统的重新修改HT的配置,并重新编译烧录固件完成故障诊断的方式节约了大量的时间成本。
内存故障检测程序考虑时效性和覆盖性,本文中的复杂内存测试并不是全地址覆盖测试,而是在选择合理的地址间隔进行测试。这种测试方法可以大幅度提高内存故障检测速度。
内存颗粒的物理设计,要求行地址线+列地址线+BANK线组合成一个物理地址后才能唯一寻址一个内存存储单元(通常由8位或16位组成)。内存故障,通常表现为某个行/列选通的地址读写都有问题。内存行地址线个数一般12个以上,列地址线个数为10。因此地址选通最小覆盖地址线的地址间隔为2^10,及1 KB。因此内存故障检测时,我们以1K的地址范围为步长进行间隔读写操作。这种检测方法比全地址覆盖的测试方法速率快1 024倍。
BIOS实际内存测试程序测试结果如下:
Start Testing Memory...
Address Stuck Testing all space...
Test address range: 0x9800000080100000~0x9800000088000000
write done...
addr 0x9800000080103600 expected: 9800000080103600 read: 9800000080103604 reread: 9800000080103604
addr 0x9800000080103800 expected: 9800000080103800 read: 9800000080103804 reread: 9800000080103804
addr 0x9800000080103a00 expected: 9800000080103a00 read: 9800000080103a04 reread: 9800000080103a04
…
内存测试结果解析:内存读写测试中期望值与读的值不一致,证明内存确有出错,根据数据位错误信息,内存读写错误固定出现数据位bit2上,也即内存的数据线DQ2
对应的内存颗粒故障。结合上述内存颗粒故障诊断方法以及板卡原理图,我们就能唯一确定内存故障颗粒位置。
这种内存故障定位方法,对于内存模块由于对应的数据线虚焊、PCB布线问题、内存数据线对应匹配电阻问题及内存颗粒本身故障等都能准确地定位,然后再由硬件工程师进行定点排查,最终决定是否更换内存颗粒。
通过BIOS中的故障诊断手段,我们实现了龙芯3号计算机板卡HT链路无法链接,内存错误导致程序出错等问题的快速定位。软件定位故障方法简化了硬件工程师在硬件问题上的排查的工作量,完成了故障诊断的轻便化和智能化操作实现。随着硬件智能化程度的提升,复杂主板板级故障诊断将向着故障预测及自修复方向发展,进一步提升系统可用性,为装备智能化发展奠定基础。