diff --git a/.gitlab-ci-opensbi.yml b/.gitlab-ci-opensbi.yml new file mode 100644 index 0000000000..dd051c0124 --- /dev/null +++ b/.gitlab-ci-opensbi.yml @@ -0,0 +1,63 @@ +docker-opensbi: + stage: build + rules: # Only run this job when the Dockerfile is modified + - changes: + - .gitlab-ci-opensbi.yml + - .gitlab-ci.d/opensbi/Dockerfile + when: always + image: docker:19.03.1 + services: + - docker:19.03.1-dind + variables: + GIT_DEPTH: 3 + IMAGE_TAG: $CI_REGISTRY_IMAGE:opensbi-cross-build + # We don't use TLS + DOCKER_HOST: tcp://docker:2375 + DOCKER_TLS_CERTDIR: "" + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + script: + - docker pull $IMAGE_TAG || true + - docker build --cache-from $IMAGE_TAG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA + --tag $IMAGE_TAG .gitlab-ci.d/opensbi + - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA + - docker push $IMAGE_TAG + +build-opensbi: + rules: # Only run this job when ... + - changes: # ... roms/opensbi/ is modified (submodule updated) + - roms/opensbi/* + when: always + - if: '$CI_COMMIT_REF_NAME =~ /^opensbi/' # or the branch/tag starts with 'opensbi' + when: always + - if: '$CI_COMMIT_MESSAGE =~ /opensbi/i' # or last commit description contains 'OpenSBI' + when: always + artifacts: + paths: # 'artifacts.zip' will contains the following files: + - pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin + - pc-bios/opensbi-riscv32-virt-fw_jump.bin + - pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin + - pc-bios/opensbi-riscv64-virt-fw_jump.bin + - opensbi32-virt-stdout.log + - opensbi32-virt-stderr.log + - opensbi64-virt-stdout.log + - opensbi64-virt-stderr.log + - opensbi32-sifive_u-stdout.log + - opensbi32-sifive_u-stderr.log + - opensbi64-sifive_u-stdout.log + - opensbi64-sifive_u-stderr.log + image: $CI_REGISTRY_IMAGE:opensbi-cross-build + variables: + GIT_DEPTH: 3 + script: # Clone the required submodules and build OpenSBI + - git submodule update --init roms/opensbi + - export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1)) + - echo "=== Using ${JOBS} simultaneous jobs ===" + - make -j${JOBS} -C roms/opensbi clean + - make -j${JOBS} -C roms opensbi32-virt 2>&1 1>opensbi32-virt-stdout.log | tee -a opensbi32-virt-stderr.log >&2 + - make -j${JOBS} -C roms/opensbi clean + - make -j${JOBS} -C roms opensbi64-virt 2>&1 1>opensbi64-virt-stdout.log | tee -a opensbi64-virt-stderr.log >&2 + - make -j${JOBS} -C roms/opensbi clean + - make -j${JOBS} -C roms opensbi32-sifive_u 2>&1 1>opensbi32-sifive_u-stdout.log | tee -a opensbi32-sifive_u-stderr.log >&2 + - make -j${JOBS} -C roms/opensbi clean + - make -j${JOBS} -C roms opensbi64-sifive_u 2>&1 1>opensbi64-sifive_u-stdout.log | tee -a opensbi64-sifive_u-stderr.log >&2 diff --git a/.gitlab-ci.d/opensbi/Dockerfile b/.gitlab-ci.d/opensbi/Dockerfile new file mode 100644 index 0000000000..4ba8a4de86 --- /dev/null +++ b/.gitlab-ci.d/opensbi/Dockerfile @@ -0,0 +1,33 @@ +# +# Docker image to cross-compile OpenSBI firmware binaries +# +FROM ubuntu:18.04 + +MAINTAINER Bin Meng + +# Install packages required to build OpenSBI +RUN apt update \ + && \ + \ + DEBIAN_FRONTEND=noninteractive \ + apt install --assume-yes --no-install-recommends \ + build-essential \ + ca-certificates \ + git \ + make \ + wget \ + && \ + \ + rm -rf /var/lib/apt/lists/* + +# Manually install the kernel.org "Crosstool" based toolchains for gcc-8.3 +RUN wget -O - \ + https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.3.0/x86_64-gcc-8.3.0-nolibc-riscv32-linux.tar.xz \ + | tar -C /opt -xJ +RUN wget -O - \ + https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.3.0/x86_64-gcc-8.3.0-nolibc-riscv64-linux.tar.xz \ + | tar -C /opt -xJ + +# Export the toolchains to the system path +ENV PATH="/opt/gcc-8.3.0-nolibc/riscv32-linux/bin:${PATH}" +ENV PATH="/opt/gcc-8.3.0-nolibc/riscv64-linux/bin:${PATH}" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 72f8b8aa51..b889fb96b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ include: - local: '/.gitlab-ci-edk2.yml' + - local: '/.gitlab-ci-opensbi.yml' before_script: - apt-get update -qq diff --git a/Makefile b/Makefile index 7df22fcc5d..ea0e08fc57 100644 --- a/Makefile +++ b/Makefile @@ -848,7 +848,7 @@ u-boot.e500 u-boot-sam460-20100605.bin \ qemu_vga.ndrv \ edk2-licenses.txt \ hppa-firmware.img \ -opensbi-riscv32-virt-fw_jump.bin \ +opensbi-riscv32-sifive_u-fw_jump.bin opensbi-riscv32-virt-fw_jump.bin \ opensbi-riscv64-sifive_u-fw_jump.bin opensbi-riscv64-virt-fw_jump.bin diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 156a003642..4409ea1ccc 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -56,7 +56,11 @@ #include -#define BIOS_FILENAME "opensbi-riscv64-sifive_u-fw_jump.bin" +#if defined(TARGET_RISCV32) +# define BIOS_FILENAME "opensbi-riscv32-sifive_u-fw_jump.bin" +#else +# define BIOS_FILENAME "opensbi-riscv64-sifive_u-fw_jump.bin" +#endif static const struct MemmapEntry { hwaddr base; diff --git a/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin b/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin new file mode 100644 index 0000000000..bab13f597a Binary files /dev/null and b/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin differ diff --git a/pc-bios/opensbi-riscv32-virt-fw_jump.bin b/pc-bios/opensbi-riscv32-virt-fw_jump.bin index 6c5b7b89f6..c9654e7047 100644 Binary files a/pc-bios/opensbi-riscv32-virt-fw_jump.bin and b/pc-bios/opensbi-riscv32-virt-fw_jump.bin differ diff --git a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin index 971f2be405..77f4dc8f83 100644 Binary files a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin and b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin differ diff --git a/pc-bios/opensbi-riscv64-virt-fw_jump.bin b/pc-bios/opensbi-riscv64-virt-fw_jump.bin index 45a5aed1ce..31e74d12ea 100644 Binary files a/pc-bios/opensbi-riscv64-virt-fw_jump.bin and b/pc-bios/opensbi-riscv64-virt-fw_jump.bin differ diff --git a/roms/Makefile b/roms/Makefile index 28e1e557b0..f9acf39954 100644 --- a/roms/Makefile +++ b/roms/Makefile @@ -66,6 +66,7 @@ default help: @echo " efi -- update UEFI (edk2) platform firmware" @echo " opensbi32-virt -- update OpenSBI for 32-bit virt machine" @echo " opensbi64-virt -- update OpenSBI for 64-bit virt machine" + @echo " opensbi32-sifive_u -- update OpenSBI for 32-bit sifive_u machine" @echo " opensbi64-sifive_u -- update OpenSBI for 64-bit sifive_u machine" @echo " bios-microvm -- update bios-microvm.bin (qboot)" @echo " clean -- delete the files generated by the previous" \ @@ -181,6 +182,12 @@ opensbi64-virt: PLATFORM="qemu/virt" cp opensbi/build/platform/qemu/virt/firmware/fw_jump.bin ../pc-bios/opensbi-riscv64-virt-fw_jump.bin +opensbi32-sifive_u: + $(MAKE) -C opensbi \ + CROSS_COMPILE=$(riscv32_cross_prefix) \ + PLATFORM="sifive/fu540" + cp opensbi/build/platform/sifive/fu540/firmware/fw_jump.bin ../pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin + opensbi64-sifive_u: $(MAKE) -C opensbi \ CROSS_COMPILE=$(riscv64_cross_prefix) \ diff --git a/roms/opensbi b/roms/opensbi index be92da280d..ac5e821d50 160000 --- a/roms/opensbi +++ b/roms/opensbi @@ -1 +1 @@ -Subproject commit be92da280d87c38a2e0adc5d3f43bab7b5468f09 +Subproject commit ac5e821d50be631f26274765a59bc1b444ffd862 diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 5ea5d133aa..d3ba9efb02 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -46,7 +46,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env) target_ulong pending = env->mip & env->mie & ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); target_ulong vspending = (env->mip & env->mie & - (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)) >> 1; + (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)); target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && mstatus_mie); @@ -907,6 +907,13 @@ void riscv_cpu_do_interrupt(CPUState *cs) if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) && !force_hs_execp) { + /* + * See if we need to adjust cause. Yes if its VS mode interrupt + * no if hypervisor has delegated one of hs mode's interrupt + */ + if (cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT || + cause == IRQ_VS_EXT) + cause = cause - 1; /* Trap to VS mode */ } else if (riscv_cpu_virt_enabled(env)) { /* Trap into HS mode, from virt */ diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 8736f689c2..c6412f680c 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -85,7 +85,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb) } if (env->priv_ver >= PRIV_VERSION_1_10_0 && - get_field(env->mstatus, MSTATUS_TSR)) { + get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) { riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); }