【问题标题】:ARM64 (Cortex-A53) - GNU Assembler - GIC register: unknown or missing system register nameARM64 (Cortex-A53) - GNU 汇编器 - GIC 寄存器:未知或缺少系统寄存器名称
【发布时间】:2020-09-26 16:26:17
【问题描述】:

我已经为 Cortex-A53 启动了一个简单的裸机应用程序。现在我想实现中断,但我遇到了一个问题。想读取寄存器ICC_SRE_ELx 以确定SRE 标志,以了解是否必须使用内存映射GIC 接口。如果启用了 SRE,还想写入这些寄存器以启用 IRQ 和 FIQ。

收到以下错误消息:

$ make
aarch64-suse-linux-gcc -c -Wall -I ./include -ffreestanding -mcpu=cortex-a53 misc.S -o misc.o
misc.S: Assembler messages:
misc.S:38: Error: unknown or missing system register name at operand 2 -- `mrs x0,ICC_SRE_EL2'
misc.S:42: Error: unknown or missing system register name at operand 2 -- `mrs w0,ICC_SRE_EL2'
misc.S:44: Error: unknown or missing system register name at operand 1 -- `msr ICC_SRE_EL2,w0'
misc.S:48: Error: unknown or missing system register name at operand 2 -- `mrs x0,ICC_SRE_EL2'
misc.S:50: Error: unknown or missing system register name at operand 2 -- `mrs x0,ICC_SRE_EL2'

写了这么简单的代码:

#include <asm.h>

#define ICC_SRE_EL2_FIQ     0x2
#define ICC_SRE_EL2_IRQ     0x4

.text

FUNCTION(_cpu_get_el)
    mrs x0, CurrentEL
    and x0, x0, #0xC
    asr x0, x0, #2
    ret

FUNCTION(_cpu_get_id)
    mrs x0, MPIDR_EL1
    and x0, x0, #0x3
    ret

FUNCTION(_cpu_get_icc_sre_el2)
    mrs x0, ICC_SRE_EL2
    ret

FUNCTION(_cpu_set_icc_sre_el2_irq)
    mrs x0, ICC_SRE_EL2
    orr x0, x0, #ICC_SRE_EL2_IRQ
    msr ICC_SRE_EL2, x0
    ret

FUNCTION(_cpu_set_icc_sre_el2_fiq)
    mrs x0, ICC_SRE_EL2
    orr x0, x0, #ICC_SRE_EL2_FIQ
    mrs x0, ICC_SRE_EL2
    ret

.end

我使用以下 GCC 标志:

-Wall -I ./include -ffreestanding -mcpu=cortex-a53

根据official TRM,这些寄存器应该在Cortex-A53上实现。

我是这个架构的新手。任何帮助将不胜感激!

编辑:

我尝试了以下 GAS 版本:

我用过的操作系统(openSUSE Leap 15.1)的包:

$ aarch64-suse-linux-as --version
GNU assembler (GNU Binutils; devel:gcc / openSUSE_Leap_15.1) 2.34.0.20200325-lp151.386
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `aarch64-suse-linux'.

official tool-chains from the ARM homepage:

$ ../gcc/bin/aarch64-none-elf-as --version
GNU assembler (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 2.33.1.20191209
Copyright (C) 2019 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `aarch64-none-elf'.

【问题讨论】:

  • 据我所知,-ffreestanding-mcpu 只影响 C 编译器。这里不涉及 C 编译器;您只是使用gcc 驱动程序作为调用汇编程序的一种方式。
  • 好的。我试图通过选项-Wa,-mcpu=cortex-a53。不幸的是同样的错误。

标签: gcc cpu-registers arm64 gnu-assembler interrupt-handling


【解决方案1】:

GNU AS 不知道所有Aarch64 符号系统寄存器名称,您需要将ICC_SRE_EL2 替换为其op0,op1,CRn,CRm,op2 编码,即s3_4_c12_c9_5 - 请参阅Arm 文档here(查找“访问 ICC_SRE_EL2”部分)。

这些寄存器当然可以直接从 C/C++ 代码中使用实用程序函数访问,如下面提供的那些:

// write system register  ICC_SRE_EL1 (s3_0_c12_c12_5) with specified value.
static inline void system_write_ICC_SRE_EL1(uint64_t val)
{
    asm volatile("msr s3_0_c12_c12_5 , %0" : : "r" (val));
}

// read system register value ICC_SRE_EL1 (s3_0_c12_c12_5).
static inline uint64_t system_read_ICC_SRE_EL1(void)
{
    uint64_t val;
    asm volatile("mrs %0, s3_0_c12_c12_5" : "=r" (val));
    return val;
}

// write system register  ICC_SRE_EL2 (s3_4_c12_c9_5) with specified value.
static inline void system_write_ICC_SRE_EL2(uint64_t val)
{
    asm volatile("msr s3_4_c12_c9_5 , %0" : : "r" (val));
}

// read system register value ICC_SRE_EL2 (s3_4_c12_c9_5).
static inline uint64_t system_read_ICC_SRE_EL2(void)
{
    uint64_t val;
    asm volatile("mrs %0, s3_4_c12_c9_5" : "=r" (val));
    return val;
}

// write system register  ICC_SRE_EL3 (s3_6_c12_c12_5) with specified value.
static inline void system_write_ICC_SRE_EL3(uint64_t val)
{
    asm volatile("msr s3_6_c12_c12_5 , %0" : : "r" (val));
}

// read system register value ICC_SRE_EL3 (s3_6_c12_c12_5).
static inline uint64_t system_read_ICC_SRE_EL3(void)
{
    uint64_t val;
    asm volatile("mrs %0, s3_6_c12_c12_5" : "=r" (val));
    return val;
}

GNU AS 识别的系统寄存器列表可以在变量const aarch64_sys_reg aarch64_sys_regs [] 中找到,该变量定义在opcodes/aarch64-opc.c GNU AS 源代码文件部分,存档可从here 下载:

/* TODO there is one more issues need to be resolved
   1. handle cpu-implementation-defined system registers.  */
const aarch64_sys_reg aarch64_sys_regs [] =
{
  { "spsr_el1",         CPEN_(0,C0,0),  0 }, /* = spsr_svc */
  { "spsr_el12",    CPEN_ (5, C0, 0), F_ARCHEXT },
  { "elr_el1",          CPEN_(0,C0,1),  0 },
  { "elr_el12", CPEN_ (5, C0, 1), F_ARCHEXT },
  { "sp_el0",           CPEN_(0,C1,0),  0 },
  { "spsel",            CPEN_(0,C2,0),  0 },
  { "daif",             CPEN_(3,C2,1),  0 },
  { "currentel",        CPEN_(0,C2,2),  F_REG_READ }, /* RO */
  { "pan",      CPEN_(0,C2,3),  F_ARCHEXT },
  { "uao",      CPEN_ (0, C2, 4), F_ARCHEXT },
  { "nzcv",             CPEN_(3,C2,0),  0 },
  { "ssbs",     CPEN_(3,C2,6),  F_ARCHEXT },
  { "fpcr",             CPEN_(3,C4,0),  0 },
  { "fpsr",             CPEN_(3,C4,1),  0 },
  { "dspsr_el0",        CPEN_(3,C5,0),  0 },
  { "dlr_el0",          CPEN_(3,C5,1),  0 },
  { "spsr_el2",         CPEN_(4,C0,0),  0 }, /* = spsr_hyp */
  { "elr_el2",          CPEN_(4,C0,1),  0 },
  { "sp_el1",           CPEN_(4,C1,0),  0 },
  { "spsr_irq",         CPEN_(4,C3,0),  0 },
  { "spsr_abt",         CPEN_(4,C3,1),  0 },
  { "spsr_und",         CPEN_(4,C3,2),  0 },
  { "spsr_fiq",         CPEN_(4,C3,3),  0 },
  { "spsr_el3",         CPEN_(6,C0,0),  0 },
  { "elr_el3",          CPEN_(6,C0,1),  0 },
  { "sp_el2",           CPEN_(6,C1,0),  0 },
  ...

希望对你有所帮助。

【讨论】:

  • 绝对有帮助。谢谢。是否可以概述 GNU 实现了哪些符号寄存器名称?
  • 我能想到的最佳参考是您计划使用的确切版本的 GNU 的源代码 - 我用从 binutils 2.34 检索的相关代码部分扩充了上面的答案。 Ich hoffe das ist auch nützlich...
  • 顺便说一下,我看到你正在使用aarch64-suse-linux-gcc。我强烈建议对裸机使用ArmLinaro GCC 工具链。 Linux 发行版提供的交叉编译器更容易出现奇怪的问题,可能是因为它们的测试比 Arm/Linaro 的同类产品少——我的两分钱。一个好处是,人们可以使用与您使用的完全相同的编译器更轻松地重现问题。
  • 好的。我主要使用来自 ARM 的官方 GNU 工具链。但也尝试使用 openSUSE 包。到目前为止,我刚刚看到,我的问题已经存在于Stack Overflow。但是在我写我的问题时没有找到它。但你的回答更详细。
猜你喜欢
  • 1970-01-01
  • 2021-03-25
  • 2012-01-02
  • 1970-01-01
  • 2016-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
相关资源
最近更新 更多