1

我有一些在 QEMU 中运行的裸机 AARCH64 软件。我正在尝试从 EL2 访问 GICv3 系统寄存器 ICH_*,但是当我读/写它时我不断收到异常。

ESR 0x2000000: ec 0x0, il 0x2000000, iss 0x0


x0  0xffffffff000bd2c0 x1                 0x3 x2  0xffff00004808cd50 x3  0xffff00004808cd20
x4          0x77616974 x5          0x65766e74 x6          0x74696d72 x7                   0
x8                   0 x9          0xffffffff x10 0xffff0000401fc870 x11 0x4a49524200000000
x12                  0 x13 0xffffffff00131000 x14 0xffff000042290000 x15 0xffff0000401fc730
x16 0xffffffff00117100 x17 0xffff0000401feb80 x18 0xffffffff00117100 x19 0xffff00004808ccb0
x20                  0 x21 0xffff0083dd174db8 x22 0xffff00004808cd38 x23 0xffff00004806eba8
x24 0xffff00004806f028 x25 0xffff00004808ccc8 x26 0xffff0083dd174e18 x27            0x80000
x28                0x1 x29 0xffff0083dd174d50 lr  0xffffffff000bc5a0 usp                  0
elr  0xffffffff000bd2c0
spsr         0x20000305

我通过设置 ICC_SRE_EL2 寄存器启用了 SRE

我错过了什么吗?

-金

4

1 回答 1

1

以下是您的用例的最小、完整和可验证示例:

a) 在以下位置创建ich_hcr_l2.S文件/tmp

#define             ICH_HCR_EL2 S3_4_C12_C11_0

                    .arch   armv8-a
                    .globl _start
                    .text
_start:
#ifdef __RETURN_CURRENT_EL__
                    // test only - returning CurrentEL
                    mrs  x0, CurrentEL
                    ubfx x0, x0,2,2
#else
                    mrs x0, ICH_HCR_EL2
#endif
                    // exiting/returning w0 using Angel/Semihosting interface
                    adr x1, status
                    str w0, [x1]
                    mov w0, #0x18
                    adr x1, code
                    hlt #0xf000     

                    .data
                    .balign 8
code:               .dword 0x00020026
status:             .dword 0x00000000
                    .end

b) 创建一个名为ich_hcr_l2.shin的可执行 shell 脚本/tmp

#!/bin/bash

# Absolute path to this script. /home/user/bin/foo.sh
SCRIPT=$(readlink -f $BASH_SOURCE)

# Absolute path this script is in. /home/user/bin
SCRIPTPATH=$(dirname $SCRIPT)

set -e 
QEMU_VERSION=2.11.0
QEMU_SYSTEM_ARM=${SCRIPTPATH}/qemu/bin/qemu-system-aarch64

build_qemu()
{
  if [ ! -f ${SCRIPTPATH}/qemu/bin/qemu-system-aarch64 ]
  then
    if [ ! -f ${SCRIPTPATH}/qemu-${QEMU_VERSION}.tar.xz ]
    then
      wget https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz
    fi
    rm -rf ${SCRIPTPATH}/qemu-${QEMU_VERSION}
    tar Jxf ${SCRIPTPATH}/qemu-${QEMU_VERSION}.tar.xz -C ${SCRIPTPATH}
    pushd qemu-${QEMU_VERSION}
    ./configure --target-list="aarch64-softmmu" --prefix=${SCRIPTPATH}/qemu
    make all install
    popd
  fi
}

build_example()
{
  aarch64-linux-gnu-gcc ${CFLAGS} -nostartfiles -nodefaultlibs -Wl,-Ttext=0x0000000042000000 -o ${SCRIPTPATH}/ich_hcr_l2.elf ${SCRIPTPATH}/ich_hcr_l2.S
  aarch64-linux-gnu-objdump -D ${SCRIPTPATH}/ich_hcr_l2.elf > ${SCRIPTPATH}/ich_hcr_l2.lst
}

run_example()
{
  # exit code will be the context at w0 register.
  ${QEMU_SYSTEM_ARM} -m 256M -semihosting -machine virt,gic-version=3,virtualization=on,secure=${SECURE} -monitor telnet:127.0.0.1:1235,server,nowait -cpu cortex-a53 -nographic -kernel ${SCRIPTPATH}/ich_hcr_l2.elf
  printf "Program returned with w0=%d\n" $?
}

# main
build_example
build_qemu
set +e 
# testing program - should return CurrentEL=2
CFLAGS="-D__RETURN_CURRENT_EL__"
SECURE=off
build_example
run_example

# testing program - should return CurrentEL=3
CFLAGS="-D__RETURN_CURRENT_EL__"
SECURE=on
build_example
run_example

# actual test case: retrieving ICH_HCR_L2 at EL2:
CFLAGS=""
SECURE=off
build_example
run_example

c) 将 /tmp 设为当前工作目录,然后执行 ich_hcr_l2.sh,然后耐心等待:脚本将下载,然后从其源代码构建 qemu-system-aarch64 2.11.0。

过了一会儿,您应该会看到以下两个三个正在显示:

Program returned with w0=2
Program returned with w0=3
Program returned with w0=0

和 /tmp/ich_hcr_l2.lst 应该包含:

/home/eperie/aarch64/ich_hcr_l2.elf:     file format elf64-littleaarch64


Disassembly of section .text:

0000000042000000 <_start>:
    42000000:   d53ccb00        mrs     x0, s3_4_c12_c11_0
    42000004:   100800e1        adr     x1, 42010020 <status>
    42000008:   b9000020        str     w0, [x1]
    4200000c:   52800300        mov     w0, #0x18                       // #24
    42000010:   10080041        adr     x1, 42010018 <code>
    42000014:   d45e0000        hlt     #0xf000

Disassembly of section .note.gnu.build-id:

0000000000400120 <.note.gnu.build-id>:
  400120:       00000004        .inst   0x00000004 ; undefined
  400124:       00000014        .inst   0x00000014 ; undefined
  400128:       00000003        .inst   0x00000003 ; undefined
  40012c:       00554e47        .inst   0x00554e47 ; undefined
  400130:       e7c953ee        .inst   0xe7c953ee ; undefined
  400134:       d3437b0f        ubfx    x15, x24, #3, #28
  400138:       2edb19d4        .inst   0x2edb19d4 ; undefined
  40013c:       9350921e        sbfx    x30, x16, #16, #21
  400140:       ea5adf9d        ands    x29, x28, x26, lsr #55

Disassembly of section .data:

0000000042010018 <code>:
    42010018:   00020026        .word   0x00020026
    4201001c:   00000000        .word   0x00000000

0000000042010020 <status>:
        ...
于 2018-02-08T18:35:24.050 回答