summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:23:15 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:23:15 +0000
commit62a5715c0af49b62b331c2538025a8ab5ce6c6e5 (patch)
treed4ddd30e61ba20eca4a3ba0f63f2e33c8573dfa0 /src/VBox/Devices
parentReleasing progress-linux version 7.0.18-dfsg-2~progress7.99u1. (diff)
downloadvirtualbox-62a5715c0af49b62b331c2538025a8ab5ce6c6e5.tar.xz
virtualbox-62a5715c0af49b62b331c2538025a8ab5ce6c6e5.zip
Merging upstream version 7.0.20-dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices')
-rw-r--r--src/VBox/Devices/Audio/AudioMixer.cpp14
-rw-r--r--src/VBox/Devices/Audio/DevHdaCodec.cpp54
-rw-r--r--src/VBox/Devices/Audio/DevHdaCodec.h3
-rw-r--r--src/VBox/Devices/Config.kmk12
-rw-r--r--src/VBox/Devices/EFI/DevEFI.cpp12
-rw-r--r--src/VBox/Devices/EFI/DevEFI.h1
-rw-r--r--src/VBox/Devices/EFI/Firmware/Makefile.kmk6
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c46
-rw-r--r--src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fdbin4194304 -> 4194304 bytes
-rw-r--r--src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fdbin4194304 -> 4194304 bytes
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp21
-rw-r--r--src/VBox/Devices/Graphics/DevVGA-SVGA.cpp38
-rw-r--r--src/VBox/Devices/Makefile.kmk1
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum2
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum2
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum2
-rw-r--r--src/VBox/Devices/PC/vbox-tpm.dsl269
-rw-r--r--src/VBox/Devices/Security/DevTpmPpi.cpp453
-rw-r--r--src/VBox/Devices/USB/DevEHCI.cpp41
-rw-r--r--src/VBox/Devices/USB/DrvVUSBRootHub.cpp13
-rw-r--r--src/VBox/Devices/USB/VUSBInternal.h2
-rw-r--r--src/VBox/Devices/USB/VUSBUrb.cpp2
-rw-r--r--src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp37
-rw-r--r--src/VBox/Devices/VirtIO/VirtioCore.cpp9
-rw-r--r--src/VBox/Devices/build/VBoxDD.cpp4
-rw-r--r--src/VBox/Devices/build/VBoxDD.h1
35 files changed, 1000 insertions, 81 deletions
diff --git a/src/VBox/Devices/Audio/AudioMixer.cpp b/src/VBox/Devices/Audio/AudioMixer.cpp
index 899154eb..071e997f 100644
--- a/src/VBox/Devices/Audio/AudioMixer.cpp
+++ b/src/VBox/Devices/Audio/AudioMixer.cpp
@@ -311,9 +311,13 @@ int AudioMixerSetMasterVolume(PAUDIOMIXER pMixer, PCPDMAUDIOVOLUME pVol)
*/
LogFlowFunc(("[%s] fMuted=%RTbool auChannels=%.*Rhxs => fMuted=%RTbool auChannels=%.*Rhxs\n", pMixer->pszName,
pMixer->VolMaster.fMuted, sizeof(pMixer->VolMaster.auChannels), pMixer->VolMaster.auChannels,
- pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels ));
+ pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels));
memcpy(&pMixer->VolMaster, pVol, sizeof(PDMAUDIOVOLUME));
+ LogRelMax(256, ("Audio Mixer: %s master volume of '%s' -- channel volumes: %.*Rhxs\n",
+ pMixer->VolMaster.fMuted ? "MUTING" : "Setting",
+ pMixer->pszName, sizeof(pMixer->VolMaster.auChannels), pMixer->VolMaster.auChannels));
+
/*
* Propagate new master volume to all sinks.
*/
@@ -1108,6 +1112,11 @@ static int audioMixerSinkUpdateVolume(PAUDMIXSINK pSink, PCPDMAUDIOVOLUME pVolMa
pSink->Volume.fMuted, sizeof(pSink->Volume.auChannels), pSink->Volume.auChannels,
pSink->VolumeCombined.fMuted, sizeof(pSink->VolumeCombined.auChannels), pSink->VolumeCombined.auChannels ));
+ LogRelMax(256, ("Audio Mixer: %s sink '%s/%s' -- channel volumes: %.*Rhxs\n",
+ pSink->VolumeCombined.fMuted ? "MUTING" : "Setting",
+ pSink->pParent->pszName, pSink->pszName,
+ sizeof(pSink->VolumeCombined.auChannels), pSink->VolumeCombined.auChannels));
+
AudioMixBufSetVolume(&pSink->MixBuf, &pSink->VolumeCombined);
return VINF_SUCCESS;
}
@@ -1131,9 +1140,6 @@ int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PCPDMAUDIOVOLUME pVol)
memcpy(&pSink->Volume, pVol, sizeof(PDMAUDIOVOLUME));
- LogRel2(("Audio Mixer: Setting volume of sink '%s' to fMuted=%RTbool auChannels=%.*Rhxs\n",
- pSink->pszName, pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels));
-
Assert(pSink->pParent);
if (pSink->pParent)
rc = audioMixerSinkUpdateVolume(pSink, &pSink->pParent->VolMaster);
diff --git a/src/VBox/Devices/Audio/DevHdaCodec.cpp b/src/VBox/Devices/Audio/DevHdaCodec.cpp
index 9782ac7f..4ea275fd 100644
--- a/src/VBox/Devices/Audio/DevHdaCodec.cpp
+++ b/src/VBox/Devices/Audio/DevHdaCodec.cpp
@@ -805,7 +805,8 @@ static int stac9220Construct(PHDACODECR3 pThis, HDACODECCFG *pCfg)
AssertCompile(STAC9221_NUM_NODES <= RT_ELEMENTS(pThis->aNodes));
pCfg->cTotalNodes = STAC9221_NUM_NODES;
- pCfg->idxAdcVolsLineIn = STAC9220_NID_AMP_ADC0;
+ pCfg->idxAdcVolsLineIn = STAC9220_NID_AMP_ADC0; /* We treat ADC0 as Line-In. */
+ pCfg->idxAdcVolsMicIn = STAC9220_NID_AMP_ADC1; /* We treat ADC1 as Mic-In. */
pCfg->idxDacLineOut = STAC9220_NID_DAC1;
/* Copy over the node class lists and popuplate afNodeClassifications. */
@@ -2105,25 +2106,42 @@ static DECLCALLBACK(int) vrbProcR3SetAmplifier(PHDACODECR3 pThis, uint32_t uCmd,
if (fIsRight)
hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), uCmd, 0);
- /*
- * Check if the node ID is the one we use for controlling the line-in volume;
- * with STAC9220 this is connected to STAC9220_NID_AMP_ADC0 (ID 0x17).
- *
- * If we don't do this check here, some guests like newer Ubuntus mute mic-in
- * afterwards (connected to STAC9220_NID_AMP_ADC1 (ID 0x18)). This then would
- * also mute line-in, which breaks audio recording.
- *
- * See STAC9220 V1.0 01/08, p. 30 + oem2ticketref:53.
- */
- if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsLineIn)
- hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
-
-#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
-# error "Implement mic-in volume / mute setting."
- else if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsMicIn)
- hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_MIC_IN);
+ switch (pThis->Cfg.enmType)
+ {
+ case CODECTYPE_STAC9220:
+ {
+ /*
+ * Check if the node ID is the one we use for controlling the recording (capturing) volume + mute status.
+ *
+ * The STAC9220 codec is connected to STAC9220_NID_AMP_ADC0 (ID 0x17) and
+ * STAC9220_NID_AMP_ADC0 (ID 0x18).
+ *
+ * If we don't do this check here, some guests like newer Ubuntus mute mic-in
+ * afterwards (connected to STAC9220_NID_AMP_ADC1 (ID 0x18)). This then would
+ * also mute line-in, which breaks audio recording.
+ *
+ * See STAC9220 V1.0 01/08, p. 30 + @oem2ticketref{53}.
+ */
+ if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsLineIn)
+ hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
+
+#ifdef VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN
+ /* Newer Windows 10 versions use STAC9220_NID_AMP_ADC1 (ID 0x18) for microphone
+ * volume control by default. */
+# ifndef VBOX_WITH_AUDIO_HDA_MIC_IN
+ /* If we don't implement dedicated microphone-in support (we then only offer recording via line-in),
+ * make sure to propagate volume control from mic-in to our line-in mixer control. See @oem2ticketref{93}. */
+ else if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsMicIn)
+ hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
+# endif
#endif
+ break;
+ }
+ default:
+ /* Nothing to do here. */
+ break;
+ }
}
if (fIsOut)
{
diff --git a/src/VBox/Devices/Audio/DevHdaCodec.h b/src/VBox/Devices/Audio/DevHdaCodec.h
index 00890922..52e52bf7 100644
--- a/src/VBox/Devices/Audio/DevHdaCodec.h
+++ b/src/VBox/Devices/Audio/DevHdaCodec.h
@@ -836,11 +836,12 @@ typedef struct HDACODECCFG
uint8_t cTotalNodes;
uint8_t idxAdcVolsLineIn;
+ uint8_t idxAdcVolsMicIn;
uint8_t idxDacLineOut;
/** Align the lists below so they don't cross cache lines (assumes
* CODEC_NODES_MAX is 32). */
- uint8_t const abPadding1[CODEC_NODES_MAX - 15];
+ uint8_t const abPadding1[CODEC_NODES_MAX - 16];
/** @name Node classifications.
* @note These are copies of the g_abStac9220Xxxx arrays in DevHdaCodec.cpp.
diff --git a/src/VBox/Devices/Config.kmk b/src/VBox/Devices/Config.kmk
index f24024f8..335a83eb 100644
--- a/src/VBox/Devices/Config.kmk
+++ b/src/VBox/Devices/Config.kmk
@@ -112,7 +112,7 @@ TEMPLATE_VBoxBios32Lib_POST_CMDS = $(NO_SUCH_VARIABLE)
#
VBOX_AUDIO_DEFS :=
if 0 # Not stable yet.
- # Enable microphone-in support for HDA. Otherwise only line-in is supported.
+ # Enable dedicated microphone-in support for HDA. Otherwise only line-in is supported.
VBOX_AUDIO_DEFS += VBOX_WITH_AUDIO_HDA_MIC_IN
# Enable interleavig streams support for HDA. Needed for 5.1 surround support.
@@ -123,6 +123,16 @@ if 0 # Not stable yet.
VBOX_AUDIO_DEFS += VBOX_WITH_AUDIO_HDA_51_SURROUND
endif
+# If dedicated microphone-in support for HDA isn't enabled, treat mic-in as line-in to
+# propagate the volume (+ mute) settings appropriately.
+ifndef VBOX_WITH_AUDIO_HDA_MIC_IN
+ VBOX_AUDIO_DEFS += VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN
+endif
+
+if defined(VBOX_WITH_AUDIO_HDA_MIC_IN) && defined(VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN)
+ $(error Defining VBOX_WITH_AUDIO_HDA_MIC_IN and VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN at the same time makes no sense!)
+endif
+
# Enable backend-independent device enumeration support.
VBOX_AUDIO_DEFS += VBOX_WITH_AUDIO_ENUM
diff --git a/src/VBox/Devices/EFI/DevEFI.cpp b/src/VBox/Devices/EFI/DevEFI.cpp
index e14f6858..35b6cca7 100644
--- a/src/VBox/Devices/EFI/DevEFI.cpp
+++ b/src/VBox/Devices/EFI/DevEFI.cpp
@@ -201,6 +201,8 @@ typedef struct DEVEFIR3
uint64_t u64McfgBase;
/** Length of PCI config space MMIO region */
uint64_t cbMcfgLength;
+ /** Physical address of the TPM PPI area. */
+ uint64_t u64TpmPpiBase;
/** Size of the configured NVRAM device. */
uint32_t cbNvram;
/** Start address of the NVRAM flash. */
@@ -331,6 +333,7 @@ static uint32_t efiInfoSize(PDEVEFIR3 pThisCC)
case EFI_INFO_INDEX_TSC_FREQUENCY:
case EFI_INFO_INDEX_MCFG_BASE:
case EFI_INFO_INDEX_MCFG_SIZE:
+ case EFI_INFO_INDEX_TPM_PPI_BASE:
return 8;
case EFI_INFO_INDEX_APIC_MODE:
return 1;
@@ -433,6 +436,7 @@ static uint8_t efiInfoNextByte(PDEVEFIR3 pThisCC)
case EFI_INFO_INDEX_MCFG_BASE: return efiInfoNextByteU64(pThisCC, pThisCC->u64McfgBase);
case EFI_INFO_INDEX_MCFG_SIZE: return efiInfoNextByteU64(pThisCC, pThisCC->cbMcfgLength);
case EFI_INFO_INDEX_APIC_MODE: return efiInfoNextByteU8(pThisCC, pThisCC->u8APIC);
+ case EFI_INFO_INDEX_TPM_PPI_BASE: return efiInfoNextByteU64(pThisCC, pThisCC->u64TpmPpiBase);
default:
PDMDevHlpDBGFStop(pThisCC->pDevIns, RT_SRC_POS, "%#x", pThisCC->iInfoSelector);
@@ -1567,7 +1571,8 @@ static DECLCALLBACK(int) efiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
"UgaHorizontalResolution|" // legacy
"UgaVerticalResolution|" // legacy
"GraphicsResolution|"
- "NvramFile", "");
+ "NvramFile|"
+ "TpmPpiBase", "");
/* CPU count (optional). */
rc = pHlp->pfnCFGMQueryU32Def(pCfg, "NumCPUs", &pThisCC->cCpus, 1);
@@ -1765,6 +1770,11 @@ static DECLCALLBACK(int) efiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Querying \"NvramFile\" as a string failed"));
+ rc = pHlp->pfnCFGMQueryU64Def(pCfg, "TpmPpiBase", &pThisCC->u64TpmPpiBase, 0);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Querying \"TpmPpiBase\" as integer failed"));
+
/*
* Load firmware volume and thunk ROM.
*/
diff --git a/src/VBox/Devices/EFI/DevEFI.h b/src/VBox/Devices/EFI/DevEFI.h
index 400f537a..704035d4 100644
--- a/src/VBox/Devices/EFI/DevEFI.h
+++ b/src/VBox/Devices/EFI/DevEFI.h
@@ -84,6 +84,7 @@ typedef enum
EFI_INFO_INDEX_APIC_MODE,
EFI_INFO_INDEX_CPU_COUNT_CURRENT,
EFI_INFO_INDEX_CPU_COUNT_MAX,
+ EFI_INFO_INDEX_TPM_PPI_BASE,
EFI_INFO_INDEX_END
} EfiInfoIndex;
diff --git a/src/VBox/Devices/EFI/Firmware/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/Makefile.kmk
index 02395eb5..7f597026 100644
--- a/src/VBox/Devices/EFI/Firmware/Makefile.kmk
+++ b/src/VBox/Devices/EFI/Firmware/Makefile.kmk
@@ -198,15 +198,15 @@ if1of ($(KBUILD_HOST), win)
VBOX_EFI_REDIRECT_E_EQUAL := $(EQUAL)
VBOX_EFI_BUILD_CMD = $(REDIRECT) \
-E 'PATH=$(VBOX_PATH_STAGE_EFI_BLDPROGS)$(VBOX_SEP)$(PATH);' \
- -E 'INCLUDE=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_SEP)$(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)$(INCLUDE);' \
+ -E 'INCLUDE=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_PATH_EFI_FIRMWARE)/..$(VBOX_SEP)$(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)$(INCLUDE);' \
-E 'COMSPEC=$(firstword $(windir) $(SystemRoot) C:\windows)\system32\cmd.exe' \
-E 'MAKEFLAGS='
else
VBOX_EFI_REDIRECT_E_EQUAL :=
VBOX_EFI_BUILD_CMD = $(REDIRECT) \
-E "PATH=$(VBOX_PATH_STAGE_EFI_BLDPROGS)$(VBOX_SEP)$(PATH)" \
- -E "C_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(C_INCLUDE_PATH)" \
- -E "CPLUS_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(C_INCLUDE_PATH)"
+ -E "C_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_PATH_EFI_FIRMWARE)/..$(VBOX_SEP)$(C_INCLUDE_PATH)" \
+ -E "CPLUS_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_PATH_EFI_FIRMWARE)/..$(VBOX_SEP)$(CPLUS_INCLUDE_PATH)"
endif
VBOX_EFI_BUILD_CMD += \
-E 'PYTHONPATH=$(VBOX_PATH_EFI_FIRMWARE)/BaseTools/Source/Python' \
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c
index 226743dc..29e53bc9 100644
--- a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c
@@ -35,6 +35,33 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/Tcg2PhysicalPresenceLib.h>
+#if defined(VBOX)
+# define IN_RING0
+# include "../../../../DevEFI.h"
+# include "iprt/cdefs.h" /* RT_ARCH_XXX */
+
+# if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
+# include "iprt/asm-amd64-x86.h"
+
+/*
+ * Internal Functions
+ */
+static UINT32
+GetVmVariable(UINT32 Variable, CHAR8 *pbBuf, UINT32 cbBuf)
+{
+ UINT32 cbVar, offBuf;
+
+ ASMOutU32(EFI_INFO_PORT, Variable);
+ cbVar = ASMInU32(EFI_INFO_PORT);
+
+ for (offBuf = 0; offBuf < cbVar && offBuf < cbBuf; offBuf++)
+ pbBuf[offBuf] = ASMInU8(EFI_INFO_PORT);
+
+ return cbVar;
+}
+# endif
+#endif
+
#define CONFIRM_BUFFER_SIZE 4096
EFI_HII_HANDLE mTcg2PpStringPackHandle;
@@ -44,6 +71,8 @@ EFI_HII_HANDLE mTcg2PpStringPackHandle;
STATIC volatile QEMU_TPM_PPI *mPpi;
+#if !defined(VBOX) \
+ || (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64))
/**
Reads QEMU PPI config from fw_cfg.
@@ -75,6 +104,7 @@ QemuTpmReadConfig (
QemuFwCfgReadBytes (sizeof (*Config), Config);
return EFI_SUCCESS;
}
+#endif
/**
@@ -90,7 +120,9 @@ QemuTpmInitPPI (
)
{
EFI_STATUS Status;
+#ifndef VBOX
QEMU_FWCFG_TPM_CONFIG Config;
+#endif
EFI_PHYSICAL_ADDRESS PpiAddress64;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
UINTN Idx;
@@ -99,6 +131,8 @@ QemuTpmInitPPI (
return EFI_SUCCESS;
}
+#if !defined(VBOX) \
+ || (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64))
Status = QemuTpmReadConfig (&Config);
if (EFI_ERROR (Status)) {
return Status;
@@ -108,6 +142,14 @@ QemuTpmInitPPI (
if (mPpi == NULL) {
return EFI_PROTOCOL_ERROR;
}
+#else
+ uint64_t u64TpmPpiBase = 0;
+ if ( GetVmVariable(EFI_INFO_INDEX_TPM_PPI_BASE, (CHAR8 *)&u64TpmPpiBase, sizeof(u64TpmPpiBase)) != sizeof(u64TpmPpiBase)
+ || u64TpmPpiBase == 0)
+ return EFI_PROTOCOL_ERROR;
+
+ mPpi = (QEMU_TPM_PPI *)(UINTN)u64TpmPpiBase;
+#endif
DEBUG ((DEBUG_INFO, "[TPM2PP] mPpi=%p version=%d\n", mPpi, Config.TpmVersion));
@@ -133,7 +175,9 @@ QemuTpmInitPPI (
for (Idx = 0; Idx < ARRAY_SIZE (mPpi->Func); Idx++) {
mPpi->Func[Idx] = 0;
}
+#ifndef VBOX
if (Config.TpmVersion == QEMU_TPM_VERSION_2) {
+#endif
mPpi->Func[TCG2_PHYSICAL_PRESENCE_NO_ACTION] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_CLEAR] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR] = TPM_PPI_FLAGS;
@@ -144,7 +188,9 @@ QemuTpmInitPPI (
mPpi->Func[TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID] = TPM_PPI_FLAGS;
+#ifndef VBOX
}
+#endif
if (mPpi->In == 0) {
mPpi->In = 1;
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
index 16789a3b..e63fbd06 100644
--- a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
+++ b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
Binary files differ
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
index a11bbd1b..5711cfdb 100644
--- a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
+++ b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
Binary files differ
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
index 0c156fb2..e5d2f0ef 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
@@ -8281,7 +8281,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.18 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.20 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -9212,7 +9212,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.18', 000h
+ db 'Oracle VM VirtualBox Version 7.0.20', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -9247,4 +9247,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 0dah
+ db 000h, 0e8h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
index 5b04df55..7d578726 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
@@ -1 +1 @@
-a9f7b007aff3ce32ea3f5295bc1144ed *VBoxVgaBios286.rom
+1ab418acec7c367d0ffd228c5ef63633 *VBoxVgaBios286.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
index b480612b..0d013e8b 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
@@ -7735,7 +7735,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.18 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.20 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -8666,7 +8666,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.18', 000h
+ db 'Oracle VM VirtualBox Version 7.0.20', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -8701,4 +8701,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 04fh
+ db 000h, 05dh
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
index 62bbb895..f4eab9e3 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
@@ -1 +1 @@
-73c6f655de7140699ff561c5b01f3625 *VBoxVgaBios386.rom
+fc1076be2c8e2edddd08bbfdf33182ff *VBoxVgaBios386.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
index fbfc435c..83e60936 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
@@ -8439,7 +8439,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.18 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.20 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -9370,7 +9370,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.18', 000h
+ db 'Oracle VM VirtualBox Version 7.0.20', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -9405,4 +9405,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 019h
+ db 000h, 027h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
index 1940a52f..bf5f9e97 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
@@ -1 +1 @@
-0f0564e36ea2319f2e46b42b53b39e81 *VBoxVgaBios8086.rom
+945a23ce7641a719d5917bf389c9dbb4 *VBoxVgaBios8086.rom
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
index cc4f0f1b..c84b93c5 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
@@ -1857,6 +1857,11 @@ static void vmsvga3dCmdDefineGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC
pScreen->offVRAM = 0; /* Not applicable for screen targets, they use either a separate memory buffer or a host window. */
pScreen->cbPitch = pCmd->width * 4;
pScreen->cBpp = 32;
+ pScreen->cDpi = pCmd->dpi;
+
+ /* The screen bitmap must be deallocated after 'vmsvgaR3ChangeMode'. */
+ void *pvOldScreenBitmap = pScreen->pvScreenBitmap;
+ pScreen->pvScreenBitmap = 0;
if (RT_LIKELY(pThis->svga.f3DEnabled))
vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
@@ -1869,6 +1874,8 @@ static void vmsvga3dCmdDefineGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC
pThis->svga.fGFBRegisters = false;
vmsvgaR3ChangeMode(pThis, pThisCC);
+
+ RTMemFree(pvOldScreenBitmap);
}
}
@@ -6757,6 +6764,12 @@ void vmsvgaR3CmdDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDe
VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen];
Assert(pScreen->idScreen == idScreen);
+ pScreen->cDpi = 0; /* SVGAFifoCmdDefineScreen does not support dpi. */
+
+ /* SVGAFifoCmdDefineScreen uses the guest VRAM. The screen bitmap must be deallocated after 'vmsvgaR3ChangeMode'. */
+ void *pvOldScreenBitmap = pScreen->pvScreenBitmap;
+ pScreen->pvScreenBitmap = 0;
+
pScreen->fDefined = true;
pScreen->fModified = true;
pScreen->fuScreen = pCmd->screen.flags;
@@ -6779,13 +6792,15 @@ void vmsvgaR3CmdDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDe
/* Screen blanked. Keep old values. */
}
- pThis->svga.fGFBRegisters = false;
- vmsvgaR3ChangeMode(pThis, pThisCC);
-
#ifdef VBOX_WITH_VMSVGA3D
if (RT_LIKELY(pThis->svga.f3DEnabled))
vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
#endif
+
+ pThis->svga.fGFBRegisters = false;
+ vmsvgaR3ChangeMode(pThis, pThisCC);
+
+ RTMemFree(pvOldScreenBitmap);
}
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
index c199b618..ea34efa2 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
@@ -1655,6 +1655,22 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
VMSVGASCREENOBJECT *pScreen = &pSVGAState->aScreens[0];
Assert(pScreen->idScreen == 0);
+
+ if ( pScreen->cWidth == VMSVGA_VAL_UNINITIALIZED
+ || pScreen->cHeight == VMSVGA_VAL_UNINITIALIZED
+ || pScreen->cBpp == VMSVGA_VAL_UNINITIALIZED)
+ {
+ /* Do not apply the change if the guest has not finished updating registers.
+ * This is necessary in order to make a full mode change, including freeing
+ * pvScreenBitmap buffers for screen 0 if necessary.
+ */
+ return VINF_SUCCESS;
+ }
+
+ /* Remember screen bitmap buffers to be freed. */
+ void * apvOldScreenBitmap[RT_ELEMENTS(pSVGAState->aScreens)];
+ RT_ZERO(apvOldScreenBitmap);
+
pScreen->fDefined = true;
pScreen->fModified = true;
pScreen->fuScreen = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
@@ -1665,6 +1681,11 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
pScreen->cWidth = pThis->svga.uWidth;
pScreen->cHeight = pThis->svga.uHeight;
pScreen->cBpp = pThis->svga.uBpp;
+ pScreen->cDpi = 0; /* GFB mode does not support dpi. */
+ /* GFB mode uses the guest VRAM. The screen bitmap must be deallocated after 'vmsvgaR3VBVAResize'. */
+ apvOldScreenBitmap[0] = pScreen->pvScreenBitmap;
+ /* Set pvScreenBitmap to zero because if it is not, then vmsvgaR3VBVAResize uses it as VRAM address. */
+ pScreen->pvScreenBitmap = 0;
for (unsigned iScreen = 1; iScreen < RT_ELEMENTS(pSVGAState->aScreens); ++iScreen)
{
@@ -1674,8 +1695,21 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
{
pScreen->fModified = true;
pScreen->fDefined = false;
+
+#ifdef VBOX_WITH_VMSVGA3D
+ if (RT_LIKELY(pThis->svga.f3DEnabled))
+ vmsvga3dDestroyScreen(pThisCC, pScreen);
+#endif
+ apvOldScreenBitmap[iScreen] = pScreen->pvScreenBitmap;
+ pScreen->pvScreenBitmap = 0;
}
}
+
+ vmsvgaR3VBVAResize(pThis, pThisCC);
+
+ /* Deallocate screen bitmaps for all screens because GFB mode uses the guest VRAM. */
+ for (unsigned iScreen = 0; iScreen < RT_ELEMENTS(apvOldScreenBitmap); ++iScreen)
+ RTMemFree(apvOldScreenBitmap[iScreen]);
}
else
{
@@ -1686,9 +1720,9 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
pThis->svga.uWidth = VMSVGA_VAL_UNINITIALIZED;
pThis->svga.uHeight = VMSVGA_VAL_UNINITIALIZED;
pThis->svga.uBpp = pThis->svga.uHostBpp;
- }
- vmsvgaR3VBVAResize(pThis, pThisCC);
+ vmsvgaR3VBVAResize(pThis, pThisCC);
+ }
/* Last stuff. For the VGA device screenshot. */
pThis->last_bpp = pSVGAState->aScreens[0].cBpp;
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index a17e655f..3e22f141 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -626,6 +626,7 @@ if !defined(VBOX_ONLY_EXTPACKS) && "$(intersects $(KBUILD_TARGET_ARCH),$(VBOX_SU
VBoxDD_DEFS += VBOX_WITH_TPM
VBoxDD_SOURCES += \
Security/DevTpm.cpp \
+ Security/DevTpmPpi.cpp \
Security/DrvTpmEmu.cpp
VBoxDD_SOURCES.linux += \
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
index 96b8e631..b70cd3f5 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
@@ -1621,7 +1621,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xcda class=DATA group=DGROUP
section CONST2 progbits vstart=0xdca align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0dca LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0dca 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0dca LB 0x12
- db 'VirtualBox 7.0.18', 000h
+ db 'VirtualBox 7.0.20', 000h
; disGetNextSymbol 0xf0ddc LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0ddc '_bios_prefix_string'
_bios_prefix_string: ; 0xf0ddc LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19429,4 +19429,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0d4h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0dbh
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
index 8fb531ac..c546774a 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
@@ -1 +1 @@
-ad4d1a253850bc31cfa497722faafa3a *VBoxPcBios286.rom
+60aec905c47ddf2c8a658f7fdedf61b6 *VBoxPcBios286.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
index 85af1d40..9e1c4215 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
@@ -1566,7 +1566,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xd14 class=DATA group=DGROUP
section CONST2 progbits vstart=0xe04 align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0e04 LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0e04 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0e04 LB 0x12
- db 'VirtualBox 7.0.18', 000h
+ db 'VirtualBox 7.0.20', 000h
; disGetNextSymbol 0xf0e16 LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0e16 '_bios_prefix_string'
_bios_prefix_string: ; 0xf0e16 LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19195,4 +19195,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 032h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 039h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
index 9cb9bea8..7934d06b 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
@@ -1 +1 @@
-79eeb980dd6104d8bc534c8c7c4e877a *VBoxPcBios386.rom
+dbb41e6f7bffdc046e70fcc71697c569 *VBoxPcBios386.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
index 80829ed2..44b44449 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
@@ -1621,7 +1621,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xcda class=DATA group=DGROUP
section CONST2 progbits vstart=0xdca align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0dca LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0dca 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0dca LB 0x12
- db 'VirtualBox 7.0.18', 000h
+ db 'VirtualBox 7.0.20', 000h
; disGetNextSymbol 0xf0ddc LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0ddc '_bios_prefix_string'
_bios_prefix_string: ; 0xf0ddc LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19906,4 +19906,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fbh, 0b9h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fbh, 0c0h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
index fc4dd6b7..9ad9c6d4 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
@@ -1 +1 @@
-bd634fab26a7c7e944a845a9415c8623 *VBoxPcBios8086.rom
+c032703c5648215f94b3881f8ea0174a *VBoxPcBios8086.rom
diff --git a/src/VBox/Devices/PC/vbox-tpm.dsl b/src/VBox/Devices/PC/vbox-tpm.dsl
index a24f9f16..889f1515 100644
--- a/src/VBox/Devices/PC/vbox-tpm.dsl
+++ b/src/VBox/Devices/PC/vbox-tpm.dsl
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2021-2023 Oracle and/or its affiliates.
+ * Copyright (C) 2021-2024 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
@@ -27,6 +27,8 @@
DefinitionBlock ("SSDT.aml", "SSDT", 1, "VBOX ", "VBOXTPMT", 2)
{
+ External(DBG, MethodObj, ,)
+
Scope (\_SB)
{
Device (TPM)
@@ -88,6 +90,271 @@ DefinitionBlock ("SSDT.aml", "SSDT", 1, "VBOX ", "VBOXTPMT", 2)
{
Return (RES)
}
+
+ Method (TPFS, 1, Serialized)
+ {
+ If (LGreaterEqual(Arg0, 0x100))
+ {
+ Return (Zero)
+ }
+
+ OperationRegion (TPP1, SystemMemory, Add(0xFED45000, Arg0), One)
+ Field (TPP1, ByteAcc, NoLock, Preserve)
+ {
+ TPPF, 8
+ }
+
+ Return (TPPF)
+ }
+
+ /**
+ * Device-Specific Method
+ */
+ Method (_DSM, 4, Serialized)
+ {
+ /**
+ * The TPM Physical Presence Interface MMIO region.
+ */
+ OperationRegion (TPMP, SystemMemory, 0xFED45100, 0x5A)
+ Field (TPMP, AnyAcc, NoLock, Preserve)
+ {
+ PPIN, 8,
+ PPIP, 32,
+ PPRP, 32,
+ PPRQ, 32,
+ PPRM, 32,
+ LPPR, 32
+ }
+
+ Name (TPB2, Package (0x02)
+ {
+ Zero,
+ Zero
+ })
+
+ Name (TPB3, Package (0x03)
+ {
+ Zero,
+ Zero,
+ Zero
+ })
+
+ /**
+ * Physical Presence Interface Specification PPI.
+ */
+ If (LEqual (Arg0, ToUUID("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
+ {
+ /**
+ * Standard _DSM query function.
+ */
+ If (LEqual (Arg2, Zero))
+ {
+ DBG("_DSM: Query\n")
+ Return (Buffer (0x02) { 0xFF, 0x01 })
+ }
+
+ /**
+ * Query supported PPI revision.
+ *
+ * Result:
+ * 1.3 (string).
+ */
+ If (LEqual (Arg2, One))
+ {
+ DBG("_DSM: PPI Revision\n")
+ Return ("1.3")
+ }
+
+ /**
+ * Submit TPM Operation Request to pre-OS environment.
+ *
+ * Input:
+ * Package[0] - Operation value of the request
+ * Result:
+ * - 0: Success
+ * - 1: Operation value of the request not supported.
+ * - 2: General failure
+ */
+ If (LEqual (Arg2, 0x02))
+ {
+ DBG("_DSM: Submit TPM Operation Request\n")
+
+ Store(DerefOf(Index(Arg3, Zero)), Local0)
+ Store(TPFS(Local0), Local1)
+ If (LEqual(And(Local1, 0x07), Zero))
+ {
+ Return (One)
+ }
+
+ Store(Local0, PPRQ)
+ Store(Zero, PPRM)
+ Return (Zero)
+ }
+
+ /**
+ * Get Pending TPM Operation Requested by the OS.
+ *
+ * Result:
+ * Package[0] - Function Return Code:
+ * - 0: Success
+ * - 1: General Failure
+ * Package[1] - Pending operation requested by the OS:
+ * - 0: None
+ * - >0: Operation value of the pending request
+ * Package[2] - Optional argument to pending operation requested by the OS:
+ * - 0: None
+ * - >0: Argument value of the pending request
+ */
+ If (LEqual (Arg2, 0x03))
+ {
+ DBG("_DSM: Get Pending TPM Operation Request\n")
+
+ if (LEqual(Arg1, One))
+ {
+ Store(PPRQ, Index(TPB2, One))
+ Return (TPB2)
+ }
+
+ if (LEqual(Arg1, 0x02))
+ {
+ Store(PPRQ, Index(TPB3, One))
+ Store(PPRM, Index(TPB3, 0x02))
+ Return (TPB3)
+ }
+
+ Return (TPB3)
+ }
+
+ /**
+ * Get Platform-Specific Action to Transition to Pre-OS Environment.
+ *
+ * Result:
+ * - 0: None
+ * - 1: Shutdown
+ * - 2: Reboot
+ * - 3: OS vendor specific
+ */
+ If (LEqual (Arg2, 0x04))
+ {
+ DBG("_DSM: Get Platform-Specific Action to Transition to Pre-OS Environment\n")
+
+ Return (0x02)
+ }
+
+ /**
+ * Return TPM Operation Response to OS Environment.
+ */
+ If (LEqual (Arg2, 0x05))
+ {
+ DBG("_DSM: Return TPM Operation Response to OS Environment\n")
+
+ Store (LPPR, Index (TPB3, One))
+ Store (PPRP, Index (TPB3, 0x02))
+ Return (TPB3)
+ }
+
+ /**
+ * Submit preferred user language - deprecated
+ *
+ * Result:
+ * - 3: Not implemented
+ */
+ If (LEqual (Arg2, 0x06))
+ {
+ DBG("_DSM: Submit preferred user language\n")
+
+ Return (0x03)
+ }
+
+ /**
+ * Submit TPM Operation Request to Pre-OS Environment 2
+ */
+ If (LEqual (Arg2, 0x07))
+ {
+ DBG("_DSM: Submit TPM Operation Request 2\n")
+
+ Store(DerefOf(Index(Arg3, Zero)), Local0) /* Local0 = *Arg3[0] (Arg3 is a Package) */
+ Store(TPFS(Local0), Local1) /* Local1 = TPFS(Local0) */
+ Store(And(Local1, 0x07), Local1) /* Local1 &= 0x7 */
+ If (LEqual(Local1, Zero))
+ {
+ Return (One) /* Operation not implemented */
+ }
+
+ If (LEqual(Local1, 0x02))
+ {
+ Return (0x03) /* Operation blocked by current firmware settings */
+ }
+
+ If (LEqual(Arg1, One))
+ {
+ Store(Local0, PPRQ)
+ Store(Zero, PPRM)
+ }
+
+ If (LEqual(Arg1, 0x02))
+ {
+ Store(DerefOf(Index(Arg3, One)), Local2) /* Local2 = *Arg3[1] (Arg3 is a Package) */
+
+ Store(Local0, PPRQ)
+ Store(Local2, PPRM)
+ }
+
+ Return (Zero)
+ }
+
+ /**
+ * Get User Confirmation Status for Operation.
+ *
+ * Input is the operation value maybe needing user confirmation
+ * Result:
+ * - 0: Not implemented
+ * - 1: Firmware only
+ * - 2: Blocked for OS by firmware configuration.
+ * - 3: Allowed and physically present user required
+ * - 4: Allowed and physically present user not required.
+ */
+ If (LEqual (Arg2, 0x08))
+ {
+ DBG("_DSM: Get user confirmation status for operation\n")
+
+ Store(DerefOf(Index(Arg3, Zero)), Local0)
+ Store(TPFS(Local0), Local1)
+
+ Return (And(Local1, 0x7))
+ }
+
+ DBG("TPM_DSM: Unknown function\n")
+ Return (Buffer (One) { 0x00 })
+ }
+
+ /**
+ * TCG Platform Reset Attack Mitigation Specification interface.
+ */
+ If (LEqual (Arg0, ToUUID("376054ed-cc13-4675-901c-4756d7f2d45d")))
+ {
+ /**
+ * Standard _DSM query function.
+ */
+ If (LEqual (Arg2, Zero))
+ {
+ Return (Buffer (One) { 0x03 })
+ }
+
+ /**
+ * Set Memory Overwrite Request (MOR) bit to specified value.
+ */
+ If (LEqual (Arg2, One))
+ {
+ /* Memory is always zeroed on reset. */
+ Return (Zero)
+ }
+
+ Return (Buffer (One) { 0x00 })
+ }
+
+ Return (Buffer (One) { 0x00 })
+ }
}
}
}
diff --git a/src/VBox/Devices/Security/DevTpmPpi.cpp b/src/VBox/Devices/Security/DevTpmPpi.cpp
new file mode 100644
index 00000000..03159d88
--- /dev/null
+++ b/src/VBox/Devices/Security/DevTpmPpi.cpp
@@ -0,0 +1,453 @@
+/* $Id: DevTpmPpi.cpp $ */
+/** @file
+ * DevTpmPpi - Guest platform <-> VirtualBox TPM Physical Presence Interface Integration Framework.
+ *
+ * Based on: https://github.com/qemu/qemu/blob/master/docs/specs/tpm.rst (2024-06-26).
+ */
+
+/*
+ * Copyright (C) 2024 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * 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, in version 3 of the
+ * License.
+ *
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_DEV_TPM
+
+#include <VBox/vmm/pdmdev.h>
+#include <VBox/log.h>
+#include <VBox/err.h>
+#include <VBox/param.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/ctype.h>
+
+#include "VBoxDD.h"
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+
+/** The TPM saved state version. */
+#define TPM_PPI_SAVED_STATE_VERSION 1
+
+/** The TPM PPI MMIO base default (compatible with qemu). */
+#define TPM_PPI_MMIO_BASE_DEFAULT UINT64_C(0xfed45000)
+/** The size of the TPM PPI MMIO area. */
+#define TPM_PPI_MMIO_SIZE _4K
+
+/** @name QEMU compatible PPI interface layout.
+ * @{ */
+/**
+ * The PPI structure layout (yes, it really is misaligned).
+ */
+#pragma pack(1)
+typedef union QEMUTPMPPI
+{
+ /** The byte view. */
+ uint8_t ab[0x400];
+ /** The structured view. */
+ struct
+ {
+ /** Supported operation flags set by the firmware for each operation. */
+ uint8_t abFunc[0x100];
+ /** SMI interrupt to use, set by firmware. Not supported. */
+ uint8_t bPpin;
+ /** ACPI function index to pass to SMM code, set by ACPI. Not supported. */
+ uint32_t u32Ppip;
+ /** Result of last executed operation, set by firmware. */
+ uint32_t u32Pprp;
+ /** Operation request number to execute, set by ACPI. */
+ uint32_t u32Pprq;
+ /** Operation request optional parameter, set by ACPI. */
+ uint32_t u32Pprm;
+ /** Last executed operation request number, copied from QEMUTPMPPI::u32PPrq field by firmware. */
+ uint32_t u32Lppr;
+ /** Result code from SMM function, not supported. */
+ uint32_t u32Fret;
+ /** Reserved for future use. */
+ uint8_t abRsvd[0x40];
+ /** Operation to execute after reboot by firmware, used by firmware. */
+ uint8_t bNextStep;
+ /** Memory overwrite variable. */
+ uint8_t bMovv;
+ } s;
+} QEMUTPMPPI;
+#pragma pack()
+AssertCompileSize(QEMUTPMPPI, 0x400);
+/** Pointer to the QEMU PPI structure layout. */
+typedef QEMUTPMPPI *PQEMUTPMPPI;
+/** Pointer to a const QEMU PPI structure layout. */
+typedef const QEMUTPMPPI *PCQEMUTPMPPI;
+/** @} */
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+
+/**
+ * Shared TPM PPI device state.
+ */
+typedef struct DEVTPMPPI
+{
+ /** Base MMIO address of the TPM PPI area. */
+ RTGCPHYS GCPhysMmio;
+ /** The handle of the MMIO region. */
+ IOMMMIOHANDLE hMmio;
+ /** The QEMU PPI state. */
+ QEMUTPMPPI Ppi;
+} DEVTPMPPI;
+/** Pointer to the shared TPM PPI device state. */
+typedef DEVTPMPPI *PDEVTPMPPI;
+
+/**
+ * TPM PPI device state for ring-3.
+ */
+typedef struct DEVTPMPPIR3
+{
+ /** Pointer to the device instance. */
+ PPDMDEVINS pDevIns;
+} DEVTPMPPIR3;
+/** Pointer to the TPM device state for ring-3. */
+typedef DEVTPMPPIR3 *PDEVTPMPPIR3;
+
+
+/**
+ * TPM PPI device state for ring-0.
+ */
+typedef struct DEVTPMPPIR0
+{
+ uint32_t u32Dummy;
+
+} DEVTPMPPIR0;
+/** Pointer to the TPM device state for ring-0. */
+typedef DEVTPMPPIR0 *PDEVTPMPPIR0;
+
+
+/**
+ * TPM PPI device state for raw-mode.
+ */
+typedef struct DEVTPMPPIRC
+{
+ uint32_t u32Dummy;
+} DEVTPMPPIRC;
+/** Pointer to the TPM device state for raw-mode. */
+typedef DEVTPMPPIRC *PDEVTPMPPIRC;
+
+/** The TPM PI device state for the current context. */
+typedef CTX_SUFF(DEVTPMPPI) DEVTPMPPICC;
+/** Pointer to the TPM PPI device state for the current context. */
+typedef CTX_SUFF(PDEVTPMPPI) PDEVTPMPPICC;
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+
+#ifdef IN_RING3
+/**
+ * SSM descriptor table for the TPM PPI structure.
+ */
+static SSMFIELD const g_aTpmPpiFields[] =
+{
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.abFunc),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.bPpin),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Ppip),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprp),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprq),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprm),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Lppr),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Fret),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.bNextStep),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.bMovv),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif
+
+
+/* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
+
+/**
+ * @callback_method_impl{FNIOMMMIONEWREAD}
+ */
+static DECLCALLBACK(VBOXSTRICTRC) tpmPpiMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ RT_NOREF(pvUser);
+
+ LogFlowFunc(("off=%RGp cb=%u\n", off, cb));
+ if (off + cb > sizeof(pThis->Ppi))
+ return VINF_IOM_MMIO_UNUSED_FF;
+
+ memcpy(pv, &pThis->Ppi.ab[off], cb);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @callback_method_impl{FNIOMMMIONEWWRITE}
+ */
+static DECLCALLBACK(VBOXSTRICTRC) tpmPpiMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ RT_NOREF(pvUser);
+
+ LogFlowFunc(("off=%RGp cb=%u\n", off, cb));
+ if (off + cb > sizeof(pThis->Ppi))
+ return VINF_SUCCESS;
+
+ memcpy(&pThis->Ppi.ab[off], pv, cb);
+ return VINF_SUCCESS;
+}
+
+
+#ifdef IN_RING3
+
+/* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
+
+/**
+ * @callback_method_impl{FNSSMDEVLIVEEXEC}
+ */
+static DECLCALLBACK(int) tpmPpiR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+ RT_NOREF(uPass);
+
+ /* Save the part of the config used for verification purposes when restoring. */
+ pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysMmio);
+
+ return VINF_SSM_DONT_CALL_AGAIN;
+}
+
+
+/**
+ * @callback_method_impl{FNSSMDEVSAVEEXEC}
+ */
+static DECLCALLBACK(int) tpmPpiR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+
+ tpmPpiR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
+
+ int rc = pHlp->pfnSSMPutStructEx(pSSM, &pThis->Ppi, sizeof(pThis->Ppi), 0 /*fFlags*/, &g_aTpmPpiFields[0], NULL);
+ AssertRCReturn(rc, rc);
+
+ return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); /* sanity/terminator */
+}
+
+
+/**
+ * @callback_method_impl{FNSSMDEVLOADEXEC}
+ */
+static DECLCALLBACK(int) tpmPpiR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+ RTGCPHYS GCPhysMmio;
+
+ Assert(uPass == SSM_PASS_FINAL); RT_NOREF(uPass);
+ AssertMsgReturn(uVersion == TPM_PPI_SAVED_STATE_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
+
+ /* Verify the config first. */
+ int rc = pHlp->pfnSSMGetGCPhys(pSSM, &GCPhysMmio);
+ AssertRCReturn(rc, rc);
+ if (GCPhysMmio != pThis->GCPhysMmio)
+ return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS,
+ N_("Config mismatch - saved GCPhysMmio=%#RGp; configured GCPhysMmio=%#RGp"),
+ GCPhysMmio, pThis->GCPhysMmio);
+
+ if (uPass == SSM_PASS_FINAL)
+ {
+ rc = pHlp->pfnSSMGetStructEx(pSSM, &pThis->Ppi, sizeof(pThis->Ppi), 0 /*fFlags*/, &g_aTpmPpiFields[0], NULL);
+ AssertRCReturn(rc, rc);
+
+ /* The marker. */
+ uint32_t u32;
+ rc = pHlp->pfnSSMGetU32(pSSM, &u32);
+ AssertRCReturn(rc, rc);
+ AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnDestruct}
+ */
+static DECLCALLBACK(int) tpmPpiR3Destruct(PPDMDEVINS pDevIns)
+{
+ PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnConstruct}
+ */
+static DECLCALLBACK(int) tpmPpiR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+{
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PDEVTPMPPICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMPPICC);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+ int rc;
+
+ RT_NOREF(iInstance);
+ Assert(iInstance == 0);
+
+ /*
+ * Initalize the basic variables so that the destructor always works.
+ */
+ pThisCC->pDevIns = pDevIns;
+
+ /*
+ * Validate and read the configuration.
+ */
+ PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "MmioBase", "");
+
+ rc = pHlp->pfnCFGMQueryU64Def(pCfg, "MmioBase", &pThis->GCPhysMmio, TPM_PPI_MMIO_BASE_DEFAULT);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to get the \"MmioBase\" value"));
+
+ /*
+ * Register the MMIO range, PDM API requests page aligned
+ * addresses and sizes.
+ */
+ rc = PDMDevHlpMmioCreateAndMap(pDevIns, pThis->GCPhysMmio, TPM_PPI_MMIO_SIZE, tpmPpiMmioWrite, tpmPpiMmioRead,
+ IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
+ "TPM PPI MMIO", &pThis->hMmio);
+ AssertRCReturn(rc, rc);
+
+ /*
+ * Saved state.
+ */
+ rc = PDMDevHlpSSMRegister3(pDevIns, TPM_PPI_SAVED_STATE_VERSION, sizeof(*pThis),
+ tpmPpiR3LiveExec, tpmPpiR3SaveExec, tpmPpiR3LoadExec);
+ AssertRCReturn(rc, rc);
+
+ return VINF_SUCCESS;
+}
+
+
+#else /* !IN_RING3 */
+
+/**
+ * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
+ */
+static DECLCALLBACK(int) tpmPpiRZConstruct(PPDMDEVINS pDevIns)
+{
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+
+ int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, tpmPpiMmioWrite, tpmPpiMmioRead, NULL /*pvUser*/);
+ AssertRCReturn(rc, rc);
+
+ return VINF_SUCCESS;
+}
+
+#endif /* !IN_RING3 */
+
+
+/**
+ * The device registration structure.
+ */
+const PDMDEVREG g_DeviceTpmPpi =
+{
+ /* .u32Version = */ PDM_DEVREG_VERSION,
+ /* .uReserved0 = */ 0,
+ /* .szName = */ "tpm-ppi",
+ /* .fFlags = */ PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_NEW_STYLE,
+ /* .fClass = */ PDM_DEVREG_CLASS_ARCH_BIOS,
+ /* .cMaxInstances = */ 1,
+ /* .uSharedVersion = */ 42,
+ /* .cbInstanceShared = */ sizeof(DEVTPMPPI),
+ /* .cbInstanceCC = */ sizeof(DEVTPMPPICC),
+ /* .cbInstanceRC = */ sizeof(DEVTPMPPIRC),
+ /* .cMaxPciDevices = */ 0,
+ /* .cMaxMsixVectors = */ 0,
+ /* .pszDescription = */ "Device implementing the TPM Physical Presence Interface (PPI)\n",
+#if defined(IN_RING3)
+ /* .pszRCMod = */ "",
+ /* .pszR0Mod = */ "",
+ /* .pfnConstruct = */ tpmPpiR3Construct,
+ /* .pfnDestruct = */ tpmPpiR3Destruct,
+ /* .pfnRelocate = */ NULL,
+ /* .pfnMemSetup = */ NULL,
+ /* .pfnPowerOn = */ NULL,
+ /* .pfnReset = */ NULL,
+ /* .pfnSuspend = */ NULL,
+ /* .pfnResume = */ NULL,
+ /* .pfnAttach = */ NULL,
+ /* .pfnDetach = */ NULL,
+ /* .pfnQueryInterface = */ NULL,
+ /* .pfnInitComplete = */ NULL,
+ /* .pfnPowerOff = */ NULL,
+ /* .pfnSoftReset = */ NULL,
+ /* .pfnReserved0 = */ NULL,
+ /* .pfnReserved1 = */ NULL,
+ /* .pfnReserved2 = */ NULL,
+ /* .pfnReserved3 = */ NULL,
+ /* .pfnReserved4 = */ NULL,
+ /* .pfnReserved5 = */ NULL,
+ /* .pfnReserved6 = */ NULL,
+ /* .pfnReserved7 = */ NULL,
+#elif defined(IN_RING0)
+ /* .pfnEarlyConstruct = */ NULL,
+ /* .pfnConstruct = */ tpmPpiRZConstruct,
+ /* .pfnDestruct = */ NULL,
+ /* .pfnFinalDestruct = */ NULL,
+ /* .pfnRequest = */ NULL,
+ /* .pfnReserved0 = */ NULL,
+ /* .pfnReserved1 = */ NULL,
+ /* .pfnReserved2 = */ NULL,
+ /* .pfnReserved3 = */ NULL,
+ /* .pfnReserved4 = */ NULL,
+ /* .pfnReserved5 = */ NULL,
+ /* .pfnReserved6 = */ NULL,
+ /* .pfnReserved7 = */ NULL,
+#elif defined(IN_RC)
+ /* .pfnConstruct = */ tpmPpiRZConstruct,
+ /* .pfnReserved0 = */ NULL,
+ /* .pfnReserved1 = */ NULL,
+ /* .pfnReserved2 = */ NULL,
+ /* .pfnReserved3 = */ NULL,
+ /* .pfnReserved4 = */ NULL,
+ /* .pfnReserved5 = */ NULL,
+ /* .pfnReserved6 = */ NULL,
+ /* .pfnReserved7 = */ NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+ /* .u32VersionEnd = */ PDM_DEVREG_VERSION
+};
diff --git a/src/VBox/Devices/USB/DevEHCI.cpp b/src/VBox/Devices/USB/DevEHCI.cpp
index 1ca85af3..48659563 100644
--- a/src/VBox/Devices/USB/DevEHCI.cpp
+++ b/src/VBox/Devices/USB/DevEHCI.cpp
@@ -161,7 +161,7 @@ typedef struct VUSBURBHCITDINT
/** The address of the TD. */
RTGCPHYS TdAddr;
/** A copy of the TD. */
- uint32_t TdCopy[16];
+ uint32_t TdCopy[18];
} VUSBURBHCITDINT;
/**
@@ -526,19 +526,25 @@ typedef const EHCI_ITD *PEHCI_CITD;
AssertCompileSize(EHCI_ITD, 0x40);
/** @} */
-/* ITD with extra padding to add 8th 'Buffer' entry. The PG member of
+/* ITD with extra padding to add 8th and 9th 'Buffer' entry. The PG member of
* EHCI_ITD_TRANSACTION can contain values in the 0-7 range, but only values
* 0-6 are valid. The extra padding is added to avoid cluttering the code
* with range checks; ehciR3ReadItd() initializes the pad with a safe value.
* The EHCI 1.0 specification explicitly says using PG value of 7 yields
- * undefined behavior.
+ * undefined behavior. Two pad entries are needed because initial PG value
+ * of 7 (already 'wrong') can cross to the next page (8).
*/
typedef struct
{
- EHCI_ITD itd;
- EHCI_BUFFER_PTR pad;
+ EHCI_TD_PTR Next;
+ EHCI_ITD_TRANSACTION Transaction[EHCI_NUM_ITD_TRANSACTIONS];
+ union
+ {
+ EHCI_ITD_MISC Misc;
+ EHCI_BUFFER_PTR Buffer[EHCI_NUM_ITD_PAGES + 2];
+ } Buffer;
} EHCI_ITD_PAD, *PEHCI_ITD_PAD;
-AssertCompileSize(EHCI_ITD_PAD, 0x44);
+AssertCompileSize(EHCI_ITD_PAD, 0x48);
/** @name Split Transaction Isochronous Transfer Descriptor (siTD)
* @{ */
@@ -1471,7 +1477,8 @@ DECLINLINE(void) ehciR3ReadTDPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, EHCI_TD_PT
DECLINLINE(void) ehciR3ReadItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD_PAD pPItd)
{
ehciGetDWords(pDevIns, GCPhys, (uint32_t *)pPItd, sizeof(EHCI_ITD) >> 2);
- pPItd->pad.Pointer = 0xFFFFF; /* Direct accesses at the last page under 4GB (ROM). */
+ pPItd->Buffer.Buffer[7].Pointer = 0xFFFFF; /* Direct ill-defined accesses to the last page under 4GB (ROM). */
+ pPItd->Buffer.Buffer[8].Pointer = 0xFFFFF;
}
DECLINLINE(void) ehciR3ReadSitd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_SITD pSitd)
@@ -1479,7 +1486,7 @@ DECLINLINE(void) ehciR3ReadSitd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_SITD
ehciGetDWords(pDevIns, GCPhys, (uint32_t *)pSitd, sizeof(*pSitd) >> 2);
}
-DECLINLINE(void) ehciR3WriteItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD pItd)
+DECLINLINE(void) ehciR3WriteItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD_PAD pItd)
{
/** @todo might need to be careful about write order in async io thread */
/*
@@ -1490,7 +1497,7 @@ DECLINLINE(void) ehciR3WriteItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD p
uint32_t offDWordsWrite = offWrite / sizeof(uint32_t);
Assert(!(offWrite % sizeof(uint32_t)));
- ehciPutDWords(pDevIns, GCPhys + offWrite, (uint32_t *)pItd + offDWordsWrite, (sizeof(*pItd) >> 2) - offDWordsWrite);
+ ehciPutDWords(pDevIns, GCPhys + offWrite, (uint32_t *)pItd + offDWordsWrite, (sizeof(EHCI_ITD) >> 2) - offDWordsWrite);
}
DECLINLINE(void) ehciR3ReadQHD(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_QHD pQHD)
@@ -1758,7 +1765,7 @@ DECLINLINE(void) ehciR3DumpITD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLi
/* Read the whole ITD */
EHCI_ITD_PAD PaddedItd;
- PEHCI_ITD pItd = &PaddedItd.itd;
+ PEHCI_ITD_PAD pItd = &PaddedItd;
ehciR3ReadItd(pDevIns, GCPhys, &PaddedItd);
Log2(("Addr=%x EndPt=%x Dir=%s MaxSize=%x Mult=%d}\n", pItd->Buffer.Misc.DeviceAddress, pItd->Buffer.Misc.EndPt, (pItd->Buffer.Misc.DirectionIn) ? "in" : "out", pItd->Buffer.Misc.MaxPacket, pItd->Buffer.Misc.Multi));
@@ -2028,7 +2035,7 @@ static int ehciR3InFlightRemoveUrb(PEHCI pThis, PEHCICC pThisCC, PVUSBURB pUrb)
* @param pUrb The URB in question.
* @param pItd The ITD pointer.
*/
-static bool ehciR3ItdHasUrbBeenCanceled(PEHCICC pThisCC, PVUSBURB pUrb, PEHCI_ITD pItd)
+static bool ehciR3ItdHasUrbBeenCanceled(PEHCICC pThisCC, PVUSBURB pUrb, PEHCI_ITD_PAD pItd)
{
RT_NOREF(pThisCC);
Assert(pItd);
@@ -2252,7 +2259,7 @@ static void ehciR3RhXferCompleteITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pTh
{
/* Read the whole ITD */
EHCI_ITD_PAD PaddedItd;
- PEHCI_ITD pItd = &PaddedItd.itd;
+ PEHCI_ITD_PAD pItd = &PaddedItd;
ehciR3ReadItd(pDevIns, pUrb->paTds[0].TdAddr, &PaddedItd);
/*
@@ -2323,7 +2330,7 @@ static void ehciR3RhXferCompleteITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pTh
ehciPhysWrite(pDevIns, GCPhysBuf, pb, cb1);
if ((pg + 1) >= EHCI_NUM_ITD_PAGES)
- LogRelMax(10, ("EHCI: Crossing to undefined page %d in iTD at %RGp on completion.\n", pg + 1, pUrb->paTds[0].TdAddr));
+ LogRelMax(10, ("EHCI: Crossing to nonstandard page %d in iTD at %RGp on completion.\n", pg + 1, pUrb->paTds[0].TdAddr));
GCPhysBuf = (RTGCPHYS)pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
ehciPhysWrite(pDevIns, GCPhysBuf, pb + cb1, cb2);
@@ -2790,7 +2797,7 @@ static bool ehciR3SubmitQTD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC, RT
* @returns false on failure to submit.
*/
static bool ehciR3SubmitITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
- PEHCI_ITD pItd, RTGCPHYS ITdAddr, const unsigned iFrame)
+ PEHCI_ITD_PAD pItd, RTGCPHYS ITdAddr, const unsigned iFrame)
{
/*
* Determine the endpoint direction.
@@ -2875,7 +2882,7 @@ static bool ehciR3SubmitITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
ehciPhysRead(pDevIns, GCPhysBuf, &pUrb->abData[curOffset], cb1);
if ((pg + 1) >= EHCI_NUM_ITD_PAGES)
- LogRelMax(10, ("EHCI: Crossing to undefined page %d in iTD at %RGp on submit.\n", pg + 1, pUrb->paTds[0].TdAddr));
+ LogRelMax(10, ("EHCI: Crossing to nonstandard page %d in iTD at %RGp on submit.\n", pg + 1, pUrb->paTds[0].TdAddr));
GCPhysBuf = (RTGCPHYS)pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
ehciPhysRead(pDevIns, GCPhysBuf, &pUrb->abData[curOffset + cb1], cb2);
@@ -2932,7 +2939,7 @@ static void ehciR3ServiceITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
RT_NOREF(enmServiceType);
bool fAnyActive = false;
EHCI_ITD_PAD PaddedItd;
- PEHCI_ITD pItd = &PaddedItd.itd;
+ PEHCI_ITD_PAD pItd = &PaddedItd;
if (ehciR3IsTdInFlight(pThisCC, GCPhys))
return;
@@ -2953,7 +2960,7 @@ static void ehciR3ServiceITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
/* Using out of range PG value (7) yields undefined behavior. We will attempt
* the last page below 4GB (which is ROM, not writable).
*/
- LogRelMax(10, ("EHCI: Illegal page value %d in iTD at %RGp.\n", pItd->Transaction[i].PG, (RTGCPHYS)GCPhys));
+ LogRelMax(10, ("EHCI: Nonstandard page value %d in iTD at %RGp.\n", pItd->Transaction[i].PG, (RTGCPHYS)GCPhys));
}
Log2((" T%d Len=%x Offset=%x PG=%d IOC=%d Buffer=%x\n", i, pItd->Transaction[i].Length, pItd->Transaction[i].Offset, pItd->Transaction[i].PG, pItd->Transaction[i].IOC,
diff --git a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
index c1d5ab9d..81a4b08d 100644
--- a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
+++ b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
@@ -703,7 +703,8 @@ DECLHIDDEN(uint64_t) vusbRhR3ProcessFrame(PVUSBROOTHUB pThis, bool fCallback)
uint64_t tsNanoStart = RTTimeNanoTS();
/* Don't do anything if we are not supposed to process anything (EHCI and XHCI). */
- if (!pThis->uFrameRateDefault)
+ if ( !pThis->uFrameRateDefault
+ || ASMAtomicReadBool(&pThis->fSavingState))
return 0;
if (ASMAtomicXchgBool(&pThis->fFrameProcessing, true))
@@ -1348,15 +1349,16 @@ static DECLCALLBACK(int) vusbR3RhSavePrep(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
LogFlow(("vusbR3RhSavePrep:\n"));
RT_NOREF(pSSM);
+ ASMAtomicXchgBool(&pThis->fSavingState, true);
+
/*
* Detach all proxied devices.
*/
- RTCritSectEnter(&pThis->CritSectDevices);
/** @todo we a) can't tell which are proxied, and b) this won't work well when continuing after saving! */
for (unsigned i = 0; i < RT_ELEMENTS(pThis->apDevByPort); i++)
{
- PVUSBDEV pDev = pThis->apDevByPort[i];
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, i, "SavePrep");
if (pDev)
{
if (!VUSBIDevIsSavedStateSupported(&pDev->IDevice))
@@ -1369,13 +1371,13 @@ static DECLCALLBACK(int) vusbR3RhSavePrep(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
* This will work fine even if the save fails since the Done handler is
* called unconditionally if the Prep handler was called.
*/
+ Assert(!pThis->apDevByPort[i]);
pThis->apDevByPort[i] = pDev;
+ vusbDevRelease(pDev, "SavePrep");
}
}
}
- RTCritSectLeave(&pThis->CritSectDevices);
-
/*
* Kill old load data which might be hanging around.
*/
@@ -1423,6 +1425,7 @@ static DECLCALLBACK(int) vusbR3RhSaveDone(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
vusbHubAttach(pThis, pDev);
}
+ ASMAtomicXchgBool(&pThis->fSavingState, false);
return VINF_SUCCESS;
}
diff --git a/src/VBox/Devices/USB/VUSBInternal.h b/src/VBox/Devices/USB/VUSBInternal.h
index e82c4ce4..4a482ca5 100644
--- a/src/VBox/Devices/USB/VUSBInternal.h
+++ b/src/VBox/Devices/USB/VUSBInternal.h
@@ -421,6 +421,8 @@ typedef struct VUSBROOTHUB
/** Flag whether a frame is currently being processed. */
volatile bool fFrameProcessing;
+ /** Flag whether we are in the middle of saving the VM state. */
+ volatile bool fSavingState;
#if HC_ARCH_BITS == 32
uint32_t Alignment1;
diff --git a/src/VBox/Devices/USB/VUSBUrb.cpp b/src/VBox/Devices/USB/VUSBUrb.cpp
index 595277f9..f55e8746 100644
--- a/src/VBox/Devices/USB/VUSBUrb.cpp
+++ b/src/VBox/Devices/USB/VUSBUrb.cpp
@@ -231,7 +231,7 @@ static void vusbMsgCompletion(PVUSBURB pUrb)
int vusbUrbErrorRhEx(PVUSBROOTHUB pRh, PVUSBURB pUrb)
{
PVUSBDEV pDev = pUrb->pVUsb->pDev;
- LogFlow(("%s: vusbUrbErrorRh: pDev=%p[%s] rh=%p\n", pUrb->pszDesc, pDev, pDev->pUsbIns ? pDev->pUsbIns->pszName : "", pRh));
+ LogFlow(("%s: vusbUrbErrorRh: pDev=%p[%s] rh=%p\n", pUrb->pszDesc, pDev, pDev && pDev->pUsbIns ? pDev->pUsbIns->pszName : "", pRh));
RT_NOREF(pDev);
return pRh->pIRhPort->pfnXferError(pRh->pIRhPort, pUrb);
}
diff --git a/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp b/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
index e76eb5f8..f3b568f7 100644
--- a/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
+++ b/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
@@ -50,6 +50,7 @@
#include <iprt/assert.h>
#include <iprt/critsect.h>
+#include <iprt/ldr.h>
#include <iprt/list.h>
#include <iprt/mem.h>
#include <iprt/once.h>
@@ -74,6 +75,17 @@
typedef struct USBPROXYIFOSX *PUSBPROXYIFOSX;
+/** @name IOKitLib declarations and definitions for IOServiceAuthorize() which is not available in all SDKs.
+ * @{ */
+/** IOServiceAuthorize in IOKit. */
+typedef kern_return_t (* PFNIOSERVICEAUTHORIZE)(io_service_t, uint32_t options);
+
+#ifndef kIOServiceInteractionAllowed
+# define kIOServiceInteractionAllowed 0x00000001
+#endif
+/** @} */
+
+
/**
* A low latency isochronous buffer.
*
@@ -278,6 +290,8 @@ static CFStringRef g_pRunLoopMode = NULL;
/** The IO Master Port.
* Not worth cleaning up. */
static mach_port_t g_MasterPort = MACH_PORT_NULL;
+/** Pointer to the IOServiceAuthorize() method. */
+static PFNIOSERVICEAUTHORIZE g_pfnIOServiceAuthorize = NULL;
/**
@@ -291,7 +305,17 @@ static DECLCALLBACK(int32_t) usbProxyDarwinInitOnce(void *pvUser1)
{
RT_NOREF(pvUser1);
- int rc;
+ RTLDRMOD hMod = NIL_RTLDRMOD;
+ int rc = RTLdrLoadEx("/System/Library/Frameworks/IOKit.framework/Versions/Current/IOKit", &hMod, RTLDRLOAD_FLAGS_NO_SUFFIX | RTLDRLOAD_FLAGS_NO_UNLOAD,
+ NULL);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTLdrGetSymbol(hMod, "IOServiceAuthorize", (void **)&g_pfnIOServiceAuthorize);
+ if (RT_FAILURE(rc))
+ LogRel(("USB: Failed to resolve IOServiceAuthorize(), capturing USB devices might not work (%Rrc)\n", rc));
+ RTLdrClose(hMod);
+ }
+
kern_return_t krc = IOMasterPort(MACH_PORT_NULL, &g_MasterPort);
if (krc == KERN_SUCCESS)
{
@@ -1215,6 +1239,17 @@ static DECLCALLBACK(int) usbProxyDarwinOpen(PUSBPROXYDEV pProxyDev, const char *
}
/*
+ * Ask for authorization (which only works with the com.apple.vm.device-access entitlement).
+ */
+ if (g_pfnIOServiceAuthorize)
+ {
+ irc = g_pfnIOServiceAuthorize(USBDevice, kIOServiceInteractionAllowed);
+ if (irc != kIOReturnSuccess)
+ LogRel(("USB: Failed to get authorization for device '%s', capturing the device might not work: irc=%#x\n",
+ pszAddress, irc));
+ }
+
+ /*
* Create a plugin interface for the device and query its IOUSBDeviceInterface.
*/
SInt32 Score = 0;
diff --git a/src/VBox/Devices/VirtIO/VirtioCore.cpp b/src/VBox/Devices/VirtIO/VirtioCore.cpp
index f0ed6e42..a0deddd6 100644
--- a/src/VBox/Devices/VirtIO/VirtioCore.cpp
+++ b/src/VBox/Devices/VirtIO/VirtioCore.cpp
@@ -1193,7 +1193,10 @@ int virtioCoreR3VirtqUsedBufPut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_
size_t cbCopy = 0, cbTotal = 0, cbRemain = 0;
- if (pSgVirtReturn)
+ /** @todo r=aeichner Check whether VirtIO should return an error if the device wants to return data but
+ * the guest didn't set up an IN buffer. */
+ if ( pSgVirtReturn
+ && pSgPhysReturn)
{
size_t cbTarget = virtioCoreGCPhysChainCalcBufSize(pSgPhysReturn);
cbRemain = cbTotal = RTSgBufCalcTotalLength(pSgVirtReturn);
@@ -1227,7 +1230,9 @@ int virtioCoreR3VirtqUsedBufPut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_
virtioWriteUsedElem(pDevIns, pVirtio, pVirtq, pVirtq->uUsedIdxShadow++, pVirtqBuf->uHeadIdx, (uint32_t)cbTotal);
#ifdef LOG_ENABLED
- if (LogIs6Enabled() && pSgVirtReturn)
+ if ( LogIs6Enabled()
+ && pSgVirtReturn
+ && pSgPhysReturn)
{
LogFunc((" ... %d segs, %zu bytes, copied to %u byte buf@offset=%u. Residual: %zu bytes\n",
diff --git a/src/VBox/Devices/build/VBoxDD.cpp b/src/VBox/Devices/build/VBoxDD.cpp
index 36b12c69..1e88822d 100644
--- a/src/VBox/Devices/build/VBoxDD.cpp
+++ b/src/VBox/Devices/build/VBoxDD.cpp
@@ -246,6 +246,10 @@ extern "C" DECLEXPORT(int) VBoxDevicesRegister(PPDMDEVREGCB pCallbacks, uint32_t
rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceTpm);
if (RT_FAILURE(rc))
return rc;
+
+ rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceTpmPpi);
+ if (RT_FAILURE(rc))
+ return rc;
#endif
return VINF_SUCCESS;
diff --git a/src/VBox/Devices/build/VBoxDD.h b/src/VBox/Devices/build/VBoxDD.h
index 9350f428..e451abcd 100644
--- a/src/VBox/Devices/build/VBoxDD.h
+++ b/src/VBox/Devices/build/VBoxDD.h
@@ -115,6 +115,7 @@ extern const PDMDEVREG g_DeviceVirtualKD;
extern const PDMDEVREG g_DeviceQemuFwCfg;
#ifdef VBOX_WITH_TPM
extern const PDMDEVREG g_DeviceTpm;
+extern const PDMDEVREG g_DeviceTpmPpi;
#endif
extern const PDMDRVREG g_DrvMouseQueue;