在复杂SoC设计中,内存保护单元(MPU)是确保系统安全性的第一道防线。CMN-600AE作为Arm CoreLink系列中的一致性网状网络控制器,其MPU模块采用分层保护机制,通过硬件级访问控制实现以下核心功能:
关键设计要点:所有MPU寄存器必须通过安全访问(Secure Access)配置,且在首次非配置访问前完成初始化,否则会产生配置锁定保护。
以por_mpu_m1_prbar9为例,其64位寄存器分为高低两部分:
高位字段(bits[63:32]):
markdown复制| 位域 | 字段名 | 功能描述 | 类型 | 复位值 |
|-----------|---------------------|----------------------------|------|--------|
| 63:48 | Reserved | 保留位 | RO | - |
| 47:32 | region9_base_addr | 基地址[47:32] | RW | 16'b0 |
低位字段(bits[31:0]):
markdown复制| 位域 | 字段名 | 功能描述 | 类型 | 复位值 |
|-----------|---------------------|----------------------------|------|--------|
| 31:12 | region9_base_addr | 基地址[31:12] | RW | 20'b0 |
| 11:10 | Reserved | 保留位 | RO | - |
| 9 | region9_br | 背景区域指示(1=背景区域) | RW | 1'b0 |
| 8:6 | Reserved | 保留位 | RO | - |
| 5:2 | region9_ap | 访问权限控制位 | RW | 4'b0 |
| 1:0 | Reserved | 保留位 | RO | - |
访问权限位(AP)具体解码:
c复制ap[0]: NW (Non-secure Write) // 非安全写权限
ap[1]: SW (Secure Write) // 安全写权限
ap[2]: NR (Non-secure Read) // 非安全读权限
ap[3]: SR (Secure Read) // 安全读权限
对应por_mpu_m1_prlar9寄存器:
高位字段(bits[63:32]):
markdown复制| 位域 | 字段名 | 功能描述 | 类型 | 复位值 |
|-----------|---------------------|----------------------------|------|--------|
| 63:48 | Reserved | 保留位 | RO | - |
| 47:32 | region9_limit_addr | 限界地址[47:32] | RW | 16'b0 |
低位字段(bits[31:0]):
markdown复制| 位域 | 字段名 | 功能描述 | 类型 | 复位值 |
|-----------|---------------------|----------------------------|------|--------|
| 31:12 | region9_limit_addr | 限界地址[31:12] | RW | 20'b0 |
| 11:1 | Reserved | 保留位 | RO | - |
| 0 | region9_en | 区域使能位(1=启用) | RW | 1'b0 |
计算地址对齐:
python复制# 基地址必须64KB对齐
base_addr = 0x80000000 & ~(0xFFFF)
# 限界地址=末地址+1,且必须大于基地址
limit_addr = (base_addr + region_size - 1) | 0xFFFF
寄存器写入序列:
c复制// 配置PRBAR9
WRITE_REG(0x14A0, (base_addr >> 32) & 0xFFFF); // 写入高位
WRITE_REG(0x14A4, (base_addr & 0xFFFFF000) |
(1 << 9) | // 设置BR位
(0xB << 2)); // AP=1011(安全R/W,非安全R)
// 配置PRLAR9
WRITE_REG(0x14A8, (limit_addr >> 32) & 0xFFFF); // 写入高位
WRITE_REG(0x14AC, (limit_addr & 0xFFFFF000) |
1); // 使能区域
配置验证:
armasm复制; 尝试访问保护区域
LDR R0, =0x80010000
LDR R1, [R0] ; 应成功读取
STR R1, [R0] ; 在非安全态应触发异常
常用AP配置模式:
| AP值 | 二进制 | 权限说明 | 适用场景 |
|---|---|---|---|
| 0xC | 1100 | 安全R/W,非安全无访问 | 安全关键数据区 |
| 0xA | 1010 | 安全R/W,非安全只读 | 安全至非安全共享数据 |
| 0x8 | 1000 | 安全只读,非安全无访问 | 安全代码区 |
| 0x0 | 0000 | 完全无访问权限 | 隔离区域 |
地址未对齐:
错误现象:写入寄存器后使能位自动清零
解决方案:确保基地址bits[15:0]=0,限界地址bits[15:0]=0xFFFF
权限冲突:
c复制// 错误配置:安全写使能但非安全读禁止
ap_config = 0x9; // 1001
// 正确配置:安全写必须配套安全读
ap_config = 0xB; // 1011
初始化顺序错误:
markdown复制正确流程:
1. 配置所有PRBARx/PRLARx寄存器
2. 最后统一设置使能位
3. 执行DSB/ISB屏障指令
区域重叠处理:
缓存一致性:
armasm复制; 配置后执行缓存维护
DMB SY
DSB SY
ISB
调试接口:
python复制# 通过APB接口读取当前配置
def read_mpu_config(region):
bar_hi = read_reg(0x1400 + region*0x10)
bar_lo = read_reg(0x1404 + region*0x10)
lar_hi = read_reg(0x1408 + region*0x10)
lar_lo = read_reg(0x140C + region*0x10)
return (bar_hi << 32 | bar_lo, lar_hi << 32 | lar_lo)
在ISO 26262 ASIL-D系统中,建议采用以下安全配置模式:
关键数据保护:
c复制// ECC校验区配置(仅安全访问)
#define ECC_REGION 12
WRITE_MPU_REG(ECC_REGION,
0xE0000000, // 基地址
0xE00FFFFF, // 限界地址
AP_SECURE_RW);
故障注入测试:
python复制# 验证MPU保护有效性
def test_mpu_lock():
try:
write_memory(0xE0001000, 0xDEADBEEF) # 应触发异常
return "FAIL"
except SecurityError:
return "PASS"
运行时验证机制:
c复制// 定期检查关键区域配置
bool verify_mpu_config(void) {
uint64_t expected_bar = 0xE0000000ULL;
uint64_t actual_bar = read_mpu_bar(ECC_REGION);
return (actual_bar == expected_bar);
}
通过这种细粒度的内存访问控制,CMN-600AE的MPU能够有效防止以下安全威胁: