Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bb4a8a47a | ||
|
|
045fa84784 | ||
|
|
56270e5d3d | ||
|
|
60da8301fe | ||
|
|
8b479229ff | ||
|
|
d4919bbcc2 | ||
|
|
cae7dc1452 | ||
|
|
7385e00665 | ||
|
|
1d4fb5815c | ||
|
|
b822207513 | ||
|
|
2947da750e | ||
|
|
60a7f5c8fe | ||
|
|
566dac7127 | ||
|
|
8ae20123b6 | ||
|
|
6c24b6000b | ||
|
|
987e90cfd2 | ||
|
|
b9f83298b9 | ||
|
|
3d6251f416 | ||
|
|
9832a670b3 | ||
|
|
df33ce9b6d | ||
|
|
eeee989f72 | ||
|
|
93d4107937 | ||
|
|
6356785daa | ||
|
|
01bf87c8e3 | ||
|
|
25ec23ab3f | ||
|
|
9dc6f05cc8 | ||
|
|
d5361580ac | ||
|
|
e8f5ca57e4 | ||
|
|
4448c345bc | ||
|
|
4fbd5a5202 | ||
|
|
16cc9594d2 | ||
|
|
1efefd13ca | ||
|
|
c2e0495e3c | ||
|
|
f64f1f8704 | ||
|
|
9f54fef2c0 | ||
|
|
5358980d33 | ||
|
|
6864f05cb1 | ||
|
|
0175121c6c | ||
|
|
e975434d62 | ||
|
|
e5e77f256f | ||
|
|
645b87f650 | ||
|
|
86d7b08d71 | ||
|
|
5691fbf440 | ||
|
|
441106eebb | ||
|
|
63188a00bb | ||
|
|
7012e20b2d | ||
|
|
c8e381d672 | ||
|
|
34808d041c | ||
|
|
01f6417f15 | ||
|
|
14a8213b75 | ||
|
|
c12eddbd48 | ||
|
|
880e82ed78 | ||
|
|
5980189e96 |
@@ -2,21 +2,11 @@
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
||||
cache:
|
||||
paths:
|
||||
- ccache
|
||||
key: "$CI_JOB_NAME"
|
||||
when: always
|
||||
before_script:
|
||||
- JOBS=$(expr $(nproc) + 1)
|
||||
script:
|
||||
- export CCACHE_BASEDIR="$(pwd)"
|
||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||
- export CCACHE_MAXSIZE="500M"
|
||||
- export PATH="$CCACHE_WRAPPERSDIR:$PATH"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ccache --zero-stats
|
||||
- ../configure --enable-werror --disable-docs --enable-fdt=system
|
||||
${TARGETS:+--target-list="$TARGETS"}
|
||||
$CONFIGURE_ARGS ||
|
||||
@@ -30,7 +20,6 @@
|
||||
then
|
||||
make -j"$JOBS" $MAKE_CHECK_ARGS ;
|
||||
fi
|
||||
- ccache --show-stats
|
||||
|
||||
# We jump some hoops in common_test_job_template to avoid
|
||||
# rebuilding all the object files we skip in the artifacts
|
||||
|
||||
@@ -103,7 +103,7 @@ crash-test-debian:
|
||||
script:
|
||||
- cd build
|
||||
- make NINJA=":" check-venv
|
||||
- pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
|
||||
|
||||
build-system-fedora:
|
||||
extends:
|
||||
@@ -146,8 +146,8 @@ crash-test-fedora:
|
||||
script:
|
||||
- cd build
|
||||
- make NINJA=":" check-venv
|
||||
- pyvenv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
|
||||
- pyvenv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
|
||||
|
||||
build-system-centos:
|
||||
extends:
|
||||
|
||||
@@ -50,7 +50,7 @@ x64-freebsd-13-build:
|
||||
NAME: freebsd-13
|
||||
CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
|
||||
CIRRUS_VM_IMAGE_SELECTOR: image_family
|
||||
CIRRUS_VM_IMAGE_NAME: freebsd-13-2
|
||||
CIRRUS_VM_IMAGE_NAME: freebsd-13-1
|
||||
CIRRUS_VM_CPUS: 8
|
||||
CIRRUS_VM_RAM: 8G
|
||||
UPDATE_COMMAND: pkg update; pkg upgrade -y
|
||||
|
||||
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
|
||||
NINJA='/usr/local/bin/ninja'
|
||||
PACKAGING_COMMAND='pkg'
|
||||
PIP3='/usr/local/bin/pip-3.8'
|
||||
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-tomli py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso zstd'
|
||||
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso zstd'
|
||||
PYPI_PKGS=''
|
||||
PYTHON='/usr/local/bin/python3'
|
||||
|
||||
@@ -12,5 +12,5 @@ NINJA='/opt/homebrew/bin/ninja'
|
||||
PACKAGING_COMMAND='brew'
|
||||
PIP3='/opt/homebrew/bin/pip3'
|
||||
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol tesseract usbredir vde vte3 xorriso zlib zstd'
|
||||
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
|
||||
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme'
|
||||
PYTHON='/opt/homebrew/bin/python3'
|
||||
|
||||
@@ -2,20 +2,10 @@
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
||||
cache:
|
||||
paths:
|
||||
- ccache
|
||||
key: "$CI_JOB_NAME"
|
||||
when: always
|
||||
timeout: 80m
|
||||
script:
|
||||
- export CCACHE_BASEDIR="$(pwd)"
|
||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||
- export CCACHE_MAXSIZE="500M"
|
||||
- export PATH="$CCACHE_WRAPPERSDIR:$PATH"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ccache --zero-stats
|
||||
- ../configure --enable-werror --disable-docs --enable-fdt=system
|
||||
--disable-user $QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS
|
||||
--target-list-exclude="arm-softmmu cris-softmmu
|
||||
@@ -28,7 +18,6 @@
|
||||
version="$(git describe --match v[0-9]* 2>/dev/null || git rev-parse --short HEAD)";
|
||||
mv -v qemu-setup*.exe qemu-setup-${version}.exe;
|
||||
fi
|
||||
- ccache --show-stats
|
||||
|
||||
# Job to cross-build specific accelerators.
|
||||
#
|
||||
@@ -40,15 +29,7 @@
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
||||
timeout: 30m
|
||||
cache:
|
||||
paths:
|
||||
- ccache/
|
||||
key: "$CI_JOB_NAME"
|
||||
script:
|
||||
- export CCACHE_BASEDIR="$(pwd)"
|
||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||
- export CCACHE_MAXSIZE="500M"
|
||||
- export PATH="$CCACHE_WRAPPERSDIR:$PATH"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
||||
@@ -59,14 +40,7 @@
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
||||
cache:
|
||||
paths:
|
||||
- ccache/
|
||||
key: "$CI_JOB_NAME"
|
||||
script:
|
||||
- export CCACHE_BASEDIR="$(pwd)"
|
||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||
- export CCACHE_MAXSIZE="500M"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
- windows
|
||||
- windows-1809
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
key: "${CI_JOB_NAME}-cache"
|
||||
paths:
|
||||
- msys64/var/cache
|
||||
- ccache
|
||||
when: always
|
||||
needs: []
|
||||
stage: build
|
||||
timeout: 100m
|
||||
timeout: 80m
|
||||
variables:
|
||||
# This feature doesn't (currently) work with PowerShell, it stops
|
||||
# the echo'ing of commands being run and doesn't show any timing
|
||||
@@ -73,7 +72,6 @@
|
||||
bison diffutils flex
|
||||
git grep make sed
|
||||
$MINGW_TARGET-capstone
|
||||
$MINGW_TARGET-ccache
|
||||
$MINGW_TARGET-curl
|
||||
$MINGW_TARGET-cyrus-sasl
|
||||
$MINGW_TARGET-dtc
|
||||
@@ -103,18 +101,11 @@
|
||||
- Write-Output "Running build at $(Get-Date -Format u)"
|
||||
- $env:CHERE_INVOKING = 'yes' # Preserve the current working directory
|
||||
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
|
||||
- $env:CCACHE_BASEDIR = "$env:CI_PROJECT_DIR"
|
||||
- $env:CCACHE_DIR = "$env:CCACHE_BASEDIR/ccache"
|
||||
- $env:CCACHE_MAXSIZE = "500M"
|
||||
- $env:CCACHE_DEPEND = 1 # cache misses are too expensive with preprocessor mode
|
||||
- $env:CC = "ccache gcc"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ..\msys64\usr\bin\bash -lc "ccache --zero-stats"
|
||||
- ..\msys64\usr\bin\bash -lc "../configure --enable-fdt=system $CONFIGURE_ARGS"
|
||||
- ..\msys64\usr\bin\bash -lc "make"
|
||||
- ..\msys64\usr\bin\bash -lc "make check MTESTARGS='$TEST_ARGS' || { cat meson-logs/testlog.txt; exit 1; } ;"
|
||||
- ..\msys64\usr\bin\bash -lc "ccache --show-stats"
|
||||
- Write-Output "Finished build at $(Get-Date -Format u)"
|
||||
|
||||
msys2-64bit:
|
||||
|
||||
+8
-8
@@ -543,6 +543,14 @@ F: include/sysemu/xen.h
|
||||
F: include/sysemu/xen-mapcache.h
|
||||
F: stubs/xen-hw-stub.c
|
||||
|
||||
Guest CPU Cores (HAXM)
|
||||
---------------------
|
||||
X86 HAXM CPUs
|
||||
S: Orphan
|
||||
F: accel/stubs/hax-stub.c
|
||||
F: include/sysemu/hax.h
|
||||
F: target/i386/hax/
|
||||
|
||||
Guest CPU Cores (NVMM)
|
||||
----------------------
|
||||
NetBSD Virtual Machine Monitor (NVMM) CPU support
|
||||
@@ -2248,13 +2256,6 @@ F: tests/qtest/nvme-test.c
|
||||
F: docs/system/devices/nvme.rst
|
||||
T: git git://git.infradead.org/qemu-nvme.git nvme-next
|
||||
|
||||
ufs
|
||||
M: Jeuk Kim <jeuk20.kim@samsung.com>
|
||||
S: Supported
|
||||
F: hw/ufs/*
|
||||
F: include/block/ufs.h
|
||||
F: tests/qtest/ufs-test.c
|
||||
|
||||
megasas
|
||||
M: Hannes Reinecke <hare@suse.com>
|
||||
L: qemu-block@nongnu.org
|
||||
@@ -3700,7 +3701,6 @@ S: Supported
|
||||
F: block/parallels.c
|
||||
F: block/parallels-ext.c
|
||||
F: docs/interop/parallels.txt
|
||||
T: git https://src.openvz.org/scm/~den/qemu.git parallels
|
||||
|
||||
qed
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
|
||||
@@ -164,6 +164,14 @@ ifneq ($(filter $(ninja-targets), $(ninja-cmd-goals)),)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PLUGIN),y)
|
||||
.PHONY: plugins
|
||||
plugins:
|
||||
$(call quiet-command,\
|
||||
$(MAKE) $(SUBDIR_MAKEFLAGS) -C contrib/plugins V="$(V)", \
|
||||
"BUILD", "example plugins")
|
||||
endif # $(CONFIG_PLUGIN)
|
||||
|
||||
else # config-host.mak does not exist
|
||||
ifneq ($(filter-out $(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail))
|
||||
$(error Please call configure before running make)
|
||||
@@ -176,20 +184,15 @@ include $(SRC_PATH)/tests/Makefile.include
|
||||
|
||||
all: recurse-all
|
||||
|
||||
SUBDIR_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(SUBDIRS)))
|
||||
.PHONY: $(SUBDIR_RULES)
|
||||
$(SUBDIR_RULES):
|
||||
ROMS_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(ROMS)))
|
||||
.PHONY: $(ROMS_RULES)
|
||||
$(ROMS_RULES):
|
||||
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" TARGET_DIR="$(dir $@)" $(notdir $@),)
|
||||
|
||||
ifneq ($(filter contrib/plugins, $(SUBDIRS)),)
|
||||
.PHONY: plugins
|
||||
plugins: contrib/plugins/all
|
||||
endif
|
||||
|
||||
.PHONY: recurse-all recurse-clean
|
||||
recurse-all: $(addsuffix /all, $(SUBDIRS))
|
||||
recurse-clean: $(addsuffix /clean, $(SUBDIRS))
|
||||
recurse-distclean: $(addsuffix /distclean, $(SUBDIRS))
|
||||
recurse-all: $(addsuffix /all, $(ROMS))
|
||||
recurse-clean: $(addsuffix /clean, $(ROMS))
|
||||
recurse-distclean: $(addsuffix /distclean, $(ROMS))
|
||||
|
||||
######################################################################
|
||||
|
||||
@@ -293,7 +296,7 @@ help:
|
||||
$(call print-help,cscope,Generate cscope index)
|
||||
$(call print-help,sparse,Run sparse on the QEMU source)
|
||||
@echo ''
|
||||
ifneq ($(filter contrib/plugins, $(SUBDIRS)),)
|
||||
ifeq ($(CONFIG_PLUGIN),y)
|
||||
@echo 'Plugin targets:'
|
||||
$(call print-help,plugins,Build the example TCG plugins)
|
||||
@echo ''
|
||||
@@ -313,7 +316,7 @@ endif
|
||||
@echo 'Documentation targets:'
|
||||
$(call print-help,html man,Build documentation in specified format)
|
||||
@echo ''
|
||||
ifneq ($(filter msi, $(ninja-targets)),)
|
||||
ifdef CONFIG_WIN32
|
||||
@echo 'Windows targets:'
|
||||
$(call print-help,installer,Build NSIS-based installer for QEMU)
|
||||
$(call print-help,msi,Build MSI-based installer for qemu-ga)
|
||||
|
||||
@@ -4,6 +4,9 @@ config WHPX
|
||||
config NVMM
|
||||
bool
|
||||
|
||||
config HAX
|
||||
bool
|
||||
|
||||
config HVF
|
||||
bool
|
||||
|
||||
|
||||
@@ -474,7 +474,7 @@ static void hvf_start_vcpu_thread(CPUState *cpu)
|
||||
cpu, QEMU_THREAD_JOINABLE);
|
||||
}
|
||||
|
||||
static int hvf_insert_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len)
|
||||
static int hvf_insert_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len)
|
||||
{
|
||||
struct hvf_sw_breakpoint *bp;
|
||||
int err;
|
||||
@@ -512,7 +512,7 @@ static int hvf_insert_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hvf_remove_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len)
|
||||
static int hvf_remove_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len)
|
||||
{
|
||||
struct hvf_sw_breakpoint *bp;
|
||||
int err;
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ void assert_hvf_ok(hv_return_t ret)
|
||||
abort();
|
||||
}
|
||||
|
||||
struct hvf_sw_breakpoint *hvf_find_sw_breakpoint(CPUState *cpu, vaddr pc)
|
||||
struct hvf_sw_breakpoint *hvf_find_sw_breakpoint(CPUState *cpu, target_ulong pc)
|
||||
{
|
||||
struct hvf_sw_breakpoint *bp;
|
||||
|
||||
|
||||
+9
-9
@@ -1454,13 +1454,15 @@ static void *kvm_dirty_ring_reaper_thread(void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void kvm_dirty_ring_reaper_init(KVMState *s)
|
||||
static int kvm_dirty_ring_reaper_init(KVMState *s)
|
||||
{
|
||||
struct KVMDirtyRingReaper *r = &s->reaper;
|
||||
|
||||
qemu_thread_create(&r->reaper_thr, "kvm-reaper",
|
||||
kvm_dirty_ring_reaper_thread,
|
||||
s, QEMU_THREAD_JOINABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_dirty_ring_init(KVMState *s)
|
||||
@@ -2525,11 +2527,6 @@ static int kvm_init(MachineState *ms)
|
||||
type = kvm_arch_get_default_type(ms);
|
||||
}
|
||||
|
||||
if (type < 0) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = kvm_ioctl(s, KVM_CREATE_VM, type);
|
||||
} while (ret == -EINTR);
|
||||
@@ -2742,7 +2739,10 @@ static int kvm_init(MachineState *ms)
|
||||
}
|
||||
|
||||
if (s->kvm_dirty_ring_size) {
|
||||
kvm_dirty_ring_reaper_init(s);
|
||||
ret = kvm_dirty_ring_reaper_init(s);
|
||||
if (ret) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (kvm_check_extension(kvm_state, KVM_CAP_BINARY_STATS_FD)) {
|
||||
@@ -2760,7 +2760,6 @@ err:
|
||||
if (s->fd != -1) {
|
||||
close(s->fd);
|
||||
}
|
||||
g_free(s->as);
|
||||
g_free(s->memory_listener.slots);
|
||||
|
||||
return ret;
|
||||
@@ -3309,7 +3308,8 @@ bool kvm_arm_supports_user_irq(void)
|
||||
}
|
||||
|
||||
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
||||
struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu, vaddr pc)
|
||||
struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
|
||||
target_ulong pc)
|
||||
{
|
||||
struct kvm_sw_breakpoint *bp;
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* QEMU HAXM support
|
||||
*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
*
|
||||
* Copyright 2016 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* See the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "sysemu/hax.h"
|
||||
|
||||
bool hax_allowed;
|
||||
|
||||
int hax_sync_vcpus(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
sysemu_stubs_ss = ss.source_set()
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c'))
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c'))
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c'))
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c'))
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
# define END _le
|
||||
#endif
|
||||
|
||||
ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
|
||||
ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
||||
ABI_TYPE cmpv, ABI_TYPE newv,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
|
||||
}
|
||||
|
||||
#if DATA_SIZE < 16
|
||||
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
|
||||
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
|
||||
@@ -100,7 +100,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
|
||||
}
|
||||
|
||||
#define GEN_ATOMIC_HELPER(X) \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
|
||||
{ \
|
||||
DATA_TYPE *haddr, ret; \
|
||||
@@ -131,7 +131,7 @@ GEN_ATOMIC_HELPER(xor_fetch)
|
||||
* of CF_PARALLEL's value, we'll trace just a read and a write.
|
||||
*/
|
||||
#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
|
||||
{ \
|
||||
XDATA_TYPE *haddr, cmp, old, new, val = xval; \
|
||||
@@ -172,7 +172,7 @@ GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
|
||||
# define END _be
|
||||
#endif
|
||||
|
||||
ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
|
||||
ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
||||
ABI_TYPE cmpv, ABI_TYPE newv,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
@@ -190,7 +190,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
|
||||
}
|
||||
|
||||
#if DATA_SIZE < 16
|
||||
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
|
||||
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
|
||||
@@ -203,7 +203,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
|
||||
}
|
||||
|
||||
#define GEN_ATOMIC_HELPER(X) \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
|
||||
{ \
|
||||
DATA_TYPE *haddr, ret; \
|
||||
@@ -231,7 +231,7 @@ GEN_ATOMIC_HELPER(xor_fetch)
|
||||
* of CF_PARALLEL's value, we'll trace just a read and a write.
|
||||
*/
|
||||
#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
||||
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
|
||||
{ \
|
||||
XDATA_TYPE *haddr, ldo, ldn, old, new, val = xval; \
|
||||
|
||||
@@ -33,6 +33,36 @@ void cpu_loop_exit_noexc(CPUState *cpu)
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
void cpu_reloading_memory_map(void)
|
||||
{
|
||||
if (qemu_in_vcpu_thread() && current_cpu->running) {
|
||||
/* The guest can in theory prolong the RCU critical section as long
|
||||
* as it feels like. The major problem with this is that because it
|
||||
* can do multiple reconfigurations of the memory map within the
|
||||
* critical section, we could potentially accumulate an unbounded
|
||||
* collection of memory data structures awaiting reclamation.
|
||||
*
|
||||
* Because the only thing we're currently protecting with RCU is the
|
||||
* memory data structures, it's sufficient to break the critical section
|
||||
* in this callback, which we know will get called every time the
|
||||
* memory map is rearranged.
|
||||
*
|
||||
* (If we add anything else in the system that uses RCU to protect
|
||||
* its data structures, we will need to implement some other mechanism
|
||||
* to force TCG CPUs to exit the critical section, at which point this
|
||||
* part of this callback might become unnecessary.)
|
||||
*
|
||||
* This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
|
||||
* only protects cpu->as->dispatch. Since we know our caller is about
|
||||
* to reload it, it's safe to split the critical section.
|
||||
*/
|
||||
rcu_read_unlock();
|
||||
rcu_read_lock();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void cpu_loop_exit(CPUState *cpu)
|
||||
{
|
||||
/* Undo the setting in cpu_tb_exec. */
|
||||
|
||||
+8
-9
@@ -74,9 +74,8 @@
|
||||
} while (0)
|
||||
|
||||
/* run_on_cpu_data.target_ptr should always be big enough for a
|
||||
* vaddr even on 32 bit builds
|
||||
*/
|
||||
QEMU_BUILD_BUG_ON(sizeof(vaddr) > sizeof(run_on_cpu_data));
|
||||
* target_ulong even on 32 bit builds */
|
||||
QEMU_BUILD_BUG_ON(sizeof(target_ulong) > sizeof(run_on_cpu_data));
|
||||
|
||||
/* We currently can't handle more than 16 bits in the MMUIDX bitmask.
|
||||
*/
|
||||
@@ -1109,7 +1108,7 @@ static void tlb_add_large_page(CPUArchState *env, int mmu_idx,
|
||||
}
|
||||
|
||||
static inline void tlb_set_compare(CPUTLBEntryFull *full, CPUTLBEntry *ent,
|
||||
vaddr address, int flags,
|
||||
target_ulong address, int flags,
|
||||
MMUAccessType access_type, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
@@ -3134,14 +3133,14 @@ static void plugin_store_cb(CPUArchState *env, abi_ptr addr, MemOpIdx oi)
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||
}
|
||||
|
||||
void cpu_stb_mmu(CPUArchState *env, abi_ptr addr, uint8_t val,
|
||||
void cpu_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
helper_stb_mmu(env, addr, val, oi, retaddr);
|
||||
plugin_store_cb(env, addr, oi);
|
||||
}
|
||||
|
||||
void cpu_stw_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
|
||||
void cpu_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
|
||||
@@ -3149,7 +3148,7 @@ void cpu_stw_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
|
||||
plugin_store_cb(env, addr, oi);
|
||||
}
|
||||
|
||||
void cpu_stl_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
void cpu_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
|
||||
@@ -3157,7 +3156,7 @@ void cpu_stl_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
plugin_store_cb(env, addr, oi);
|
||||
}
|
||||
|
||||
void cpu_stq_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
void cpu_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
|
||||
@@ -3165,7 +3164,7 @@ void cpu_stq_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
plugin_store_cb(env, addr, oi);
|
||||
}
|
||||
|
||||
void cpu_st16_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
|
||||
void cpu_st16_mmu(CPUArchState *env, target_ulong addr, Int128 val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
|
||||
|
||||
@@ -11,9 +11,7 @@ tcg_ss.add(files(
|
||||
))
|
||||
tcg_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
|
||||
tcg_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_false: files('user-exec-stub.c'))
|
||||
if get_option('plugins')
|
||||
tcg_ss.add(files('plugin-gen.c'))
|
||||
endif
|
||||
tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c')])
|
||||
tcg_ss.add(when: libdw, if_true: files('debuginfo.c'))
|
||||
tcg_ss.add(when: 'CONFIG_LINUX', if_true: files('perf.c'))
|
||||
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Translation Block Maintenance
|
||||
* Translation Block Maintaince
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
|
||||
@@ -112,12 +112,8 @@ static int tpm_util_request(int fd,
|
||||
void *response,
|
||||
size_t responselen)
|
||||
{
|
||||
fd_set readfds;
|
||||
GPollFD fds[1] = { {.fd = fd, .events = G_IO_IN } };
|
||||
int n;
|
||||
struct timeval tv = {
|
||||
.tv_sec = 1,
|
||||
.tv_usec = 0,
|
||||
};
|
||||
|
||||
n = write(fd, request, requestlen);
|
||||
if (n < 0) {
|
||||
@@ -127,11 +123,8 @@ static int tpm_util_request(int fd,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd, &readfds);
|
||||
|
||||
/* wait for a second */
|
||||
n = select(fd + 1, &readfds, NULL, NULL, &tv);
|
||||
n = RETRY_ON_EINTR(g_poll(fds, 1, 1000));
|
||||
if (n != 1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -6480,13 +6480,6 @@ int coroutine_fn bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
}
|
||||
memset(bdi, 0, sizeof(*bdi));
|
||||
ret = drv->bdrv_co_get_info(bs, bdi);
|
||||
if (bdi->subcluster_size == 0) {
|
||||
/*
|
||||
* If the driver left this unset, subclusters are not supported.
|
||||
* Then it is safe to treat each cluster as having only one subcluster.
|
||||
*/
|
||||
bdi->subcluster_size = bdi->cluster_size;
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
+25
-25
@@ -728,21 +728,21 @@ BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Round a region to subcluster (if supported) or cluster boundaries
|
||||
* Round a region to cluster boundaries
|
||||
*/
|
||||
void coroutine_fn GRAPH_RDLOCK
|
||||
bdrv_round_to_subclusters(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
int64_t *align_offset, int64_t *align_bytes)
|
||||
bdrv_round_to_clusters(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
int64_t *cluster_offset, int64_t *cluster_bytes)
|
||||
{
|
||||
BlockDriverInfo bdi;
|
||||
IO_CODE();
|
||||
if (bdrv_co_get_info(bs, &bdi) < 0 || bdi.subcluster_size == 0) {
|
||||
*align_offset = offset;
|
||||
*align_bytes = bytes;
|
||||
if (bdrv_co_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
|
||||
*cluster_offset = offset;
|
||||
*cluster_bytes = bytes;
|
||||
} else {
|
||||
int64_t c = bdi.subcluster_size;
|
||||
*align_offset = QEMU_ALIGN_DOWN(offset, c);
|
||||
*align_bytes = QEMU_ALIGN_UP(offset - *align_offset + bytes, c);
|
||||
int64_t c = bdi.cluster_size;
|
||||
*cluster_offset = QEMU_ALIGN_DOWN(offset, c);
|
||||
*cluster_bytes = QEMU_ALIGN_UP(offset - *cluster_offset + bytes, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1168,8 +1168,8 @@ bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
void *bounce_buffer = NULL;
|
||||
|
||||
BlockDriver *drv = bs->drv;
|
||||
int64_t align_offset;
|
||||
int64_t align_bytes;
|
||||
int64_t cluster_offset;
|
||||
int64_t cluster_bytes;
|
||||
int64_t skip_bytes;
|
||||
int ret;
|
||||
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
|
||||
@@ -1203,28 +1203,28 @@ bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
* BDRV_REQUEST_MAX_BYTES (even when the original read did not), which
|
||||
* is one reason we loop rather than doing it all at once.
|
||||
*/
|
||||
bdrv_round_to_subclusters(bs, offset, bytes, &align_offset, &align_bytes);
|
||||
skip_bytes = offset - align_offset;
|
||||
bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);
|
||||
skip_bytes = offset - cluster_offset;
|
||||
|
||||
trace_bdrv_co_do_copy_on_readv(bs, offset, bytes,
|
||||
align_offset, align_bytes);
|
||||
cluster_offset, cluster_bytes);
|
||||
|
||||
while (align_bytes) {
|
||||
while (cluster_bytes) {
|
||||
int64_t pnum;
|
||||
|
||||
if (skip_write) {
|
||||
ret = 1; /* "already allocated", so nothing will be copied */
|
||||
pnum = MIN(align_bytes, max_transfer);
|
||||
pnum = MIN(cluster_bytes, max_transfer);
|
||||
} else {
|
||||
ret = bdrv_is_allocated(bs, align_offset,
|
||||
MIN(align_bytes, max_transfer), &pnum);
|
||||
ret = bdrv_is_allocated(bs, cluster_offset,
|
||||
MIN(cluster_bytes, max_transfer), &pnum);
|
||||
if (ret < 0) {
|
||||
/*
|
||||
* Safe to treat errors in querying allocation as if
|
||||
* unallocated; we'll probably fail again soon on the
|
||||
* read, but at least that will set a decent errno.
|
||||
*/
|
||||
pnum = MIN(align_bytes, max_transfer);
|
||||
pnum = MIN(cluster_bytes, max_transfer);
|
||||
}
|
||||
|
||||
/* Stop at EOF if the image ends in the middle of the cluster */
|
||||
@@ -1242,7 +1242,7 @@ bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
/* Must copy-on-read; use the bounce buffer */
|
||||
pnum = MIN(pnum, MAX_BOUNCE_BUFFER);
|
||||
if (!bounce_buffer) {
|
||||
int64_t max_we_need = MAX(pnum, align_bytes - pnum);
|
||||
int64_t max_we_need = MAX(pnum, cluster_bytes - pnum);
|
||||
int64_t max_allowed = MIN(max_transfer, MAX_BOUNCE_BUFFER);
|
||||
int64_t bounce_buffer_len = MIN(max_we_need, max_allowed);
|
||||
|
||||
@@ -1254,7 +1254,7 @@ bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
}
|
||||
qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum);
|
||||
|
||||
ret = bdrv_driver_preadv(bs, align_offset, pnum,
|
||||
ret = bdrv_driver_preadv(bs, cluster_offset, pnum,
|
||||
&local_qiov, 0, 0);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
@@ -1266,13 +1266,13 @@ bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
/* FIXME: Should we (perhaps conditionally) be setting
|
||||
* BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy
|
||||
* that still correctly reads as zero? */
|
||||
ret = bdrv_co_do_pwrite_zeroes(bs, align_offset, pnum,
|
||||
ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, pnum,
|
||||
BDRV_REQ_WRITE_UNCHANGED);
|
||||
} else {
|
||||
/* This does not change the data on the disk, it is not
|
||||
* necessary to flush even in cache=writethrough mode.
|
||||
*/
|
||||
ret = bdrv_driver_pwritev(bs, align_offset, pnum,
|
||||
ret = bdrv_driver_pwritev(bs, cluster_offset, pnum,
|
||||
&local_qiov, 0,
|
||||
BDRV_REQ_WRITE_UNCHANGED);
|
||||
}
|
||||
@@ -1301,8 +1301,8 @@ bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
}
|
||||
}
|
||||
|
||||
align_offset += pnum;
|
||||
align_bytes -= pnum;
|
||||
cluster_offset += pnum;
|
||||
cluster_bytes -= pnum;
|
||||
progress += pnum - skip_bytes;
|
||||
skip_bytes = 0;
|
||||
}
|
||||
|
||||
+4
-4
@@ -283,8 +283,8 @@ static int coroutine_fn mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
|
||||
need_cow |= !test_bit((*offset + *bytes - 1) / s->granularity,
|
||||
s->cow_bitmap);
|
||||
if (need_cow) {
|
||||
bdrv_round_to_subclusters(blk_bs(s->target), *offset, *bytes,
|
||||
&align_offset, &align_bytes);
|
||||
bdrv_round_to_clusters(blk_bs(s->target), *offset, *bytes,
|
||||
&align_offset, &align_bytes);
|
||||
}
|
||||
|
||||
if (align_bytes > max_bytes) {
|
||||
@@ -576,8 +576,8 @@ static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
|
||||
int64_t target_offset;
|
||||
int64_t target_bytes;
|
||||
WITH_GRAPH_RDLOCK_GUARD() {
|
||||
bdrv_round_to_subclusters(blk_bs(s->target), offset, io_bytes,
|
||||
&target_offset, &target_bytes);
|
||||
bdrv_round_to_clusters(blk_bs(s->target), offset, io_bytes,
|
||||
&target_offset, &target_bytes);
|
||||
}
|
||||
if (target_offset == offset &&
|
||||
target_bytes == io_bytes) {
|
||||
|
||||
+48
-298
@@ -136,12 +136,6 @@ static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
|
||||
return MIN(nb_sectors, ret);
|
||||
}
|
||||
|
||||
static uint32_t host_cluster_index(BDRVParallelsState *s, int64_t off)
|
||||
{
|
||||
off -= s->data_start << BDRV_SECTOR_BITS;
|
||||
return off / s->cluster_size;
|
||||
}
|
||||
|
||||
static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
|
||||
int nb_sectors, int *pnum)
|
||||
{
|
||||
@@ -194,8 +188,7 @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
|
||||
idx = sector_num / s->tracks;
|
||||
to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx;
|
||||
|
||||
/*
|
||||
* This function is called only by parallels_co_writev(), which will never
|
||||
/* This function is called only by parallels_co_writev(), which will never
|
||||
* pass a sector_num at or beyond the end of the image (because the block
|
||||
* layer never passes such a sector_num to that function). Therefore, idx
|
||||
* is always below s->bat_size.
|
||||
@@ -203,8 +196,7 @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
|
||||
* exceed the image end. Therefore, idx + to_allocate cannot exceed
|
||||
* s->bat_size.
|
||||
* Note that s->bat_size is an unsigned int, therefore idx + to_allocate
|
||||
* will always fit into a uint32_t.
|
||||
*/
|
||||
* will always fit into a uint32_t. */
|
||||
assert(idx < s->bat_size && idx + to_allocate <= s->bat_size);
|
||||
|
||||
space = to_allocate * s->tracks;
|
||||
@@ -238,15 +230,13 @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to read from backing to fill empty clusters
|
||||
/* Try to read from backing to fill empty clusters
|
||||
* FIXME: 1. previous write_zeroes may be redundant
|
||||
* 2. most of data we read from backing will be rewritten by
|
||||
* parallels_co_writev. On aligned-to-cluster write we do not need
|
||||
* this read at all.
|
||||
* 3. it would be good to combine write of data from backing and new
|
||||
* data into one write call.
|
||||
*/
|
||||
* data into one write call */
|
||||
if (bs->backing) {
|
||||
int64_t nb_cow_sectors = to_allocate * s->tracks;
|
||||
int64_t nb_cow_bytes = nb_cow_sectors << BDRV_SECTOR_BITS;
|
||||
@@ -450,81 +440,6 @@ static void parallels_check_unclean(BlockDriverState *bs,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if data_off is correct, otherwise false. In both cases
|
||||
* correct_offset is set to the proper value.
|
||||
*/
|
||||
static bool parallels_test_data_off(BDRVParallelsState *s,
|
||||
int64_t file_nb_sectors,
|
||||
uint32_t *correct_offset)
|
||||
{
|
||||
uint32_t data_off, min_off;
|
||||
bool old_magic;
|
||||
|
||||
/*
|
||||
* There are two slightly different image formats: with "WithoutFreeSpace"
|
||||
* or "WithouFreSpacExt" magic words. Call the first one as "old magic".
|
||||
* In such images data_off field can be zero. In this case the offset is
|
||||
* calculated as the end of BAT table plus some padding to ensure sector
|
||||
* size alignment.
|
||||
*/
|
||||
old_magic = !memcmp(s->header->magic, HEADER_MAGIC, 16);
|
||||
|
||||
min_off = DIV_ROUND_UP(bat_entry_off(s->bat_size), BDRV_SECTOR_SIZE);
|
||||
if (!old_magic) {
|
||||
min_off = ROUND_UP(min_off, s->cluster_size / BDRV_SECTOR_SIZE);
|
||||
}
|
||||
|
||||
if (correct_offset) {
|
||||
*correct_offset = min_off;
|
||||
}
|
||||
|
||||
data_off = le32_to_cpu(s->header->data_off);
|
||||
if (data_off == 0 && old_magic) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data_off < min_off || data_off > file_nb_sectors) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (correct_offset) {
|
||||
*correct_offset = data_off;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
parallels_check_data_off(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
BdrvCheckMode fix)
|
||||
{
|
||||
BDRVParallelsState *s = bs->opaque;
|
||||
int64_t file_size;
|
||||
uint32_t data_off;
|
||||
|
||||
file_size = bdrv_co_nb_sectors(bs->file->bs);
|
||||
if (file_size < 0) {
|
||||
res->check_errors++;
|
||||
return file_size;
|
||||
}
|
||||
|
||||
if (parallels_test_data_off(s, file_size, &data_off)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
res->corruptions++;
|
||||
if (fix & BDRV_FIX_ERRORS) {
|
||||
s->header->data_off = cpu_to_le32(data_off);
|
||||
res->corruptions_fixed++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s data_off field has incorrect value\n",
|
||||
fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
parallels_check_outside_image(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
BdrvCheckMode fix)
|
||||
@@ -569,13 +484,13 @@ parallels_check_outside_image(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
parallels_check_leak(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
BdrvCheckMode fix, bool explicit)
|
||||
BdrvCheckMode fix)
|
||||
{
|
||||
BDRVParallelsState *s = bs->opaque;
|
||||
int64_t size;
|
||||
int ret;
|
||||
|
||||
size = bdrv_co_getlength(bs->file->bs);
|
||||
size = bdrv_getlength(bs->file->bs);
|
||||
if (size < 0) {
|
||||
res->check_errors++;
|
||||
return size;
|
||||
@@ -584,13 +499,10 @@ parallels_check_leak(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
if (size > res->image_end_offset) {
|
||||
int64_t count;
|
||||
count = DIV_ROUND_UP(size - res->image_end_offset, s->cluster_size);
|
||||
if (explicit) {
|
||||
fprintf(stderr,
|
||||
"%s space leaked at the end of the image %" PRId64 "\n",
|
||||
fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR",
|
||||
size - res->image_end_offset);
|
||||
res->leaks += count;
|
||||
}
|
||||
fprintf(stderr, "%s space leaked at the end of the image %" PRId64 "\n",
|
||||
fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR",
|
||||
size - res->image_end_offset);
|
||||
res->leaks += count;
|
||||
if (fix & BDRV_FIX_LEAKS) {
|
||||
Error *local_err = NULL;
|
||||
|
||||
@@ -605,148 +517,13 @@ parallels_check_leak(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
res->check_errors++;
|
||||
return ret;
|
||||
}
|
||||
if (explicit) {
|
||||
res->leaks_fixed += count;
|
||||
}
|
||||
res->leaks_fixed += count;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
parallels_check_duplicate(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
BdrvCheckMode fix)
|
||||
{
|
||||
BDRVParallelsState *s = bs->opaque;
|
||||
int64_t host_off, host_sector, guest_sector;
|
||||
unsigned long *bitmap;
|
||||
uint32_t i, bitmap_size, cluster_index, bat_entry;
|
||||
int n, ret = 0;
|
||||
uint64_t *buf = NULL;
|
||||
bool fixed = false;
|
||||
|
||||
/*
|
||||
* Create a bitmap of used clusters.
|
||||
* If a bit is set, there is a BAT entry pointing to this cluster.
|
||||
* Loop through the BAT entries, check bits relevant to an entry offset.
|
||||
* If bit is set, this entry is duplicated. Otherwise set the bit.
|
||||
*
|
||||
* We shouldn't worry about newly allocated clusters outside the image
|
||||
* because they are created higher then any existing cluster pointed by
|
||||
* a BAT entry.
|
||||
*/
|
||||
bitmap_size = host_cluster_index(s, res->image_end_offset);
|
||||
if (bitmap_size == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (res->image_end_offset % s->cluster_size) {
|
||||
/* A not aligned image end leads to a bitmap shorter by 1 */
|
||||
bitmap_size++;
|
||||
}
|
||||
|
||||
bitmap = bitmap_new(bitmap_size);
|
||||
|
||||
buf = qemu_blockalign(bs, s->cluster_size);
|
||||
|
||||
for (i = 0; i < s->bat_size; i++) {
|
||||
host_off = bat2sect(s, i) << BDRV_SECTOR_BITS;
|
||||
if (host_off == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cluster_index = host_cluster_index(s, host_off);
|
||||
assert(cluster_index < bitmap_size);
|
||||
if (!test_bit(cluster_index, bitmap)) {
|
||||
bitmap_set(bitmap, cluster_index, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* this cluster duplicates another one */
|
||||
fprintf(stderr, "%s duplicate offset in BAT entry %u\n",
|
||||
fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
|
||||
|
||||
res->corruptions++;
|
||||
|
||||
if (!(fix & BDRV_FIX_ERRORS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the entry and allocate a new cluster
|
||||
* for the relevant guest offset. In this way we let
|
||||
* the lower layer to place the new cluster properly.
|
||||
* Copy the original cluster to the allocated one.
|
||||
* But before save the old offset value for repairing
|
||||
* if we have an error.
|
||||
*/
|
||||
bat_entry = s->bat_bitmap[i];
|
||||
parallels_set_bat_entry(s, i, 0);
|
||||
|
||||
ret = bdrv_co_pread(bs->file, host_off, s->cluster_size, buf, 0);
|
||||
if (ret < 0) {
|
||||
res->check_errors++;
|
||||
goto out_repair_bat;
|
||||
}
|
||||
|
||||
guest_sector = (i * (int64_t)s->cluster_size) >> BDRV_SECTOR_BITS;
|
||||
host_sector = allocate_clusters(bs, guest_sector, s->tracks, &n);
|
||||
if (host_sector < 0) {
|
||||
res->check_errors++;
|
||||
goto out_repair_bat;
|
||||
}
|
||||
host_off = host_sector << BDRV_SECTOR_BITS;
|
||||
|
||||
ret = bdrv_co_pwrite(bs->file, host_off, s->cluster_size, buf, 0);
|
||||
if (ret < 0) {
|
||||
res->check_errors++;
|
||||
goto out_repair_bat;
|
||||
}
|
||||
|
||||
if (host_off + s->cluster_size > res->image_end_offset) {
|
||||
res->image_end_offset = host_off + s->cluster_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the future allocate_cluster() will reuse holed offsets
|
||||
* inside the image. Keep the used clusters bitmap content
|
||||
* consistent for the new allocated clusters too.
|
||||
*
|
||||
* Note, clusters allocated outside the current image are not
|
||||
* considered, and the bitmap size doesn't change.
|
||||
*/
|
||||
cluster_index = host_cluster_index(s, host_off);
|
||||
if (cluster_index < bitmap_size) {
|
||||
bitmap_set(bitmap, cluster_index, 1);
|
||||
}
|
||||
|
||||
fixed = true;
|
||||
res->corruptions_fixed++;
|
||||
|
||||
}
|
||||
|
||||
if (fixed) {
|
||||
/*
|
||||
* When new clusters are allocated, the file size increases by
|
||||
* 128 Mb. We need to truncate the file to the right size. Let
|
||||
* the leak fix code make its job without res changing.
|
||||
*/
|
||||
ret = parallels_check_leak(bs, res, fix, false);
|
||||
}
|
||||
|
||||
out_free:
|
||||
g_free(buf);
|
||||
g_free(bitmap);
|
||||
return ret;
|
||||
/*
|
||||
* We can get here only from places where index and old_offset have
|
||||
* meaningful values.
|
||||
*/
|
||||
out_repair_bat:
|
||||
s->bat_bitmap[i] = bat_entry;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
static void parallels_collect_statistics(BlockDriverState *bs,
|
||||
BdrvCheckResult *res,
|
||||
BdrvCheckMode fix)
|
||||
@@ -788,22 +565,12 @@ parallels_co_check(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
WITH_QEMU_LOCK_GUARD(&s->lock) {
|
||||
parallels_check_unclean(bs, res, fix);
|
||||
|
||||
ret = parallels_check_data_off(bs, res, fix);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = parallels_check_outside_image(bs, res, fix);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = parallels_check_leak(bs, res, fix, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = parallels_check_duplicate(bs, res, fix);
|
||||
ret = parallels_check_leak(bs, res, fix);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1031,12 +798,10 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
BDRVParallelsState *s = bs->opaque;
|
||||
ParallelsHeader ph;
|
||||
int ret, size, i;
|
||||
int64_t file_nb_sectors, sector;
|
||||
uint32_t data_start;
|
||||
int64_t file_nb_sectors;
|
||||
QemuOpts *opts = NULL;
|
||||
Error *local_err = NULL;
|
||||
char *buf;
|
||||
bool data_off_is_correct;
|
||||
|
||||
ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
|
||||
if (ret < 0) {
|
||||
@@ -1094,6 +859,15 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
s->data_end = le32_to_cpu(ph.data_off);
|
||||
if (s->data_end == 0) {
|
||||
s->data_end = ROUND_UP(bat_entry_off(s->bat_size), BDRV_SECTOR_SIZE);
|
||||
}
|
||||
if (s->data_end < s->header_size) {
|
||||
/* there is not enough unused space to fit to block align between BAT
|
||||
and actual data. We can't avoid read-modify-write... */
|
||||
s->header_size = size;
|
||||
}
|
||||
|
||||
ret = bdrv_pread(bs->file, 0, s->header_size, s->header, 0);
|
||||
if (ret < 0) {
|
||||
@@ -1101,20 +875,33 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
s->bat_bitmap = (uint32_t *)(s->header + 1);
|
||||
|
||||
if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
|
||||
s->header_unclean = true;
|
||||
for (i = 0; i < s->bat_size; i++) {
|
||||
int64_t off = bat2sect(s, i);
|
||||
if (off >= file_nb_sectors) {
|
||||
if (flags & BDRV_O_CHECK) {
|
||||
continue;
|
||||
}
|
||||
error_setg(errp, "parallels: Offset %" PRIi64 " in BAT[%d] entry "
|
||||
"is larger than file size (%" PRIi64 ")",
|
||||
off << BDRV_SECTOR_BITS, i,
|
||||
file_nb_sectors << BDRV_SECTOR_BITS);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
if (off >= s->data_end) {
|
||||
s->data_end = off + s->tracks;
|
||||
}
|
||||
}
|
||||
|
||||
data_off_is_correct = parallels_test_data_off(s, file_nb_sectors,
|
||||
&data_start);
|
||||
s->data_start = data_start;
|
||||
s->data_end = s->data_start;
|
||||
if (s->data_end < (s->header_size >> BDRV_SECTOR_BITS)) {
|
||||
/*
|
||||
* There is not enough unused space to fit to block align between BAT
|
||||
* and actual data. We can't avoid read-modify-write...
|
||||
*/
|
||||
s->header_size = size;
|
||||
if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
|
||||
/* Image was not closed correctly. The check is mandatory */
|
||||
s->header_unclean = true;
|
||||
if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
|
||||
error_setg(errp, "parallels: Image was not closed correctly; "
|
||||
"cannot be opened read/write");
|
||||
ret = -EACCES;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
opts = qemu_opts_create(¶llels_runtime_opts, NULL, 0, errp);
|
||||
@@ -1175,41 +962,10 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
ret = migrate_add_blocker(s->migration_blocker, errp);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "Migration blocker error");
|
||||
error_free(s->migration_blocker);
|
||||
goto fail;
|
||||
}
|
||||
qemu_co_mutex_init(&s->lock);
|
||||
|
||||
for (i = 0; i < s->bat_size; i++) {
|
||||
sector = bat2sect(s, i);
|
||||
if (sector + s->tracks > s->data_end) {
|
||||
s->data_end = sector + s->tracks;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't repair the image here if it's opened for checks. Also we don't
|
||||
* want to change inactive images and can't change readonly images.
|
||||
*/
|
||||
if ((flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) || !(flags & BDRV_O_RDWR)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Repair the image if it's dirty or
|
||||
* out-of-image corruption was detected.
|
||||
*/
|
||||
if (s->data_end > file_nb_sectors || s->header_unclean
|
||||
|| !data_off_is_correct) {
|
||||
BdrvCheckResult res;
|
||||
ret = bdrv_check(bs, &res, BDRV_FIX_ERRORS | BDRV_FIX_LEAKS);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not repair corrupted image");
|
||||
migrate_del_blocker(s->migration_blocker);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_format:
|
||||
@@ -1217,12 +973,6 @@ fail_format:
|
||||
fail_options:
|
||||
ret = -EINVAL;
|
||||
fail:
|
||||
/*
|
||||
* "s" object was allocated by g_malloc0 so we can safely
|
||||
* try to free its fields even they were not allocated.
|
||||
*/
|
||||
error_free(s->migration_blocker);
|
||||
g_free(s->bat_dirty_bmap);
|
||||
qemu_vfree(s->header);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,6 @@ typedef struct BDRVParallelsState {
|
||||
uint32_t *bat_bitmap;
|
||||
unsigned int bat_size;
|
||||
|
||||
int64_t data_start;
|
||||
int64_t data_end;
|
||||
uint64_t prealloc_size;
|
||||
ParallelsPreallocMode prealloc_mode;
|
||||
|
||||
@@ -5197,7 +5197,6 @@ qcow2_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
bdi->cluster_size = s->cluster_size;
|
||||
bdi->subcluster_size = s->subcluster_size;
|
||||
bdi->vm_state_offset = qcow2_vm_state_offset(s);
|
||||
bdi->is_dirty = s->incompatible_features & QCOW2_INCOMPAT_DIRTY;
|
||||
return 0;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef TARGET_ARCH_ELF_H
|
||||
#define TARGET_ARCH_ELF_H
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
#define ELF_ET_DYN_LOAD_ADDR 0x500000
|
||||
|
||||
#define elf_check_arch(x) ((x) == EM_ARM)
|
||||
|
||||
+4
-2
@@ -51,8 +51,10 @@ do { \
|
||||
unlock_user(p1, arg1, 0); \
|
||||
} while (0)
|
||||
|
||||
struct iovec *lock_iovec(int type, abi_ulong target_addr, int count, int copy);
|
||||
void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count, int copy);
|
||||
extern struct iovec *lock_iovec(int type, abi_ulong target_addr, int count,
|
||||
int copy);
|
||||
extern void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count,
|
||||
int copy);
|
||||
|
||||
int safe_open(const char *path, int flags, mode_t mode);
|
||||
int safe_openat(int fd, const char *path, int flags, mode_t mode);
|
||||
|
||||
+3
-1
@@ -738,6 +738,8 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
|
||||
/* OK, This is the point of no return */
|
||||
info->end_data = 0;
|
||||
info->end_code = 0;
|
||||
info->start_mmap = (abi_ulong)ELF_START_MMAP;
|
||||
info->mmap = 0;
|
||||
elf_entry = (abi_ulong) elf_ex.e_entry;
|
||||
|
||||
/* XXX Join this with PT_INTERP search? */
|
||||
@@ -811,7 +813,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
|
||||
bprm->stringp, &elf_ex, load_addr,
|
||||
et_dyn_addr, interp_load_addr, info);
|
||||
info->load_addr = reloc_func_desc;
|
||||
info->brk = elf_brk;
|
||||
info->start_brk = info->brk = elf_brk;
|
||||
info->start_stack = bprm->p;
|
||||
info->load_bias = 0;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
bsd_user_ss.add(files(
|
||||
'os-stat.c',
|
||||
'os-sys.c',
|
||||
'os-syscall.c',
|
||||
))
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
/*
|
||||
* FreeBSD stat related conversion routines
|
||||
*
|
||||
* Copyright (c) 2013 Stacey D. Son
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "qemu.h"
|
||||
|
||||
/*
|
||||
* stat conversion
|
||||
*/
|
||||
abi_long h2t_freebsd11_stat(abi_ulong target_addr,
|
||||
struct freebsd11_stat *host_st)
|
||||
{
|
||||
struct target_freebsd11_stat *target_st;
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
memset(target_st, 0, sizeof(*target_st));
|
||||
__put_user(host_st->st_dev, &target_st->st_dev);
|
||||
__put_user(host_st->st_ino, &target_st->st_ino);
|
||||
__put_user(host_st->st_mode, &target_st->st_mode);
|
||||
__put_user(host_st->st_nlink, &target_st->st_nlink);
|
||||
__put_user(host_st->st_uid, &target_st->st_uid);
|
||||
__put_user(host_st->st_gid, &target_st->st_gid);
|
||||
__put_user(host_st->st_rdev, &target_st->st_rdev);
|
||||
__put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec);
|
||||
__put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec);
|
||||
__put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec);
|
||||
__put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec);
|
||||
__put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec);
|
||||
__put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec);
|
||||
__put_user(host_st->st_size, &target_st->st_size);
|
||||
__put_user(host_st->st_blocks, &target_st->st_blocks);
|
||||
__put_user(host_st->st_blksize, &target_st->st_blksize);
|
||||
__put_user(host_st->st_flags, &target_st->st_flags);
|
||||
__put_user(host_st->st_gen, &target_st->st_gen);
|
||||
/* st_lspare not used */
|
||||
__put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec);
|
||||
__put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec);
|
||||
unlock_user_struct(target_st, target_addr, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
abi_long h2t_freebsd_stat(abi_ulong target_addr,
|
||||
struct stat *host_st)
|
||||
{
|
||||
struct target_stat *target_st;
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
memset(target_st, 0, sizeof(*target_st));
|
||||
__put_user(host_st->st_dev, &target_st->st_dev);
|
||||
__put_user(host_st->st_ino, &target_st->st_ino);
|
||||
__put_user(host_st->st_nlink, &target_st->st_nlink);
|
||||
__put_user(host_st->st_mode, &target_st->st_mode);
|
||||
__put_user(host_st->st_uid, &target_st->st_uid);
|
||||
__put_user(host_st->st_gid, &target_st->st_gid);
|
||||
__put_user(host_st->st_rdev, &target_st->st_rdev);
|
||||
__put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec);
|
||||
__put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec);
|
||||
#ifdef TARGET_HAS_STAT_TIME_T_EXT
|
||||
/* __put_user(host_st->st_mtim_ext, &target_st->st_mtim_ext); XXX */
|
||||
#endif
|
||||
__put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec);
|
||||
__put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec);
|
||||
#ifdef TARGET_HAS_STAT_TIME_T_EXT
|
||||
/* __put_user(host_st->st_ctim_ext, &target_st->st_ctim_ext); XXX */
|
||||
#endif
|
||||
__put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec);
|
||||
__put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec);
|
||||
#ifdef TARGET_HAS_STAT_TIME_T_EXT
|
||||
/* __put_user(host_st->st_birthtim_ext, &target_st->st_birthtim_ext); XXX */
|
||||
#endif
|
||||
__put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec);
|
||||
__put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec);
|
||||
|
||||
__put_user(host_st->st_size, &target_st->st_size);
|
||||
__put_user(host_st->st_blocks, &target_st->st_blocks);
|
||||
__put_user(host_st->st_blksize, &target_st->st_blksize);
|
||||
__put_user(host_st->st_flags, &target_st->st_flags);
|
||||
__put_user(host_st->st_gen, &target_st->st_gen);
|
||||
unlock_user_struct(target_st, target_addr, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
abi_long h2t_freebsd11_nstat(abi_ulong target_addr,
|
||||
struct freebsd11_stat *host_st)
|
||||
{
|
||||
struct target_freebsd11_nstat *target_st;
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
memset(target_st, 0, sizeof(*target_st));
|
||||
__put_user(host_st->st_dev, &target_st->st_dev);
|
||||
__put_user(host_st->st_ino, &target_st->st_ino);
|
||||
__put_user(host_st->st_mode, &target_st->st_mode);
|
||||
__put_user(host_st->st_nlink, &target_st->st_nlink);
|
||||
__put_user(host_st->st_uid, &target_st->st_uid);
|
||||
__put_user(host_st->st_gid, &target_st->st_gid);
|
||||
__put_user(host_st->st_rdev, &target_st->st_rdev);
|
||||
__put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec);
|
||||
__put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec);
|
||||
__put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec);
|
||||
__put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec);
|
||||
__put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec);
|
||||
__put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec);
|
||||
__put_user(host_st->st_size, &target_st->st_size);
|
||||
__put_user(host_st->st_blocks, &target_st->st_blocks);
|
||||
__put_user(host_st->st_blksize, &target_st->st_blksize);
|
||||
__put_user(host_st->st_flags, &target_st->st_flags);
|
||||
__put_user(host_st->st_gen, &target_st->st_gen);
|
||||
__put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec);
|
||||
__put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec);
|
||||
unlock_user_struct(target_st, target_addr, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* file handle conversion
|
||||
*/
|
||||
abi_long t2h_freebsd_fhandle(fhandle_t *host_fh, abi_ulong target_addr)
|
||||
{
|
||||
target_freebsd_fhandle_t *target_fh;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, target_fh, target_addr, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__get_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]);
|
||||
__get_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]);
|
||||
__get_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len);
|
||||
/* u_short fid_data0; */
|
||||
memcpy(host_fh->fh_fid.fid_data, target_fh->fh_fid.fid_data,
|
||||
TARGET_MAXFIDSZ);
|
||||
unlock_user_struct(target_fh, target_addr, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
abi_long h2t_freebsd_fhandle(abi_ulong target_addr, fhandle_t *host_fh)
|
||||
{
|
||||
target_freebsd_fhandle_t *target_fh;
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_fh, target_addr, 0)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__put_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]);
|
||||
__put_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]);
|
||||
__put_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len);
|
||||
/* u_short fid_data0; */
|
||||
memcpy(target_fh->fh_fid.fid_data, host_fh->fh_fid.fid_data,
|
||||
TARGET_MAXFIDSZ);
|
||||
unlock_user_struct(target_fh, target_addr, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* file system stat
|
||||
*/
|
||||
abi_long h2t_freebsd11_statfs(abi_ulong target_addr,
|
||||
struct freebsd11_statfs *host_statfs)
|
||||
{
|
||||
struct target_freebsd11_statfs *target_statfs;
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_statfs, target_addr, 0)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__put_user(host_statfs->f_version, &target_statfs->f_version);
|
||||
__put_user(host_statfs->f_type, &target_statfs->f_type);
|
||||
__put_user(host_statfs->f_flags, &target_statfs->f_flags);
|
||||
__put_user(host_statfs->f_bsize, &target_statfs->f_bsize);
|
||||
__put_user(host_statfs->f_iosize, &target_statfs->f_iosize);
|
||||
__put_user(host_statfs->f_blocks, &target_statfs->f_blocks);
|
||||
__put_user(host_statfs->f_bfree, &target_statfs->f_bfree);
|
||||
__put_user(host_statfs->f_bavail, &target_statfs->f_bavail);
|
||||
__put_user(host_statfs->f_files, &target_statfs->f_files);
|
||||
__put_user(host_statfs->f_ffree, &target_statfs->f_ffree);
|
||||
__put_user(host_statfs->f_syncwrites, &target_statfs->f_syncwrites);
|
||||
__put_user(host_statfs->f_asyncwrites, &target_statfs->f_asyncwrites);
|
||||
__put_user(host_statfs->f_syncreads, &target_statfs->f_syncreads);
|
||||
__put_user(host_statfs->f_asyncreads, &target_statfs->f_asyncreads);
|
||||
/* uint64_t f_spare[10]; */
|
||||
__put_user(host_statfs->f_namemax, &target_statfs->f_namemax);
|
||||
__put_user(host_statfs->f_owner, &target_statfs->f_owner);
|
||||
__put_user(host_statfs->f_fsid.val[0], &target_statfs->f_fsid.val[0]);
|
||||
__put_user(host_statfs->f_fsid.val[1], &target_statfs->f_fsid.val[1]);
|
||||
/* char f_charspace[80]; */
|
||||
strncpy(target_statfs->f_fstypename, host_statfs->f_fstypename,
|
||||
sizeof(target_statfs->f_fstypename));
|
||||
strncpy(target_statfs->f_mntfromname, host_statfs->f_mntfromname,
|
||||
sizeof(target_statfs->f_mntfromname));
|
||||
strncpy(target_statfs->f_mntonname, host_statfs->f_mntonname,
|
||||
sizeof(target_statfs->f_mntonname));
|
||||
unlock_user_struct(target_statfs, target_addr, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
abi_long h2t_freebsd_statfs(abi_ulong target_addr,
|
||||
struct statfs *host_statfs)
|
||||
{
|
||||
struct target_statfs *target_statfs;
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_statfs, target_addr, 0)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__put_user(host_statfs->f_version, &target_statfs->f_version);
|
||||
__put_user(host_statfs->f_type, &target_statfs->f_type);
|
||||
__put_user(host_statfs->f_flags, &target_statfs->f_flags);
|
||||
__put_user(host_statfs->f_bsize, &target_statfs->f_bsize);
|
||||
__put_user(host_statfs->f_iosize, &target_statfs->f_iosize);
|
||||
__put_user(host_statfs->f_blocks, &target_statfs->f_blocks);
|
||||
__put_user(host_statfs->f_bfree, &target_statfs->f_bfree);
|
||||
__put_user(host_statfs->f_bavail, &target_statfs->f_bavail);
|
||||
__put_user(host_statfs->f_files, &target_statfs->f_files);
|
||||
__put_user(host_statfs->f_ffree, &target_statfs->f_ffree);
|
||||
__put_user(host_statfs->f_syncwrites, &target_statfs->f_syncwrites);
|
||||
__put_user(host_statfs->f_asyncwrites, &target_statfs->f_asyncwrites);
|
||||
__put_user(host_statfs->f_syncreads, &target_statfs->f_syncreads);
|
||||
__put_user(host_statfs->f_asyncreads, &target_statfs->f_asyncreads);
|
||||
/* uint64_t f_spare[10]; */
|
||||
__put_user(host_statfs->f_namemax, &target_statfs->f_namemax);
|
||||
__put_user(host_statfs->f_owner, &target_statfs->f_owner);
|
||||
__put_user(host_statfs->f_fsid.val[0], &target_statfs->f_fsid.val[0]);
|
||||
__put_user(host_statfs->f_fsid.val[1], &target_statfs->f_fsid.val[1]);
|
||||
/* char f_charspace[80]; */
|
||||
strncpy(target_statfs->f_fstypename, host_statfs->f_fstypename,
|
||||
sizeof(target_statfs->f_fstypename));
|
||||
strncpy(target_statfs->f_mntfromname, host_statfs->f_mntfromname,
|
||||
sizeof(target_statfs->f_mntfromname));
|
||||
strncpy(target_statfs->f_mntonname, host_statfs->f_mntonname,
|
||||
sizeof(target_statfs->f_mntonname));
|
||||
unlock_user_struct(target_statfs, target_addr, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* fcntl cmd conversion
|
||||
*/
|
||||
abi_long target_to_host_fcntl_cmd(int cmd)
|
||||
{
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@@ -1,663 +0,0 @@
|
||||
/*
|
||||
* stat related system call shims and definitions
|
||||
*
|
||||
* Copyright (c) 2013 Stacey D. Son
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BSD_USER_FREEBSD_OS_STAT_H
|
||||
#define BSD_USER_FREEBSD_OS_STAT_H
|
||||
|
||||
int freebsd11_stat(const char *path, struct freebsd11_stat *stat);
|
||||
__sym_compat(stat, freebsd11_stat, FBSD_1.0);
|
||||
int freebsd11_lstat(const char *path, struct freebsd11_stat *stat);
|
||||
__sym_compat(lstat, freebsd11_lstat, FBSD_1.0);
|
||||
int freebsd11_fstat(int fd, struct freebsd11_stat *stat);
|
||||
__sym_compat(fstat, freebsd11_fstat, FBSD_1.0);
|
||||
int freebsd11_fstatat(int fd, const char *path, struct freebsd11_stat *stat,
|
||||
int flag);
|
||||
__sym_compat(fstatat, freebsd11_fstatat, FBSD_1.1);
|
||||
|
||||
int freebsd11_fhstat(const fhandle_t *fhandle, struct freebsd11_stat *stat);
|
||||
__sym_compat(fhstat, freebsd11_fhstat, FBSD_1.0);
|
||||
int freebsd11_getfsstat(struct freebsd11_statfs *buf, long bufsize, int mode);
|
||||
__sym_compat(getfsstat, freebsd11_getfsstat, FBSD_1.0);
|
||||
int freebsd11_fhstatfs(const fhandle_t *fhandle, struct freebsd11_statfs * buf);
|
||||
__sym_compat(fhstatfs, freebsd11_fhstatfs, FBSD_1.0);
|
||||
int freebsd11_statfs(const char *path, struct freebsd11_statfs *buf);
|
||||
__sym_compat(statfs, freebsd11_statfs, FBSD_1.0);
|
||||
int freebsd11_fstatfs(int fd, struct freebsd11_statfs *buf);
|
||||
__sym_compat(fstatfs, freebsd11_fstatfs, FBSD_1.0);
|
||||
|
||||
ssize_t freebsd11_getdirentries(int fd, char *buf, size_t nbytes, off_t *basep);
|
||||
__sym_compat(getdirentries, freebsd11_getdirentries, FBSD_1.0);
|
||||
ssize_t freebsd11_getdents(int fd, char *buf, size_t nbytes);
|
||||
__sym_compat(getdents, freebsd11_getdents, FBSD_1.0);
|
||||
|
||||
/* undocumented nstat system calls */
|
||||
int freebsd11_nstat(const char *path, struct freebsd11_stat *sb);
|
||||
__sym_compat(nstat, freebsd11_nstat, FBSD_1.0);
|
||||
int freebsd11_nlstat(const char *path, struct freebsd11_stat *sb);
|
||||
__sym_compat(nlstat, freebsd11_nlstat, FBSD_1.0);
|
||||
int freebsd11_nfstat(int fd, struct freebsd11_stat *sb);
|
||||
__sym_compat(nfstat, freebsd11_nfstat, FBSD_1.0);
|
||||
|
||||
/* stat(2) */
|
||||
static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct freebsd11_stat st;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(freebsd11_stat(path(p), &st));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (!is_error(ret)) {
|
||||
ret = h2t_freebsd11_stat(arg2, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* lstat(2) */
|
||||
static inline abi_long do_freebsd11_lstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct freebsd11_stat st;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(freebsd11_lstat(path(p), &st));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (!is_error(ret)) {
|
||||
ret = h2t_freebsd11_stat(arg2, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* fstat(2) */
|
||||
static inline abi_long do_freebsd11_fstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
struct freebsd11_stat st;
|
||||
|
||||
ret = get_errno(freebsd11_fstat(arg1, &st));
|
||||
if (!is_error(ret)) {
|
||||
ret = h2t_freebsd11_stat(arg2, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* fstat(2) */
|
||||
static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
struct stat st;
|
||||
|
||||
ret = get_errno(fstat(arg1, &st));
|
||||
if (!is_error(ret)) {
|
||||
ret = h2t_freebsd_stat(arg2, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* fstatat(2) */
|
||||
static inline abi_long do_freebsd11_fstatat(abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct freebsd11_stat st;
|
||||
|
||||
LOCK_PATH(p, arg2);
|
||||
ret = get_errno(freebsd11_fstatat(arg1, p, &st, arg4));
|
||||
UNLOCK_PATH(p, arg2);
|
||||
if (!is_error(ret) && arg3) {
|
||||
ret = h2t_freebsd11_stat(arg3, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* fstatat(2) */
|
||||
static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct stat st;
|
||||
|
||||
LOCK_PATH(p, arg2);
|
||||
ret = get_errno(fstatat(arg1, p, &st, arg4));
|
||||
UNLOCK_PATH(p, arg2);
|
||||
if (!is_error(ret) && arg3) {
|
||||
ret = h2t_freebsd_stat(arg3, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* undocummented nstat(char *path, struct nstat *ub) syscall */
|
||||
static abi_long do_freebsd11_nstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct freebsd11_stat st;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(freebsd11_nstat(path(p), &st));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (!is_error(ret)) {
|
||||
ret = h2t_freebsd11_nstat(arg2, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* undocummented nfstat(int fd, struct nstat *sb) syscall */
|
||||
static abi_long do_freebsd11_nfstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
struct freebsd11_stat st;
|
||||
|
||||
ret = get_errno(freebsd11_nfstat(arg1, &st));
|
||||
if (!is_error(ret)) {
|
||||
ret = h2t_freebsd11_nstat(arg2, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* undocummented nlstat(char *path, struct nstat *ub) syscall */
|
||||
static abi_long do_freebsd11_nlstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct freebsd11_stat st;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(freebsd11_nlstat(path(p), &st));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (!is_error(ret)) {
|
||||
ret = h2t_freebsd11_nstat(arg2, &st);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* getfh(2) */
|
||||
static abi_long do_freebsd_getfh(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
fhandle_t host_fh;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(getfh(path(p), &host_fh));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
return h2t_freebsd_fhandle(arg2, &host_fh);
|
||||
}
|
||||
|
||||
/* lgetfh(2) */
|
||||
static inline abi_long do_freebsd_lgetfh(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
fhandle_t host_fh;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(lgetfh(path(p), &host_fh));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
return h2t_freebsd_fhandle(arg2, &host_fh);
|
||||
}
|
||||
|
||||
/* fhopen(2) */
|
||||
static inline abi_long do_freebsd_fhopen(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
fhandle_t host_fh;
|
||||
|
||||
ret = t2h_freebsd_fhandle(&host_fh, arg1);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return get_errno(fhopen(&host_fh, arg2));
|
||||
}
|
||||
|
||||
/* fhstat(2) */
|
||||
static inline abi_long do_freebsd11_fhstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
fhandle_t host_fh;
|
||||
struct freebsd11_stat host_sb;
|
||||
|
||||
ret = t2h_freebsd_fhandle(&host_fh, arg1);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
ret = get_errno(freebsd11_fhstat(&host_fh, &host_sb));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
return h2t_freebsd11_stat(arg2, &host_sb);
|
||||
}
|
||||
|
||||
/* fhstat(2) */
|
||||
static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
fhandle_t host_fh;
|
||||
struct stat host_sb;
|
||||
|
||||
ret = t2h_freebsd_fhandle(&host_fh, arg1);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
ret = get_errno(fhstat(&host_fh, &host_sb));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
return h2t_freebsd_stat(arg2, &host_sb);
|
||||
}
|
||||
|
||||
/* fhstatfs(2) */
|
||||
static inline abi_long do_freebsd11_fhstatfs(abi_ulong target_fhp_addr,
|
||||
abi_ulong target_stfs_addr)
|
||||
{
|
||||
abi_long ret;
|
||||
fhandle_t host_fh;
|
||||
struct freebsd11_statfs host_stfs;
|
||||
|
||||
ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
ret = get_errno(freebsd11_fhstatfs(&host_fh, &host_stfs));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
return h2t_freebsd11_statfs(target_stfs_addr, &host_stfs);
|
||||
}
|
||||
|
||||
/* fhstatfs(2) */
|
||||
static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr,
|
||||
abi_ulong target_stfs_addr)
|
||||
{
|
||||
abi_long ret;
|
||||
fhandle_t host_fh;
|
||||
struct statfs host_stfs;
|
||||
|
||||
ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
ret = get_errno(fhstatfs(&host_fh, &host_stfs));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
return h2t_freebsd_statfs(target_stfs_addr, &host_stfs);
|
||||
}
|
||||
|
||||
/* statfs(2) */
|
||||
static inline abi_long do_freebsd11_statfs(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct freebsd11_statfs host_stfs;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(freebsd11_statfs(path(p), &host_stfs));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return h2t_freebsd11_statfs(arg2, &host_stfs);
|
||||
}
|
||||
|
||||
/* statfs(2) */
|
||||
static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p;
|
||||
struct statfs host_stfs;
|
||||
|
||||
LOCK_PATH(p, arg1);
|
||||
ret = get_errno(statfs(path(p), &host_stfs));
|
||||
UNLOCK_PATH(p, arg1);
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return h2t_freebsd_statfs(arg2, &host_stfs);
|
||||
}
|
||||
|
||||
/* fstatfs(2) */
|
||||
static inline abi_long do_freebsd11_fstatfs(abi_long fd, abi_ulong target_addr)
|
||||
{
|
||||
abi_long ret;
|
||||
struct freebsd11_statfs host_stfs;
|
||||
|
||||
ret = get_errno(freebsd11_fstatfs(fd, &host_stfs));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return h2t_freebsd11_statfs(target_addr, &host_stfs);
|
||||
}
|
||||
|
||||
/* fstatfs(2) */
|
||||
static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr)
|
||||
{
|
||||
abi_long ret;
|
||||
struct statfs host_stfs;
|
||||
|
||||
ret = get_errno(fstatfs(fd, &host_stfs));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return h2t_freebsd_statfs(target_addr, &host_stfs);
|
||||
}
|
||||
|
||||
/* getfsstat(2) */
|
||||
static inline abi_long do_freebsd11_getfsstat(abi_ulong target_addr,
|
||||
abi_long bufsize, abi_long flags)
|
||||
{
|
||||
abi_long ret;
|
||||
struct freebsd11_statfs *host_stfs;
|
||||
int count;
|
||||
long host_bufsize;
|
||||
|
||||
count = bufsize / sizeof(struct target_freebsd11_statfs);
|
||||
|
||||
/* if user buffer is NULL then return number of mounted FS's */
|
||||
if (target_addr == 0 || count == 0) {
|
||||
return get_errno(freebsd11_getfsstat(NULL, 0, flags));
|
||||
}
|
||||
|
||||
/* XXX check count to be reasonable */
|
||||
host_bufsize = sizeof(struct freebsd11_statfs) * count;
|
||||
host_stfs = alloca(host_bufsize);
|
||||
if (!host_stfs) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
ret = count = get_errno(freebsd11_getfsstat(host_stfs, host_bufsize, flags));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
if (h2t_freebsd11_statfs((target_addr +
|
||||
(count * sizeof(struct target_freebsd11_statfs))),
|
||||
&host_stfs[count])) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* getfsstat(2) */
|
||||
static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr,
|
||||
abi_long bufsize, abi_long flags)
|
||||
{
|
||||
abi_long ret;
|
||||
struct statfs *host_stfs;
|
||||
int count;
|
||||
long host_bufsize;
|
||||
|
||||
count = bufsize / sizeof(struct target_statfs);
|
||||
|
||||
/* if user buffer is NULL then return number of mounted FS's */
|
||||
if (target_addr == 0 || count == 0) {
|
||||
return get_errno(freebsd11_getfsstat(NULL, 0, flags));
|
||||
}
|
||||
|
||||
/* XXX check count to be reasonable */
|
||||
host_bufsize = sizeof(struct statfs) * count;
|
||||
host_stfs = alloca(host_bufsize);
|
||||
if (!host_stfs) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
ret = count = get_errno(getfsstat(host_stfs, host_bufsize, flags));
|
||||
if (is_error(ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
if (h2t_freebsd_statfs((target_addr +
|
||||
(count * sizeof(struct target_statfs))),
|
||||
&host_stfs[count])) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* getdents(2) */
|
||||
static inline abi_long do_freebsd11_getdents(abi_long arg1,
|
||||
abi_ulong arg2, abi_long nbytes)
|
||||
{
|
||||
abi_long ret;
|
||||
struct freebsd11_dirent *dirp;
|
||||
|
||||
dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
|
||||
if (dirp == NULL) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(freebsd11_getdents(arg1, (char *)dirp, nbytes));
|
||||
if (!is_error(ret)) {
|
||||
struct freebsd11_dirent *de;
|
||||
int len = ret;
|
||||
int reclen;
|
||||
|
||||
de = dirp;
|
||||
while (len > 0) {
|
||||
reclen = de->d_reclen;
|
||||
if (reclen > len) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
de->d_reclen = tswap16(reclen);
|
||||
de->d_fileno = tswap32(de->d_fileno);
|
||||
len -= reclen;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* getdirecentries(2) */
|
||||
static inline abi_long do_freebsd11_getdirentries(abi_long arg1,
|
||||
abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
|
||||
{
|
||||
abi_long ret;
|
||||
struct freebsd11_dirent *dirp;
|
||||
long basep;
|
||||
|
||||
dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
|
||||
if (dirp == NULL) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(freebsd11_getdirentries(arg1, (char *)dirp, nbytes, &basep));
|
||||
if (!is_error(ret)) {
|
||||
struct freebsd11_dirent *de;
|
||||
int len = ret;
|
||||
int reclen;
|
||||
|
||||
de = dirp;
|
||||
while (len > 0) {
|
||||
reclen = de->d_reclen;
|
||||
if (reclen > len) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
de->d_reclen = tswap16(reclen);
|
||||
de->d_fileno = tswap32(de->d_fileno);
|
||||
len -= reclen;
|
||||
de = (struct freebsd11_dirent *)((void *)de + reclen);
|
||||
}
|
||||
}
|
||||
unlock_user(dirp, arg2, ret);
|
||||
if (arg4) {
|
||||
if (put_user(basep, arg4, abi_ulong)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* getdirecentries(2) */
|
||||
static inline abi_long do_freebsd_getdirentries(abi_long arg1,
|
||||
abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
|
||||
{
|
||||
abi_long ret;
|
||||
struct dirent *dirp;
|
||||
long basep;
|
||||
|
||||
dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
|
||||
if (dirp == NULL) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(getdirentries(arg1, (char *)dirp, nbytes, &basep));
|
||||
if (!is_error(ret)) {
|
||||
struct dirent *de;
|
||||
int len = ret;
|
||||
int reclen;
|
||||
|
||||
de = dirp;
|
||||
while (len > 0) {
|
||||
reclen = de->d_reclen;
|
||||
if (reclen > len) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
de->d_fileno = tswap64(de->d_fileno);
|
||||
de->d_off = tswap64(de->d_off);
|
||||
de->d_reclen = tswap16(de->d_reclen);
|
||||
de->d_namlen = tswap16(de->d_namlen);
|
||||
len -= reclen;
|
||||
de = (struct dirent *)((void *)de + reclen);
|
||||
}
|
||||
}
|
||||
unlock_user(dirp, arg2, ret);
|
||||
if (arg4) {
|
||||
if (put_user(basep, arg4, abi_ulong)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* fcntl(2) */
|
||||
static inline abi_long do_freebsd_fcntl(abi_long arg1, abi_long arg2,
|
||||
abi_ulong arg3)
|
||||
{
|
||||
abi_long ret;
|
||||
int host_cmd;
|
||||
struct flock fl;
|
||||
struct target_freebsd_flock *target_fl;
|
||||
|
||||
host_cmd = target_to_host_fcntl_cmd(arg2);
|
||||
if (host_cmd < 0) {
|
||||
return host_cmd;
|
||||
}
|
||||
switch (arg2) {
|
||||
case TARGET_F_GETLK:
|
||||
if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__get_user(fl.l_type, &target_fl->l_type);
|
||||
__get_user(fl.l_whence, &target_fl->l_whence);
|
||||
__get_user(fl.l_start, &target_fl->l_start);
|
||||
__get_user(fl.l_len, &target_fl->l_len);
|
||||
__get_user(fl.l_pid, &target_fl->l_pid);
|
||||
__get_user(fl.l_sysid, &target_fl->l_sysid);
|
||||
unlock_user_struct(target_fl, arg3, 0);
|
||||
ret = get_errno(safe_fcntl(arg1, host_cmd, &fl));
|
||||
if (!is_error(ret)) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__put_user(fl.l_type, &target_fl->l_type);
|
||||
__put_user(fl.l_whence, &target_fl->l_whence);
|
||||
__put_user(fl.l_start, &target_fl->l_start);
|
||||
__put_user(fl.l_len, &target_fl->l_len);
|
||||
__put_user(fl.l_pid, &target_fl->l_pid);
|
||||
__put_user(fl.l_sysid, &target_fl->l_sysid);
|
||||
unlock_user_struct(target_fl, arg3, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_F_SETLK:
|
||||
case TARGET_F_SETLKW:
|
||||
if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
__get_user(fl.l_type, &target_fl->l_type);
|
||||
__get_user(fl.l_whence, &target_fl->l_whence);
|
||||
__get_user(fl.l_start, &target_fl->l_start);
|
||||
__get_user(fl.l_len, &target_fl->l_len);
|
||||
__get_user(fl.l_pid, &target_fl->l_pid);
|
||||
__get_user(fl.l_sysid, &target_fl->l_sysid);
|
||||
unlock_user_struct(target_fl, arg3, 0);
|
||||
ret = get_errno(safe_fcntl(arg1, host_cmd, &fl));
|
||||
break;
|
||||
|
||||
case TARGET_F_DUPFD:
|
||||
case TARGET_F_DUP2FD:
|
||||
case TARGET_F_GETOWN:
|
||||
case TARGET_F_SETOWN:
|
||||
case TARGET_F_GETFD:
|
||||
case TARGET_F_SETFD:
|
||||
case TARGET_F_GETFL:
|
||||
case TARGET_F_SETFL:
|
||||
case TARGET_F_READAHEAD:
|
||||
case TARGET_F_RDAHEAD:
|
||||
case TARGET_F_ADD_SEALS:
|
||||
case TARGET_F_GET_SEALS:
|
||||
default:
|
||||
ret = get_errno(safe_fcntl(arg1, host_cmd, arg3));
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version >= 1300080
|
||||
extern int __realpathat(int fd, const char *path, char *buf, size_t size,
|
||||
int flags);
|
||||
/* https://svnweb.freebsd.org/base?view=revision&revision=358172 */
|
||||
/* no man page */
|
||||
static inline abi_long do_freebsd_realpathat(abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
abi_long ret;
|
||||
void *p, *b;
|
||||
|
||||
LOCK_PATH(p, arg2);
|
||||
b = lock_user(VERIFY_WRITE, arg3, arg4, 0);
|
||||
if (b == NULL) {
|
||||
UNLOCK_PATH(p, arg2);
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
ret = get_errno(__realpathat(arg1, p, b, arg4, arg5));
|
||||
UNLOCK_PATH(p, arg2);
|
||||
unlock_user(b, arg3, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSD_USER_FREEBSD_OS_STAT_H */
|
||||
+11
-111
@@ -17,6 +17,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We need the FreeBSD "legacy" definitions. Rust needs the FreeBSD 11 system
|
||||
* calls since it doesn't use libc at all, so we have to emulate that despite
|
||||
* FreeBSD 11 being EOL'd.
|
||||
*/
|
||||
#define _WANT_FREEBSD11_STAT
|
||||
#define _WANT_FREEBSD11_STATFS
|
||||
#define _WANT_FREEBSD11_DIRENT
|
||||
#define _WANT_KERNEL_ERRNO
|
||||
#define _WANT_SEMUN
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/path.h"
|
||||
@@ -36,9 +47,6 @@
|
||||
#include "bsd-file.h"
|
||||
#include "bsd-proc.h"
|
||||
|
||||
/* *BSD dependent syscall shims */
|
||||
#include "os-stat.h"
|
||||
|
||||
/* I/O */
|
||||
safe_syscall3(int, open, const char *, path, int, flags, mode_t, mode);
|
||||
safe_syscall4(int, openat, int, fd, const char *, path, int, flags, mode_t,
|
||||
@@ -240,7 +248,6 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
|
||||
case TARGET_FREEBSD_NR_preadv: /* preadv(2) */
|
||||
ret = do_bsd_preadv(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_write: /* write(2) */
|
||||
ret = do_bsd_write(arg1, arg2, arg3);
|
||||
@@ -486,113 +493,6 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
ret = do_bsd_undelete(arg1);
|
||||
break;
|
||||
|
||||
/*
|
||||
* stat system calls
|
||||
*/
|
||||
case TARGET_FREEBSD_NR_freebsd11_stat: /* stat(2) */
|
||||
ret = do_freebsd11_stat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_lstat: /* lstat(2) */
|
||||
ret = do_freebsd11_lstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_fstat: /* fstat(2) */
|
||||
ret = do_freebsd11_fstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_fstat: /* fstat(2) */
|
||||
ret = do_freebsd_fstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_fstatat: /* fstatat(2) */
|
||||
ret = do_freebsd11_fstatat(arg1, arg2, arg3, arg4);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_fstatat: /* fstatat(2) */
|
||||
ret = do_freebsd_fstatat(arg1, arg2, arg3, arg4);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_nstat: /* undocumented */
|
||||
ret = do_freebsd11_nstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_nfstat: /* undocumented */
|
||||
ret = do_freebsd11_nfstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_nlstat: /* undocumented */
|
||||
ret = do_freebsd11_nlstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_getfh: /* getfh(2) */
|
||||
ret = do_freebsd_getfh(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_lgetfh: /* lgetfh(2) */
|
||||
ret = do_freebsd_lgetfh(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_fhopen: /* fhopen(2) */
|
||||
ret = do_freebsd_fhopen(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_fhstat: /* fhstat(2) */
|
||||
ret = do_freebsd11_fhstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_fhstat: /* fhstat(2) */
|
||||
ret = do_freebsd_fhstat(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_fhstatfs: /* fhstatfs(2) */
|
||||
ret = do_freebsd11_fhstatfs(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_fhstatfs: /* fhstatfs(2) */
|
||||
ret = do_freebsd_fhstatfs(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_statfs: /* statfs(2) */
|
||||
ret = do_freebsd11_statfs(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_statfs: /* statfs(2) */
|
||||
ret = do_freebsd_statfs(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_fstatfs: /* fstatfs(2) */
|
||||
ret = do_freebsd11_fstatfs(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_fstatfs: /* fstatfs(2) */
|
||||
ret = do_freebsd_fstatfs(arg1, arg2);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_getfsstat: /* getfsstat(2) */
|
||||
ret = do_freebsd11_getfsstat(arg1, arg2, arg3);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_getfsstat: /* getfsstat(2) */
|
||||
ret = do_freebsd_getfsstat(arg1, arg2, arg3);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_getdents: /* getdents(2) */
|
||||
ret = do_freebsd11_getdents(arg1, arg2, arg3);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_getdirentries: /* getdirentries(2) */
|
||||
ret = do_freebsd_getdirentries(arg1, arg2, arg3, arg4);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_freebsd11_getdirentries: /* getdirentries(2) */
|
||||
ret = do_freebsd11_getdirentries(arg1, arg2, arg3, arg4);
|
||||
break;
|
||||
case TARGET_FREEBSD_NR_fcntl: /* fcntl(2) */
|
||||
ret = do_freebsd_fcntl(arg1, arg2, arg3);
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
* sys{ctl, arch, call}
|
||||
*/
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* FreeBSD conversion extern declarations
|
||||
*
|
||||
* Copyright (c) 2013 Stacey D. Son
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QEMU_OS_H
|
||||
#define QEMU_OS_H
|
||||
|
||||
/* qemu/osdep.h pulls in the rest */
|
||||
|
||||
#include <sys/acl.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/timex.h>
|
||||
#include <sys/rtprio.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
struct freebsd11_stat;
|
||||
|
||||
/* os-stat.c */
|
||||
abi_long h2t_freebsd11_stat(abi_ulong target_addr,
|
||||
struct freebsd11_stat *host_st);
|
||||
abi_long h2t_freebsd11_nstat(abi_ulong target_addr,
|
||||
struct freebsd11_stat *host_st);
|
||||
abi_long t2h_freebsd_fhandle(fhandle_t *host_fh, abi_ulong target_addr);
|
||||
abi_long h2t_freebsd_fhandle(abi_ulong target_addr, fhandle_t *host_fh);
|
||||
abi_long h2t_freebsd11_statfs(abi_ulong target_addr,
|
||||
struct freebsd11_statfs *host_statfs);
|
||||
abi_long target_to_host_fcntl_cmd(int cmd);
|
||||
abi_long h2t_freebsd_stat(abi_ulong target_addr,
|
||||
struct stat *host_st);
|
||||
abi_long h2t_freebsd_statfs(abi_ulong target_addr,
|
||||
struct statfs *host_statfs);
|
||||
|
||||
#endif /* QEMU_OS_H */
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef TARGET_ARCH_ELF_H
|
||||
#define TARGET_ARCH_ELF_H
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
#define ELF_ET_DYN_LOAD_ADDR 0x01001000
|
||||
#define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
|
||||
|
||||
|
||||
@@ -553,6 +553,8 @@ int main(int argc, char **argv)
|
||||
fprintf(f, "page layout changed following binary load\n");
|
||||
page_dump(f);
|
||||
|
||||
fprintf(f, "start_brk 0x" TARGET_ABI_FMT_lx "\n",
|
||||
info->start_brk);
|
||||
fprintf(f, "end_code 0x" TARGET_ABI_FMT_lx "\n",
|
||||
info->end_code);
|
||||
fprintf(f, "start_code 0x" TARGET_ABI_FMT_lx "\n",
|
||||
|
||||
+50
-62
@@ -38,7 +38,6 @@ extern char **environ;
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/clang-tsa.h"
|
||||
|
||||
#include "qemu-os.h"
|
||||
/*
|
||||
* This struct is used to hold certain information about the image. Basically,
|
||||
* it replicates in user space what would be certain task_struct fields in the
|
||||
@@ -51,7 +50,10 @@ struct image_info {
|
||||
abi_ulong end_code;
|
||||
abi_ulong start_data;
|
||||
abi_ulong end_data;
|
||||
abi_ulong start_brk;
|
||||
abi_ulong brk;
|
||||
abi_ulong start_mmap;
|
||||
abi_ulong mmap;
|
||||
abi_ulong rss;
|
||||
abi_ulong start_stack;
|
||||
abi_ulong entry;
|
||||
@@ -273,64 +275,50 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||
* These are usually used to access struct data members once the struct has been
|
||||
* locked - usually with lock_user_struct().
|
||||
*/
|
||||
#define __put_user(x, hptr)\
|
||||
({\
|
||||
int size = sizeof(*hptr);\
|
||||
switch (size) {\
|
||||
case 1:\
|
||||
*(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
|
||||
break;\
|
||||
case 2:\
|
||||
*(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
|
||||
break;\
|
||||
case 4:\
|
||||
*(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
|
||||
break;\
|
||||
case 8:\
|
||||
*(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
|
||||
break;\
|
||||
default:\
|
||||
abort();\
|
||||
} \
|
||||
0;\
|
||||
})
|
||||
|
||||
/*
|
||||
* Tricky points:
|
||||
* - Use __builtin_choose_expr to avoid type promotion from ?:,
|
||||
* - Invalid sizes result in a compile time error stemming from
|
||||
* the fact that abort has no parameters.
|
||||
* - It's easier to use the endian-specific unaligned load/store
|
||||
* functions than host-endian unaligned load/store plus tswapN.
|
||||
* - The pragmas are necessary only to silence a clang false-positive
|
||||
* warning: see https://bugs.llvm.org/show_bug.cgi?id=39113 .
|
||||
* - gcc has bugs in its _Pragma() support in some versions, eg
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83256 -- so we only
|
||||
* include the warning-suppression pragmas for clang
|
||||
*/
|
||||
#if defined(__clang__) && __has_warning("-Waddress-of-packed-member")
|
||||
#define PRAGMA_DISABLE_PACKED_WARNING \
|
||||
_Pragma("GCC diagnostic push"); \
|
||||
_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"")
|
||||
|
||||
#define PRAGMA_REENABLE_PACKED_WARNING \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
|
||||
#else
|
||||
#define PRAGMA_DISABLE_PACKED_WARNING
|
||||
#define PRAGMA_REENABLE_PACKED_WARNING
|
||||
#endif
|
||||
|
||||
#define __put_user_e(x, hptr, e) \
|
||||
do { \
|
||||
PRAGMA_DISABLE_PACKED_WARNING; \
|
||||
(__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \
|
||||
__builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \
|
||||
__builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \
|
||||
__builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \
|
||||
((hptr), (x)), (void)0); \
|
||||
PRAGMA_REENABLE_PACKED_WARNING; \
|
||||
} while (0)
|
||||
|
||||
#define __get_user_e(x, hptr, e) \
|
||||
do { \
|
||||
PRAGMA_DISABLE_PACKED_WARNING; \
|
||||
((x) = (typeof(*hptr))( \
|
||||
__builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \
|
||||
__builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \
|
||||
__builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \
|
||||
__builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \
|
||||
(hptr)), (void)0); \
|
||||
PRAGMA_REENABLE_PACKED_WARNING; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#if TARGET_BIG_ENDIAN
|
||||
# define __put_user(x, hptr) __put_user_e(x, hptr, be)
|
||||
# define __get_user(x, hptr) __get_user_e(x, hptr, be)
|
||||
#else
|
||||
# define __put_user(x, hptr) __put_user_e(x, hptr, le)
|
||||
# define __get_user(x, hptr) __get_user_e(x, hptr, le)
|
||||
#endif
|
||||
#define __get_user(x, hptr) \
|
||||
({\
|
||||
int size = sizeof(*hptr);\
|
||||
switch (size) {\
|
||||
case 1:\
|
||||
x = (typeof(*hptr))*(uint8_t *)(hptr);\
|
||||
break;\
|
||||
case 2:\
|
||||
x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
|
||||
break;\
|
||||
case 4:\
|
||||
x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
|
||||
break;\
|
||||
case 8:\
|
||||
x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
|
||||
break;\
|
||||
default:\
|
||||
x = 0;\
|
||||
abort();\
|
||||
} \
|
||||
0;\
|
||||
})
|
||||
|
||||
/*
|
||||
* put_user()/get_user() take a guest address and check access
|
||||
@@ -343,10 +331,10 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||
({ \
|
||||
abi_ulong __gaddr = (gaddr); \
|
||||
target_type *__hptr; \
|
||||
abi_long __ret = 0; \
|
||||
abi_long __ret; \
|
||||
__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0); \
|
||||
if (__hptr) { \
|
||||
__put_user((x), __hptr); \
|
||||
__ret = __put_user((x), __hptr); \
|
||||
unlock_user(__hptr, __gaddr, sizeof(target_type)); \
|
||||
} else \
|
||||
__ret = -TARGET_EFAULT; \
|
||||
@@ -357,10 +345,10 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||
({ \
|
||||
abi_ulong __gaddr = (gaddr); \
|
||||
target_type *__hptr; \
|
||||
abi_long __ret = 0; \
|
||||
abi_long __ret; \
|
||||
__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1); \
|
||||
if (__hptr) { \
|
||||
__get_user((x), __hptr); \
|
||||
__ret = __get_user((x), __hptr); \
|
||||
unlock_user(__hptr, __gaddr, 0); \
|
||||
} else { \
|
||||
(x) = 0; \
|
||||
|
||||
+4
-1
@@ -787,7 +787,10 @@ static int reset_signal_mask(target_ucontext_t *ucontext)
|
||||
TaskState *ts = (TaskState *)thread_cpu->opaque;
|
||||
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
__get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i]);
|
||||
if (__get_user(target_set.__bits[i],
|
||||
&ucontext->uc_sigmask.__bits[i])) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
target_to_host_sigset_internal(&blocked, &target_set);
|
||||
ts->signal_mask = blocked;
|
||||
|
||||
+4
-217
@@ -45,9 +45,9 @@
|
||||
*
|
||||
*/
|
||||
#if (!defined(TARGET_I386))
|
||||
typedef int64_t target_time_t;
|
||||
typedef int64_t target_freebsd_time_t;
|
||||
#else
|
||||
typedef int32_t target_time_t;
|
||||
typedef int32_t target_freebsd_time_t;
|
||||
#endif
|
||||
|
||||
struct target_iovec {
|
||||
@@ -102,7 +102,7 @@ typedef abi_long target_freebsd_suseconds_t;
|
||||
|
||||
/* compare to sys/timespec.h */
|
||||
struct target_freebsd_timespec {
|
||||
target_time_t tv_sec; /* seconds */
|
||||
target_freebsd_time_t tv_sec; /* seconds */
|
||||
abi_long tv_nsec; /* and nanoseconds */
|
||||
#if !defined(TARGET_I386) && TARGET_ABI_BITS == 32
|
||||
abi_long _pad;
|
||||
@@ -120,7 +120,7 @@ struct target_freebsd__umtx_time {
|
||||
};
|
||||
|
||||
struct target_freebsd_timeval {
|
||||
target_time_t tv_sec; /* seconds */
|
||||
target_freebsd_time_t tv_sec; /* seconds */
|
||||
target_freebsd_suseconds_t tv_usec;/* and microseconds */
|
||||
#if !defined(TARGET_I386) && TARGET_ABI_BITS == 32
|
||||
abi_long _pad;
|
||||
@@ -179,217 +179,6 @@ struct target_freebsd__wrusage {
|
||||
struct target_freebsd_rusage wru_children;
|
||||
};
|
||||
|
||||
/*
|
||||
* sys/stat.h
|
||||
*/
|
||||
struct target_freebsd11_stat {
|
||||
uint32_t st_dev; /* inode's device */
|
||||
uint32_t st_ino; /* inode's number */
|
||||
int16_t st_mode; /* inode protection mode */
|
||||
int16_t st_nlink; /* number of hard links */
|
||||
uint32_t st_uid; /* user ID of the file's owner */
|
||||
uint32_t st_gid; /* group ID of the file's group */
|
||||
uint32_t st_rdev; /* device type */
|
||||
struct target_freebsd_timespec st_atim; /* time last accessed */
|
||||
struct target_freebsd_timespec st_mtim; /* time last data modification */
|
||||
struct target_freebsd_timespec st_ctim; /* time last file status change */
|
||||
int64_t st_size; /* file size, in bytes */
|
||||
int64_t st_blocks; /* blocks allocated for file */
|
||||
uint32_t st_blksize; /* optimal blocksize for I/O */
|
||||
uint32_t st_flags; /* user defined flags for file */
|
||||
uint32_t st_gen; /* file generation number */
|
||||
int32_t st_lspare;
|
||||
struct target_freebsd_timespec st_birthtim; /* time of file creation */
|
||||
/*
|
||||
* Explicitly pad st_birthtim to 16 bytes so that the size of
|
||||
* struct stat is backwards compatible. We use bitfields instead
|
||||
* of an array of chars so that this doesn't require a C99 compiler
|
||||
* to compile if the size of the padding is 0. We use 2 bitfields
|
||||
* to cover up to 64 bits on 32-bit machines. We assume that
|
||||
* CHAR_BIT is 8...
|
||||
*/
|
||||
unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
|
||||
unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
|
||||
} __packed;
|
||||
|
||||
#if defined(__i386__)
|
||||
#define TARGET_HAS_STAT_TIME_T_EXT 1
|
||||
#endif
|
||||
|
||||
struct target_stat {
|
||||
uint64_t st_dev; /* inode's device */
|
||||
uint64_t st_ino; /* inode's number */
|
||||
uint64_t st_nlink; /* number of hard links */
|
||||
int16_t st_mode; /* inode protection mode */
|
||||
int16_t st_padding0;
|
||||
uint32_t st_uid; /* user ID of the file's owner */
|
||||
uint32_t st_gid; /* group ID of the file's group */
|
||||
int32_t st_padding1;
|
||||
uint64_t st_rdev; /* device type */
|
||||
#ifdef TARGET_HAS_STAT_TIME_T_EXT
|
||||
int32_t st_atim_ext;
|
||||
#endif
|
||||
struct target_freebsd_timespec st_atim; /* time of last access */
|
||||
#ifdef TARGET_HAS_STAT_TIME_T_EXT
|
||||
int32_t st_mtim_ext;
|
||||
#endif
|
||||
struct target_freebsd_timespec st_mtim; /* time of last data modification */
|
||||
#ifdef TARGET_HAS_STAT_TIME_T_EXT
|
||||
int32_t st_ctim_ext;
|
||||
#endif
|
||||
struct target_freebsd_timespec st_ctim;/* time of last file status change */
|
||||
#ifdef TARGET_HAS_STAT_TIME_T_EXT
|
||||
int32_t st_btim_ext;
|
||||
#endif
|
||||
struct target_freebsd_timespec st_birthtim; /* time of file creation */
|
||||
int64_t st_size; /* file size, in bytes */
|
||||
int64_t st_blocks; /* blocks allocated for file */
|
||||
uint32_t st_blksize; /* optimal blocksize for I/O */
|
||||
uint32_t st_flags; /* user defined flags for file */
|
||||
uint64_t st_gen; /* file generation number */
|
||||
uint64_t st_spare[10];
|
||||
};
|
||||
|
||||
|
||||
/* struct nstat is the same as stat above but without the st_lspare field */
|
||||
struct target_freebsd11_nstat {
|
||||
uint32_t st_dev; /* inode's device */
|
||||
uint32_t st_ino; /* inode's number */
|
||||
int16_t st_mode; /* inode protection mode */
|
||||
int16_t st_nlink; /* number of hard links */
|
||||
uint32_t st_uid; /* user ID of the file's owner */
|
||||
uint32_t st_gid; /* group ID of the file's group */
|
||||
uint32_t st_rdev; /* device type */
|
||||
struct target_freebsd_timespec st_atim; /* time last accessed */
|
||||
struct target_freebsd_timespec st_mtim; /* time last data modification */
|
||||
struct target_freebsd_timespec st_ctim; /* time last file status change */
|
||||
int64_t st_size; /* file size, in bytes */
|
||||
int64_t st_blocks; /* blocks allocated for file */
|
||||
uint32_t st_blksize; /* optimal blocksize for I/O */
|
||||
uint32_t st_flags; /* user defined flags for file */
|
||||
uint32_t st_gen; /* file generation number */
|
||||
struct target_freebsd_timespec st_birthtim; /* time of file creation */
|
||||
/*
|
||||
* Explicitly pad st_birthtim to 16 bytes so that the size of
|
||||
* struct stat is backwards compatible. We use bitfields instead
|
||||
* of an array of chars so that this doesn't require a C99 compiler
|
||||
* to compile if the size of the padding is 0. We use 2 bitfields
|
||||
* to cover up to 64 bits on 32-bit machines. We assume that
|
||||
* CHAR_BIT is 8...
|
||||
*/
|
||||
unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
|
||||
unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* sys/mount.h
|
||||
*/
|
||||
|
||||
/* filesystem id type */
|
||||
typedef struct target_freebsd_fsid { int32_t val[2]; } target_freebsd_fsid_t;
|
||||
|
||||
/* filesystem statistics */
|
||||
struct target_freebsd11_statfs {
|
||||
uint32_t f_version; /* structure version number */
|
||||
uint32_t f_type; /* type of filesystem */
|
||||
uint64_t f_flags; /* copy of mount exported flags */
|
||||
uint64_t f_bsize; /* filesystem fragment size */
|
||||
uint64_t f_iosize; /* optimal transfer block size */
|
||||
uint64_t f_blocks; /* total data blocks in filesystem */
|
||||
uint64_t f_bfree; /* free blocks in filesystem */
|
||||
int64_t f_bavail; /* free blocks avail to non-superuser */
|
||||
uint64_t f_files; /* total file nodes in filesystem */
|
||||
int64_t f_ffree; /* free nodes avail to non-superuser */
|
||||
uint64_t f_syncwrites; /* count of sync writes since mount */
|
||||
uint64_t f_asyncwrites; /* count of async writes since mount */
|
||||
uint64_t f_syncreads; /* count of sync reads since mount */
|
||||
uint64_t f_asyncreads; /* count of async reads since mount */
|
||||
uint64_t f_spare[10]; /* unused spare */
|
||||
uint32_t f_namemax; /* maximum filename length */
|
||||
uint32_t f_owner; /* user that mounted the filesystem */
|
||||
target_freebsd_fsid_t f_fsid; /* filesystem id */
|
||||
char f_charspare[80]; /* spare string space */
|
||||
char f_fstypename[16]; /* filesys type name */
|
||||
char f_mntfromname[88]; /* mount filesystem */
|
||||
char f_mntonname[88]; /* dir on which mounted*/
|
||||
};
|
||||
|
||||
struct target_statfs {
|
||||
uint32_t f_version; /* structure version number */
|
||||
uint32_t f_type; /* type of filesystem */
|
||||
uint64_t f_flags; /* copy of mount exported flags */
|
||||
uint64_t f_bsize; /* filesystem fragment size */
|
||||
uint64_t f_iosize; /* optimal transfer block size */
|
||||
uint64_t f_blocks; /* total data blocks in filesystem */
|
||||
uint64_t f_bfree; /* free blocks in filesystem */
|
||||
int64_t f_bavail; /* free blocks avail to non-superuser */
|
||||
uint64_t f_files; /* total file nodes in filesystem */
|
||||
int64_t f_ffree; /* free nodes avail to non-superuser */
|
||||
uint64_t f_syncwrites; /* count of sync writes since mount */
|
||||
uint64_t f_asyncwrites; /* count of async writes since mount */
|
||||
uint64_t f_syncreads; /* count of sync reads since mount */
|
||||
uint64_t f_asyncreads; /* count of async reads since mount */
|
||||
uint64_t f_spare[10]; /* unused spare */
|
||||
uint32_t f_namemax; /* maximum filename length */
|
||||
uint32_t f_owner; /* user that mounted the filesystem */
|
||||
target_freebsd_fsid_t f_fsid; /* filesystem id */
|
||||
char f_charspare[80]; /* spare string space */
|
||||
char f_fstypename[16]; /* filesystem type name */
|
||||
char f_mntfromname[1024]; /* mounted filesystem */
|
||||
char f_mntonname[1024]; /* directory on which mounted */
|
||||
};
|
||||
|
||||
/* File identifier. These are unique per filesystem on a single machine. */
|
||||
#define TARGET_MAXFIDSZ 16
|
||||
|
||||
struct target_freebsd_fid {
|
||||
uint16_t fid_len; /* len of data in bytes */
|
||||
uint16_t fid_data0; /* force longword align */
|
||||
char fid_data[TARGET_MAXFIDSZ]; /* data (variable len) */
|
||||
};
|
||||
|
||||
/* Generic file handle */
|
||||
struct target_freebsd_fhandle {
|
||||
target_freebsd_fsid_t fh_fsid; /* Filesystem id of mount point */
|
||||
struct target_freebsd_fid fh_fid; /* Filesys specific id */
|
||||
};
|
||||
typedef struct target_freebsd_fhandle target_freebsd_fhandle_t;
|
||||
|
||||
/*
|
||||
* sys/fcntl.h
|
||||
*/
|
||||
#define TARGET_F_DUPFD 0
|
||||
#define TARGET_F_GETFD 1
|
||||
#define TARGET_F_SETFD 2
|
||||
#define TARGET_F_GETFL 3
|
||||
#define TARGET_F_SETFL 4
|
||||
#define TARGET_F_GETOWN 5
|
||||
#define TARGET_F_SETOWN 6
|
||||
#define TARGET_F_OGETLK 7
|
||||
#define TARGET_F_OSETLK 8
|
||||
#define TARGET_F_OSETLKW 9
|
||||
#define TARGET_F_DUP2FD 10
|
||||
#define TARGET_F_GETLK 11
|
||||
#define TARGET_F_SETLK 12
|
||||
#define TARGET_F_SETLKW 13
|
||||
#define TARGET_F_SETLK_REMOTE 14
|
||||
#define TARGET_F_READAHEAD 15
|
||||
#define TARGET_F_RDAHEAD 16
|
||||
#define TARGET_F_DUPFD_CLOEXEC 17
|
||||
#define TARGET_F_DUP2FD_CLOEXEC 18
|
||||
/* FreeBSD-specific */
|
||||
#define TARGET_F_ADD_SEALS 19
|
||||
#define TARGET_F_GET_SEALS 20
|
||||
|
||||
struct target_freebsd_flock {
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
int32_t l_sysid;
|
||||
} QEMU_PACKED;
|
||||
|
||||
#define safe_syscall0(type, name) \
|
||||
type safe_##name(void) \
|
||||
{ \
|
||||
@@ -437,8 +226,6 @@ type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
|
||||
return safe_syscall(SYS_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
|
||||
}
|
||||
|
||||
#define safe_fcntl(...) safe_syscall(SYS_fcntl, __VA_ARGS__)
|
||||
|
||||
/* So far all target and host bitmasks are the same */
|
||||
#undef target_to_host_bitmask
|
||||
#define target_to_host_bitmask(x, tbl) (x)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef TARGET_ARCH_ELF_H
|
||||
#define TARGET_ARCH_ELF_H
|
||||
|
||||
#define ELF_START_MMAP 0x2aaaaab000ULL
|
||||
#define ELF_ET_DYN_LOAD_ADDR 0x01021000
|
||||
#define elf_check_arch(x) (((x) == ELF_ARCH))
|
||||
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ chardev_ss.add(when: 'CONFIG_WIN32', if_true: files(
|
||||
'char-win.c',
|
||||
))
|
||||
|
||||
chardev_ss = chardev_ss.apply(config_targetos, strict: false)
|
||||
chardev_ss = chardev_ss.apply(config_host, strict: false)
|
||||
|
||||
system_ss.add(files(
|
||||
'char-hmp-cmds.c',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
TARGET_ARCH=loongarch64
|
||||
TARGET_BASE_ARCH=loongarch
|
||||
TARGET_SUPPORTS_MTTCG=y
|
||||
TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
|
||||
TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
|
||||
TARGET_NEED_FDT=y
|
||||
|
||||
@@ -245,9 +245,10 @@ for opt do
|
||||
esac
|
||||
done
|
||||
|
||||
default_cflags='-O2 -g'
|
||||
|
||||
git_submodules_action="update"
|
||||
git="git"
|
||||
debug_tcg="no"
|
||||
docs="auto"
|
||||
EXESUF=""
|
||||
prefix="/usr/local"
|
||||
@@ -256,7 +257,6 @@ softmmu="yes"
|
||||
linux_user=""
|
||||
bsd_user=""
|
||||
plugins="$default_feature"
|
||||
subdirs=""
|
||||
ninja=""
|
||||
python=
|
||||
download="enabled"
|
||||
@@ -288,7 +288,7 @@ static="no"
|
||||
# ${cross_prefix}gcc (if cross-prefix specified)
|
||||
# system compiler
|
||||
if test -z "${CC}${cross_prefix}"; then
|
||||
cc="cc"
|
||||
cc="$host_cc"
|
||||
else
|
||||
cc="${CC-${cross_prefix}gcc}"
|
||||
fi
|
||||
@@ -374,14 +374,45 @@ fi
|
||||
|
||||
# OS specific
|
||||
|
||||
mingw32="no"
|
||||
bsd="no"
|
||||
linux="no"
|
||||
solaris="no"
|
||||
case $targetos in
|
||||
windows)
|
||||
mingw32="yes"
|
||||
plugins="no"
|
||||
pie="no"
|
||||
;;
|
||||
gnu/kfreebsd)
|
||||
bsd="yes"
|
||||
;;
|
||||
freebsd)
|
||||
bsd="yes"
|
||||
# needed for kinfo_getvmmap(3) in libutil.h
|
||||
;;
|
||||
dragonfly)
|
||||
bsd="yes"
|
||||
;;
|
||||
netbsd)
|
||||
bsd="yes"
|
||||
;;
|
||||
openbsd)
|
||||
bsd="yes"
|
||||
;;
|
||||
darwin)
|
||||
bsd="yes"
|
||||
darwin="yes"
|
||||
;;
|
||||
sunos)
|
||||
solaris="yes"
|
||||
;;
|
||||
haiku)
|
||||
pie="no"
|
||||
;;
|
||||
linux)
|
||||
linux="yes"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test ! -z "$cpu" ; then
|
||||
@@ -552,16 +583,16 @@ if test -n "$linux_arch" && ! test -d "$source_path/linux-headers/asm-$linux_arc
|
||||
fi
|
||||
|
||||
check_py_version() {
|
||||
# We require python >= 3.8.
|
||||
# We require python >= 3.7.
|
||||
# NB: a True python conditional creates a non-zero return code (Failure)
|
||||
"$1" -c 'import sys; sys.exit(sys.version_info < (3,8))'
|
||||
"$1" -c 'import sys; sys.exit(sys.version_info < (3,7))'
|
||||
}
|
||||
|
||||
first_python=
|
||||
if test -z "${PYTHON}"; then
|
||||
# A bare 'python' is traditionally python 2.x, but some distros
|
||||
# have it as python 3.x, so check in both places.
|
||||
for binary in python3 python python3.11 python3.10 python3.9 python3.8; do
|
||||
for binary in python3 python python3.11 python3.10 python3.9 python3.8 python3.7; do
|
||||
if has "$binary"; then
|
||||
python=$(command -v "$binary")
|
||||
if check_py_version "$python"; then
|
||||
@@ -596,7 +627,7 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
if test "$targetos" = "windows" ; then
|
||||
if test "$mingw32" = "yes" ; then
|
||||
EXESUF=".exe"
|
||||
prefix="/qemu"
|
||||
bindir=""
|
||||
@@ -727,13 +758,16 @@ for opt do
|
||||
# configure to be used by RPM and similar macros that set
|
||||
# lots of directory switches by default.
|
||||
;;
|
||||
--enable-debug-tcg) debug_tcg="yes"
|
||||
;;
|
||||
--disable-debug-tcg) debug_tcg="no"
|
||||
;;
|
||||
--enable-debug)
|
||||
# Enable debugging options that aren't excessively noisy
|
||||
meson_option_parse --enable-debug-tcg ""
|
||||
debug_tcg="yes"
|
||||
meson_option_parse --enable-debug-graph-lock ""
|
||||
meson_option_parse --enable-debug-mutex ""
|
||||
meson_option_add -Doptimization=0
|
||||
default_cflags='-O0 -g'
|
||||
;;
|
||||
--disable-tcg) tcg="disabled"
|
||||
plugins="no"
|
||||
@@ -775,7 +809,7 @@ for opt do
|
||||
;;
|
||||
--enable-download) download="enabled"; git_submodules_action=update;
|
||||
;;
|
||||
--enable-plugins) if test "$targetos" = "windows"; then
|
||||
--enable-plugins) if test "$mingw32" = "yes"; then
|
||||
error_exit "TCG plugins not currently supported on Windows platforms"
|
||||
else
|
||||
plugins="yes"
|
||||
@@ -837,36 +871,30 @@ fi
|
||||
default_target_list=""
|
||||
mak_wilds=""
|
||||
|
||||
if [ -n "$host_arch" ] && [ -d "$source_path/common-user/host/$host_arch" ]; then
|
||||
if [ "$linux_user" != no ]; then
|
||||
if [ "$targetos" = linux ]; then
|
||||
linux_user=yes
|
||||
elif [ "$linux_user" = yes ]; then
|
||||
error_exit "linux-user not supported on this architecture"
|
||||
fi
|
||||
if [ "$linux_user" = "yes" ]; then
|
||||
mak_wilds="${mak_wilds} $source_path/configs/targets/*-linux-user.mak"
|
||||
fi
|
||||
if [ "$linux_user" != no ]; then
|
||||
if [ "$targetos" = linux ] && [ -n "$host_arch" ]; then
|
||||
linux_user=yes
|
||||
elif [ "$linux_user" = yes ]; then
|
||||
error_exit "linux-user not supported on this architecture"
|
||||
fi
|
||||
if [ "$bsd_user" != no ]; then
|
||||
if [ "$bsd_user" = "" ]; then
|
||||
test $targetos = freebsd && bsd_user=yes
|
||||
fi
|
||||
if [ "$bsd_user" = yes ] && ! [ -d "$source_path/bsd-user/$targetos" ]; then
|
||||
error_exit "bsd-user not supported on this host OS"
|
||||
fi
|
||||
if [ "$bsd_user" = "yes" ]; then
|
||||
mak_wilds="${mak_wilds} $source_path/configs/targets/*-bsd-user.mak"
|
||||
fi
|
||||
fi
|
||||
if [ "$bsd_user" != no ]; then
|
||||
if [ "$bsd_user" = "" ]; then
|
||||
test $targetos = freebsd && bsd_user=yes
|
||||
fi
|
||||
else
|
||||
if [ "$linux_user" = yes ] || [ "$bsd_user" = yes ]; then
|
||||
error_exit "user mode emulation not supported on this architecture"
|
||||
if [ "$bsd_user" = yes ] && ! [ -d "$source_path/bsd-user/$targetos" ]; then
|
||||
error_exit "bsd-user not supported on this host OS"
|
||||
fi
|
||||
fi
|
||||
if [ "$softmmu" = "yes" ]; then
|
||||
mak_wilds="${mak_wilds} $source_path/configs/targets/*-softmmu.mak"
|
||||
fi
|
||||
if [ "$linux_user" = "yes" ]; then
|
||||
mak_wilds="${mak_wilds} $source_path/configs/targets/*-linux-user.mak"
|
||||
fi
|
||||
if [ "$bsd_user" = "yes" ]; then
|
||||
mak_wilds="${mak_wilds} $source_path/configs/targets/*-bsd-user.mak"
|
||||
fi
|
||||
|
||||
for config in $mak_wilds; do
|
||||
target="$(basename "$config" .mak)"
|
||||
@@ -893,8 +921,8 @@ Advanced options (experts only):
|
||||
-Dmesonoptname=val passthrough option to meson unmodified
|
||||
--cross-prefix=PREFIX use PREFIX for compile tools, PREFIX can be blank [$cross_prefix]
|
||||
--cc=CC use C compiler CC [$cc]
|
||||
--host-cc=CC when cross compiling, use C compiler CC for code run
|
||||
at build time [$host_cc]
|
||||
--host-cc=CC use C compiler CC [$host_cc] for code run at
|
||||
build time
|
||||
--cxx=CXX use C++ compiler CXX [$cxx]
|
||||
--objcc=OBJCC use Objective-C compiler OBJCC [$objcc]
|
||||
--extra-cflags=CFLAGS append extra C compiler flags CFLAGS
|
||||
@@ -930,6 +958,7 @@ cat << EOF
|
||||
linux-user all linux usermode emulation targets
|
||||
bsd-user all BSD usermode emulation targets
|
||||
pie Position Independent Executables
|
||||
debug-tcg TCG debugging (default is disabled)
|
||||
|
||||
NOTE: The object files are built at the place where configure is launched
|
||||
EOF
|
||||
@@ -952,7 +981,7 @@ then
|
||||
fi
|
||||
|
||||
if ! check_py_version "$python"; then
|
||||
error_exit "Cannot use '$python', Python >= 3.8 is required." \
|
||||
error_exit "Cannot use '$python', Python >= 3.7 is required." \
|
||||
"Use --python=/path/to/python to specify a supported Python." \
|
||||
"Maybe try:" \
|
||||
" openSUSE Leap 15.3+: zypper install python39" \
|
||||
@@ -989,14 +1018,19 @@ fi
|
||||
python="$python -B"
|
||||
mkvenv="$python ${source_path}/python/scripts/mkvenv.py"
|
||||
|
||||
# Finish preparing the virtual environment using vendored .whl files
|
||||
mkvenv_flags=""
|
||||
if test "$download" = "enabled" ; then
|
||||
mkvenv_flags="--online"
|
||||
fi
|
||||
|
||||
if $python -c 'import sys; sys.exit(sys.version_info >= (3,11))'; then
|
||||
$mkvenv ensure --dir "${source_path}/python/wheels" \
|
||||
'tomli>=1.2.0' || exit 1
|
||||
if ! $mkvenv ensure \
|
||||
$mkvenv_flags \
|
||||
--dir "${source_path}/python/wheels" \
|
||||
--diagnose "meson" \
|
||||
"meson>=0.63.0" ;
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
$mkvenv ensuregroup --dir "${source_path}/python/wheels" \
|
||||
${source_path}/pythondeps.toml meson || exit 1
|
||||
|
||||
# At this point, we expect Meson to be installed and available.
|
||||
# We expect mkvenv or pip to have created pyvenv/bin/meson for us.
|
||||
@@ -1013,9 +1047,10 @@ if test "$download" = "enabled" -a "$docs" = "enabled" ; then
|
||||
fi
|
||||
|
||||
if test "$docs" != "disabled" ; then
|
||||
if ! $mkvenv ensuregroup \
|
||||
if ! $mkvenv ensure \
|
||||
$mkvenv_flags \
|
||||
${source_path}/pythondeps.toml docs;
|
||||
--diagnose "sphinx-build" \
|
||||
"sphinx>=1.6.0" "sphinx-rtd-theme>=0.5.0";
|
||||
then
|
||||
if test "$docs" = "enabled" ; then
|
||||
exit 1
|
||||
@@ -1045,7 +1080,7 @@ fi
|
||||
# by default. Only enable by default for git builds
|
||||
if test -z "$werror" ; then
|
||||
if test -e "$source_path/.git" && \
|
||||
{ test "$targetos" = linux || test "$targetos" = "windows"; }; then
|
||||
{ test "$linux" = "yes" || test "$mingw32" = "yes"; }; then
|
||||
werror="yes"
|
||||
else
|
||||
werror="no"
|
||||
@@ -1068,9 +1103,6 @@ if test "$static" = "yes" ; then
|
||||
fi
|
||||
fi
|
||||
test "$plugins" = "" && plugins=yes
|
||||
if test "$plugins" = "yes"; then
|
||||
subdirs="$subdirs contrib/plugins"
|
||||
fi
|
||||
|
||||
cat > $TMPC << EOF
|
||||
|
||||
@@ -1126,6 +1158,14 @@ else
|
||||
done
|
||||
fi
|
||||
|
||||
# see if system emulation was really requested
|
||||
case " $target_list " in
|
||||
*"-softmmu "*) softmmu=yes
|
||||
;;
|
||||
*) softmmu=no
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$tcg" = "auto"; then
|
||||
if test -z "$target_list"; then
|
||||
tcg="disabled"
|
||||
@@ -1231,7 +1271,6 @@ fi
|
||||
: ${cross_prefix_sh4="sh4-linux-gnu-"}
|
||||
: ${cross_prefix_sparc64="sparc64-linux-gnu-"}
|
||||
: ${cross_prefix_sparc="$cross_prefix_sparc64"}
|
||||
: ${cross_prefix_tricore="tricore-"}
|
||||
: ${cross_prefix_x86_64="x86_64-linux-gnu-"}
|
||||
|
||||
: ${cross_cc_aarch64_be="$cross_cc_aarch64"}
|
||||
@@ -1318,7 +1357,7 @@ probe_target_compiler() {
|
||||
sh4) container_hosts=x86_64 ;;
|
||||
sparc64) container_hosts=x86_64 ;;
|
||||
tricore) container_hosts=x86_64 ;;
|
||||
x86_64) container_hosts="aarch64 ppc64le x86_64" ;;
|
||||
x86_64) container_hosts="aarch64 ppc64el x86_64" ;;
|
||||
xtensa*) container_hosts=x86_64 ;;
|
||||
esac
|
||||
|
||||
@@ -1419,12 +1458,17 @@ probe_target_compiler() {
|
||||
tricore)
|
||||
container_image=debian-tricore-cross
|
||||
container_cross_prefix=tricore-
|
||||
container_cross_as=tricore-as
|
||||
container_cross_ld=tricore-ld
|
||||
container_cross_cc=tricore-gcc
|
||||
break
|
||||
;;
|
||||
x86_64)
|
||||
container_image=debian-amd64-cross
|
||||
container_cross_prefix=x86_64-linux-gnu-
|
||||
;;
|
||||
xtensa*)
|
||||
container_hosts=x86_64
|
||||
container_image=debian-xtensa-cross
|
||||
|
||||
# default to the dc232b cpu
|
||||
@@ -1623,11 +1667,12 @@ done
|
||||
echo "# Automatically generated by configure - do not modify" > Makefile.prereqs
|
||||
|
||||
# Mac OS X ships with a broken assembler
|
||||
roms=
|
||||
if have_target i386-softmmu x86_64-softmmu && \
|
||||
test "$targetos" != "darwin" && test "$targetos" != "sunos" && \
|
||||
test "$targetos" != "haiku" && \
|
||||
probe_target_compiler i386-softmmu; then
|
||||
subdirs="$subdirs pc-bios/optionrom"
|
||||
roms="pc-bios/optionrom"
|
||||
config_mak=pc-bios/optionrom/config.mak
|
||||
echo "# Automatically generated by configure - do not modify" > $config_mak
|
||||
echo "TOPSRC_DIR=$source_path" >> $config_mak
|
||||
@@ -1636,7 +1681,7 @@ fi
|
||||
|
||||
if have_target ppc-softmmu ppc64-softmmu && \
|
||||
probe_target_compiler ppc-softmmu; then
|
||||
subdirs="$subdirs pc-bios/vof"
|
||||
roms="$roms pc-bios/vof"
|
||||
config_mak=pc-bios/vof/config.mak
|
||||
echo "# Automatically generated by configure - do not modify" > $config_mak
|
||||
echo "SRC_DIR=$source_path/pc-bios/vof" >> $config_mak
|
||||
@@ -1655,7 +1700,7 @@ if have_target s390x-softmmu && probe_target_compiler s390x-softmmu && \
|
||||
echo "WARNING: Your compiler does not support the z900!"
|
||||
echo " The s390-ccw bios will only work with guest CPUs >= z10."
|
||||
fi
|
||||
subdirs="$subdirs pc-bios/s390-ccw"
|
||||
roms="$roms pc-bios/s390-ccw"
|
||||
config_mak=pc-bios/s390-ccw/config-host.mak
|
||||
echo "# Automatically generated by configure - do not modify" > $config_mak
|
||||
echo "SRC_PATH=$source_path/pc-bios/s390-ccw" >> $config_mak
|
||||
@@ -1674,15 +1719,41 @@ echo >> $config_host_mak
|
||||
|
||||
echo all: >> $config_host_mak
|
||||
|
||||
if test "$targetos" = "windows"; then
|
||||
if test "$debug_tcg" = "yes" ; then
|
||||
echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$mingw32" = "yes" ; then
|
||||
echo "CONFIG_WIN32=y" >> $config_host_mak
|
||||
echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER-QEMU}" >> $config_host_mak
|
||||
echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO-Linux}" >> $config_host_mak
|
||||
echo "QEMU_GA_VERSION=${QEMU_GA_VERSION-$(cat "$source_path"/VERSION)}" >> $config_host_mak
|
||||
else
|
||||
echo "CONFIG_POSIX=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$linux" = "yes" ; then
|
||||
echo "CONFIG_LINUX=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$darwin" = "yes" ; then
|
||||
echo "CONFIG_DARWIN=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$solaris" = "yes" ; then
|
||||
echo "CONFIG_SOLARIS=y" >> $config_host_mak
|
||||
fi
|
||||
echo "SRC_PATH=$source_path" >> $config_host_mak
|
||||
echo "TARGET_DIRS=$target_list" >> $config_host_mak
|
||||
|
||||
# XXX: suppress that
|
||||
if [ "$bsd" = "yes" ] ; then
|
||||
echo "CONFIG_BSD=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$plugins" = "yes" ; then
|
||||
echo "CONFIG_PLUGIN=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test -n "$gdb_bin"; then
|
||||
gdb_version=$($gdb_bin --version | head -n 1)
|
||||
if version_ge ${gdb_version##* } 9.1; then
|
||||
@@ -1697,21 +1768,24 @@ if test "$container" != no; then
|
||||
echo "ENGINE=$container" >> $config_host_mak
|
||||
echo "RUNC=$runc" >> $config_host_mak
|
||||
fi
|
||||
echo "SUBDIRS=$subdirs" >> $config_host_mak
|
||||
echo "ROMS=$roms" >> $config_host_mak
|
||||
echo "PYTHON=$python" >> $config_host_mak
|
||||
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
|
||||
echo "MESON=$meson" >> $config_host_mak
|
||||
echo "NINJA=$ninja" >> $config_host_mak
|
||||
echo "PKG_CONFIG=${pkg_config}" >> $config_host_mak
|
||||
echo "CC=$cc" >> $config_host_mak
|
||||
echo "EXESUF=$EXESUF" >> $config_host_mak
|
||||
|
||||
# use included Linux headers for KVM architectures
|
||||
if test "$targetos" = "linux" && test -n "$linux_arch"; then
|
||||
if test "$linux" = "yes" && test -n "$linux_arch"; then
|
||||
symlink "$source_path/linux-headers/asm-$linux_arch" linux-headers/asm
|
||||
fi
|
||||
|
||||
for target in $target_list; do
|
||||
target_dir="$target"
|
||||
target_name=$(echo $target | cut -d '-' -f 1)$EXESUF
|
||||
mkdir -p "$target_dir"
|
||||
case $target in
|
||||
*-user) symlink "../qemu-$target_name" "$target_dir/qemu-$target_name" ;;
|
||||
*) symlink "../qemu-system-$target_name" "$target_dir/qemu-system-$target_name" ;;
|
||||
@@ -1726,21 +1800,12 @@ if test "$ccache_cpp2" = "yes"; then
|
||||
echo "export CCACHE_CPP2=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
# contrib/plugins configuration
|
||||
echo "# Automatically generated by configure - do not modify" > contrib/plugins/$config_host_mak
|
||||
echo "SRC_PATH=$source_path/contrib/plugins" >> contrib/plugins/$config_host_mak
|
||||
echo "PKG_CONFIG=${pkg_config}" >> contrib/plugins/$config_host_mak
|
||||
echo "CC=$cc $CPU_CFLAGS" >> contrib/plugins/$config_host_mak
|
||||
echo "CFLAGS=${CFLAGS-$default_cflags} $EXTRA_CFLAGS" >> contrib/plugins/$config_host_mak
|
||||
if test "$targetos" = darwin; then
|
||||
echo "CONFIG_DARWIN=y" >> contrib/plugins/$config_host_mak
|
||||
fi
|
||||
|
||||
# tests/tcg configuration
|
||||
(config_host_mak=tests/tcg/config-host.mak
|
||||
mkdir -p tests/tcg
|
||||
echo "# Automatically generated by configure - do not modify" > $config_host_mak
|
||||
echo "SRC_PATH=$source_path" >> $config_host_mak
|
||||
echo "HOST_CC=$host_cc" >> $config_host_mak
|
||||
|
||||
# versioned checked in the main config_host.mak above
|
||||
if test -n "$gdb_bin"; then
|
||||
@@ -1833,6 +1898,7 @@ if test "$skip_meson" = no; then
|
||||
echo "windres = [$(meson_quote $windres)]" >> $cross
|
||||
echo "windmc = [$(meson_quote $windmc)]" >> $cross
|
||||
if test "$cross_compile" = "yes"; then
|
||||
cross_arg="--cross-file config-meson.cross"
|
||||
echo "[host_machine]" >> $cross
|
||||
echo "system = '$targetos'" >> $cross
|
||||
case "$cpu" in
|
||||
@@ -1849,14 +1915,6 @@ if test "$skip_meson" = no; then
|
||||
else
|
||||
echo "endian = 'little'" >> $cross
|
||||
fi
|
||||
cross_arg="--cross-file config-meson.cross"
|
||||
|
||||
native="config-meson.native.new"
|
||||
echo "# Automatically generated by configure - do not modify" > $native
|
||||
echo "[binaries]" >> $native
|
||||
echo "c = [$(meson_quote $host_cc)]" >> $native
|
||||
mv $native config-meson.native
|
||||
cross_arg="$cross_arg --native-file config-meson.native"
|
||||
else
|
||||
cross_arg="--native-file config-meson.cross"
|
||||
fi
|
||||
@@ -1876,7 +1934,6 @@ if test "$skip_meson" = no; then
|
||||
test "$cfi" != false && meson_option_add "-Dcfi=$cfi"
|
||||
test "$docs" != auto && meson_option_add "-Ddocs=$docs"
|
||||
test -n "${LIB_FUZZING_ENGINE+xxx}" && meson_option_add "-Dfuzzing_engine=$LIB_FUZZING_ENGINE"
|
||||
test "$plugins" = yes && meson_option_add "-Dplugins=true"
|
||||
test "$qemu_suffix" != qemu && meson_option_add "-Dqemu_suffix=$qemu_suffix"
|
||||
test "$smbd" != '' && meson_option_add "-Dsmbd=$smbd"
|
||||
test "$tcg" != enabled && meson_option_add "-Dtcg=$tcg"
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
# programs that the main configure has already done for us.
|
||||
#
|
||||
|
||||
include config-host.mak
|
||||
BUILD_DIR := $(CURDIR)/../..
|
||||
|
||||
TOP_SRC_PATH = $(SRC_PATH)/../..
|
||||
include $(BUILD_DIR)/config-host.mak
|
||||
|
||||
VPATH += $(SRC_PATH)
|
||||
VPATH += $(SRC_PATH)/contrib/plugins
|
||||
|
||||
NAMES :=
|
||||
NAMES += execlog
|
||||
@@ -26,25 +26,21 @@ SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
|
||||
|
||||
# The main QEMU uses Glib extensively so it's perfectly fine to use it
|
||||
# in plugins (which many example do).
|
||||
PLUGIN_CFLAGS := $(shell $(PKG_CONFIG) --cflags glib-2.0)
|
||||
PLUGIN_CFLAGS += -fPIC -Wall
|
||||
PLUGIN_CFLAGS += -I$(TOP_SRC_PATH)/include/qemu
|
||||
CFLAGS := $(shell $(PKG_CONFIG) --cflags glib-2.0)
|
||||
CFLAGS += -fPIC -Wall
|
||||
CFLAGS += $(if $(CONFIG_DEBUG_TCG), -ggdb -O0)
|
||||
CFLAGS += -I$(SRC_PATH)/include/qemu
|
||||
|
||||
all: $(SONAMES)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) $(PLUGIN_CFLAGS) -c -o $@ $<
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
lib%.so: %.o
|
||||
ifeq ($(CONFIG_DARWIN),y)
|
||||
$(CC) -bundle -Wl,-undefined,dynamic_lookup -o $@ $^ $(LDLIBS)
|
||||
else
|
||||
$(CC) -shared -o $@ $^ $(LDLIBS)
|
||||
endif
|
||||
$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDLIBS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.so *.d
|
||||
rm -Rf .libs
|
||||
|
||||
.PHONY: all clean
|
||||
.SECONDARY:
|
||||
|
||||
+10
-11
@@ -350,7 +350,7 @@ static int in_cache(Cache *cache, uint64_t addr)
|
||||
* @cache: The cache under simulation
|
||||
* @addr: The address of the requested memory location
|
||||
*
|
||||
* Returns true if the requested data is hit in the cache and false when missed.
|
||||
* Returns true if the requsted data is hit in the cache and false when missed.
|
||||
* The cache is updated on miss for the next access.
|
||||
*/
|
||||
static bool access_cache(Cache *cache, uint64_t addr)
|
||||
@@ -545,8 +545,8 @@ static void append_stats_line(GString *line, uint64_t l1_daccess,
|
||||
l1_dmiss_rate = ((double) l1_dmisses) / (l1_daccess) * 100.0;
|
||||
l1_imiss_rate = ((double) l1_imisses) / (l1_iaccess) * 100.0;
|
||||
|
||||
g_string_append_printf(line, "%-14" PRIu64 " %-12" PRIu64 " %9.4lf%%"
|
||||
" %-14" PRIu64 " %-12" PRIu64 " %9.4lf%%",
|
||||
g_string_append_printf(line, "%-14lu %-12lu %9.4lf%% %-14lu %-12lu"
|
||||
" %9.4lf%%",
|
||||
l1_daccess,
|
||||
l1_dmisses,
|
||||
l1_daccess ? l1_dmiss_rate : 0.0,
|
||||
@@ -556,8 +556,7 @@ static void append_stats_line(GString *line, uint64_t l1_daccess,
|
||||
|
||||
if (use_l2) {
|
||||
l2_miss_rate = ((double) l2_misses) / (l2_access) * 100.0;
|
||||
g_string_append_printf(line,
|
||||
" %-12" PRIu64 " %-11" PRIu64 " %10.4lf%%",
|
||||
g_string_append_printf(line, " %-12lu %-11lu %10.4lf%%",
|
||||
l2_access,
|
||||
l2_misses,
|
||||
l2_access ? l2_miss_rate : 0.0);
|
||||
@@ -663,8 +662,8 @@ static void log_top_insns(void)
|
||||
if (insn->symbol) {
|
||||
g_string_append_printf(rep, " (%s)", insn->symbol);
|
||||
}
|
||||
g_string_append_printf(rep, ", %" PRId64 ", %s\n",
|
||||
insn->l1_dmisses, insn->disas_str);
|
||||
g_string_append_printf(rep, ", %ld, %s\n", insn->l1_dmisses,
|
||||
insn->disas_str);
|
||||
}
|
||||
|
||||
miss_insns = g_list_sort(miss_insns, icmp);
|
||||
@@ -676,8 +675,8 @@ static void log_top_insns(void)
|
||||
if (insn->symbol) {
|
||||
g_string_append_printf(rep, " (%s)", insn->symbol);
|
||||
}
|
||||
g_string_append_printf(rep, ", %" PRId64 ", %s\n",
|
||||
insn->l1_imisses, insn->disas_str);
|
||||
g_string_append_printf(rep, ", %ld, %s\n", insn->l1_imisses,
|
||||
insn->disas_str);
|
||||
}
|
||||
|
||||
if (!use_l2) {
|
||||
@@ -693,8 +692,8 @@ static void log_top_insns(void)
|
||||
if (insn->symbol) {
|
||||
g_string_append_printf(rep, " (%s)", insn->symbol);
|
||||
}
|
||||
g_string_append_printf(rep, ", %" PRId64 ", %s\n",
|
||||
insn->l2_misses, insn->disas_str);
|
||||
g_string_append_printf(rep, ", %ld, %s\n", insn->l2_misses,
|
||||
insn->disas_str);
|
||||
}
|
||||
|
||||
finish:
|
||||
|
||||
@@ -48,7 +48,7 @@ static void printf_header(unsigned long count)
|
||||
uint64_t start_code = qemu_plugin_start_code();
|
||||
uint64_t end_code = qemu_plugin_end_code();
|
||||
uint64_t entry = qemu_plugin_entry_code();
|
||||
fprintf(fp, "0, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s\n",
|
||||
fprintf(fp, "0, 0x%lx, 0x%lx, 0x%lx, %s\n",
|
||||
start_code, end_code, entry, path);
|
||||
fprintf(fp, "BB Table: %ld bbs\n", count);
|
||||
}
|
||||
|
||||
@@ -181,8 +181,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
|
||||
switch (class->what) {
|
||||
case COUNT_CLASS:
|
||||
if (class->count || verbose) {
|
||||
g_string_append_printf(report,
|
||||
"Class: %-24s\t(%" PRId64 " hits)\n",
|
||||
g_string_append_printf(report, "Class: %-24s\t(%ld hits)\n",
|
||||
class->class,
|
||||
class->count);
|
||||
}
|
||||
@@ -209,8 +208,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
|
||||
i++, counts = g_list_next(counts)) {
|
||||
InsnExecCount *rec = (InsnExecCount *) counts->data;
|
||||
g_string_append_printf(report,
|
||||
"Instr: %-24s\t(%" PRId64 " hits)"
|
||||
"\t(op=0x%08x/%s)\n",
|
||||
"Instr: %-24s\t(%ld hits)\t(op=0x%08x/%s)\n",
|
||||
rec->insn,
|
||||
rec->count,
|
||||
rec->opcode,
|
||||
|
||||
@@ -108,7 +108,7 @@ static void report_divergance(ExecState *us, ExecState *them)
|
||||
|
||||
/*
|
||||
* If we have diverged before did we get back on track or are we
|
||||
* totally losing it?
|
||||
* totally loosing it?
|
||||
*/
|
||||
if (divergence_log) {
|
||||
DivergeState *last = (DivergeState *) divergence_log->data;
|
||||
@@ -134,9 +134,7 @@ static void report_divergance(ExecState *us, ExecState *them)
|
||||
|
||||
/* Output short log entry of going out of sync... */
|
||||
if (verbose || divrec.distance == 1 || diverged) {
|
||||
g_string_printf(out,
|
||||
"@ 0x%016" PRIx64 " vs 0x%016" PRIx64
|
||||
" (%d/%d since last)\n",
|
||||
g_string_printf(out, "@ 0x%016lx vs 0x%016lx (%d/%d since last)\n",
|
||||
us->pc, them->pc, g_slist_length(divergence_log),
|
||||
divrec.distance);
|
||||
qemu_plugin_outs(out->str);
|
||||
@@ -146,9 +144,7 @@ static void report_divergance(ExecState *us, ExecState *them)
|
||||
int i;
|
||||
GSList *entry;
|
||||
|
||||
g_string_printf(out,
|
||||
"Δ insn_count @ 0x%016" PRIx64
|
||||
" (%ld) vs 0x%016" PRIx64 " (%ld)\n",
|
||||
g_string_printf(out, "Δ insn_count @ 0x%016lx (%ld) vs 0x%016lx (%ld)\n",
|
||||
us->pc, us->insn_count, them->pc, them->insn_count);
|
||||
|
||||
for (entry = log, i = 0;
|
||||
@@ -156,8 +152,7 @@ static void report_divergance(ExecState *us, ExecState *them)
|
||||
entry = g_slist_next(entry), i++) {
|
||||
ExecInfo *prev = (ExecInfo *) entry->data;
|
||||
g_string_append_printf(out,
|
||||
" previously @ 0x%016" PRIx64 "/%" PRId64
|
||||
" (%ld insns)\n",
|
||||
" previously @ 0x%016lx/%ld (%ld insns)\n",
|
||||
prev->block->pc, prev->block->insns,
|
||||
prev->insn_count);
|
||||
}
|
||||
|
||||
+7
-6
@@ -28,18 +28,19 @@ struct QCryptoHmacDriver {
|
||||
void (*hmac_free)(QCryptoHmac *hmac);
|
||||
};
|
||||
|
||||
void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
|
||||
const uint8_t *key, size_t nkey,
|
||||
Error **errp);
|
||||
extern void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
|
||||
const uint8_t *key, size_t nkey,
|
||||
Error **errp);
|
||||
extern QCryptoHmacDriver qcrypto_hmac_lib_driver;
|
||||
|
||||
#ifdef CONFIG_AF_ALG
|
||||
|
||||
#include "afalgpriv.h"
|
||||
|
||||
QCryptoAFAlg *qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
|
||||
const uint8_t *key, size_t nkey,
|
||||
Error **errp);
|
||||
extern QCryptoAFAlg *
|
||||
qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
|
||||
const uint8_t *key, size_t nkey,
|
||||
Error **errp);
|
||||
extern QCryptoHmacDriver qcrypto_hmac_afalg_driver;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -52,7 +52,7 @@ Those hosts are officially supported, with various accelerators:
|
||||
* - SPARC
|
||||
- tcg
|
||||
* - x86
|
||||
- hvf (64 bit only), kvm, nvmm, tcg, whpx (64 bit only), xen
|
||||
- hax, hvf (64 bit only), kvm, nvmm, tcg, whpx (64 bit only), xen
|
||||
|
||||
Other host architectures are not supported. It is possible to build QEMU system
|
||||
emulation on an unsupported host architecture using the configure
|
||||
|
||||
@@ -105,6 +105,12 @@ Use ``-machine hpet=off`` instead.
|
||||
The ``-no-acpi`` setting has been turned into a machine property.
|
||||
Use ``-machine acpi=off`` instead.
|
||||
|
||||
``-accel hax`` (since 8.0)
|
||||
''''''''''''''''''''''''''
|
||||
|
||||
The HAXM project has been retired (see https://github.com/intel/haxm#status).
|
||||
Use "whpx" (on Windows) or "hvf" (on macOS) instead.
|
||||
|
||||
``-async-teardown`` (since 8.1)
|
||||
'''''''''''''''''''''''''''''''
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ QEMU can be used in several different ways. The most common is for
|
||||
:ref:`System Emulation`, where it provides a virtual model of an
|
||||
entire machine (CPU, memory and emulated devices) to run a guest OS.
|
||||
In this mode the CPU may be fully emulated, or it may work with a
|
||||
hypervisor such as KVM, Xen or Hypervisor.Framework to allow the
|
||||
hypervisor such as KVM, Xen, Hax or Hypervisor.Framework to allow the
|
||||
guest to run directly on the host CPU.
|
||||
|
||||
The second supported way to use QEMU is :ref:`User Mode Emulation`,
|
||||
|
||||
@@ -659,18 +659,15 @@ Use ``Icelake-Server`` instead.
|
||||
System accelerators
|
||||
-------------------
|
||||
|
||||
Userspace local APIC with KVM (x86, removed in 8.0)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
Userspace local APIC with KVM (x86, removed 8.0)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
``-M kernel-irqchip=off`` cannot be used on KVM if the CPU model includes
|
||||
a local APIC. The ``split`` setting is supported, as is using ``-M
|
||||
kernel-irqchip=off`` when the CPU does not have a local APIC.
|
||||
|
||||
HAXM (``-accel hax``) (removed in 8.2)
|
||||
''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The HAXM project has been retired (see https://github.com/intel/haxm#status).
|
||||
Use "whpx" (on Windows) or "hvf" (on macOS) instead.
|
||||
System accelerators
|
||||
-------------------
|
||||
|
||||
MIPS "Trap-and-Emulate" KVM support (removed in 8.0)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
@@ -61,19 +61,19 @@ Under ``tests/avocado/`` as the root we have:
|
||||
::
|
||||
|
||||
$ make check-venv (needed only the first time to create the venv)
|
||||
$ ./pyvenv/bin/avocado run -t acpi tests/avocado
|
||||
$ ./tests/venv/bin/avocado run -t acpi tests/avocado
|
||||
|
||||
The above will run all acpi avocado tests including this one.
|
||||
In order to run the individual tests, perform the following:
|
||||
::
|
||||
|
||||
$ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py --tap -
|
||||
$ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py --tap -
|
||||
|
||||
The above will produce output in tap format. You can omit "--tap -" in the
|
||||
end and it will produce output like the following:
|
||||
::
|
||||
|
||||
$ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py
|
||||
$ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py
|
||||
Fetching asset from tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits
|
||||
JOB ID : eab225724da7b64c012c65705dc2fa14ab1defef
|
||||
JOB LOG : /home/anisinha/avocado/job-results/job-2022-10-10T17.58-eab2257/job.log
|
||||
|
||||
@@ -460,13 +460,17 @@ Built by configure:
|
||||
|
||||
``config-host.mak``
|
||||
When configure has determined the characteristics of the build host it
|
||||
will write the paths to various tools to this file, for use in ``Makefile``
|
||||
and to a smaller extent ``meson.build``.
|
||||
will write them to this file for use in ``Makefile`` and to a smaller
|
||||
extent ``meson.build``. These include the paths to various tools and a
|
||||
variety of ``CONFIG_*`` variables related to optionally enabled features.
|
||||
|
||||
``config-host.mak`` is also used as a dependency checking mechanism. If make
|
||||
sees that the modification timestamp on configure is newer than that on
|
||||
``config-host.mak``, then configure will be re-run.
|
||||
|
||||
The variables defined here apply to all QEMU
|
||||
build outputs.
|
||||
|
||||
``config-meson.cross``
|
||||
|
||||
A Meson "cross file" (or native file) used to communicate the paths to
|
||||
|
||||
@@ -188,10 +188,3 @@ If you've got access to a CentOS Stream 8 x86_64 host that can be
|
||||
used as a gitlab-CI runner, you can set this variable to enable the
|
||||
tests that require this kind of host. The runner should be tagged with
|
||||
both "centos_stream_8" and "x86_64".
|
||||
|
||||
CCACHE_DISABLE
|
||||
~~~~~~~~~~~~~~
|
||||
The jobs are configured to use "ccache" by default since this typically
|
||||
reduces compilation time, at the cost of increased storage. If the
|
||||
use of "ccache" is suspected to be hurting the overall job execution
|
||||
time, setting the "CCACHE_DISABLE=1" env variable to disable it.
|
||||
|
||||
@@ -316,6 +316,6 @@ variable::
|
||||
|
||||
host_kconfig = \
|
||||
(have_tpm ? ['CONFIG_TPM=y'] : []) + \
|
||||
(targetos == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
|
||||
('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
|
||||
(have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
|
||||
...
|
||||
|
||||
@@ -204,14 +204,7 @@ Declarations
|
||||
|
||||
Mixed declarations (interleaving statements and declarations within
|
||||
blocks) are generally not allowed; declarations should be at the beginning
|
||||
of blocks. To avoid accidental re-use it is permissible to declare
|
||||
loop variables inside for loops:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(thing); i++) {
|
||||
/* do something loopy */
|
||||
}
|
||||
of blocks.
|
||||
|
||||
Every now and then, an exception is made for declarations inside a
|
||||
#ifdef or #ifndef block: if the code looks nicer, such declarations can
|
||||
|
||||
+3
-12
@@ -498,12 +498,6 @@ Conditional moves
|
||||
|
|
||||
| Set *dest* to 1 if (*t1* *cond* *t2*) is true, otherwise set to 0.
|
||||
|
||||
* - negsetcond_i32/i64 *dest*, *t1*, *t2*, *cond*
|
||||
|
||||
- | *dest* = -(*t1* *cond* *t2*)
|
||||
|
|
||||
| Set *dest* to -1 if (*t1* *cond* *t2*) is true, otherwise set to 0.
|
||||
|
||||
* - movcond_i32/i64 *dest*, *c1*, *c2*, *v1*, *v2*, *cond*
|
||||
|
||||
- | *dest* = (*c1* *cond* *c2* ? *v1* : *v2*)
|
||||
@@ -718,9 +712,7 @@ E.g. VECL = 1 -> 64 << 1 -> v128, and VECE = 2 -> 1 << 2 -> i32.
|
||||
.. list-table::
|
||||
|
||||
* - mov_vec *v0*, *v1*
|
||||
|
||||
ld_vec *v0*, *t1*
|
||||
|
||||
st_vec *v0*, *t1*
|
||||
|
||||
- | Move, load and store.
|
||||
@@ -890,15 +882,14 @@ sub2_i32, brcond2_i32).
|
||||
On a 64 bit target, the values are transferred between 32 and 64-bit
|
||||
registers using the following ops:
|
||||
|
||||
- extrl_i64_i32
|
||||
- extrh_i64_i32
|
||||
- trunc_shr_i64_i32
|
||||
- ext_i32_i64
|
||||
- extu_i32_i64
|
||||
|
||||
They ensure that the values are correctly truncated or extended when
|
||||
moved from a 32-bit to a 64-bit register or vice-versa. Note that the
|
||||
extrl_i64_i32 and extrh_i64_i32 are optional ops. It is not necessary
|
||||
to implement them if all the following conditions are met:
|
||||
trunc_shr_i64_i32 is an optional op. It is not necessary to implement
|
||||
it if all the following conditions are met:
|
||||
|
||||
- 64-bit registers can hold 32-bit values
|
||||
- 32-bit values in a 64-bit register do not need to stay zero or
|
||||
|
||||
@@ -894,9 +894,9 @@ You can run the avocado tests simply by executing:
|
||||
|
||||
make check-avocado
|
||||
|
||||
This involves the automatic installation, from PyPI, of all the
|
||||
necessary avocado-framework dependencies into the QEMU venv within the
|
||||
build tree (at ``./pyvenv``). Test results are also saved within the
|
||||
This involves the automatic creation of Python virtual environment
|
||||
within the build tree (at ``tests/venv``) which will have all the
|
||||
right dependencies, and will save tests results also within the
|
||||
build tree (at ``tests/results``).
|
||||
|
||||
Note: the build environment must be using a Python 3 stack, and have
|
||||
@@ -953,7 +953,7 @@ may be invoked by running:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run $OPTION1 $OPTION2 tests/avocado/
|
||||
tests/venv/bin/avocado run $OPTION1 $OPTION2 tests/avocado/
|
||||
|
||||
Note that if ``make check-avocado`` was not executed before, it is
|
||||
possible to create the Python virtual environment with the dependencies
|
||||
@@ -968,20 +968,20 @@ a test file. To run tests from a single file within the build tree, use:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE
|
||||
tests/venv/bin/avocado run tests/avocado/$TESTFILE
|
||||
|
||||
To run a single test within a test file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE:$TESTCLASS.$TESTNAME
|
||||
tests/venv/bin/avocado run tests/avocado/$TESTFILE:$TESTCLASS.$TESTNAME
|
||||
|
||||
Valid test names are visible in the output from any previous execution
|
||||
of Avocado or ``make check-avocado``, and can also be queried using:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado list tests/avocado
|
||||
tests/venv/bin/avocado list tests/avocado
|
||||
|
||||
Manual Installation
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -117,13 +117,13 @@ to support the multiple thread compression migration:
|
||||
{qemu} migrate_set_capability compress on
|
||||
|
||||
3. Set the compression thread count on source:
|
||||
{qemu} migrate_set_parameter compress_threads 12
|
||||
{qemu} migrate_set_parameter compress-threads 12
|
||||
|
||||
4. Set the compression level on the source:
|
||||
{qemu} migrate_set_parameter compress_level 1
|
||||
{qemu} migrate_set_parameter compress-level 1
|
||||
|
||||
5. Set the decompression thread count on destination:
|
||||
{qemu} migrate_set_parameter decompress_threads 3
|
||||
{qemu} migrate_set_parameter decompress-threads 3
|
||||
|
||||
6. Start outgoing migration:
|
||||
{qemu} migrate -d tcp:destination.host:4444
|
||||
@@ -133,9 +133,9 @@ to support the multiple thread compression migration:
|
||||
|
||||
The following are the default settings:
|
||||
compress: off
|
||||
compress_threads: 8
|
||||
decompress_threads: 2
|
||||
compress_level: 1 (which means best speed)
|
||||
compress-threads: 8
|
||||
decompress-threads: 2
|
||||
compress-level: 1 (which means best speed)
|
||||
|
||||
So, only the first two steps are required to use the multiple
|
||||
thread compression in migration. You can do more if the default
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ RUNNING:
|
||||
First, set the migration speed to match your hardware's capabilities:
|
||||
|
||||
QEMU Monitor Command:
|
||||
$ migrate_set_parameter max_bandwidth 40g # or whatever is the MAX of your RDMA device
|
||||
$ migrate_set_parameter max-bandwidth 40g # or whatever is the MAX of your RDMA device
|
||||
|
||||
Next, on the destination machine, add the following to the QEMU command line:
|
||||
|
||||
|
||||
@@ -92,8 +92,6 @@ PCI devices (other than virtio):
|
||||
PCI PVPanic device (``-device pvpanic-pci``)
|
||||
1b36:0012
|
||||
PCI ACPI ERST device (``-device acpi-erst``)
|
||||
1b36:0013
|
||||
PCI UFS device (``-device ufs``)
|
||||
|
||||
All these devices are documented in :doc:`index`.
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ To boot a kernel directly from a Linux build tree:
|
||||
-dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
|
||||
-initrd rootfs.cpio
|
||||
|
||||
To boot the machine from the flash image, use an MTD drive :
|
||||
The image should be attached as an MTD drive. Run :
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -117,46 +117,23 @@ Options specific to Aspeed machines are :
|
||||
device by using the FMC controller to load the instructions, and
|
||||
not simply from RAM. This takes a little longer.
|
||||
|
||||
* ``fmc-model`` to change the default FMC Flash model. FW needs
|
||||
support for the chip model to boot.
|
||||
* ``fmc-model`` to change the FMC Flash model. FW needs support for
|
||||
the chip model to boot.
|
||||
|
||||
* ``spi-model`` to change the default SPI Flash model.
|
||||
* ``spi-model`` to change the SPI Flash model.
|
||||
|
||||
* ``bmc-console`` to change the default console device. Most of the
|
||||
machines use the ``UART5`` device for a boot console, which is
|
||||
mapped on ``/dev/ttyS4`` under Linux, but it is not always the
|
||||
case.
|
||||
|
||||
To use other flash models, for instance a different FMC chip and a
|
||||
bigger (64M) SPI for the ``ast2500-evb`` machine, run :
|
||||
For instance, to start the ``ast2500-evb`` machine with a different
|
||||
FMC chip and a bigger (64M) SPI chip, use :
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
-M ast2500-evb,fmc-model=mx25l25635e,spi-model=mx66u51235f
|
||||
|
||||
When more flexibility is needed to define the flash devices, to use
|
||||
different flash models or define all flash devices (up to 8), the
|
||||
``-nodefaults`` QEMU option can be used to avoid creating the default
|
||||
flash devices.
|
||||
|
||||
Flash devices should then be created from the command line and attached
|
||||
to a block device :
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ qemu-system-arm -M ast2600-evb \
|
||||
-blockdev node-name=fmc0,driver=file,filename=/path/to/fmc0.img \
|
||||
-device mx66u51235f,bus=ssi.0,cs=0x0,drive=fmc0 \
|
||||
-blockdev node-name=fmc1,driver=file,filename=/path/to/fmc1.img \
|
||||
-device mx66u51235f,bus=ssi.0,cs=0x1,drive=fmc1 \
|
||||
-blockdev node-name=spi1,driver=file,filename=/path/to/spi1.img \
|
||||
-device mx66u51235f,cs=0x0,bus=ssi.1,drive=spi1 \
|
||||
-nographic -nodefaults
|
||||
|
||||
In that case, the machine boots fetching instructions from the FMC0
|
||||
device. It is slower to start but closer to what HW does. Using the
|
||||
machine option ``execute-in-place`` has a similar effect.
|
||||
|
||||
To change the boot console and use device ``UART3`` (``/dev/ttyS2``
|
||||
under Linux), use :
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ the following architecture extensions:
|
||||
- FEAT_HAFDBS (Hardware management of the access flag and dirty bit state)
|
||||
- FEAT_HCX (Support for the HCRX_EL2 register)
|
||||
- FEAT_HPDS (Hierarchical permission disables)
|
||||
- FEAT_HPDS2 (Translation table page-based hardware attributes)
|
||||
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
|
||||
- FEAT_IDST (ID space trap handling)
|
||||
- FEAT_IESB (Implicit error synchronization event)
|
||||
|
||||
@@ -6,7 +6,7 @@ System Emulation
|
||||
|
||||
This section of the manual is the overall guide for users using QEMU
|
||||
for full system emulation (as opposed to user-mode emulation).
|
||||
This includes working with hypervisors such as KVM, Xen
|
||||
This includes working with hypervisors such as KVM, Xen, Hax
|
||||
or Hypervisor.Framework.
|
||||
|
||||
.. toctree::
|
||||
|
||||
@@ -21,6 +21,9 @@ Tiny Code Generator (TCG) capable of emulating many CPUs.
|
||||
* - Xen
|
||||
- Linux (as dom0)
|
||||
- Arm, x86
|
||||
* - Intel HAXM (hax)
|
||||
- Linux, Windows
|
||||
- x86
|
||||
* - Hypervisor Framework (hvf)
|
||||
- MacOS
|
||||
- x86 (64 bit only), Arm (64 bit only)
|
||||
|
||||
@@ -181,7 +181,7 @@ Audio data is recorded and replay automatically. The command line for recording
|
||||
and replaying must contain identical specifications of audio hardware, e.g.:
|
||||
|
||||
.. parsed-literal::
|
||||
-audio pa,model=ac97
|
||||
-soundhw ac97
|
||||
|
||||
Serial ports
|
||||
------------
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.loongarch.base">
|
||||
<reg name="r0" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r1" bitsize="32" type="code_ptr" group="general"/>
|
||||
<reg name="r2" bitsize="32" type="data_ptr" group="general"/>
|
||||
<reg name="r3" bitsize="32" type="data_ptr" group="general"/>
|
||||
<reg name="r4" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r5" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r6" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r7" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r8" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r9" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r10" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r11" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r12" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r13" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r14" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r15" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r16" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r17" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r18" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r19" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r20" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r21" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r22" bitsize="32" type="data_ptr" group="general"/>
|
||||
<reg name="r23" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r24" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r25" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r26" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r27" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r28" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r29" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r30" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="r31" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="orig_a0" bitsize="32" type="uint32" group="general"/>
|
||||
<reg name="pc" bitsize="32" type="code_ptr" group="general"/>
|
||||
<reg name="badv" bitsize="32" type="code_ptr" group="general"/>
|
||||
</feature>
|
||||
@@ -45,13 +45,6 @@
|
||||
<reg name="f29" bitsize="64" type="fputype" group="float"/>
|
||||
<reg name="f30" bitsize="64" type="fputype" group="float"/>
|
||||
<reg name="f31" bitsize="64" type="fputype" group="float"/>
|
||||
<reg name="fcc0" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc1" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc2" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc3" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc4" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc5" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc6" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc7" bitsize="8" type="uint8" group="float"/>
|
||||
<reg name="fcc" bitsize="64" type="uint64" group="float"/>
|
||||
<reg name="fcsr" bitsize="32" type="uint32" group="float"/>
|
||||
</feature>
|
||||
|
||||
+58
-86
@@ -75,6 +75,8 @@ void gdb_init_gdbserver_state(void)
|
||||
gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
|
||||
}
|
||||
|
||||
bool gdb_has_xml;
|
||||
|
||||
/* writes 2*len+1 bytes in buf */
|
||||
void gdb_memtohex(GString *buf, const uint8_t *mem, int len)
|
||||
{
|
||||
@@ -349,75 +351,67 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
|
||||
}
|
||||
}
|
||||
|
||||
bool gdb_has_xml(void)
|
||||
{
|
||||
return !!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml;
|
||||
}
|
||||
|
||||
static const char *get_feature_xml(const char *p, const char **newp,
|
||||
GDBProcess *process)
|
||||
{
|
||||
size_t len;
|
||||
int i;
|
||||
const char *name;
|
||||
CPUState *cpu = gdb_get_first_cpu_in_process(process);
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
* qXfer:features:read:ANNEX:OFFSET,LENGTH'
|
||||
* ^p ^newp
|
||||
*/
|
||||
char *term = strchr(p, ':');
|
||||
*newp = term + 1;
|
||||
len = term - p;
|
||||
len = 0;
|
||||
while (p[len] && p[len] != ':')
|
||||
len++;
|
||||
*newp = p + len;
|
||||
|
||||
/* Is it the main target xml? */
|
||||
name = NULL;
|
||||
if (strncmp(p, "target.xml", len) == 0) {
|
||||
if (!process->target_xml) {
|
||||
char *buf = process->target_xml;
|
||||
const size_t buf_sz = sizeof(process->target_xml);
|
||||
|
||||
/* Generate the XML description for this CPU. */
|
||||
if (!buf[0]) {
|
||||
GDBRegisterState *r;
|
||||
GString *xml = g_string_new("<?xml version=\"1.0\"?>");
|
||||
|
||||
g_string_append(xml,
|
||||
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
|
||||
"<target>");
|
||||
|
||||
pstrcat(buf, buf_sz,
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
|
||||
"<target>");
|
||||
if (cc->gdb_arch_name) {
|
||||
g_autofree gchar *arch = cc->gdb_arch_name(cpu);
|
||||
g_string_append_printf(xml,
|
||||
"<architecture>%s</architecture>",
|
||||
arch);
|
||||
gchar *arch = cc->gdb_arch_name(cpu);
|
||||
pstrcat(buf, buf_sz, "<architecture>");
|
||||
pstrcat(buf, buf_sz, arch);
|
||||
pstrcat(buf, buf_sz, "</architecture>");
|
||||
g_free(arch);
|
||||
}
|
||||
g_string_append(xml, "<xi:include href=\"");
|
||||
g_string_append(xml, cc->gdb_core_xml_file);
|
||||
g_string_append(xml, "\"/>");
|
||||
pstrcat(buf, buf_sz, "<xi:include href=\"");
|
||||
pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
|
||||
pstrcat(buf, buf_sz, "\"/>");
|
||||
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||
g_string_append(xml, "<xi:include href=\"");
|
||||
g_string_append(xml, r->xml);
|
||||
g_string_append(xml, "\"/>");
|
||||
pstrcat(buf, buf_sz, "<xi:include href=\"");
|
||||
pstrcat(buf, buf_sz, r->xml);
|
||||
pstrcat(buf, buf_sz, "\"/>");
|
||||
}
|
||||
g_string_append(xml, "</target>");
|
||||
|
||||
process->target_xml = g_string_free(xml, false);
|
||||
return process->target_xml;
|
||||
pstrcat(buf, buf_sz, "</target>");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
/* Is it dynamically generated by the target? */
|
||||
if (cc->gdb_get_dynamic_xml) {
|
||||
g_autofree char *xmlname = g_strndup(p, len);
|
||||
char *xmlname = g_strndup(p, len);
|
||||
const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
|
||||
|
||||
g_free(xmlname);
|
||||
if (xml) {
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
/* Is it one of the encoded gdb-xml/ files? */
|
||||
for (int i = 0; xml_builtin[i][0]; i++) {
|
||||
const char *name = xml_builtin[i][0];
|
||||
if ((strncmp(name, p, len) == 0) &&
|
||||
strlen(name) == len) {
|
||||
return xml_builtin[i][1];
|
||||
}
|
||||
for (i = 0; ; i++) {
|
||||
name = xml_builtin[i][0];
|
||||
if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
|
||||
break;
|
||||
}
|
||||
|
||||
/* failed */
|
||||
return NULL;
|
||||
return name ? xml_builtin[i][1] : NULL;
|
||||
}
|
||||
|
||||
static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
|
||||
@@ -456,6 +450,12 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Register a supplemental set of CPU registers. If g_pos is nonzero it
|
||||
specifies the first register number and these registers are included in
|
||||
a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
|
||||
gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
|
||||
*/
|
||||
|
||||
void gdb_register_coprocessor(CPUState *cpu,
|
||||
gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
|
||||
int num_regs, const char *xml, int g_pos)
|
||||
@@ -597,15 +597,6 @@ static int gdb_handle_vcont(const char *p)
|
||||
* or incorrect parameters passed.
|
||||
*/
|
||||
res = 0;
|
||||
|
||||
/*
|
||||
* target_count and last_target keep track of how many CPUs we are going to
|
||||
* step or resume, and a pointer to the state structure of one of them,
|
||||
* respectivelly
|
||||
*/
|
||||
int target_count = 0;
|
||||
CPUState *last_target = NULL;
|
||||
|
||||
while (*p) {
|
||||
if (*p++ != ';') {
|
||||
return -ENOTSUP;
|
||||
@@ -646,9 +637,6 @@ static int gdb_handle_vcont(const char *p)
|
||||
while (cpu) {
|
||||
if (newstates[cpu->cpu_index] == 1) {
|
||||
newstates[cpu->cpu_index] = cur_action;
|
||||
|
||||
target_count++;
|
||||
last_target = cpu;
|
||||
}
|
||||
|
||||
cpu = gdb_next_attached_cpu(cpu);
|
||||
@@ -666,9 +654,6 @@ static int gdb_handle_vcont(const char *p)
|
||||
while (cpu) {
|
||||
if (newstates[cpu->cpu_index] == 1) {
|
||||
newstates[cpu->cpu_index] = cur_action;
|
||||
|
||||
target_count++;
|
||||
last_target = cpu;
|
||||
}
|
||||
|
||||
cpu = gdb_next_cpu_in_process(cpu);
|
||||
@@ -686,25 +671,11 @@ static int gdb_handle_vcont(const char *p)
|
||||
/* only use if no previous match occourred */
|
||||
if (newstates[cpu->cpu_index] == 1) {
|
||||
newstates[cpu->cpu_index] = cur_action;
|
||||
|
||||
target_count++;
|
||||
last_target = cpu;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if we're about to resume a specific set of CPUs/threads, make it so that
|
||||
* in case execution gets interrupted, we can send GDB a stop reply with a
|
||||
* correct value. it doesn't really matter which CPU we tell GDB the signal
|
||||
* happened in (VM pauses stop all of them anyway), so long as it is one of
|
||||
* the ones we resumed/single stepped here.
|
||||
*/
|
||||
if (target_count > 0) {
|
||||
gdbserver_state.c_cpu = last_target;
|
||||
}
|
||||
|
||||
gdbserver_state.signal = signal;
|
||||
gdb_continue_partial(newstates);
|
||||
return res;
|
||||
@@ -836,7 +807,7 @@ static inline int startswith(const char *string, const char *pattern)
|
||||
return !strncmp(string, pattern, strlen(pattern));
|
||||
}
|
||||
|
||||
static int process_string_cmd(const char *data,
|
||||
static int process_string_cmd(void *user_ctx, const char *data,
|
||||
const GdbCmdParseEntry *cmds, int num_cmds)
|
||||
{
|
||||
int i;
|
||||
@@ -863,7 +834,7 @@ static int process_string_cmd(const char *data,
|
||||
}
|
||||
|
||||
gdbserver_state.allow_stop_reply = cmd->allow_stop_reply;
|
||||
cmd->handler(params, NULL);
|
||||
cmd->handler(params, user_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -881,7 +852,7 @@ static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
|
||||
|
||||
/* In case there was an error during the command parsing we must
|
||||
* send a NULL packet to indicate the command is not supported */
|
||||
if (process_string_cmd(data, cmd, 1)) {
|
||||
if (process_string_cmd(NULL, data, cmd, 1)) {
|
||||
gdb_put_packet("");
|
||||
}
|
||||
}
|
||||
@@ -1081,7 +1052,7 @@ static void handle_set_reg(GArray *params, void *user_ctx)
|
||||
{
|
||||
int reg_size;
|
||||
|
||||
if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
|
||||
if (!gdb_has_xml) {
|
||||
gdb_put_packet("");
|
||||
return;
|
||||
}
|
||||
@@ -1102,7 +1073,7 @@ static void handle_get_reg(GArray *params, void *user_ctx)
|
||||
{
|
||||
int reg_size;
|
||||
|
||||
if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
|
||||
if (!gdb_has_xml) {
|
||||
gdb_put_packet("");
|
||||
return;
|
||||
}
|
||||
@@ -1394,7 +1365,7 @@ static void handle_v_commands(GArray *params, void *user_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
if (process_string_cmd(get_param(params, 0)->data,
|
||||
if (process_string_cmd(NULL, get_param(params, 0)->data,
|
||||
gdb_v_commands_table,
|
||||
ARRAY_SIZE(gdb_v_commands_table))) {
|
||||
gdb_put_packet("");
|
||||
@@ -1569,6 +1540,7 @@ static void handle_query_xfer_features(GArray *params, void *user_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
gdb_has_xml = true;
|
||||
p = get_param(params, 0)->data;
|
||||
xml = get_feature_xml(p, &p, process);
|
||||
if (!xml) {
|
||||
@@ -1737,13 +1709,13 @@ static void handle_gen_query(GArray *params, void *user_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!process_string_cmd(get_param(params, 0)->data,
|
||||
if (!process_string_cmd(NULL, get_param(params, 0)->data,
|
||||
gdb_gen_query_set_common_table,
|
||||
ARRAY_SIZE(gdb_gen_query_set_common_table))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (process_string_cmd(get_param(params, 0)->data,
|
||||
if (process_string_cmd(NULL, get_param(params, 0)->data,
|
||||
gdb_gen_query_table,
|
||||
ARRAY_SIZE(gdb_gen_query_table))) {
|
||||
gdb_put_packet("");
|
||||
@@ -1756,13 +1728,13 @@ static void handle_gen_set(GArray *params, void *user_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!process_string_cmd(get_param(params, 0)->data,
|
||||
if (!process_string_cmd(NULL, get_param(params, 0)->data,
|
||||
gdb_gen_query_set_common_table,
|
||||
ARRAY_SIZE(gdb_gen_query_set_common_table))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (process_string_cmd(get_param(params, 0)->data,
|
||||
if (process_string_cmd(NULL, get_param(params, 0)->data,
|
||||
gdb_gen_set_table,
|
||||
ARRAY_SIZE(gdb_gen_set_table))) {
|
||||
gdb_put_packet("");
|
||||
@@ -2244,6 +2216,6 @@ void gdb_create_default_process(GDBState *s)
|
||||
process = &s->processes[s->process_num - 1];
|
||||
process->pid = pid;
|
||||
process->attached = false;
|
||||
process->target_xml = NULL;
|
||||
process->target_xml[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -33,8 +33,7 @@ typedef struct GDBProcess {
|
||||
uint32_t pid;
|
||||
bool attached;
|
||||
|
||||
/* If gdb sends qXfer:features:read:target.xml this will be populated */
|
||||
char *target_xml;
|
||||
char target_xml[1024];
|
||||
} GDBProcess;
|
||||
|
||||
enum RSState {
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ gdb_system_ss = ss.source_set()
|
||||
gdb_user_ss.add(files('gdbstub.c', 'user.c'))
|
||||
gdb_system_ss.add(files('gdbstub.c', 'softmmu.c'))
|
||||
|
||||
gdb_user_ss = gdb_user_ss.apply(config_targetos, strict: false)
|
||||
gdb_system_ss = gdb_system_ss.apply(config_targetos, strict: false)
|
||||
gdb_user_ss = gdb_user_ss.apply(config_host, strict: false)
|
||||
gdb_system_ss = gdb_system_ss.apply(config_host, strict: false)
|
||||
|
||||
libgdb_user = static_library('gdb_user',
|
||||
gdb_user_ss.sources() + genh,
|
||||
|
||||
@@ -97,6 +97,7 @@ static void gdb_chr_event(void *opaque, QEMUChrEvent event)
|
||||
|
||||
vm_stop(RUN_STATE_PAUSED);
|
||||
replay_gdb_attached();
|
||||
gdb_has_xml = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -198,6 +198,7 @@ static void gdb_accept_init(int fd)
|
||||
gdbserver_state.c_cpu = gdb_first_attached_cpu();
|
||||
gdbserver_state.g_cpu = gdbserver_state.c_cpu;
|
||||
gdbserver_user_state.fd = fd;
|
||||
gdb_has_xml = false;
|
||||
}
|
||||
|
||||
static bool gdb_accept_socket(int gdb_fd)
|
||||
|
||||
@@ -38,7 +38,6 @@ source smbios/Kconfig
|
||||
source ssi/Kconfig
|
||||
source timer/Kconfig
|
||||
source tpm/Kconfig
|
||||
source ufs/Kconfig
|
||||
source usb/Kconfig
|
||||
source virtio/Kconfig
|
||||
source vfio/Kconfig
|
||||
|
||||
@@ -85,8 +85,6 @@ static Property iotkit_properties[] = {
|
||||
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
|
||||
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
|
||||
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
|
||||
DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
|
||||
DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
@@ -100,10 +98,6 @@ static Property sse200_properties[] = {
|
||||
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
|
||||
DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
|
||||
DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
|
||||
DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
|
||||
DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
|
||||
DEFINE_PROP_UINT32("CPU1_MPU_NS", ARMSSE, cpu_mpu_ns[1], 8),
|
||||
DEFINE_PROP_UINT32("CPU1_MPU_S", ARMSSE, cpu_mpu_s[1], 8),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
@@ -115,8 +109,6 @@ static Property sse300_properties[] = {
|
||||
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
|
||||
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
|
||||
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
|
||||
DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
|
||||
DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
@@ -1037,14 +1029,6 @@ static void armsse_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!object_property_set_uint(cpuobj, "mpu-ns-regions",
|
||||
s->cpu_mpu_ns[i], errp)) {
|
||||
return;
|
||||
}
|
||||
if (!object_property_set_uint(cpuobj, "mpu-s-regions",
|
||||
s->cpu_mpu_s[i], errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
|
||||
|
||||
@@ -334,25 +334,6 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Real M-profile hardware can be configured with a different number of
|
||||
* MPU regions for Secure vs NonSecure. QEMU's CPU implementation doesn't
|
||||
* support that yet, so catch attempts to select that.
|
||||
*/
|
||||
if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
|
||||
s->mpu_ns_regions != s->mpu_s_regions) {
|
||||
error_setg(errp,
|
||||
"mpu-ns-regions and mpu-s-regions properties must have the same value");
|
||||
return;
|
||||
}
|
||||
if (s->mpu_ns_regions != UINT_MAX &&
|
||||
object_property_find(OBJECT(s->cpu), "pmsav7-dregion")) {
|
||||
if (!object_property_set_uint(OBJECT(s->cpu), "pmsav7-dregion",
|
||||
s->mpu_ns_regions, errp)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
|
||||
* have one. Similarly, tell the NVIC where its CPU is.
|
||||
@@ -549,8 +530,6 @@ static Property armv7m_properties[] = {
|
||||
false),
|
||||
DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
|
||||
DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
|
||||
DEFINE_PROP_UINT32("mpu-ns-regions", ARMv7MState, mpu_ns_regions, UINT_MAX),
|
||||
DEFINE_PROP_UINT32("mpu-s-regions", ARMv7MState, mpu_s_regions, UINT_MAX),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
||||
+21
-19
@@ -15,7 +15,6 @@
|
||||
#include "hw/arm/aspeed.h"
|
||||
#include "hw/arm/aspeed_soc.h"
|
||||
#include "hw/arm/aspeed_eeprom.h"
|
||||
#include "hw/block/flash.h"
|
||||
#include "hw/i2c/i2c_mux_pca954x.h"
|
||||
#include "hw/i2c/smbus_eeprom.h"
|
||||
#include "hw/misc/pca9552.h"
|
||||
@@ -48,13 +47,6 @@ struct AspeedMachineState {
|
||||
char *spi_model;
|
||||
};
|
||||
|
||||
/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */
|
||||
#if HOST_LONG_BITS == 32
|
||||
#define ASPEED_RAM_SIZE(sz) MIN((sz), 1 * GiB)
|
||||
#else
|
||||
#define ASPEED_RAM_SIZE(sz) (sz)
|
||||
#endif
|
||||
|
||||
/* Palmetto hardware value: 0x120CE416 */
|
||||
#define PALMETTO_BMC_HW_STRAP1 ( \
|
||||
SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \
|
||||
@@ -308,14 +300,17 @@ void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
|
||||
qemu_irq cs_line;
|
||||
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);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
|
||||
qdev_connect_gpio_out_named(DEVICE(s), "cs", i, cs_line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,14 +392,12 @@ static void aspeed_machine_init(MachineState *machine)
|
||||
connect_serial_hds_to_uarts(bmc);
|
||||
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
|
||||
|
||||
if (defaults_enabled()) {
|
||||
aspeed_board_init_flashes(&bmc->soc.fmc,
|
||||
aspeed_board_init_flashes(&bmc->soc.fmc,
|
||||
bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
|
||||
amc->num_cs, 0);
|
||||
aspeed_board_init_flashes(&bmc->soc.spi[0],
|
||||
aspeed_board_init_flashes(&bmc->soc.spi[0],
|
||||
bmc->spi_model ? bmc->spi_model : amc->spi_model,
|
||||
1, amc->num_cs);
|
||||
}
|
||||
|
||||
if (machine->kernel_filename && sc->num_cpus > 1) {
|
||||
/* With no u-boot we must set up a boot stub for the secondary CPU */
|
||||
@@ -437,12 +430,11 @@ static void aspeed_machine_init(MachineState *machine)
|
||||
}
|
||||
|
||||
if (!bmc->mmio_exec) {
|
||||
DeviceState *dev = ssi_get_cs(bmc->soc.fmc.spi, 0);
|
||||
BlockBackend *fmc0 = dev ? m25p80_get_blk(dev) : NULL;
|
||||
DriveInfo *mtd0 = drive_get(IF_MTD, 0, 0);
|
||||
|
||||
if (fmc0) {
|
||||
if (mtd0) {
|
||||
uint64_t rom_size = memory_region_size(&bmc->soc.spi_boot);
|
||||
aspeed_install_boot_rom(bmc, fmc0, rom_size);
|
||||
aspeed_install_boot_rom(bmc, blk_by_legacy_dinfo(mtd0), rom_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1431,7 +1423,12 @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
|
||||
aspeed_soc_num_cpus(amc->soc_name);
|
||||
};
|
||||
|
||||
#define FUJI_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB)
|
||||
/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */
|
||||
#if HOST_LONG_BITS == 32
|
||||
#define FUJI_BMC_RAM_SIZE (1 * GiB)
|
||||
#else
|
||||
#define FUJI_BMC_RAM_SIZE (2 * GiB)
|
||||
#endif
|
||||
|
||||
static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
@@ -1453,7 +1450,12 @@ static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
|
||||
aspeed_soc_num_cpus(amc->soc_name);
|
||||
};
|
||||
|
||||
#define BLETCHLEY_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB)
|
||||
/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */
|
||||
#if HOST_LONG_BITS == 32
|
||||
#define BLETCHLEY_BMC_RAM_SIZE (1 * GiB)
|
||||
#else
|
||||
#define BLETCHLEY_BMC_RAM_SIZE (2 * GiB)
|
||||
#endif
|
||||
|
||||
static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
|
||||
+60
-114
@@ -64,7 +64,12 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
|
||||
|
||||
/*
|
||||
* GPIOs
|
||||
* GPR
|
||||
*/
|
||||
object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
|
||||
|
||||
/*
|
||||
* GPIOs 1 to 5
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
|
||||
snprintf(name, NAME_SIZE, "gpio%d", i);
|
||||
@@ -72,7 +77,7 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* GPTs
|
||||
* GPT 1, 2
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
|
||||
snprintf(name, NAME_SIZE, "gpt%d", i);
|
||||
@@ -80,7 +85,7 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* EPITs
|
||||
* EPIT 1, 2
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
|
||||
snprintf(name, NAME_SIZE, "epit%d", i + 1);
|
||||
@@ -88,7 +93,7 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* eCSPIs
|
||||
* eCSPI
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
|
||||
snprintf(name, NAME_SIZE, "spi%d", i + 1);
|
||||
@@ -96,7 +101,7 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* I2Cs
|
||||
* I2C
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
|
||||
snprintf(name, NAME_SIZE, "i2c%d", i + 1);
|
||||
@@ -104,7 +109,7 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* UARTs
|
||||
* UART
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
|
||||
snprintf(name, NAME_SIZE, "uart%d", i);
|
||||
@@ -112,31 +117,25 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* Ethernets
|
||||
* Ethernet
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
|
||||
snprintf(name, NAME_SIZE, "eth%d", i);
|
||||
object_initialize_child(obj, name, &s->eth[i], TYPE_IMX_ENET);
|
||||
}
|
||||
|
||||
/*
|
||||
* USB PHYs
|
||||
*/
|
||||
/* USB */
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
|
||||
snprintf(name, NAME_SIZE, "usbphy%d", i);
|
||||
object_initialize_child(obj, name, &s->usbphy[i], TYPE_IMX_USBPHY);
|
||||
}
|
||||
|
||||
/*
|
||||
* USBs
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
|
||||
snprintf(name, NAME_SIZE, "usb%d", i);
|
||||
object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
|
||||
}
|
||||
|
||||
/*
|
||||
* SDHCIs
|
||||
* SDHCI
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
|
||||
snprintf(name, NAME_SIZE, "usdhc%d", i);
|
||||
@@ -144,7 +143,7 @@ static void fsl_imx6ul_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* Watchdogs
|
||||
* Watchdog
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
|
||||
snprintf(name, NAME_SIZE, "wdt%d", i);
|
||||
@@ -190,10 +189,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
* A7MPCORE DAP
|
||||
*/
|
||||
create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
|
||||
FSL_IMX6UL_A7MPCORE_DAP_SIZE);
|
||||
0x100000);
|
||||
|
||||
/*
|
||||
* GPTs
|
||||
* GPT 1, 2
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
|
||||
@@ -218,7 +217,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* EPITs
|
||||
* EPIT 1, 2
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
|
||||
@@ -243,7 +242,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* GPIOs
|
||||
* GPIO
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
|
||||
@@ -285,12 +284,17 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* IOMUXC
|
||||
* IOMUXC and IOMUXC_GPR
|
||||
*/
|
||||
create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
|
||||
FSL_IMX6UL_IOMUXC_SIZE);
|
||||
create_unimplemented_device("iomuxc_gpr", FSL_IMX6UL_IOMUXC_GPR_ADDR,
|
||||
FSL_IMX6UL_IOMUXC_GPR_SIZE);
|
||||
for (i = 0; i < 1; i++) {
|
||||
static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
|
||||
FSL_IMX6UL_IOMUXC_ADDR,
|
||||
FSL_IMX6UL_IOMUXC_GPR_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "iomuxc%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
|
||||
}
|
||||
|
||||
/*
|
||||
* CCM
|
||||
@@ -310,9 +314,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
|
||||
|
||||
/*
|
||||
* ECSPIs
|
||||
*/
|
||||
/* Initialize all ECSPI */
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
|
||||
FSL_IMX6UL_ECSPI1_ADDR,
|
||||
@@ -340,7 +342,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* I2Cs
|
||||
* I2C
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
|
||||
@@ -366,7 +368,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* UARTs
|
||||
* UART
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
|
||||
@@ -404,7 +406,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* Ethernets
|
||||
* Ethernet
|
||||
*
|
||||
* We must use two loops since phy_connected affects the other interface
|
||||
* and we have to set all properties before calling sysbus_realize().
|
||||
@@ -457,45 +459,28 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
* USB PHYs
|
||||
*/
|
||||
/* USB */
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
|
||||
static const hwaddr
|
||||
FSL_IMX6UL_USB_PHYn_ADDR[FSL_IMX6UL_NUM_USB_PHYS] = {
|
||||
FSL_IMX6UL_USBPHY1_ADDR,
|
||||
FSL_IMX6UL_USBPHY2_ADDR,
|
||||
};
|
||||
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->usbphy[i]), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
|
||||
FSL_IMX6UL_USB_PHYn_ADDR[i]);
|
||||
FSL_IMX6UL_USBPHY1_ADDR + i * 0x1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* USBs
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_USB02_USBn_ADDR[FSL_IMX6UL_NUM_USBS] = {
|
||||
FSL_IMX6UL_USBO2_USB1_ADDR,
|
||||
FSL_IMX6UL_USBO2_USB2_ADDR,
|
||||
};
|
||||
|
||||
static const int FSL_IMX6UL_USBn_IRQ[] = {
|
||||
FSL_IMX6UL_USB1_IRQ,
|
||||
FSL_IMX6UL_USB2_IRQ,
|
||||
};
|
||||
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
|
||||
FSL_IMX6UL_USB02_USBn_ADDR[i]);
|
||||
FSL_IMX6UL_USBO2_USB_ADDR + i * 0x200);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->a7mpcore),
|
||||
FSL_IMX6UL_USBn_IRQ[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
* USDHCs
|
||||
* USDHC
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
|
||||
@@ -527,7 +512,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
|
||||
|
||||
/*
|
||||
* Watchdogs
|
||||
* Watchdog
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
|
||||
@@ -535,7 +520,6 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
FSL_IMX6UL_WDOG2_ADDR,
|
||||
FSL_IMX6UL_WDOG3_ADDR,
|
||||
};
|
||||
|
||||
static const int FSL_IMX6UL_WDOGn_IRQ[FSL_IMX6UL_NUM_WDTS] = {
|
||||
FSL_IMX6UL_WDOG1_IRQ,
|
||||
FSL_IMX6UL_WDOG2_IRQ,
|
||||
@@ -553,66 +537,42 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
FSL_IMX6UL_WDOGn_IRQ[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
* GPR
|
||||
*/
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);
|
||||
|
||||
/*
|
||||
* SDMA
|
||||
*/
|
||||
create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR,
|
||||
FSL_IMX6UL_SDMA_SIZE);
|
||||
create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);
|
||||
|
||||
/*
|
||||
* SAIs (Audio SSI (Synchronous Serial Interface))
|
||||
* SAI (Audio SSI (Synchronous Serial Interface))
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_SAIS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_SAIn_ADDR[FSL_IMX6UL_NUM_SAIS] = {
|
||||
FSL_IMX6UL_SAI1_ADDR,
|
||||
FSL_IMX6UL_SAI2_ADDR,
|
||||
FSL_IMX6UL_SAI3_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "sai%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX6UL_SAIn_ADDR[i],
|
||||
FSL_IMX6UL_SAIn_SIZE);
|
||||
}
|
||||
create_unimplemented_device("sai1", FSL_IMX6UL_SAI1_ADDR, 0x4000);
|
||||
create_unimplemented_device("sai2", FSL_IMX6UL_SAI2_ADDR, 0x4000);
|
||||
create_unimplemented_device("sai3", FSL_IMX6UL_SAI3_ADDR, 0x4000);
|
||||
|
||||
/*
|
||||
* PWMs
|
||||
* PWM
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_PWMS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_PWMn_ADDR[FSL_IMX6UL_NUM_PWMS] = {
|
||||
FSL_IMX6UL_PWM1_ADDR,
|
||||
FSL_IMX6UL_PWM2_ADDR,
|
||||
FSL_IMX6UL_PWM3_ADDR,
|
||||
FSL_IMX6UL_PWM4_ADDR,
|
||||
FSL_IMX6UL_PWM5_ADDR,
|
||||
FSL_IMX6UL_PWM6_ADDR,
|
||||
FSL_IMX6UL_PWM7_ADDR,
|
||||
FSL_IMX6UL_PWM8_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "pwm%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX6UL_PWMn_ADDR[i],
|
||||
FSL_IMX6UL_PWMn_SIZE);
|
||||
}
|
||||
create_unimplemented_device("pwm1", FSL_IMX6UL_PWM1_ADDR, 0x4000);
|
||||
create_unimplemented_device("pwm2", FSL_IMX6UL_PWM2_ADDR, 0x4000);
|
||||
create_unimplemented_device("pwm3", FSL_IMX6UL_PWM3_ADDR, 0x4000);
|
||||
create_unimplemented_device("pwm4", FSL_IMX6UL_PWM4_ADDR, 0x4000);
|
||||
|
||||
/*
|
||||
* Audio ASRC (asynchronous sample rate converter)
|
||||
*/
|
||||
create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR,
|
||||
FSL_IMX6UL_ASRC_SIZE);
|
||||
create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR, 0x4000);
|
||||
|
||||
/*
|
||||
* CANs
|
||||
* CAN
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX6UL_NUM_CANS; i++) {
|
||||
static const hwaddr FSL_IMX6UL_CANn_ADDR[FSL_IMX6UL_NUM_CANS] = {
|
||||
FSL_IMX6UL_CAN1_ADDR,
|
||||
FSL_IMX6UL_CAN2_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "can%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX6UL_CANn_ADDR[i],
|
||||
FSL_IMX6UL_CANn_SIZE);
|
||||
}
|
||||
create_unimplemented_device("can1", FSL_IMX6UL_CAN1_ADDR, 0x4000);
|
||||
create_unimplemented_device("can2", FSL_IMX6UL_CAN2_ADDR, 0x4000);
|
||||
|
||||
/*
|
||||
* APHB_DMA
|
||||
@@ -630,27 +590,13 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "adc%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i],
|
||||
FSL_IMX6UL_ADCn_SIZE);
|
||||
create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000);
|
||||
}
|
||||
|
||||
/*
|
||||
* LCD
|
||||
*/
|
||||
create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
|
||||
FSL_IMX6UL_LCDIF_SIZE);
|
||||
|
||||
/*
|
||||
* CSU
|
||||
*/
|
||||
create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
|
||||
FSL_IMX6UL_CSU_SIZE);
|
||||
|
||||
/*
|
||||
* TZASC
|
||||
*/
|
||||
create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
|
||||
FSL_IMX6UL_TZASC_SIZE);
|
||||
create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000);
|
||||
|
||||
/*
|
||||
* ROM memory
|
||||
|
||||
+40
-161
@@ -36,9 +36,6 @@ static void fsl_imx7_init(Object *obj)
|
||||
char name[NAME_SIZE];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* CPUs
|
||||
*/
|
||||
for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
|
||||
snprintf(name, NAME_SIZE, "cpu%d", i);
|
||||
object_initialize_child(obj, name, &s->cpu[i],
|
||||
@@ -52,7 +49,7 @@ static void fsl_imx7_init(Object *obj)
|
||||
TYPE_A15MPCORE_PRIV);
|
||||
|
||||
/*
|
||||
* GPIOs
|
||||
* GPIOs 1 to 7
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
|
||||
snprintf(name, NAME_SIZE, "gpio%d", i);
|
||||
@@ -60,7 +57,7 @@ static void fsl_imx7_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* GPTs
|
||||
* GPT1, 2, 3, 4
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
|
||||
snprintf(name, NAME_SIZE, "gpt%d", i);
|
||||
@@ -82,29 +79,19 @@ static void fsl_imx7_init(Object *obj)
|
||||
*/
|
||||
object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
|
||||
|
||||
/*
|
||||
* SRC
|
||||
*/
|
||||
object_initialize_child(obj, "src", &s->src, TYPE_IMX7_SRC);
|
||||
|
||||
/*
|
||||
* ECSPIs
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
|
||||
snprintf(name, NAME_SIZE, "spi%d", i + 1);
|
||||
object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
|
||||
}
|
||||
|
||||
/*
|
||||
* I2Cs
|
||||
*/
|
||||
|
||||
for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
|
||||
snprintf(name, NAME_SIZE, "i2c%d", i + 1);
|
||||
object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
|
||||
}
|
||||
|
||||
/*
|
||||
* UARTs
|
||||
* UART
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
|
||||
snprintf(name, NAME_SIZE, "uart%d", i);
|
||||
@@ -112,7 +99,7 @@ static void fsl_imx7_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* Ethernets
|
||||
* Ethernet
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
|
||||
snprintf(name, NAME_SIZE, "eth%d", i);
|
||||
@@ -120,7 +107,7 @@ static void fsl_imx7_init(Object *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* SDHCIs
|
||||
* SDHCI
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
|
||||
snprintf(name, NAME_SIZE, "usdhc%d", i);
|
||||
@@ -133,7 +120,7 @@ static void fsl_imx7_init(Object *obj)
|
||||
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
|
||||
|
||||
/*
|
||||
* Watchdogs
|
||||
* Watchdog
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
|
||||
snprintf(name, NAME_SIZE, "wdt%d", i);
|
||||
@@ -145,14 +132,8 @@ static void fsl_imx7_init(Object *obj)
|
||||
*/
|
||||
object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
|
||||
|
||||
/*
|
||||
* PCIE
|
||||
*/
|
||||
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
|
||||
|
||||
/*
|
||||
* USBs
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
|
||||
snprintf(name, NAME_SIZE, "usb%d", i);
|
||||
object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
|
||||
@@ -175,9 +156,6 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPUs
|
||||
*/
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
o = OBJECT(&s->cpu[i]);
|
||||
|
||||
@@ -228,10 +206,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
* A7MPCORE DAP
|
||||
*/
|
||||
create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
|
||||
FSL_IMX7_A7MPCORE_DAP_SIZE);
|
||||
0x100000);
|
||||
|
||||
/*
|
||||
* GPTs
|
||||
* GPT1, 2, 3, 4
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
|
||||
static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
|
||||
@@ -256,9 +234,6 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
FSL_IMX7_GPTn_IRQ[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
* GPIOs
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
|
||||
static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
|
||||
FSL_IMX7_GPIO1_ADDR,
|
||||
@@ -306,10 +281,16 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
/*
|
||||
* IOMUXC and IOMUXC_LPSR
|
||||
*/
|
||||
create_unimplemented_device("iomuxc", FSL_IMX7_IOMUXC_ADDR,
|
||||
FSL_IMX7_IOMUXC_SIZE);
|
||||
create_unimplemented_device("iomuxc_lspr", FSL_IMX7_IOMUXC_LPSR_ADDR,
|
||||
FSL_IMX7_IOMUXC_LPSR_SIZE);
|
||||
for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
|
||||
static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
|
||||
FSL_IMX7_IOMUXC_ADDR,
|
||||
FSL_IMX7_IOMUXC_LPSR_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "iomuxc%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
|
||||
FSL_IMX7_IOMUXCn_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* CCM
|
||||
@@ -329,9 +310,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
|
||||
|
||||
/*
|
||||
* ECSPIs
|
||||
*/
|
||||
/* Initialize all ECSPI */
|
||||
for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
|
||||
static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
|
||||
FSL_IMX7_ECSPI1_ADDR,
|
||||
@@ -356,9 +335,6 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
FSL_IMX7_SPIn_IRQ[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
* I2Cs
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
|
||||
static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
|
||||
FSL_IMX7_I2C1_ADDR,
|
||||
@@ -383,7 +359,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* UARTs
|
||||
* UART
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
|
||||
static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
|
||||
@@ -418,7 +394,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* Ethernets
|
||||
* Ethernet
|
||||
*
|
||||
* We must use two loops since phy_connected affects the other interface
|
||||
* and we have to set all properties before calling sysbus_realize().
|
||||
@@ -458,7 +434,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/*
|
||||
* USDHCs
|
||||
* USDHC
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
|
||||
static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
|
||||
@@ -488,16 +464,15 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
* SNVS
|
||||
*/
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_HP_ADDR);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_ADDR);
|
||||
|
||||
/*
|
||||
* SRC
|
||||
*/
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX7_SRC_ADDR);
|
||||
create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
|
||||
|
||||
/*
|
||||
* Watchdogs
|
||||
* Watchdog
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
|
||||
static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
|
||||
@@ -534,49 +509,25 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
create_unimplemented_device("caam", FSL_IMX7_CAAM_ADDR, FSL_IMX7_CAAM_SIZE);
|
||||
|
||||
/*
|
||||
* PWMs
|
||||
* PWM
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_PWMS; i++) {
|
||||
static const hwaddr FSL_IMX7_PWMn_ADDR[FSL_IMX7_NUM_PWMS] = {
|
||||
FSL_IMX7_PWM1_ADDR,
|
||||
FSL_IMX7_PWM2_ADDR,
|
||||
FSL_IMX7_PWM3_ADDR,
|
||||
FSL_IMX7_PWM4_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "pwm%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX7_PWMn_ADDR[i],
|
||||
FSL_IMX7_PWMn_SIZE);
|
||||
}
|
||||
create_unimplemented_device("pwm1", FSL_IMX7_PWM1_ADDR, FSL_IMX7_PWMn_SIZE);
|
||||
create_unimplemented_device("pwm2", FSL_IMX7_PWM2_ADDR, FSL_IMX7_PWMn_SIZE);
|
||||
create_unimplemented_device("pwm3", FSL_IMX7_PWM3_ADDR, FSL_IMX7_PWMn_SIZE);
|
||||
create_unimplemented_device("pwm4", FSL_IMX7_PWM4_ADDR, FSL_IMX7_PWMn_SIZE);
|
||||
|
||||
/*
|
||||
* CANs
|
||||
* CAN
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_CANS; i++) {
|
||||
static const hwaddr FSL_IMX7_CANn_ADDR[FSL_IMX7_NUM_CANS] = {
|
||||
FSL_IMX7_CAN1_ADDR,
|
||||
FSL_IMX7_CAN2_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "can%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX7_CANn_ADDR[i],
|
||||
FSL_IMX7_CANn_SIZE);
|
||||
}
|
||||
create_unimplemented_device("can1", FSL_IMX7_CAN1_ADDR, FSL_IMX7_CANn_SIZE);
|
||||
create_unimplemented_device("can2", FSL_IMX7_CAN2_ADDR, FSL_IMX7_CANn_SIZE);
|
||||
|
||||
/*
|
||||
* SAIs (Audio SSI (Synchronous Serial Interface))
|
||||
* SAI (Audio SSI (Synchronous Serial Interface))
|
||||
*/
|
||||
for (i = 0; i < FSL_IMX7_NUM_SAIS; i++) {
|
||||
static const hwaddr FSL_IMX7_SAIn_ADDR[FSL_IMX7_NUM_SAIS] = {
|
||||
FSL_IMX7_SAI1_ADDR,
|
||||
FSL_IMX7_SAI2_ADDR,
|
||||
FSL_IMX7_SAI3_ADDR,
|
||||
};
|
||||
|
||||
snprintf(name, NAME_SIZE, "sai%d", i);
|
||||
create_unimplemented_device(name, FSL_IMX7_SAIn_ADDR[i],
|
||||
FSL_IMX7_SAIn_SIZE);
|
||||
}
|
||||
create_unimplemented_device("sai1", FSL_IMX7_SAI1_ADDR, FSL_IMX7_SAIn_SIZE);
|
||||
create_unimplemented_device("sai2", FSL_IMX7_SAI2_ADDR, FSL_IMX7_SAIn_SIZE);
|
||||
create_unimplemented_device("sai2", FSL_IMX7_SAI3_ADDR, FSL_IMX7_SAIn_SIZE);
|
||||
|
||||
/*
|
||||
* OCOTP
|
||||
@@ -584,15 +535,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
create_unimplemented_device("ocotp", FSL_IMX7_OCOTP_ADDR,
|
||||
FSL_IMX7_OCOTP_SIZE);
|
||||
|
||||
/*
|
||||
* GPR
|
||||
*/
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_IOMUXC_GPR_ADDR);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_GPR_ADDR);
|
||||
|
||||
/*
|
||||
* PCIE
|
||||
*/
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
|
||||
|
||||
@@ -605,9 +550,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
|
||||
|
||||
/*
|
||||
* USBs
|
||||
*/
|
||||
|
||||
for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
|
||||
static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
|
||||
FSL_IMX7_USBMISC1_ADDR,
|
||||
@@ -669,70 +612,6 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
|
||||
*/
|
||||
create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
|
||||
FSL_IMX7_PCIE_PHY_SIZE);
|
||||
|
||||
/*
|
||||
* CSU
|
||||
*/
|
||||
create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
|
||||
FSL_IMX7_CSU_SIZE);
|
||||
|
||||
/*
|
||||
* TZASC
|
||||
*/
|
||||
create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
|
||||
FSL_IMX7_TZASC_SIZE);
|
||||
|
||||
/*
|
||||
* OCRAM memory
|
||||
*/
|
||||
memory_region_init_ram(&s->ocram, NULL, "imx7.ocram",
|
||||
FSL_IMX7_OCRAM_MEM_SIZE,
|
||||
&error_abort);
|
||||
memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
|
||||
&s->ocram);
|
||||
|
||||
/*
|
||||
* OCRAM EPDC memory
|
||||
*/
|
||||
memory_region_init_ram(&s->ocram_epdc, NULL, "imx7.ocram_epdc",
|
||||
FSL_IMX7_OCRAM_EPDC_SIZE,
|
||||
&error_abort);
|
||||
memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
|
||||
&s->ocram_epdc);
|
||||
|
||||
/*
|
||||
* OCRAM PXP memory
|
||||
*/
|
||||
memory_region_init_ram(&s->ocram_pxp, NULL, "imx7.ocram_pxp",
|
||||
FSL_IMX7_OCRAM_PXP_SIZE,
|
||||
&error_abort);
|
||||
memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
|
||||
&s->ocram_pxp);
|
||||
|
||||
/*
|
||||
* OCRAM_S memory
|
||||
*/
|
||||
memory_region_init_ram(&s->ocram_s, NULL, "imx7.ocram_s",
|
||||
FSL_IMX7_OCRAM_S_SIZE,
|
||||
&error_abort);
|
||||
memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
|
||||
&s->ocram_s);
|
||||
|
||||
/*
|
||||
* ROM memory
|
||||
*/
|
||||
memory_region_init_rom(&s->rom, OBJECT(dev), "imx7.rom",
|
||||
FSL_IMX7_ROM_SIZE, &error_abort);
|
||||
memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
|
||||
&s->rom);
|
||||
|
||||
/*
|
||||
* CAAM memory
|
||||
*/
|
||||
memory_region_init_rom(&s->caam, OBJECT(dev), "imx7.caam",
|
||||
FSL_IMX7_CAAM_MEM_SIZE, &error_abort);
|
||||
memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
|
||||
&s->caam);
|
||||
}
|
||||
|
||||
static Property fsl_imx7_properties[] = {
|
||||
|
||||
@@ -124,10 +124,6 @@ struct MPS2TZMachineClass {
|
||||
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
|
||||
uint32_t init_svtor; /* init-svtor setting for SSE */
|
||||
uint32_t sram_addr_width; /* SRAM_ADDR_WIDTH setting for SSE */
|
||||
uint32_t cpu0_mpu_ns; /* CPU0_MPU_NS setting for SSE */
|
||||
uint32_t cpu0_mpu_s; /* CPU0_MPU_S setting for SSE */
|
||||
uint32_t cpu1_mpu_ns; /* CPU1_MPU_NS setting for SSE */
|
||||
uint32_t cpu1_mpu_s; /* CPU1_MPU_S setting for SSE */
|
||||
const RAMInfo *raminfo;
|
||||
const char *armsse_type;
|
||||
uint32_t boot_ram_size; /* size of ram at address 0; 0 == find in raminfo */
|
||||
@@ -187,9 +183,6 @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
|
||||
#define MPS3_DDR_SIZE (2 * GiB)
|
||||
#endif
|
||||
|
||||
/* For cpu{0,1}_mpu_{ns,s}, means "leave at SSE's default value" */
|
||||
#define MPU_REGION_DEFAULT UINT32_MAX
|
||||
|
||||
static const uint32_t an505_oscclk[] = {
|
||||
40000000,
|
||||
24580000,
|
||||
@@ -835,20 +828,6 @@ static void mps2tz_common_init(MachineState *machine)
|
||||
OBJECT(system_memory), &error_abort);
|
||||
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
|
||||
qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
|
||||
if (mmc->cpu0_mpu_ns != MPU_REGION_DEFAULT) {
|
||||
qdev_prop_set_uint32(iotkitdev, "CPU0_MPU_NS", mmc->cpu0_mpu_ns);
|
||||
}
|
||||
if (mmc->cpu0_mpu_s != MPU_REGION_DEFAULT) {
|
||||
qdev_prop_set_uint32(iotkitdev, "CPU0_MPU_S", mmc->cpu0_mpu_s);
|
||||
}
|
||||
if (object_property_find(OBJECT(iotkitdev), "CPU1_MPU_NS")) {
|
||||
if (mmc->cpu1_mpu_ns != MPU_REGION_DEFAULT) {
|
||||
qdev_prop_set_uint32(iotkitdev, "CPU1_MPU_NS", mmc->cpu1_mpu_ns);
|
||||
}
|
||||
if (mmc->cpu1_mpu_s != MPU_REGION_DEFAULT) {
|
||||
qdev_prop_set_uint32(iotkitdev, "CPU1_MPU_S", mmc->cpu1_mpu_s);
|
||||
}
|
||||
}
|
||||
qdev_prop_set_uint32(iotkitdev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
|
||||
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
|
||||
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
|
||||
@@ -1277,17 +1256,10 @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
|
||||
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
|
||||
|
||||
mc->init = mps2tz_common_init;
|
||||
mc->reset = mps2_machine_reset;
|
||||
iic->check = mps2_tz_idau_check;
|
||||
|
||||
/* Most machines leave these at the SSE defaults */
|
||||
mmc->cpu0_mpu_ns = MPU_REGION_DEFAULT;
|
||||
mmc->cpu0_mpu_s = MPU_REGION_DEFAULT;
|
||||
mmc->cpu1_mpu_ns = MPU_REGION_DEFAULT;
|
||||
mmc->cpu1_mpu_s = MPU_REGION_DEFAULT;
|
||||
}
|
||||
|
||||
static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
|
||||
@@ -1424,7 +1396,6 @@ static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
|
||||
mmc->numirq = 96;
|
||||
mmc->uart_overflow_irq = 48;
|
||||
mmc->init_svtor = 0x00000000;
|
||||
mmc->cpu0_mpu_s = mmc->cpu0_mpu_ns = 16;
|
||||
mmc->sram_addr_width = 21;
|
||||
mmc->raminfo = an547_raminfo;
|
||||
mmc->armsse_type = TYPE_SSE300;
|
||||
|
||||
+3
-4
@@ -1235,15 +1235,14 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
|
||||
|
||||
dinfo = drive_get(IF_SD, 0, 0);
|
||||
blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
|
||||
carddev = qdev_new(TYPE_SD_CARD_SPI);
|
||||
carddev = qdev_new(TYPE_SD_CARD);
|
||||
qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
|
||||
qdev_prop_set_bit(carddev, "spi", true);
|
||||
qdev_realize_and_unref(carddev,
|
||||
qdev_get_child_bus(sddev, "sd-bus"),
|
||||
&error_fatal);
|
||||
|
||||
ssddev = qdev_new("ssd0323");
|
||||
qdev_prop_set_uint8(ssddev, "cs", 1);
|
||||
qdev_realize_and_unref(ssddev, bus, &error_fatal);
|
||||
ssddev = ssi_create_peripheral(bus, "ssd0323");
|
||||
|
||||
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
|
||||
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
|
||||
|
||||
+2
-9
@@ -2913,7 +2913,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
|
||||
"require an IPA range (%d bits) larger than "
|
||||
"the one supported by the host (%d bits)",
|
||||
requested_pa_size, max_vm_pa_size);
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* We return the requested PA log size, unless KVM only supports
|
||||
@@ -3170,17 +3170,10 @@ static void machvirt_machine_init(void)
|
||||
}
|
||||
type_init(machvirt_machine_init);
|
||||
|
||||
static void virt_machine_8_2_options(MachineClass *mc)
|
||||
{
|
||||
}
|
||||
DEFINE_VIRT_MACHINE_AS_LATEST(8, 2)
|
||||
|
||||
static void virt_machine_8_1_options(MachineClass *mc)
|
||||
{
|
||||
virt_machine_8_2_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(8, 1)
|
||||
DEFINE_VIRT_MACHINE_AS_LATEST(8, 1)
|
||||
|
||||
static void virt_machine_8_0_options(MachineClass *mc)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "qapi/qapi-commands-migration.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/tpm_backend.h"
|
||||
@@ -60,73 +59,6 @@ struct XenArmState {
|
||||
} cfg;
|
||||
};
|
||||
|
||||
static MemoryRegion ram_lo, ram_hi;
|
||||
|
||||
/*
|
||||
* VIRTIO_MMIO_DEV_SIZE is imported from tools/libs/light/libxl_arm.c under Xen
|
||||
* repository.
|
||||
*
|
||||
* Origin: git://xenbits.xen.org/xen.git 2128143c114c
|
||||
*/
|
||||
#define VIRTIO_MMIO_DEV_SIZE 0x200
|
||||
|
||||
#define NR_VIRTIO_MMIO_DEVICES \
|
||||
(GUEST_VIRTIO_MMIO_SPI_LAST - GUEST_VIRTIO_MMIO_SPI_FIRST)
|
||||
|
||||
static void xen_set_irq(void *opaque, int irq, int level)
|
||||
{
|
||||
xendevicemodel_set_irq_level(xen_dmod, xen_domid, irq, level);
|
||||
}
|
||||
|
||||
static void xen_create_virtio_mmio_devices(XenArmState *xam)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NR_VIRTIO_MMIO_DEVICES; i++) {
|
||||
hwaddr base = GUEST_VIRTIO_MMIO_BASE + i * VIRTIO_MMIO_DEV_SIZE;
|
||||
qemu_irq irq = qemu_allocate_irq(xen_set_irq, NULL,
|
||||
GUEST_VIRTIO_MMIO_SPI_FIRST + i);
|
||||
|
||||
sysbus_create_simple("virtio-mmio", base, irq);
|
||||
|
||||
DPRINTF("Created virtio-mmio device %d: irq %d base 0x%lx\n",
|
||||
i, GUEST_VIRTIO_MMIO_SPI_FIRST + i, base);
|
||||
}
|
||||
}
|
||||
|
||||
static void xen_init_ram(MachineState *machine)
|
||||
{
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
ram_addr_t block_len, ram_size[GUEST_RAM_BANKS];
|
||||
|
||||
if (machine->ram_size <= GUEST_RAM0_SIZE) {
|
||||
ram_size[0] = machine->ram_size;
|
||||
ram_size[1] = 0;
|
||||
block_len = GUEST_RAM0_BASE + ram_size[0];
|
||||
} else {
|
||||
ram_size[0] = GUEST_RAM0_SIZE;
|
||||
ram_size[1] = machine->ram_size - GUEST_RAM0_SIZE;
|
||||
block_len = GUEST_RAM1_BASE + ram_size[1];
|
||||
}
|
||||
|
||||
memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len,
|
||||
&error_fatal);
|
||||
|
||||
memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo", &ram_memory,
|
||||
GUEST_RAM0_BASE, ram_size[0]);
|
||||
memory_region_add_subregion(sysmem, GUEST_RAM0_BASE, &ram_lo);
|
||||
DPRINTF("Initialized region xen.ram.lo: base 0x%llx size 0x%lx\n",
|
||||
GUEST_RAM0_BASE, ram_size[0]);
|
||||
|
||||
if (ram_size[1] > 0) {
|
||||
memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi", &ram_memory,
|
||||
GUEST_RAM1_BASE, ram_size[1]);
|
||||
memory_region_add_subregion(sysmem, GUEST_RAM1_BASE, &ram_hi);
|
||||
DPRINTF("Initialized region xen.ram.hi: base 0x%llx size 0x%lx\n",
|
||||
GUEST_RAM1_BASE, ram_size[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
|
||||
{
|
||||
hw_error("Invalid ioreq type 0x%x\n", req->type);
|
||||
@@ -176,18 +108,8 @@ static void xen_arm_init(MachineState *machine)
|
||||
|
||||
xam->state = g_new0(XenIOState, 1);
|
||||
|
||||
if (machine->ram_size == 0) {
|
||||
DPRINTF("ram_size not specified. QEMU machine started without IOREQ"
|
||||
"(no emulated devices including Virtio)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
xen_init_ram(machine);
|
||||
|
||||
xen_register_ioreq(xam->state, machine->smp.cpus, &xen_memory_listener);
|
||||
|
||||
xen_create_virtio_mmio_devices(xam);
|
||||
|
||||
#ifdef CONFIG_TPM
|
||||
if (xam->cfg.tpm_base_addr) {
|
||||
xen_enable_tpm(xam);
|
||||
@@ -231,8 +153,6 @@ static void xen_arm_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->init = xen_arm_init;
|
||||
mc->max_cpus = 1;
|
||||
mc->default_machine_opts = "accel=xen";
|
||||
/* Set explicitly here to make sure that real ram_size is passed */
|
||||
mc->default_ram_size = 0;
|
||||
|
||||
#ifdef CONFIG_TPM
|
||||
object_class_property_add(oc, "tpm-base-addr", "uint64_t",
|
||||
|
||||
@@ -164,7 +164,6 @@ static inline int zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
|
||||
blk_by_legacy_dinfo(dinfo),
|
||||
&error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", j);
|
||||
qdev_realize_and_unref(flash_dev, BUS(spi), &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
||||
@@ -740,7 +740,6 @@ static void versal_virt_init(MachineState *machine)
|
||||
qdev_prop_set_drive_err(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", i);
|
||||
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
||||
@@ -201,7 +201,6 @@ static void xlnx_zcu102_init(MachineState *machine)
|
||||
qdev_prop_set_drive_err(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", i);
|
||||
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
@@ -225,7 +224,6 @@ static void xlnx_zcu102_init(MachineState *machine)
|
||||
qdev_prop_set_drive_err(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_prop_set_uint8(flash_dev, "cs", i);
|
||||
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "qemu/units.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "hw/block/block.h"
|
||||
#include "hw/block/flash.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-properties-system.h"
|
||||
#include "hw/ssi/ssi.h"
|
||||
@@ -1831,8 +1830,3 @@ static void m25p80_register_types(void)
|
||||
}
|
||||
|
||||
type_init(m25p80_register_types)
|
||||
|
||||
BlockBackend *m25p80_get_blk(DeviceState *dev)
|
||||
{
|
||||
return M25P80(dev)->blk;
|
||||
}
|
||||
|
||||
@@ -307,11 +307,11 @@ static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
|
||||
/* instant drain the fifo when there's no back-end */
|
||||
if (!qemu_chr_fe_backend_connected(&s->chr)) {
|
||||
s->tx_count = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!s->tx_count) {
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_count);
|
||||
@@ -326,12 +326,12 @@ static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
|
||||
cadence_uart_xmit, s);
|
||||
if (!r) {
|
||||
s->tx_count = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
uart_update_status(s);
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
|
||||
|
||||
@@ -199,7 +199,7 @@ static gboolean uart_transmit(void *do_not_use, GIOCondition cond, void *opaque)
|
||||
s->watch_tag = 0;
|
||||
|
||||
if (!(s->ctrl & R_CTRL_TX_EN_MASK) || !(s->state & R_STATE_TXFULL_MASK)) {
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = qemu_chr_fe_write(&s->chr, &s->txbuf, 1);
|
||||
@@ -215,7 +215,7 @@ static gboolean uart_transmit(void *do_not_use, GIOCondition cond, void *opaque)
|
||||
}
|
||||
/* Transmit pending */
|
||||
trace_cmsdk_apb_uart_tx_pending();
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buffer_drained:
|
||||
@@ -227,7 +227,7 @@ buffer_drained:
|
||||
s->intstatus |= R_INTSTATUS_TX_MASK;
|
||||
}
|
||||
cmsdk_apb_uart_update(s);
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void uart_cancel_transmit(CMSDKAPBUART *s)
|
||||
|
||||
+4
-4
@@ -147,7 +147,7 @@ static gboolean ibex_uart_xmit(void *do_not_use, GIOCondition cond,
|
||||
/* instant drain the fifo when there's no back-end */
|
||||
if (!qemu_chr_fe_backend_connected(&s->chr)) {
|
||||
s->tx_level = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!s->tx_level) {
|
||||
@@ -156,7 +156,7 @@ static gboolean ibex_uart_xmit(void *do_not_use, GIOCondition cond,
|
||||
s->uart_intr_state |= R_INTR_STATE_TX_EMPTY_MASK;
|
||||
s->uart_intr_state &= ~R_INTR_STATE_TX_WATERMARK_MASK;
|
||||
ibex_uart_update_irqs(s);
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_level);
|
||||
@@ -171,7 +171,7 @@ static gboolean ibex_uart_xmit(void *do_not_use, GIOCondition cond,
|
||||
ibex_uart_xmit, s);
|
||||
if (!r) {
|
||||
s->tx_level = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ static gboolean ibex_uart_xmit(void *do_not_use, GIOCondition cond,
|
||||
}
|
||||
|
||||
ibex_uart_update_irqs(s);
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
|
||||
|
||||
@@ -93,13 +93,13 @@ static gboolean uart_transmit(void *do_not_use, GIOCondition cond, void *opaque)
|
||||
*/
|
||||
goto buffer_drained;
|
||||
}
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buffer_drained:
|
||||
s->reg[R_UART_TXDRDY] = 1;
|
||||
s->pending_tx_byte = false;
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void uart_cancel_transmit(NRF51UARTState *s)
|
||||
|
||||
+16
-42
@@ -48,15 +48,14 @@ DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
|
||||
return dev;
|
||||
}
|
||||
|
||||
/* Flag Register, UARTFR */
|
||||
#define PL011_INT_TX 0x20
|
||||
#define PL011_INT_RX 0x10
|
||||
|
||||
#define PL011_FLAG_TXFE 0x80
|
||||
#define PL011_FLAG_RXFF 0x40
|
||||
#define PL011_FLAG_TXFF 0x20
|
||||
#define PL011_FLAG_RXFE 0x10
|
||||
|
||||
/* Data Register, UARTDR */
|
||||
#define DR_BE (1 << 10)
|
||||
|
||||
/* Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC */
|
||||
#define INT_OE (1 << 10)
|
||||
#define INT_BE (1 << 9)
|
||||
@@ -72,33 +71,11 @@ DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
|
||||
#define INT_E (INT_OE | INT_BE | INT_PE | INT_FE)
|
||||
#define INT_MS (INT_RI | INT_DSR | INT_DCD | INT_CTS)
|
||||
|
||||
/* Line Control Register, UARTLCR_H */
|
||||
#define LCR_FEN (1 << 4)
|
||||
#define LCR_BRK (1 << 0)
|
||||
|
||||
static const unsigned char pl011_id_arm[8] =
|
||||
{ 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
|
||||
static const unsigned char pl011_id_luminary[8] =
|
||||
{ 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
|
||||
|
||||
static const char *pl011_regname(hwaddr offset)
|
||||
{
|
||||
static const char *const rname[] = {
|
||||
[0] = "DR", [1] = "RSR", [6] = "FR", [8] = "ILPR", [9] = "IBRD",
|
||||
[10] = "FBRD", [11] = "LCRH", [12] = "CR", [13] = "IFLS", [14] = "IMSC",
|
||||
[15] = "RIS", [16] = "MIS", [17] = "ICR", [18] = "DMACR",
|
||||
};
|
||||
unsigned idx = offset >> 2;
|
||||
|
||||
if (idx < ARRAY_SIZE(rname) && rname[idx]) {
|
||||
return rname[idx];
|
||||
}
|
||||
if (idx >= 0x3f8 && idx <= 0x400) {
|
||||
return "ID";
|
||||
}
|
||||
return "UNKN";
|
||||
}
|
||||
|
||||
/* Which bits in the interrupt status matter for each outbound IRQ line ? */
|
||||
static const uint32_t irqmask[] = {
|
||||
INT_E | INT_MS | INT_RT | INT_TX | INT_RX, /* combined IRQ */
|
||||
@@ -123,7 +100,7 @@ static void pl011_update(PL011State *s)
|
||||
|
||||
static bool pl011_is_fifo_enabled(PL011State *s)
|
||||
{
|
||||
return (s->lcr & LCR_FEN) != 0;
|
||||
return (s->lcr & 0x10) != 0;
|
||||
}
|
||||
|
||||
static inline unsigned pl011_get_fifo_depth(PL011State *s)
|
||||
@@ -161,7 +138,7 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
|
||||
s->flags |= PL011_FLAG_RXFE;
|
||||
}
|
||||
if (s->read_count == s->read_trigger - 1)
|
||||
s->int_level &= ~ INT_RX;
|
||||
s->int_level &= ~ PL011_INT_RX;
|
||||
trace_pl011_read_fifo(s->read_count);
|
||||
s->rsr = c >> 8;
|
||||
pl011_update(s);
|
||||
@@ -214,7 +191,7 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
|
||||
break;
|
||||
}
|
||||
|
||||
trace_pl011_read(offset, r, pl011_regname(offset));
|
||||
trace_pl011_read(offset, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -225,7 +202,7 @@ static void pl011_set_read_trigger(PL011State *s)
|
||||
the threshold. However linux only reads the FIFO in response to an
|
||||
interrupt. Triggering the interrupt when the FIFO is non-empty seems
|
||||
to make things work. */
|
||||
if (s->lcr & LCR_FEN)
|
||||
if (s->lcr & 0x10)
|
||||
s->read_trigger = (s->ifl >> 1) & 0x1c;
|
||||
else
|
||||
#endif
|
||||
@@ -257,7 +234,7 @@ static void pl011_write(void *opaque, hwaddr offset,
|
||||
PL011State *s = (PL011State *)opaque;
|
||||
unsigned char ch;
|
||||
|
||||
trace_pl011_write(offset, value, pl011_regname(offset));
|
||||
trace_pl011_write(offset, value);
|
||||
|
||||
switch (offset >> 2) {
|
||||
case 0: /* UARTDR */
|
||||
@@ -266,7 +243,7 @@ static void pl011_write(void *opaque, hwaddr offset,
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(&s->chr, &ch, 1);
|
||||
s->int_level |= INT_TX;
|
||||
s->int_level |= PL011_INT_TX;
|
||||
pl011_update(s);
|
||||
break;
|
||||
case 1: /* UARTRSR/UARTECR */
|
||||
@@ -275,7 +252,7 @@ static void pl011_write(void *opaque, hwaddr offset,
|
||||
case 6: /* UARTFR */
|
||||
/* Writes to Flag register are ignored. */
|
||||
break;
|
||||
case 8: /* UARTILPR */
|
||||
case 8: /* UARTUARTILPR */
|
||||
s->ilpr = value;
|
||||
break;
|
||||
case 9: /* UARTIBRD */
|
||||
@@ -288,11 +265,11 @@ static void pl011_write(void *opaque, hwaddr offset,
|
||||
break;
|
||||
case 11: /* UARTLCR_H */
|
||||
/* Reset the FIFO state on FIFO enable or disable */
|
||||
if ((s->lcr ^ value) & LCR_FEN) {
|
||||
if ((s->lcr ^ value) & 0x10) {
|
||||
pl011_reset_fifo(s);
|
||||
}
|
||||
if ((s->lcr ^ value) & LCR_BRK) {
|
||||
int break_enable = value & LCR_BRK;
|
||||
if ((s->lcr ^ value) & 0x1) {
|
||||
int break_enable = value & 0x1;
|
||||
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
|
||||
&break_enable);
|
||||
}
|
||||
@@ -354,7 +331,7 @@ static void pl011_put_fifo(void *opaque, uint32_t value)
|
||||
s->flags |= PL011_FLAG_RXFF;
|
||||
}
|
||||
if (s->read_count == s->read_trigger) {
|
||||
s->int_level |= INT_RX;
|
||||
s->int_level |= PL011_INT_RX;
|
||||
pl011_update(s);
|
||||
}
|
||||
}
|
||||
@@ -366,9 +343,8 @@ static void pl011_receive(void *opaque, const uint8_t *buf, int size)
|
||||
|
||||
static void pl011_event(void *opaque, QEMUChrEvent event)
|
||||
{
|
||||
if (event == CHR_EVENT_BREAK) {
|
||||
pl011_put_fifo(opaque, DR_BE);
|
||||
}
|
||||
if (event == CHR_EVENT_BREAK)
|
||||
pl011_put_fifo(opaque, 0x400);
|
||||
}
|
||||
|
||||
static void pl011_clock_update(void *opaque, ClockEvent event)
|
||||
@@ -382,8 +358,6 @@ static const MemoryRegionOps pl011_ops = {
|
||||
.read = pl011_read,
|
||||
.write = pl011_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.impl.min_access_size = 4,
|
||||
.impl.max_access_size = 4,
|
||||
};
|
||||
|
||||
static bool pl011_clock_needed(void *opaque)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "exec/tswap.h"
|
||||
#include "sysemu/dma.h"
|
||||
|
||||
#define RISCV_DEBUG_HTIF 0
|
||||
@@ -209,11 +210,11 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
|
||||
} else {
|
||||
uint64_t syscall[8];
|
||||
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
|
||||
if (syscall[0] == PK_SYS_WRITE &&
|
||||
syscall[1] == HTIF_DEV_CONSOLE &&
|
||||
syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
|
||||
if (tswap64(syscall[0]) == PK_SYS_WRITE &&
|
||||
tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
|
||||
tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
|
||||
uint8_t ch;
|
||||
cpu_physical_memory_read(syscall[2], &ch, 1);
|
||||
cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
|
||||
qemu_chr_fe_write(&s->chr, &ch, 1);
|
||||
resp = 0x100 | (uint8_t)payload;
|
||||
} else {
|
||||
@@ -232,7 +233,8 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
|
||||
s->tohost = 0; /* clear to indicate we read */
|
||||
return;
|
||||
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
|
||||
qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
|
||||
uint8_t ch = (uint8_t)payload;
|
||||
qemu_chr_fe_write(&s->chr, &ch, 1);
|
||||
resp = 0x100 | (uint8_t)payload;
|
||||
} else {
|
||||
qemu_log("HTIF device %d: unknown command\n", device);
|
||||
|
||||
+1
-1
@@ -226,7 +226,7 @@ static gboolean serial_watch_cb(void *do_not_use, GIOCondition cond,
|
||||
SerialState *s = opaque;
|
||||
s->watch_tag = 0;
|
||||
serial_xmit(s);
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void serial_xmit(SerialState *s)
|
||||
|
||||
@@ -54,9 +54,9 @@ escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=0x%0
|
||||
|
||||
# pl011.c
|
||||
pl011_irq_state(int level) "irq state %d"
|
||||
pl011_read(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s"
|
||||
pl011_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
pl011_read_fifo(int read_count) "FIFO read, read_count now %d"
|
||||
pl011_write(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s"
|
||||
pl011_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
pl011_can_receive(uint32_t lcr, int read_count, int r) "LCR 0x%08x read_count %d returning %d"
|
||||
pl011_put_fifo(uint32_t c, int read_count) "new char 0x%x read_count now %d"
|
||||
pl011_put_fifo_full(void) "FIFO now full, RXFF set"
|
||||
|
||||
@@ -45,7 +45,7 @@ static gboolean chr_write_unblocked(void *do_not_use, GIOCondition cond,
|
||||
|
||||
vcon->watch = 0;
|
||||
virtio_serial_throttle_port(VIRTIO_SERIAL_PORT(vcon), false);
|
||||
return G_SOURCE_REMOVE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Callback function that's called when the guest sends us data */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user