NVMe-eMMC Bridge 芯片固件开发(一):硬件和软件架构

1. 项目背景

本系列文章将详细介绍一款 NVMe-eMMC Bridge 芯片(BayBridge) 的固件开发实践。该芯片的核心功能是将 NVMe/PCIe 协议转换为 eMMC 协议,使 eMMC 存储模组能够以 NVMe 设备的形态呈现给主机系统。

1.1 典型应用场景

  • NAS 存储系统:采用 eMMC 作为系统盘,通过 PCIe 接口连接
  • 游戏掌机:如 Steam Deck,需要高速存储但成本敏感
  • 嵌入式计算:龙芯等国产平台的存储解决方案
  • 消费电子:HP、Lanner 等品牌的终端产品

1.2 芯片核心参数

参数 规格
CPU 架构 SPARC LEON2
CPU 主频 100MHz (ASIC) / 50MHz (FPGA)
片上 RAM 160KB
PCIe 接口 PCIe 3.0 x1
eMMC 接口 2 个 eMMC 5.1 通道
支持协议 NVMe 1.4

2. 硬件架构

2.1 整体架构框图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
+------------------------------------------------------------------+
| Host (x86/ARM) |
+------------------------------------------------------------------+
|
PCIe 3.0 x1
|
+------------------------------------------------------------------+
| BayBridge SoC |
| +------------------------------------------------------------+ |
| | PCIe Controller | |
| | - NVMe Controller Registers (BAR0) | |
| | - MSI/MSI-X Interrupt Controller | |
| | - DMA Engine (DMA0, DMA1) | |
| +------------------------------------------------------------+ |
| | |
| +------------------------------------------------------------+ |
| | SPARC LEON2 CPU | |
| | - 100MHz Core Clock | |
| | - Instruction/Data Cache | |
| | - Hardware Multiply/Divide | |
| +------------------------------------------------------------+ |
| | |
| +------------------------------------------------------------+ |
| | On-Chip SRAM (160KB) | |
| | - 0x40000000: Code + Data + BSS | |
| | - Stack: RAM Top - 1KB | |
| | - Parameters: Top 1KB Reserved | |
| +------------------------------------------------------------+ |
| | |
| +---------------------------+---------------------------+ |
| | eMMC Host 0 | eMMC Host 1 | |
| | - HS400 Support | - HS400 Support | |
| | - Command Queuing | - Command Queuing | |
| +---------------------------+---------------------------+ |
+------------------------------------------------------------------+
| |
eMMC Card 0 eMMC Card 1

2.2 地址空间映射

SPARC LEON2 采用大端模式(Big Endian),地址空间划分如下:

1
2
3
4
5
6
7
// 核心地址定义 (from register.h)
#define BAYBRIDGE_WORKRAM_BASE 0x40000000 // 160KB RAM
#define BAYBRIDGE_NVME_CONTROLLER_BASE 0x30200000 // NVMe 控制器寄存器
#define BAYBRIDGE_CONTROL_BASE 0x30000000 // 芯片控制寄存器
#define BAYBRIDGE_PCI_CFG_BASE 0x30100000 // PCIe 配置空间
#define BAYBRIDGE_SD_EMMC_HOST_BASE 0x33000000 // eMMC 主控寄存器
#define BB_ROM_BASE 0x50000000 // ROM 存储(可选)

2.3 中断系统

SPARC LEON2 采用分级中断控制器架构:

1
2
3
4
5
6
7
8
9
10
11
// 中断向量定义
#define IRQ_TIMER0 10 // 定时器 0
#define IRQ_TIMER1 12 // 定时器 1
#define IRQ_BB_INTERNAL 14 // BayBridge 内部中断

// 内部中断状态位
#define CMD_BUFFER0_READ_READY_INTERRUPT_STATUS_BIT BIT0
#define CMD_BUFFER1_READ_READY_INTERRUPT_STATUS_BIT BIT1
#define DMA0_INTERRUPT_STATUS_BIT BIT2
#define DMA1_INTERRUPT_STATUS_BIT BIT3
#define DATA_TRANSFER_COMPLETE_INTERRUPT_STATUS_BIT BIT4

3. 软件架构

3.1 固件分层设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
+--------------------------------------------------+
| Application Layer |
| - NVMe Command Processing |
| - Namespace Management |
| - Power Management (L1.2/APST) |
+--------------------------------------------------+
| Protocol Layer |
| - NVMe Admin Command Set |
| - NVMe IO Command Set (Read/Write/Flush) |
| - eMMC Command Queue (CQ Mode) |
+--------------------------------------------------+
| Driver Layer |
| - DMA Controller Driver |
| - eMMC Host Controller Driver |
| - Timer/Watchdog Driver |
+--------------------------------------------------+
| BSP Layer |
| - Interrupt Controller |
| - UART Debug Print |
| - GPIO/Pinshare |
+--------------------------------------------------+
| Bootloader |
| - CPU Register Init |
| - Firmware Load (SPI Flash/eMMC Boot) |
| - Secure Boot (SHA256/MD5) |
+--------------------------------------------------+

3.2 源码目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
baybridge/
├── src/
│ ├── boot/ # Bootloader 源码
│ │ ├── boot.S # 汇编启动代码
│ │ ├── boot_route.c # 启动路由逻辑
│ │ ├── boot_card.c # eMMC Boot 支持
│ │ └── firmware_downloader.c # 固件下载器
│ │
│ ├── system/ # 系统层
│ │ ├── bsp/ # BSP 驱动
│ │ ├── trap/ # 中断/异常处理
│ │ ├── libc/ # C 库函数
│ │ └── init_sys.c # 系统初始化
│ │
│ ├── nvme/ # NVMe 协议实现
│ │ ├── main.c # Firmware 主循环
│ │ ├── controller.c # NVMe 控制器核心
│ │ ├── identify.c # Identify 命令
│ │ ├── read_write.c # IO 命令处理
│ │ ├── emmc_read_write.c # eMMC CQ 模式读写
│ │ └── power_manage.c # 电源管理
│ │
│ └── inc/ # 头文件
│ ├── config.h # 编译配置
│ ├── controller_register.h # 寄存器定义
│ └── command_queue.h # 命令队列结构

├── lds/ # 链接脚本
│ ├── boot_rom.lds # ROM 版 Bootloader
│ ├── boot_flash.lds # SPI Flash 版 Bootloader
│ └── fw_sys.lds # Firmware 链接脚本

├── config/ # 配置文件
│ ├── build.def # 编译配置
│ ├── customer.cfg # 客户定制参数
│ └── defs/ # 批量编译配置

└── Makefile # 构建脚本

3.3 内存布局设计

固件运行时的 RAM 布局(fw_sys.lds):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
0x40000000                              0x40028000 (160KB)
| |
+----------------------------------------+
| .common_text (Code + rodata) |
+----------------------------------------+
| .data (Initialized) |
+----------------------------------------+
| .bss (Uninitialized) |
+----------------------------------------+
| |
| Free Space |
| |
+----------------------------------------+
| Stack Space |
+----------------------------------------+ 0x40027C00 (%sp)
| Frame Pointer Space |
+----------------------------------------+ 0x40027C80 (%fp)
| Parameter Block (1KB) |
+----------------------------------------+ 0x40028000

关键设计点:

  • 栈顶预留 1KB:存储从 SPI Flash 拷贝的 Firmware Header 参数
  • 16 字节对齐:满足 SPARC 栈帧对齐要求
  • BSS 清零:Bootloader 负责初始化 BSS 段

3.4 编译构建系统

使用 SPARC ELF 交叉编译工具链

1
2
3
4
5
6
7
8
9
10
11
# 工具链配置 (Makefile)
CROSS_COMPILE := sparc-elf-
CFLAGS = -c -O3 -Wall -msoft-float -mv8

# 编译目标
# 1. libnvme.a - NVMe 协议实现库
# 2. libsys.a - 系统/BSP 库
# 3. boot_rom.bin - ROM 固化 Bootloader
# 4. boot_flash.bin - SPI Flash Bootloader
# 5. fw_sys.bin - Firmware 主体
# 6. bootFwSys_flash_checksumed.bin - 完整固件镜像

构建流程:

1
2
3
4
5
# 单次编译
./make.sh stg=mp_asic

# 批量编译(生成多个客户版本)
./build_All.sh stg=mp_asic

4. 数据流架构

4.1 NVMe 读操作数据流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Host Memory                    BayBridge                     eMMC
| | |
| 1. Write to SQ Doorbell | |
|----------------------------->| |
| | 2. Fetch NVMe CMD (DMA) |
| | 3. Parse CMD, Add to Task Queue
| | |
| | 4. CMD44/45 Set Task |
| |-------------------------->|
| | 5. CMD13 Query Status |
| |-------------------------->|
| |<--------------------------|
| | 6. CMD46 Execute Read |
| |-------------------------->|
| |<=========================>| (Data Transfer)
|<============================| |
| 7. DMA Write to Host Memory | |
| | |
|<-----------------------------| |
| 8. CQ Completion Entry | |

4.2 关键数据结构

任务队列结构(用于 NVMe 到 eMMC 命令转换):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// command_queue.h
typedef struct {
u64 prp1; // Host 内存 PRP Entry 1
u64 prp2; // Host 内存 PRP Entry 2 或 PRP List
u64 address; // eMMC 逻辑扇区地址
u16 block_len; // 数据块数量
u16 nvme_sq_id; // 来源 SQ ID
u16 nvme_cmd_id; // NVMe 命令 ID
u8 direction; // 0: Read, 1: Write
u8 fused_flag; // Fused 命令标记
u8 next_pointer; // Fused 命令链表指针
u8 start_card; // 起始 eMMC 卡号
} task_info_struct;

// 任务状态定义
#define EMPTY 0x00 // 空闲槽位
#define PRE_CANDIDATE 0x01 // 预候选(刚加入)
#define CANDIDATE 0x02 // 候选(已下发 CMD44/45)
#define EXECUTING 0x03 // 执行中
#define COMPLETED 0x04 // 已完成
#define ERR_STATUS 0x7F // 错误状态

5. 关键技术特性

5.1 双 eMMC 支持

芯片支持两个 eMMC 通道,可配置为多种模式:

1
2
3
4
5
6
7
8
9
// Namespace 到 eMMC 映射模式
typedef enum {
DOUBLE_EMMC_TOTAL_NS, // 两个 eMMC 合并为单个 Namespace
DOUBLE_EMMC_DOUBLE_NS, // 两个 eMMC 映射为两个 Namespace
SINGLE_EMMC0_SINGLE_NS, // 仅使用 eMMC0
SINGLE_EMMC1_SINGLE_NS, // 仅使用 eMMC1
DOUBLE_EMMC_HIDE_NS0, // 隐藏 Namespace 0
DOUBLE_EMMC_HIDE_NS1, // 隐藏 Namespace 1
} ns_emmc_map_case;

5.2 PCIe 电源管理

支持完整的 PCIe L1.2 低功耗状态:

1
2
3
4
5
6
7
8
9
// 电源状态控制 (power_manage.c)
#define ID_KEEP_L0 0 // 保持 L0 状态
#define ID_KEEP_PLL_ACTIVE 1 // 保持 PLL 激活
#define ID_FW_STATUS 2 // Firmware 忙/空闲状态
#define ID_PWR_STATE 3 // NVMe Power State (PS0/PS1)

// LTR (Latency Tolerance Reporting) 配置
#define FAST_LTR_VALUE 0x083b883b // 快速 LTR
#define SLOW_LTR_VALUE 0x0c5c8c5c // 慢速 LTR

5.3 Secure Boot

支持固件完整性校验:

1
2
3
4
// Firmware Checksum 校验
// 1. Bootloader 阶段:奇偶校验(Parity Check)
// 2. Firmware 加载后:XOR Checksum 验证
// 3. 可选:SHA256/MD5 签名验证

6. 开发调试工具

6.1 调试接口

  • UART 串口:波特率 115200,用于 LOG 输出
  • JTAG:SPARC DSU (Debug Support Unit) 接口
  • GPIO Monitor:支持 4 路 GPIO 输出调试信号

6.2 调试宏控制

1
2
3
4
5
// config.h
#define BB_DEBUG_LEVEL 1 // 0: ERROR, 1: KEY_INFO, 2: POSITION, 3: ALL
#define TEST_BOOT_TIMING 0 // 启动时间测量
#define TEST_RAM_SPACE 0 // RAM 空间压力测试
#define TEST_FW_STATUS 1 // FW 状态监控

7. 总结

BayBridge 芯片固件采用经典的嵌入式分层架构设计:

  1. 硬件抽象:BSP 层屏蔽底层硬件差异
  2. 协议解耦:NVMe 和 eMMC 协议栈独立实现
  3. 内存优化:精心设计的内存布局,充分利用 160KB RAM
  4. 低功耗:完整支持 PCIe L1.2 和 APST 电源管理

后续文章将深入各个模块的实现细节,包括:

  • Bootloader 启动流程
  • NVMe 协议栈实现
  • eMMC Command Queuing 优化
  • 固件空间和性能优化技术

参考资料

  • NVMe Base Specification 1.4
  • eMMC Specification JEDEC JESD84-B51
  • SPARC Architecture Manual V8
  • LEON2 Processor User’s Manual