这篇文章会简单的介绍8255的启动流程,然后着重介绍8255在实际项目中新硬件上的bring up工作,可以给大家做些参考。
下面这些信息来自文档:《QAM8255P IVI Boot and CoreBSP Architecture Technical Overview》 80-42847-11 Rev. AC,如果已经对这个文档比较熟悉可以跳过这个部分。如果没有看过,建议一定要认真看一遍。

- 1. After the chipset is reset, the SAIL and Qualcomm® Kryo™ CPU Gold core 0 comes out of reset.
- 1a. SAIL configures the pre-built-in self-test (pre-BIST) and go into wait for interrupt (WFI) and hardware BIST controller unit (HBCU), which is a
- hardware controller performs the BIST on SAIL. SAIL PBL initializes hardware and loads SAIL hypervisor to run.
- 1b. SAIL hypervisor loads the SW1/SW2/SW3 images.
- 1c. APPS core0 executes application primary boot loader (APPS PBL) pre-BIST configuration and goes into WFI and wait for SAIL communication
- to run BIST on APSS. After Phase-1 BIST, SAIL sends post BIST reset to APSS, APSS reset and the Kryo Gold core 0, APPS PBL initializes
- hardware (timer, PRNG, clocks, and so on), enables caches and memory management unit (MMU), and detects the boot device according to
- the boot option configuration:
- □ Default boot option for APSS: UFS
- □ Default boot option for SAIL: NOR
- □ Default boot option: Overridden by EDL cookie or force USB GPIO
- 2a. APPS PBL loads and authenticates XBL loader (region #1) from the boot device to the Boot IMEM.
- 2b. APPS PBL loads and authenticates XBL SDI (region #2) from the boot device to on-chip internal memory (OCIMEM).
- 2c. APPS PBL loads XBL SEC (region #0) from the boot device to boot IMEM. XBL SEC is a QTI-signed ELF segment, which locks xPUs. XBL
- SEC runs the security configuration in the EL3 mode
- 3. XBL SEC runs the security configuration in the EL3 mode and after it is done, it will inform SAIL hypervisor that APPS is ready for the phase
- BIST-II on DPU, Camera, CamNoc, NSP, Ethernet, PCIe, and so on.
- 4a. XBL loader will take over control and continue to load multi-image signature and integrity check (MISC).
- 4b. XBL loader loads and authenticates XBLConfig image.
- 4c. XBL loader loads SHRM.
- 4d. XBL loader loads and authenticates MISC image.
- 4e. XBL loader loads and authenticates the AOP image from the boot device to the AOP CodeRAM.
- 4f. XBL loader brings the AOP processor out of reset.
- 4g. XBL loader will then load and authenticate the CPU firmware.
- 4h. XBL loader loads and authenticates Qualcomm® Trusted Execution Environment (TEE) into pseudo internal memory (pIMEM).
- 4i. XBL loader loads and authenticates Qualcomm® Hypervisor Execution Environment (HEE).
- 4j. Loads and authenticates XBL core from XBL image.
- 4k. XBL jumps to XBL_SEC and XBL SEC transfers execution to the Qualcomm TEE.
- 5. Qualcomm TEE transfers the execution to Qualcomm HEE, Qualcomm HEE runs at EL2 mode. Qualcomm HEE configures SMMUs and
- provides virtualization support.
- 6. Qualcomm HEE transfers the execution to XBL core(region #3). It runs at nonsecure EL1 mode
- 7. Linux loader application (part of application boot loader firmware volume (ABL FV)) loads and authenticates the HLOS kernel with verified boot,
- jumps to HLOS. HLOS runs at nonsecure EL1 mode
- 8-13. HLOS Peripheral image loader (PIL) driver loads all subsystems iris firmware (FW), camera FW, audio FW, sensor FW, turing FW, deep
- learning FW images to DDR and configures the clocks and power rails, if necessary. HLOS PIL driver executes a secure channel manager
- (SCM) call to Qualcomm TEE to request a secure PIL driver, authenticates images, and Qualcomm HEE brings each subsystem out of reset.
- QAM8255P Cold Boot Flow – Phase 2 BIST
这几天刚刚把新到的8255的硬件完成了bring up,中间遇到了挺多问题,趁着现在还有些印象抓紧记录一下。

1,由于功能安全的要求,8255的boot流程和8155有很大的差异
2,MCU和SAIL(安全岛)在boot的流程中需要多次握手,且SAIL软件正常工作时才会放行MD(main domain)域的软件
3,MCU-SAIL之间通信方式为UART,同时SAIL会向外输出ERR_PIN1/PIN2来表明当前的异常状态
4,SAIL和MD之间是通过mailbox进行通信,他们之间也会做一些状态监控
5,这里的MD主域指的是APPS,即application processes,我们常说的A核
6,这里的MCU/VIP型号可能是TC397也可能是瑞萨的RH850系列
bring up工作更像是阶段性的总结工作,对这一阶段的工作成果进行验证和总结,打个比喻,你可以认为bring up是一次期中考试。前期工作做的好不好,准备的充不充分,将会在这个时刻得到充分的验证。所以越是前期工作准备的越充分,bring up节点到来的时候,成功bring up的难度就越小,成功率就越高,软硬件的问题也就越少。
在前期的硬件设计阶段,你需要:
1,参与硬件原理图设计的评审会
2,检查review pin mux/HSIS
软件需要提前阅读熟悉下面几个文档:
QAM8255P IVI Boot and CoreBSP Architecture Technical Overview
Qualcomm® Snapdragon Ride™ Platform Automotive Reference (SA8775P/SA8650P/SRV1H/SRV1M/SA8255P/ SA8620P/SA7255P) Vehicle Interface Processor (Aurix) User Guide)
SoC-MCU Protocol – Boot and Safety Status Messages
1,搭建好MCU的开发环境
2,熟悉MCU芯片的各项功能,编写控制GPIO驱动,SPI/UART通信驱动
3,熟悉MCU-SAIL之间的通信方式,握手机制,阅读相关的文档
1,准备好QNX的编译环境,下载好SDP包
2,下载8255 SDK软件包
3,编译好所有镜像文件
1,安装刷机软件,熟悉刷机流程
2,准备好相关的刷机工具,如USB线束等
MCU需要根据手册要求控制连接到PMIC的两个pin脚:PWR_EN和RESET。
这里的前提是MCU自己本身的bring-up已经完成!
这里我们就遇到了一些问题,在bring up MCU的时候,烧录完MCU的软件,重新上电之后发现MCU的晶振并没有起振。做了一些列的检查之后,发现硬件本身是没有问题的,问题出在软件上,这个MCU比较特殊,需要配置一些参数才能触发外部晶振起振(MCU内部自带一个时钟源)。
电源检测流程图:

下面的每一个步骤都是在上一个步骤完成的前提下进行的:
1,需要确保MCU自身bring up 完成
2,MCU完成对PWR_EN/RESET两个pin的控制之后,需要硬件确认所有的供电是否正常才能进行下一步
3,通过FORCE_USB pin强制让SOC进入下载模式
4,SOC进入下载模式后,连接USB CABLE到PC上,这个时候应该在PC上识别到com设备,如果没有观察到COM设备,请回去检查前面的步骤,需要注意的是进入下载模式的COM设备是不需要安装特别驱动就能识别到的!
5,打开烧录软件,烧录nor-flash,UFS,需要注意的是在烧录nor-flash时,需要先擦在写(这里我们踩过坑),UFS需要做一次provision。
6,如果烧录成功,那么刷机软件会有相应的提示,否则会提示错误,这里导致烧录失败的原因有很多,比如DDR的问题,线束的问题,供电的问题等等,可以说烧录成功是bring up成功的一个里程碑的节点。
MCU-SAIL之间需要有一些通信和握手,细节可以看下面这张图。

总结来说:
1,在MCU给SOC上电之后,MCU需要通过uart来查询SAIL的bootstatus,发送的数据帧格式长下面这样:

具体来说是:crc+cmd 0xB0 + 0x10 + 数据包长度64个字节 0x40 + 消息序列号,从0开始每次递增1 + data[0] ... data[58]. 下面是几个具体的发送帧示例:

数据包的总长度是64个字节
2,这个时候SAIL通常会返回一个256个字节数据帧来告诉MCU当前他的boot状态
一个正常的uart返回帧:

一个异常的返回帧:

需要注意的是,异常的时候返回的数据帧格式可能不是完全按照 第2点的帧格式返回的,但是也是可以解析出来哪里出了异常。比如上面返回的异常uart消息,我们可以按照协议解析出来哪里出了问题:

比如这里读回来的异常状态帧数据:00 A0 10 0C 00 F0 B1 40 00 00 0D E0 04 00 E2 FF FF FF
对应观察到的现象:
SAIL debug uart: 无任何输出
MD debug uart:输出下面日志之后,停住
- Format: Log Type - Time(microsec) - Message - Optional Info
- Log Type: B - Since Boot(Power On Reset), D - Delta, S - Statistic
- S - QC_IMAGE_VERSION_STRING=BOOT.MXF.1.2-00286-LEMANS-1
- S - IMAGE_VARIANT_STRING=SocLeMansAU
- S - OEM_IMAGE_VERSION_STRING=ip-10-195-204-120
- S - Boot Interface: UFS
- S - Secure Boot: Off
- S - Boot Config @ 0x00786064 = 0x000000c0
- S - JTAG ID @ 0x00786130 = 0x101cf0e1
- S - OEM ID @ 0x00786138 = 0x00000000
- S - Serial Number @ 0x00786134 = 0x2b1b8fbf
- S - OEM Config Row 0 @ 0x007841a8 = 0x0000000000000000
- S - OEM Config Row 1 @ 0x007841b0 = 0x0000000000400000
- S - Raw PTE Row 0 @ 0x00784158 = 0x300101cf
- S - Core 0 Frequency, 1632 MHz
- S - PBL Patch Ver: 2
- D - 8341 - pbl_apps_init_timestamp
- D - 35427 - bootable_media_detect_timestamp
- D - 953 - bl_elf_metadata_loading_timestamp
- D - 556 - bl_hash_seg_auth_timestamp
- D - 6396 - bl_elf_loadable_segment_loading_timestamp
- D - 4260 - bl_elf_segs_hash_verify_timestamp
- D - 3164 - bl_sec_hash_seg_auth_timestamp
- D - 826 - bl_sec_segs_hash_verify_timestamp
- D - 12 - pbl_populate_shared_data_and_exit_timestamp
- S - 59935 - PBL, End
- B - 67557 - SBL1, Start
- B - 198921 - SBL1 BUILD @ 14:24:59 on Sep 13 2023
- B - 203404 - usb: usb2phy: PRIM success , 0x4
- B - 206271 - usb: qusb_ldr_eud_init
- B - 210724 - usb: eud_serial_upd , 0x2b1b8fbf
- D - 12779 - sbl1_hw_init
- D - 0 - init_partition_ids
- D - 0 - boot_flashless_boot_init
- D - 0 - boot_sail_pbl_edl_check
- D - 4575 - sail_execute_bist_sequence
- B - 234057 - UFS Boot LUN: 1
- B - 243298 - UFS INQUIRY ID: KIOXIA THGJFGT0T25BAZZA0100
- D - 20130 - boot_media_init
- D - 0 - boot_check_recoveryinfo_partition
- D - 0 - boot_update_sbl_recovery_partition_ids
- B - 260470 - BOOT_BANK_A
- B - 265533 - Recovery: partition magic not set
- B - 268003 - Recovery: Info missing
- D - 12047 - boot_recovery_select_boot_partitions
- D - 0 - boot_recovery_partitions_info_imem_init
- D - 30 - boot_save_sbl_recovery_partition_info
- B - 285907 - SAIL SS - Image Load, Start
- D - 4849 - SAIL SS - Image Loaded, Delta - (0 Bytes)
- D - 0 - boot_recovery_media_partial_init_return
- D - 31 - boot_default_cdt_init
- D - 92 - boot_cdt_init
- B - 308660 - CDT - Image Load, Start
- D - 2745 - CDT - Image Loaded, Delta - (0 Bytes)
- D - 30 - shrm_load_cancel
- B - 320097 - SHRM - Image Load, Start
- D - 762 - Auth Metadata
- D - 1128 - Segments hash check
- D - 9577 - SHRM - Image Loaded, Delta - (35744 Bytes)
- D - 610 - Auth Metadata
- D - 5612 - sbl1_xblconfig_init
- D - 183 - sbl1_xcfg_sw_feature_config_init
- D - 0 - init-logstomedia
- D - 0 - sbl1_xcfg_process_bds_entry_flag
- B - 351848 - CDT Version:3,Platform ID:37,Major ID:1,Minor ID:0,Subtype:1
- D - 20709 - sbl1_hw_platform_pre_ddr
- D - 0 - devcfg init
- B - 382073 - PMIC A:2.0 B:2.0 C:2.0 D:2.0 E:2.0 F:2.0 G:2.0 H:2.0
- B - 493490 - PM: PSI: b0xe0_v0xd2
- B - 495991 - PM: Device Init # SPMI Transn: 2454
- D - 120628 - pm_device_init, Delta
- B - 501633 - pm_driver_init, Start
- B - 508557 - PM: Driver Init # SPMI Transn: 232
- D - 3477 - pm_driver_init, Delta
- B - 513223 - vsense_init, Start
- D - 0 - vsense_init, Delta
- B - 519964 - wait-for-bist, Start
- B - 523166 - waiting for SAIL to finish MD P2 BIST
对于异常帧数据的解析及定位原因
返回的异常帧数据为:00 A0 10 0C 00 F0 B1 40 00 00 0D E0 04 00 E2 FF FF FF
00 A0 10 0C 00 F0: 这段数据应该是有特殊含义的,但是目前手头上没这块手册,所以不知道具体含义。
B1: 对应的是上图DATA0 数据域
40:对应DATA1
00: 对应DATA2,表明CORE1/2/3均处于未RELEASE的状态,CORE1/2/3均未处于START状态
00:对应DATA3,同样表明每个CORE的EL1状态
0D:表明SAIL一直处于BIST状态,MD没有在BIST状态
总结来说:
1,SAIL上的CORE1/2/3均处于未运行的状态,很有可能只有CORE 0处于running状态
2,SAIL一直处于BIST状态,说明BIST失败或者没有办法进入下一个阶段
3,MD不处于BIST状态,可能为未运行或者已经完成了BIST
回到 《QAM8255P IVI Boot and CoreBSP Architecture Technical Overview》中对于boot的流程的说明:
1,在PMIC给SOC正确上电之后,SAIL_PBL&MD_PBL都会无条件运行
2,SAIL_PBL会负责load SAIL_HYP镜像,并且跳转到SAIL_HYP上
3,SAIL_HYP会负责load SAIL SW1/2/3镜像
4,需要注意的是,这个时候MD的core 0也是同时在跑的
5,从现象及异常帧数据,我们做进一步的推测和分析:
a, 由DATA3数据分析可知,当前SAIL应该处于EL0/EL2状态,不可能处于EL1
b, SAIL本身有几个阶段: PBL->HYP->SW1/2/3,现在出现异常的时候,很有可能处于HYP阶段。
c, MD已经打印了一部分日志,说明其很有可能已经处于XBL阶段

6,为了进一步确认到底SAIL处于哪一个阶段,我们做了一个实验,在EVB开发板上,将SAIL 的nor-flash全部擦除,这个时候重新上电板子发现MD的debug uart完全没有日志输出
7,从step6的实验可以得到,SAIL至少处于HYP阶段,或者HYP阶段已经完成,这个结论能解释的通前面所有的现象。
8,SAIL_HYP没有切换到SAIL SW1/2/3,可能的原因有几个:
a, SW1/2/3镜像数据不完整
b, SW1/2/3软件有异常,运行报错
9,刷写的SAIL的软件镜像和EVB板是一模一样的,为了确认数据是否正常,我们尝试使用QFILE软件将nor-flash上的数据读取出来,与原始烧录/EVB nor-flash上的数据进行对比
10,读取得到的数据发现了异常,发现只有HYP的分区数据是正确的,SW1/2/3读取得到的数据均和EVB读回来的数据不一致。
11,重新对nor-flash进行先擦写,再烧录,确保刷写完成的数据与EVB无异之后,MD正常在debug uart正常输出日志,系统能够正常启动,QNX可以正常启动,QVM可以bring up android系统,但是无法进入launcher,屏幕无任何输出。
12,反思:重新回顾烧录的步骤,我们发现中间忽略了一个比较重要的操作,即对nor-flash烧录缺少了关键的步骤:全盘擦除,这个缺失的步骤导致后续一连串的异常。
细节可以参考《对于异常帧数据的解析及定位原因》的描述,但是有一个问题需要读者认真思考的:
对于一个完全空的SOC/UFS,首次上电SOC是否能输出日志?比如8255,如果nor-flash/UFS完全没有烧录,是否会有PBL的日志输出?又比如8155,如果UFS完全没有烧录,在UFS boot的模式下,PBL是否有日志输出到uart上?
MD可以正常启动QNX之后,发现SAIL端的debug uart 完全没有日志输出,且VIP-SAIL之间的uart不在有更多的uart帧数据输出,这个现象与EVB完全不同(EVB会不停的发送uart帧数据到VIP)
针对这个现象,我们重新检测了VIP的软件,发现其中对board id check这个环节是缺失的,这个环节的缺失导致了SAIL停止在uart口上输出数据
更新VIP软件增加对board id check功能之后,SAIL debug uart & SAIL-VIP uart可以正常输出数据了
细节参考《对于异常帧数据的解析及定位原因》的描述。
需要注意的是,QNX bring up之后需要确认一下,系统都正常启动了那些进程,这些进程和EVB的进程对比,是否有差异,差异是否合理等等。
我们在bring up QNX遇到的第一个问题是openwfd_server无法正常启动,原因在于我们自己的板子和EVB硬件上有很多的不同,所以需要修改一部分的软件保证QNX的display 显示驱动框架能正常启动。
主要修改的是qcdisplay.xml这个配置文件,对当中的client&port阶段进行修改。
QNX 显示驱动框架bring up成功的标志是:
1,openwfd_server能够正常运行
2,screen能够正常运行
3,ssplash/齿轮测试程序能够正常出图
这块我们也经历了很多,这里就不展开了。
这里的bring up的阶段基本上是要看下logcat的日志,看下那些关键服务产生crash,进行修改即可。
我们遇到的最主要的问题有两个:
1,surfaceflinger无法找到display,与QNX的显示驱动框架&DPU资源分配有关
2,system_server报WCG not support,与qcdisplay.xml资源分配有关,android拿到的display只有External类型,没有internal的display
这两个问题都解决之后,系统可以正常进入launcher
Great!