我想读取一些 Cortex-A53 寄存器的值,比如
- D_AA64ISAR0_EL1 (AArch64)
- ID_ISAR5 (Aarch32)
- ID_ISAR5_EL1 (Aarch64)
不幸的是,我缺乏一点嵌入式/组装经验。文件显示
访问 ID_AA64ISAR0_EL1: MRS , ID_AA64ISAR0_EL1 ;将 ID_AA64ISAR0_EL1 读入 Xt ID_AA64ISAR0_EL1[31:0] 可以通过内部存储器映射接口和外部调试接口访问,偏移量 0xD30。
我决定在我的目标上使用 devmem2(因为 busybox 不包括 devmem 小程序)。以下程序是否正确读取寄存器?
devmem2 0xD30
我不确定的部分是使用“偏移量”作为直接物理地址。如果是实际地址,为什么要调用“偏移”而不是“地址”。如果是偏移量,基地址是什么?我 99% 确定这不是正确的程序,但我怎么知道要添加偏移量的基地址?我搜索了 Armv8 技术参考手册和 A53 MPCore 文档均无济于事。详细解释寄存器内容,但似乎假设您使用标签 ID_AA64ISAR0_EL1 从 ASM 读取它们。
更新:
我找到了这个:
配置基地址寄存器,EL1 CBAR_EL1 的特性是: 用途 保存内存映射的 GIC CPU 接口寄存器的物理基地址。
但这只是重复了我的问题,如何读取其他寄存器?
更新 2: 第一次更新似乎只与 GIC 相关,而与我试图读取的配置寄存器无关(我误解了我认为的信息)。
对于手头的具体问题(检查加密扩展可用性),可以简单地 cat /proc/cpuinfo 并查找 aes/sha 等。
更新 3:
我现在正在调查http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0176c/ar01s04s01.html,以及特定于 SoC 的基地址,因此可以在SoC 的参考手册。
更新 4:
感谢出色的答案,我似乎能够通过我的内核模块读取数据:
[ 4943.461948] ID_AA64ISA_EL1 : 0x11120
[ 4943.465775] ID_ISAR5_EL1 : 0x11121
PS: 这非常有见地,再次感谢您!
更新5: 根据要求的源代码:
/******************************************************************************
*
* Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*****************************************************************************/
#include <linux/module.h>
#include <linux/types.h>
/*****************************************************************************/
// read system register value ID_AA64ISAR0_EL1 (s3_0_c0_c6_0).
static inline uint64_t system_read_ID_AA64ISAR0_EL1(void)
{
uint64_t val;
asm volatile("mrs %0, ID_AA64ISAR0_EL1" : "=r" (val));
return val;
}
// read system register value ID_ISAR5_EL1 (s3_0_c0_c2_5).
static inline uint64_t system_read_ID_ISAR5_EL1(void)
{
uint64_t val;
asm volatile("mrs %0, s3_0_c0_c2_5" : "=r" (val));
return val;
}
/*****************************************************************************/
int init_module(void)
{
printk("ramdump Hello World!\n");
printk("ID_AA64ISAR0_EL1 : 0x%llX\n", system_read_ID_AA64ISAR0_EL1());
printk("ID_ISAR5_EL1 : 0x%llX\n", system_read_ID_ISAR5_EL1());
return 0;
}
void cleanup_module(void)
{
printk("ramdump Goodbye Cruel World!\n");
}
MODULE_LICENSE("GPL");