Assembly 我能';是否重置GICv3相关寄存器的值?

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

我正在开发一个裸机中断控制器,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) {
    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.