mirror of https://github.com/xemu-project/xemu.git
Merge branch 'master' into enable_libusb
This commit is contained in:
commit
173bba197c
|
@ -93,8 +93,8 @@ jobs:
|
|||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/xemu-ccache
|
||||
key: cache-wincross-${{ runner.os }}-${{ matrix.configuration }}-${{ github.sha }}
|
||||
restore-keys: cache-wincross-${{ runner.os }}-${{ matrix.configuration }}-
|
||||
key: cache-wincross-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.configuration }}-${{ github.sha }}
|
||||
restore-keys: cache-wincross-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.configuration }}-
|
||||
- name: Pull Docker image
|
||||
run: docker pull $DOCKER_IMAGE_NAME
|
||||
- name: Compile
|
||||
|
@ -163,28 +163,44 @@ jobs:
|
|||
path: dist
|
||||
|
||||
Ubuntu:
|
||||
name: Build for Ubuntu (${{ matrix.configuration }})
|
||||
runs-on: ubuntu-latest
|
||||
name: Build for Ubuntu (${{matrix.arch}}, ${{ matrix.configuration }})
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
needs: Init
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- configuration: Debug
|
||||
- arch: x86_64
|
||||
configuration: Debug
|
||||
build_param: --debug
|
||||
artifact_name: xemu-ubuntu-debug
|
||||
artifact_filename: xemu-ubuntu-debug.tgz
|
||||
- configuration: Release
|
||||
artifact_name: xemu-ubuntu-x86_64-debug
|
||||
artifact_filename: xemu-ubuntu-x86_64-debug.tgz
|
||||
runs-on: ubuntu-24.04
|
||||
- arch: x86_64
|
||||
configuration: Release
|
||||
build_param:
|
||||
artifact_name: xemu-ubuntu-release
|
||||
artifact_filename: xemu-ubuntu-release.tgz
|
||||
artifact_name: xemu-ubuntu-x86_64-release
|
||||
artifact_filename: xemu-ubuntu-x86_64-release.tgz
|
||||
runs-on: ubuntu-22.04
|
||||
- arch: aarch64
|
||||
configuration: Debug
|
||||
build_param: --debug
|
||||
artifact_name: xemu-ubuntu-aarch64-debug
|
||||
artifact_filename: xemu-ubuntu-aarch64-debug.tgz
|
||||
runs-on: ubuntu-24.04-arm
|
||||
- arch: aarch64
|
||||
configuration: Release
|
||||
build_param:
|
||||
artifact_name: xemu-ubuntu-aarch64-release
|
||||
artifact_filename: xemu-ubuntu-aarch64-release.tgz
|
||||
runs-on: ubuntu-24.04-arm
|
||||
steps:
|
||||
- name: Initialize compiler cache
|
||||
id: cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/xemu-ccache
|
||||
key: cache-${{ runner.os }}-${{ matrix.configuration }}-${{ github.sha }}
|
||||
restore-keys: cache-${{ runner.os }}-${{ matrix.configuration }}-
|
||||
key: cache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.configuration }}-${{ github.sha }}
|
||||
restore-keys: cache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.configuration }}-
|
||||
- name: Download source package
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
|
@ -231,8 +247,8 @@ jobs:
|
|||
ccache -s
|
||||
- name: Generate AppImage
|
||||
run: |
|
||||
wget --no-verbose https://github.com/linuxdeploy/linuxdeploy/releases/latest/download/linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
wget --no-verbose https://github.com/linuxdeploy/linuxdeploy/releases/latest/download/linuxdeploy-${{ matrix.arch }}.AppImage
|
||||
chmod +x linuxdeploy-${{ matrix.arch }}.AppImage
|
||||
|
||||
ar x dist/*.deb
|
||||
mkdir appimage
|
||||
|
@ -244,7 +260,7 @@ jobs:
|
|||
export VERSION=$VERSION-dbg
|
||||
fi
|
||||
|
||||
./linuxdeploy-x86_64.AppImage --output appimage --appdir appimage
|
||||
./linuxdeploy-${{ matrix.arch }}.AppImage --output appimage --appdir appimage
|
||||
mv xemu-*.AppImage dist
|
||||
- name: Bundle artifacts
|
||||
run: |
|
||||
|
@ -388,13 +404,13 @@ jobs:
|
|||
echo "XEMU_VERSION=$(cat XEMU_VERSION)" >> $GITHUB_ENV
|
||||
- name: Extract Ubuntu artifacts
|
||||
run: |
|
||||
pushd dist/xemu-ubuntu-release
|
||||
tar xvf xemu-ubuntu-release.tgz
|
||||
popd
|
||||
|
||||
pushd dist/xemu-ubuntu-debug
|
||||
tar xvf xemu-ubuntu-debug.tgz
|
||||
popd
|
||||
for arch in x86_64 aarch64; do
|
||||
for config in release debug; do
|
||||
pushd dist/xemu-ubuntu-$arch-$config
|
||||
tar xvf xemu-ubuntu-$arch-$config.tgz
|
||||
popd
|
||||
done
|
||||
done
|
||||
# Architecture tags were recently added to the Windows release path. Provide an alias with the former name for a while.
|
||||
- name: Add transitionary package alias
|
||||
run: |
|
||||
|
@ -419,8 +435,10 @@ jobs:
|
|||
dist/xemu-win-x86_64-release-pdb/xemu-win-release.zip
|
||||
dist/xemu-macos-universal-release/xemu-macos-universal-release.zip
|
||||
dist/xemu-macos-universal-debug/xemu-macos-universal-debug.zip
|
||||
dist/xemu-ubuntu-release/xemu/xemu-v${{ env.XEMU_VERSION }}-x86_64.AppImage
|
||||
dist/xemu-ubuntu-debug/xemu/xemu-v${{ env.XEMU_VERSION }}-dbg-x86_64.AppImage
|
||||
dist/xemu-ubuntu-x86_64-debug/xemu/xemu-v${{ env.XEMU_VERSION }}-dbg-x86_64.AppImage
|
||||
dist/xemu-ubuntu-x86_64-release/xemu/xemu-v${{ env.XEMU_VERSION }}-x86_64.AppImage
|
||||
dist/xemu-ubuntu-aarch64-debug/xemu/xemu-v${{ env.XEMU_VERSION }}-dbg-aarch64.AppImage
|
||||
dist/xemu-ubuntu-aarch64-release/xemu/xemu-v${{ env.XEMU_VERSION }}-aarch64.AppImage
|
||||
- name: Trigger website update
|
||||
uses: benc-uk/workflow-dispatch@v1.2.2
|
||||
with:
|
||||
|
|
|
@ -1 +1 @@
|
|||
9.2.0
|
||||
9.2.1
|
||||
|
|
|
@ -437,6 +437,16 @@ int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
|
|||
return kvm_fd;
|
||||
}
|
||||
|
||||
static void kvm_reset_parked_vcpus(void *param)
|
||||
{
|
||||
KVMState *s = param;
|
||||
struct KVMParkedVcpu *cpu;
|
||||
|
||||
QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
|
||||
kvm_arch_reset_parked_vcpu(cpu->vcpu_id, cpu->kvm_fd);
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_create_vcpu(CPUState *cpu)
|
||||
{
|
||||
unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
|
||||
|
@ -2728,6 +2738,7 @@ static int kvm_init(MachineState *ms)
|
|||
}
|
||||
|
||||
qemu_register_reset(kvm_unpoison_all, NULL);
|
||||
qemu_register_reset(kvm_reset_parked_vcpus, s);
|
||||
|
||||
if (s->kernel_irqchip_allowed) {
|
||||
kvm_irqchip_create(s);
|
||||
|
|
|
@ -281,8 +281,7 @@ static int cryptodev_vhost_user_create_session(
|
|||
break;
|
||||
|
||||
default:
|
||||
error_setg(&local_error, "Unsupported opcode :%" PRIu32 "",
|
||||
sess_info->op_code);
|
||||
error_report("Unsupported opcode :%" PRIu32 "", sess_info->op_code);
|
||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ display:
|
|||
fullscreen_exclusive: bool
|
||||
startup_size:
|
||||
type: enum
|
||||
values: [last_used, 640x480, 1280x720, 1280x800, 1280x960, 1920x1080, 2560x1440, 2560x1600, 2560x1920, 3840x2160]
|
||||
values: [last_used, 640x480, 720x480, 1280x720, 1280x800, 1280x960, 1920x1080, 2560x1440, 2560x1600, 2560x1920, 3840x2160]
|
||||
default: 1280x960
|
||||
last_width:
|
||||
type: integer
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
TARGET_ARCH=i386
|
||||
TARGET_SUPPORTS_MTTCG=y
|
||||
TARGET_KVM_HAVE_GUEST_DEBUG=y
|
||||
TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
|
||||
TARGET_XML_FILES= gdb-xml/i386-32bit.xml
|
||||
|
|
|
@ -2,4 +2,5 @@ TARGET_ARCH=x86_64
|
|||
TARGET_BASE_ARCH=i386
|
||||
TARGET_SUPPORTS_MTTCG=y
|
||||
TARGET_KVM_HAVE_GUEST_DEBUG=y
|
||||
TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
|
||||
TARGET_XML_FILES= gdb-xml/i386-64bit.xml
|
||||
|
|
|
@ -107,7 +107,7 @@ static void *threaded_qcrypto_pbkdf2_count_iters(void *data)
|
|||
size_t nsalt = iters_data->nsalt;
|
||||
size_t nout = iters_data->nout;
|
||||
Error **errp = iters_data->errp;
|
||||
|
||||
size_t scaled = 0;
|
||||
uint64_t ret = -1;
|
||||
g_autofree uint8_t *out = g_new(uint8_t, nout);
|
||||
uint64_t iterations = (1 << 15);
|
||||
|
@ -131,7 +131,17 @@ static void *threaded_qcrypto_pbkdf2_count_iters(void *data)
|
|||
|
||||
delta_ms = end_ms - start_ms;
|
||||
|
||||
if (delta_ms == 0) { /* sanity check */
|
||||
/*
|
||||
* For very small 'iterations' values, CPU (or crypto
|
||||
* accelerator) might be fast enough that the scheduler
|
||||
* hasn't incremented getrusage() data, or incremented
|
||||
* it by a very small amount, resulting in delta_ms == 0.
|
||||
* Once we've scaled 'iterations' x10, 5 times, we really
|
||||
* should be seeing delta_ms != 0, so sanity check at
|
||||
* that point.
|
||||
*/
|
||||
if (scaled > 5 &&
|
||||
delta_ms == 0) { /* sanity check */
|
||||
error_setg(errp, "Unable to get accurate CPU usage");
|
||||
goto cleanup;
|
||||
} else if (delta_ms > 500) {
|
||||
|
@ -141,6 +151,7 @@ static void *threaded_qcrypto_pbkdf2_count_iters(void *data)
|
|||
} else {
|
||||
iterations = (iterations * 1000 / delta_ms);
|
||||
}
|
||||
scaled++;
|
||||
}
|
||||
|
||||
iterations = iterations * 1000 / delta_ms;
|
||||
|
|
|
@ -75,7 +75,7 @@ marked deprecated since 9.0, users have to ensure that all the topology members
|
|||
described with -smp are supported by the target machine.
|
||||
|
||||
``-runas`` (since 9.1)
|
||||
----------------------
|
||||
''''''''''''''''''''''
|
||||
|
||||
Use ``-run-with user=..`` instead.
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ and later do not support it because the virtio-scsi device was introduced for
|
|||
full SCSI support. Use virtio-scsi instead when SCSI passthrough is required.
|
||||
|
||||
``-fsdev proxy`` and ``-virtfs proxy`` (since 9.2)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The 9p ``proxy`` filesystem backend driver was originally developed to
|
||||
enhance security by dispatching low level filesystem operations from 9p
|
||||
|
@ -1077,8 +1077,8 @@ processor IP (see `Intel discontinuance notification`_).
|
|||
TCG introspection features
|
||||
--------------------------
|
||||
|
||||
TCG trace-events (since 6.2)
|
||||
''''''''''''''''''''''''''''
|
||||
TCG trace-events (removed in 7.0)
|
||||
'''''''''''''''''''''''''''''''''
|
||||
|
||||
The ability to add new TCG trace points had bit rotted and as the
|
||||
feature can be replicated with TCG plugins it was removed. If
|
||||
|
|
|
@ -317,9 +317,9 @@ void gdb_handle_v_file_open(GArray *params, void *user_ctx)
|
|||
int fd = open(filename, flags, mode);
|
||||
#endif
|
||||
if (fd < 0) {
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
|
||||
} else {
|
||||
g_string_printf(gdbserver_state.str_buf, "F%d", fd);
|
||||
g_string_printf(gdbserver_state.str_buf, "F%x", fd);
|
||||
}
|
||||
gdb_put_strbuf();
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ void gdb_handle_v_file_close(GArray *params, void *user_ctx)
|
|||
int fd = gdb_get_cmd_param(params, 0)->val_ul;
|
||||
|
||||
if (close(fd) == -1) {
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
|
||||
gdb_put_strbuf();
|
||||
return;
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ void gdb_handle_v_file_pread(GArray *params, void *user_ctx)
|
|||
|
||||
ssize_t n = pread(fd, buf, bufsiz, offset);
|
||||
if (n < 0) {
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
|
||||
gdb_put_strbuf();
|
||||
return;
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ void gdb_handle_v_file_readlink(GArray *params, void *user_ctx)
|
|||
ssize_t n = readlink(filename, buf, BUFSIZ);
|
||||
#endif
|
||||
if (n < 0) {
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
|
||||
g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
|
||||
gdb_put_strbuf();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -177,20 +177,27 @@ again:
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (close_if_special_file(fd) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
serrno = errno;
|
||||
/* O_NONBLOCK was only needed to open the file. Let's drop it. We don't
|
||||
* do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat()
|
||||
* ignored it anyway.
|
||||
*/
|
||||
/* Only if O_PATH is not set ... */
|
||||
if (!(flags & O_PATH_9P_UTIL)) {
|
||||
/*
|
||||
* Prevent I/O on special files (device files, etc.) on host side,
|
||||
* however it is safe and required to allow opening them with O_PATH,
|
||||
* as this is limited to (required) path based operations only.
|
||||
*/
|
||||
if (close_if_special_file(fd) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
serrno = errno;
|
||||
/*
|
||||
* O_NONBLOCK was only needed to open the file. Let's drop it. We don't
|
||||
* do that with O_PATH since fcntl(F_SETFL) isn't supported, and
|
||||
* openat() ignored it anyway.
|
||||
*/
|
||||
ret = fcntl(fd, F_SETFL, flags);
|
||||
assert(!ret);
|
||||
errno = serrno;
|
||||
}
|
||||
errno = serrno;
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
|
|
@ -657,6 +657,7 @@ static Aml *aml_pci_pdsm(void)
|
|||
Aml *acpi_index = aml_local(2);
|
||||
Aml *zero = aml_int(0);
|
||||
Aml *one = aml_int(1);
|
||||
Aml *not_supp = aml_int(0xFFFFFFFF);
|
||||
Aml *func = aml_arg(2);
|
||||
Aml *params = aml_arg(4);
|
||||
Aml *bnum = aml_derefof(aml_index(params, aml_int(0)));
|
||||
|
@ -681,7 +682,7 @@ static Aml *aml_pci_pdsm(void)
|
|||
*/
|
||||
ifctx1 = aml_if(aml_lnot(
|
||||
aml_or(aml_equal(acpi_index, zero),
|
||||
aml_equal(acpi_index, aml_int(0xFFFFFFFF)), NULL)
|
||||
aml_equal(acpi_index, not_supp), NULL)
|
||||
));
|
||||
{
|
||||
/* have supported functions */
|
||||
|
@ -707,18 +708,30 @@ static Aml *aml_pci_pdsm(void)
|
|||
{
|
||||
Aml *pkg = aml_package(2);
|
||||
|
||||
aml_append(pkg, zero);
|
||||
/*
|
||||
* optional, if not impl. should return null string
|
||||
*/
|
||||
aml_append(pkg, aml_string("%s", ""));
|
||||
aml_append(ifctx, aml_store(pkg, ret));
|
||||
|
||||
aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
|
||||
aml_append(ifctx, aml_store(pkg, ret));
|
||||
/*
|
||||
* update acpi-index to actual value
|
||||
* Windows calls func=7 without checking if it's available,
|
||||
* as workaround Microsoft has suggested to return invalid for func7
|
||||
* Package, so return 2 elements package but only initialize elements
|
||||
* when acpi_index is supported and leave them uninitialized, which
|
||||
* leads elements to being Uninitialized ObjectType and should trip
|
||||
* Windows into discarding result as an unexpected and prevent setting
|
||||
* bogus 'PCI Label' on the device.
|
||||
*/
|
||||
aml_append(ifctx, aml_store(acpi_index, aml_index(ret, zero)));
|
||||
ifctx1 = aml_if(aml_lnot(aml_lor(
|
||||
aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
|
||||
)));
|
||||
{
|
||||
aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
|
||||
/*
|
||||
* optional, if not impl. should return null string
|
||||
*/
|
||||
aml_append(ifctx1, aml_store(aml_string("%s", ""),
|
||||
aml_index(ret, one)));
|
||||
}
|
||||
aml_append(ifctx, ifctx1);
|
||||
|
||||
aml_append(ifctx, aml_return(ret));
|
||||
}
|
||||
|
||||
|
|
|
@ -945,7 +945,7 @@ void x86_load_linux(X86MachineState *x86ms,
|
|||
* kernel on the other side of the fw_cfg interface matches the hash of the
|
||||
* file the user passed in.
|
||||
*/
|
||||
if (!sev_enabled()) {
|
||||
if (!sev_enabled() && protocol > 0) {
|
||||
memcpy(setup, header, MIN(sizeof(header), setup_size));
|
||||
}
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ static ItsCmdResult lookup_vte(GICv3ITSState *s, const char *who,
|
|||
static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite,
|
||||
int irqlevel)
|
||||
{
|
||||
CTEntry cte;
|
||||
CTEntry cte = {};
|
||||
ItsCmdResult cmdres;
|
||||
|
||||
cmdres = lookup_cte(s, __func__, ite->icid, &cte);
|
||||
|
@ -479,7 +479,7 @@ static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite,
|
|||
static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite,
|
||||
int irqlevel)
|
||||
{
|
||||
VTEntry vte;
|
||||
VTEntry vte = {};
|
||||
ItsCmdResult cmdres;
|
||||
|
||||
cmdres = lookup_vte(s, __func__, ite->vpeid, &vte);
|
||||
|
@ -514,8 +514,8 @@ static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite,
|
|||
static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid,
|
||||
uint32_t eventid, ItsCmdType cmd)
|
||||
{
|
||||
DTEntry dte;
|
||||
ITEntry ite;
|
||||
DTEntry dte = {};
|
||||
ITEntry ite = {};
|
||||
ItsCmdResult cmdres;
|
||||
int irqlevel;
|
||||
|
||||
|
@ -583,8 +583,8 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt,
|
|||
uint32_t pIntid = 0;
|
||||
uint64_t num_eventids;
|
||||
uint16_t icid = 0;
|
||||
DTEntry dte;
|
||||
ITEntry ite;
|
||||
DTEntry dte = {};
|
||||
ITEntry ite = {};
|
||||
|
||||
devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
|
||||
eventid = cmdpkt[1] & EVENTID_MASK;
|
||||
|
@ -651,8 +651,8 @@ static ItsCmdResult process_vmapti(GICv3ITSState *s, const uint64_t *cmdpkt,
|
|||
{
|
||||
uint32_t devid, eventid, vintid, doorbell, vpeid;
|
||||
uint32_t num_eventids;
|
||||
DTEntry dte;
|
||||
ITEntry ite;
|
||||
DTEntry dte = {};
|
||||
ITEntry ite = {};
|
||||
|
||||
if (!its_feature_virtual(s)) {
|
||||
return CMD_CONTINUE;
|
||||
|
@ -761,7 +761,7 @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte)
|
|||
static ItsCmdResult process_mapc(GICv3ITSState *s, const uint64_t *cmdpkt)
|
||||
{
|
||||
uint16_t icid;
|
||||
CTEntry cte;
|
||||
CTEntry cte = {};
|
||||
|
||||
icid = cmdpkt[2] & ICID_MASK;
|
||||
cte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK;
|
||||
|
@ -822,7 +822,7 @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte)
|
|||
static ItsCmdResult process_mapd(GICv3ITSState *s, const uint64_t *cmdpkt)
|
||||
{
|
||||
uint32_t devid;
|
||||
DTEntry dte;
|
||||
DTEntry dte = {};
|
||||
|
||||
devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
|
||||
dte.size = cmdpkt[1] & SIZE_MASK;
|
||||
|
@ -886,9 +886,9 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
|
|||
{
|
||||
uint32_t devid, eventid;
|
||||
uint16_t new_icid;
|
||||
DTEntry dte;
|
||||
CTEntry old_cte, new_cte;
|
||||
ITEntry old_ite;
|
||||
DTEntry dte = {};
|
||||
CTEntry old_cte = {}, new_cte = {};
|
||||
ITEntry old_ite = {};
|
||||
ItsCmdResult cmdres;
|
||||
|
||||
devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID);
|
||||
|
@ -965,7 +965,7 @@ static bool update_vte(GICv3ITSState *s, uint32_t vpeid, const VTEntry *vte)
|
|||
|
||||
static ItsCmdResult process_vmapp(GICv3ITSState *s, const uint64_t *cmdpkt)
|
||||
{
|
||||
VTEntry vte;
|
||||
VTEntry vte = {};
|
||||
uint32_t vpeid;
|
||||
|
||||
if (!its_feature_virtual(s)) {
|
||||
|
@ -1030,7 +1030,7 @@ static void vmovp_callback(gpointer data, gpointer opaque)
|
|||
*/
|
||||
GICv3ITSState *s = data;
|
||||
VmovpCallbackData *cbdata = opaque;
|
||||
VTEntry vte;
|
||||
VTEntry vte = {};
|
||||
ItsCmdResult cmdres;
|
||||
|
||||
cmdres = lookup_vte(s, __func__, cbdata->vpeid, &vte);
|
||||
|
@ -1085,9 +1085,9 @@ static ItsCmdResult process_vmovi(GICv3ITSState *s, const uint64_t *cmdpkt)
|
|||
{
|
||||
uint32_t devid, eventid, vpeid, doorbell;
|
||||
bool doorbell_valid;
|
||||
DTEntry dte;
|
||||
ITEntry ite;
|
||||
VTEntry old_vte, new_vte;
|
||||
DTEntry dte = {};
|
||||
ITEntry ite = {};
|
||||
VTEntry old_vte = {}, new_vte = {};
|
||||
ItsCmdResult cmdres;
|
||||
|
||||
if (!its_feature_virtual(s)) {
|
||||
|
@ -1186,10 +1186,10 @@ static ItsCmdResult process_vinvall(GICv3ITSState *s, const uint64_t *cmdpkt)
|
|||
static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt)
|
||||
{
|
||||
uint32_t devid, eventid;
|
||||
ITEntry ite;
|
||||
DTEntry dte;
|
||||
CTEntry cte;
|
||||
VTEntry vte;
|
||||
ITEntry ite = {};
|
||||
DTEntry dte = {};
|
||||
CTEntry cte = {};
|
||||
VTEntry vte = {};
|
||||
ItsCmdResult cmdres;
|
||||
|
||||
devid = FIELD_EX64(cmdpkt[0], INV_0, DEVICEID);
|
||||
|
|
|
@ -248,9 +248,12 @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic,
|
|||
|
||||
if ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) ||
|
||||
(sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
|
||||
if (!aplic->msimode || (aplic->msimode && !pending)) {
|
||||
if (!aplic->msimode) {
|
||||
return;
|
||||
}
|
||||
if (aplic->msimode && !pending) {
|
||||
goto noskip_write_pending;
|
||||
}
|
||||
if ((aplic->state[irq] & APLIC_ISTATE_INPUT) &&
|
||||
(sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
|
||||
return;
|
||||
|
@ -261,6 +264,7 @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic,
|
|||
}
|
||||
}
|
||||
|
||||
noskip_write_pending:
|
||||
riscv_aplic_set_pending_raw(aplic, irq, pending);
|
||||
}
|
||||
|
||||
|
|
|
@ -843,7 +843,7 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
|
|||
ComponentRegisters *regs = &cxl_cstate->crb;
|
||||
MemoryRegion *mr = ®s->component_registers;
|
||||
uint8_t *pci_conf = pci_dev->config;
|
||||
unsigned short msix_num = 6;
|
||||
unsigned short msix_num = 10;
|
||||
int i, rc;
|
||||
uint16_t count;
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr,
|
|||
PCIDevice *dev = opaque;
|
||||
if (dev->msix_vector_poll_notifier) {
|
||||
unsigned vector_start = addr * 8;
|
||||
unsigned vector_end = MIN(addr + size * 8, dev->msix_entries_nr);
|
||||
unsigned vector_end = MIN((addr + size) * 8, dev->msix_entries_nr);
|
||||
dev->msix_vector_poll_notifier(dev, vector_start, vector_end);
|
||||
}
|
||||
|
||||
|
|
|
@ -1113,18 +1113,22 @@ void pcie_sync_bridge_lnk(PCIDevice *bridge_dev)
|
|||
if ((lnksta & PCI_EXP_LNKSTA_NLW) > (lnkcap & PCI_EXP_LNKCAP_MLW)) {
|
||||
lnksta &= ~PCI_EXP_LNKSTA_NLW;
|
||||
lnksta |= lnkcap & PCI_EXP_LNKCAP_MLW;
|
||||
} else if (!(lnksta & PCI_EXP_LNKSTA_NLW)) {
|
||||
lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1);
|
||||
}
|
||||
|
||||
if ((lnksta & PCI_EXP_LNKSTA_CLS) > (lnkcap & PCI_EXP_LNKCAP_SLS)) {
|
||||
lnksta &= ~PCI_EXP_LNKSTA_CLS;
|
||||
lnksta |= lnkcap & PCI_EXP_LNKCAP_SLS;
|
||||
} else if (!(lnksta & PCI_EXP_LNKSTA_CLS)) {
|
||||
lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(lnksta & PCI_EXP_LNKSTA_NLW)) {
|
||||
lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1);
|
||||
}
|
||||
|
||||
if (!(lnksta & PCI_EXP_LNKSTA_CLS)) {
|
||||
lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT);
|
||||
}
|
||||
|
||||
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
|
||||
PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW);
|
||||
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, lnksta &
|
||||
|
|
|
@ -180,6 +180,17 @@ static void s390_memory_init(MemoryRegion *ram)
|
|||
{
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
|
||||
if (!QEMU_IS_ALIGNED(memory_region_size(ram), 1 * MiB)) {
|
||||
/*
|
||||
* SCLP cannot possibly expose smaller granularity right now and KVM
|
||||
* cannot handle smaller granularity. As we don't support NUMA, the
|
||||
* region size directly corresponds to machine->ram_size, and the region
|
||||
* is a single RAM memory region.
|
||||
*/
|
||||
error_report("ram size must be multiples of 1 MiB");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* allocate RAM for core */
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
|
||||
|
@ -1189,6 +1200,7 @@ static void ccw_machine_2_9_instance_options(MachineState *machine)
|
|||
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ZPCI);
|
||||
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_INT_SUPPRESSION);
|
||||
s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_EVENT_NOTIFICATION);
|
||||
css_migration_enabled = false;
|
||||
}
|
||||
|
||||
static void ccw_machine_2_9_class_options(MachineClass *mc)
|
||||
|
@ -1201,7 +1213,6 @@ static void ccw_machine_2_9_class_options(MachineClass *mc)
|
|||
ccw_machine_2_10_class_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
|
||||
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
||||
css_migration_enabled = false;
|
||||
}
|
||||
DEFINE_CCW_MACHINE(2, 9);
|
||||
|
||||
|
|
|
@ -1164,7 +1164,7 @@ static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
|
|||
value = ufs_read_attr_value(u, idn);
|
||||
ret = UFS_QUERY_RESULT_SUCCESS;
|
||||
} else {
|
||||
value = req->req_upiu.qr.value;
|
||||
value = be32_to_cpu(req->req_upiu.qr.value);
|
||||
ret = ufs_write_attr_value(u, idn, value);
|
||||
}
|
||||
req->rsp_upiu.qr.value = cpu_to_be32(value);
|
||||
|
|
|
@ -197,8 +197,8 @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p)
|
|||
switch (p->pid) {
|
||||
case USB_TOKEN_OUT:
|
||||
trace_canokey_handle_data_out(ep_out, p->iov.size);
|
||||
usb_packet_copy(p, key->ep_out_buffer[ep_out], p->iov.size);
|
||||
out_pos = 0;
|
||||
/* segment packet into (possibly multiple) ep_out */
|
||||
while (out_pos != p->iov.size) {
|
||||
/*
|
||||
* key->ep_out[ep_out] set by prepare_receive
|
||||
|
@ -207,8 +207,8 @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p)
|
|||
* to be the buffer length
|
||||
*/
|
||||
out_len = MIN(p->iov.size - out_pos, key->ep_out_size[ep_out]);
|
||||
memcpy(key->ep_out[ep_out],
|
||||
key->ep_out_buffer[ep_out] + out_pos, out_len);
|
||||
/* usb_packet_copy would update the pos offset internally */
|
||||
usb_packet_copy(p, key->ep_out[ep_out], out_len);
|
||||
out_pos += out_len;
|
||||
/* update ep_out_size to actual len */
|
||||
key->ep_out_size[ep_out] = out_len;
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#define CANOKEY_EP_NUM 3
|
||||
/* BULK/INTR IN can be up to 1352 bytes, e.g. get key info */
|
||||
#define CANOKEY_EP_IN_BUFFER_SIZE 2048
|
||||
/* BULK OUT can be up to 270 bytes, e.g. PIV import cert */
|
||||
#define CANOKEY_EP_OUT_BUFFER_SIZE 512
|
||||
|
||||
typedef enum {
|
||||
CANOKEY_EP_IN_WAIT,
|
||||
|
@ -59,8 +57,6 @@ typedef struct CanoKeyState {
|
|||
/* OUT pointer to canokey recv buffer */
|
||||
uint8_t *ep_out[CANOKEY_EP_NUM];
|
||||
uint32_t ep_out_size[CANOKEY_EP_NUM];
|
||||
/* For large BULK OUT, multiple write to ep_out is needed */
|
||||
uint8_t ep_out_buffer[CANOKEY_EP_NUM][CANOKEY_EP_OUT_BUFFER_SIZE];
|
||||
|
||||
/* Properties */
|
||||
char *file; /* canokey-file */
|
||||
|
|
|
@ -74,6 +74,7 @@ static bool xhci_pci_intr_raise(XHCIState *xhci, int n, bool level)
|
|||
}
|
||||
|
||||
if (msi_enabled(pci_dev) && level) {
|
||||
n %= msi_nr_vectors_allocated(pci_dev);
|
||||
msi_notify(pci_dev, n);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@ static int voice_resample(MCPXAPUState *d, uint16_t v, float samples[][2],
|
|||
static void voice_reset_filters(MCPXAPUState *d, uint16_t v);
|
||||
static void voice_process(MCPXAPUState *d,
|
||||
float mixbins[NUM_MIXBINS][NUM_SAMPLES_PER_FRAME],
|
||||
uint16_t v);
|
||||
uint16_t v, int voice_list);
|
||||
static int voice_get_samples(MCPXAPUState *d, uint32_t v, float samples[][2],
|
||||
int num_samples_requested);
|
||||
static void se_frame(MCPXAPUState *d);
|
||||
|
@ -245,6 +245,7 @@ static void mcpx_debug_begin_frame(void)
|
|||
{
|
||||
for (int i = 0; i < MCPX_HW_MAX_VOICES; i++) {
|
||||
g_dbg.vp.v[i].active = false;
|
||||
g_dbg.vp.v[i].multipass_dst_voice = 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,6 +287,19 @@ void mcpx_apu_debug_clear_isolations(void)
|
|||
static bool voice_should_mute(uint16_t v)
|
||||
{
|
||||
bool m = (g_dbg_voice_monitor >= 0) && (v != g_dbg_voice_monitor);
|
||||
|
||||
if (m && g_dbg_cache.vp.v[g_dbg_voice_monitor].multipass) {
|
||||
uint8_t mp_bin = g_dbg_cache.vp.v[g_dbg_voice_monitor].multipass_bin;
|
||||
struct McpxApuDebugVoice *d = &g_dbg_cache.vp.v[v];
|
||||
|
||||
for (int i = 0; i < sizeof(d->bin) / sizeof(d->bin[0]); i++) {
|
||||
if (d->bin[i] == mp_bin) {
|
||||
m = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m || mcpx_apu_debug_is_muted(v);
|
||||
}
|
||||
|
||||
|
@ -1590,9 +1604,101 @@ static void voice_reset_filters(MCPXAPUState *d, uint16_t v)
|
|||
}
|
||||
}
|
||||
|
||||
static int peek_ahead_multipass_bin(MCPXAPUState *d, uint16_t v,
|
||||
uint16_t *dst_voice)
|
||||
{
|
||||
bool first = true;
|
||||
|
||||
while (v != 0xFFFF) {
|
||||
bool multipass = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_MULTIPASS);
|
||||
if (multipass) {
|
||||
if (first) {
|
||||
break;
|
||||
}
|
||||
|
||||
*dst_voice = v;
|
||||
int mp_bin = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_MULTIPASS_BIN);
|
||||
return mp_bin;
|
||||
}
|
||||
|
||||
v = voice_get_mask(d, v, NV_PAVS_VOICE_TAR_PITCH_LINK,
|
||||
NV_PAVS_VOICE_TAR_PITCH_LINK_NEXT_VOICE_HANDLE);
|
||||
first = false;
|
||||
}
|
||||
|
||||
*dst_voice = 0xFFFF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void dump_multipass_unused_debug_info(MCPXAPUState *d, uint16_t v)
|
||||
{
|
||||
unsigned int sample_size = voice_get_mask(
|
||||
d, v, NV_PAVS_VOICE_CFG_FMT, NV_PAVS_VOICE_CFG_FMT_SAMPLE_SIZE);
|
||||
unsigned int container_size_index = voice_get_mask(
|
||||
d, v, NV_PAVS_VOICE_CFG_FMT, NV_PAVS_VOICE_CFG_FMT_CONTAINER_SIZE);
|
||||
bool stream = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_DATA_TYPE);
|
||||
bool loop =
|
||||
voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT, NV_PAVS_VOICE_CFG_FMT_LOOP);
|
||||
uint32_t ebo = voice_get_mask(d, v, NV_PAVS_VOICE_PAR_NEXT,
|
||||
NV_PAVS_VOICE_PAR_NEXT_EBO);
|
||||
uint32_t cbo = voice_get_mask(d, v, NV_PAVS_VOICE_PAR_OFFSET,
|
||||
NV_PAVS_VOICE_PAR_OFFSET_CBO);
|
||||
uint32_t lbo = voice_get_mask(d, v, NV_PAVS_VOICE_CUR_PSH_SAMPLE,
|
||||
NV_PAVS_VOICE_CUR_PSH_SAMPLE_LBO);
|
||||
uint32_t ba = voice_get_mask(d, v, NV_PAVS_VOICE_CUR_PSL_START,
|
||||
NV_PAVS_VOICE_CUR_PSL_START_BA);
|
||||
bool persist = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_PERSIST);
|
||||
bool linked = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_LINKED);
|
||||
|
||||
struct McpxApuDebugVoice *dbg = &g_dbg.vp.v[v];
|
||||
dbg->container_size = container_size_index;
|
||||
dbg->sample_size = sample_size;
|
||||
dbg->stream = stream;
|
||||
dbg->loop = loop;
|
||||
dbg->ebo = ebo;
|
||||
dbg->cbo = cbo;
|
||||
dbg->lbo = lbo;
|
||||
dbg->ba = ba;
|
||||
dbg->samples_per_block = 0; // Value overloaded with multipass bin
|
||||
dbg->persist = persist;
|
||||
dbg->linked = linked;
|
||||
}
|
||||
|
||||
static void get_multipass_samples(MCPXAPUState *d,
|
||||
float mixbins[][NUM_SAMPLES_PER_FRAME],
|
||||
uint16_t v, float samples[][2])
|
||||
{
|
||||
struct McpxApuDebugVoice *dbg = &g_dbg.vp.v[v];
|
||||
|
||||
// DirectSound sets bin to 31, but hardware would allow other bins
|
||||
int mp_bin = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_MULTIPASS_BIN);
|
||||
dbg->multipass_bin = mp_bin;
|
||||
|
||||
for (int i = 0; i < NUM_SAMPLES_PER_FRAME; i++) {
|
||||
samples[i][0] = mixbins[mp_bin][i];
|
||||
samples[i][1] = mixbins[mp_bin][i];
|
||||
}
|
||||
|
||||
// DirectSound sets clear mix to true
|
||||
bool clear_mix = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_CLEAR_MIX);
|
||||
if (clear_mix) {
|
||||
memset(&mixbins[mp_bin][0], 0, sizeof(mixbins[0]));
|
||||
}
|
||||
|
||||
// Dump irrelevant data for audio debug UI to avoid showing stale info
|
||||
dump_multipass_unused_debug_info(d, v);
|
||||
}
|
||||
|
||||
static void voice_process(MCPXAPUState *d,
|
||||
float mixbins[NUM_MIXBINS][NUM_SAMPLES_PER_FRAME],
|
||||
uint16_t v)
|
||||
uint16_t v, int voice_list)
|
||||
{
|
||||
assert(v < MCPX_HW_MAX_VOICES);
|
||||
bool stereo = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
|
@ -1633,18 +1739,28 @@ static void voice_process(MCPXAPUState *d,
|
|||
assert(ea_value <= 1.0f);
|
||||
|
||||
float samples[NUM_SAMPLES_PER_FRAME][2] = { 0 };
|
||||
for (int sample_count = 0; sample_count < NUM_SAMPLES_PER_FRAME;) {
|
||||
int active = voice_get_mask(d, v, NV_PAVS_VOICE_PAR_STATE,
|
||||
NV_PAVS_VOICE_PAR_STATE_ACTIVE_VOICE);
|
||||
if (!active) {
|
||||
return;
|
||||
|
||||
bool multipass = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_MULTIPASS);
|
||||
dbg->multipass = multipass;
|
||||
|
||||
if (multipass) {
|
||||
get_multipass_samples(d, mixbins, v, samples);
|
||||
} else {
|
||||
for (int sample_count = 0; sample_count < NUM_SAMPLES_PER_FRAME;) {
|
||||
int active = voice_get_mask(d, v, NV_PAVS_VOICE_PAR_STATE,
|
||||
NV_PAVS_VOICE_PAR_STATE_ACTIVE_VOICE);
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
int count =
|
||||
voice_resample(d, v, &samples[sample_count],
|
||||
NUM_SAMPLES_PER_FRAME - sample_count, rate);
|
||||
if (count < 0) {
|
||||
break;
|
||||
}
|
||||
sample_count += count;
|
||||
}
|
||||
int count = voice_resample(d, v, &samples[sample_count],
|
||||
NUM_SAMPLES_PER_FRAME - sample_count, rate);
|
||||
if (count < 0) {
|
||||
break;
|
||||
}
|
||||
sample_count += count;
|
||||
}
|
||||
|
||||
int active = voice_get_mask(d, v, NV_PAVS_VOICE_PAR_STATE,
|
||||
|
@ -1771,9 +1887,32 @@ static void voice_process(MCPXAPUState *d,
|
|||
/* For VP mon, simply mix all voices together here, selecting the
|
||||
* maximal volume used for any given mixbin as the overall volume for
|
||||
* this voice.
|
||||
*
|
||||
* If the current voice belongs to a multipass sub-voice group we must
|
||||
* skip it here to avoid mixing it in twice because the sub-voices are
|
||||
* mixed into the multipass bin and that sub-mix will be mixed in here
|
||||
* later when the destination (i.e. second pass) voice is processed.
|
||||
* TODO: Are the 2D, 3D and MP voice lists merely a DirectSound
|
||||
* convention? Perhaps hardware doesn't care if e.g. a multipass
|
||||
* voice is in the 2D or 3D list. On the other hand, MON_VP is
|
||||
* not how the hardware works anyway so not much point worrying
|
||||
* about precise emulation here. DirectSound compatibility is
|
||||
* enough.
|
||||
*/
|
||||
int mp_bin = -1;
|
||||
uint16_t mp_dst_voice = 0xFFFF;
|
||||
if (voice_list == NV1BA0_PIO_SET_ANTECEDENT_VOICE_LIST_MP_TOP - 1) {
|
||||
mp_bin = peek_ahead_multipass_bin(d, v, &mp_dst_voice);
|
||||
}
|
||||
dbg->multipass_dst_voice = mp_dst_voice;
|
||||
|
||||
bool debug_isolation =
|
||||
g_dbg_voice_monitor >= 0 && g_dbg_voice_monitor == v;
|
||||
float g = 0.0f;
|
||||
for (int b = 0; b < 8; b++) {
|
||||
if (bin[b] == mp_bin && !debug_isolation) {
|
||||
continue;
|
||||
}
|
||||
float hr = 1 << d->vp.submix_headroom[bin[b]];
|
||||
g = fmax(g, attenuate(vol[b]) / hr);
|
||||
}
|
||||
|
@ -1822,6 +1961,8 @@ static int voice_get_samples(MCPXAPUState *d, uint32_t v, float samples[][2],
|
|||
bool linked = voice_get_mask(d, v, NV_PAVS_VOICE_CFG_FMT,
|
||||
NV_PAVS_VOICE_CFG_FMT_LINKED); /* FIXME? */
|
||||
|
||||
assert(!multipass); // Multipass is handled before this
|
||||
|
||||
int ssl_index = 0;
|
||||
int ssl_seg = 0;
|
||||
int page = 0;
|
||||
|
@ -1954,11 +2095,6 @@ static int voice_get_samples(MCPXAPUState *d, uint32_t v, float samples[][2],
|
|||
|
||||
DPRINTF("CBO=%d EBO=%d\n", cbo, ebo);
|
||||
|
||||
if (multipass) {
|
||||
// FIXME
|
||||
samples_per_block = 1;
|
||||
}
|
||||
|
||||
block_size *= samples_per_block;
|
||||
|
||||
// FIXME: Restructure this loop
|
||||
|
@ -2147,7 +2283,7 @@ static void se_frame(MCPXAPUState *d)
|
|||
qemu_cond_wait(&d->cond, &d->lock);
|
||||
qemu_spin_lock(&d->vp.voice_spinlocks[v]);
|
||||
}
|
||||
voice_process(d, mixbins, v);
|
||||
voice_process(d, mixbins, v, list);
|
||||
qemu_spin_unlock(&d->vp.voice_spinlocks[v]);
|
||||
}
|
||||
d->regs[current] = d->regs[next];
|
||||
|
|
|
@ -44,6 +44,8 @@ struct McpxApuDebugVoice
|
|||
bool persist;
|
||||
bool multipass;
|
||||
bool linked;
|
||||
uint8_t multipass_bin;
|
||||
uint16_t multipass_dst_voice;
|
||||
int container_size, sample_size;
|
||||
unsigned int samples_per_block;
|
||||
uint32_t ebo, cbo, lbo, ba;
|
||||
|
|
|
@ -377,6 +377,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s);
|
|||
int kvm_arch_init_vcpu(CPUState *cpu);
|
||||
int kvm_arch_destroy_vcpu(CPUState *cpu);
|
||||
|
||||
#ifdef TARGET_KVM_HAVE_RESET_PARKED_VCPU
|
||||
void kvm_arch_reset_parked_vcpu(unsigned long vcpu_id, int kvm_fd);
|
||||
#else
|
||||
static inline void kvm_arch_reset_parked_vcpu(unsigned long vcpu_id, int kvm_fd)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
bool kvm_vcpu_id_is_valid(int vcpu_id);
|
||||
|
||||
/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
|
||||
|
|
|
@ -1143,7 +1143,7 @@ endif
|
|||
|
||||
libnfs = not_found
|
||||
if not get_option('libnfs').auto() or have_block
|
||||
libnfs = dependency('libnfs', version: '>=1.9.3',
|
||||
libnfs = dependency('libnfs', version: ['>=1.9.3', '<6.0.0'],
|
||||
required: get_option('libnfs'),
|
||||
method: 'pkg-config')
|
||||
endif
|
||||
|
|
|
@ -362,6 +362,7 @@ int multifd_ram_flush_and_sync(void)
|
|||
bool multifd_send_prepare_common(MultiFDSendParams *p)
|
||||
{
|
||||
MultiFDPages_t *pages = &p->data->u.ram;
|
||||
multifd_send_prepare_header(p);
|
||||
multifd_send_zero_page_detect(p);
|
||||
|
||||
if (!pages->normal_num) {
|
||||
|
@ -369,8 +370,6 @@ bool multifd_send_prepare_common(MultiFDSendParams *p)
|
|||
return false;
|
||||
}
|
||||
|
||||
multifd_send_prepare_header(p);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -373,6 +373,7 @@ static int qatzip_recv(MultiFDRecvParams *p, Error **errp)
|
|||
/* Copy each page to its appropriate location. */
|
||||
for (int i = 0; i < p->normal_num; i++) {
|
||||
memcpy(p->host + p->normal[i], q->out_buf + page_size * i, page_size);
|
||||
ramblock_recv_bitmap_set_offset(p->block, p->normal[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -679,6 +679,7 @@ static int multifd_qpl_recv(MultiFDRecvParams *p, Error **errp)
|
|||
qpl->zlen[i] = be32_to_cpu(qpl->zlen[i]);
|
||||
assert(qpl->zlen[i] <= multifd_ram_page_size());
|
||||
zbuf_len += qpl->zlen[i];
|
||||
ramblock_recv_bitmap_set_offset(p->block, p->normal[i]);
|
||||
}
|
||||
|
||||
/* read compressed pages */
|
||||
|
|
|
@ -169,7 +169,7 @@ static int multifd_uadk_send_prepare(MultiFDSendParams *p, Error **errp)
|
|||
.src_len = page_size,
|
||||
.dst = buf,
|
||||
/* Set dst_len to double the src in case compressed out >= page_size */
|
||||
.dst_len = p->page_size * 2,
|
||||
.dst_len = page_size * 2,
|
||||
};
|
||||
|
||||
if (uadk_data->handle) {
|
||||
|
|
|
@ -252,9 +252,8 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
|
|||
p->packet_num = be64_to_cpu(packet->packet_num);
|
||||
p->packets_recved++;
|
||||
|
||||
if (!(p->flags & MULTIFD_FLAG_SYNC)) {
|
||||
ret = multifd_ram_unfill_packet(p, errp);
|
||||
}
|
||||
/* Always unfill, old QEMUs (<9.0) send data along with SYNC */
|
||||
ret = multifd_ram_unfill_packet(p, errp);
|
||||
|
||||
trace_multifd_recv_unfill(p->id, p->packet_num, p->flags,
|
||||
p->next_packet_size);
|
||||
|
@ -1151,9 +1150,13 @@ static void *multifd_recv_thread(void *opaque)
|
|||
flags = p->flags;
|
||||
/* recv methods don't know how to handle the SYNC flag */
|
||||
p->flags &= ~MULTIFD_FLAG_SYNC;
|
||||
if (!(flags & MULTIFD_FLAG_SYNC)) {
|
||||
has_data = p->normal_num || p->zero_num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Even if it's a SYNC packet, this needs to be set
|
||||
* because older QEMUs (<9.0) still send data along with
|
||||
* the SYNC packet.
|
||||
*/
|
||||
has_data = p->normal_num || p->zero_num;
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
} else {
|
||||
/*
|
||||
|
|
|
@ -338,7 +338,7 @@ static int put_nullptr(QEMUFile *f, void *pv, size_t size,
|
|||
}
|
||||
|
||||
const VMStateInfo vmstate_info_nullptr = {
|
||||
.name = "uint64",
|
||||
.name = "nullptr",
|
||||
.get = get_nullptr,
|
||||
.put = put_nullptr,
|
||||
};
|
||||
|
|
|
@ -51,6 +51,36 @@ vmstate_field_exists(const VMStateDescription *vmsd, const VMStateField *field,
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a fake nullptr field when there's a NULL pointer detected in the
|
||||
* array of a VMS_ARRAY_OF_POINTER VMSD field. It's needed because we
|
||||
* can't dereference the NULL pointer.
|
||||
*/
|
||||
static const VMStateField *
|
||||
vmsd_create_fake_nullptr_field(const VMStateField *field)
|
||||
{
|
||||
VMStateField *fake = g_new0(VMStateField, 1);
|
||||
|
||||
/* It can only happen on an array of pointers! */
|
||||
assert(field->flags & VMS_ARRAY_OF_POINTER);
|
||||
|
||||
/* Some of fake's properties should match the original's */
|
||||
fake->name = field->name;
|
||||
fake->version_id = field->version_id;
|
||||
|
||||
/* Do not need "field_exists" check as it always exists (which is null) */
|
||||
fake->field_exists = NULL;
|
||||
|
||||
/* See vmstate_info_nullptr - use 1 byte to represent nullptr */
|
||||
fake->size = 1;
|
||||
fake->info = &vmstate_info_nullptr;
|
||||
fake->flags = VMS_SINGLE;
|
||||
|
||||
/* All the rest fields shouldn't matter.. */
|
||||
|
||||
return (const VMStateField *)fake;
|
||||
}
|
||||
|
||||
static int vmstate_n_elems(void *opaque, const VMStateField *field)
|
||||
{
|
||||
int n_elems = 1;
|
||||
|
@ -143,23 +173,39 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
|
|||
}
|
||||
for (i = 0; i < n_elems; i++) {
|
||||
void *curr_elem = first_elem + size * i;
|
||||
const VMStateField *inner_field;
|
||||
|
||||
if (field->flags & VMS_ARRAY_OF_POINTER) {
|
||||
curr_elem = *(void **)curr_elem;
|
||||
}
|
||||
|
||||
if (!curr_elem && size) {
|
||||
/* if null pointer check placeholder and do not follow */
|
||||
assert(field->flags & VMS_ARRAY_OF_POINTER);
|
||||
ret = vmstate_info_nullptr.get(f, curr_elem, size, NULL);
|
||||
} else if (field->flags & VMS_STRUCT) {
|
||||
ret = vmstate_load_state(f, field->vmsd, curr_elem,
|
||||
field->vmsd->version_id);
|
||||
} else if (field->flags & VMS_VSTRUCT) {
|
||||
ret = vmstate_load_state(f, field->vmsd, curr_elem,
|
||||
field->struct_version_id);
|
||||
/*
|
||||
* If null pointer found (which should only happen in
|
||||
* an array of pointers), use null placeholder and do
|
||||
* not follow.
|
||||
*/
|
||||
inner_field = vmsd_create_fake_nullptr_field(field);
|
||||
} else {
|
||||
ret = field->info->get(f, curr_elem, size, field);
|
||||
inner_field = field;
|
||||
}
|
||||
|
||||
if (inner_field->flags & VMS_STRUCT) {
|
||||
ret = vmstate_load_state(f, inner_field->vmsd, curr_elem,
|
||||
inner_field->vmsd->version_id);
|
||||
} else if (inner_field->flags & VMS_VSTRUCT) {
|
||||
ret = vmstate_load_state(f, inner_field->vmsd, curr_elem,
|
||||
inner_field->struct_version_id);
|
||||
} else {
|
||||
ret = inner_field->info->get(f, curr_elem, size,
|
||||
inner_field);
|
||||
}
|
||||
|
||||
/* If we used a fake temp field.. free it now */
|
||||
if (inner_field != field) {
|
||||
g_clear_pointer((gpointer *)&inner_field, g_free);
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
ret = qemu_file_get_error(f);
|
||||
}
|
||||
|
@ -311,7 +357,7 @@ static void vmsd_desc_field_start(const VMStateDescription *vmsd,
|
|||
|
||||
static void vmsd_desc_field_end(const VMStateDescription *vmsd,
|
||||
JSONWriter *vmdesc,
|
||||
const VMStateField *field, size_t size, int i)
|
||||
const VMStateField *field, size_t size)
|
||||
{
|
||||
if (!vmdesc) {
|
||||
return;
|
||||
|
@ -379,37 +425,89 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
|
|||
int size = vmstate_size(opaque, field);
|
||||
uint64_t old_offset, written_bytes;
|
||||
JSONWriter *vmdesc_loop = vmdesc;
|
||||
bool is_prev_null = false;
|
||||
|
||||
trace_vmstate_save_state_loop(vmsd->name, field->name, n_elems);
|
||||
if (field->flags & VMS_POINTER) {
|
||||
first_elem = *(void **)first_elem;
|
||||
assert(first_elem || !n_elems || !size);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_elems; i++) {
|
||||
void *curr_elem = first_elem + size * i;
|
||||
const VMStateField *inner_field;
|
||||
bool is_null;
|
||||
int max_elems = n_elems - i;
|
||||
|
||||
vmsd_desc_field_start(vmsd, vmdesc_loop, field, i, n_elems);
|
||||
old_offset = qemu_file_transferred(f);
|
||||
if (field->flags & VMS_ARRAY_OF_POINTER) {
|
||||
assert(curr_elem);
|
||||
curr_elem = *(void **)curr_elem;
|
||||
}
|
||||
|
||||
if (!curr_elem && size) {
|
||||
/* if null pointer write placeholder and do not follow */
|
||||
assert(field->flags & VMS_ARRAY_OF_POINTER);
|
||||
ret = vmstate_info_nullptr.put(f, curr_elem, size, NULL,
|
||||
NULL);
|
||||
} else if (field->flags & VMS_STRUCT) {
|
||||
ret = vmstate_save_state(f, field->vmsd, curr_elem,
|
||||
vmdesc_loop);
|
||||
} else if (field->flags & VMS_VSTRUCT) {
|
||||
ret = vmstate_save_state_v(f, field->vmsd, curr_elem,
|
||||
vmdesc_loop,
|
||||
field->struct_version_id, errp);
|
||||
/*
|
||||
* If null pointer found (which should only happen in
|
||||
* an array of pointers), use null placeholder and do
|
||||
* not follow.
|
||||
*/
|
||||
inner_field = vmsd_create_fake_nullptr_field(field);
|
||||
is_null = true;
|
||||
} else {
|
||||
ret = field->info->put(f, curr_elem, size, field,
|
||||
vmdesc_loop);
|
||||
inner_field = field;
|
||||
is_null = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Due to the fake nullptr handling above, if there's mixed
|
||||
* null/non-null data, it doesn't make sense to emit a
|
||||
* compressed array representation spanning the entire array
|
||||
* because the field types will be different (e.g. struct
|
||||
* vs. nullptr). Search ahead for the next null/non-null element
|
||||
* and start a new compressed array if found.
|
||||
*/
|
||||
if (field->flags & VMS_ARRAY_OF_POINTER &&
|
||||
is_null != is_prev_null) {
|
||||
|
||||
is_prev_null = is_null;
|
||||
vmdesc_loop = vmdesc;
|
||||
|
||||
for (int j = i + 1; j < n_elems; j++) {
|
||||
void *elem = *(void **)(first_elem + size * j);
|
||||
bool elem_is_null = !elem && size;
|
||||
|
||||
if (is_null != elem_is_null) {
|
||||
max_elems = j - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vmsd_desc_field_start(vmsd, vmdesc_loop, inner_field,
|
||||
i, max_elems);
|
||||
|
||||
if (inner_field->flags & VMS_STRUCT) {
|
||||
ret = vmstate_save_state(f, inner_field->vmsd,
|
||||
curr_elem, vmdesc_loop);
|
||||
} else if (inner_field->flags & VMS_VSTRUCT) {
|
||||
ret = vmstate_save_state_v(f, inner_field->vmsd,
|
||||
curr_elem, vmdesc_loop,
|
||||
inner_field->struct_version_id,
|
||||
errp);
|
||||
} else {
|
||||
ret = inner_field->info->put(f, curr_elem, size,
|
||||
inner_field, vmdesc_loop);
|
||||
}
|
||||
|
||||
written_bytes = qemu_file_transferred(f) - old_offset;
|
||||
vmsd_desc_field_end(vmsd, vmdesc_loop, inner_field,
|
||||
written_bytes);
|
||||
|
||||
/* If we used a fake temp field.. free it now */
|
||||
if (inner_field != field) {
|
||||
g_clear_pointer((gpointer *)&inner_field, g_free);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
error_setg(errp, "Save of field %s/%s failed",
|
||||
vmsd->name, field->name);
|
||||
|
@ -419,9 +517,6 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
|
|||
return ret;
|
||||
}
|
||||
|
||||
written_bytes = qemu_file_transferred(f) - old_offset;
|
||||
vmsd_desc_field_end(vmsd, vmdesc_loop, field, written_bytes, i);
|
||||
|
||||
/* Compressed arrays only care about the first element */
|
||||
if (vmdesc_loop && vmsd_can_compress(field)) {
|
||||
vmdesc_loop = NULL;
|
||||
|
|
|
@ -155,7 +155,8 @@ static ssize_t filter_dump_receive_iov(NetFilterState *nf, NetClientState *sndr,
|
|||
{
|
||||
NetFilterDumpState *nfds = FILTER_DUMP(nf);
|
||||
|
||||
dump_receive_iov(&nfds->ds, iov, iovcnt, qemu_get_vnet_hdr_len(nf->netdev));
|
||||
dump_receive_iov(&nfds->ds, iov, iovcnt, flags & QEMU_NET_PACKET_FLAG_RAW ?
|
||||
0 : qemu_get_vnet_hdr_len(nf->netdev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -822,6 +822,7 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
|||
iov_copy[0].iov_len = nc->vnet_hdr_len;
|
||||
memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
|
||||
iov = iov_copy;
|
||||
iovcnt++;
|
||||
}
|
||||
|
||||
if (nc->info->receive_iov) {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"description": "UEFI firmware for riscv64",
|
||||
"interface-types": [
|
||||
"uefi"
|
||||
],
|
||||
"mapping": {
|
||||
"device": "flash",
|
||||
"executable": {
|
||||
"filename": "@DATADIR@/edk2-riscv-code.fd",
|
||||
"format": "raw"
|
||||
},
|
||||
"nvram-template": {
|
||||
"filename": "@DATADIR@/edk2-riscv-vars.fd",
|
||||
"format": "raw"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"architecture": "riscv64",
|
||||
"machines": [
|
||||
"virt*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"features": [
|
||||
|
||||
],
|
||||
"tags": [
|
||||
|
||||
]
|
||||
}
|
|
@ -6,7 +6,8 @@ if unpack_edk2_blobs and get_option('install_blobs')
|
|||
'60-edk2-arm.json',
|
||||
'60-edk2-i386.json',
|
||||
'60-edk2-x86_64.json',
|
||||
'60-edk2-loongarch64.json'
|
||||
'60-edk2-loongarch64.json',
|
||||
'60-edk2-riscv64.json'
|
||||
]
|
||||
configure_file(input: files(f),
|
||||
output: f,
|
||||
|
|
|
@ -157,6 +157,11 @@ edk2-version: edk2
|
|||
touch $@; \
|
||||
fi
|
||||
|
||||
edk2-basetools: edk2-version
|
||||
$(PYTHON) edk2-build.py --config edk2-build.config \
|
||||
--silent --no-logs \
|
||||
--match none # build only basetools
|
||||
|
||||
efi: edk2-version
|
||||
$(PYTHON) edk2-build.py --config edk2-build.config \
|
||||
--version-override "$(EDK2_STABLE)$(FIRMWARE_EXTRAVERSION)" \
|
||||
|
|
|
@ -65,6 +65,9 @@ class MigrationFile(object):
|
|||
def tell(self):
|
||||
return self.file.tell()
|
||||
|
||||
def seek(self, a, b):
|
||||
return self.file.seek(a, b)
|
||||
|
||||
# The VMSD description is at the end of the file, after EOF. Look for
|
||||
# the last NULL byte, then for the beginning brace of JSON.
|
||||
def read_migration_debug_json(self):
|
||||
|
@ -272,11 +275,24 @@ class S390StorageAttributes(object):
|
|||
self.section_key = section_key
|
||||
|
||||
def read(self):
|
||||
pos = 0
|
||||
while True:
|
||||
addr_flags = self.file.read64()
|
||||
flags = addr_flags & 0xfff
|
||||
if (flags & (self.STATTR_FLAG_DONE | self.STATTR_FLAG_EOS)):
|
||||
|
||||
if flags & self.STATTR_FLAG_DONE:
|
||||
pos = self.file.tell()
|
||||
continue
|
||||
elif flags & self.STATTR_FLAG_EOS:
|
||||
return
|
||||
else:
|
||||
# No EOS came after DONE, that's OK, but rewind the
|
||||
# stream because this is not our data.
|
||||
if pos:
|
||||
self.file.seek(pos, os.SEEK_SET)
|
||||
return
|
||||
raise Exception("Unknown flags %x", flags)
|
||||
|
||||
if (flags & self.STATTR_FLAG_ERROR):
|
||||
raise Exception("Error in migration stream")
|
||||
count = self.file.read64()
|
||||
|
@ -401,6 +417,28 @@ class VMSDFieldIntLE(VMSDFieldInt):
|
|||
super(VMSDFieldIntLE, self).__init__(desc, file)
|
||||
self.dtype = '<i%d' % self.size
|
||||
|
||||
class VMSDFieldNull(VMSDFieldGeneric):
|
||||
NULL_PTR_MARKER = b'0'
|
||||
|
||||
def __init__(self, desc, file):
|
||||
super(VMSDFieldNull, self).__init__(desc, file)
|
||||
|
||||
def __repr__(self):
|
||||
# A NULL pointer is encoded in the stream as a '0' to
|
||||
# disambiguate from a mere 0x0 value and avoid consumers
|
||||
# trying to follow the NULL pointer. Displaying '0', 0x30 or
|
||||
# 0x0 when analyzing the JSON debug stream could become
|
||||
# confusing, so use an explicit term instead.
|
||||
return "nullptr"
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
||||
def read(self):
|
||||
super(VMSDFieldNull, self).read()
|
||||
assert(self.data == self.NULL_PTR_MARKER)
|
||||
return self.data
|
||||
|
||||
class VMSDFieldBool(VMSDFieldGeneric):
|
||||
def __init__(self, desc, file):
|
||||
super(VMSDFieldBool, self).__init__(desc, file)
|
||||
|
@ -429,6 +467,9 @@ class VMSDFieldStruct(VMSDFieldGeneric):
|
|||
super(VMSDFieldStruct, self).__init__(desc, file)
|
||||
self.data = collections.OrderedDict()
|
||||
|
||||
if 'fields' not in self.desc['struct']:
|
||||
raise Exception("No fields in struct. VMSD:\n%s" % self.desc)
|
||||
|
||||
# When we see compressed array elements, unfold them here
|
||||
new_fields = []
|
||||
for field in self.desc['struct']['fields']:
|
||||
|
@ -461,15 +502,25 @@ class VMSDFieldStruct(VMSDFieldGeneric):
|
|||
field['data'] = reader(field, self.file)
|
||||
field['data'].read()
|
||||
|
||||
if 'index' in field:
|
||||
if field['name'] not in self.data:
|
||||
self.data[field['name']] = []
|
||||
a = self.data[field['name']]
|
||||
if len(a) != int(field['index']):
|
||||
raise Exception("internal index of data field unmatched (%d/%d)" % (len(a), int(field['index'])))
|
||||
a.append(field['data'])
|
||||
fname = field['name']
|
||||
fdata = field['data']
|
||||
|
||||
# The field could be:
|
||||
# i) a single data entry, e.g. uint64
|
||||
# ii) an array, indicated by it containing the 'index' key
|
||||
#
|
||||
# However, the overall data after parsing the whole
|
||||
# stream, could be a mix of arrays and single data fields,
|
||||
# all sharing the same field name due to how QEMU breaks
|
||||
# up arrays with NULL pointers into multiple compressed
|
||||
# array segments.
|
||||
if fname not in self.data:
|
||||
self.data[fname] = fdata
|
||||
elif type(self.data[fname]) == list:
|
||||
self.data[fname].append(fdata)
|
||||
else:
|
||||
self.data[field['name']] = field['data']
|
||||
tmp = self.data[fname]
|
||||
self.data[fname] = [tmp, fdata]
|
||||
|
||||
if 'subsections' in self.desc['struct']:
|
||||
for subsection in self.desc['struct']['subsections']:
|
||||
|
@ -477,6 +528,10 @@ class VMSDFieldStruct(VMSDFieldGeneric):
|
|||
raise Exception("Subsection %s not found at offset %x" % ( subsection['vmsd_name'], self.file.tell()))
|
||||
name = self.file.readstr()
|
||||
version_id = self.file.read32()
|
||||
|
||||
if not subsection:
|
||||
raise Exception("Empty description for subsection: %s" % name)
|
||||
|
||||
self.data[name] = VMSDSection(self.file, version_id, subsection, (name, 0))
|
||||
self.data[name].read()
|
||||
|
||||
|
@ -535,6 +590,7 @@ vmsd_field_readers = {
|
|||
"bitmap" : VMSDFieldGeneric,
|
||||
"struct" : VMSDFieldStruct,
|
||||
"capability": VMSDFieldCap,
|
||||
"nullptr": VMSDFieldNull,
|
||||
"unknown" : VMSDFieldGeneric,
|
||||
}
|
||||
|
||||
|
@ -574,10 +630,13 @@ class MigrationDump(object):
|
|||
}
|
||||
self.filename = filename
|
||||
self.vmsd_desc = None
|
||||
self.vmsd_json = ""
|
||||
|
||||
def read(self, desc_only = False, dump_memory = False, write_memory = False):
|
||||
def read(self, desc_only = False, dump_memory = False,
|
||||
write_memory = False):
|
||||
# Read in the whole file
|
||||
file = MigrationFile(self.filename)
|
||||
self.vmsd_json = file.read_migration_debug_json()
|
||||
|
||||
# File magic
|
||||
data = file.read32()
|
||||
|
@ -635,9 +694,11 @@ class MigrationDump(object):
|
|||
file.close()
|
||||
|
||||
def load_vmsd_json(self, file):
|
||||
vmsd_json = file.read_migration_debug_json()
|
||||
self.vmsd_desc = json.loads(vmsd_json, object_pairs_hook=collections.OrderedDict)
|
||||
self.vmsd_desc = json.loads(self.vmsd_json,
|
||||
object_pairs_hook=collections.OrderedDict)
|
||||
for device in self.vmsd_desc['devices']:
|
||||
if 'fields' not in device:
|
||||
raise Exception("vmstate for device %s has no fields" % device['name'])
|
||||
key = (device['name'], device['instance_id'])
|
||||
value = ( VMSDSection, device )
|
||||
self.section_classes[key] = value
|
||||
|
@ -666,31 +727,34 @@ args = parser.parse_args()
|
|||
|
||||
jsonenc = JSONEncoder(indent=4, separators=(',', ': '))
|
||||
|
||||
if args.extract:
|
||||
dump = MigrationDump(args.file)
|
||||
|
||||
dump.read(desc_only = True)
|
||||
print("desc.json")
|
||||
f = open("desc.json", "w")
|
||||
f.truncate()
|
||||
f.write(jsonenc.encode(dump.vmsd_desc))
|
||||
f.close()
|
||||
|
||||
dump.read(write_memory = True)
|
||||
dict = dump.getDict()
|
||||
print("state.json")
|
||||
f = open("state.json", "w")
|
||||
f.truncate()
|
||||
f.write(jsonenc.encode(dict))
|
||||
f.close()
|
||||
elif args.dump == "state":
|
||||
dump = MigrationDump(args.file)
|
||||
dump.read(dump_memory = args.memory)
|
||||
dict = dump.getDict()
|
||||
print(jsonenc.encode(dict))
|
||||
elif args.dump == "desc":
|
||||
dump = MigrationDump(args.file)
|
||||
dump.read(desc_only = True)
|
||||
print(jsonenc.encode(dump.vmsd_desc))
|
||||
else:
|
||||
if not any([args.extract, args.dump == "state", args.dump == "desc"]):
|
||||
raise Exception("Please specify either -x, -d state or -d desc")
|
||||
|
||||
try:
|
||||
dump = MigrationDump(args.file)
|
||||
|
||||
if args.extract:
|
||||
dump.read(desc_only = True)
|
||||
|
||||
print("desc.json")
|
||||
f = open("desc.json", "w")
|
||||
f.truncate()
|
||||
f.write(jsonenc.encode(dump.vmsd_desc))
|
||||
f.close()
|
||||
|
||||
dump.read(write_memory = True)
|
||||
dict = dump.getDict()
|
||||
print("state.json")
|
||||
f = open("state.json", "w")
|
||||
f.truncate()
|
||||
f.write(jsonenc.encode(dict))
|
||||
f.close()
|
||||
elif args.dump == "state":
|
||||
dump.read(dump_memory = args.memory)
|
||||
dict = dump.getDict()
|
||||
print(jsonenc.encode(dict))
|
||||
elif args.dump == "desc":
|
||||
dump.read(desc_only = True)
|
||||
print(jsonenc.encode(dump.vmsd_desc))
|
||||
except Exception:
|
||||
raise Exception("Full JSON dump:\n%s", dump.vmsd_json)
|
||||
|
|
|
@ -10,6 +10,27 @@
|
|||
# This work is licensed under the terms of the GNU GPLv2 or later.
|
||||
# See the COPYING file in the top-level directory.
|
||||
|
||||
function subproject_dir() {
|
||||
if test ! -f "subprojects/$1.wrap"; then
|
||||
error "scripts/archive-source.sh should only process wrap subprojects"
|
||||
fi
|
||||
|
||||
# Print the directory key of the wrap file, defaulting to the
|
||||
# subproject name. The wrap file is in ini format and should
|
||||
# have a single section only. There should be only one section
|
||||
# named "[wrap-*]", which helps keeping the script simple.
|
||||
local dir
|
||||
dir=$(sed -n \
|
||||
-e '/^\[wrap-[a-z][a-z]*\]$/,/^\[/{' \
|
||||
-e '/^directory *= */!b' \
|
||||
-e 's///p' \
|
||||
-e 'q' \
|
||||
-e '}' \
|
||||
"subprojects/$1.wrap")
|
||||
|
||||
echo "${dir:-$1}"
|
||||
}
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage:"
|
||||
echo " $0 gitrepo version"
|
||||
|
@ -51,5 +72,13 @@ meson subprojects download $SUBPROJECTS
|
|||
CryptoPkg/Library/OpensslLib/openssl \
|
||||
MdeModulePkg/Library/BrotliCustomDecompressLib/brotli)
|
||||
popd
|
||||
tar --exclude=.git -cJf ${destination}.tar.xz ${destination}
|
||||
|
||||
exclude=(--exclude=.git)
|
||||
# include the tarballs in subprojects/packagecache but not their expansion
|
||||
for sp in $SUBPROJECTS; do
|
||||
if grep -xqF "[wrap-file]" subprojects/$sp.wrap; then
|
||||
exclude+=(--exclude=subprojects/"$(subproject_dir $sp)")
|
||||
fi
|
||||
done
|
||||
tar "${exclude[@]}" -cJf ${destination}.tar.xz ${destination}
|
||||
rm -rf ${destination}
|
||||
|
|
|
@ -57,8 +57,8 @@ if have_user
|
|||
stub_ss.add(files('cpu-synchronize-state.c'))
|
||||
|
||||
# Stubs for QAPI events. Those can always be included in the build, but
|
||||
# they are not built at all for --disable-system --disable-tools builds.
|
||||
if not (have_system or have_tools)
|
||||
# they are not built at all for --disable-system builds.
|
||||
if not have_system
|
||||
stub_ss.add(files('qdev.c'))
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[wrap-git]
|
||||
url=https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
|
||||
revision=v3.2.0
|
||||
revision=v3.2.1
|
||||
depth=1
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
[wrap-file]
|
||||
directory = xxHash-0.8.2
|
||||
source_url = https://github.com/Cyan4973/xxHash/archive/v0.8.2.tar.gz
|
||||
source_filename = xxHash-0.8.2.tar.gz
|
||||
source_hash = baee0c6afd4f03165de7a4e67988d16f0f2b257b51d0e3cb91909302a26a79c4
|
||||
patch_filename = xxhash_0.8.2-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/xxhash_0.8.2-1/get_patch
|
||||
patch_hash = e721ef7a4c4ee0ade8b8440f6f7cb9f935b68e825249d74cb1c2503c53e68d25
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/xxhash_0.8.2-1/xxHash-0.8.2.tar.gz
|
||||
wrapdb_version = 0.8.2-1
|
||||
directory = xxHash-0.8.3
|
||||
source_url = https://github.com/Cyan4973/xxHash/archive/v0.8.3.tar.gz
|
||||
source_filename = xxHash-0.8.3.tar.gz
|
||||
source_hash = aae608dfe8213dfd05d909a57718ef82f30722c392344583d3f39050c7f29a80
|
||||
patch_filename = xxhash_0.8.3-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/xxhash_0.8.3-1/get_patch
|
||||
patch_hash = 39c2418defa1d34cfe079c477b314b0a7a1bca657d91cdff4a05b8a7ed78aceb
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/xxhash_0.8.3-1/xxHash-0.8.3.tar.gz
|
||||
wrapdb_version = 0.8.3-1
|
||||
|
||||
[provide]
|
||||
libxxhash = xxhash_dep
|
||||
|
|
|
@ -2054,10 +2054,12 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
|
|||
size = REAL_HOST_PAGE_ALIGN(size);
|
||||
|
||||
file_size = get_file_size(fd);
|
||||
if (file_size > offset && file_size < (offset + size)) {
|
||||
error_setg(errp, "backing store size 0x%" PRIx64
|
||||
" does not match 'size' option 0x" RAM_ADDR_FMT,
|
||||
file_size, size);
|
||||
if (file_size && file_size < offset + size) {
|
||||
error_setg(errp, "%s backing store size 0x%" PRIx64
|
||||
" is too small for 'size' option 0x" RAM_ADDR_FMT
|
||||
" plus 'offset' option 0x%" PRIx64,
|
||||
memory_region_name(mr), file_size, size,
|
||||
(uint64_t)offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -7362,7 +7362,7 @@ static void arm_reset_sve_state(CPUARMState *env)
|
|||
memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs));
|
||||
/* Recall that FFR is stored as pregs[16]. */
|
||||
memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs));
|
||||
vfp_set_fpcr(env, 0x0800009f);
|
||||
vfp_set_fpsr(env, 0x0800009f);
|
||||
}
|
||||
|
||||
void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask)
|
||||
|
|
|
@ -3715,6 +3715,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
|||
},
|
||||
{
|
||||
.version = 4,
|
||||
.note = "IBRS, EPT switching, no TSX",
|
||||
.props = (PropValue[]) {
|
||||
{ "vmx-eptp-switching", "on" },
|
||||
{ /* end of list */ }
|
||||
|
@ -3849,7 +3850,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
|||
},
|
||||
},
|
||||
{ .version = 4,
|
||||
.note = "ARCH_CAPABILITIES, no TSX",
|
||||
.note = "ARCH_CAPABILITIES, EPT switching, no TSX",
|
||||
.props = (PropValue[]) {
|
||||
{ "vmx-eptp-switching", "on" },
|
||||
{ /* end of list */ }
|
||||
|
@ -7768,8 +7769,10 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose)
|
|||
env->avx10_version = version;
|
||||
have_filtered_features = true;
|
||||
}
|
||||
} else if (env->avx10_version && prefix) {
|
||||
warn_report("%s: avx10.%d.", prefix, env->avx10_version);
|
||||
} else if (env->avx10_version) {
|
||||
if (prefix) {
|
||||
warn_report("%s: avx10.%d.", prefix, env->avx10_version);
|
||||
}
|
||||
have_filtered_features = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2415,6 +2415,21 @@ void kvm_arch_after_reset_vcpu(X86CPU *cpu)
|
|||
}
|
||||
}
|
||||
|
||||
void kvm_arch_reset_parked_vcpu(unsigned long vcpu_id, int kvm_fd)
|
||||
{
|
||||
g_autofree struct kvm_msrs *msrs = NULL;
|
||||
|
||||
msrs = g_malloc0(sizeof(*msrs) + sizeof(msrs->entries[0]));
|
||||
msrs->entries[0].index = MSR_IA32_TSC;
|
||||
msrs->entries[0].data = 1; /* match the value in x86_cpu_reset() */
|
||||
msrs->nmsrs++;
|
||||
|
||||
if (ioctl(kvm_fd, KVM_SET_MSRS, msrs) != 1) {
|
||||
warn_report("parked vCPU %lu TSC reset failed: %d",
|
||||
vcpu_id, errno);
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arch_do_init_vcpu(X86CPU *cpu)
|
||||
{
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
|
|
@ -5126,7 +5126,7 @@ static bool do_vbsrl_v(DisasContext *ctx, arg_vv_i *a, uint32_t oprsz)
|
|||
{
|
||||
int i, ofs;
|
||||
|
||||
if (!check_vec(ctx, 32)) {
|
||||
if (!check_vec(ctx, oprsz)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ static inline int s390_probe_access(CPUArchState *env, target_ulong addr,
|
|||
int mmu_idx, bool nonfault,
|
||||
void **phost, uintptr_t ra)
|
||||
{
|
||||
int flags = probe_access_flags(env, addr, 0, access_type, mmu_idx,
|
||||
int flags = probe_access_flags(env, addr, size, access_type, mmu_idx,
|
||||
nonfault, phost, ra);
|
||||
|
||||
if (unlikely(flags & TLB_INVALID_MASK)) {
|
||||
|
|
|
@ -1624,7 +1624,7 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
|
|||
insn |= 0x02100000;
|
||||
}
|
||||
if (a0 & TCG_MO_ST_ST) {
|
||||
insn |= 0x02200000;
|
||||
insn |= 0x01100000;
|
||||
}
|
||||
tcg_out32(s, insn);
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -25,13 +25,16 @@ class RxGdbSimMachine(QemuSystemTest):
|
|||
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
|
||||
|
||||
ASSET_UBOOT = Asset(
|
||||
'https://acc.dl.osdn.jp/users/23/23888/u-boot.bin.gz',
|
||||
'7146567d669e91dbac166384b29aeba1715beb844c8551e904b86831bfd9d046')
|
||||
('https://github.com/philmd/qemu-testing-blob/raw/rx-gdbsim/rx/gdbsim/'
|
||||
'u-boot.bin'),
|
||||
'dd7dd4220cccf7aeb32227b26233bf39600db05c3f8e26005bcc2bf6c927207d')
|
||||
ASSET_DTB = Asset(
|
||||
'https://acc.dl.osdn.jp/users/23/23887/rx-virt.dtb',
|
||||
('https://github.com/philmd/qemu-testing-blob/raw/rx-gdbsim/rx/gdbsim/'
|
||||
'rx-gdbsim.dtb'),
|
||||
'aa278d9c1907a4501741d7ee57e7f65c02dd1b3e0323b33c6d4247f1b32cf29a')
|
||||
ASSET_KERNEL = Asset(
|
||||
'http://acc.dl.osdn.jp/users/23/23845/zImage',
|
||||
('https://github.com/philmd/qemu-testing-blob/raw/rx-gdbsim/rx/gdbsim/'
|
||||
'zImage'),
|
||||
'baa43205e74a7220ed8482188c5e9ce497226712abb7f4e7e4f825ce19ff9656')
|
||||
|
||||
def test_uboot(self):
|
||||
|
@ -40,9 +43,7 @@ class RxGdbSimMachine(QemuSystemTest):
|
|||
"""
|
||||
self.set_machine('gdbsim-r5f562n8')
|
||||
|
||||
uboot_path_gz = self.ASSET_UBOOT.fetch()
|
||||
uboot_path = os.path.join(self.workdir, 'u-boot.bin')
|
||||
gzip_uncompress(uboot_path_gz, uboot_path)
|
||||
uboot_path = self.ASSET_UBOOT.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios', uboot_path,
|
||||
|
|
|
@ -185,7 +185,7 @@ static const testdef_t tests[] = {
|
|||
sizeof(kernel_plml605), kernel_plml605 },
|
||||
{ "arm", "raspi2b", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 },
|
||||
/* For hppa, force bios to output to serial by disabling graphics. */
|
||||
{ "hppa", "hppa", "-vga none", "SeaBIOS wants SYSTEM HALT" },
|
||||
{ "hppa", "B160L", "-vga none", "SeaBIOS wants SYSTEM HALT" },
|
||||
{ "aarch64", "virt", "-cpu max", "TT", sizeof(kernel_aarch64),
|
||||
kernel_aarch64 },
|
||||
{ "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 },
|
||||
|
|
|
@ -145,7 +145,7 @@ static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function,
|
|||
req_upiu.qr.idn = idn;
|
||||
req_upiu.qr.index = index;
|
||||
req_upiu.qr.selector = selector;
|
||||
req_upiu.qr.value = attr_value;
|
||||
req_upiu.qr.value = cpu_to_be32(attr_value);
|
||||
req_upiu.qr.length = UFS_QUERY_DESC_MAX_SIZE;
|
||||
qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu,
|
||||
sizeof(req_upiu));
|
||||
|
|
|
@ -6,10 +6,10 @@ FROM ubuntu:24.04
|
|||
|
||||
ENV MXE_PATH=/opt/mxe
|
||||
ENV MXE_REPO=https://github.com/mxe/mxe.git
|
||||
ENV MXE_VERSION=7f054f14930d109412d2d61d019c12fa80816b8c
|
||||
ENV MXE_VERSION=866492387740cc6580ef516c8a746402be645453
|
||||
|
||||
ENV MXE_LLVM_MINGW_REPO=https://github.com/libvips/build-win64-mxe
|
||||
ENV MXE_LLVM_MINGW_VERSION=8a4e0ab8a3b574287378459356f6bdaecc727de2
|
||||
ENV MXE_LLVM_MINGW_VERSION=32a2d0ecdfd3ea16bb4a99e333a8d5a3d63be491
|
||||
ENV MXE_LLVM_MINGW_PATH=/opt/build-win64-mxe
|
||||
|
||||
ARG PLUGIN_DIRS="${MXE_LLVM_MINGW_PATH} ${MXE_LLVM_MINGW_PATH}/build/plugins/llvm-mingw"
|
||||
|
|
|
@ -731,6 +731,7 @@ static void sdl2_display_very_early_init(DisplayOptions *o)
|
|||
|
||||
const int res_table[][2] = {
|
||||
{640, 480},
|
||||
{720, 480},
|
||||
{1280, 720},
|
||||
{1280, 800},
|
||||
{1280, 960},
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "font-manager.hh"
|
||||
#include "viewport-manager.hh"
|
||||
|
||||
#define MAX_VOICES 256
|
||||
|
||||
DebugApuWindow::DebugApuWindow() : m_is_open(false)
|
||||
{
|
||||
}
|
||||
|
@ -60,8 +62,7 @@ void DebugApuWindow::Draw()
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2*g_viewport_mgr.m_scale, 2*g_viewport_mgr.m_scale));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4*g_viewport_mgr.m_scale, 4*g_viewport_mgr.m_scale));
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
for (int i = 0; i < MAX_VOICES; i++) {
|
||||
if (i % 16) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
@ -132,8 +133,15 @@ void DebugApuWindow::Draw()
|
|||
|
||||
assert(voice->container_size < 4);
|
||||
assert(voice->sample_size < 4);
|
||||
ImGui::Text("Container Size: %s, Sample Size: %s, Samples per Block: %d",
|
||||
cs[voice->container_size], ss[voice->sample_size], voice->samples_per_block);
|
||||
const char *spb_or_bin_label = "Samples per Block";
|
||||
unsigned int spb_or_bin = voice->samples_per_block;
|
||||
if (voice->multipass) {
|
||||
spb_or_bin_label = "Multipass Bin";
|
||||
spb_or_bin = voice->multipass_bin;
|
||||
}
|
||||
ImGui::Text("Container Size: %s, Sample Size: %s, %s: %d",
|
||||
cs[voice->container_size], ss[voice->sample_size],
|
||||
spb_or_bin_label, spb_or_bin);
|
||||
ImGui::Text("Rate: %f (%d Hz)", voice->rate, (int)(48000.0/voice->rate));
|
||||
ImGui::Text("EBO=%d CBO=%d LBO=%d BA=%x",
|
||||
voice->ebo, voice->cbo, voice->lbo, voice->ba);
|
||||
|
@ -153,6 +161,30 @@ void DebugApuWindow::Draw()
|
|||
}
|
||||
ImGui::Text("%-17s", buf);
|
||||
}
|
||||
|
||||
int mon = mcpx_apu_debug_get_monitor();
|
||||
if (mon == MCPX_APU_DEBUG_MON_VP) {
|
||||
if (voice->multipass_dst_voice != 0xFFFF) {
|
||||
ImGui::Text("Multipass Dest Voice: 0x%02x",
|
||||
voice->multipass_dst_voice);
|
||||
}
|
||||
if (voice->multipass) {
|
||||
ImGui::Text("Multipass Src Voices:");
|
||||
int n = 0;
|
||||
|
||||
for (int i = 0; i < MAX_VOICES; i++) {
|
||||
if (dbg->vp.v[i].multipass_dst_voice == voice_info) {
|
||||
if (n > 0 && ((n & 7) == 0)) {
|
||||
ImGui::Text(" ");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("0x%02x", i);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopFont();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
|
|
@ -525,6 +525,7 @@ void MainMenuDisplayView::Draw()
|
|||
if (ChevronCombo("Window size", &g_config.display.window.startup_size,
|
||||
"Last Used\0"
|
||||
"640x480\0"
|
||||
"720x480\0"
|
||||
"1280x720\0"
|
||||
"1280x800\0"
|
||||
"1280x960\0"
|
||||
|
|
Loading…
Reference in New Issue