ARM64 (Cortex-A53) - GNU 汇编程序 - GIC 寄存器:未知或缺少系统寄存器名称
ARM64 (Cortex-A53) - GNU Assembler - GIC register: unknown or missing system register name
我已经为 Cortex-A53 启动了一个简单的裸机应用程序。现在我想实现中断,但我 运行 遇到了问题。想读取寄存器 ICC_SRE_ELx
来判断 SRE
flag,想知道是否一定要使用内存映射的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 版本:
我使用的包 OS (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'.
GNU AS 不知道所有 Aarch64
符号系统寄存器名称,您需要用其 op0,op1,CRn,CRm,op2
编码替换 ICC_SRE_EL2
,即 s3_4_c12_c9_5
- 请参阅到 Arm 文档 here(查找 'Accessing the 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 },
...
希望对您有所帮助。
我已经为 Cortex-A53 启动了一个简单的裸机应用程序。现在我想实现中断,但我 运行 遇到了问题。想读取寄存器 ICC_SRE_ELx
来判断 SRE
flag,想知道是否一定要使用内存映射的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 版本:
我使用的包 OS (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'.
GNU AS 不知道所有 Aarch64
符号系统寄存器名称,您需要用其 op0,op1,CRn,CRm,op2
编码替换 ICC_SRE_EL2
,即 s3_4_c12_c9_5
- 请参阅到 Arm 文档 here(查找 'Accessing the 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 },
...
希望对您有所帮助。