Assembly 我能';是否重置GICv3相关寄存器的值?
我正在开发一个裸机中断控制器,GIC版本3。底层架构是Virt,带有QEMU和CPU Arm Cortex-72,aarch64。我使用以下命令运行项目:Assembly 我能';是否重置GICv3相关寄存器的值?,assembly,arm,arm64,Assembly,Arm,Arm64,我正在开发一个裸机中断控制器,GIC版本3。底层架构是Virt,带有QEMU和CPU Arm Cortex-72,aarch64。我使用以下命令运行项目: qemu-system-aarch64 -machine virt,gic-version=3 -cpu cortex-a72 -nographic -kernel kernel.elf 我无法重置GIC_GICC_BPR1_EL1的值,但可以将其设置为任何其他值。我在下面准备了一个测试函数: void test(void) { u
qemu-system-aarch64 -machine virt,gic-version=3 -cpu cortex-a72 -nographic -kernel kernel.elf
我无法重置GIC_GICC_BPR1_EL1的值,但可以将其设置为任何其他值。我在下面准备了一个测试函数:
void test(void) {
uint64_t state = 0;
// set Binary point to 0x07
SysReg_write_ICC_BPR1_EL1(0x07);
// read Binary point
state = SysReg_read_ICC_BPR1_EL1();
uart_puts("TEST - ICC_BPR1_EL1 (expected 0x7): ");
uart_puthex(state);
uart_puts("\n");
// set Binary point to 0
SysReg_write_ICC_BPR1_EL1(0x00);
// read Binary point
state = SysReg_read_ICC_BPR1_EL1();
uart_puts("TEST - ICC_BPR1_EL1 (expected 0): ");
uart_puthex(state);
uart_puts("\n");
}
读取和设置的功能包括:
uint64_t SysReg_read_ICC_BPR1_EL1(void)
{
uint64_t val;
asm volatile("mrs %0, s3_0_c12_c12_3" : "=r" (val));
return val;
}
// write system register ICC_BPR1_EL1 (s3_0_c12_c12_3) with specified value.
// source: /home/user/git/preprocessor/arm/SysReg_xml_v87A-2020-09/AArch64-icc_bpr1_el1.xml
void SysReg_write_ICC_BPR1_EL1(uint64_t val)
{
asm volatile("msr s3_0_c12_c12_3 , %0" : : "r" (val));
}
其中,s3_0_c12_c12_3
是根据arm规范的寄存器ID,因为GICC相关寄存器被定义为“没有架构名称的寄存器”
此示例的输出为:
TEST - ICC_BPR1_EL1 (expected 0x7): 0x00000000 00000007
TEST - ICC_BPR1_EL1 (expected 0): 0x00000000 00000001
我使用了uart,但您也可以使用gdb,方法是使用void test(void)函数的汇编代码并使用标签
因此,我无法以任何方式将其设置为0。
你知道我哪里错了吗?我无法重现你的问题,你的功能在我的设置中运行良好。但是,我可能有一组不同的gcc/qemu-sytem-aarch64/gdb minimal-aarch64.c:
#include <stdint.h>
uint64_t raw_read_gic_gicc_bpr1_el1(void) {
uint64_t gicc_bpr1_el1 = 0;
__asm__ __volatile__("mrs %0, s3_0_c12_c12_3\n\t" : "=r" (gicc_bpr1_el1) : : "memory");
return gicc_bpr1_el1;
}
void set_gic_gicc_bpr1_el1(uint64_t value)
{
__asm__ __volatile__("msr s3_0_c12_c12_3, %0\n\t" : : "r" (value) : "memory");
}
int main(int argc, char** argv)
{
uint64_t state = 0;
set_gic_gicc_bpr1_el1(0x00);
state = raw_read_gic_gicc_bpr1_el1();
set_gic_gicc_bpr1_el1(0x07);
state = raw_read_gic_gicc_bpr1_el1();
}
启动QEMU:
/opt/qemu-5.2.0/bin/qemu-system-aarch64 -semihosting -m 1M -nographic -serial telnet::4444,server,nowait -machine virt,gic-version=3,secure=on,virtualization=off -S -gdb tcp::1234,ipv4 -cpu cortex-a72 -kernel minimal-aarch64.elf
启动GDB:
/opt/gdb/gdb-10.1-aarch64-elf-x86_64-linux-gnu/bin/aarch64-elf-gdb -tui --quiet -nx -ex 'target remote localhost:1234' -ex 'load' --ex 'b main' minimal-aarch64.elf
全球发展集团会议:
remote Thread 1.1 In: main L23 PC: 0x400360
Loading section .text, size 0x3894 lma 0x400040
Loading section .fini, size 0x34 lma 0x4038d4
Loading section .rodata, size 0x74 lma 0x403908
Loading section .eh_frame, size 0x4 lma 0x40397c
Loading section .init_array, size 0x8 lma 0x413980
Loading section .fini_array, size 0x8 lma 0x413988
Loading section .data, size 0x10c8 lma 0x413990
Start address 0x0000000000400178, load size 19020
Transfer rate: 1326 KB/sec, 1118 bytes/write.
Breakpoint 1 at 0x400338: file minimal-aarch64.c, line 16.
(gdb) c
Continuing.
Breakpoint 1, main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:16
(gdb) p/x state
$1 = 0x0
(gdb) step
set_gic_gicc_bpr1_el1 (value=0) at minimal-aarch64.c:11
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:19
(gdb) p/x state
$2 = 0x0
(gdb) step
raw_read_gic_gicc_bpr1_el1 () at minimal-aarch64.c:4
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:21
set_gic_gicc_bpr1_el1 (value=7) at minimal-aarch64.c:11
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:22
raw_read_gic_gicc_bpr1_el1 () at minimal-aarch64.c:4
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:23
(gdb) p/x state
$3 = 0x7
(gdb)
请注意,某些值可能无效,至少根据(我在A72文档中找不到信息):
但根据2020-12版:
这可能解释了为什么您不能在
ICC-BPR1-EL1
中写入0值,亲爱的Frant,感谢您的回答,它在制定更好的问题时帮助了我很多,所以我在您修改您的答案时对其进行了修改。基本上,它帮助了我。与您不同的是,我可以将寄存器设置为任何值(例如0x07),但不能设置为(0x00)。如果我设置0x00,它将变为0x01。。我无法解释。我将准确地复制您的代码。来源:Arm Armv8-A体系结构寄存器-此寄存器的非安全副本的最小值是ICC_BPR0_EL1+1的最小值。此寄存器的安全副本的最小值为ICC_BPR0_EL1的最小值。问题解决了,再次感谢!
remote Thread 1.1 In: main L23 PC: 0x400360
Loading section .text, size 0x3894 lma 0x400040
Loading section .fini, size 0x34 lma 0x4038d4
Loading section .rodata, size 0x74 lma 0x403908
Loading section .eh_frame, size 0x4 lma 0x40397c
Loading section .init_array, size 0x8 lma 0x413980
Loading section .fini_array, size 0x8 lma 0x413988
Loading section .data, size 0x10c8 lma 0x413990
Start address 0x0000000000400178, load size 19020
Transfer rate: 1326 KB/sec, 1118 bytes/write.
Breakpoint 1 at 0x400338: file minimal-aarch64.c, line 16.
(gdb) c
Continuing.
Breakpoint 1, main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:16
(gdb) p/x state
$1 = 0x0
(gdb) step
set_gic_gicc_bpr1_el1 (value=0) at minimal-aarch64.c:11
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:19
(gdb) p/x state
$2 = 0x0
(gdb) step
raw_read_gic_gicc_bpr1_el1 () at minimal-aarch64.c:4
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:21
set_gic_gicc_bpr1_el1 (value=7) at minimal-aarch64.c:11
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:22
raw_read_gic_gicc_bpr1_el1 () at minimal-aarch64.c:4
main (argc=1, argv=0x400fffe0) at minimal-aarch64.c:23
(gdb) p/x state
$3 = 0x7
(gdb)
The minimum value implemented of ICC_BPR1_EL1 Secure register is 0x2.
The minimum value implemented of ICC_BPR1_EL1 Non-secure register is 0x3.