结论:AMDev 的启动不是一条固定路径,而是先读 IP discovery 再分流:scratch7 等于 AMDev.Version 且未请求 AM_RESET 时才初步允许部分启动,scratch6 非零或 GC 保护故障寄存器非零通常退回完整启动,GC 9.5.0 的既有 AM 状态反而再次强制部分启动以避免完整启动损伤互连。完整启动按 SOC→GMC→IH→PSP→SMU 初始化,两条路径最终都重建 GFX 与 SDMA,VF 会跳过 PF 专属的 PSP 与 SMU。启动标记只表示 AM 自身的阶段完成,不代表模型已编译、GPU 队列已成功执行或已获车辆控制权。本文为固定归档 amdev.py 与 ip.py 的静态阅读,未打开 PCI/USB、未刷写固件、未碰 GPU/车辆/CAN。
启动顺序与实际分支
AMDev.__init__() 先处理 PCIe ASPM,映射 VRAM、doorbell 与 MMIO,判断 VF 并请求访问窗口;随后 _run_discovery() 从 VRAM 末端读取 IP discovery、harvested 实例与版本/基址,再由 _build_regs() 生成寄存器对象及可访问的 AID 集合。_run_discovery() 仅检查两类 signature,仍直接按表内偏移与数量做 ctypes 地址遍历,固件或设备损坏场景下需要台架注入验证长度边界,不能把它视为不可信数据解析沙箱。
init_sw() 建内存管理器、固件目录和七个 IP 实例,按 SOC、GMC、IH、PSP、SMU、GFX、SDMA 顺序对每个组件调用 init_sw()。scratch7 匹配且未请求 AM_RESET 时,才初步允许部分启动;若 scratch6 非零或 GC 保护故障寄存器非零,通常退回完整启动。完整启动如检测到存活的 PSP/SMU,可能先做 mode1 reset;hive 多卡状态要求另行复位。之后完整启动按 SOC→GMC→IH→PSP→SMU 初始化,VF 跳过 PF 专属的 PSP/SMU;部分启动沿用底层状态,非 VF 会重新初始化 TMR;两路最终都初始化 GFX→SDMA。
| 判定条件 | 走向 | 说明 |
|---|---|---|
scratch7 == AMDev.Version 且未请求 AM_RESET |
初步允许部分启动 | 沿用底层状态,非 VF 重新初始化 TMR |
scratch6 非零或 GC 保护故障寄存器非零 |
退回完整启动 | 可能先做 mode1 reset |
| GC 9.5.0 的既有 AM 状态 | 强制部分启动 | 避免完整启动损伤互连 |
| VF 模式 | 跳过 PF 专属 PSP/SMU | 经访问窗口获得并释放租约 |
| 两路共同收尾 | GFX→SDMA | 配置功耗/时钟与 clock gating,写启动标记 |
启动尾部对非 VF 配置功耗/时钟与 clock gating,再写 scratch5(TMR 大小)、scratch7(AM 版本)和 scratch6=1。reset_mode=True 的 hive 异常分支可提早返回,因此调用者不能仅以构造函数返回推断所有初始化阶段完成。
七个 IP 的入口与职责
| 子组件 | 主要入口 | 本层职责与风险边界 |
|---|---|---|
AM_SOC |
init_sw()、init_hw()、doorbell_enable() |
选 SoC/中断源元数据、设置 NBIO/doorbell;门铃可达不等于队列完成 |
AM_GMC |
init_hub()、enable_vm_addressing()、flush_tlb() |
计算 FB/MC/XGMI/VA 范围,初始化页表与 TLB;错误映射可能影响所有 GPU 内存访问 |
AM_IH |
init_hw()、interrupt_handler()、drain() |
启动 IH ring,解析 SQ/VM fault/RAS,设置 is_err_state;日志打印不是自动恢复 |
AM_PSP |
init_hw()、_ring_submit()、_load_ip_fw_cmd() |
启动 sOS、创建命令 ring、设置 TMR 并加载各 IP 固件;固件来源、哈希与响应状态是独立验收门 |
AM_SMU |
_send_msg()、mode1_reset()、set_clocks() |
电源/时钟/重置消息,按 IP 版本选协议;超时与电源策略不能由模型插件自行决定 |
AM_GFX |
init_hw()、reset_mec()、setup_ring()、fini_hw() |
初始化 GC hub/MEC,配置 MQD/HQD 与计算 ring;部分启动只重置 MEC |
AM_SDMA |
init_hw()、setup_ring()、fini_hw() |
按 SDMA 版本配置 watchdog、doorbell、copy ring 与关闭路径;传输完成与计算完成不是同一事件 |
内存侧还有一条必须保持的先后关系:AMMemoryManager.on_range_mapped() 在页表变更后依次请求 GC 和 MM TLB flush,AM_GMC.flush_tlb() 会先做 HDP flush,未初始化 hub 则返回,VF 与常规路径的 invalidation/ACK 不同。插件若要抽象 GPU 内存,必须保持映射、TLB、队列提交的先后关系,不能只替换分配器。
停机、恢复与未验证项
AMDev.fini() 先在 VF 需要时请求访问窗口,只对 SDMA/GFX 调用 fini_hw(),再调低时钟、处理 IH、写 scratch6 并释放 VF 租约;它不是逐一销毁七个 IP 或解除所有 BAR 与固件状态。recover() 只在错误态或 force=True 时处理 IH 并重置 MEC,不能等同于 PCI 热复位、全卡重新发现或固件重验。本专题没有运行 AMD/AM 单元测试或真机驱动,初始化寄存器表、PSP 固件加载、SMU 响应、IH 故障与内存一致性需要单独台架验证;AMDev.__init__() 的多阶段初始化没有包裹通用清理块,若中间异常,已映射资源、VF 租约和部分配置如何回退应通过故障注入确认。此外,VF 与 PF 模式、hive 多卡状态以及 GC 9.5.0 的强制部分启动分支,都不能用一块普通单卡的测试结果替代——它们各自有独立的复位路径与访问租约,验收时必须分别覆盖。
自制车载硬件的插件边界
应把 AMDev/IP 层限定为受信任的计算设备驱动,而不是任意动态插件。硬件适配需声明 PCI/USB 身份、BAR 布局、IP 发现表版本、固件哈希、PF/VF 模式、AID/XCC/harvest 信息、内存与 TLB 语义、队列和中断超时。验证顺序为只读发现与固件校验、独立台架冷/暖启动和异常回滚、GPU 队列与内存数值回归、车端只读观察;每一步单独上报设备在线、固件准备、队列可提交、任务完成与模型输出有效,任何状态都不得绕过车型 CAN 编码或 panda 安全钩子。
常见问题
AM 启动后 scratch6=1 代表什么?
它只是 AM 自身的启动标记之一,与 scratch5(TMR 大小)、scratch7(AM 版本)一起写入。它不表示任何模型已编译、GPU 队列已成功执行或系统已获车辆控制权限,因此不能把标记写入当作端到端就绪。
什么情况下会走部分启动,什么情况下退回完整启动?
scratch7 等于 AMDev.Version 且未请求 AM_RESET 时才初步允许部分启动;scratch6 非零或 GC 保护故障寄存器非零通常退回完整启动。GC 9.5.0 的既有 AM 状态是例外,会再次强制部分启动以避免完整启动损伤互连。
recover() 等于把 GPU 重新初始化一遍吗?
不等于。recover() 只在错误态或 force=True 时处理 IH 并重置 MEC,它不能等同于 PCI 热复位、全卡重新发现或固件重验;AMDev.fini() 也只对 SDMA/GFX 调用 fini_hw(),并非逐组件销毁。
为什么说队列可达不等于任务完成?
因为各层完成点是分开的:AM_SOC 的 doorbell 可达、AM_SDMA 的传输完成与 GPU 计算完成都不是同一事件,IH 打印故障日志也不等于自动恢复。上报时应把设备在线、固件准备、队列可提交、任务完成与模型输出有效分开记录。
延伸阅读
- tinygrad Chestnut USB 与 AMD 桥接 —— 承接本文 AM 层在设备接入中的上游位置。
- tinygrad Qualcomm KGSL 运行时 —— 对照另一加速器后端的选择与生命周期边界。
- tinygrad JIT 捕获与回放 —— 说明 GPU 计算图在上层的捕获时机与本文队列完成的区分。
- tinygrad 数据类型与 uop 下沉模拟 —— 解释模型算子如何落到本文的 GFX/SDMA 队列。
- 进程生命周期、通信与设备服务 —— 说明设备驱动与进程管理层的分工。
参考资料
- 项目 02 ——
openpilot-research/TINYGRAD_AM_DEVICE_IP_BOOT_PARTIAL_RESET_LIFECYCLE_DEEP_DIVE.md(取用了启动顺序、完整与部分启动分支、七个 IP 入口、停机恢复与硬件插件边界)。 - 项目 02 ——
openpilot-research/TINYGRAD_AM_GMC_VM_PTE_TLB_COHERENCY_DEEP_DIVE.md(仅用于确认 TLB flush 与页表变更的先后关系)。
说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11
发表回复