aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.d/buildtest.yml62
-rw-r--r--.gitlab-ci.d/cirrus.yml2
-rw-r--r--.gitlab-ci.d/crossbuilds.yml46
-rw-r--r--.gitlab-ci.d/static_checks.yml6
-rwxr-xr-xconfigure23
-rw-r--r--docs/about/build-platforms.rst2
-rw-r--r--docs/about/deprecated.rst9
-rw-r--r--docs/system/arm/aspeed.rst31
-rw-r--r--hw/arm/Kconfig3
-rw-r--r--hw/arm/aspeed.c107
-rw-r--r--hw/arm/aspeed_ast10x0.c2
-rw-r--r--hw/arm/aspeed_ast2600.c76
-rw-r--r--hw/arm/aspeed_ast27x0-fc.c77
-rw-r--r--hw/arm/aspeed_ast27x0.c74
-rw-r--r--hw/arm/aspeed_soc_common.c96
-rw-r--r--hw/misc/aspeed_sbc.c197
-rw-r--r--hw/misc/trace-events6
-rw-r--r--hw/nvram/aspeed_otp.c190
-rw-r--r--hw/nvram/meson.build4
-rw-r--r--hw/nvram/trace-events5
-rw-r--r--hw/pci-host/Kconfig4
-rw-r--r--hw/pci-host/aspeed_pcie.c1015
-rw-r--r--hw/pci-host/meson.build1
-rw-r--r--hw/pci-host/trace-events11
-rw-r--r--include/hw/arm/aspeed_soc.h23
-rw-r--r--include/hw/misc/aspeed_sbc.h6
-rw-r--r--include/hw/nvram/aspeed_otp.h33
-rw-r--r--include/hw/pci-host/aspeed_pcie.h137
-rw-r--r--include/hw/pci/pci_ids.h2
-rw-r--r--meson.build34
-rw-r--r--rust/bql/meson.build1
-rw-r--r--rust/chardev/meson.build1
-rw-r--r--rust/hw/char/pl011/meson.build1
-rw-r--r--rust/hw/core/meson.build1
-rw-r--r--rust/migration/meson.build3
-rw-r--r--rust/qom/meson.build1
-rw-r--r--rust/system/meson.build1
-rw-r--r--rust/util/meson.build1
-rwxr-xr-xscripts/archive-source.sh34
-rw-r--r--scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml5
-rw-r--r--scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml5
-rwxr-xr-xscripts/rust-to-clang-target-test.sh43
-rw-r--r--scripts/rust-to-clang-target.sh60
-rwxr-xr-xtests/docker/common.rc13
-rw-r--r--tests/docker/dockerfiles/alpine.docker6
-rw-r--r--tests/docker/dockerfiles/centos9.docker4
-rw-r--r--tests/docker/dockerfiles/debian-amd64-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian-arm64-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian-armhf-cross.docker21
-rw-r--r--tests/docker/dockerfiles/debian-i686-cross.docker20
-rw-r--r--tests/docker/dockerfiles/debian-mips64el-cross.docker9
-rw-r--r--tests/docker/dockerfiles/debian-mipsel-cross.docker9
-rw-r--r--tests/docker/dockerfiles/debian-ppc64el-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian-riscv64-cross.docker116
-rw-r--r--tests/docker/dockerfiles/debian-s390x-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian.docker18
-rw-r--r--tests/docker/dockerfiles/emsdk-wasm32-cross.docker2
-rw-r--r--tests/docker/dockerfiles/fedora-rust-nightly.docker18
-rw-r--r--tests/docker/dockerfiles/fedora-win64-cross.docker15
-rw-r--r--tests/docker/dockerfiles/fedora.docker18
-rw-r--r--tests/docker/dockerfiles/opensuse-leap.docker7
-rw-r--r--tests/docker/dockerfiles/ubuntu2204.docker7
-rwxr-xr-xtests/functional/aarch64/test_aspeed_ast2700.py4
-rwxr-xr-xtests/functional/arm/test_aspeed_ast1030.py24
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2600.py36
-rw-r--r--tests/functional/aspeed.py8
m---------tests/lcitool/libvirt-ci0
-rw-r--r--tests/lcitool/projects/qemu.yml3
-rwxr-xr-xtests/lcitool/refresh49
-rwxr-xr-xtests/vm/freebsd4
-rw-r--r--ui/gtk-egl.c5
-rw-r--r--ui/gtk-gl-area.c5
-rw-r--r--ui/icons/qemu.svg21
-rw-r--r--ui/sdl2.c2
-rw-r--r--ui/spice-core.c6
-rw-r--r--ui/spice-display.c4
76 files changed, 2619 insertions, 348 deletions
diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index e296fc3..0502094 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -36,7 +36,7 @@ build-system-ubuntu:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-ubuntu2204-container
+ - job: amd64-ubuntu2204-container
variables:
IMAGE: ubuntu2204
CONFIGURE_ARGS: --enable-docs
@@ -66,7 +66,7 @@ build-system-debian:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-debian-container
+ - job: amd64-debian-container
variables:
IMAGE: debian
CONFIGURE_ARGS: --with-coroutine=sigaltstack --enable-rust
@@ -109,7 +109,7 @@ build-system-fedora:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-fedora-container
+ - job: amd64-fedora-container
variables:
IMAGE: fedora
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs --enable-crypto-afalg --enable-rust
@@ -122,7 +122,7 @@ build-system-fedora-rust-nightly:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-fedora-rust-nightly-container
+ - job: amd64-fedora-rust-nightly-container
variables:
IMAGE: fedora-rust-nightly
CONFIGURE_ARGS: --disable-docs --enable-rust --enable-strict-rust-lints
@@ -167,7 +167,7 @@ build-system-centos:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-centos9-container
+ - job: amd64-centos9-container
variables:
IMAGE: centos9
CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-vfio-user-server
@@ -189,7 +189,7 @@ build-previous-qemu:
- build-previous/tests/qtest/migration-test
- build-previous/scripts
needs:
- job: amd64-opensuse-leap-container
+ - job: amd64-opensuse-leap-container
variables:
IMAGE: opensuse-leap
TARGETS: x86_64-softmmu aarch64-softmmu
@@ -274,7 +274,7 @@ build-system-opensuse:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-opensuse-leap-container
+ - job: amd64-opensuse-leap-container
variables:
IMAGE: opensuse-leap
TARGETS: s390x-softmmu x86_64-softmmu aarch64-softmmu
@@ -308,7 +308,7 @@ build-system-flaky:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-debian-container
+ - job: amd64-debian-container
variables:
IMAGE: debian
QEMU_JOB_OPTIONAL: 1
@@ -338,7 +338,7 @@ functional-system-flaky:
build-tcg-disabled:
extends: .native_build_job_template
needs:
- job: amd64-centos9-container
+ - job: amd64-centos9-container
variables:
IMAGE: centos9
script:
@@ -364,7 +364,7 @@ build-tcg-disabled:
build-user:
extends: .native_build_job_template
needs:
- job: amd64-debian-user-cross-container
+ - job: amd64-debian-user-cross-container
variables:
IMAGE: debian-all-test-cross
CONFIGURE_ARGS: --disable-tools --disable-system
@@ -374,7 +374,7 @@ build-user:
build-user-static:
extends: .native_build_job_template
needs:
- job: amd64-debian-user-cross-container
+ - job: amd64-debian-user-cross-container
variables:
IMAGE: debian-all-test-cross
CONFIGURE_ARGS: --disable-tools --disable-system --static
@@ -385,7 +385,7 @@ build-user-static:
build-legacy:
extends: .native_build_job_template
needs:
- job: amd64-debian-legacy-cross-container
+ - job: amd64-debian-legacy-cross-container
variables:
IMAGE: debian-legacy-test-cross
TARGETS: alpha-linux-user alpha-softmmu sh4-linux-user
@@ -395,7 +395,7 @@ build-legacy:
build-user-hexagon:
extends: .native_build_job_template
needs:
- job: hexagon-cross-container
+ - job: hexagon-cross-container
variables:
IMAGE: debian-hexagon-cross
TARGETS: hexagon-linux-user
@@ -408,7 +408,7 @@ build-user-hexagon:
build-some-softmmu:
extends: .native_build_job_template
needs:
- job: amd64-debian-user-cross-container
+ - job: amd64-debian-user-cross-container
variables:
IMAGE: debian-all-test-cross
CONFIGURE_ARGS: --disable-tools --enable-debug
@@ -419,7 +419,7 @@ build-some-softmmu:
build-loongarch64:
extends: .native_build_job_template
needs:
- job: loongarch-debian-cross-container
+ - job: loongarch-debian-cross-container
variables:
IMAGE: debian-loongarch-cross
CONFIGURE_ARGS: --disable-tools --enable-debug
@@ -430,7 +430,7 @@ build-loongarch64:
build-tricore-softmmu:
extends: .native_build_job_template
needs:
- job: tricore-debian-cross-container
+ - job: tricore-debian-cross-container
variables:
IMAGE: debian-tricore-cross
CONFIGURE_ARGS: --disable-tools --disable-fdt --enable-debug
@@ -440,7 +440,7 @@ build-tricore-softmmu:
clang-system:
extends: .native_build_job_template
needs:
- job: amd64-fedora-container
+ - job: amd64-fedora-container
variables:
IMAGE: fedora
CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-ubsan
@@ -451,7 +451,7 @@ clang-system:
clang-user:
extends: .native_build_job_template
needs:
- job: amd64-debian-user-cross-container
+ - job: amd64-debian-user-cross-container
timeout: 70m
variables:
IMAGE: debian-all-test-cross
@@ -479,7 +479,7 @@ build-cfi-aarch64:
LD_JOBS: 1
AR: llvm-ar
IMAGE: fedora
- CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi --enable-cfi-debug
+ CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi
--enable-safe-stack --disable-slirp
TARGETS: aarch64-softmmu
MAKE_CHECK_ARGS: check-build
@@ -517,7 +517,7 @@ build-cfi-ppc64-s390x:
LD_JOBS: 1
AR: llvm-ar
IMAGE: fedora
- CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi --enable-cfi-debug
+ CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi
--enable-safe-stack --disable-slirp
TARGETS: ppc64-softmmu s390x-softmmu
MAKE_CHECK_ARGS: check-build
@@ -555,7 +555,7 @@ build-cfi-x86_64:
LD_JOBS: 1
AR: llvm-ar
IMAGE: fedora
- CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi --enable-cfi-debug
+ CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi
--enable-safe-stack --disable-slirp
TARGETS: x86_64-softmmu
MAKE_CHECK_ARGS: check-build
@@ -582,7 +582,7 @@ functional-cfi-x86_64:
tsan-build:
extends: .native_build_job_template
needs:
- job: amd64-ubuntu2204-container
+ - job: amd64-ubuntu2204-container
variables:
IMAGE: ubuntu2204
CONFIGURE_ARGS: --enable-tsan --cc=clang --cxx=clang++
@@ -596,7 +596,7 @@ tsan-build:
gcov:
extends: .native_build_job_template
needs:
- job: amd64-ubuntu2204-container
+ - job: amd64-ubuntu2204-container
timeout: 80m
variables:
IMAGE: ubuntu2204
@@ -623,7 +623,7 @@ gcov:
build-oss-fuzz:
extends: .native_build_job_template
needs:
- job: amd64-fedora-container
+ - job: amd64-fedora-container
variables:
IMAGE: fedora
script:
@@ -645,7 +645,7 @@ build-oss-fuzz:
build-tci:
extends: .native_build_job_template
needs:
- job: amd64-debian-user-cross-container
+ - job: amd64-debian-user-cross-container
variables:
IMAGE: debian-all-test-cross
script:
@@ -670,7 +670,7 @@ build-tci:
build-without-defaults:
extends: .native_build_job_template
needs:
- job: amd64-centos9-container
+ - job: amd64-centos9-container
variables:
IMAGE: centos9
CONFIGURE_ARGS:
@@ -688,7 +688,7 @@ build-libvhost-user:
stage: build
image: $CI_REGISTRY_IMAGE/qemu/fedora:$QEMU_CI_CONTAINER_TAG
needs:
- job: amd64-fedora-container
+ - job: amd64-fedora-container
script:
- mkdir subprojects/libvhost-user/build
- cd subprojects/libvhost-user/build
@@ -702,9 +702,9 @@ build-tools-and-docs-debian:
- .native_build_job_template
- .native_build_artifact_template
needs:
- job: amd64-debian-container
- # when running on 'master' we use pre-existing container
- optional: true
+ - job: amd64-debian-container
+ # when running on 'master' we use pre-existing container
+ optional: true
variables:
IMAGE: debian
MAKE_CHECK_ARGS: check-unit ctags TAGS cscope
@@ -791,7 +791,7 @@ build-wasm:
extends: .wasm_build_job_template
timeout: 2h
needs:
- job: wasm-emsdk-cross-container
+ - job: wasm-emsdk-cross-container
variables:
IMAGE: emsdk-wasm32-cross
CONFIGURE_ARGS: --static --disable-tools --enable-debug --enable-tcg-interpreter
diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml
index 75b6114..13a0bf5 100644
--- a/.gitlab-ci.d/cirrus.yml
+++ b/.gitlab-ci.d/cirrus.yml
@@ -42,7 +42,7 @@ x64-freebsd-14-build:
CIRRUS_VM_RAM: 8G
UPDATE_COMMAND: pkg update; pkg upgrade -y
INSTALL_COMMAND: pkg install -y
- CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblaze-softmmu,mips64el-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4eb-softmmu,xtensa-softmmu
+ CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblaze-softmmu,mips64el-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4eb-softmmu,xtensa-softmmu --enable-rust
TEST_TARGETS: check
aarch64-macos-build:
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
index 3f76c90..8ff0c27 100644
--- a/.gitlab-ci.d/crossbuilds.yml
+++ b/.gitlab-ci.d/crossbuilds.yml
@@ -4,28 +4,28 @@ include:
cross-armhf-user:
extends: .cross_user_build_job
needs:
- job: armhf-debian-cross-container
+ - job: armhf-debian-cross-container
variables:
IMAGE: debian-armhf-cross
cross-arm64-system:
extends: .cross_system_build_job
needs:
- job: arm64-debian-cross-container
+ - job: arm64-debian-cross-container
variables:
IMAGE: debian-arm64-cross
cross-arm64-user:
extends: .cross_user_build_job
needs:
- job: arm64-debian-cross-container
+ - job: arm64-debian-cross-container
variables:
IMAGE: debian-arm64-cross
cross-arm64-kvm-only:
extends: .cross_accel_build_job
needs:
- job: arm64-debian-cross-container
+ - job: arm64-debian-cross-container
variables:
IMAGE: debian-arm64-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg --without-default-features
@@ -35,7 +35,7 @@ cross-i686-system:
- .cross_system_build_job
- .cross_test_artifacts
needs:
- job: i686-debian-cross-container
+ - job: i686-debian-cross-container
variables:
IMAGE: debian-i686-cross
EXTRA_CONFIGURE_OPTS: --disable-kvm
@@ -46,7 +46,7 @@ cross-i686-user:
- .cross_user_build_job
- .cross_test_artifacts
needs:
- job: i686-debian-cross-container
+ - job: i686-debian-cross-container
variables:
IMAGE: debian-i686-cross
MAKE_CHECK_ARGS: check
@@ -57,7 +57,7 @@ cross-i686-tci:
- .cross_test_artifacts
timeout: 60m
needs:
- job: i686-debian-cross-container
+ - job: i686-debian-cross-container
variables:
IMAGE: debian-i686-cross
ACCEL: tcg-interpreter
@@ -71,49 +71,49 @@ cross-i686-tci:
cross-mipsel-system:
extends: .cross_system_build_job
needs:
- job: mipsel-debian-cross-container
+ - job: mipsel-debian-cross-container
variables:
IMAGE: debian-mipsel-cross
cross-mipsel-user:
extends: .cross_user_build_job
needs:
- job: mipsel-debian-cross-container
+ - job: mipsel-debian-cross-container
variables:
IMAGE: debian-mipsel-cross
cross-mips64el-system:
extends: .cross_system_build_job
needs:
- job: mips64el-debian-cross-container
+ - job: mips64el-debian-cross-container
variables:
IMAGE: debian-mips64el-cross
cross-mips64el-user:
extends: .cross_user_build_job
needs:
- job: mips64el-debian-cross-container
+ - job: mips64el-debian-cross-container
variables:
IMAGE: debian-mips64el-cross
cross-ppc64el-system:
extends: .cross_system_build_job
needs:
- job: ppc64el-debian-cross-container
+ - job: ppc64el-debian-cross-container
variables:
IMAGE: debian-ppc64el-cross
cross-ppc64el-user:
extends: .cross_user_build_job
needs:
- job: ppc64el-debian-cross-container
+ - job: ppc64el-debian-cross-container
variables:
IMAGE: debian-ppc64el-cross
cross-ppc64el-kvm-only:
extends: .cross_accel_build_job
needs:
- job: ppc64el-debian-cross-container
+ - job: ppc64el-debian-cross-container
variables:
IMAGE: debian-ppc64el-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg --without-default-devices
@@ -121,35 +121,35 @@ cross-ppc64el-kvm-only:
cross-riscv64-system:
extends: .cross_system_build_job
needs:
- job: riscv64-debian-cross-container
+ - job: riscv64-debian-cross-container
variables:
IMAGE: debian-riscv64-cross
cross-riscv64-user:
extends: .cross_user_build_job
needs:
- job: riscv64-debian-cross-container
+ - job: riscv64-debian-cross-container
variables:
IMAGE: debian-riscv64-cross
cross-s390x-system:
extends: .cross_system_build_job
needs:
- job: s390x-debian-cross-container
+ - job: s390x-debian-cross-container
variables:
IMAGE: debian-s390x-cross
cross-s390x-user:
extends: .cross_user_build_job
needs:
- job: s390x-debian-cross-container
+ - job: s390x-debian-cross-container
variables:
IMAGE: debian-s390x-cross
cross-s390x-kvm-only:
extends: .cross_accel_build_job
needs:
- job: s390x-debian-cross-container
+ - job: s390x-debian-cross-container
variables:
IMAGE: debian-s390x-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg --enable-trace-backends=ftrace
@@ -157,7 +157,7 @@ cross-s390x-kvm-only:
cross-mips64el-kvm-only:
extends: .cross_accel_build_job
needs:
- job: mips64el-debian-cross-container
+ - job: mips64el-debian-cross-container
variables:
IMAGE: debian-mips64el-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg --target-list=mips64el-softmmu
@@ -165,7 +165,7 @@ cross-mips64el-kvm-only:
cross-win64-system:
extends: .cross_system_build_job
needs:
- job: win64-fedora-cross-container
+ - job: win64-fedora-cross-container
variables:
IMAGE: fedora-win64-cross
EXTRA_CONFIGURE_OPTS: --enable-fdt=internal --disable-plugins
@@ -181,7 +181,7 @@ cross-win64-system:
cross-amd64-xen-only:
extends: .cross_accel_build_job
needs:
- job: amd64-debian-cross-container
+ - job: amd64-debian-cross-container
variables:
IMAGE: debian-amd64-cross
ACCEL: xen
@@ -190,7 +190,7 @@ cross-amd64-xen-only:
cross-arm64-xen-only:
extends: .cross_accel_build_job
needs:
- job: arm64-debian-cross-container
+ - job: arm64-debian-cross-container
variables:
IMAGE: debian-arm64-cross
ACCEL: xen
diff --git a/.gitlab-ci.d/static_checks.yml b/.gitlab-ci.d/static_checks.yml
index c3ed6de..61fe2fa 100644
--- a/.gitlab-ci.d/static_checks.yml
+++ b/.gitlab-ci.d/static_checks.yml
@@ -32,7 +32,7 @@ check-python-minreqs:
variables:
GIT_DEPTH: 1
needs:
- job: python-container
+ - job: python-container
check-python-tox:
extends: .base_job_template
@@ -45,7 +45,7 @@ check-python-tox:
QEMU_TOX_EXTRA_ARGS: --skip-missing-interpreters=false
QEMU_JOB_OPTIONAL: 1
needs:
- job: python-container
+ - job: python-container
check-rust-tools-nightly:
extends: .base_job_template
@@ -76,7 +76,7 @@ check-build-units:
stage: build
image: $CI_REGISTRY_IMAGE/qemu/debian:$QEMU_CI_CONTAINER_TAG
needs:
- job: amd64-debian-container
+ - job: amd64-debian-container
before_script:
- source scripts/ci/gitlab-ci-section
- section_start setup "Install Tools"
diff --git a/configure b/configure
index 0f7eb95..78445cb 100755
--- a/configure
+++ b/configure
@@ -1000,7 +1000,19 @@ $mkvenv ensuregroup --dir "${source_path}/python/wheels" \
# We ignore PATH completely here: we want to use the venv's Meson
# *exclusively*.
-meson="$(cd pyvenv/bin; pwd)/meson"
+# for msys2
+get_pwd() {
+ if pwd -W >/dev/null 2>&1; then
+ pwd -W
+ else
+ pwd
+ fi
+}
+
+meson="$(cd pyvenv/bin; get_pwd)/meson"
+if [ -f "$meson$EXESUF" ]; then
+ meson="$meson$EXESUF"
+fi
# Conditionally ensure Sphinx is installed.
@@ -1878,6 +1890,13 @@ if test "$skip_meson" = no; then
eval "c=\$devices_${a}"
echo "${a}-softmmu = '$c'" >> $cross
done
+ if test "$rust" != disabled; then
+ if test "$cross_compile" = "yes"; then
+ . "$source_path/scripts/rust-to-clang-target.sh"
+ clang_target=$(rust_to_clang_target "$rust_target_triple")
+ echo "bindgen_clang_arguments = [$(meson_quote --target="$clang_target")]" >> $cross
+ fi
+ fi
echo "[built-in options]" >> $cross
echo "c_args = [$(meson_quote $CFLAGS $EXTRA_CFLAGS)]" >> $cross
@@ -1958,7 +1977,7 @@ if test "$skip_meson" = no; then
echo "[binaries]" >> $native
echo "c = [$(meson_quote $host_cc)]" >> $native
if test "$rust" != disabled; then
- echo "rust = [$(meson_quote $rustc)]" >> $cross
+ echo "rust = [$(meson_quote $rustc)]" >> $native
fi
mv $native config-meson.native
meson_option_add --native-file
diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst
index 0160d3a..798cb46 100644
--- a/docs/about/build-platforms.rst
+++ b/docs/about/build-platforms.rst
@@ -44,8 +44,6 @@ Those hosts are officially supported, with various accelerators:
- Accelerators
* - Arm
- hvf (64 bit only), kvm (64 bit only), tcg, xen
- * - MIPS (64 bit little endian only)
- - kvm, tcg
* - PPC
- kvm, tcg
* - RISC-V
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index b8d60c1..67e5277 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -172,8 +172,8 @@ This argument has always been ignored.
Host Architectures
------------------
-Big endian MIPS since 7.2; 32-bit little endian MIPS since 9.2
-''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+Big endian MIPS since 7.2; 32-bit little endian MIPS since 9.2, MIPS since 11.0
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
As Debian 10 ("Buster") moved into LTS the big endian 32 bit version of
MIPS moved out of support making it hard to maintain our
@@ -181,10 +181,7 @@ cross-compilation CI tests of the architecture. As we no longer have
CI coverage support may bitrot away before the deprecation process
completes.
-Likewise, the little endian variant of 32 bit MIPS is not supported by
-Debian 13 ("Trixie") and newer.
-
-64 bit little endian MIPS is still a supported host architecture.
+Likewise, MIPS is not supported by Debian 13 ("Trixie") and newer.
System emulation on 32-bit x86 hosts (since 8.0)
''''''''''''''''''''''''''''''''''''''''''''''''
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index bf18c56..6317c0e 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -243,6 +243,37 @@ under Linux), use :
-M ast2500-evb,bmc-console=uart3
+OTP Option
+^^^^^^^^^^
+
+Both the AST2600 and AST1030 chips use the same One Time Programmable
+(OTP) memory module, which is utilized for configuration, key storage,
+and storing user-programmable data. This OTP memory module is managed
+by the Secure Boot Controller (SBC). The following options can be
+specified or omitted based on your needs.
+
+ * When the options are specified, the pre-generated configuration
+ file will be used as the OTP memory storage.
+
+ * When the options are omitted, an internal memory buffer will be
+ used to store the OTP memory data.
+
+.. code-block:: bash
+
+ -blockdev driver=file,filename=otpmem.img,node-name=otp \
+ -global aspeed-otp.drive=otp \
+
+The following bash command can be used to generate a default
+configuration file for OTP memory:
+
+.. code-block:: bash
+
+ if [ ! -f otpmem.img ]; then
+ for i in $(seq 1 2048); do
+ printf '\x00\x00\x00\x00\xff\xff\xff\xff'
+ done > otpmem.img
+ fi
+
Aspeed 2700 family boards (``ast2700-evb``)
==================================================================
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3baa6c6..b44b85f 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -541,6 +541,7 @@ config ASPEED_SOC
bool
default y
depends on TCG && ARM
+ imply PCI_DEVICES
select DS1338
select FTGMAC100
select I2C
@@ -561,6 +562,8 @@ config ASPEED_SOC
select MAX31785
select FSI_APB2OPB_ASPEED
select AT24C
+ select PCI_EXPRESS
+ select PCI_EXPRESS_ASPEED
config MPS2
bool
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c31bbe7..6046ec0 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -26,9 +26,7 @@
#include "hw/qdev-properties.h"
#include "system/block-backend.h"
#include "system/reset.h"
-#include "hw/loader.h"
#include "qemu/error-report.h"
-#include "qemu/datadir.h"
#include "qemu/units.h"
#include "hw/qdev-clock.h"
#include "system/system.h"
@@ -263,102 +261,6 @@ static void aspeed_reset_secondary(ARMCPU *cpu,
cpu_set_pc(cs, info->smp_loader_start);
}
-static void write_boot_rom(BlockBackend *blk, hwaddr addr, size_t rom_size,
- Error **errp)
-{
- g_autofree void *storage = NULL;
- int64_t size;
-
- /*
- * The block backend size should have already been 'validated' by
- * the creation of the m25p80 object.
- */
- size = blk_getlength(blk);
- if (size <= 0) {
- error_setg(errp, "failed to get flash size");
- return;
- }
-
- if (rom_size > size) {
- rom_size = size;
- }
-
- storage = g_malloc0(rom_size);
- if (blk_pread(blk, 0, rom_size, storage, 0) < 0) {
- error_setg(errp, "failed to read the initial flash content");
- return;
- }
-
- rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
-}
-
-/*
- * Create a ROM and copy the flash contents at the expected address
- * (0x0). Boots faster than execute-in-place.
- */
-static void aspeed_install_boot_rom(AspeedMachineState *bmc, BlockBackend *blk,
- uint64_t rom_size)
-{
- AspeedSoCState *soc = bmc->soc;
- AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(soc);
-
- memory_region_init_rom(&bmc->boot_rom, NULL, "aspeed.boot_rom", rom_size,
- &error_abort);
- memory_region_add_subregion_overlap(&soc->spi_boot_container, 0,
- &bmc->boot_rom, 1);
- write_boot_rom(blk, sc->memmap[ASPEED_DEV_SPI_BOOT],
- rom_size, &error_abort);
-}
-
-#define VBOOTROM_FILE_NAME "ast27x0_bootrom.bin"
-
-/*
- * This function locates the vbootrom image file specified via the command line
- * using the -bios option. It loads the specified image into the vbootrom
- * memory region and handles errors if the file cannot be found or loaded.
- */
-static void aspeed_load_vbootrom(AspeedMachineState *bmc, const char *bios_name,
- Error **errp)
-{
- g_autofree char *filename = NULL;
- AspeedSoCState *soc = bmc->soc;
- int ret;
-
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (!filename) {
- error_setg(errp, "Could not find vbootrom image '%s'", bios_name);
- return;
- }
-
- ret = load_image_mr(filename, &soc->vbootrom);
- if (ret < 0) {
- error_setg(errp, "Failed to load vbootrom image '%s'", bios_name);
- return;
- }
-}
-
-void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
- unsigned int count, int unit0)
-{
- int i;
-
- if (!flashtype) {
- return;
- }
-
- for (i = 0; i < count; ++i) {
- DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
- DeviceState *dev;
-
- dev = qdev_new(flashtype);
- if (dinfo) {
- qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
- }
- qdev_prop_set_uint8(dev, "cs", i);
- qdev_realize_and_unref(dev, BUS(s->spi), &error_fatal);
- }
-}
-
static void sdhci_attach_drive(SDHCIState *sdhci, DriveInfo *dinfo, bool emmc,
bool boot_emmc)
{
@@ -511,15 +413,16 @@ static void aspeed_machine_init(MachineState *machine)
if (fmc0 && !boot_emmc) {
uint64_t rom_size = memory_region_size(&bmc->soc->spi_boot);
- aspeed_install_boot_rom(bmc, fmc0, rom_size);
+ aspeed_install_boot_rom(bmc->soc, fmc0, &bmc->boot_rom, rom_size);
} else if (emmc0) {
- aspeed_install_boot_rom(bmc, blk_by_legacy_dinfo(emmc0), 64 * KiB);
+ aspeed_install_boot_rom(bmc->soc, blk_by_legacy_dinfo(emmc0),
+ &bmc->boot_rom, 64 * KiB);
}
}
if (amc->vbootrom) {
bios_name = machine->firmware ?: VBOOTROM_FILE_NAME;
- aspeed_load_vbootrom(bmc, bios_name, &error_abort);
+ aspeed_load_vbootrom(bmc->soc, bios_name, &error_abort);
}
arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
@@ -1995,7 +1898,6 @@ static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc,
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
- mc->alias = "ast2700-evb";
mc->desc = "Aspeed AST2700 A0 EVB (Cortex-A35)";
amc->soc_name = "ast2700-a0";
amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
@@ -2018,6 +1920,7 @@ static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc,
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+ mc->alias = "ast2700-evb";
mc->desc = "Aspeed AST2700 A1 EVB (Cortex-A35)";
amc->soc_name = "ast2700-a1";
amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
index e6e1ee6..c446e70 100644
--- a/hw/arm/aspeed_ast10x0.c
+++ b/hw/arm/aspeed_ast10x0.c
@@ -154,7 +154,7 @@ static void aspeed_soc_ast1030_init(Object *obj)
object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
- object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
+ object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_AST10X0_SBC);
for (i = 0; i < sc->wdts_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index d12707f..03e5df9 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -48,11 +48,13 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_XDMA] = 0x1E6E7000,
[ASPEED_DEV_ADC] = 0x1E6E9000,
[ASPEED_DEV_DP] = 0x1E6EB000,
+ [ASPEED_DEV_PCIE_PHY1] = 0x1E6ED200,
[ASPEED_DEV_SBC] = 0x1E6F2000,
[ASPEED_DEV_EMMC_BC] = 0x1E6f5000,
[ASPEED_DEV_VIDEO] = 0x1E700000,
[ASPEED_DEV_SDHCI] = 0x1E740000,
[ASPEED_DEV_EMMC] = 0x1E750000,
+ [ASPEED_DEV_PCIE0] = 0x1E770000,
[ASPEED_DEV_GPIO] = 0x1E780000,
[ASPEED_DEV_GPIO_1_8V] = 0x1E780800,
[ASPEED_DEV_RTC] = 0x1E781000,
@@ -79,6 +81,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_FSI1] = 0x1E79B000,
[ASPEED_DEV_FSI2] = 0x1E79B100,
[ASPEED_DEV_I3C] = 0x1E7A0000,
+ [ASPEED_DEV_PCIE_MMIO1] = 0x70000000,
[ASPEED_DEV_SDRAM] = 0x80000000,
};
@@ -127,6 +130,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
[ASPEED_DEV_LPC] = 35,
[ASPEED_DEV_IBT] = 143,
[ASPEED_DEV_I2C] = 110, /* 110 -> 125 */
+ [ASPEED_DEV_PCIE0] = 168,
[ASPEED_DEV_PECI] = 38,
[ASPEED_DEV_ETH1] = 2,
[ASPEED_DEV_ETH2] = 3,
@@ -191,6 +195,10 @@ static void aspeed_soc_ast2600_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
object_initialize_child(obj, "i2c", &s->i2c, typename);
+ object_initialize_child(obj, "pcie-cfg", &s->pcie[0], TYPE_ASPEED_PCIE_CFG);
+ object_initialize_child(obj, "pcie-phy[*]", &s->pcie_phy[0],
+ TYPE_ASPEED_PCIE_PHY);
+
object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
@@ -261,7 +269,7 @@ static void aspeed_soc_ast2600_init(Object *obj)
object_initialize_child(obj, "i3c", &s->i3c, TYPE_ASPEED_I3C);
- object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
+ object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_AST2600_SBC);
object_initialize_child(obj, "iomem", &s->iomem, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "video", &s->video, TYPE_UNIMPLEMENTED_DEVICE);
@@ -285,6 +293,67 @@ static uint64_t aspeed_calc_affinity(int cpu)
return (0xf << ARM_AFF1_SHIFT) | cpu;
}
+/*
+ * PCIe Root Complex (RC)
+ *
+ * H2X register space (single block 0x00-0xFF):
+ * 0x00-0x7F : shared by RC_L (PCIe0) and RC_H (PCIe1)
+ * 0x80-0xBF : RC_L only
+ * 0xC0-0xFF : RC_H only
+ *
+ * Model scope / limitations:
+ * - Firmware supports RC_H only; this QEMU model does not support RC_L.
+ * - RC_H uses PHY1 and the MMIO window [0x70000000, 0x80000000]
+ * (aka MMIO1).
+ *
+ * Indexing convention (this model):
+ * - Expose a single logical instance at index 0.
+ * - pcie[0] -> hardware RC_H (PCIe1)
+ * - phy[0] -> hardware PHY1
+ * - mmio.0 -> guest address range MMIO1: 0x70000000-0x80000000
+ * - RC_L / PCIe0 is not created and mapped.
+ */
+static bool aspeed_soc_ast2600_pcie_realize(DeviceState *dev, Error **errp)
+{
+ Aspeed2600SoCState *a = ASPEED2600_SOC(dev);
+ AspeedSoCState *s = ASPEED_SOC(dev);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ MemoryRegion *mmio_mr = NULL;
+ qemu_irq irq;
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_phy[0]), errp)) {
+ return false;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->pcie_phy[0]), 0,
+ sc->memmap[ASPEED_DEV_PCIE_PHY1]);
+
+ object_property_set_int(OBJECT(&s->pcie[0]), "dram-base",
+ sc->memmap[ASPEED_DEV_SDRAM],
+ &error_abort);
+ object_property_set_link(OBJECT(&s->pcie[0]), "dram", OBJECT(s->dram_mr),
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie[0]), errp)) {
+ return false;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->pcie[0]), 0,
+ sc->memmap[ASPEED_DEV_PCIE0]);
+
+ irq = qdev_get_gpio_in(DEVICE(&a->a7mpcore),
+ sc->irqmap[ASPEED_DEV_PCIE0]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie[0].rc), 0, irq);
+
+ mmio_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pcie[0].rc), 1);
+ memory_region_init_alias(&s->pcie_mmio_alias[0], OBJECT(&s->pcie[0].rc),
+ "aspeed.pcie-mmio", mmio_mr,
+ sc->memmap[ASPEED_DEV_PCIE_MMIO1],
+ 0x10000000);
+ memory_region_add_subregion(s->memory,
+ sc->memmap[ASPEED_DEV_PCIE_MMIO1],
+ &s->pcie_mmio_alias[0]);
+
+ return true;
+}
+
static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
{
int i;
@@ -438,6 +507,11 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_PECI));
+ /* PCIe Root Complex (RC) */
+ if (!aspeed_soc_ast2600_pcie_realize(dev, errp)) {
+ return;
+ }
+
/* FMC, The number of CS is set at the board level */
object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
&error_abort);
diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c
index 7087be4..2e16a03 100644
--- a/hw/arm/aspeed_ast27x0-fc.c
+++ b/hw/arm/aspeed_ast27x0-fc.c
@@ -56,7 +56,7 @@ struct Ast2700FCState {
#define AST2700FC_FMC_MODEL "w25q01jvq"
#define AST2700FC_SPI_MODEL "w25q512jv"
-static void ast2700fc_ca35_init(MachineState *machine)
+static bool ast2700fc_ca35_init(MachineState *machine, Error **errp)
{
Ast2700FCState *s = AST2700A1FC(machine);
AspeedSoCState *soc;
@@ -71,22 +71,15 @@ static void ast2700fc_ca35_init(MachineState *machine)
memory_region_add_subregion(get_system_memory(), 0, &s->ca35_memory);
if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram",
- AST2700FC_BMC_RAM_SIZE, &error_abort)) {
- return;
- }
- if (!object_property_set_link(OBJECT(&s->ca35), "memory",
- OBJECT(&s->ca35_memory),
- &error_abort)) {
- return;
- };
- if (!object_property_set_link(OBJECT(&s->ca35), "dram",
- OBJECT(&s->ca35_dram), &error_abort)) {
- return;
- }
- if (!object_property_set_int(OBJECT(&s->ca35), "ram-size",
- AST2700FC_BMC_RAM_SIZE, &error_abort)) {
- return;
+ AST2700FC_BMC_RAM_SIZE, errp)) {
+ return false;
}
+ object_property_set_link(OBJECT(&s->ca35), "memory",
+ OBJECT(&s->ca35_memory), &error_abort);
+ object_property_set_link(OBJECT(&s->ca35), "dram", OBJECT(&s->ca35_dram),
+ &error_abort);
+ object_property_set_int(OBJECT(&s->ca35), "ram-size",
+ AST2700FC_BMC_RAM_SIZE, &error_abort);
for (int i = 0; i < sc->macs_num; i++) {
if (!qemu_configure_nic_device(DEVICE(&soc->ftgmac100[i]),
@@ -94,17 +87,13 @@ static void ast2700fc_ca35_init(MachineState *machine)
break;
}
}
- if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
- AST2700FC_HW_STRAP1, &error_abort)) {
- return;
- }
- if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
- AST2700FC_HW_STRAP2, &error_abort)) {
- return;
- }
+ object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
+ AST2700FC_HW_STRAP1, &error_abort);
+ object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
+ AST2700FC_HW_STRAP2, &error_abort);
aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART12, serial_hd(0));
- if (!qdev_realize(DEVICE(&s->ca35), NULL, &error_abort)) {
- return;
+ if (!qdev_realize(DEVICE(&s->ca35), NULL, errp)) {
+ return false;
}
/*
@@ -119,9 +108,11 @@ static void ast2700fc_ca35_init(MachineState *machine)
ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info);
+
+ return true;
}
-static void ast2700fc_ssp_init(MachineState *machine)
+static bool ast2700fc_ssp_init(MachineState *machine, Error **errp)
{
AspeedSoCState *soc;
Ast2700FCState *s = AST2700A1FC(machine);
@@ -133,19 +124,19 @@ static void ast2700fc_ssp_init(MachineState *machine)
UINT64_MAX);
qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk);
- if (!object_property_set_link(OBJECT(&s->ssp), "memory",
- OBJECT(&s->ssp_memory), &error_abort)) {
- return;
- }
+ object_property_set_link(OBJECT(&s->ssp), "memory",
+ OBJECT(&s->ssp_memory), &error_abort);
soc = ASPEED_SOC(&s->ssp);
aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(1));
- if (!qdev_realize(DEVICE(&s->ssp), NULL, &error_abort)) {
- return;
+ if (!qdev_realize(DEVICE(&s->ssp), NULL, errp)) {
+ return false;
}
+
+ return true;
}
-static void ast2700fc_tsp_init(MachineState *machine)
+static bool ast2700fc_tsp_init(MachineState *machine, Error **errp)
{
AspeedSoCState *soc;
Ast2700FCState *s = AST2700A1FC(machine);
@@ -157,23 +148,23 @@ static void ast2700fc_tsp_init(MachineState *machine)
UINT64_MAX);
qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk);
- if (!object_property_set_link(OBJECT(&s->tsp), "memory",
- OBJECT(&s->tsp_memory), &error_abort)) {
- return;
- }
+ object_property_set_link(OBJECT(&s->tsp), "memory",
+ OBJECT(&s->tsp_memory), &error_abort);
soc = ASPEED_SOC(&s->tsp);
aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART7, serial_hd(2));
- if (!qdev_realize(DEVICE(&s->tsp), NULL, &error_abort)) {
- return;
+ if (!qdev_realize(DEVICE(&s->tsp), NULL, errp)) {
+ return false;
}
+
+ return true;
}
static void ast2700fc_init(MachineState *machine)
{
- ast2700fc_ca35_init(machine);
- ast2700fc_ssp_init(machine);
- ast2700fc_tsp_init(machine);
+ ast2700fc_ca35_init(machine, &error_abort);
+ ast2700fc_ssp_init(machine, &error_abort);
+ ast2700fc_tsp_init(machine, &error_abort);
}
static void ast2700fc_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 6aa3841..8533391 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -38,6 +38,8 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_EHCI2] = 0x12063000,
[ASPEED_DEV_HACE] = 0x12070000,
[ASPEED_DEV_EMMC] = 0x12090000,
+ [ASPEED_DEV_PCIE0] = 0x120E0000,
+ [ASPEED_DEV_PCIE1] = 0x120F0000,
[ASPEED_DEV_INTC] = 0x12100000,
[ASPEED_GIC_DIST] = 0x12200000,
[ASPEED_GIC_REDIST] = 0x12280000,
@@ -45,6 +47,8 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_SCU] = 0x12C02000,
[ASPEED_DEV_RTC] = 0x12C0F000,
[ASPEED_DEV_TIMER1] = 0x12C10000,
+ [ASPEED_DEV_PCIE_PHY0] = 0x12C15000,
+ [ASPEED_DEV_PCIE_PHY1] = 0x12C15800,
[ASPEED_DEV_SLI] = 0x12C17000,
[ASPEED_DEV_UART4] = 0x12C1A000,
[ASPEED_DEV_IOMEM1] = 0x14000000,
@@ -59,6 +63,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_ETH2] = 0x14060000,
[ASPEED_DEV_ETH3] = 0x14070000,
[ASPEED_DEV_SDHCI] = 0x14080000,
+ [ASPEED_DEV_PCIE2] = 0x140D0000,
[ASPEED_DEV_EHCI3] = 0x14121000,
[ASPEED_DEV_EHCI4] = 0x14123000,
[ASPEED_DEV_ADC] = 0x14C00000,
@@ -66,6 +71,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_GPIO] = 0x14C0B000,
[ASPEED_DEV_I2C] = 0x14C0F000,
[ASPEED_DEV_INTCIO] = 0x14C18000,
+ [ASPEED_DEV_PCIE_PHY2] = 0x14C1C000,
[ASPEED_DEV_SLIIO] = 0x14C1E000,
[ASPEED_DEV_VUART] = 0x14C30000,
[ASPEED_DEV_UART0] = 0x14C33000,
@@ -81,6 +87,9 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_UART11] = 0x14C33A00,
[ASPEED_DEV_UART12] = 0x14C33B00,
[ASPEED_DEV_WDT] = 0x14C37000,
+ [ASPEED_DEV_PCIE_MMIO0] = 0x60000000,
+ [ASPEED_DEV_PCIE_MMIO1] = 0x80000000,
+ [ASPEED_DEV_PCIE_MMIO2] = 0xA0000000,
[ASPEED_DEV_SPI_BOOT] = 0x100000000,
[ASPEED_DEV_LTPI] = 0x300000000,
[ASPEED_DEV_SDRAM] = 0x400000000,
@@ -156,6 +165,8 @@ static const int aspeed_soc_ast2700a1_irqmap[] = {
[ASPEED_DEV_DP] = 28,
[ASPEED_DEV_EHCI1] = 33,
[ASPEED_DEV_EHCI2] = 37,
+ [ASPEED_DEV_PCIE0] = 56,
+ [ASPEED_DEV_PCIE1] = 57,
[ASPEED_DEV_LPC] = 192,
[ASPEED_DEV_IBT] = 192,
[ASPEED_DEV_KCS] = 192,
@@ -166,6 +177,7 @@ static const int aspeed_soc_ast2700a1_irqmap[] = {
[ASPEED_DEV_WDT] = 195,
[ASPEED_DEV_PWM] = 195,
[ASPEED_DEV_I3C] = 195,
+ [ASPEED_DEV_PCIE2] = 196,
[ASPEED_DEV_UART0] = 196,
[ASPEED_DEV_UART1] = 196,
[ASPEED_DEV_UART2] = 196,
@@ -233,6 +245,7 @@ static const int ast2700_gic132_gic196_intcmap[] = {
[ASPEED_DEV_UART12] = 18,
[ASPEED_DEV_EHCI3] = 28,
[ASPEED_DEV_EHCI4] = 29,
+ [ASPEED_DEV_PCIE2] = 31,
};
/* GICINT 133 */
@@ -519,6 +532,17 @@ static void aspeed_soc_ast2700_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
object_initialize_child(obj, "hace", &s->hace, typename);
+
+ for (i = 0; i < sc->pcie_num; i++) {
+ snprintf(typename, sizeof(typename), "aspeed.pcie-phy-%s", socname);
+ object_initialize_child(obj, "pcie-phy[*]", &s->pcie_phy[i], typename);
+ object_property_set_int(OBJECT(&s->pcie_phy[i]), "id", i, &error_abort);
+
+ snprintf(typename, sizeof(typename), "aspeed.pcie-cfg-%s", socname);
+ object_initialize_child(obj, "pcie-cfg[*]", &s->pcie[i], typename);
+ object_property_set_int(OBJECT(&s->pcie[i]), "id", i, &error_abort);
+ }
+
object_initialize_child(obj, "dpmcu", &s->dpmcu,
TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "ltpi", &s->ltpi,
@@ -610,6 +634,49 @@ static bool aspeed_soc_ast2700_gic_realize(DeviceState *dev, Error **errp)
return true;
}
+static bool aspeed_soc_ast2700_pcie_realize(DeviceState *dev, Error **errp)
+{
+ AspeedSoCState *s = ASPEED_SOC(dev);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ MemoryRegion *mmio_mr = NULL;
+ char name[64];
+ qemu_irq irq;
+ int i;
+
+ for (i = 0; i < sc->pcie_num; i++) {
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_phy[i]), errp)) {
+ return false;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->pcie_phy[i]), 0,
+ sc->memmap[ASPEED_DEV_PCIE_PHY0 + i]);
+
+ object_property_set_int(OBJECT(&s->pcie[i]), "dram-base",
+ sc->memmap[ASPEED_DEV_SDRAM],
+ &error_abort);
+ object_property_set_link(OBJECT(&s->pcie[i]), "dram",
+ OBJECT(s->dram_mr), &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie[i]), errp)) {
+ return false;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->pcie[i]), 0,
+ sc->memmap[ASPEED_DEV_PCIE0 + i]);
+ irq = aspeed_soc_get_irq(s, ASPEED_DEV_PCIE0 + i);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie[i].rc), 0, irq);
+
+ mmio_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pcie[i].rc), 1);
+ snprintf(name, sizeof(name), "aspeed.pcie-mmio.%d", i);
+ memory_region_init_alias(&s->pcie_mmio_alias[i], OBJECT(&s->pcie[i].rc),
+ name, mmio_mr,
+ sc->memmap[ASPEED_DEV_PCIE_MMIO0 + i],
+ 0x20000000);
+ memory_region_add_subregion(s->memory,
+ sc->memmap[ASPEED_DEV_PCIE_MMIO0 + i],
+ &s->pcie_mmio_alias[i]);
+ }
+
+ return true;
+}
+
static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
{
int i;
@@ -936,6 +1003,11 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
+ /* PCIe Root Complex (RC) */
+ if (!aspeed_soc_ast2700_pcie_realize(dev, errp)) {
+ return;
+ }
+
aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->dpmcu),
"aspeed.dpmcu",
sc->memmap[ASPEED_DEV_DPMCU],
@@ -974,6 +1046,7 @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, const void *data)
sc->valid_cpu_types = valid_cpu_types;
sc->silicon_rev = AST2700_A0_SILICON_REV;
sc->sram_size = 0x20000;
+ sc->pcie_num = 0;
sc->spis_num = 3;
sc->ehcis_num = 2;
sc->wdts_num = 8;
@@ -1002,6 +1075,7 @@ static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, const void *data)
sc->valid_cpu_types = valid_cpu_types;
sc->silicon_rev = AST2700_A1_SILICON_REV;
sc->sram_size = 0x20000;
+ sc->pcie_num = 3;
sc->spis_num = 3;
sc->ehcis_num = 4;
sc->wdts_num = 8;
diff --git a/hw/arm/aspeed_soc_common.c b/hw/arm/aspeed_soc_common.c
index 1c4ac93..bc70e86 100644
--- a/hw/arm/aspeed_soc_common.c
+++ b/hw/arm/aspeed_soc_common.c
@@ -16,6 +16,10 @@
#include "hw/misc/unimp.h"
#include "hw/arm/aspeed_soc.h"
#include "hw/char/serial-mm.h"
+#include "system/blockdev.h"
+#include "system/block-backend.h"
+#include "hw/loader.h"
+#include "qemu/datadir.h"
const char *aspeed_soc_cpu_type(AspeedSoCClass *sc)
@@ -124,6 +128,98 @@ void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
sysbus_mmio_get_region(dev, 0), -1000);
}
+void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
+ unsigned int count, int unit0)
+{
+ int i;
+
+ if (!flashtype) {
+ return;
+ }
+
+ for (i = 0; i < count; ++i) {
+ DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
+ DeviceState *dev;
+
+ dev = qdev_new(flashtype);
+ if (dinfo) {
+ qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
+ }
+ qdev_prop_set_uint8(dev, "cs", i);
+ qdev_realize_and_unref(dev, BUS(s->spi), &error_fatal);
+ }
+}
+
+void aspeed_write_boot_rom(BlockBackend *blk, hwaddr addr, size_t rom_size,
+ Error **errp)
+{
+ g_autofree void *storage = NULL;
+ int64_t size;
+
+ /*
+ * The block backend size should have already been 'validated' by
+ * the creation of the m25p80 object.
+ */
+ size = blk_getlength(blk);
+ if (size <= 0) {
+ error_setg(errp, "failed to get flash size");
+ return;
+ }
+
+ if (rom_size > size) {
+ rom_size = size;
+ }
+
+ storage = g_malloc0(rom_size);
+ if (blk_pread(blk, 0, rom_size, storage, 0) < 0) {
+ error_setg(errp, "failed to read the initial flash content");
+ return;
+ }
+
+ rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
+}
+
+/*
+ * Create a ROM and copy the flash contents at the expected address
+ * (0x0). Boots faster than execute-in-place.
+ */
+void aspeed_install_boot_rom(AspeedSoCState *soc, BlockBackend *blk,
+ MemoryRegion *boot_rom, uint64_t rom_size)
+{
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(soc);
+
+ memory_region_init_rom(boot_rom, NULL, "aspeed.boot_rom", rom_size,
+ &error_abort);
+ memory_region_add_subregion_overlap(&soc->spi_boot_container, 0,
+ boot_rom, 1);
+ aspeed_write_boot_rom(blk, sc->memmap[ASPEED_DEV_SPI_BOOT], rom_size,
+ &error_abort);
+}
+
+/*
+ * This function locates the vbootrom image file specified via the command line
+ * using the -bios option. It loads the specified image into the vbootrom
+ * memory region and handles errors if the file cannot be found or loaded.
+ */
+void aspeed_load_vbootrom(AspeedSoCState *soc, const char *bios_name,
+ Error **errp)
+{
+ g_autofree char *filename = NULL;
+ int ret;
+
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (!filename) {
+ error_setg(errp, "Could not find vbootrom image '%s'", bios_name);
+ return;
+ }
+
+ ret = load_image_mr(filename, &soc->vbootrom);
+ if (ret < 0) {
+ error_setg(errp, "Failed to load vbootrom image '%s'", bios_name);
+ return;
+ }
+}
+
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
{
AspeedSoCState *s = ASPEED_SOC(dev);
diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c
index a7d101b..2fc5db7 100644
--- a/hw/misc/aspeed_sbc.c
+++ b/hw/misc/aspeed_sbc.c
@@ -15,9 +15,14 @@
#include "hw/misc/aspeed_sbc.h"
#include "qapi/error.h"
#include "migration/vmstate.h"
+#include "trace.h"
#define R_PROT (0x000 / 4)
+#define R_CMD (0x004 / 4)
+#define R_ADDR (0x010 / 4)
#define R_STATUS (0x014 / 4)
+#define R_CAMP1 (0x020 / 4)
+#define R_CAMP2 (0x024 / 4)
#define R_QSR (0x040 / 4)
/* R_STATUS */
@@ -41,6 +46,20 @@
#define QSR_RSA_MASK (0x3 << 12)
#define QSR_HASH_MASK (0x3 << 10)
+#define OTP_MEMORY_SIZE 0x4000
+/* OTP command */
+#define SBC_OTP_CMD_READ 0x23b1e361
+#define SBC_OTP_CMD_WRITE 0x23b1e362
+#define SBC_OTP_CMD_PROG 0x23b1e364
+
+#define OTP_DATA_DWORD_COUNT (0x800)
+#define OTP_TOTAL_DWORD_COUNT (0x1000)
+
+/* Voltage mode */
+#define MODE_REGISTER (0x1000)
+#define MODE_REGISTER_A (0x3000)
+#define MODE_REGISTER_B (0x5000)
+
static uint64_t aspeed_sbc_read(void *opaque, hwaddr addr, unsigned int size)
{
AspeedSBCState *s = ASPEED_SBC(opaque);
@@ -57,6 +76,142 @@ static uint64_t aspeed_sbc_read(void *opaque, hwaddr addr, unsigned int size)
return s->regs[addr];
}
+static bool aspeed_sbc_otp_read(AspeedSBCState *s,
+ uint32_t otp_addr)
+{
+ MemTxResult ret;
+ AspeedOTPState *otp = &s->otp;
+ uint32_t value, otp_offset;
+ bool is_data = false;
+
+ if (otp_addr < OTP_DATA_DWORD_COUNT) {
+ is_data = true;
+ } else if (otp_addr >= OTP_TOTAL_DWORD_COUNT) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Invalid OTP addr 0x%x\n",
+ otp_addr);
+ return false;
+ }
+
+ otp_offset = otp_addr << 2;
+ ret = address_space_read(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED,
+ &value, sizeof(value));
+ if (ret != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Failed to read OTP memory, addr = %x\n",
+ otp_addr);
+ return false;
+ }
+ s->regs[R_CAMP1] = value;
+ trace_aspeed_sbc_otp_read(otp_addr, value);
+
+ if (is_data) {
+ ret = address_space_read(&otp->as, otp_offset + 4,
+ MEMTXATTRS_UNSPECIFIED,
+ &value, sizeof(value));
+ if (ret != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Failed to read OTP memory, addr = %x\n",
+ otp_addr);
+ return false;
+ }
+ s->regs[R_CAMP2] = value;
+ trace_aspeed_sbc_otp_read(otp_addr + 1, value);
+ }
+
+ return true;
+}
+
+static bool mode_handler(uint32_t otp_addr)
+{
+ switch (otp_addr) {
+ case MODE_REGISTER:
+ case MODE_REGISTER_A:
+ case MODE_REGISTER_B:
+ /* HW behavior, do nothing here */
+ return true;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Unsupported address 0x%x\n",
+ otp_addr);
+ return false;
+ }
+}
+
+static bool aspeed_sbc_otp_write(AspeedSBCState *s,
+ uint32_t otp_addr)
+{
+ if (otp_addr == 0) {
+ trace_aspeed_sbc_ignore_cmd(otp_addr);
+ return true;
+ } else {
+ if (mode_handler(otp_addr) == false) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool aspeed_sbc_otp_prog(AspeedSBCState *s,
+ uint32_t otp_addr)
+{
+ MemTxResult ret;
+ AspeedOTPState *otp = &s->otp;
+ uint32_t value = s->regs[R_CAMP1];
+
+ ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED,
+ &value, sizeof(value));
+ if (ret != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Failed to write OTP memory, addr = %x\n",
+ otp_addr);
+ return false;
+ }
+
+ trace_aspeed_sbc_otp_prog(otp_addr, value);
+
+ return true;
+}
+
+static void aspeed_sbc_handle_command(void *opaque, uint32_t cmd)
+{
+ AspeedSBCState *s = ASPEED_SBC(opaque);
+ AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(opaque);
+ bool ret = false;
+ uint32_t otp_addr;
+
+ if (!sc->has_otp) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: OTP memory is not supported\n",
+ __func__);
+ return;
+ }
+
+ s->regs[R_STATUS] &= ~(OTP_MEM_IDLE | OTP_IDLE);
+ otp_addr = s->regs[R_ADDR];
+
+ switch (cmd) {
+ case SBC_OTP_CMD_READ:
+ ret = aspeed_sbc_otp_read(s, otp_addr);
+ break;
+ case SBC_OTP_CMD_WRITE:
+ ret = aspeed_sbc_otp_write(s, otp_addr);
+ break;
+ case SBC_OTP_CMD_PROG:
+ ret = aspeed_sbc_otp_prog(s, otp_addr);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Unknown command 0x%x\n",
+ __func__, cmd);
+ break;
+ }
+
+ trace_aspeed_sbc_handle_cmd(cmd, otp_addr, ret);
+ s->regs[R_STATUS] |= (OTP_MEM_IDLE | OTP_IDLE);
+}
+
static void aspeed_sbc_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
@@ -78,6 +233,9 @@ static void aspeed_sbc_write(void *opaque, hwaddr addr, uint64_t data,
"%s: write to read only register 0x%" HWADDR_PRIx "\n",
__func__, addr << 2);
return;
+ case R_CMD:
+ aspeed_sbc_handle_command(opaque, data);
+ return;
default:
break;
}
@@ -115,10 +273,30 @@ static void aspeed_sbc_reset(DeviceState *dev)
s->regs[R_QSR] = s->signing_settings;
}
+static void aspeed_sbc_instance_init(Object *obj)
+{
+ AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(obj);
+ AspeedSBCState *s = ASPEED_SBC(obj);
+
+ if (sc->has_otp) {
+ object_initialize_child(OBJECT(s), "otp", &s->otp,
+ TYPE_ASPEED_OTP);
+ }
+}
+
static void aspeed_sbc_realize(DeviceState *dev, Error **errp)
{
AspeedSBCState *s = ASPEED_SBC(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(dev);
+
+ if (sc->has_otp) {
+ object_property_set_int(OBJECT(&s->otp), "size",
+ OTP_MEMORY_SIZE, &error_abort);
+ if (!qdev_realize(DEVICE(&s->otp), NULL, errp)) {
+ return;
+ }
+ }
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sbc_ops, s,
TYPE_ASPEED_SBC, 0x1000);
@@ -155,6 +333,7 @@ static const TypeInfo aspeed_sbc_info = {
.name = TYPE_ASPEED_SBC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AspeedSBCState),
+ .instance_init = aspeed_sbc_instance_init,
.class_init = aspeed_sbc_class_init,
.class_size = sizeof(AspeedSBCClass)
};
@@ -162,8 +341,10 @@ static const TypeInfo aspeed_sbc_info = {
static void aspeed_ast2600_sbc_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedSBCClass *sc = ASPEED_SBC_CLASS(klass);
dc->desc = "AST2600 Secure Boot Controller";
+ sc->has_otp = true;
}
static const TypeInfo aspeed_ast2600_sbc_info = {
@@ -172,9 +353,25 @@ static const TypeInfo aspeed_ast2600_sbc_info = {
.class_init = aspeed_ast2600_sbc_class_init,
};
+static void aspeed_ast10x0_sbc_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedSBCClass *sc = ASPEED_SBC_CLASS(klass);
+
+ dc->desc = "AST10X0 Secure Boot Controller";
+ sc->has_otp = true;
+}
+
+static const TypeInfo aspeed_ast10x0_sbc_info = {
+ .name = TYPE_ASPEED_AST10X0_SBC,
+ .parent = TYPE_ASPEED_SBC,
+ .class_init = aspeed_ast10x0_sbc_class_init,
+};
+
static void aspeed_sbc_register_types(void)
{
type_register_static(&aspeed_ast2600_sbc_info);
+ type_register_static(&aspeed_ast10x0_sbc_info);
type_register_static(&aspeed_sbc_info);
}
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index e3f64c0..eeb9243 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -90,6 +90,12 @@ slavio_sysctrl_mem_readl(uint32_t ret) "Read system control 0x%08x"
slavio_led_mem_writew(uint32_t val) "Write diagnostic LED 0x%04x"
slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED 0x%04x"
+# aspeed_sbc.c
+aspeed_sbc_ignore_cmd(uint32_t cmd) "Ignoring command 0x%" PRIx32
+aspeed_sbc_handle_cmd(uint32_t cmd, uint32_t addr, bool ret) "Handling command 0x%" PRIx32 " for OTP addr 0x%" PRIx32 " Result: %d"
+aspeed_sbc_otp_read(uint32_t addr, uint32_t value) "OTP Memory read: addr 0x%" PRIx32 " value 0x%" PRIx32
+aspeed_sbc_otp_prog(uint32_t addr, uint32_t value) "OTP Memory write: addr 0x%" PRIx32 " value 0x%" PRIx32
+
# aspeed_scu.c
aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
aspeed_scu_read(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c
new file mode 100644
index 0000000..dcf8ed3
--- /dev/null
+++ b/hw/nvram/aspeed_otp.c
@@ -0,0 +1,190 @@
+/*
+ * ASPEED OTP (One-Time Programmable) memory
+ *
+ * Copyright (C) 2025 Aspeed
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "system/block-backend.h"
+#include "hw/qdev-properties.h"
+#include "hw/nvram/aspeed_otp.h"
+#include "hw/nvram/trace.h"
+
+static uint64_t aspeed_otp_read(void *opaque, hwaddr offset, unsigned size)
+{
+ AspeedOTPState *s = opaque;
+ uint64_t val = 0;
+
+ memcpy(&val, s->storage + offset, size);
+
+ return val;
+}
+
+static bool valid_program_data(uint32_t otp_addr,
+ uint32_t value, uint32_t prog_bit)
+{
+ uint32_t programmed_bits, has_programmable_bits;
+ bool is_odd = otp_addr & 1;
+
+ /*
+ * prog_bit uses 0s to indicate target bits to program:
+ * - if OTP word is even-indexed, programmed bits flip 0->1
+ * - if odd, bits flip 1->0
+ * Bit programming is one-way only and irreversible.
+ */
+ if (is_odd) {
+ programmed_bits = ~value & prog_bit;
+ } else {
+ programmed_bits = value & (~prog_bit);
+ }
+
+ /* If any bit can be programmed, accept the request */
+ has_programmable_bits = value ^ (~prog_bit);
+
+ if (programmed_bits) {
+ trace_aspeed_otp_prog_conflict(otp_addr, programmed_bits);
+ for (int i = 0; i < 32; ++i) {
+ if (programmed_bits & (1U << i)) {
+ trace_aspeed_otp_prog_bit(i);
+ }
+ }
+ }
+
+ return has_programmable_bits != 0;
+}
+
+static bool program_otpmem_data(void *opaque, uint32_t otp_addr,
+ uint32_t prog_bit, uint32_t *value)
+{
+ AspeedOTPState *s = opaque;
+ bool is_odd = otp_addr & 1;
+ uint32_t otp_offset = otp_addr << 2;
+
+ memcpy(value, s->storage + otp_offset, sizeof(uint32_t));
+
+ if (!valid_program_data(otp_addr, *value, prog_bit)) {
+ return false;
+ }
+
+ if (is_odd) {
+ *value &= ~prog_bit;
+ } else {
+ *value |= ~prog_bit;
+ }
+
+ return true;
+}
+
+static void aspeed_otp_write(void *opaque, hwaddr otp_addr,
+ uint64_t val, unsigned size)
+{
+ AspeedOTPState *s = opaque;
+ uint32_t otp_offset, value;
+
+ if (!program_otpmem_data(s, otp_addr, val, &value)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Failed to program data, value = %x, bit = %"PRIx64"\n",
+ __func__, value, val);
+ return;
+ }
+
+ otp_offset = otp_addr << 2;
+ memcpy(s->storage + otp_offset, &value, size);
+
+ if (s->blk) {
+ if (blk_pwrite(s->blk, otp_offset, size, &value, 0) < 0) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Failed to write %x to %x\n",
+ __func__, value, otp_offset);
+
+ return;
+ }
+ }
+ trace_aspeed_otp_prog(otp_offset, val, value);
+}
+
+static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
+{
+ uint32_t *p;
+ int i, num;
+ uint64_t perm;
+
+ if (s->blk) {
+ perm = BLK_PERM_CONSISTENT_READ |
+ (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
+ if (blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp) < 0) {
+ return false;
+ }
+ if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
+ error_setg(errp, "Failed to read the initial flash content");
+ return false;
+ }
+ } else {
+ num = s->size / sizeof(uint32_t);
+ p = (uint32_t *)s->storage;
+ for (i = 0; i < num; i++) {
+ p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
+ }
+ }
+ return true;
+}
+
+static const MemoryRegionOps aspeed_otp_ops = {
+ .read = aspeed_otp_read,
+ .write = aspeed_otp_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+ .valid.unaligned = true,
+ .impl.unaligned = true
+};
+
+static void aspeed_otp_realize(DeviceState *dev, Error **errp)
+{
+ AspeedOTPState *s = ASPEED_OTP(dev);
+
+ if (s->size == 0) {
+ error_setg(errp, "aspeed.otp: 'size' property must be set");
+ return;
+ }
+
+ s->storage = blk_blockalign(s->blk, s->size);
+
+ if (!aspeed_otp_init_storage(s, errp)) {
+ return;
+ }
+
+ memory_region_init_io(&s->mmio, OBJECT(dev), &aspeed_otp_ops,
+ s, "aspeed.otp", s->size);
+ address_space_init(&s->as, &s->mmio, NULL);
+}
+
+static const Property aspeed_otp_properties[] = {
+ DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0),
+ DEFINE_PROP_DRIVE("drive", AspeedOTPState, blk),
+};
+
+static void aspeed_otp_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->realize = aspeed_otp_realize;
+ device_class_set_props(dc, aspeed_otp_properties);
+}
+
+static const TypeInfo aspeed_otp_info = {
+ .name = TYPE_ASPEED_OTP,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(AspeedOTPState),
+ .class_init = aspeed_otp_class_init,
+};
+
+static void aspeed_otp_register_types(void)
+{
+ type_register_static(&aspeed_otp_info);
+}
+
+type_init(aspeed_otp_register_types)
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
index 10f3639..b66f236 100644
--- a/hw/nvram/meson.build
+++ b/hw/nvram/meson.build
@@ -19,3 +19,7 @@ system_ss.add(when: 'CONFIG_XLNX_BBRAM', if_true: files('xlnx-bbram.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
specific_ss.add(when: 'CONFIG_ACPI', if_true: files('fw_cfg-acpi.c'))
+
+system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
+ 'aspeed_otp.c',
+ )) \ No newline at end of file
diff --git a/hw/nvram/trace-events b/hw/nvram/trace-events
index 5e33b24..7084bf7 100644
--- a/hw/nvram/trace-events
+++ b/hw/nvram/trace-events
@@ -1,5 +1,10 @@
# See docs/devel/tracing.rst for syntax documentation.
+# aspeed_otp.c
+aspeed_otp_prog(uint32_t addr, uint32_t prog_value, uint32_t value) "OTP Memory program: addr 0x%" PRIx32 " prog_value 0x%" PRIx32 " value 0x%" PRIx32
+aspeed_otp_prog_conflict(uint32_t addr, uint32_t bits) "Conflict at addr=0x%x, bits=0x%08x"
+aspeed_otp_prog_bit(int bit) "Programmed bit %d"
+
# ds1225y.c
nvram_read(uint32_t addr, uint32_t ret) "read addr %d: 0x%02x"
nvram_write(uint32_t addr, uint32_t old, uint32_t val) "write addr %d: 0x%02x -> 0x%02x"
diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 9824fa1..8cbb830 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -46,6 +46,10 @@ config PCI_I440FX
select PCI
select PAM
+config PCI_EXPRESS_ASPEED
+ bool
+ select PCI_EXPRESS
+
config PCI_EXPRESS_Q35
bool
select PCI_EXPRESS
diff --git a/hw/pci-host/aspeed_pcie.c b/hw/pci-host/aspeed_pcie.c
new file mode 100644
index 0000000..f759344
--- /dev/null
+++ b/hw/pci-host/aspeed_pcie.c
@@ -0,0 +1,1015 @@
+/*
+ * ASPEED PCIe Host Controller
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ * Copyright (c) 2022 CƩdric Le Goater <clg@kaod.org>
+ *
+ * Authors:
+ * CƩdric Le Goater <clg@kaod.org>
+ * Jamin Lin <jamin_lin@aspeedtech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Based on previous work from CƩdric Le Goater.
+ * Modifications extend support for the ASPEED AST2600 and AST2700 platforms.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/registerfields.h"
+#include "hw/irq.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/pci-host/aspeed_pcie.h"
+#include "hw/pci/msi.h"
+#include "trace.h"
+
+/*
+ * PCIe Root Device
+ * This device exists only on AST2600.
+ */
+
+static void aspeed_pcie_root_device_class_init(ObjectClass *klass,
+ const void *data)
+{
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+ dc->desc = "ASPEED PCIe Root Device";
+ k->vendor_id = PCI_VENDOR_ID_ASPEED;
+ k->device_id = 0x2600;
+ k->class_id = PCI_CLASS_BRIDGE_HOST;
+ k->subsystem_vendor_id = k->vendor_id;
+ k->subsystem_id = k->device_id;
+ k->revision = 0;
+
+ /*
+ * PCI-facing part of the host bridge,
+ * not usable without the host-facing part
+ */
+ dc->user_creatable = false;
+}
+
+static const TypeInfo aspeed_pcie_root_device_info = {
+ .name = TYPE_ASPEED_PCIE_ROOT_DEVICE,
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(AspeedPCIERootDeviceState),
+ .class_init = aspeed_pcie_root_device_class_init,
+ .interfaces = (const InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
+};
+
+/*
+ * PCIe Root Port
+ */
+
+static void aspeed_pcie_root_port_class_init(ObjectClass *klass,
+ const void *data)
+{
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
+
+ dc->desc = "ASPEED PCIe Root Port";
+ k->vendor_id = PCI_VENDOR_ID_ASPEED;
+ k->device_id = 0x1150;
+ dc->user_creatable = true;
+
+ rpc->aer_offset = 0x100;
+}
+
+static const TypeInfo aspeed_pcie_root_port_info = {
+ .name = TYPE_ASPEED_PCIE_ROOT_PORT,
+ .parent = TYPE_PCIE_ROOT_PORT,
+ .instance_size = sizeof(AspeedPCIERootPortState),
+ .class_init = aspeed_pcie_root_port_class_init,
+};
+
+/*
+ * PCIe Root Complex (RC)
+ */
+
+#define ASPEED_PCIE_CFG_RC_MAX_MSI 64
+
+static void aspeed_pcie_rc_set_irq(void *opaque, int irq, int level)
+{
+ AspeedPCIERcState *rc = (AspeedPCIERcState *) opaque;
+ AspeedPCIECfgState *cfg =
+ container_of(rc, AspeedPCIECfgState, rc);
+ bool intx;
+
+ assert(irq < PCI_NUM_PINS);
+
+ if (level) {
+ cfg->regs[cfg->rc_regs->int_sts_reg] |= BIT(irq);
+ } else {
+ cfg->regs[cfg->rc_regs->int_sts_reg] &= ~BIT(irq);
+ }
+
+ intx = !!(cfg->regs[cfg->rc_regs->int_sts_reg] &
+ cfg->regs[cfg->rc_regs->int_en_reg]);
+ trace_aspeed_pcie_rc_intx_set_irq(cfg->id, irq, intx);
+ qemu_set_irq(rc->irq, intx);
+}
+
+static int aspeed_pcie_rc_map_irq(PCIDevice *pci_dev, int irq_num)
+{
+ return irq_num % PCI_NUM_PINS;
+}
+
+static void aspeed_pcie_rc_msi_notify(AspeedPCIERcState *rc, uint64_t data)
+{
+ AspeedPCIECfgState *cfg =
+ container_of(rc, AspeedPCIECfgState, rc);
+ uint32_t reg;
+
+ /* Written data is the HW IRQ number */
+ assert(data < ASPEED_PCIE_CFG_RC_MAX_MSI);
+
+ reg = (data < 32) ?
+ cfg->rc_regs->msi_sts0_reg : cfg->rc_regs->msi_sts1_reg;
+ cfg->regs[reg] |= BIT(data % 32);
+
+ trace_aspeed_pcie_rc_msi_set_irq(cfg->id, data, 1);
+ qemu_set_irq(rc->irq, 1);
+}
+
+static void aspeed_pcie_rc_msi_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+ AspeedPCIERcState *rc = ASPEED_PCIE_RC(opaque);
+ AspeedPCIECfgState *cfg =
+ container_of(rc, AspeedPCIECfgState, rc);
+
+ trace_aspeed_pcie_rc_msi_notify(cfg->id, addr + rc->msi_addr, data);
+ aspeed_pcie_rc_msi_notify(rc, data);
+}
+
+static const MemoryRegionOps aspeed_pcie_rc_msi_ops = {
+ .write = aspeed_pcie_rc_msi_write,
+ .read = NULL,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static AddressSpace *aspeed_pcie_rc_get_as(PCIBus *bus, void *opaque, int devfn)
+{
+ AspeedPCIERcState *rc = ASPEED_PCIE_RC(opaque);
+ return &rc->iommu_as;
+}
+
+static const PCIIOMMUOps aspeed_pcie_rc_iommu_ops = {
+ .get_address_space = aspeed_pcie_rc_get_as,
+};
+
+static void aspeed_pcie_rc_realize(DeviceState *dev, Error **errp)
+{
+ PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
+ AspeedPCIERcState *rc = ASPEED_PCIE_RC(dev);
+ AspeedPCIECfgState *cfg =
+ container_of(rc, AspeedPCIECfgState, rc);
+ PCIHostState *pci = PCI_HOST_BRIDGE(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ g_autofree char *ioport_window_name = NULL;
+ g_autofree char *mmio_window_name = NULL;
+ g_autofree char *iommu_root_name = NULL;
+ g_autofree char *dram_alias_name = NULL;
+ g_autofree char *root_bus_name = NULL;
+
+ /* PCI configuration space */
+ pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
+ sysbus_init_mmio(sbd, &pex->mmio);
+
+ /* MMIO and IO region */
+ memory_region_init(&rc->mmio, OBJECT(rc), "mmio", UINT64_MAX);
+ memory_region_init(&rc->io, OBJECT(rc), "io", 0x10000);
+
+ mmio_window_name = g_strdup_printf("pcie.%d.mmio_window", cfg->id);
+ memory_region_init_io(&rc->mmio_window, OBJECT(rc), &unassigned_io_ops,
+ OBJECT(rc), mmio_window_name, UINT64_MAX);
+ ioport_window_name = g_strdup_printf("pcie.%d.ioport_window", cfg->id);
+ memory_region_init_io(&rc->io_window, OBJECT(rc), &unassigned_io_ops,
+ OBJECT(rc), ioport_window_name, 0x10000);
+
+ memory_region_add_subregion(&rc->mmio_window, 0, &rc->mmio);
+ memory_region_add_subregion(&rc->io_window, 0, &rc->io);
+ sysbus_init_mmio(sbd, &rc->mmio_window);
+ sysbus_init_mmio(sbd, &rc->io_window);
+
+ sysbus_init_irq(sbd, &rc->irq);
+ root_bus_name = g_strdup_printf("pcie.rc%d", cfg->id);
+ pci->bus = pci_register_root_bus(dev, root_bus_name,
+ aspeed_pcie_rc_set_irq,
+ aspeed_pcie_rc_map_irq, rc, &rc->mmio,
+ &rc->io, 0, 4, TYPE_PCIE_BUS);
+ pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
+
+ /*
+ * PCIe memory view setup
+ *
+ * Background:
+ * - On AST2700, all Root Complexes use the same MSI address. This MSI
+ * address is not normal system RAM - it is a PCI system memory address.
+ * If we map the MSI/MSI-X window into real system memory, a write from
+ * one EP can be seen by all RCs and wrongly trigger interrupts on them.
+ *
+ * Design:
+ * - MSI/MSI-X here is just a placeholder address so RC and EP can talk.
+ * We make a separate MMIO space (iommu_root) for the MSI window so the
+ * writes stay local to each RC.
+ *
+ * DMA:
+ * - EPs still need access to real system memory for DMA. We add a DRAM
+ * alias in the PCI space so DMA works as expected.
+ */
+ iommu_root_name = g_strdup_printf("pcie.%d.iommu_root", cfg->id);
+ memory_region_init(&rc->iommu_root, OBJECT(rc), iommu_root_name,
+ UINT64_MAX);
+ address_space_init(&rc->iommu_as, &rc->iommu_root, iommu_root_name);
+ /* setup MSI */
+ memory_region_init_io(&rc->msi_window, OBJECT(rc),
+ &aspeed_pcie_rc_msi_ops, rc,
+ "msi_window", 4);
+ memory_region_add_subregion(&rc->iommu_root, rc->msi_addr,
+ &rc->msi_window);
+ /* setup DRAM for DMA */
+ assert(rc->dram_mr != NULL);
+ dram_alias_name = g_strdup_printf("pcie.%d.dram_alias", cfg->id);
+ memory_region_init_alias(&rc->dram_alias, OBJECT(rc), dram_alias_name,
+ rc->dram_mr, 0, memory_region_size(rc->dram_mr));
+ memory_region_add_subregion(&rc->iommu_root, rc->dram_base,
+ &rc->dram_alias);
+ pci_setup_iommu(pci->bus, &aspeed_pcie_rc_iommu_ops, rc);
+
+ /* setup root device */
+ if (rc->has_rd) {
+ object_initialize_child(OBJECT(rc), "root_device", &rc->root_device,
+ TYPE_ASPEED_PCIE_ROOT_DEVICE);
+ qdev_prop_set_int32(DEVICE(&rc->root_device), "addr",
+ PCI_DEVFN(0, 0));
+ qdev_prop_set_bit(DEVICE(&rc->root_device), "multifunction", false);
+ if (!qdev_realize(DEVICE(&rc->root_device), BUS(pci->bus), errp)) {
+ return;
+ }
+ }
+
+ /* setup root port */
+ qdev_prop_set_int32(DEVICE(&rc->root_port), "addr", rc->rp_addr);
+ qdev_prop_set_uint16(DEVICE(&rc->root_port), "chassis", cfg->id);
+ if (!qdev_realize(DEVICE(&rc->root_port), BUS(pci->bus), errp)) {
+ return;
+ }
+}
+
+static const char *aspeed_pcie_rc_root_bus_path(PCIHostState *host_bridge,
+ PCIBus *rootbus)
+{
+ AspeedPCIERcState *rc = ASPEED_PCIE_RC(host_bridge);
+ AspeedPCIECfgState *cfg =
+ container_of(rc, AspeedPCIECfgState, rc);
+
+ snprintf(rc->name, sizeof(rc->name), "%04x:%02x", cfg->id, rc->bus_nr);
+
+ return rc->name;
+}
+
+static void aspeed_pcie_rc_instance_init(Object *obj)
+{
+ AspeedPCIERcState *rc = ASPEED_PCIE_RC(obj);
+ AspeedPCIERootPortState *root_port = &rc->root_port;
+
+ object_initialize_child(obj, "root_port", root_port,
+ TYPE_ASPEED_PCIE_ROOT_PORT);
+}
+
+static const Property aspeed_pcie_rc_props[] = {
+ DEFINE_PROP_UINT32("bus-nr", AspeedPCIERcState, bus_nr, 0),
+ DEFINE_PROP_BOOL("has-rd", AspeedPCIERcState, has_rd, 0),
+ DEFINE_PROP_UINT32("rp-addr", AspeedPCIERcState, rp_addr, 0),
+ DEFINE_PROP_UINT32("msi-addr", AspeedPCIERcState, msi_addr, 0),
+ DEFINE_PROP_UINT64("dram-base", AspeedPCIERcState, dram_base, 0),
+ DEFINE_PROP_LINK("dram", AspeedPCIERcState, dram_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+};
+
+static void aspeed_pcie_rc_class_init(ObjectClass *klass, const void *data)
+{
+ PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->desc = "ASPEED PCIe RC";
+ dc->realize = aspeed_pcie_rc_realize;
+ dc->fw_name = "pci";
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+
+ hc->root_bus_path = aspeed_pcie_rc_root_bus_path;
+ device_class_set_props(dc, aspeed_pcie_rc_props);
+
+ msi_nonbroken = true;
+}
+
+static const TypeInfo aspeed_pcie_rc_info = {
+ .name = TYPE_ASPEED_PCIE_RC,
+ .parent = TYPE_PCIE_HOST_BRIDGE,
+ .instance_size = sizeof(AspeedPCIERcState),
+ .instance_init = aspeed_pcie_rc_instance_init,
+ .class_init = aspeed_pcie_rc_class_init,
+};
+
+/*
+ * PCIe Config
+ *
+ * AHB to PCIe Bus Bridge (H2X)
+ *
+ * On the AST2600:
+ * NOTE: rc_l is not supported by this model.
+ * - Registers 0x00 - 0x7F are shared by both PCIe0 (rc_l) and PCIe1 (rc_h).
+ * - Registers 0x80 - 0xBF are specific to PCIe0.
+ * - Registers 0xC0 - 0xFF are specific to PCIe1.
+ *
+ * On the AST2700:
+ * - The register range 0x00 - 0xFF is assigned to a single PCIe configuration.
+ * - There are three PCIe Root Complexes (RCs), each with its own dedicated H2X
+ * register set of size 0x100 (covering offsets 0x00 to 0xFF).
+ */
+
+/* AST2600 */
+REG32(H2X_CTRL, 0x00)
+ FIELD(H2X_CTRL, CLEAR_RX, 4, 1)
+REG32(H2X_TX_CLEAR, 0x08)
+ FIELD(H2X_TX_CLEAR, IDLE, 0, 1)
+REG32(H2X_RDATA, 0x0C)
+REG32(H2X_TX_DESC0, 0x10)
+REG32(H2X_TX_DESC1, 0x14)
+REG32(H2X_TX_DESC2, 0x18)
+REG32(H2X_TX_DESC3, 0x1C)
+REG32(H2X_TX_DATA, 0x20)
+REG32(H2X_TX_STS, 0x24)
+ FIELD(H2X_TX_STS, IDLE, 31, 1)
+ FIELD(H2X_TX_STS, RC_L_TX_COMP, 24, 1)
+ FIELD(H2X_TX_STS, RC_H_TX_COMP, 25, 1)
+ FIELD(H2X_TX_STS, TRIG, 0, 1)
+REG32(H2X_RC_H_CTRL, 0xC0)
+REG32(H2X_RC_H_INT_EN, 0xC4)
+REG32(H2X_RC_H_INT_STS, 0xC8)
+ SHARED_FIELD(H2X_RC_INT_INTDONE, 4, 1)
+ SHARED_FIELD(H2X_RC_INT_INTX, 0, 4)
+REG32(H2X_RC_H_RDATA, 0xCC)
+REG32(H2X_RC_H_MSI_EN0, 0xE0)
+REG32(H2X_RC_H_MSI_EN1, 0xE4)
+REG32(H2X_RC_H_MSI_STS0, 0xE8)
+REG32(H2X_RC_H_MSI_STS1, 0xEC)
+
+/* AST2700 */
+REG32(H2X_CFGE_INT_STS, 0x08)
+ FIELD(H2X_CFGE_INT_STS, TX_IDEL, 0, 1)
+ FIELD(H2X_CFGE_INT_STS, RX_BUSY, 1, 1)
+REG32(H2X_CFGI_TLP, 0x20)
+ FIELD(H2X_CFGI_TLP, ADDR, 0, 16)
+ FIELD(H2X_CFGI_TLP, BEN, 16, 4)
+ FIELD(H2X_CFGI_TLP, WR, 20, 1)
+REG32(H2X_CFGI_WDATA, 0x24)
+REG32(H2X_CFGI_CTRL, 0x28)
+ FIELD(H2X_CFGI_CTRL, FIRE, 0, 1)
+REG32(H2X_CFGI_RDATA, 0x2C)
+REG32(H2X_CFGE_TLP1, 0x30)
+REG32(H2X_CFGE_TLPN, 0x34)
+REG32(H2X_CFGE_CTRL, 0x38)
+ FIELD(H2X_CFGE_CTRL, FIRE, 0, 1)
+REG32(H2X_CFGE_RDATA, 0x3C)
+REG32(H2X_INT_EN, 0x40)
+REG32(H2X_INT_STS, 0x48)
+ FIELD(H2X_INT_STS, INTX, 0, 4)
+REG32(H2X_MSI_EN0, 0x50)
+REG32(H2X_MSI_EN1, 0x54)
+REG32(H2X_MSI_STS0, 0x58)
+REG32(H2X_MSI_STS1, 0x5C)
+
+#define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */
+#define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */
+#define TLP_FMTTYPE_CFGRD1 0x05 /* Configuration Read Type 1 */
+#define TLP_FMTTYPE_CFGWR1 0x45 /* Configuration Write Type 1 */
+
+#define PCIE_CFG_FMTTYPE_MASK(x) (((x) >> 24) & 0xff)
+#define PCIE_CFG_BYTE_EN(x) ((x) & 0xf)
+
+static const AspeedPCIERegMap aspeed_regmap = {
+ .rc = {
+ .int_en_reg = R_H2X_RC_H_INT_EN,
+ .int_sts_reg = R_H2X_RC_H_INT_STS,
+ .msi_sts0_reg = R_H2X_RC_H_MSI_STS0,
+ .msi_sts1_reg = R_H2X_RC_H_MSI_STS1,
+ },
+};
+
+static const AspeedPCIERegMap aspeed_2700_regmap = {
+ .rc = {
+ .int_en_reg = R_H2X_INT_EN,
+ .int_sts_reg = R_H2X_INT_STS,
+ .msi_sts0_reg = R_H2X_MSI_STS0,
+ .msi_sts1_reg = R_H2X_MSI_STS1,
+ },
+};
+
+static uint64_t aspeed_pcie_cfg_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque);
+ uint32_t reg = addr >> 2;
+ uint32_t value = 0;
+
+ value = s->regs[reg];
+
+ trace_aspeed_pcie_cfg_read(s->id, addr, value);
+
+ return value;
+}
+
+static void aspeed_pcie_cfg_translate_write(uint8_t byte_en, uint32_t *addr,
+ uint64_t *val, int *len)
+{
+ uint64_t packed_val = 0;
+ int first_bit = -1;
+ int index = 0;
+ int i;
+
+ *len = ctpop8(byte_en);
+
+ if (*len == 0 || *len > 4) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid byte enable: 0x%x\n",
+ __func__, byte_en);
+ return;
+ }
+
+ /* Special case: full 4-byte write must be 4-byte aligned */
+ if (byte_en == 0x0f) {
+ if ((*addr & 0x3) != 0) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: 4-byte write not 4-byte aligned: addr=0x%x\n",
+ __func__, *addr);
+ return;
+ }
+ *val &= 0xffffffffULL;
+ return;
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (byte_en & (1 << i)) {
+ if (first_bit < 0) {
+ first_bit = i;
+ }
+ packed_val |= ((*val >> (i * 8)) & 0xff) << (index * 8);
+ index++;
+ }
+ }
+
+ *addr += first_bit;
+ *val = packed_val;
+}
+
+static void aspeed_pcie_cfg_readwrite(AspeedPCIECfgState *s,
+ const AspeedPCIECfgTxDesc *desc)
+{
+ AspeedPCIERcState *rc = &s->rc;
+ PCIHostState *pci = NULL;
+ PCIDevice *pdev = NULL;
+ uint32_t cfg_addr;
+ uint32_t offset;
+ uint8_t byte_en;
+ bool is_write;
+ uint8_t devfn;
+ uint64_t val;
+ uint8_t bus;
+ int len;
+
+ val = ~0;
+ is_write = !!(desc->desc0 & BIT(30));
+ cfg_addr = desc->desc2;
+
+ bus = (cfg_addr >> 24) & 0xff;
+ devfn = (cfg_addr >> 16) & 0xff;
+ offset = cfg_addr & 0xffc;
+
+ pci = PCI_HOST_BRIDGE(rc);
+
+ /*
+ * On the AST2600, the RC_H bus number range from 0x80 to 0xFF, with the
+ * root device and root port assigned to bus 0x80 instead of the standard
+ * 0x00. To allow the PCI subsystem to correctly discover devices on the
+ * root bus, bus 0x80 is remapped to 0x00.
+ */
+ if (bus == rc->bus_nr) {
+ bus = 0;
+ }
+
+ pdev = pci_find_device(pci->bus, bus, devfn);
+ if (!pdev) {
+ s->regs[desc->rdata_reg] = ~0;
+ goto out;
+ }
+
+ switch (PCIE_CFG_FMTTYPE_MASK(desc->desc0)) {
+ case TLP_FMTTYPE_CFGWR0:
+ case TLP_FMTTYPE_CFGWR1:
+ byte_en = PCIE_CFG_BYTE_EN(desc->desc1);
+ val = desc->wdata;
+ aspeed_pcie_cfg_translate_write(byte_en, &offset, &val, &len);
+ pci_host_config_write_common(pdev, offset, pci_config_size(pdev),
+ val, len);
+ break;
+ case TLP_FMTTYPE_CFGRD0:
+ case TLP_FMTTYPE_CFGRD1:
+ val = pci_host_config_read_common(pdev, offset,
+ pci_config_size(pdev), 4);
+ s->regs[desc->rdata_reg] = val;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid CFG type. DESC0=0x%x\n",
+ __func__, desc->desc0);
+ }
+
+out:
+ trace_aspeed_pcie_cfg_rw(s->id, is_write ? "write" : "read", bus, devfn,
+ cfg_addr, val);
+}
+
+static void aspeed_pcie_cfg_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+ AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque);
+ AspeedPCIECfgTxDesc desc;
+ uint32_t reg = addr >> 2;
+ uint32_t rc_reg;
+
+ trace_aspeed_pcie_cfg_write(s->id, addr, data);
+
+ switch (reg) {
+ case R_H2X_CTRL:
+ if (data & R_H2X_CTRL_CLEAR_RX_MASK) {
+ s->regs[R_H2X_RDATA] = ~0;
+ }
+ break;
+ case R_H2X_TX_CLEAR:
+ if (data & R_H2X_TX_CLEAR_IDLE_MASK) {
+ s->regs[R_H2X_TX_STS] &= ~R_H2X_TX_STS_IDLE_MASK;
+ }
+ break;
+ case R_H2X_TX_STS:
+ if (data & R_H2X_TX_STS_TRIG_MASK) {
+ desc.desc0 = s->regs[R_H2X_TX_DESC0];
+ desc.desc1 = s->regs[R_H2X_TX_DESC1];
+ desc.desc2 = s->regs[R_H2X_TX_DESC2];
+ desc.desc3 = s->regs[R_H2X_TX_DESC3];
+ desc.wdata = s->regs[R_H2X_TX_DATA];
+ desc.rdata_reg = R_H2X_RC_H_RDATA;
+ aspeed_pcie_cfg_readwrite(s, &desc);
+ rc_reg = s->rc_regs->int_sts_reg;
+ s->regs[rc_reg] |= H2X_RC_INT_INTDONE_MASK;
+ s->regs[R_H2X_TX_STS] |=
+ BIT(R_H2X_TX_STS_RC_H_TX_COMP_SHIFT);
+ s->regs[R_H2X_TX_STS] |= R_H2X_TX_STS_IDLE_MASK;
+ }
+ break;
+ /* preserve INTx status */
+ case R_H2X_RC_H_INT_STS:
+ if (data & H2X_RC_INT_INTDONE_MASK) {
+ s->regs[R_H2X_TX_STS] &= ~R_H2X_TX_STS_RC_H_TX_COMP_MASK;
+ }
+ s->regs[reg] &= ~data | H2X_RC_INT_INTX_MASK;
+ break;
+ /*
+ * These status registers are used for notify sources ISR are executed.
+ * If one source ISR is executed, it will clear one bit.
+ * If it clear all bits, it means to initialize this register status
+ * rather than sources ISR are executed.
+ */
+ case R_H2X_RC_H_MSI_STS0:
+ case R_H2X_RC_H_MSI_STS1:
+ if (data == 0) {
+ return ;
+ }
+
+ s->regs[reg] &= ~data;
+ if (data == 0xffffffff) {
+ return;
+ }
+
+ if (!s->regs[R_H2X_RC_H_MSI_STS0] &&
+ !s->regs[R_H2X_RC_H_MSI_STS1]) {
+ trace_aspeed_pcie_rc_msi_clear_irq(s->id, 0);
+ qemu_set_irq(s->rc.irq, 0);
+ }
+ break;
+ default:
+ s->regs[reg] = data;
+ break;
+ }
+}
+
+static const MemoryRegionOps aspeed_pcie_cfg_ops = {
+ .read = aspeed_pcie_cfg_read,
+ .write = aspeed_pcie_cfg_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+};
+
+static void aspeed_pcie_cfg_instance_init(Object *obj)
+{
+ AspeedPCIECfgState *s = ASPEED_PCIE_CFG(obj);
+
+ object_initialize_child(obj, "rc", &s->rc, TYPE_ASPEED_PCIE_RC);
+ object_property_add_alias(obj, "dram", OBJECT(&s->rc), "dram");
+ object_property_add_alias(obj, "dram-base", OBJECT(&s->rc), "dram-base");
+
+ return;
+}
+
+static void aspeed_pcie_cfg_reset(DeviceState *dev)
+{
+ AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev);
+ AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(s);
+
+ memset(s->regs, 0, apc->nr_regs << 2);
+ memset(s->tlpn_fifo, 0, sizeof(s->tlpn_fifo));
+ s->tlpn_idx = 0;
+}
+
+static void aspeed_pcie_cfg_realize(DeviceState *dev, Error **errp)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev);
+ AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(s);
+ g_autofree char *name = NULL;
+
+ s->rc_regs = &apc->reg_map->rc;
+ s->regs = g_new(uint32_t, apc->nr_regs);
+ name = g_strdup_printf(TYPE_ASPEED_PCIE_CFG ".regs.%d", s->id);
+ memory_region_init_io(&s->mmio, OBJECT(s), apc->reg_ops, s, name,
+ apc->nr_regs << 2);
+ sysbus_init_mmio(sbd, &s->mmio);
+
+ object_property_set_int(OBJECT(&s->rc), "bus-nr",
+ apc->rc_bus_nr,
+ &error_abort);
+ object_property_set_bool(OBJECT(&s->rc), "has-rd",
+ apc->rc_has_rd,
+ &error_abort);
+ object_property_set_int(OBJECT(&s->rc), "rp-addr",
+ apc->rc_rp_addr,
+ &error_abort);
+ object_property_set_int(OBJECT(&s->rc), "msi-addr",
+ apc->rc_msi_addr,
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->rc), errp)) {
+ return;
+ }
+}
+
+static void aspeed_pcie_cfg_unrealize(DeviceState *dev)
+{
+ AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev);
+
+ g_free(s->regs);
+ s->regs = NULL;
+}
+
+static const Property aspeed_pcie_cfg_props[] = {
+ DEFINE_PROP_UINT32("id", AspeedPCIECfgState, id, 0),
+};
+
+static void aspeed_pcie_cfg_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_CLASS(klass);
+
+ dc->desc = "ASPEED PCIe Config";
+ dc->realize = aspeed_pcie_cfg_realize;
+ dc->unrealize = aspeed_pcie_cfg_unrealize;
+ device_class_set_legacy_reset(dc, aspeed_pcie_cfg_reset);
+ device_class_set_props(dc, aspeed_pcie_cfg_props);
+
+ apc->reg_ops = &aspeed_pcie_cfg_ops;
+ apc->reg_map = &aspeed_regmap;
+ apc->nr_regs = 0x100 >> 2;
+ apc->rc_msi_addr = 0x1e77005C;
+ apc->rc_bus_nr = 0x80;
+ apc->rc_has_rd = true;
+ apc->rc_rp_addr = PCI_DEVFN(8, 0);
+}
+
+static const TypeInfo aspeed_pcie_cfg_info = {
+ .name = TYPE_ASPEED_PCIE_CFG,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_init = aspeed_pcie_cfg_instance_init,
+ .instance_size = sizeof(AspeedPCIECfgState),
+ .class_init = aspeed_pcie_cfg_class_init,
+ .class_size = sizeof(AspeedPCIECfgClass),
+};
+
+static void aspeed_2700_pcie_cfg_write(void *opaque, hwaddr addr,
+ uint64_t data, unsigned int size)
+{
+ AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque);
+ AspeedPCIECfgTxDesc desc;
+ uint32_t reg = addr >> 2;
+
+ trace_aspeed_pcie_cfg_write(s->id, addr, data);
+
+ switch (reg) {
+ case R_H2X_CFGE_INT_STS:
+ if (data & R_H2X_CFGE_INT_STS_TX_IDEL_MASK) {
+ s->regs[R_H2X_CFGE_INT_STS] &= ~R_H2X_CFGE_INT_STS_TX_IDEL_MASK;
+ }
+
+ if (data & R_H2X_CFGE_INT_STS_RX_BUSY_MASK) {
+ s->regs[R_H2X_CFGE_INT_STS] &= ~R_H2X_CFGE_INT_STS_RX_BUSY_MASK;
+ }
+ break;
+ case R_H2X_CFGI_CTRL:
+ if (data & R_H2X_CFGI_CTRL_FIRE_MASK) {
+ /*
+ * Internal access to bridge
+ * Type and BDF are 0
+ */
+ desc.desc0 = 0x04000001 |
+ (ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, WR) << 30);
+ desc.desc1 = 0x00401000 |
+ ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, BEN);
+ desc.desc2 = 0x00000000 |
+ ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, ADDR);
+ desc.wdata = s->regs[R_H2X_CFGI_WDATA];
+ desc.rdata_reg = R_H2X_CFGI_RDATA;
+ aspeed_pcie_cfg_readwrite(s, &desc);
+ }
+ break;
+ case R_H2X_CFGE_TLPN:
+ s->tlpn_fifo[s->tlpn_idx] = data;
+ s->tlpn_idx = (s->tlpn_idx + 1) % ARRAY_SIZE(s->tlpn_fifo);
+ break;
+ case R_H2X_CFGE_CTRL:
+ if (data & R_H2X_CFGE_CTRL_FIRE_MASK) {
+ desc.desc0 = s->regs[R_H2X_CFGE_TLP1];
+ desc.desc1 = s->tlpn_fifo[0];
+ desc.desc2 = s->tlpn_fifo[1];
+ desc.wdata = s->tlpn_fifo[2];
+ desc.rdata_reg = R_H2X_CFGE_RDATA;
+ aspeed_pcie_cfg_readwrite(s, &desc);
+ s->regs[R_H2X_CFGE_INT_STS] |= R_H2X_CFGE_INT_STS_TX_IDEL_MASK;
+ s->regs[R_H2X_CFGE_INT_STS] |= R_H2X_CFGE_INT_STS_RX_BUSY_MASK;
+ s->tlpn_idx = 0;
+ }
+ break;
+
+ case R_H2X_INT_STS:
+ s->regs[reg] &= ~data | R_H2X_INT_STS_INTX_MASK;
+ break;
+ /*
+ * These status registers are used for notify sources ISR are executed.
+ * If one source ISR is executed, it will clear one bit.
+ * If it clear all bits, it means to initialize this register status
+ * rather than sources ISR are executed.
+ */
+ case R_H2X_MSI_STS0:
+ case R_H2X_MSI_STS1:
+ if (data == 0) {
+ return ;
+ }
+
+ s->regs[reg] &= ~data;
+ if (data == 0xffffffff) {
+ return;
+ }
+
+ if (!s->regs[R_H2X_MSI_STS0] &&
+ !s->regs[R_H2X_MSI_STS1]) {
+ trace_aspeed_pcie_rc_msi_clear_irq(s->id, 0);
+ qemu_set_irq(s->rc.irq, 0);
+ }
+ break;
+ default:
+ s->regs[reg] = data;
+ break;
+ }
+}
+
+static const MemoryRegionOps aspeed_2700_pcie_cfg_ops = {
+ .read = aspeed_pcie_cfg_read,
+ .write = aspeed_2700_pcie_cfg_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+};
+
+static void aspeed_2700_pcie_cfg_class_init(ObjectClass *klass,
+ const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_CLASS(klass);
+
+ dc->desc = "ASPEED 2700 PCIe Config";
+ apc->reg_ops = &aspeed_2700_pcie_cfg_ops;
+ apc->reg_map = &aspeed_2700_regmap;
+ apc->nr_regs = 0x100 >> 2;
+ apc->rc_msi_addr = 0x000000F0;
+ apc->rc_bus_nr = 0;
+ apc->rc_has_rd = false;
+ apc->rc_rp_addr = PCI_DEVFN(0, 0);
+}
+
+static const TypeInfo aspeed_2700_pcie_cfg_info = {
+ .name = TYPE_ASPEED_2700_PCIE_CFG,
+ .parent = TYPE_ASPEED_PCIE_CFG,
+ .class_init = aspeed_2700_pcie_cfg_class_init,
+};
+
+/*
+ * PCIe PHY
+ *
+ * PCIe Host Controller (PCIEH)
+ */
+
+/* AST2600 */
+REG32(PEHR_ID, 0x00)
+ FIELD(PEHR_ID, DEV, 16, 16)
+REG32(PEHR_CLASS_CODE, 0x04)
+REG32(PEHR_DATALINK, 0x10)
+REG32(PEHR_PROTECT, 0x7C)
+ FIELD(PEHR_PROTECT, LOCK, 0, 8)
+REG32(PEHR_LINK, 0xC0)
+ FIELD(PEHR_LINK, STS, 5, 1)
+
+/* AST2700 */
+REG32(PEHR_2700_LINK_GEN2, 0x344)
+ FIELD(PEHR_2700_LINK_GEN2, STS, 18, 1)
+REG32(PEHR_2700_LINK_GEN4, 0x358)
+ FIELD(PEHR_2700_LINK_GEN4, STS, 8, 1)
+
+#define ASPEED_PCIE_PHY_UNLOCK 0xA8
+
+static uint64_t aspeed_pcie_phy_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(opaque);
+ uint32_t reg = addr >> 2;
+ uint32_t value = 0;
+
+ value = s->regs[reg];
+
+ trace_aspeed_pcie_phy_read(s->id, addr, value);
+
+ return value;
+}
+
+static void aspeed_pcie_phy_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+ AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(opaque);
+ uint32_t reg = addr >> 2;
+
+ trace_aspeed_pcie_phy_write(s->id, addr, data);
+
+ switch (reg) {
+ case R_PEHR_PROTECT:
+ data &= R_PEHR_PROTECT_LOCK_MASK;
+ s->regs[reg] = !!(data == ASPEED_PCIE_PHY_UNLOCK);
+ break;
+ default:
+ s->regs[reg] = data;
+ break;
+ }
+}
+
+static const MemoryRegionOps aspeed_pcie_phy_ops = {
+ .read = aspeed_pcie_phy_read,
+ .write = aspeed_pcie_phy_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+};
+
+static void aspeed_pcie_phy_reset(DeviceState *dev)
+{
+ AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
+ AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s);
+
+ memset(s->regs, 0, apc->nr_regs << 2);
+
+ s->regs[R_PEHR_ID] =
+ (0x1150 << R_PEHR_ID_DEV_SHIFT) | PCI_VENDOR_ID_ASPEED;
+ s->regs[R_PEHR_CLASS_CODE] = 0x06040006;
+ s->regs[R_PEHR_DATALINK] = 0xD7040022;
+ s->regs[R_PEHR_LINK] = R_PEHR_LINK_STS_MASK;
+}
+
+static void aspeed_pcie_phy_realize(DeviceState *dev, Error **errp)
+{
+ AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
+ AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ g_autofree char *name = NULL;
+
+ s->regs = g_new(uint32_t, apc->nr_regs);
+ name = g_strdup_printf(TYPE_ASPEED_PCIE_PHY ".regs.%d", s->id);
+ memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_pcie_phy_ops, s, name,
+ apc->nr_regs << 2);
+ sysbus_init_mmio(sbd, &s->mmio);
+}
+
+static void aspeed_pcie_phy_unrealize(DeviceState *dev)
+{
+ AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
+
+ g_free(s->regs);
+ s->regs = NULL;
+}
+
+static const Property aspeed_pcie_phy_props[] = {
+ DEFINE_PROP_UINT32("id", AspeedPCIEPhyState, id, 0),
+};
+
+static void aspeed_pcie_phy_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_CLASS(klass);
+
+ dc->desc = "ASPEED PCIe Phy";
+ dc->realize = aspeed_pcie_phy_realize;
+ dc->unrealize = aspeed_pcie_phy_unrealize;
+ device_class_set_legacy_reset(dc, aspeed_pcie_phy_reset);
+ device_class_set_props(dc, aspeed_pcie_phy_props);
+
+ apc->nr_regs = 0x100 >> 2;
+}
+
+static const TypeInfo aspeed_pcie_phy_info = {
+ .name = TYPE_ASPEED_PCIE_PHY,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AspeedPCIEPhyState),
+ .class_init = aspeed_pcie_phy_class_init,
+ .class_size = sizeof(AspeedPCIEPhyClass),
+};
+
+static void aspeed_2700_pcie_phy_reset(DeviceState *dev)
+{
+ AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
+ AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s);
+
+ memset(s->regs, 0, apc->nr_regs << 2);
+
+ s->regs[R_PEHR_ID] =
+ (0x1150 << R_PEHR_ID_DEV_SHIFT) | PCI_VENDOR_ID_ASPEED;
+ s->regs[R_PEHR_CLASS_CODE] = 0x06040011;
+ s->regs[R_PEHR_2700_LINK_GEN2] = R_PEHR_2700_LINK_GEN2_STS_MASK;
+ s->regs[R_PEHR_2700_LINK_GEN4] = R_PEHR_2700_LINK_GEN4_STS_MASK;
+}
+
+static void aspeed_2700_pcie_phy_class_init(ObjectClass *klass,
+ const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_CLASS(klass);
+
+ dc->desc = "ASPEED AST2700 PCIe Phy";
+ device_class_set_legacy_reset(dc, aspeed_2700_pcie_phy_reset);
+
+ apc->nr_regs = 0x800 >> 2;
+}
+
+static const TypeInfo aspeed_2700_pcie_phy_info = {
+ .name = TYPE_ASPEED_2700_PCIE_PHY,
+ .parent = TYPE_ASPEED_PCIE_PHY,
+ .class_init = aspeed_2700_pcie_phy_class_init,
+};
+
+static void aspeed_pcie_register_types(void)
+{
+ type_register_static(&aspeed_pcie_rc_info);
+ type_register_static(&aspeed_pcie_root_device_info);
+ type_register_static(&aspeed_pcie_root_port_info);
+ type_register_static(&aspeed_pcie_cfg_info);
+ type_register_static(&aspeed_2700_pcie_cfg_info);
+ type_register_static(&aspeed_pcie_phy_info);
+ type_register_static(&aspeed_2700_pcie_phy_info);
+}
+
+type_init(aspeed_pcie_register_types);
+
diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
index 937a0f7..86b754d 100644
--- a/hw/pci-host/meson.build
+++ b/hw/pci-host/meson.build
@@ -2,6 +2,7 @@ pci_ss = ss.source_set()
pci_ss.add(when: 'CONFIG_PAM', if_true: files('pam.c'))
pci_ss.add(when: 'CONFIG_PCI_BONITO', if_true: files('bonito.c'))
pci_ss.add(when: 'CONFIG_GT64120', if_true: files('gt64120.c'))
+pci_ss.add(when: 'CONFIG_PCI_EXPRESS_ASPEED', if_true: files('aspeed_pcie.c'))
pci_ss.add(when: 'CONFIG_PCI_EXPRESS_DESIGNWARE', if_true: files('designware.c'))
pci_ss.add(when: 'CONFIG_PCI_EXPRESS_GENERIC_BRIDGE', if_true: files('gpex.c'))
pci_ss.add(when: ['CONFIG_PCI_EXPRESS_GENERIC_BRIDGE', 'CONFIG_ACPI'], if_true: files('gpex-acpi.c'))
diff --git a/hw/pci-host/trace-events b/hw/pci-host/trace-events
index 0a816b9..a6fd88c 100644
--- a/hw/pci-host/trace-events
+++ b/hw/pci-host/trace-events
@@ -1,5 +1,16 @@
# See docs/devel/tracing.rst for syntax documentation.
+# aspeed_pcie.c
+aspeed_pcie_rc_intx_set_irq(uint32_t id, int num, int level) "%d: num %d set IRQ leve %d"
+aspeed_pcie_rc_msi_notify(uint32_t id, uint64_t addr, uint64_t data) "%d: 0x%" PRIx64 " data 0x%" PRIx64
+aspeed_pcie_rc_msi_set_irq(uint32_t id, uint64_t unm, int level) "%d: num 0x%" PRIx64 " set IRQ level %d"
+aspeed_pcie_rc_msi_clear_irq(uint32_t id, int level) "%d: clear IRQ level %d"
+aspeed_pcie_cfg_read(uint32_t id, uint64_t addr, uint32_t value) "%d: addr 0x%" PRIx64 " value 0x%" PRIx32
+aspeed_pcie_cfg_write(uint32_t id, uint64_t addr, uint32_t value) "%d: addr 0x%" PRIx64 " value 0x%" PRIx32
+aspeed_pcie_cfg_rw(uint32_t id, const char *dir, uint8_t bus, uint8_t devfn, uint64_t addr, uint64_t data) "%d: %s bus:0x%x devfn:0x%x addr 0x%" PRIx64 " data 0x%" PRIx64
+aspeed_pcie_phy_read(uint32_t id, uint64_t addr, uint32_t value) "%d: addr 0x%" PRIx64 " value 0x%" PRIx32
+aspeed_pcie_phy_write(uint32_t id, uint64_t addr, uint32_t value) "%d: addr 0x%" PRIx64 " value 0x%" PRIx32
+
# bonito.c
bonito_spciconf_small_access(uint64_t addr, unsigned size) "PCI config address is smaller then 32-bit, addr: 0x%"PRIx64", size: %u"
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 217ef0e..ed32efb 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -37,11 +37,14 @@
#include "qom/object.h"
#include "hw/misc/aspeed_lpc.h"
#include "hw/misc/unimp.h"
+#include "hw/pci-host/aspeed_pcie.h"
#include "hw/misc/aspeed_peci.h"
#include "hw/fsi/aspeed_apb2opb.h"
#include "hw/char/serial-mm.h"
#include "hw/intc/arm_gicv3.h"
+#define VBOOTROM_FILE_NAME "ast27x0_bootrom.bin"
+
#define ASPEED_SPIS_NUM 3
#define ASPEED_EHCIS_NUM 4
#define ASPEED_WDTS_NUM 8
@@ -49,6 +52,7 @@
#define ASPEED_MACS_NUM 4
#define ASPEED_UARTS_NUM 13
#define ASPEED_JTAG_NUM 2
+#define ASPEED_PCIE_NUM 3
struct AspeedSoCState {
DeviceState parent;
@@ -60,6 +64,7 @@ struct AspeedSoCState {
MemoryRegion spi_boot_container;
MemoryRegion spi_boot;
MemoryRegion vbootrom;
+ MemoryRegion pcie_mmio_alias[ASPEED_PCIE_NUM];
AddressSpace dram_as;
AspeedRtcState rtc;
AspeedTimerCtrlState timerctrl;
@@ -87,6 +92,8 @@ struct AspeedSoCState {
AspeedSDHCIState sdhci;
AspeedSDHCIState emmc;
AspeedLPCState lpc;
+ AspeedPCIECfgState pcie[ASPEED_PCIE_NUM];
+ AspeedPCIEPhyState pcie_phy[ASPEED_PCIE_NUM];
AspeedPECIState peci;
SerialMM uart[ASPEED_UARTS_NUM];
Clock *sysclk;
@@ -181,6 +188,7 @@ struct AspeedSoCClass {
uint32_t silicon_rev;
uint64_t sram_size;
uint64_t secsram_size;
+ int pcie_num;
int spis_num;
int ehcis_num;
int wdts_num;
@@ -254,6 +262,15 @@ enum {
ASPEED_DEV_LPC,
ASPEED_DEV_IBT,
ASPEED_DEV_I2C,
+ ASPEED_DEV_PCIE0,
+ ASPEED_DEV_PCIE1,
+ ASPEED_DEV_PCIE2,
+ ASPEED_DEV_PCIE_PHY0,
+ ASPEED_DEV_PCIE_PHY1,
+ ASPEED_DEV_PCIE_PHY2,
+ ASPEED_DEV_PCIE_MMIO0,
+ ASPEED_DEV_PCIE_MMIO1,
+ ASPEED_DEV_PCIE_MMIO2,
ASPEED_DEV_PECI,
ASPEED_DEV_ETH1,
ASPEED_DEV_ETH2,
@@ -297,6 +314,12 @@ void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
uint64_t size);
void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
unsigned int count, int unit0);
+void aspeed_write_boot_rom(BlockBackend *blk, hwaddr addr, size_t rom_size,
+ Error **errp);
+void aspeed_install_boot_rom(AspeedSoCState *soc, BlockBackend *blk,
+ MemoryRegion *boot_rom, uint64_t rom_size);
+void aspeed_load_vbootrom(AspeedSoCState *soc, const char *bios_name,
+ Error **errp);
static inline int aspeed_uart_index(int uart_dev)
{
diff --git a/include/hw/misc/aspeed_sbc.h b/include/hw/misc/aspeed_sbc.h
index 405e678..7d640a0 100644
--- a/include/hw/misc/aspeed_sbc.h
+++ b/include/hw/misc/aspeed_sbc.h
@@ -10,9 +10,11 @@
#define ASPEED_SBC_H
#include "hw/sysbus.h"
+#include "hw/nvram/aspeed_otp.h"
#define TYPE_ASPEED_SBC "aspeed.sbc"
#define TYPE_ASPEED_AST2600_SBC TYPE_ASPEED_SBC "-ast2600"
+#define TYPE_ASPEED_AST10X0_SBC TYPE_ASPEED_SBC "-ast10x0"
OBJECT_DECLARE_TYPE(AspeedSBCState, AspeedSBCClass, ASPEED_SBC)
#define ASPEED_SBC_NR_REGS (0x93c >> 2)
@@ -36,10 +38,14 @@ struct AspeedSBCState {
MemoryRegion iomem;
uint32_t regs[ASPEED_SBC_NR_REGS];
+
+ AspeedOTPState otp;
};
struct AspeedSBCClass {
SysBusDeviceClass parent_class;
+
+ bool has_otp;
};
#endif /* ASPEED_SBC_H */
diff --git a/include/hw/nvram/aspeed_otp.h b/include/hw/nvram/aspeed_otp.h
new file mode 100644
index 0000000..3752353
--- /dev/null
+++ b/include/hw/nvram/aspeed_otp.h
@@ -0,0 +1,33 @@
+/*
+ * ASPEED OTP (One-Time Programmable) memory
+ *
+ * Copyright (C) 2025 Aspeed
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_OTP_H
+#define ASPEED_OTP_H
+
+#include "system/memory.h"
+#include "hw/block/block.h"
+#include "system/address-spaces.h"
+
+#define TYPE_ASPEED_OTP "aspeed-otp"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedOTPState, ASPEED_OTP)
+
+typedef struct AspeedOTPState {
+ DeviceState parent_obj;
+
+ BlockBackend *blk;
+
+ uint64_t size;
+
+ AddressSpace as;
+
+ MemoryRegion mmio;
+
+ uint8_t *storage;
+} AspeedOTPState;
+
+#endif /* ASPEED_OTP_H */
diff --git a/include/hw/pci-host/aspeed_pcie.h b/include/hw/pci-host/aspeed_pcie.h
new file mode 100644
index 0000000..be53ea96
--- /dev/null
+++ b/include/hw/pci-host/aspeed_pcie.h
@@ -0,0 +1,137 @@
+/*
+ * ASPEED PCIe Host Controller
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ * Copyright (c) 2022 CƩdric Le Goater <clg@kaod.org>
+ *
+ * Authors:
+ * CƩdric Le Goater <clg@kaod.org>
+ * Jamin Lin <jamin_lin@aspeedtech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Based on previous work from CƩdric Le Goater.
+ * Modifications extend support for the ASPEED AST2600 and AST2700 platforms.
+ */
+
+#ifndef ASPEED_PCIE_H
+#define ASPEED_PCIE_H
+
+#include "hw/sysbus.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pcie_port.h"
+#include "qom/object.h"
+
+typedef struct AspeedPCIECfgTxDesc {
+ uint32_t desc0;
+ uint32_t desc1;
+ uint32_t desc2;
+ uint32_t desc3;
+ uint32_t wdata;
+ uint32_t rdata_reg;
+} AspeedPCIECfgTxDesc;
+
+typedef struct AspeedPCIERcRegs {
+ uint32_t int_en_reg;
+ uint32_t int_sts_reg;
+ uint32_t msi_sts0_reg;
+ uint32_t msi_sts1_reg;
+} AspeedPCIERcRegs;
+
+typedef struct AspeedPCIERegMap {
+ AspeedPCIERcRegs rc;
+} AspeedPCIERegMap;
+
+#define TYPE_ASPEED_PCIE_ROOT_PORT "aspeed.pcie-root-port"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERootPortState, ASPEED_PCIE_ROOT_PORT)
+
+typedef struct AspeedPCIERootPortState {
+ PCIESlot parent_obj;
+} AspeedPCIERootPortState;
+
+#define TYPE_ASPEED_PCIE_ROOT_DEVICE "aspeed.pcie-root-device"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERootDeviceState, ASPEED_PCIE_ROOT_DEVICE);
+
+struct AspeedPCIERootDeviceState {
+ PCIBridge parent_obj;
+};
+
+#define TYPE_ASPEED_PCIE_RC "aspeed.pcie-rc"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERcState, ASPEED_PCIE_RC);
+
+struct AspeedPCIERcState {
+ PCIExpressHost parent_obj;
+
+ MemoryRegion iommu_root;
+ AddressSpace iommu_as;
+ MemoryRegion dram_alias;
+ MemoryRegion *dram_mr;
+ MemoryRegion mmio_window;
+ MemoryRegion msi_window;
+ MemoryRegion io_window;
+ MemoryRegion mmio;
+ MemoryRegion io;
+
+ uint64_t dram_base;
+ uint32_t msi_addr;
+ uint32_t rp_addr;
+ uint32_t bus_nr;
+ char name[16];
+ bool has_rd;
+ qemu_irq irq;
+
+ AspeedPCIERootDeviceState root_device;
+ AspeedPCIERootPortState root_port;
+};
+
+/* Bridge between AHB bus and PCIe RC. */
+#define TYPE_ASPEED_PCIE_CFG "aspeed.pcie-cfg"
+#define TYPE_ASPEED_2700_PCIE_CFG TYPE_ASPEED_PCIE_CFG "-ast2700"
+OBJECT_DECLARE_TYPE(AspeedPCIECfgState, AspeedPCIECfgClass, ASPEED_PCIE_CFG);
+
+struct AspeedPCIECfgState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t *regs;
+ uint32_t id;
+
+ const AspeedPCIERcRegs *rc_regs;
+ AspeedPCIERcState rc;
+ uint32_t tlpn_fifo[3];
+ uint32_t tlpn_idx;
+};
+
+struct AspeedPCIECfgClass {
+ SysBusDeviceClass parent_class;
+
+ const AspeedPCIERegMap *reg_map;
+ const MemoryRegionOps *reg_ops;
+
+ uint32_t rc_msi_addr;
+ uint32_t rc_rp_addr;
+ uint64_t rc_bus_nr;
+ uint64_t nr_regs;
+ bool rc_has_rd;
+};
+
+#define TYPE_ASPEED_PCIE_PHY "aspeed.pcie-phy"
+#define TYPE_ASPEED_2700_PCIE_PHY TYPE_ASPEED_PCIE_PHY "-ast2700"
+OBJECT_DECLARE_TYPE(AspeedPCIEPhyState, AspeedPCIEPhyClass, ASPEED_PCIE_PHY);
+
+struct AspeedPCIEPhyState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t *regs;
+ uint32_t id;
+};
+
+struct AspeedPCIEPhyClass {
+ SysBusDeviceClass parent_class;
+
+ uint64_t nr_regs;
+};
+
+#endif /* ASPEED_PCIE_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 33e2898..16034aa 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -291,4 +291,6 @@
#define PCI_VENDOR_ID_NVIDIA 0x10de
+#define PCI_VENDOR_ID_ASPEED 0x1A03
+
#endif
diff --git a/meson.build b/meson.build
index bdfb621..55c8202 100644
--- a/meson.build
+++ b/meson.build
@@ -681,6 +681,9 @@ if get_option('cfi')
error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
endif
if get_option('cfi_debug')
+ if get_option('safe_stack')
+ error('cfi_debug is not compatible with safe_stack')
+ endif
if cc.compiles('int main () { return 0; }',
name: '-fno-sanitize-trap=cfi-icall',
args: ['-flto', '-fsanitize=cfi-icall',
@@ -1350,7 +1353,13 @@ if get_option('spice') \
endif
spice_headers = spice.partial_dependency(compile_args: true, includes: true)
-rt = cc.find_library('rt', required: false)
+rt = not_found
+if host_os != 'windows'
+ have_shm_open = cc.has_function('shm_open')
+ if not have_shm_open
+ rt = cc.find_library('rt', required: true)
+ endif
+endif
libiscsi = not_found
if not get_option('libiscsi').auto() or have_block
@@ -3812,14 +3821,10 @@ util_ss = util_ss.apply({})
libqemuutil = static_library('qemuutil',
build_by_default: false,
sources: util_ss.sources() + stub_ss.sources() + genh,
- dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc])
-qemuutil_deps = [event_loop_base]
-if host_os != 'windows'
- qemuutil_deps += [rt]
-endif
+ dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, rt])
qemuutil = declare_dependency(link_with: libqemuutil,
sources: genh + version_res,
- dependencies: qemuutil_deps)
+ dependencies: [event_loop_base])
if have_system or have_user
decodetree = generator(find_program('scripts/decodetree.py'),
@@ -4233,8 +4238,7 @@ if have_rust
'--no-layout-tests',
'--no-prepend-enum-name',
'--allowlist-file', meson.project_source_root() + '/include/.*',
- '--allowlist-file', meson.project_source_root() + '/.*',
- '--allowlist-file', meson.project_build_root() + '/.*'
+ '--allowlist-file', meson.project_build_root() + '/.*',
]
if not rustfmt.found()
if bindgen.version().version_compare('<0.65.0')
@@ -4252,6 +4256,10 @@ if have_rust
else
bindgen_args_common += ['--merge-extern-blocks']
endif
+ bindgen_c_args = []
+ if host_arch == 'wasm32'
+ bindgen_c_args += ['-fvisibility=default']
+ endif
subdir('rust')
endif
@@ -5036,6 +5044,14 @@ elif host_long_bits < 64
message()
message('Support for 32-bit CPU host architecture ' + cpu + ' is going')
message('to be dropped in a future QEMU release.')
+elif host_arch == 'mips'
+ message()
+ warning('DEPRECATED HOST CPU')
+ message()
+ message('Support for CPU host architecture ' + cpu + ' is going to be')
+ message('dropped as soon as the QEMU project stops supporting Debian 12')
+ message('("Bookworm"). Going forward, the QEMU project will not guarantee')
+ message('that QEMU will compile or work on this host CPU.')
endif
if not supported_oses.contains(host_os)
diff --git a/rust/bql/meson.build b/rust/bql/meson.build
index 7214d94..bc51c7f 100644
--- a/rust/bql/meson.build
+++ b/rust/bql/meson.build
@@ -21,6 +21,7 @@ _bql_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common,
+ c_args: bindgen_c_args,
)
_bql_rs = static_library(
diff --git a/rust/chardev/meson.build b/rust/chardev/meson.build
index 370895c..e7ce02b 100644
--- a/rust/chardev/meson.build
+++ b/rust/chardev/meson.build
@@ -20,6 +20,7 @@ _chardev_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common + _chardev_bindgen_args,
+ c_args: bindgen_c_args,
)
_chardev_rs = static_library(
diff --git a/rust/hw/char/pl011/meson.build b/rust/hw/char/pl011/meson.build
index ffdc8af..a33f329 100644
--- a/rust/hw/char/pl011/meson.build
+++ b/rust/hw/char/pl011/meson.build
@@ -12,6 +12,7 @@ _libpl011_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common,
+ c_args: bindgen_c_args,
)
_libpl011_rs = static_library(
diff --git a/rust/hw/core/meson.build b/rust/hw/core/meson.build
index 81d8c77..e1ae95e 100644
--- a/rust/hw/core/meson.build
+++ b/rust/hw/core/meson.build
@@ -41,6 +41,7 @@ _hwcore_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common + _hwcore_bindgen_args,
+ c_args: bindgen_c_args,
)
_hwcore_rs = static_library(
diff --git a/rust/migration/meson.build b/rust/migration/meson.build
index 2a49bd1..ddf5c2f 100644
--- a/rust/migration/meson.build
+++ b/rust/migration/meson.build
@@ -22,7 +22,8 @@ _migration_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common + _migration_bindgen_args,
- )
+ c_args: bindgen_c_args,
+)
_migration_rs = static_library(
'migration',
diff --git a/rust/qom/meson.build b/rust/qom/meson.build
index 21e1214..71fdac6 100644
--- a/rust/qom/meson.build
+++ b/rust/qom/meson.build
@@ -12,6 +12,7 @@ _qom_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common,
+ c_args: bindgen_c_args,
)
_qom_rs = static_library(
diff --git a/rust/system/meson.build b/rust/system/meson.build
index 3ec140d..0859f39 100644
--- a/rust/system/meson.build
+++ b/rust/system/meson.build
@@ -20,6 +20,7 @@ _system_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common + _system_bindgen_args,
+ c_args: bindgen_c_args,
)
_system_rs = static_library(
diff --git a/rust/util/meson.build b/rust/util/meson.build
index 7ca6993..094b433 100644
--- a/rust/util/meson.build
+++ b/rust/util/meson.build
@@ -22,6 +22,7 @@ _util_bindings_inc_rs = rust.bindgen(
include_directories: bindings_incdir,
bindgen_version: ['>=0.60.0'],
args: bindgen_args_common + _util_bindgen_args,
+ c_args: bindgen_c_args,
)
_util_rs = static_library(
diff --git a/scripts/archive-source.sh b/scripts/archive-source.sh
index 476a996..a725dd9 100755
--- a/scripts/archive-source.sh
+++ b/scripts/archive-source.sh
@@ -26,12 +26,27 @@ sub_file="${sub_tdir}/submodule.tar"
# independent of what the developer currently has initialized
# in their checkout, because the build environment is completely
# different to the host OS.
-subprojects="keycodemapdb libvfio-user berkeley-softfloat-3
- berkeley-testfloat-3 anyhow-1-rs arbitrary-int-1-rs attrs-0.2-rs bilge-0.2-rs
- bilge-impl-0.2-rs either-1-rs foreign-0.3-rs itertools-0.11-rs
- libc-0.2-rs proc-macro2-1-rs
- proc-macro-error-1-rs proc-macro-error-attr-1-rs quote-1-rs
- syn-2-rs unicode-ident-1-rs"
+subprojects=(
+ anyhow-1-rs
+ arbitrary-int-1-rs
+ attrs-0.2-rs
+ berkeley-softfloat-3
+ berkeley-testfloat-3
+ bilge-0.2-rs
+ bilge-impl-0.2-rs
+ either-1-rs
+ foreign-0.3-rs
+ itertools-0.11-rs
+ keycodemapdb
+ libc-0.2-rs
+ libvfio-user
+ proc-macro-error-1-rs
+ proc-macro-error-attr-1-rs
+ proc-macro2-1-rs
+ quote-1-rs
+ syn-2-rs
+ unicode-ident-1-rs
+)
sub_deinit=""
function cleanup() {
@@ -77,9 +92,10 @@ function subproject_dir() {
git archive --format tar "$(tree_ish)" > "$tar_file"
test $? -ne 0 && error "failed to archive qemu"
-for sp in $subprojects; do
- meson subprojects download $sp
- test $? -ne 0 && error "failed to download subproject $sp"
+meson subprojects download ${subprojects[@]} >/dev/null
+test $? -ne 0 && error "failed to download subprojects $subprojects"
+
+for sp in "${subprojects[@]}"; do
tar --append --file "$tar_file" --exclude=.git subprojects/"$(subproject_dir $sp)"
test $? -ne 0 && error "failed to append subproject $sp to $tar_file"
done
diff --git a/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml b/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml
index f11e980..2ca4a53 100644
--- a/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml
+++ b/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml
@@ -36,6 +36,7 @@ packages:
- libcap-ng-dev
- libcapstone-dev
- libcbor-dev
+ - libclang-dev
- libcmocka-dev
- libcurl4-gnutls-dev
- libdaxctl-dev
@@ -80,6 +81,7 @@ packages:
- libspice-protocol-dev
- libspice-server-dev
- libssh-dev
+ - libstd-rust-dev
- libsystemd-dev
- libtasn1-6-dev
- libubsan1
@@ -95,7 +97,6 @@ packages:
- llvm
- locales
- make
- - meson
- mtools
- multipath-tools
- ncat
@@ -108,10 +109,12 @@ packages:
- python3-opencv
- python3-pillow
- python3-pip
+ - python3-setuptools
- python3-sphinx
- python3-sphinx-rtd-theme
- python3-tomli
- python3-venv
+ - python3-wheel
- python3-yaml
- rpm2cpio
- rustc-1.77
diff --git a/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml b/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml
index 6559cb2..7198fbb 100644
--- a/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml
+++ b/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml
@@ -36,6 +36,7 @@ packages:
- libcap-ng-dev
- libcapstone-dev
- libcbor-dev
+ - libclang-dev
- libcmocka-dev
- libcurl4-gnutls-dev
- libdaxctl-dev
@@ -79,6 +80,7 @@ packages:
- libsndio-dev
- libspice-protocol-dev
- libssh-dev
+ - libstd-rust-dev
- libsystemd-dev
- libtasn1-6-dev
- libubsan1
@@ -93,7 +95,6 @@ packages:
- llvm
- locales
- make
- - meson
- mtools
- multipath-tools
- ncat
@@ -106,10 +107,12 @@ packages:
- python3-opencv
- python3-pillow
- python3-pip
+ - python3-setuptools
- python3-sphinx
- python3-sphinx-rtd-theme
- python3-tomli
- python3-venv
+ - python3-wheel
- python3-yaml
- rpm2cpio
- rustc-1.77
diff --git a/scripts/rust-to-clang-target-test.sh b/scripts/rust-to-clang-target-test.sh
new file mode 100755
index 0000000..ff6f8fc
--- /dev/null
+++ b/scripts/rust-to-clang-target-test.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env sh
+#
+# Copyright (C) 2025 Red Hat, Inc.
+#
+# Based on rust_to_clang_target() tests from rust-bindgen.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+scripts_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+. "$scripts_dir/rust-to-clang-target.sh"
+
+test_case() {
+ input="$1"
+ expected="$2"
+ result=$(rust_to_clang_target "$input")
+
+ if [ "$result" = "$expected" ]; then
+ echo " OK: '$input' -> '$result'"
+ else
+ echo " FAILED: '$input'"
+ echo " Expected: '$expected'"
+ echo " Got: '$result'"
+ exit 1
+ fi
+}
+
+echo "Running tests..."
+
+test_case "aarch64-apple-ios" "arm64-apple-ios"
+test_case "riscv64gc-unknown-linux-gnu" "riscv64-unknown-linux-gnu"
+test_case "riscv64imac-unknown-none-elf" "riscv64-unknown-none-elf"
+test_case "riscv32imc-unknown-none-elf" "riscv32-unknown-none-elf"
+test_case "riscv32imac-unknown-none-elf" "riscv32-unknown-none-elf"
+test_case "riscv32imafc-unknown-none-elf" "riscv32-unknown-none-elf"
+test_case "riscv32i-unknown-none-elf" "riscv32-unknown-none-elf"
+test_case "riscv32imc-esp-espidf" "riscv32-esp-elf"
+test_case "xtensa-esp32-espidf" "xtensa-esp32-elf"
+test_case "aarch64-apple-ios-sim" "arm64-apple-ios-simulator"
+test_case "aarch64-apple-tvos-sim" "arm64-apple-tvos-simulator"
+test_case "aarch64-apple-watchos-sim" "arm64-apple-watchos-simulator"
+
+echo ""
+echo "All tests passed!"
diff --git a/scripts/rust-to-clang-target.sh b/scripts/rust-to-clang-target.sh
new file mode 100644
index 0000000..72db7e1
--- /dev/null
+++ b/scripts/rust-to-clang-target.sh
@@ -0,0 +1,60 @@
+# Copyright (C) 2025 Red Hat, Inc.
+#
+# Based on rust_to_clang_target() from rust-bindgen.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+rust_to_clang_target() {
+ rust_target="$1"
+
+ # Split the string by hyphens
+ triple_parts=""
+ old_IFS="$IFS"
+ IFS='-'
+ for part in $rust_target; do
+ triple_parts="$triple_parts $part"
+ done
+ IFS="$old_IFS"
+ set -- $triple_parts
+
+ # RISC-V
+ case "$1" in
+ riscv32*)
+ set -- "riscv32" "${2}" "${3}" "${4}"
+ ;;
+ riscv64*)
+ set -- "riscv64" "${2}" "${3}" "${4}"
+ ;;
+ esac
+
+ # Apple
+ if [ "$2" = "apple" ]; then
+ if [ "$1" = "aarch64" ]; then
+ set -- "arm64" "${2}" "${3}" "${4}"
+ fi
+ if [ "$4" = "sim" ]; then
+ set -- "${1}" "${2}" "${3}" "simulator"
+ fi
+ fi
+
+ # ESP-IDF
+ if [ "$3" = "espidf" ]; then
+ set -- "${1}" "${2}" "elf" "${4}"
+ fi
+
+ # Reassemble the string
+ new_triple=""
+ first=1
+ for part in "$@"; do
+ if [ -n "$part" ]; then
+ if [ "$first" -eq 1 ]; then
+ new_triple="$part"
+ first=0
+ else
+ new_triple="$new_triple-$part"
+ fi
+ fi
+ done
+
+ echo "$new_triple"
+}
diff --git a/tests/docker/common.rc b/tests/docker/common.rc
index a611e6a..752f4f3 100755
--- a/tests/docker/common.rc
+++ b/tests/docker/common.rc
@@ -21,6 +21,14 @@ else
DEF_TARGET_LIST=${DEF_TARGET_LIST:-"x86_64-softmmu,aarch64-softmmu"}
fi
+enable_rust=""
+if [ "$ENABLE_RUST" = "1" ]; then
+ enable_rust="--enable-rust"
+ if [ -n "$RUST_TARGET" ]; then
+ enable_rust="$enable_rust --rust-target-triple=$RUST_TARGET"
+ fi
+fi
+
requires_binary()
{
found=0
@@ -46,11 +54,12 @@ configure_qemu()
${TARGET_LIST:+--target-list=${TARGET_LIST}} \
--prefix=$INSTALL_DIR \
$QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS \
+ $enable_rust \
$@"
echo "Configure options:"
echo $config_opts
$QEMU_SRC/configure $config_opts || \
- { cat config.log && test_fail "Failed to run 'configure'"; }
+ { cat config.log >&2 ; cat meson-logs/meson-log.txt >&2 ; test_fail "Failed to run 'configure'"; }
}
build_qemu()
@@ -73,7 +82,7 @@ check_qemu()
test_fail()
{
- echo "$@"
+ echo "$@" >&2
exit 1
}
diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker
index bf3bd5a..52adf9c 100644
--- a/tests/docker/dockerfiles/alpine.docker
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -78,7 +78,7 @@ RUN apk update && \
nmap-ncat \
numactl-dev \
openssh-client \
- pcre-dev \
+ pcre2-dev \
pipewire-dev \
pixman-dev \
pkgconf \
@@ -131,8 +131,12 @@ ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
ENV NINJA "/usr/bin/ninja"
ENV PYTHON "/usr/bin/python3"
+# https://gitlab.alpinelinux.org/alpine/aports/-/issues/17463
+RUN apk add clang19-libclang
# As a final step configure the user (if env is defined)
ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/centos9.docker b/tests/docker/dockerfiles/centos9.docker
index a942835..0674d77 100644
--- a/tests/docker/dockerfiles/centos9.docker
+++ b/tests/docker/dockerfiles/centos9.docker
@@ -25,6 +25,7 @@ RUN dnf distro-sync -y && \
capstone-devel \
ccache \
clang \
+ compiler-rt \
ctags \
cyrus-sasl-devel \
daxctl-devel \
@@ -104,6 +105,7 @@ RUN dnf distro-sync -y && \
python3-tomli \
rdma-core-devel \
rust \
+ rust-std-static \
sed \
snappy-devel \
socat \
@@ -140,3 +142,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker b/tests/docker/dockerfiles/debian-amd64-cross.docker
index 081f3e0..7f46744 100644
--- a/tests/docker/dockerfiles/debian-amd64-cross.docker
+++ b/tests/docker/dockerfiles/debian-amd64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch x86_64 debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch x86_64 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-x86-64-linux-gnu \
libaio-dev:amd64 \
- libasan6:amd64 \
+ libasan8:amd64 \
libasound2-dev:amd64 \
libattr1-dev:amd64 \
libbpf-dev:amd64 \
@@ -137,6 +142,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:amd64 \
libspice-server-dev:amd64 \
libssh-dev:amd64 \
+ libstd-rust-dev:amd64 \
libsystemd-dev:amd64 \
libtasn1-6-dev:amd64 \
libubsan1:amd64 \
@@ -182,3 +188,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-arm64-cross.docker b/tests/docker/dockerfiles/debian-arm64-cross.docker
index 91c555a..c7cd54e 100644
--- a/tests/docker/dockerfiles/debian-arm64-cross.docker
+++ b/tests/docker/dockerfiles/debian-arm64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch aarch64 debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch aarch64 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-aarch64-linux-gnu \
libaio-dev:arm64 \
- libasan6:arm64 \
+ libasan8:arm64 \
libasound2-dev:arm64 \
libattr1-dev:arm64 \
libbpf-dev:arm64 \
@@ -136,6 +141,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:arm64 \
libspice-server-dev:arm64 \
libssh-dev:arm64 \
+ libstd-rust-dev:arm64 \
libsystemd-dev:arm64 \
libtasn1-6-dev:arm64 \
libubsan1:arm64 \
@@ -181,3 +187,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-armhf-cross.docker b/tests/docker/dockerfiles/debian-armhf-cross.docker
index f0e2efc..627d41c 100644
--- a/tests/docker/dockerfiles/debian-armhf-cross.docker
+++ b/tests/docker/dockerfiles/debian-armhf-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch armv7l debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch armv7l debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-arm-linux-gnueabihf \
libaio-dev:armhf \
- libasan6:armhf \
+ libasan8:armhf \
libasound2-dev:armhf \
libattr1-dev:armhf \
libbpf-dev:armhf \
@@ -103,7 +108,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libgbm-dev:armhf \
libgcrypt20-dev:armhf \
libglib2.0-dev:armhf \
- libglusterfs-dev:armhf \
libgnutls28-dev:armhf \
libgtk-3-dev:armhf \
libgtk-vnc-2.0-dev:armhf \
@@ -123,7 +127,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libpixman-1-dev:armhf \
libpng-dev:armhf \
libpulse-dev:armhf \
- librbd-dev:armhf \
librdmacm-dev:armhf \
libsasl2-dev:armhf \
libsdl2-dev:armhf \
@@ -136,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:armhf \
libspice-server-dev:armhf \
libssh-dev:armhf \
+ libstd-rust-dev:armhf \
libsystemd-dev:armhf \
libtasn1-6-dev:armhf \
libubsan1:armhf \
@@ -147,7 +151,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libvirglrenderer-dev:armhf \
libvte-2.91-dev:armhf \
libxdp-dev:armhf \
- libxen-dev:armhf \
libzstd-dev:armhf \
nettle-dev:armhf \
systemtap-sdt-dev:armhf \
@@ -181,3 +184,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-i686-cross.docker b/tests/docker/dockerfiles/debian-i686-cross.docker
index 025beb1..4e8b3a8 100644
--- a/tests/docker/dockerfiles/debian-i686-cross.docker
+++ b/tests/docker/dockerfiles/debian-i686-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch i686 debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch i686 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-i686-linux-gnu \
libaio-dev:i386 \
- libasan6:i386 \
+ libasan8:i386 \
libasound2-dev:i386 \
libattr1-dev:i386 \
libbpf-dev:i386 \
@@ -103,7 +108,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libgbm-dev:i386 \
libgcrypt20-dev:i386 \
libglib2.0-dev:i386 \
- libglusterfs-dev:i386 \
libgnutls28-dev:i386 \
libgtk-3-dev:i386 \
libgtk-vnc-2.0-dev:i386 \
@@ -123,7 +127,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libpixman-1-dev:i386 \
libpng-dev:i386 \
libpulse-dev:i386 \
- librbd-dev:i386 \
librdmacm-dev:i386 \
libsasl2-dev:i386 \
libsdl2-dev:i386 \
@@ -136,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:i386 \
libspice-server-dev:i386 \
libssh-dev:i386 \
+ libstd-rust-dev:i386 \
libsystemd-dev:i386 \
libtasn1-6-dev:i386 \
libubsan1:i386 \
@@ -180,3 +184,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-mips64el-cross.docker b/tests/docker/dockerfiles/debian-mips64el-cross.docker
index 4a941dd..6e88777 100644
--- a/tests/docker/dockerfiles/debian-mips64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-mips64el-cross.docker
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,9 +45,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
rustc-web \
@@ -67,6 +69,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -135,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:mips64el \
libspice-server-dev:mips64el \
libssh-dev:mips64el \
+ libstd-rust-dev:mips64el \
libsystemd-dev:mips64el \
libtasn1-6-dev:mips64el \
libudev-dev:mips64el \
@@ -178,3 +183,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-mipsel-cross.docker b/tests/docker/dockerfiles/debian-mipsel-cross.docker
index 4d3e5d7..5f4e3fa 100644
--- a/tests/docker/dockerfiles/debian-mipsel-cross.docker
+++ b/tests/docker/dockerfiles/debian-mipsel-cross.docker
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,9 +45,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
rustc-web \
@@ -67,6 +69,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -135,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:mipsel \
libspice-server-dev:mipsel \
libssh-dev:mipsel \
+ libstd-rust-dev:mipsel \
libsystemd-dev:mipsel \
libtasn1-6-dev:mipsel \
libudev-dev:mipsel \
@@ -178,3 +183,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-ppc64el-cross.docker b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
index 22b4457..dfa6906 100644
--- a/tests/docker/dockerfiles/debian-ppc64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch ppc64le debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch ppc64le debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-powerpc64le-linux-gnu \
libaio-dev:ppc64el \
- libasan6:ppc64el \
+ libasan8:ppc64el \
libasound2-dev:ppc64el \
libattr1-dev:ppc64el \
libbpf-dev:ppc64el \
@@ -136,6 +141,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:ppc64el \
libspice-server-dev:ppc64el \
libssh-dev:ppc64el \
+ libstd-rust-dev:ppc64el \
libsystemd-dev:ppc64el \
libtasn1-6-dev:ppc64el \
libubsan1:ppc64el \
@@ -180,3 +186,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-riscv64-cross.docker b/tests/docker/dockerfiles/debian-riscv64-cross.docker
index b0386cd..09b2953 100644
--- a/tests/docker/dockerfiles/debian-riscv64-cross.docker
+++ b/tests/docker/dockerfiles/debian-riscv64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch riscv64 debian-13 qemu-minimal
+# $ lcitool dockerfile --layers all --cross-arch riscv64 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:trixie-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -13,29 +13,65 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
+ bsdextrautils \
+ bzip2 \
ca-certificates \
ccache \
+ dbus \
+ debianutils \
+ diffutils \
+ exuberant-ctags \
findutils \
flex \
gcc \
+ gcovr \
+ gettext \
git \
+ hostname \
+ libclang-rt-dev \
libglib2.0-dev \
+ llvm \
locales \
make \
- meson \
+ mtools \
+ ncat \
ninja-build \
+ openssh-client \
pkgconf \
python3 \
+ python3-numpy \
+ python3-opencv \
+ python3-pillow \
+ python3-pip \
+ python3-setuptools \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
+ python3-yaml \
+ rpm2cpio \
+ rustc \
sed \
- tar && \
+ socat \
+ sparse \
+ swtpm \
+ tar \
+ tesseract-ocr \
+ tesseract-ocr-eng \
+ vulkan-tools \
+ xorriso \
+ zstd && \
eatmydata apt-get autoremove -y && \
eatmydata apt-get autoclean -y && \
sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -52,11 +88,78 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
eatmydata apt-get install --no-install-recommends -y \
gcc-riscv64-linux-gnu \
+ libaio-dev:riscv64 \
+ libasan8:riscv64 \
+ libasound2-dev:riscv64 \
+ libattr1-dev:riscv64 \
+ libbpf-dev:riscv64 \
+ libbrlapi-dev:riscv64 \
+ libbz2-dev:riscv64 \
libc6-dev:riscv64 \
+ libcacard-dev:riscv64 \
+ libcap-ng-dev:riscv64 \
+ libcapstone-dev:riscv64 \
+ libcbor-dev:riscv64 \
+ libcmocka-dev:riscv64 \
+ libcurl4-gnutls-dev:riscv64 \
+ libdaxctl-dev:riscv64 \
+ libdrm-dev:riscv64 \
+ libepoxy-dev:riscv64 \
libfdt-dev:riscv64 \
libffi-dev:riscv64 \
+ libfuse3-dev:riscv64 \
+ libgbm-dev:riscv64 \
+ libgcrypt20-dev:riscv64 \
libglib2.0-dev:riscv64 \
- libpixman-1-dev:riscv64 && \
+ libglusterfs-dev:riscv64 \
+ libgnutls28-dev:riscv64 \
+ libgtk-3-dev:riscv64 \
+ libgtk-vnc-2.0-dev:riscv64 \
+ libibverbs-dev:riscv64 \
+ libiscsi-dev:riscv64 \
+ libjemalloc-dev:riscv64 \
+ libjpeg62-turbo-dev:riscv64 \
+ libjson-c-dev:riscv64 \
+ liblttng-ust-dev:riscv64 \
+ liblzo2-dev:riscv64 \
+ libncursesw5-dev:riscv64 \
+ libnfs-dev:riscv64 \
+ libnuma-dev:riscv64 \
+ libpam0g-dev:riscv64 \
+ libpcre2-dev:riscv64 \
+ libpipewire-0.3-dev:riscv64 \
+ libpixman-1-dev:riscv64 \
+ libpng-dev:riscv64 \
+ libpulse-dev:riscv64 \
+ librbd-dev:riscv64 \
+ librdmacm-dev:riscv64 \
+ libsasl2-dev:riscv64 \
+ libsdl2-dev:riscv64 \
+ libsdl2-image-dev:riscv64 \
+ libseccomp-dev:riscv64 \
+ libselinux1-dev:riscv64 \
+ libslirp-dev:riscv64 \
+ libsnappy-dev:riscv64 \
+ libsndio-dev:riscv64 \
+ libspice-protocol-dev:riscv64 \
+ libspice-server-dev:riscv64 \
+ libssh-dev:riscv64 \
+ libstd-rust-dev:riscv64 \
+ libsystemd-dev:riscv64 \
+ libtasn1-6-dev:riscv64 \
+ libubsan1:riscv64 \
+ libudev-dev:riscv64 \
+ liburing-dev:riscv64 \
+ libusb-1.0-0-dev:riscv64 \
+ libusbredirhost-dev:riscv64 \
+ libvdeplug-dev:riscv64 \
+ libvirglrenderer-dev:riscv64 \
+ libvte-2.91-dev:riscv64 \
+ libxdp-dev:riscv64 \
+ libzstd-dev:riscv64 \
+ nettle-dev:riscv64 \
+ systemtap-sdt-dev:riscv64 \
+ zlib1g-dev:riscv64 && \
eatmydata apt-get autoremove -y && \
eatmydata apt-get autoclean -y && \
mkdir -p /usr/local/share/meson/cross && \
@@ -78,6 +181,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/riscv64-linux-gnu && \
ENV ABI "riscv64-linux-gnu"
ENV MESON_OPTS "--cross-file=riscv64-linux-gnu"
+ENV RUST_TARGET "riscv64gc-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=riscv64-linux-gnu-
ENV DEF_TARGET_LIST riscv64-softmmu,riscv64-linux-user
# As a final step configure the user (if env is defined)
@@ -85,3 +189,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-s390x-cross.docker b/tests/docker/dockerfiles/debian-s390x-cross.docker
index 13ec52c..09a78c1 100644
--- a/tests/docker/dockerfiles/debian-s390x-cross.docker
+++ b/tests/docker/dockerfiles/debian-s390x-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch s390x debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch s390x debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-s390x-linux-gnu \
libaio-dev:s390x \
- libasan6:s390x \
+ libasan8:s390x \
libasound2-dev:s390x \
libattr1-dev:s390x \
libbpf-dev:s390x \
@@ -135,6 +140,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libsndio-dev:s390x \
libspice-protocol-dev:s390x \
libssh-dev:s390x \
+ libstd-rust-dev:s390x \
libsystemd-dev:s390x \
libtasn1-6-dev:s390x \
libubsan1:s390x \
@@ -179,3 +185,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian.docker b/tests/docker/dockerfiles/debian.docker
index 0a57c1a..8dd893b 100644
--- a/tests/docker/dockerfiles/debian.docker
+++ b/tests/docker/dockerfiles/debian.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all debian-12 qemu
+# $ lcitool dockerfile --layers all debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -32,7 +32,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
git \
hostname \
libaio-dev \
- libasan6 \
+ libasan8 \
libasound2-dev \
libattr1-dev \
libbpf-dev \
@@ -43,6 +43,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libcap-ng-dev \
libcapstone-dev \
libcbor-dev \
+ libclang-rt-dev \
libcmocka-dev \
libcurl4-gnutls-dev \
libdaxctl-dev \
@@ -88,6 +89,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev \
libspice-server-dev \
libssh-dev \
+ libstd-rust-dev \
libsystemd-dev \
libtasn1-6-dev \
libubsan1 \
@@ -104,7 +106,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
llvm \
locales \
make \
- meson \
mtools \
multipath-tools \
ncat \
@@ -117,12 +118,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -146,6 +150,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -169,3 +175,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/emsdk-wasm32-cross.docker b/tests/docker/dockerfiles/emsdk-wasm32-cross.docker
index 60a7d02..6b1642a 100644
--- a/tests/docker/dockerfiles/emsdk-wasm32-cross.docker
+++ b/tests/docker/dockerfiles/emsdk-wasm32-cross.docker
@@ -8,7 +8,7 @@ ARG PIXMAN_VERSION=0.44.2
ARG FFI_VERSION=v3.4.7
ARG MESON_VERSION=1.5.0
-FROM emscripten/emsdk:$EMSDK_VERSION_QEMU AS build-base
+FROM docker.io/emscripten/emsdk:$EMSDK_VERSION_QEMU AS build-base
ARG MESON_VERSION
ENV TARGET=/builddeps/target
ENV CPATH="$TARGET/include"
diff --git a/tests/docker/dockerfiles/fedora-rust-nightly.docker b/tests/docker/dockerfiles/fedora-rust-nightly.docker
index 4a03330..7d31c9f 100644
--- a/tests/docker/dockerfiles/fedora-rust-nightly.docker
+++ b/tests/docker/dockerfiles/fedora-rust-nightly.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all fedora-40 qemu
+# $ lcitool dockerfile --layers all fedora-41 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM registry.fedoraproject.org/fedora:40
+FROM registry.fedoraproject.org/fedora:41
RUN dnf install -y nosync && \
printf '#!/bin/sh\n\
@@ -32,6 +32,7 @@ exec "$@"\n' > /usr/bin/nosync && \
capstone-devel \
ccache \
clang \
+ compiler-rt \
ctags \
cyrus-sasl-devel \
daxctl-devel \
@@ -91,7 +92,6 @@ exec "$@"\n' > /usr/bin/nosync && \
lzo-devel \
make \
mesa-libgbm-devel \
- meson \
mtools \
ncurses-devel \
nettle-devel \
@@ -100,7 +100,7 @@ exec "$@"\n' > /usr/bin/nosync && \
numactl-devel \
openssh-clients \
pam-devel \
- pcre-static \
+ pcre2-static \
pipewire-devel \
pixman-devel \
pkgconfig \
@@ -111,11 +111,13 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx_rtd_theme \
- python3-zombie-imp \
+ python3-wheel \
rdma-core-devel \
rust \
+ rust-std-static \
sed \
snappy-devel \
socat \
@@ -124,7 +126,7 @@ exec "$@"\n' > /usr/bin/nosync && \
spice-server-devel \
swtpm \
systemd-devel \
- systemtap-sdt-devel \
+ systemtap-sdt-dtrace \
tar \
tesseract \
tesseract-langpack-eng \
@@ -148,6 +150,8 @@ exec "$@"\n' > /usr/bin/nosync && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -181,3 +185,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker
index a950344..c76a70c 100644
--- a/tests/docker/dockerfiles/fedora-win64-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch mingw64 fedora-40 qemu,qemu-win-installer
+# $ lcitool dockerfile --layers all --cross-arch mingw64 fedora-41 qemu,qemu-win-installer
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM registry.fedoraproject.org/fedora:40
+FROM registry.fedoraproject.org/fedora:41
RUN dnf install -y nosync && \
printf '#!/bin/sh\n\
@@ -25,6 +25,7 @@ exec "$@"\n' > /usr/bin/nosync && \
bzip2 \
ca-certificates \
ccache \
+ compiler-rt \
ctags \
dbus-daemon \
diffutils \
@@ -38,7 +39,6 @@ exec "$@"\n' > /usr/bin/nosync && \
hostname \
llvm \
make \
- meson \
mtools \
ninja-build \
nmap-ncat \
@@ -49,9 +49,10 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx_rtd_theme \
- python3-zombie-imp \
+ python3-wheel \
rust \
sed \
socat \
@@ -69,6 +70,8 @@ exec "$@"\n' > /usr/bin/nosync && \
nosync dnf clean all -y && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -90,13 +93,15 @@ RUN nosync dnf install -y \
mingw64-gtk-vnc2 \
mingw64-gtk3 \
mingw64-libepoxy \
+ mingw64-libfdt \
mingw64-libgcrypt \
mingw64-libjpeg-turbo \
mingw64-libpng \
mingw64-libtasn1 \
mingw64-nettle \
mingw64-pixman \
- mingw64-pkg-config && \
+ mingw64-pkg-config \
+ rust-std-static-x86_64-pc-windows-gnu && \
nosync dnf clean all -y && \
rpm -qa | sort > /packages.txt && \
mkdir -p /usr/libexec/ccache-wrappers && \
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index 014e3cc..891a740 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all fedora-40 qemu
+# $ lcitool dockerfile --layers all fedora-41 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM registry.fedoraproject.org/fedora:40
+FROM registry.fedoraproject.org/fedora:41
RUN dnf install -y nosync && \
printf '#!/bin/sh\n\
@@ -32,6 +32,7 @@ exec "$@"\n' > /usr/bin/nosync && \
capstone-devel \
ccache \
clang \
+ compiler-rt \
ctags \
cyrus-sasl-devel \
daxctl-devel \
@@ -91,7 +92,6 @@ exec "$@"\n' > /usr/bin/nosync && \
lzo-devel \
make \
mesa-libgbm-devel \
- meson \
mtools \
ncurses-devel \
nettle-devel \
@@ -100,7 +100,7 @@ exec "$@"\n' > /usr/bin/nosync && \
numactl-devel \
openssh-clients \
pam-devel \
- pcre-static \
+ pcre2-static \
pipewire-devel \
pixman-devel \
pkgconfig \
@@ -111,11 +111,13 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx_rtd_theme \
- python3-zombie-imp \
+ python3-wheel \
rdma-core-devel \
rust \
+ rust-std-static \
sed \
snappy-devel \
socat \
@@ -124,7 +126,7 @@ exec "$@"\n' > /usr/bin/nosync && \
spice-server-devel \
swtpm \
systemd-devel \
- systemtap-sdt-devel \
+ systemtap-sdt-dtrace \
tar \
tesseract \
tesseract-langpack-eng \
@@ -148,6 +150,8 @@ exec "$@"\n' > /usr/bin/nosync && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -158,3 +162,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker
index e90225d..75e1747 100644
--- a/tests/docker/dockerfiles/opensuse-leap.docker
+++ b/tests/docker/dockerfiles/opensuse-leap.docker
@@ -19,6 +19,7 @@ RUN zypper update -y && \
ca-certificates \
ccache \
clang \
+ clang-devel \
ctags \
cyrus-sasl-devel \
dbus-1 \
@@ -89,7 +90,7 @@ RUN zypper update -y && \
ninja \
openssh \
pam-devel \
- pcre-devel-static \
+ pcre2-devel-static \
pipewire-devel \
pkgconfig \
python311 \
@@ -132,7 +133,7 @@ RUN zypper update -y && \
RUN /usr/bin/pip3.11 install \
PyYAML \
- meson==1.5.0 \
+ meson==1.8.1 \
pillow \
sphinx \
sphinx-rtd-theme
@@ -147,3 +148,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/ubuntu2204.docker b/tests/docker/dockerfiles/ubuntu2204.docker
index 28a6f93..b393db5 100644
--- a/tests/docker/dockerfiles/ubuntu2204.docker
+++ b/tests/docker/dockerfiles/ubuntu2204.docker
@@ -42,6 +42,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libcap-ng-dev \
libcapstone-dev \
libcbor-dev \
+ libclang-dev \
libcmocka-dev \
libcurl4-gnutls-dev \
libdaxctl-dev \
@@ -87,6 +88,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev \
libspice-server-dev \
libssh-dev \
+ libstd-rust-dev \
libsystemd-dev \
libtasn1-6-dev \
libubsan1 \
@@ -102,7 +104,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
llvm \
locales \
make \
- meson \
mtools \
multipath-tools \
ncat \
@@ -115,10 +116,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
rustc-1.77 \
@@ -145,6 +148,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
diff --git a/tests/functional/aarch64/test_aspeed_ast2700.py b/tests/functional/aarch64/test_aspeed_ast2700.py
index 8a08bc4..a3db267 100755
--- a/tests/functional/aarch64/test_aspeed_ast2700.py
+++ b/tests/functional/aarch64/test_aspeed_ast2700.py
@@ -115,8 +115,8 @@ class AST2x00MachineSDK(QemuSystemTest):
self.do_test_aarch64_aspeed_sdk_start(
self.scratch_file(name, 'image-bmc'))
- def test_aarch64_ast2700_evb_sdk_v09_06(self):
- self.set_machine('ast2700-evb')
+ def test_aarch64_ast2700a0_evb_sdk_v09_06(self):
+ self.set_machine('ast2700a0-evb')
self.archive_extract(self.ASSET_SDK_V906_AST2700)
self.start_ast2700_test('ast2700-a0-default')
diff --git a/tests/functional/arm/test_aspeed_ast1030.py b/tests/functional/arm/test_aspeed_ast1030.py
index 42126b5..e47b597 100755
--- a/tests/functional/arm/test_aspeed_ast1030.py
+++ b/tests/functional/arm/test_aspeed_ast1030.py
@@ -7,17 +7,18 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import LinuxKernelTest, Asset
+from aspeed import AspeedTest
from qemu_test import exec_command_and_wait_for_pattern
-class AST1030Machine(LinuxKernelTest):
+class AST1030Machine(AspeedTest):
ASSET_ZEPHYR_3_02 = Asset(
('https://github.com/AspeedTech-BMC'
'/zephyr/releases/download/v00.03.02/ast1030-evb-demo.zip'),
'1ec83caab3ddd5d09481772801be7210e222cb015ce22ec6fffb8a76956dcd4f')
- def test_ast1030_zephyros_3_02(self):
+ def test_arm_ast1030_zephyros_3_02(self):
self.set_machine('ast1030-evb')
kernel_name = "ast1030-evb-demo-3/zephyr.elf"
@@ -36,7 +37,7 @@ class AST1030Machine(LinuxKernelTest):
'/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip'),
'ad52e27959746988afaed8429bf4e12ab988c05c4d07c9d90e13ec6f7be4574c')
- def test_ast1030_zephyros_1_07(self):
+ def test_arm_ast1030_zephyros_1_07(self):
self.set_machine('ast1030-evb')
kernel_name = "ast1030-evb-demo/zephyr.bin"
@@ -68,6 +69,21 @@ class AST1030Machine(LinuxKernelTest):
'kernel uptime',
]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$")
+ def test_arm_ast1030_otp_blockdev_device(self):
+ self.vm.set_machine("ast1030-evb")
+
+ kernel_name = "ast1030-evb-demo-3/zephyr.elf"
+ kernel_file = self.archive_extract(self.ASSET_ZEPHYR_3_02, member=kernel_name)
+ otp_img = self.generate_otpmem_image()
+
+ self.vm.set_console()
+ self.vm.add_args(
+ "-kernel", kernel_file,
+ "-blockdev", f"driver=file,filename={otp_img},node-name=otp",
+ "-global", "aspeed-otp.drive=otp",
+ )
+ self.vm.launch()
+ self.wait_for_console_pattern("Booting Zephyr OS")
if __name__ == '__main__':
- LinuxKernelTest.main()
+ AspeedTest.main()
diff --git a/tests/functional/arm/test_aspeed_ast2600.py b/tests/functional/arm/test_aspeed_ast2600.py
index 129695c..f655c0b 100755
--- a/tests/functional/arm/test_aspeed_ast2600.py
+++ b/tests/functional/arm/test_aspeed_ast2600.py
@@ -101,8 +101,26 @@ class AST2600Machine(AspeedTest):
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.07/ast2600-default-obmc.tar.gz',
'cb6c08595bcbba1672ce716b068ba4e48eda1ed9abe78a07b30392ba2278feba')
+ def do_ast2600_pcie_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 80:00.0',
+ '80:00.0 Host bridge: '
+ 'ASPEED Technology, Inc. Device 2600')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 80:08.0',
+ '80:08.0 PCI bridge: '
+ 'ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 81:00.0',
+ '81:00.0 Ethernet controller: '
+ 'Intel Corporation 82574L Gigabit Network Connection')
+ exec_command_and_wait_for_pattern(self,
+ 'ip addr show dev eth4',
+ 'inet 10.0.2.15/24')
+
def test_arm_ast2600_evb_sdk(self):
self.set_machine('ast2600-evb')
+ self.require_netdev('user')
self.archive_extract(self.ASSET_SDK_V907_AST2600)
@@ -110,6 +128,8 @@ class AST2600Machine(AspeedTest):
'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
'ds1338,bus=aspeed.i2c.bus.5,address=0x32')
+ self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.0')
+ self.vm.add_args('-netdev', 'user,id=net1')
self.do_test_arm_aspeed_sdk_start(
self.scratch_file("ast2600-default", "image-bmc"))
@@ -135,6 +155,22 @@ class AST2600Machine(AspeedTest):
year = time.strftime("%Y")
exec_command_and_wait_for_pattern(self,
'/sbin/hwclock -f /dev/rtc1', year)
+ self.do_ast2600_pcie_test()
+
+ def test_arm_ast2600_otp_blockdev_device(self):
+ self.vm.set_machine("ast2600-evb")
+
+ image_path = self.archive_extract(self.ASSET_SDK_V907_AST2600)
+ otp_img = self.generate_otpmem_image()
+
+ self.vm.set_console()
+ self.vm.add_args(
+ "-blockdev", f"driver=file,filename={otp_img},node-name=otp",
+ "-global", "aspeed-otp.drive=otp",
+ )
+ self.do_test_arm_aspeed_sdk_start(
+ self.scratch_file("ast2600-default", "image-bmc"))
+ self.wait_for_console_pattern("ast2600-default login:")
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py
index b131703..47e84e0 100644
--- a/tests/functional/aspeed.py
+++ b/tests/functional/aspeed.py
@@ -61,3 +61,11 @@ class AspeedTest(LinuxKernelTest):
self.wait_for_console_pattern('U-Boot 2019.04')
self.wait_for_console_pattern('## Loading kernel from FIT Image')
self.wait_for_console_pattern('Starting kernel ...')
+
+ def generate_otpmem_image(self):
+ path = self.scratch_file("otpmem.img")
+ pattern = b'\x00\x00\x00\x00\xff\xff\xff\xff' * (16 * 1024 // 8)
+ with open(path, "wb") as f:
+ f.write(pattern)
+ return path
+
diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci
-Subproject 18c4bfe02c467e5639bf9a687139735ccd7a3ff
+Subproject 9da20ff7c3bc9067804a7561c2ff87583b43485
diff --git a/tests/lcitool/projects/qemu.yml b/tests/lcitool/projects/qemu.yml
index c07242f..82812e7 100644
--- a/tests/lcitool/projects/qemu.yml
+++ b/tests/lcitool/projects/qemu.yml
@@ -44,6 +44,7 @@ packages:
- libcacard
- libcap-ng
- libcbor
+ - libclang-rt
- libcurl
- libdrm
- libepoxy
@@ -91,7 +92,6 @@ packages:
- pkg-config
- pulseaudio
- python3
- - python3-imp
- python3-numpy
- python3-opencv
- python3-pillow
@@ -104,6 +104,7 @@ packages:
- python3-venv
- rpm2cpio
- rust
+ - rust-std
- sdl2
- sdl2-image
- sed
diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh
index d3488b2..6459593 100755
--- a/tests/lcitool/refresh
+++ b/tests/lcitool/refresh
@@ -63,7 +63,8 @@ add_user_mapping = [
" id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi\n"
]
-def generate_dockerfile(host, target, project="qemu", cross=None, trailer=None):
+def generate_dockerfile(host, target, project="qemu", cross=None, trailer=None,
+ enable_rust=True):
filename = Path(src_dir, "tests", "docker", "dockerfiles", host + ".docker")
cmd = lcitool_cmd + ["dockerfile"]
if cross is not None:
@@ -75,6 +76,8 @@ def generate_dockerfile(host, target, project="qemu", cross=None, trailer=None):
else:
trailer = "\n".join(add_user_mapping)
+ if enable_rust:
+ trailer += "\nENV ENABLE_RUST 1\n"
generate(filename, cmd, trailer)
@@ -97,10 +100,15 @@ def generate_yaml(os, target, arch, trailer=None):
generate(filename, cmd, trailer)
+alpine_extras = [
+ "# https://gitlab.alpinelinux.org/alpine/aports/-/issues/17463\n",
+ "RUN apk add clang19-libclang\n",
+]
+
# Netmap still needs to be manually built as it is yet to be packaged
# into a distro. We also add cscope and gtags which are used in the CI
# test
-debian12_extras = [
+debian13_extras = [
"# netmap/cscope/global\n",
"RUN DEBIAN_FRONTEND=noninteractive eatmydata \\\n",
" apt install -y --no-install-recommends \\\n",
@@ -167,48 +175,53 @@ try:
#
# Standard native builds
#
- generate_dockerfile("alpine", "alpine-321")
+ generate_dockerfile("alpine", "alpine-321",
+ trailer="".join(alpine_extras))
generate_dockerfile("centos9", "centos-stream-9")
- generate_dockerfile("debian", "debian-12",
- trailer="".join(debian12_extras))
- generate_dockerfile("fedora", "fedora-40")
+ generate_dockerfile("debian", "debian-13",
+ trailer="".join(debian13_extras))
+ generate_dockerfile("fedora", "fedora-41")
generate_dockerfile("opensuse-leap", "opensuse-leap-15")
generate_dockerfile("ubuntu2204", "ubuntu-2204",
- trailer="".join(ubuntu2204_rust_extras))
+ trailer="".join(ubuntu2204_rust_extras),
+ # https://bugs.launchpad.net/ubuntu/+source/rustc-1.83/+bug/2120318
+ enable_rust=False)
#
# Non-fatal Rust-enabled build
#
- generate_dockerfile("fedora-rust-nightly", "fedora-40",
+ generate_dockerfile("fedora-rust-nightly", "fedora-41",
trailer="".join(fedora_rustup_nightly_extras))
#
# Cross compiling builds
#
- generate_dockerfile("debian-amd64-cross", "debian-12",
+ generate_dockerfile("debian-amd64-cross", "debian-13",
cross="x86_64",
trailer=cross_build("x86_64-linux-gnu-",
"x86_64-softmmu,"
"x86_64-linux-user,"
"i386-softmmu,i386-linux-user"))
- generate_dockerfile("debian-arm64-cross", "debian-12",
+ generate_dockerfile("debian-arm64-cross", "debian-13",
cross="aarch64",
trailer=cross_build("aarch64-linux-gnu-",
"aarch64-softmmu,aarch64-linux-user"))
- generate_dockerfile("debian-armhf-cross", "debian-12",
+ generate_dockerfile("debian-armhf-cross", "debian-13",
cross="armv7l",
trailer=cross_build("arm-linux-gnueabihf-",
"arm-softmmu,arm-linux-user"))
- generate_dockerfile("debian-i686-cross", "debian-12",
+ generate_dockerfile("debian-i686-cross", "debian-13",
cross="i686",
trailer=cross_build("i686-linux-gnu-",
"x86_64-softmmu,"
"x86_64-linux-user,"
"i386-softmmu,i386-linux-user"))
+ # mips no longer supported in debian-13
+ # https://www.debian.org/releases/trixie/release-notes/issues.html#mips-architectures-removed
generate_dockerfile("debian-mips64el-cross", "debian-12",
cross="mips64el",
trailer=cross_build("mips64el-linux-gnuabi64-",
@@ -219,7 +232,7 @@ try:
trailer=cross_build("mipsel-linux-gnu-",
"mipsel-softmmu,mipsel-linux-user"))
- generate_dockerfile("debian-ppc64el-cross", "debian-12",
+ generate_dockerfile("debian-ppc64el-cross", "debian-13",
cross="ppc64le",
trailer=cross_build("powerpc64le-linux-gnu-",
"ppc64-softmmu,ppc64-linux-user"))
@@ -227,21 +240,23 @@ try:
# while not yet a release architecture the packages are still
# build while part of testing
generate_dockerfile("debian-riscv64-cross", "debian-13",
- project="qemu-minimal",
cross="riscv64",
trailer=cross_build("riscv64-linux-gnu-",
"riscv64-softmmu,riscv64-linux-user"))
- generate_dockerfile("debian-s390x-cross", "debian-12",
+ generate_dockerfile("debian-s390x-cross", "debian-13",
cross="s390x",
trailer=cross_build("s390x-linux-gnu-",
"s390x-softmmu,s390x-linux-user"))
- generate_dockerfile("fedora-win64-cross", "fedora-40",
+ generate_dockerfile("fedora-win64-cross", "fedora-41",
project='qemu,qemu-win-installer',
cross="mingw64",
trailer=cross_build("x86_64-w64-mingw32-",
- "x86_64-softmmu"))
+ "x86_64-softmmu"),
+ # linking with rust is buggy:
+ # https://github.com/mesonbuild/meson/pull/14991
+ enable_rust=False)
#
# Cirrus packages lists for GitLab
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index 2e96c9e..ea09b21 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -40,7 +40,9 @@ class FreeBSDVM(basevm.BaseVM):
tar -xf /dev/vtbd1;
cd ../build;
../src/configure --extra-ldflags=-L/usr/local/lib \
- --extra-cflags=-I/usr/local/include {configure_opts};
+ --extra-cflags=-I/usr/local/include \
+ --enable-rust \
+ {configure_opts};
gmake --output-sync -j{jobs} {target} {verbose};
"""
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 0b787be..ae92399 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -72,7 +72,7 @@ void gd_egl_draw(VirtualConsole *vc)
#endif
int ww, wh, pw, ph, gs;
- if (!vc->gfx.gls) {
+ if (!vc->gfx.gls || !vc->gfx.ds) {
return;
}
@@ -112,9 +112,6 @@ void gd_egl_draw(VirtualConsole *vc)
}
#endif
} else {
- if (!vc->gfx.ds) {
- return;
- }
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 8151cc4..05fc380 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -48,7 +48,7 @@ void gd_gl_area_draw(VirtualConsole *vc)
int fbw, fbh;
int wx_offset, wy_offset;
- if (!vc->gfx.gls) {
+ if (!vc->gfx.gls || !vc->gfx.ds) {
return;
}
@@ -135,9 +135,6 @@ void gd_gl_area_draw(VirtualConsole *vc)
}
#endif
} else {
- if (!vc->gfx.ds) {
- return;
- }
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, pw, ph);
diff --git a/ui/icons/qemu.svg b/ui/icons/qemu.svg
index 24ca23a..f2500de 100644
--- a/ui/icons/qemu.svg
+++ b/ui/icons/qemu.svg
@@ -918,7 +918,26 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ <dc:title>Kew the Angry Emu</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>BenoƮt Canet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>CC BY 3.0</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>QEMU Community</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:date>2012-02-15</dc:date>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by/3.0/" />
+ <dc:source>https://lists.gnu.org/archive/html/qemu-devel/2012-02/msg02865.html</dc:source>
</cc:Work>
</rdf:RDF>
</metadata>
diff --git a/ui/sdl2.c b/ui/sdl2.c
index b00e421..032dc14 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -421,7 +421,7 @@ static void handle_keydown(SDL_Event *ev)
sdl_grab_end(scon);
}
break;
- case SDL_SCANCODE_U:
+ case SDL_SCANCODE_0:
sdl2_window_resize(scon);
if (!scon->opengl) {
/* re-create scon->texture */
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 5992f9d..2645e96 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -50,8 +50,6 @@ static int spice_migration_completed;
static int spice_display_is_running;
static int spice_have_target_host;
-static QemuThread me;
-
struct SpiceTimer {
QEMUTimer *timer;
};
@@ -222,7 +220,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
* thread and grab the BQL if so before calling qemu
* functions.
*/
- bool need_lock = !qemu_thread_is_self(&me);
+ bool need_lock = !bql_locked();
if (need_lock) {
bql_lock();
}
@@ -675,8 +673,6 @@ static void qemu_spice_init(void)
spice_wan_compression_t wan_compr;
bool seamless_migration;
- qemu_thread_get_self(&me);
-
if (!opts) {
return;
}
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 669832c..db71e86 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -980,7 +980,9 @@ static void spice_server_gl_scanout(QXLInstance *qxl,
spice_qxl_gl_scanout2(qxl, fd, width, height, offset, stride,
num_planes, format, modifier, y_0_top);
#else
- if (num_planes <= 1) {
+ if (fd == NULL) {
+ spice_qxl_gl_scanout(qxl, -1, 0, 0, 0, 0, false);
+ } else if (num_planes <= 1) {
spice_qxl_gl_scanout(qxl, fd[0], width, height, stride[0], format, y_0_top);
} else {
error_report("SPICE server does not support multi plane GL scanout");