1. 项目概述与ISC核心价值
在嵌入式系统,尤其是像TI AM64x/AM243x这类高性能多核异构处理器上,系统互连(System Interconnect)的设计直接决定了整个SoC的“交通秩序”和“安全等级”。你可以把它想象成一个高度复杂的城市交通网络,处理器核心、DSP、各种加速器和外设(如PCIe、USB、以太网)就是城市里不同功能的建筑,而数据包就是穿梭其间的车辆。如果没有一套精密的交通规则和安检系统,整个城市很快就会陷入混乱,甚至发生严重的安全事故。ISC(Interconnect Security Controller)模块,就是这个网络中的核心“交通管制与安全中心”。
我接触过不少项目,初期因为对互连配置理解不深,要么是性能瓶颈莫名其妙,要么是某个核心突然访问了不该访问的内存区域导致系统崩溃,调试起来极其痛苦。AM64x/AM243x的ISC提供了一套非常精细的寄存器级控制方案,允许我们为不同的“道路区间”(即内存区域)设置专属的“通行证”(Privilege ID)、“安检级别”(Secure/Non-secure属性)以及“车道规则”(访问权限)。理解并正确配置这些寄存器,是从“能让系统跑起来”到“能让系统跑得既快又稳又安全”的关键一步。本文就将深入这些寄存器的细节,结合实战经验,为你拆解ISC区域控制的配置逻辑、常见陷阱以及最佳实践。
2. ISC区域控制寄存器深度解析
要驾驭ISC,首先得读懂它的“控制面板”——也就是那一组组控制寄存器。AM64x/AM243x的ISC为每个主设备(Master)的每个区域(Region)都提供了一套独立的寄存器组,主要包括控制寄存器(CONTROL)、起始地址寄存器(START_ADDRESS_L/H)和结束地址寄存器(END_ADDRESS_L/H)。我们以资料中提到的ISC_IPCIE_G2X1_64_MAIN_0_PCIE_MST_RD_ISC_REGION_0_CONTROL寄存器为例,进行逐比特位的剖析。
2.1 控制寄存器(CONTROL Register)位域详解
控制寄存器是区域配置的灵魂,它定义了匹配到该区域后,数据事务(Transaction)将被施加何种属性转换和规则。其复位值通常为0xB300(对于非默认区域),这个默认值本身就隐含了TI的默认安全策略。
权限属性控制位(PRIV/NOPRIV, Bit 25-24, 27-26)
- PRIV (Bit 25:24): 设置输出事务的Privilege属性。这是一个2比特字段,每一位对应事务中Priv位的一个比特。若某位被写1,则输出事务对应的Priv位将被强制设为1(即提升为特权访问)。
- NOPRIV (Bit 27:26): 清除输出事务的Privilege属性。同样为2比特。若某位被写1,则输出事务对应的Priv位将被强制清零(即降级为非特权访问)。
- 核心逻辑与冲突规避:这里有一个至关重要的设计:PRIV和NOPRIV的同一比特位不能同时被设置为1。例如,你不能同时设置
PRIV[0]=1和NOPRIV[0]=1,这会导致未定义行为。硬件通常会有保护机制,但软件配置时必须避免。其作用是实现权限的强制升级或降级。例如,一个非特权(User mode)发起的访问,经过ISC区域匹配后,可以通过设置PRIV位,使其以特权(Supervisor mode)身份访问目标从设备,这常用于操作系统内核访问硬件资源。反之,也可以将特权访问降级,用于某些沙盒或隔离场景。
安全属性控制位(SEC/NONSEC, Bit 19:16, Bit 20)
- SEC (Bit 19:16): 这是一个4比特字段,但起作用的是一种特殊编码。只有当该字段被写入
0xA时,输出事务的Secure属性才会被强制设置为1(安全事务)。写入其他任何值,此字段不起作用,事务的Secure属性保持不变或由其他逻辑决定。 - NONSEC (Bit 20): 单比特控制。当此位被写1时,输出事务的Secure属性被强制清零(非安全事务)。
- 安全域转换机制:与PRIV/NOPRIV类似,SEC和NONSEC位也不能同时有效。你不能在设置
SEC=0xA的同时又设置NONSEC=1。这个机制是实现芯片内安全世界(Secure World)与非安全世界(Non-secure World)隔离的关键。例如,当非安全世界的主设备(如一个普通应用处理器)需要访问安全资源时,可以通过一个特定的ISC区域,将其发起的非安全事务“转换”为安全事务,从而获得访问权限。反之,也可以将安全事务转换为非安全事务以访问共享资源。
PrivID替换控制位(PASS/PRIV_ID, Bit 21, Bit 15:8)
- PASS (Bit 21): 此位控制PrivID的传递行为。当
PASS=1时,输入事务自带的PrivID将直接“透传”到输出,ISC不做修改。当PASS=0时,输入事务的PrivID将被PRIV_ID字段的值替换。 - PRIV_ID (Bit 15:8): 一个8比特的PrivID值。当
PASS=0时,它将成为输出事务的PrivID。 - 访问权限精细化管理的核心:PrivID是SoC内部用于标识和区分不同主设备或主设备上下文(Context)的标签。通过ISC的替换机制,我们可以实现复杂的访问策略。例如,多个不同的非安全主设备(PrivID各异)在访问同一个安全外设时,我们可以将它们映射到同一个ISC区域,并统一将其PrivID替换为一个固定的、被目标外设认可的ID(比如
0xB3,正如复位值所示)。这样,目标外设只需识别一个PrivID,简化了其访问控制逻辑,而在ISC层面则实现了集中的权限映射和管理。
区域功能控制位(DEF, CH_MODE, LOCK, ENABLE, Bit 6, 5, 4, 3:0)
- DEF (Bit 6): 默认区域指示位。这是一个只读位(R),由硬件固定。对于某个主设备的最后一个区域(通常是Region 15或31,取决于设计),此位会被硬件置1,表示该区域为“默认区域”。当发起的事务地址未能匹配任何其他已使能的区域时,就会落入这个默认区域,并应用其配置的属性。这是一个重要的安全兜底机制,确保所有未明确映射的访问都有确定的归宿,而不是导致总线错误或不可预测行为。
- CH_MODE (Bit 5): 通道模式使能位。当此位为1时,该区域匹配的依据从“地址范围”变为“通道ID(ChanID)”。此时,起始地址寄存器的低12位(
START_ADDRESS_LSB)被解释为要匹配的通道号。这种模式适用于那些基于消息或标签进行路由的互连场景,而非基于内存地址。 - LOCK (Bit 4): 区域锁定位。这是一个“写1置位”类型(R/W1TS)的位。一旦软件向此位写入1,该区域的所有配置寄存器(包括CONTROL、START_ADDRESS、END_ADDRESS)将被锁定,无法再被修改,直到下一次系统复位。这是一个关键的安全特性,用于防止系统启动后,关键的区域配置被恶意或错误的软件修改,常用于锁定安全启动阶段配置好的安全区域。
- ENABLE (Bit 3:0): 区域使能位。这是一个4比特字段,采用特殊编码。只有当写入
0xA时,该区域才被使能并参与地址匹配。写入其他任何值,该区域被禁用。这种非直观的编码(而非简单的1使能/0禁用)是一种防误操作设计,要求软件显式地、有意地写入一个“魔法数字”来启用区域,减少了因数据位翻转或错误写入导致区域意外启用的风险。
2.2 地址寄存器(START/END ADDRESS)配置精要
地址寄存器定义了区域覆盖的地址范围。AM64x/AM243x支持48位物理地址,因此有高低两个32位寄存器。
- START_ADDRESS_L/H, END_ADDRESS_L/H: 分别定义了区域的起始和结束地址(包含)。在地址模式(
CH_MODE=0)下,地址必须4KB对齐。这意味着起始地址的低12位(START_ADDRESS_L[11:0])必须为0,���结束地址的低12位(END_ADDRESS_L[11:0])在硬件上会被强制设置为0xFFF,无论你写入何值。这是由END_ADDRESS_LSB字段的复位值为0xFFF且类型为只读(R)所体现的。 - 地址匹配规则:一个事务的地址
Addr如果满足(START_ADDRESS <= Addr <= END_ADDRESS),则匹配该区域。ISC会按区域编号顺序进行匹配,使用第一个匹配的、且已使能(ENABLE=0xA)的区域的配置。如果所有使能区域都不匹配,则使用默认区域(DEF=1)的配置。 - 配置计算示例:假设我们要为PCIe主设备读操作(
pcie_mst_rd)映射一个从0x7000_0000开始,大小为0x1000_0000(256MB) 的DDR区域。- 起始地址
Start = 0x7000_0000。由于4KB对齐,低12位为0,符合要求。START_ADDRESS_L = 0x7000_0000 >> 12 = 0x70000(写入START_ADDRESS_L[31:12])START_ADDRESS_LSB = 0x0(硬件要求为0)START_ADDRESS_H = 0x0(因为地址高16位为0)
- 结束地址
End = Start + Size - 1 = 0x7000_0000 + 0x0FFF_FFFF = 0x7FFF_FFFF。END_ADDRESS_L = 0x7FFF_FFFF >> 12 = 0x7FFFF(写入END_ADDRESS_L[31:12])END_ADDRESS_LSB硬件固定为0xFFF,无需软件配置。END_ADDRESS_H = 0x0。
- 起始地址
注意:在计算地址时,务必使用物理地址(PA),而不是虚拟地址(VA)。这部分映射关系取决于你的内存映射表(Memory Map)和MMU/MPU的配置。
3. 典型配置场景与实战操作流程
理解了每个比特位的含义后,我们来看如何将它们组合起来,解决实际的系统设计问题。下面以两个典型场景为例,展示完整的配置流程和代码思路。
3.1 场景一:为非安全域Linux配置PCIe访问DDR区域
在这个场景中,运行在非安全环境(比如Linux用户空间)的PCIe设备需要访问主机端的一段DDR内存。为了系统安全,我们通常希望这段访问是非特权且非安全的,并且限定在特定的物理地址范围内。
配置目标:
- 区域:
ISC_IPCIE_G2X1_64_MAIN_0_PCIE_MST_RD_ISC_REGION_0 - 地址范围:
0x7000_0000到0x7FFF_FFFF(256MB) - 属性:输出事务为非特权(Non-privileged)、非安全(Non-secure)。
- PrivID:使用固定的ID,例如
0xC0,便于主机端识别此来源的访问。
配置步骤与代码实现(以C语言伪代码为例):
#include <stdint.h> // 假设寄存器基地址已定义 #define ISC_PCIE_RD_REGION0_CTRL_BASE 0x45888000 #define REG_CTRL (*(volatile uint32_t*)(ISC_PCIE_RD_REGION0_CTRL_BASE + 0x00)) #define REG_START_ADDR_L (*(volatile uint32_t*)(ISC_PCIE_RD_REGION0_CTRL_BASE + 0x10)) #define REG_START_ADDR_H (*(volatile uint32_t*)(ISC_PCIE_RD_REGION0_CTRL_BASE + 0x14)) #define REG_END_ADDR_L (*(volatile uint32_t*)(ISC_PCIE_RD_REGION0_CTRL_BASE + 0x18)) #define REG_END_ADDR_H (*(volatile uint32_t*)(ISC_PCIE_RD_REGION0_CTRL_BASE + 0x1C)) void configure_pcie_region_for_linux_ddr(void) { // 1. 首先,确保区域未锁定且被禁用,以便配置 // 读取当前控制寄存器,清除ENABLE位(写入非0xA的值即可禁用) uint32_t ctrl_val = REG_CTRL; ctrl_val &= ~(0xF); // 清除ENABLE字段的低4位 REG_CTRL = ctrl_val; // 写入任何非0xA的值,区域即被禁用 // 2. 配置地址范围 (256MB at 0x7000_0000) uint64_t start_addr = 0x70000000; uint64_t end_addr = 0x7FFFFFFF; REG_START_ADDR_L = (uint32_t)((start_addr >> 12) & 0xFFFFF); // 取[31:12] REG_START_ADDR_H = (uint32_t)((start_addr >> 32) & 0xFFFF); // 取[47:32] // START_ADDRESS_LSB 位域在地址模式下必须为0,通常寄存器复位后即为0,无需操作。 REG_END_ADDR_L = (uint32_t)((end_addr >> 12) & 0xFFFFF); // 取[31:12] REG_END_ADDR_H = (uint32_t)((end_addr >> 32) & 0xFFFF); // 取[47:32] // END_ADDRESS_LSB 硬件强制为0xFFF,只读,无需配置。 // 3. 配置控制属性 ctrl_val = 0; // 重新构建控制字 // 设置NOPRIV[1:0] = 2‘b11,强制清除输出的两个Priv位,使其为非特权访问 ctrl_val |= (0x3 << 26); // NOPRIV field // 设置NONSEC = 1,强制输出为非安全事务 ctrl_val |= (0x1 << 20); // NONSEC bit // 设置PASS = 0,表示要替换PrivID // PASS bit默认为0,也可显式不清零。 // 设置PRIV_ID = 0xC0 ctrl_val |= (0xC0 << 8); // PRIV_ID field // 确保CH_MODE = 0 (地址模式),LOCK = 0 (未锁定) // 最后,设置ENABLE = 0xA 来使能区域 ctrl_val |= (0xA << 0); // ENABLE field // 4. 将配置写入控制寄存器,区域立即生效 REG_CTRL = ctrl_val; // 5. (可选)锁定区域,防止后续篡改 // REG_CTRL |= (0x1 << 4); // 设置LOCK位 }关键点解析:
- 配置顺序:务必遵循“先禁用,再配地址,最后配属性并启用”的顺序。直接在已使能的区域上修改地址或关键属性是危险且可能无效的。
- 属性冲突:我们同时设置了
NOPRIV和NONSEC,确保了输出事务的权限和安全等级都被明确降级,符合非安全Linux域访问的需求。 - PrivID管理:我们使用了固定的
0xC0。在主机端的软件(如驱动程序)中,也需要知道这个ID,以便在它管理的资源(如DMA缓冲区)上设置相应的访问许可。
3.2 场景二:为安全服务配置专属安全访问通道
假设有一个运行在安全环境(如TrustZone安全世界)的加密服务,需要通过某个总线主设备(比如一个专用的DMA)访问一块安全的片上SRAM(地址0x6000_0000-0x6001_FFFF)。此通道必须严格隔离,仅允许安全特权访问。
配置目标:
- 区域:
ISC_IICSS_G_16FF_MAIN_1_PR1_EXT_VBUSM_ISC_REGION_DEF_CONTROL(这是一个默认区域示例,实际应选用一个未使用的普通区域) - 地址范围:
0x6000_0000到0x6001_FFFF(128KB) - 属性:输出事务为特权(Privileged)、安全(Secure)。
- PrivID:使用安全世界分配的特定ID,例如
0x89(参考了默认区域的复位值)。
配置步骤要点:
void configure_secure_sram_region(void) { // 1. 禁用目标区域(假设是Region 1) // 2. 配置起始地址 0x6000_0000, 结束地址 0x6001_FFFF // 注意:结束地址计算为 0x6000_0000 + 0x0001_FFFF = 0x6001_FFFF // 右移12位后,START_ADDRESS_L = 0x60000, END_ADDRESS_L = 0x6001F // 3. 构建控制字 uint32_t ctrl_val = 0; // 设置PRIV[1:0] = 2'b11,强制提升为特权访问 ctrl_val |= (0x3 << 24); // PRIV field // 设置SEC = 0xA,强制输出为安全事务 ctrl_val |= (0xA << 16); // SEC field (注意是4位字段,值0xA) // 设置PASS = 0,替换PrivID为安全ID // PASS bit保持为0 // 设置PRIV_ID = 0x89 ctrl_val |= (0x89 << 8); // PRIV_ID field // 使能区域 ctrl_val |= (0xA << 0); // ENABLE field // 4. 写入寄存器 // 5. (强烈建议)立即锁定该区域! ctrl_val |= (0x1 << 4); // 设置LOCK位 // 注意:LOCK位是W1TS,所以可以在构建值时一并设置,一次性写入。 }安全配置核心:
- 权限提升:即使发起事务的源头可能不是最高特权,通过设置
PRIV位,ISC强制将其提升为特权访问,确保能访问受保护的安全SRAM。 - 安全域隔离:设置
SEC=0xA是关键,它确���了该访问通道处于安全世界,非安全世界的主设备即使知道地址也无法匹配此区域(因为其事务是非安全的),或者即使匹配,其非安全属性也会被强制转换(如果配置了NONSEC),从而无法访问安全资源。 - 立即锁定:对于安��关键区域,在配置完成后立即写入
LOCK位是最佳实践。这可以防止系统运行阶段,内核或应用软件中的漏洞或恶意代码篡改此安全配置,是纵深防御的重要一环。
4. 高级功能与配置策略
4.1 通道模式(CH_MODE)的应用
当CH_MODE位设置为1时,区域匹配的逻辑从物理地址切换到了通道ID(ChanID)。在这种模式下:
START_ADDRESS_LSB[11:0]寄存器不再表示地址的低12位,而是用来指定要匹配的通道号。- 起始/结束地址的高位寄存器(
START_ADDRESS_L[31:12],START_ADDRESS_H,END_ADDRESS_*)在通道模式下通常被忽略或不使用。 - 事务是否命中该区域,取决于其附带的ChanID是否与配置的通道号相等。
使用场景:这在基于标签路由(Tagged Routing)或消息传递(Message Passing)的互连架构中非常有用。例如,在多核处理器中,核间通信(IPC)可能通过硬件消息队列实现,每个队列关联一个特定的通道ID。通过配置ISC区域为通道模式,并指定特定的通道号,可以为发送到该消息队列的所有事务统一施加安全属性和权限属性,而不必关心其具体的(可能是虚拟的)地址。
配置示例:假设我们要将通道号为0x123的所有消息事务配置为非安全、特权访问。
// 配置通道模式区域 ctrl_val |= (1 << 5); // 设置 CH_MODE = 1 // 在START_ADDRESS_LSB中设置通道号 start_addr_low_reg_value = 0x123; // 通道号 // 其他属性配置:NONSEC, PRIV等...4.2 默认区域(DEF Region)的战略价值
每个主设备的ISC都包含一个标记为DEF=1的默认区域。这是整个访问控制策略的“安全网”或“默认路由”。
设计策略:
- 最严格的默认策略:一种保守但安全的方法是,将默认区域配置为禁用(
ENABLE != 0xA)或配置为产生一个错误响应(例如,通过设置属性导致从设备拒绝)。这样,任何未明确映射的访问都会立即失败,便于在开发早期发现地址映射错误或非法访问。TI的许多默认区域复位后ENABLE=0xA(使能)且属性较为宽松,这是为了方便启动和调试,但在产品化阶段应重新评估。 - 兜底映射:另一种方法是,将默认区域映射到一个特定的、安全的“日志”或“调试”内存区域,并配置为安全、特权访问。任何未知访问都会被重定向到这里,系统可以记录这些访问事件用于安全审计或调试,而不是直接崩溃。
- 配置要点:默认区域通常是只读的(
DEF位为R),其区域索引是固定的。你需要查阅具体的数据手册来确定哪个区域是默认区域(例如,Region 15)。它的配置方式与其他区域相同,但其DEF位硬件置1,且不可更改。
4.3 多区域配置与优先级管理
一个主设备可以拥有多个区域(例如8个、16个)。ISC按照区域编号从低到高进行匹配。第一个匹配的、已使能的区域胜出。
配置策略:
- 精确匹配优先:将范围最小、最具体的映射放在编号较小的区域。例如,将某个关键外设的精确地址范围(如4KB)配置在Region 0,将一个大范围的DDR配置(如512MB)放在Region 1。
- 避免重叠:虽然硬件可能允许区域重叠,但重叠会导致配置复杂化和不可预测的行为(取决于具体的硬件实现)。最佳实践是确保配置的地址范围互不重叠。
- 利用优先级进行属性覆盖:你可以利用优先级来实现复杂的属性覆盖。例如,在Region 0将一个大的DDR区域配置为非安全访问,但在Region 1中覆盖其中一小块安全内存区域,将其配置为安全访问。由于Region 1编号更大,对那块小内存的访问会优先匹配Region 1,从而实现“大范围非安全,小范围安全”的精细控制。
5. 调试技巧与常见问题排查
即使理解了原理,在实际配置和调试ISC时,依然会遇到各种问题。下面分享一些我踩过坑后总结的经验。
5.1 配置不生效的排查清单
当你写入ISC寄存器后,访问行为并未按预期改变,可以按以下顺序排查:
- 确认寄存器写入成功:这是最基本的一步。读取回你刚刚写入的寄存器值,确认与写入值一致。特别注意:
- LOCK位是否已置位?如果区域已被锁定,后续的所有配置写入都会被硬件忽略,但读回的值可能仍是之前写入的(或表现为只读)。务必在锁定前完成所有配置。
- 访问权限:你当前运行的代码(CPU安全状态、特权等级)是否有权限修改目标ISC寄存器?有些ISC寄存器可能只允许在安全特权模式下访问。
- 确认区域已使能:检查
ENABLE字段是否为0xA。写入0x1或0xF是常见的错误,这不会使能区域。 - 确认地址匹配:
- 计算的事务地址是否真的落在你配置的
[START, END]区间内?务必使用物理地址进行判断。 - 检查地址是否4KB对齐。如果起始地址低12位不为0,配置可能无效或行为未定义。
- 对于
END_ADDRESS,要理解它是“包含”的。如果你的区域想覆盖0x8000_0000到0x8000_0FFF(4KB),那么START = 0x8000_0000,END = 0x8000_0FFF。
- 计算的事务地址是否真的落在你配置的
- 确认属性冲突:检查
PRIV和NOPRIV是否对同一位进行了冲突设置(不能同时为1)。检查SEC和NONSEC是否冲突。 - 确认事务源属性:ISC进行的是属性“转换”或“覆盖”。你需要清楚发起事务的原始属性是什么。例如,一个源头发起的已经是安全事务(Secure=1),你配置
NONSEC=1才会将其转换为非安全。如果源头就是非安全事务,你配置SEC=0xA才会将其转换为安全。使用调试器或性能计数器查看事务的原始属性。 - 查看默认区域:如果事务没有匹配任何已使能的普通区域,它就会落入默认区域。检查默认区域的配置是否符合你的预期。有时问题不是目标区域没配对,而是事务意外落入了默认区域。
5.2 性能与功能影响评估
ISC配置不仅影响安全,也可能影响性能。
- 匹配延迟:事务需要经过所有已使能区域的匹配检查,直到找到第一个匹配项。区域数量越多,理论上匹配链越长,可能引入额外的延迟。对于高性能路径,应尽量减少使能区域的数量,或将最频繁访问的路径放在编号较小的区域。
- 区域锁定与动态配置:
LOCK功能增强了安全性,但意味着该区域配置在系统运行后无法动态调整。在设计系统软件架构时,需要明确哪些配置是静态的(如安全启动固件设置),哪些可能需要动态调整(如操作系统管理的内存映射),并为它们分配不同的、未锁定的区域。 - 与MMU/MPU的协同:ISC是位于总线上的硬件防火墙,而MMU/MPU是位于CPU核心内的内存保护单元。它们可以构成纵深防御。例如,CPU通过MMU将虚拟地址
VA1映射到物理地址PA1,并设置页面权限。当访问PA1的总线事务经过ISC时,ISC会再次根据PA1所在的区域施加属性转换。两者权限取交集最严格的部分。调试时,需要同时检查MMU页表项和ISC区域配置。
5.3 实际调试案例:PCIe设备无法访问DDR
现象:在AM64x平台上,外接的PCIe Endpoint设备无法读取主机分配的DDR缓冲区,主机侧检测到总线错误(Bus Error)。
排查过程:
- 检查主机侧软件:确认DMA缓冲区地址已正确映射并传递给Endpoint。
- 检查PCIe控制器配置:确认地址转换(ATU)配置正确,将Endpoint的地址空间映射到了正确的系统物理地址。
- 使用芯片内总线探针或系统跟��工具(如TI的System Trace),捕获从PCIe主设备读端口(
pcie_mst_rd)发起的事务。 - 发现关键线索:跟踪显示,事务成功到达ISC模块,但其PrivID和Secure属性与预期不符。事务携带了Endpoint的某个内部ID,且为非安全属性。
- 检查ISC配置:查阅为
pcie_mst_rd配置的、对应目标DDR地址范围的ISC区域。发现该区域配置了PASS=0和PRIV_ID=0xB3(这是复位值),但NONSEC位为0,SEC字段为0(非0xA)。这意味着,事务的PrivID被替换成了0xB3,但其Secure属性未被改变(因为SEC和NONSEC都未生效)。 - 定位问题:目标DDR内存控制器(如DDRSS)的配置可能要求访问者具备特定的安全属性(例如,只接受安全事务,或对安全/非安全事务有不同配置)。当前事务的非安全属性被DDRSS拒绝。
- 解决方案:修改该ISC区域的配置,根据DDRSS的要求,明确设置
NONSEC=1(如果DDRSS接受非安全访问)或SEC=0xA(如果必须为安全访问)。同时,确认替换后的PRIV_ID=0xB3是DDRSS所接受的。
这个案例凸显了ISC配置中属性转换的完整性的重要性。不仅要配置PrivID,还必须明确配置安全属性,否则事务会保留其原始属性,可能与目标从设备的期望不符。