Arch:CPU 机制与能力合同¶
这些声明来自公共头文件。选择、生命周期、支持的执行模式和物理资源授权范围仍以对应设计及支持记录为准。
arch.h¶
CPU 本地屏蔽、上下文、内存顺序与周期快照合同。
作者 Nexus Team
函数
-
nx_arch_irq_state_t nx_arch_irq_save(void)¶
保存进入时的本地屏蔽状态,并屏蔽可配置异常。
备注
仅用于特权 Task/可配置 IRQ 中的短元数据临界区;不得阻塞、分配内存、调用 OS 函数、复制大缓冲区或执行回调。NMI/HardFault 仍未屏蔽。Native 使用可递归的主机互斥模型,不提供物理 IRQ 时序或信号安全保证。NMI/HardFault 不得访问由该屏蔽保护的共享元数据。ARM 非特权调用者需要由其 OS 拥有的显式特权网关。
- 返回:
用于按嵌套的相反顺序恰好恢复一次的令牌。
-
void nx_arch_irq_restore(nx_arch_irq_state_t previous)¶
恢复进入时的屏蔽状态,保留嵌套屏蔽区的约束。
备注
仅限特权上下文。只恢复 PRIMASK;不修改已实现的 BASEPRI/FAULTMASK。
- 参数:
previous – [in] 来自当前 CPU/线程最近一次尚未配对恢复的 save 的令牌。
-
nx_arch_irq_masks_t nx_arch_irq_masks(void)¶
读取已实现本地中断屏蔽寄存器的快照。
备注
有界、只读的特权任务/IRQ 查询。不屏蔽中断,也不建立稳定的临界区。数值属于当前 CPU/安全状态,不属于另一安全域或 SMP 对等核。非特权读取不能确定实际屏蔽状态。
- 返回:
当前 PRIMASK 以及已实现的 BASEPRI/FAULTMASK 值。
-
bool nx_arch_irq_is_masked(void)¶
检查可能阻止必要完成推进的屏蔽状态。
备注
有界的特权任务/IRQ 查询,不改变状态。ARM 非特权读取不能确定实际屏蔽状态。
- 返回:
PRIMASK、已实现的 BASEPRI/FAULTMASK 或 Native 线程嵌套存在屏蔽时为 true。Baseline Cortex-M 内核只查询 PRIMASK。
-
uint32_t nx_arch_exception_number(void)¶
查询当前 CPU 异常的准确身份。
备注
有界、只读的任务/IRQ 查询。该身份属于当前 CPU/安全状态;它不是可移植的 SoC IRQ 编号,也不能证明允许调用内核 ISR API。
- 返回:
IPSR 异常编号;Thread 模式或 Native 返回零。
-
bool nx_arch_is_privileged(void)¶
查询当前 CPU 执行上下文的特权级。
备注
有界、只读的任务/IRQ 查询。Handler 模式的特权不取决于被中断 Thread 的 CONTROL.nPRIV。该查询不证明 Secure 域所有权。
- 返回:
处于 Handler 模式或特权 Thread 模式时为 true。Native 没有 CPU 特权模型,因此始终返回 true。
-
bool nx_arch_in_isr(void)¶
查询当前 CPU 异常上下文。
- 返回:
Cortex-M 的 IPSR 非零时为 true;Native 没有硬件 ISR,始终返回 false。不支持主机信号上下文。
-
void nx_arch_dmb(void)¶
为 CPU 域中的显式数据内存访问建立顺序。
备注
Cortex-M 执行 DMB;Native 执行顺序一致的线程栅栏。不证明 DMA 已空闲,也不清理非一致性缓存行。
-
void nx_arch_dsb(void)¶
完成此前的显式内存访问。
备注
Cortex-M 执行 DSB;Native 线程栅栏只是行为模型,不保证物理总线/DMA 已完成。
-
void nx_arch_isb(void)¶
同步后续 CPU 指令执行。
备注
Cortex-M 执行 ISB;Native 线程栅栏不具有流水线语义。
-
bool nx_arch_cycle_snapshot(uint32_t *cycles)¶
读取已启用自由运行周期计数器的快照。
备注
计数器频率随 CPU 时钟变化。仅可对短于 2^32 个周期的区间使用无符号快照相减;该计数器既不是共享单调时间,也不是 deadline。
- 参数:
cycles – [out] DWT CYCCNT 快照;不可用时保持输出不变。
- 返回:
已维护的 CPU 计数器已启用时为 true;Native、未审查/已禁用/不可用的 DWT 或非特权调用者返回 false。不启用或复位计数器。只有经过审查的 CPU profile 才可读取可选 DWT 寄存器。
atomic.h¶
内联、自然对齐的 32 位发布与读改写端口。
作者 Nexus Team
备注
存储必须是存续且自然对齐的 uint32_t;所有并发访问均须使用这些 helper 或兼容的编译器原子操作。发布存储前先初始化。所有已维护 CPU 的 load/store 都使用编译器 acquire/release 操作,且从不屏蔽中断。除 ARMv6-M 外,RMW 使用编译器无锁操作;exclusive 指令的重试不构成固定周期上限。
备注
ARMv6-M RMW 使用 CPU 本地、有界且保存 PRIMASK 的互斥。只有同一 CPU 上的特权 Thread/可配置 IRQ 上下文可访问该域。NMI/HardFault、非特权调用者、其他内核、DMA 和其他安全域不得并发访问其存储。它不是 SMP 或总线原子操作。屏蔽期间不执行回调、分配、阻塞调用或载荷复制。
函数
-
static inline uint32_t nx_atomic_u32_load_relaxed(const uint32_t *value)¶
读取一个字,不发布或获取其他数据。
-
static inline uint32_t nx_atomic_u32_load_acquire(const uint32_t *value)¶
读取一个字,并通过所观察的发布获取数据。
-
static inline void nx_atomic_u32_store_relaxed(uint32_t *value, uint32_t desired)¶
存储一个字,不发布其他数据。
-
static inline void nx_atomic_u32_store_release(uint32_t *value, uint32_t desired)¶
通过一次对齐的 release 存储发布此前数据。
-
static inline bool nx_atomic_u32_compare_exchange_acq_rel(uint32_t *value, uint32_t *expected, uint32_t desired)¶
强 acq_rel 比较交换,失败时采用 acquire 顺序。
- 参数:
value – [inout] 调用者拥有的原子域内、存续且自然对齐的字;所有并发访问均遵守本合同。
expected – [inout] 独立的调用者私有存储;失败时以观察到的值替换,成功时保持不变。
desired – [in] 仅在比较成功时写入的替换字。
- 返回:
仅当原字等于 expected 且 desired 字已存入时为 true。不允许伪失败。
-
static inline uint32_t nx_atomic_u32_fetch_add_acq_rel(uint32_t *value, uint32_t amount)¶
按模 2^32 以 acq_rel 顺序相加,返回原值。
-
static inline uint32_t nx_atomic_u32_fetch_add_release(uint32_t *value, uint32_t amount)¶
按模 2^32 以 release 顺序相加,返回原值。
备注
ARMv6-M 还会保守地以 acquire 语义读取观察到的字。
-
static inline uint32_t nx_atomic_u32_fetch_sub_acq_rel(uint32_t *value, uint32_t amount)¶
按模 2^32 以 acq_rel 顺序相减,返回原值。
-
static inline uint32_t nx_atomic_u32_fetch_sub_release(uint32_t *value, uint32_t amount)¶
按模 2^32 以 release 顺序相减,返回原值。
备注
ARMv6-M 还会保守地以 acquire 语义读取观察到的字。
cache.h¶
显式的 CPU 完整缓存行维护机制。
作者 Nexus Team
函数
-
nx_arch_result_t nx_arch_dcache_clean(uintptr_t address, size_t bytes)¶
将脏数据缓存行发布到一致性点。
备注
仅限当前安全域中的特权任务/可配置 IRQ 上下文。调用者须在返回前排除其他 CPU、安全域及 DMA 对每个完整缓存行的使用,并保持缓存配置稳定。不隐式屏蔽 IRQ、分配内存或启用缓存。支持的几何仅为经过显式审查的 32 字节缓存行;禁止将范围向外取整。工作量以 bytes/32 为界,不代表 DMA 排空、设备完成或所有权转移。
- 参数:
address – [in] 独占拥有的完整缓存行的首字节。
bytes – [in] CPU 地址空间内、非零且由完整缓存行组成的长度。
- 返回:
维护和屏障完成后返回 OK;部分缓存行或溢出/非 32 位范围返回 INVALID;非特权调用者返回 CONTEXT;经过审查的缓存不存在或已禁用时返回 UNSUPPORTED。拒绝时不进行维护写入。
-
nx_arch_result_t nx_arch_dcache_invalidate(uintptr_t address, size_t bytes)¶
丢弃完整数据缓存行,不执行写回。
备注
调用者须允许丢弃这些缓存行中的全部脏数据,并满足 clean 的互斥/上下文合同。不触及相邻行,也不将其向外取整纳入范围。DMA 接收由 provider 协调 DMA 前与排空后的维护;本调用不证明空闲。
- 参数:
address – [in] 独占拥有的完整缓存行的首字节。
bytes – [in] CPU 地址空间内、非零且由完整缓存行组成的长度。
- 返回:
上下文、范围和能力相关返回结果与 clean 相同。
-
nx_arch_result_t nx_arch_dcache_clean_invalidate(uintptr_t address, size_t bytes)¶
发布脏数据并丢弃完整缓存行。
备注
须满足 clean 的互斥/上下文合同。与 invalidate 不同:先写回脏内容,再丢弃。
- 参数:
address – [in] 独占拥有的完整缓存行的首字节。
bytes – [in] CPU 地址空间内、非零且由完整缓存行组成的长度。
- 返回:
上下文、范围和能力相关返回结果与 clean 相同。
-
nx_arch_result_t nx_arch_instruction_sync(uintptr_t address, size_t bytes)¶
使调用者拥有的完整范围对 CPU 指令保持一致。
备注
须满足 clean 的互斥/上下文合同。任何维护前先检查所有存在的缓存;只有一个经过审查的缓存时,只维护该缓存。调用者须阻止从正在改变的范围执行代码,包括其他安全域用户。这不是代码验证、MPU 策略变更,也不是全局缓存/分支预测器刷新。
- 参数:
address – [in] 独占拥有的完整缓存行的首字节。
bytes – [in] CPU 地址空间内、非零且由完整缓存行组成的长度。
- 返回:
数据 clean、指令 invalidate 和执行屏障完成后返回 OK;INVALID/CONTEXT 同上;两个经过审查的缓存均不存在,或某个存在的缓存已禁用时返回 UNSUPPORTED。
cache_control.h¶
显式、自有的 Cortex-M7 冷缓存状态转换。
作者 Nexus Team
枚举
函数
-
nx_arch_cache_control_result_t nx_arch_cache_cold_enable(nx_arch_cache_control_t *control, uint32_t mask)¶
对冷缓存作准入判定,并启用显式选定的缓存。
备注
仅支持经过审查的 M7。要求特权 Thread、PRIMASK=1、BASEPRI=FAULTMASK=0,并且缓存已由可信复位或先前成功的所有者 clean/disable 证明为干净。仅 CCR 位为零不能证明外来状态干净;绝不接管未知 bootloader 状态。调用者须在整个转换期间排除所有其他缓存用户、DMA、NMI 和 HardFault 对受影响内存的访问,并拥有内存属性、执行和一致性策略;启用缓存本身不建立 DMA 一致性。不改变 IRQ 屏蔽、不分配内存,也不接管缓存。初始准入被拒绝时不保留责任。IO 失败可能保留 owned_mask/selector_pending;须调用 cold_disable,并保留存储直至其成功。
- 参数:
control – [inout] 独占拥有且初始为空的控制对象。
mask – [in] DATA 和 INSTRUCTION 位的非零组合。
- 返回:
验证启用及 selector 恢复后返回 OK;参数错误返回 INVALID;上下文不安全返回 CONTEXT;CPU/几何未经审查返回 UNSUPPORTED;存在活动/外来缓存返回 STATE;寄存器写入未获回读确认时返回 IO。
-
nx_arch_cache_control_result_t nx_arch_cache_cold_disable(nx_arch_cache_control_t *control)¶
清理并禁用此控制对象负责的缓存。
备注
在所有 DMA/provider 均已排空后,满足 enable 的互斥和上下文合同。拒绝 owned_mask 以外已启用的缓存。数据 clean/disable 转换使用不使用栈的叶函数,避免最终 clean 与 CCR 更新之间出现本地脏行。其有界工作量为四路乘以经过验证的组数,不代表恒定延迟。失败操作可重试,不接管新缓存,也不遗忘原 selector。对于受支持的 CPU profile,零对象是幂等的无操作。
- 参数:
control – [inout] 传给 cold_enable 的同一存续对象。
- 返回:
仅在缓存禁用且 selector 恢复后返回 OK;INVALID、CONTEXT、UNSUPPORTED、STATE 或 IO 均保留所有权。
-
struct nx_arch_cache_control_t¶
- #include <cache_control.h>
调用者拥有的缓存责任与选择器恢复状态。
备注
首次使用前零初始化;不得修改字段或复制活动对象。须保留对象,直到 owned_mask 和 selector_pending 都为零。owned_mask 保守记录清理责任,不表示硬件启用位。
features.h¶
已审查的 CPU 机制与无分配结果类型。
作者 Nexus Team
枚举
函数
-
nx_arch_features_t nx_arch_features(void)¶
查询不可变、编译期确定的 CPU 机制能力。
备注
只读的 Task/IRQ 查询,不访问硬件,也不进行发现。
- 返回:
经过精确审查的 CPU 事实;Native 报告硬件不存在。
-
struct nx_arch_features_t¶
- #include <features.h>
实际编译的精确 CPU profile 中的已审查机制。
备注
缓存不存在时大小为零;MPU 版本为零、七或八。这些事实不证明硬件已启用、内存可达、跨域所有权或 HIL 状态。
mpu.h¶
分别实现 Armv7-M 与 Armv8-M MPU 编码机制。
作者 Nexus Team
函数
-
nx_arch_result_t nx_arch_mpu_v7_encode(const nx_arch_mpu_v7_region_t *region, nx_arch_mpu_v7_encoding_t *encoding)¶
编码准确的 Armv7-M 区域,不访问硬件。
备注
纯函数、有界的任务/IRQ 操作。输入与输出不得重叠。它只编码字段,不证明 SoC 内存可达性、缓存所有权、DMA 一致性或产品保护策略。
- 参数:
region – [in] 大小指数为 5..32,base 按大小对齐,AP 为 0/1/2/3/5/6,TEX 为 0..7,S/C/B 为原始位。子区域 mask 不超过 255;大小小于 256 字节时必须为零。4 GiB 区域的 base 为零。拒绝保留/实现定义的 TEX/C/B 编码,不截断或取整。
encoding – [out] RBAR 和置有启用位的 RASR 编码;失败时不改变输出。
- 返回:
NX_ARCH_OK 或 NX_ARCH_INVALID,与 CPU profile 无关。
-
nx_arch_result_t nx_arch_mpu_v8_encode(const nx_arch_mpu_v8_region_t *region, nx_arch_mpu_v8_encoding_t *encoding)¶
编码准确的 Armv8-M 区域,不访问硬件。
备注
纯函数、有界的任务/IRQ 操作。输入与输出不得重叠。不进行地址取整或 v7/v8 策略转换。
- 参数:
region – [in] base 按 32 字节对齐;包含在范围内的 limit 末尾为 0x1f;base 不大于 limit;AP 为 0..3,SH 为 0/2/3,MAIR 索引为 0..7。调用者拥有相应的 MAIR 策略。
encoding – [out] RBAR 和置有启用位的 RLAR 编码;失败时不改变输出。
- 返回:
NX_ARCH_OK 或 NX_ARCH_INVALID,与 CPU profile 无关。
-
nx_arch_result_t nx_arch_mpu_v7_program(uint32_t index, const nx_arch_mpu_v7_region_t *region)¶
在当前安全世界的 MPU 关闭时,编程一个 Armv7-M 区域。
备注
仅限 PRIMASK 已置位、且调用者独占此 MPU 的特权 Thread。NMI/HardFault/其他安全域不得修改它。只禁用选定区域、写入其字段、恢复传入的 RNR,并保持 CTRL 不变。不分配内存、不调用 OS、不隐式启用 MPU、不批量清零,也不从 Secure 访问 Non-secure 别名。
- 参数:
index – [in] 小于实际 MPU_TYPE.DREGION 的区域编号。
region – [in] 已由 nx_arch_mpu_v7_encode 验证的字段。
- 返回:
编译的 MPU 类型不同或不存在时,在 MMIO 前返回 NX_ARCH_UNSUPPORTED;字段或索引无效返回 NX_ARCH_INVALID;非特权、Handler、未屏蔽或 MPU 已启用的调用上下文返回 NX_ARCH_CONTEXT。拒绝时不写寄存器。
-
nx_arch_result_t nx_arch_mpu_v8_program(uint32_t index, const nx_arch_mpu_v8_region_t *region)¶
在当前安全世界的 MPU 关闭时,编程一个 Armv8-M 区域。
备注
要求已屏蔽的特权 Thread、已禁用的 MPU 及本地独占所有权。不更新 MAIR,也不访问跨域别名。保留传入的 RNR 和 CTRL。
- 参数:
index – [in] 小于实际 MPU_TYPE.DREGION 的区域编号。
region – [in] 已由 nx_arch_mpu_v8_encode 验证的字段。
- 返回:
拒绝及所有权规则与 v7_program 相同;编译的 MPU 必须明确实现 Armv8-M。
-
nx_arch_result_t nx_arch_mpu_v8_attribute_set(uint32_t index, uint32_t attribute)¶
更新一个 Armv8-M MAIR 字节,不修改相邻字节。
备注
调用者拥有有效内存属性及所有使用此槽的区域。要求已屏蔽的特权 Thread、已禁用的 MPU 及本地独占所有权。不写 CTRL 或 RNR、不维护缓存,也不跨域访问寄存器。
- 参数:
index – [in] 属性槽 0..7。
attribute – [in] 架构 MAIR 字节,不超过 255。Device 编码为 0x00/0x04/0x08/0x0c;Normal 内存使用非零的外层/内层半字节,且不得为保留值 0x8。
- 返回:
成功返回 NX_ARCH_OK;MPU 不存在或为 v7 返回 NX_ARCH_UNSUPPORTED;字段越界返回 NX_ARCH_INVALID;不满足编程上下文规则时返回 NX_ARCH_CONTEXT。
nonsecure.h¶
显式的 NonSecure 非特权地址权限检查。
作者 Nexus Team
枚举
函数
-
nx_arch_result_t nx_arch_nonsecure_check(const void *address, size_t bytes, nx_arch_nonsecure_access_t access)¶
检查当前 NonSecure 非特权上下文对完整范围的访问权限。
备注
只进行不分配内存的权限观察。硬件 CMSE 按非特权调用者身份,同时检查安全属性和 NonSecure MPU 权限。相邻的许可区域也可能被保守拒绝。不复制、固定或借用任何内存。成功既不认证网关调用者,也不证明 RAM、DMA 可达性、生命周期或故障安全。集成所有者须通过其 SoC RAM 策略排除 MMIO,并在后续访问期间阻止属性/映射变化。这里不排除中断、其他安全域、DMA 或故障;不改变屏蔽或硬件策略。任何不可逆操作前,网关还须独立快照输入并验证输出。
- 参数:
address – [in] 非空起始地址;此 API 从不解引用它。
bytes – [in] 正长度,且包含在范围内的结束地址可表示。
access – [in] 精确选择 READ 或 READWRITE 访问,不是位 mask。
- 返回:
完整当前访问允许时返回 OK;范围格式错误或拒绝访问返回 INVALID;特权 Secure Thread 以外返回 CONTEXT;Native、单一安全状态或 NonSecure 镜像返回 UNSUPPORTED。
security.h¶
本地安全状态与显式 SAU 区域机制。
作者 Nexus Team
函数
-
nx_arch_security_state_t nx_arch_security_state(void)¶
查询此镜像的编译期安全状态。
备注
有界、只读的 Task/IRQ 查询,不访问硬件。不授予访问其他安全域内存或设备的权限。
- 返回:
经过审查的镜像状态:单域、Secure 或 NonSecure。
-
nx_arch_result_t nx_arch_sau_encode(const nx_arch_sau_region_t *region, nx_arch_sau_words_t *words)¶
编码显式 SAU 区域,不访问硬件。
备注
纯 Task/IRQ 操作。编码将请求区域标为已启用,但不启用 SAU 硬件。外部策略拥有重叠、IDAU 限制和 NSC veneer 的责任。
- 参数:
region – [in] base 按 32 字节对齐;包含在范围内的 limit 须位于完整 32 字节边界的末尾。base 不得超过 limit。
words – [out] 编码后的区域;失败时保持不变。
- 返回:
成功返回 OK;参数为空或边界无效返回 INVALID。
-
nx_arch_result_t nx_arch_sau_write(uint32_t index, const nx_arch_sau_region_t *region)¶
SAU 关闭时,编程一个自有 SAU 区域。
备注
仅限传入 PRIMASK 已置位的 Secure 特权 Thread。调用者须排除所有其他区域/selector 用户,并使 NMI/HardFault 不接触该元数据。要求已审查的 SAU 区域支持。不修改 CTRL、ALLNS、其他区域或其他安全域寄存器,也不启用 SAU。恢复当前 RNR;DSB/ISB 完成区域写入。策略、安全网关及 IDAU 配置仍由外部负责。
- 参数:
index – [in] 小于实际硬件 TYPE 计数的区域索引。
region – [in] 显式审查过的区域及 NSC 权限。
- 返回:
返回 OK、INVALID、CONTEXT 或 UNSUPPORTED,不保留状态。
-
nx_arch_result_t nx_arch_sau_clear(uint32_t index)¶
SAU 关闭时,禁用一个自有 SAU 区域。
备注
上下文和所有权合同与 nx_arch_sau_write 相同。保留 CTRL、ALLNS、其他区域及传入的 RNR。
- 参数:
index – [in] 小于实际硬件 TYPE 计数的区域索引。
- 返回:
返回 OK、INVALID、CONTEXT 或 UNSUPPORTED,不进行其他写入。
-
struct nx_arch_sau_region_t¶
- #include <security.h>
由 Secure 调用者拥有、准确按 32 字节对齐的 SAU 区域。
-
struct nx_arch_sau_words_t¶
- #include <security.h>
经过验证的 SAU 寄存器字;编码不会改变硬件。
sleep.h¶
已审查的单 CPU 浅睡眠合同。
作者 Nexus Team 版本 1.0.0 日期 2026-10-11 版权 Copyright (c) 2026 Nexus Team
函数
-
nx_arch_result_t nx_arch_wait_for_interrupt(void)¶
在可配置异常已被屏蔽的条件下等待一次。
备注
特权 Thread 模式,传入 PRIMASK=1,BASEPRI 和 FAULTMASK 清零。SCR.SLEEPDEEP 必须清零。调用者拥有最终就绪检查及定时器/唤醒源。即使 PRIMASK 已置位,待决且已启用的中断也会使 WFI 唤醒;调用者恢复保存的屏蔽后才执行中断。不改变任何寄存器、屏蔽、时钟或待决中断。仅针对当前 CPU/安全状态,不声明物理 HIL 资格。
- 返回:
唤醒后返回 OK;CONTEXT 或 UNSUPPORTED 时不进入睡眠。
-
nx_arch_result_t nx_arch_idle_if_unchanged(const uint32_t *sequence, uint32_t expected, bool *slept)¶
执行 WFI 前,以原子方式重新检查已发布序列。
备注
特权 Thread 模式,所有传入屏蔽均须清零。保存 PRIMASK,在该屏蔽下执行 acquire 观察,必要时睡眠,然后精确恢复原屏蔽。发布者必须是同 CPU 的可配置 IRQ 或 Thread;排除 NMI/HardFault、DMA、SMP 及其他安全域发布者。调用者须保持存储存续,为有限 deadline 拥有已启用的 IRQ 定时器,并在唤醒后重试权威谓词。Native 不支持。
- 参数:
sequence – [in] 自然对齐的共享 32 位唤醒序列。
expected – [in] 调用者执行就绪检查前的快照。
slept – [out] 仅在实际执行 WFI 时为 true。
- 返回:
返回 OK、INVALID、CONTEXT 或 UNSUPPORTED。