QEMUの続き。独自ターゲットでビルドしてみる。myriscvx64
コンフィグレーションを用意した。
../configure --disable-werror --target-list=myriscvx64-softmmu make -j$(nproc)
default_configs/myriscvx64-softmmu.mak
# Default configuration for myriscvx64-softmmu # Uncomment the following lines to disable these optional devices: # #CONFIG_PCI_DEVICES=n # Boards: # CONFIG_SPIKE=y CONFIG_SIFIVE_E=y CONFIG_SIFIVE_U=y CONFIG_RISCV_VIRT=y
$ ../configure --disable-werror --target-list=myriscvx64-softmmu $ make -j$(nproc)
以下のようなエラーメッセージが表示された。cpu.h
はすべてのターゲットで必須なのか?
/home/msyksphinz/work/riscv/qemu/tcg/tcg-op.c:26:10: fatal error: cpu.h: No such file or directory #include "cpu.h" ^~~~~~~ compilation terminated. /home/msyksphinz/work/riscv/qemu/tcg/tcg-op-vec.c:21:10: fatal error: cpu.h: No such file or directory #include "cpu.h" ^~~~~~~ compilation terminated. In file included from /home/msyksphinz/work/riscv/qemu/exec-vary.c:25:
$ git find cpu.h
${BASE}/qemu/include/hw/acpi/cpu.h ${BASE}/qemu/include/hw/core/cpu.h ${BASE}/qemu/include/migration/cpu.h ${BASE}/qemu/target/alpha/cpu.h ${BASE}/qemu/target/arm/cpu.h ${BASE}/qemu/target/cris/cpu.h ${BASE}/qemu/target/hppa/cpu.h ${BASE}/qemu/target/i386/cpu.h ${BASE}/qemu/target/lm32/cpu.h ${BASE}/qemu/target/m68k/cpu.h ${BASE}/qemu/target/microblaze/cpu.h ${BASE}/qemu/target/mips/cpu.h ${BASE}/qemu/target/moxie/cpu.h ${BASE}/qemu/target/nios2/cpu.h ${BASE}/qemu/target/openrisc/cpu.h ${BASE}/qemu/target/ppc/cpu.h ${BASE}/qemu/target/riscv/cpu.h ${BASE}/qemu/target/rx/cpu.h ${BASE}/qemu/target/s390x/cpu.h ${BASE}/qemu/target/sh4/cpu.h ${BASE}/qemu/target/sparc/cpu.h ${BASE}/qemu/target/tilegx/cpu.h ${BASE}/qemu/target/tricore/cpu.h ${BASE}/qemu/target/unicore32/cpu.h ${BASE}/qemu/target/xtensa/cpu.h
${BASE}/qemu/target/myriscvx/cpu.h
を作ってみる。
#ifndef MYRISCVX_CPU_H #define MYRISCVX_CPU_H #endif /* MYRISCVX_CPU_H */
するとバンバンエラーが出てきた。
CC myriscvx64-softmmu/fpu/softfloat.o CC myriscvx64-softmmu/disas.o GEN myriscvx64-softmmu/gdbstub-xml.c In file included from /home/msyksphinz/work/riscv/qemu/include/exec/exec-all.h:26, from /home/msyksphinz/work/riscv/qemu/tcg/tcg.c:45: /home/msyksphinz/work/riscv/qemu/include/exec/cpu_ldst.h:93:9: error: unknown type name 'target_ulong' typedef target_ulong abi_ptr; ^~~~~~~~~~~~ /home/msyksphinz/work/riscv/qemu/include/exec/cpu_ldst.h:97:24: error: unknown type name 'CPUArchState'; did you mean 'CPUState'? uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr); ^~~~~~~~~~~~ CPUState /home/msyksphinz/work/riscv/qemu/include/exec/cpu_ldst.h:98:24: error: unknown type name 'CPUArchState'; did you mean 'CPUState'? uint32_t cpu_lduw_data(CPUArchState *env, abi_ptr ptr); ^~~~~~~~~~~~ CPUState /home/msyksphinz/work/riscv/qemu/include/exec/cpu_ldst.h:99:23: error: unknown type name 'CPUArchState'; did you mean 'CPUState'? uint32_t cpu_ldl_data(CPUArchState *env, abi_ptr ptr); ^~~~~~~~~~~~ CPUState
target_ulong
はcpu-defs.h
に定義がある。また、アーキテクチャの定義するビット長はcpu-param.h
で決定するようだ。
qemu/include/exec/cpu-defs.h
/* target_ulong is the type of a virtual address */ #if TARGET_LONG_SIZE == 4 typedef int32_t target_long; typedef uint32_t target_ulong; #define TARGET_FMT_lx "%08x" #define TARGET_FMT_ld "%d" #define TARGET_FMT_lu "%u" #elif TARGET_LONG_SIZE == 8 typedef int64_t target_long; typedef uint64_t target_ulong; #define TARGET_FMT_lx "%016" PRIx64 #define TARGET_FMT_ld "%" PRId64 #define TARGET_FMT_lu "%" PRIu64 #else #error TARGET_LONG_SIZE undefined #endif
qemu/target/riscv/cpu-param.h
#if defined(TARGET_RISCV64) # define TARGET_LONG_BITS 64 # define TARGET_PHYS_ADDR_SPACE_BITS 56 /* 44-bit PPN */ # define TARGET_VIRT_ADDR_SPACE_BITS 48 /* sv48 */ #elif defined(TARGET_RISCV32) # define TARGET_LONG_BITS 32 # define TARGET_PHYS_ADDR_SPACE_BITS 34 /* 22-bit PPN */ # define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */ #endif
MYRISCVXでは64ビットのみとした。
qemu/target/myriscvx/cpu-param.h
#ifndef MYRISCVX_CPU_PARAM_H #define MYRISCVX_CPU_PARAM_H 1 #define TARGET_LONG_BITS 64 #endif
RISC-VではTARGET_RISCV64
とTARGET_RISCV32
で条件分けがされているが...
build/riscv64-softmmu/config-target.mak
# Automatically generated by configure - do not modify TARGET_RISCV64=y TARGET_NAME=riscv64 TARGET_BASE_ARCH=riscv TARGET_ABI_DIR=riscv CONFIG_SOFTMMU=y TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-cpu.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-32bit-fpu.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-fpu.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-csr.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-virtual.xml CONFIG_I386_DIS=y CONFIG_RISCV_DIS=y QEMU_LDFLAGS+= QEMU_CFLAGS+=
なるほど、ここでTARGET_RISCV64
が定義される。では、TARGET_MYRISCVX64
は、
build-myriscvx/myriscvx64-softmmu/config-target.mak
TARGET_MYRISCVX64=y TARGET_NAME=myriscvx64 TARGET_BASE_ARCH=myriscvx TARGET_ABI_DIR=myriscvx CONFIG_SOFTMMU=y TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-cpu.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-32bit-fpu.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-fpu.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-csr.xml /home/msyksphinz/work/riscv/qemu/gdb-xml/riscv-64bit-virtual.xml CONFIG_I386_DIS=y QEMU_LDFLAGS+= QEMU_CFLAGS+=
ここで定義されているのか。
次はCPUArchState
の定義だ。これはCPUそのものを定義するのか?RISC-Vでは以下のような定義になっていた。
qemu/target/riscv/cpu.h
typedef struct CPURISCVState CPURISCVState; struct CPURISCVState { target_ulong gpr[32]; uint64_t fpr[32]; /* assume both F and D extensions */ target_ulong pc; target_ulong load_res; target_ulong load_val; ... float_status fp_status; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *timer; /* Internal timer */ }; ... typedef CPURISCVState CPUArchState; typedef RISCVCPU ArchCPU;
なるほど、ここでCPU機能全体を定義するのか。まずは簡単なものだけ定義しておこう。PCも必要なようだ。
qemu/target/riscv/cpu.h
typedef struct CPUMYRISCVXState { target_ulong gpr[32]; target_ulong pc; } CPURISCVState; typedef CPURISCVState CPUArchState; typedef RISCVCPU ArchCPU; #include "exec/cpu-all.h"
最後のcpu-all.h
はなんとなくRISC-V版の実装でも入っていたし、便利なユーティリティが入っているようだったので入れてみた。
まだエラーがある。いろんなパラメータをcpu-param.h
で設定しなければならないらしい。
/home/msyksphinz/work/riscv/qemu/include/exec/cpu-defs.h:43:3: error: #error NB_MMU_MODES must be defined in cpu-param.h # error NB_MMU_MODES must be defined in cpu-param.h ^~~~~ In file included from /home/msyksphinz/work/riscv/qemu/target/myriscvx/cpu.h:24, from /home/msyksphinz/work/riscv/qemu/tcg/tcg-op-vec.c:21: /home/msyksphinz/work/riscv/qemu/include/exec/cpu-defs.h:43:3: error: #error NB_MMU_MODES must be defined in cpu-param.h # error NB_MMU_MODES must be defined in cpu-param.h ^~~~~ /home/msyksphinz/work/riscv/qemu/include/exec/cpu-defs.h:46:3: error: #error TARGET_PHYS_ADDR_SPACE_BITS must be defined in cpu-param.h # error TARGET_PHYS_ADDR_SPACE_BITS must be defined in cpu-param.h ^~~~~ In file included from /home/msyksphinz/work/riscv/qemu/target/myriscvx/cpu.h:24, from /home/msyksphinz/work/riscv/qemu/include/tcg/tcg.h:28, from /home/msyksphinz/work/riscv/qemu/tcg/tcg-op-gvec.c:21: /home/msyksphinz/work/riscv/qemu/include/exec/cpu-defs.h:43:3: error: #error NB_MMU_MODES must be defined in cpu-param.
NB_MMU_MODES
のNB
って何だ?
qemu/target/myriscvx/cpu-param.h
#if defined(TARGET_MYRISCVX64) #define TARGET_LONG_BITS 64 #define TARGET_PHYS_ADDR_SPACE_BITS 56 /* 44-bit PPN */ #define TARGET_VIRT_ADDR_SPACE_BITS 39 /* sv39 */ #endif // defined(TARGET_RISCV64) #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */ #define NB_MMU_MODES 4