我在
arm-tf/include/lib/mmio.h
中找到了mmio访问api,它像许多其他特权软件(addr
、linux
等)一样访问optee-os
来执行I/O操作:
static inline void mmio_write_32(uintptr_t addr, uint32_t value)
{
*(volatile uint32_t*)addr = value;
}
static inline uint32_t mmio_read_32(uintptr_t addr)
{
return *(volatile uint32_t*)addr;
}
据我所知,
addr
应该是虚拟内存地址,MMU将其转换为物理地址,然后在MMIO地址上进行读/写。
以下面的代码为例。看来atf是以SMMUv3的MMIO物理地址为
addr
,直接访问MMIO物理地址:
#define PLAT_FVP_SMMUV3_BASE UL(0x2b400000)
smmuv3_init(PLAT_FVP_SMMUV3_BASE);
int __init smmuv3_init(uintptr_t smmu_base)
{
/* Abort all incoming transactions */
if (smmuv3_security_init(smmu_base) != 0)
return -1;
/* Check if the SMMU supports secure state */
if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
SMMU_S_IDR1_SECURE_IMPL) == 0U)
return 0;
/*
* Initiate invalidation of secure caches and TLBs if the SMMU
* supports secure state. If not, it's implementation defined
* as to how SMMU_S_INIT register is accessed.
*/
mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
/* Wait for global invalidation operation to finish */
return smmuv3_poll(smmu_base + SMMU_S_INIT,
SMMU_S_INIT_INV_ALL, 0U);
}
也许我漏掉了一些内存管理的知识。这是因为 Arm 可信固件具有更高的权限级别 (EL3)?或者Arm Trusted Firmware中没有MMU配置,所以可以直接访问物理内存?
现代 SoC 上的启动很复杂,因此在初始化过程中可能会多次启用和禁用 MMU。可信固件绝对可以在启用 MMU 的情况下运行。我不知道在这个特定的初始化代码运行时是否启用了 MMU。
这让您了解流程:
https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/design/firmware-design.rst