summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices
diff options
context:
space:
mode:
Diffstat (limited to '')
-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--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py0
-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/Network/DevVirtioNet.cpp10
-rw-r--r--src/VBox/Devices/Network/SrvIntNetR0.cpp2
-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.cpp191
-rw-r--r--src/VBox/Devices/VirtIO/VirtioCore.h3
-rw-r--r--src/VBox/Devices/build/VBoxDD.cpp4
-rw-r--r--src/VBox/Devices/build/VBoxDD.h1
51 files changed, 1183 insertions, 95 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/BaseTools/Scripts/GetUtcDateTime.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py
index c23a3a10..c23a3a10 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py
index b3198d5b..b3198d5b 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py
index c0a3269b..c0a3269b 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py
index c0b5e460..c0b5e460 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py
index f4cf1989..f4cf1989 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
index 7f000648..7f000648 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py
index 4e19e636..4e19e636 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py
index e5e20f41..e5e20f41 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py
index 29ed80b4..29ed80b4 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py
index afe58534..afe58534 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py
index a287f3a3..a287f3a3 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py
diff --git a/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl b/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl
index 5b0749fa..5b0749fa 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl
+++ b/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py
index a71073ba..a71073ba 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py
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 2c689d9b..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 e586a195..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 0b83b579..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.16 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.16', 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, 0deh
+ db 000h, 0e8h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
index 9d6aad04..7d578726 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
@@ -1 +1 @@
-852353ec31d0749de1c385e91ab27511 *VBoxVgaBios286.rom
+1ab418acec7c367d0ffd228c5ef63633 *VBoxVgaBios286.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
index 12ea3360..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.16 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.16', 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, 053h
+ db 000h, 05dh
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
index 5bbcac9e..f4eab9e3 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
@@ -1 +1 @@
-5fd5574a01aad6139078230edb9b0545 *VBoxVgaBios386.rom
+fc1076be2c8e2edddd08bbfdf33182ff *VBoxVgaBios386.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
index 695ce11f..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.16 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.16', 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, 01dh
+ db 000h, 027h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
index d19f9c05..bf5f9e97 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
@@ -1 +1 @@
-4d5fd4aad75f5b2295caecb11ca646b2 *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/Network/DevVirtioNet.cpp b/src/VBox/Devices/Network/DevVirtioNet.cpp
index 66d2cbf1..336b3000 100644
--- a/src/VBox/Devices/Network/DevVirtioNet.cpp
+++ b/src/VBox/Devices/Network/DevVirtioNet.cpp
@@ -791,7 +791,11 @@ void virtioNetDumpGcPhysRxBuf(PPDMDEVINS pDevIns, PVIRTIONETPKTHDR pRxPktHdr,
/**
* @callback_method_impl{FNDBGFHANDLERDEV, virtio-net debugger info callback.}
*/
+#ifdef VIRTIO_REL_INFO_DUMP
+DECLCALLBACK(void) virtioNetR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+#else /* !VIRTIO_REL_INFO_DUMP */
static DECLCALLBACK(void) virtioNetR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+#endif /* !VIRTIO_REL_INFO_DUMP */
{
PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC);
@@ -904,7 +908,7 @@ static DECLCALLBACK(void) virtioNetR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp
pHlp->pfnPrintf(pHlp, " cVirtqPairs .,............. %d\n", pThis->cVirtqPairs);
pHlp->pfnPrintf(pHlp, " cVirtqs .,................. %d\n", pThis->cVirtqs);
pHlp->pfnPrintf(pHlp, " cWorkers .................. %d\n", pThis->cWorkers);
- pHlp->pfnPrintf(pHlp, " MMIO mapping name ......... %d\n", pThisCC->Virtio.szMmioName);
+ pHlp->pfnPrintf(pHlp, " MMIO mapping name ......... %s\n", pThisCC->Virtio.szMmioName);
pHlp->pfnPrintf(pHlp, "\n");
}
@@ -923,7 +927,7 @@ static DECLCALLBACK(void) virtioNetR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp
pHlp->pfnPrintf(pHlp, " Suppress multicast: ....... %s\n", pThis->fNoMulticast ? "true" : "false");
pHlp->pfnPrintf(pHlp, " Promiscuous: .............. %s\n", pThis->fPromiscuous ? "true" : "false");
pHlp->pfnPrintf(pHlp, "\n");
- pHlp->pfnPrintf(pHlp, " Default Rx MAC filter: .... %RTmac\n", pThis->rxFilterMacDefault);
+ pHlp->pfnPrintf(pHlp, " Default Rx MAC filter: .... %RTmac\n", &pThis->rxFilterMacDefault);
pHlp->pfnPrintf(pHlp, "\n");
pHlp->pfnPrintf(pHlp, " Unicast filter MACs:\n");
@@ -3675,7 +3679,7 @@ static DECLCALLBACK(int) virtioNetR3Construct(PPDMDEVINS pDevIns, int iInstance,
* Register the debugger info callback (ignore errors).
*/
char szTmp[128];
- rc = PDMDevHlpDBGFInfoRegister(pDevIns, "virtio-net", "Display virtio-net info (help, net, features, state, pointers, queues, all)", virtioNetR3Info);
+ rc = PDMDevHlpDBGFInfoRegister(pDevIns, "virtionet", "Display virtionet info (help, net, features, state, pointers, queues, all)", virtioNetR3Info);
if (RT_FAILURE(rc))
LogRel(("Failed to register DBGF info for device %s\n", szTmp));
return rc;
diff --git a/src/VBox/Devices/Network/SrvIntNetR0.cpp b/src/VBox/Devices/Network/SrvIntNetR0.cpp
index 728cd25a..9e9d1757 100644
--- a/src/VBox/Devices/Network/SrvIntNetR0.cpp
+++ b/src/VBox/Devices/Network/SrvIntNetR0.cpp
@@ -2935,7 +2935,7 @@ static int intnetR0TrunkIfSendGsoFallback(PINTNETTRUNKIF pThis, PINTNETIF pIfSen
union
{
- uint8_t abBuf[sizeof(INTNETSG) + sizeof(INTNETSEG)];
+ uint8_t abBuf[sizeof(INTNETSG) + 2 * sizeof(INTNETSEG)];
INTNETSG SG;
} u;
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
index 5b6da227..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.16', 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, 0d6h
+ 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 556bdbe3..c546774a 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
@@ -1 +1 @@
-574c2c72048d5a5c9c079fbf47683b0f *VBoxPcBios286.rom
+60aec905c47ddf2c8a658f7fdedf61b6 *VBoxPcBios286.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
index a3231d00..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.16', 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, 034h
+ 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 80cc8e0a..7934d06b 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
@@ -1 +1 @@
-951bc82dd1a8482863248e9157928f1b *VBoxPcBios386.rom
+dbb41e6f7bffdc046e70fcc71697c569 *VBoxPcBios386.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
index 92665f77..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.16', 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, 0bbh
+ 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 95f06271..9ad9c6d4 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
@@ -1 +1 @@
-0704d20fb86b2ca3eba57b2ca2f9e135 *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 23ecf30c..a0deddd6 100644
--- a/src/VBox/Devices/VirtIO/VirtioCore.cpp
+++ b/src/VBox/Devices/VirtIO/VirtioCore.cpp
@@ -618,6 +618,42 @@ bool virtioCoreR3VirtqIsEnabled(PVIRTIOCORE pVirtio, uint16_t uVirtqNbr)
return (bool)pVirtq->uEnable && pVirtq->GCPhysVirtqDesc;
}
+DECLINLINE(void) virtioCoreR3DescInfo(PCDBGFINFOHLP pHlp, PVIRTQ_DESC_T pDesc, uint16_t iDesc, const char *cszTail)
+{
+ if (pDesc->fFlags & VIRTQ_DESC_F_NEXT)
+ pHlp->pfnPrintf(pHlp, " [%4d]%c%c %5d bytes @ %p [%4d] %s\n",
+ iDesc, pDesc->fFlags & VIRTQ_DESC_F_INDIRECT ? 'I' : ' ',
+ pDesc->fFlags & VIRTQ_DESC_F_WRITE ? 'W' : 'R',
+ pDesc->cb, pDesc->GCPhysBuf, pDesc->uDescIdxNext, cszTail);
+ else
+ pHlp->pfnPrintf(pHlp, " [%4d]%c%c %5d bytes @ %p %s\n",
+ iDesc, pDesc->fFlags & VIRTQ_DESC_F_INDIRECT ? 'I' : ' ',
+ pDesc->fFlags & VIRTQ_DESC_F_WRITE ? 'W' : 'R',
+ pDesc->cb, pDesc->GCPhysBuf, cszTail);
+}
+
+#ifdef VIRTIO_REL_INFO_DUMP
+DECLHIDDEN(void) virtioCoreR3DumpAvailRing(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, PVIRTIOCORE pVirtio, PVIRTQUEUE pVirtq)
+{
+ uint16_t auTmp[VIRTQ_SIZE];
+ virtioCoreGCPhysRead(pVirtio, pDevIns,
+ pVirtq->GCPhysVirtqAvail + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[0]),
+ auTmp, pVirtq->uQueueSize * sizeof(uint16_t));
+ pHlp->pfnPrintf(pHlp, " avail ring dump:\n%.*RhXd\n", pVirtq->uQueueSize * sizeof(uint16_t), auTmp,
+ pVirtq->GCPhysVirtqAvail + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[0]));
+}
+
+DECLHIDDEN(void) virtioCoreR3DumpUsedRing(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, PVIRTIOCORE pVirtio, PVIRTQUEUE pVirtq)
+{
+ VIRTQ_USED_ELEM_T aTmp[VIRTQ_SIZE];
+ virtioCoreGCPhysRead(pVirtio, pDevIns,
+ pVirtq->GCPhysVirtqUsed + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[0]),
+ aTmp, pVirtq->uQueueSize * sizeof(VIRTQ_USED_ELEM_T));
+ pHlp->pfnPrintf(pHlp, " used ring dump:\n%.*RhXd\n", pVirtq->uQueueSize * sizeof(VIRTQ_USED_ELEM_T), aTmp,
+ pVirtq->GCPhysVirtqUsed + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[0]));
+}
+#endif /* VIRTIO_REL_INFO_DUMP */
+
/** API Fuunction: See header file */
void virtioCoreR3VirtqInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs, int uVirtq)
{
@@ -634,9 +670,23 @@ void virtioCoreR3VirtqInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *p
uint16_t uUsedIdx = virtioReadUsedRingIdx(pDevIns, pVirtio, pVirtq);
uint16_t uUsedIdxShadow = pVirtq->uUsedIdxShadow;
+ uint16_t uAvailEventIdx = 0;
+ uint16_t uUsedEventIdx = 0;
+ bool fNotify = !!(pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX);
+ if (fNotify)
+ {
+ uUsedEventIdx = virtioReadAvailUsedEvent(pDevIns, pVirtio, pVirtq);
+ /* There is no helper for reading AvailEvent since the device is not supposed to read it. */
+ virtioCoreGCPhysRead(pVirtio, pDevIns,
+ pVirtq->GCPhysVirtqUsed
+ + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[pVirtq->uQueueSize]),
+ &uAvailEventIdx, sizeof(uAvailEventIdx));
+ }
+
#ifdef VIRTIO_VBUF_ON_STACK
VIRTQBUF_T VirtqBuf;
PVIRTQBUF pVirtqBuf = &VirtqBuf;
+ RT_ZERO(VirtqBuf); /* Make sure pSgPhysSend and pSgPhysReturn are initialized. */
#else /* !VIRTIO_VBUF_ON_STACK */
PVIRTQBUF pVirtqBuf = NULL;
#endif /* !VIRTIO_VBUF_ON_STACK */
@@ -667,19 +717,19 @@ void virtioCoreR3VirtqInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *p
pHlp->pfnPrintf(pHlp, " MSIX vector: ....... %4.4x\n", pVirtq->uMsixVector);
pHlp->pfnPrintf(pHlp, "\n");
pHlp->pfnPrintf(pHlp, " avail ring (%d entries):\n", uAvailIdx - uAvailIdxShadow);
- pHlp->pfnPrintf(pHlp, " index: ................ %d\n", uAvailIdx);
- pHlp->pfnPrintf(pHlp, " shadow: ............... %d\n", uAvailIdxShadow);
+ pHlp->pfnPrintf(pHlp, " index: ................ %d (%d)\n", pVirtq->uQueueSize ? uAvailIdx % pVirtq->uQueueSize : uAvailIdx, uAvailIdx);
+ pHlp->pfnPrintf(pHlp, " shadow: ............... %d (%d)\n", pVirtq->uQueueSize ? uAvailIdxShadow % pVirtq->uQueueSize : uAvailIdxShadow, uAvailIdxShadow);
pHlp->pfnPrintf(pHlp, " flags: ................ %s\n", fAvailNoInterrupt ? "NO_INTERRUPT" : "");
pHlp->pfnPrintf(pHlp, "\n");
- pHlp->pfnPrintf(pHlp, " used ring (%d entries):\n", uUsedIdx - uUsedIdxShadow);
- pHlp->pfnPrintf(pHlp, " index: ................ %d\n", uUsedIdx);
- pHlp->pfnPrintf(pHlp, " shadow: ............... %d\n", uUsedIdxShadow);
+ pHlp->pfnPrintf(pHlp, " used ring (%d entries):\n", uUsedIdxShadow - uUsedIdx);
+ pHlp->pfnPrintf(pHlp, " index: ................ %d (%d)\n", pVirtq->uQueueSize ? uUsedIdx % pVirtq->uQueueSize : uUsedIdx, uUsedIdx);
+ pHlp->pfnPrintf(pHlp, " shadow: ............... %d (%d)\n", pVirtq->uQueueSize ? uUsedIdxShadow % pVirtq->uQueueSize : uUsedIdxShadow, uUsedIdxShadow);
pHlp->pfnPrintf(pHlp, " flags: ................ %s\n", fUsedNoNotify ? "NO_NOTIFY" : "");
pHlp->pfnPrintf(pHlp, "\n");
if (!fEmpty)
{
pHlp->pfnPrintf(pHlp, " desc chain:\n");
- pHlp->pfnPrintf(pHlp, " head idx: ............. %d\n", uUsedIdx);
+ pHlp->pfnPrintf(pHlp, " head idx: ............. %d (%d)\n", pVirtq->uQueueSize ? uUsedIdx % pVirtq->uQueueSize : uUsedIdx, uUsedIdx);
pHlp->pfnPrintf(pHlp, " segs: ................. %d\n", cSendSegs + cReturnSegs);
pHlp->pfnPrintf(pHlp, " refCnt ................ %d\n", pVirtqBuf->cRefs);
pHlp->pfnPrintf(pHlp, "\n");
@@ -691,7 +741,7 @@ void virtioCoreR3VirtqInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *p
pHlp->pfnPrintf(pHlp, " unsent ............. %d\n", pVirtqBuf->pSgPhysSend->cbSegLeft);
}
pHlp->pfnPrintf(pHlp, "\n");
- pHlp->pfnPrintf(pHlp, " guest-to-host (%d bytes)\n", pVirtqBuf->cbPhysReturn);
+ pHlp->pfnPrintf(pHlp, " guest-to-host (%d bytes):\n", pVirtqBuf->cbPhysReturn);
pHlp->pfnPrintf(pHlp, " segs: .............. %d\n", cReturnSegs);
if (cReturnSegs)
{
@@ -699,8 +749,77 @@ void virtioCoreR3VirtqInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *p
pHlp->pfnPrintf(pHlp, " unsent ............. %d\n", pVirtqBuf->pSgPhysReturn->cbSegLeft);
}
} else
- pHlp->pfnPrintf(pHlp, " No desc chains available\n");
+ pHlp->pfnPrintf(pHlp, " no desc chains available\n");
+ pHlp->pfnPrintf(pHlp, "\n");
+
+ /* Avoid handling zero-sized queues, there is nothing to show anyway. */
+ if (pVirtq->uQueueSize == 0)
+ return;
+
+ pHlp->pfnPrintf(pHlp, " desc table:\n");
+ /*
+ * Each line in the descriptor table output consists of two parts: a fixed part and a variable "tail".
+ * The fixed part shows the descriptor index, its writability, size, physical address, and optionally
+ * which descriptor is next the chain. The tail shows which elements of avail/used rings point to
+ * this descriptor.
+ */
+ VIRTQ_DESC_T descTable[VIRTQ_SIZE];
+ char aszTails[VIRTQ_SIZE][32];
+ virtioCoreGCPhysRead(pVirtio, pDevIns, pVirtq->GCPhysVirtqDesc,
+ &descTable, sizeof(VIRTQ_DESC_T) * pVirtq->uQueueSize);
+ RT_BZERO(aszTails, sizeof(aszTails)); /* No tails by default */
+
+ /* Fill avail tail fields. */
+
+ /* The first available descriptor gets outer reverse angle brackets. */
+ char chOuterLeft = '>', chOuterRight = '<';
+ char chLeft = '[', chRight = ']';
+ /* Use 'not-equal' instead of 'less' because of uint16_t wrapping! */
+ for (uint16_t i = uAvailIdxShadow; i != uAvailIdx; i++)
+ {
+ /* The last descriptor gets inner curly braces, inner square brackets for the rest. */
+ if (i + 1 == uAvailIdx) { chLeft = '{'; chRight = '}'; }
+ uint16_t uDescIdx = virtioReadAvailDescIdx(pDevIns, pVirtio, pVirtq, i);
+ /* Print an exclamation sign instead of outer right bracket if this descriptor triggers notification. */
+ RTStrPrintf(aszTails[uDescIdx], sizeof(aszTails[0]), "%c%c%4d%c%c ",
+ chOuterLeft, chLeft, i % pVirtq->uQueueSize, chRight,
+ fNotify ? ((i % pVirtq->uQueueSize) == (uAvailEventIdx % pVirtq->uQueueSize) ? '!' : chOuterRight) : chOuterRight);
+ chOuterLeft = chOuterRight = ' ';
+ }
+
+ /* Fill used tail fields, see comments in the similar loop above. */
+
+ chOuterLeft = '>'; chOuterRight = '<';
+ chLeft = '['; chRight = ']';
+ for (uint16_t i = uUsedIdx; i != uUsedIdxShadow; i++)
+ {
+ VIRTQ_USED_ELEM_T elem;
+ virtioCoreGCPhysRead(pVirtio, pDevIns,
+ pVirtq->GCPhysVirtqUsed
+ + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[i % pVirtq->uQueueSize]),
+ &elem, sizeof(elem));
+ if (i + 1 == uUsedIdxShadow) { chLeft = '{'; chRight = '}'; }
+ char *szTail = aszTails[elem.uDescIdx % pVirtq->uQueueSize];
+ /* Add empty avail field if none is present, 9 spaces + terminating zero. */
+ if (*szTail == '\0')
+ RTStrCopy(szTail, 10, " ");
+ RTStrPrintf(szTail + 9, sizeof(aszTails[0]) - 9, " %c%c%4d%c%c %d bytes",
+ chOuterLeft, chLeft, i % pVirtq->uQueueSize, chRight,
+ fNotify ? ((i % pVirtq->uQueueSize) == (uUsedEventIdx % pVirtq->uQueueSize) ? '!' : chOuterRight) : chOuterRight,
+ elem.cbElem);
+ chOuterLeft = chOuterRight = ' ';
+ }
+
+ pHlp->pfnPrintf(pHlp, " index w/r size phys addr next @avail @used\n");
+ pHlp->pfnPrintf(pHlp, " ------ - ----------- ---------------- ------- -------- ------------------\n");
+ for (uint16_t i = 0; i < pVirtq->uQueueSize; i++)
+ virtioCoreR3DescInfo(pHlp, &descTable[i], i, aszTails[i]);
+#ifdef VIRTIO_REL_INFO_DUMP
pHlp->pfnPrintf(pHlp, "\n");
+ virtioCoreR3DumpAvailRing(pDevIns, pHlp, pVirtio, pVirtq);
+ pHlp->pfnPrintf(pHlp, "\n");
+ virtioCoreR3DumpUsedRing(pDevIns, pHlp, pVirtio, pVirtq);
+#endif /* VIRTIO_REL_INFO_DUMP */
}
#ifdef VIRTIO_VBUF_ON_STACK
@@ -819,6 +938,46 @@ int virtioCoreR3VirtqAvailBufNext(PVIRTIOCORE pVirtio, uint16_t uVirtq)
return VINF_SUCCESS;
}
+#ifdef VIRTIO_REL_INFO_DUMP
+DECLCALLBACK(void) virtioNetR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
+
+static DECLCALLBACK(void) dbgVirtio_Printf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)
+{
+ RT_NOREF(pHlp);
+ va_list va;
+ va_start(va, pszFormat);
+ RTLogRelPrintfV(pszFormat, va);
+ va_end(va);
+}
+
+
+static DECLCALLBACK(void) dbgVirtio_PrintfV(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args)
+{
+ RT_NOREF(pHlp);
+ RTLogRelPrintfV(pszFormat, args);
+}
+
+
+/**
+ * @interface_method_impl{DBGCCMDHLP,pfnGetDbgfOutputHlp}
+ */
+static void dbgVirtioDump(PPDMDEVINS pDevIns)
+{
+ PVIRTIOCORE pVirtio = PDMDEVINS_2_DATA(pDevIns, PVIRTIOCORE);
+ LogRel(("dbgVirtioDump(%s)", pVirtio->szInstance));
+ if (RTStrNCmp("virtio-net", pVirtio->szInstance, 10) == 0)
+ {
+ DBGFINFOHLP DbgHlp;
+
+ DbgHlp.pfnPrintf = dbgVirtio_Printf;
+ DbgHlp.pfnPrintfV = dbgVirtio_PrintfV;
+ DbgHlp.pfnGetOptError = NULL;
+
+ virtioNetR3Info(pDevIns, &DbgHlp, "a"); // Print everything!
+ }
+}
+
+#endif /* VIRTIO_REL_INFO_DUMP */
/** API Function: See header file */
#ifdef VIRTIO_VBUF_ON_STACK
int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq,
@@ -889,11 +1048,14 @@ int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16
static volatile uint32_t s_cThreshold = 1;
if (ASMAtomicIncU32(&s_cMessages) == ASMAtomicReadU32(&s_cThreshold))
{
- LogRelMax(64, ("Too many linked descriptors; check if the guest arranges descriptors in a loop (cSegsIn=%u cSegsOut=%u uQueueSize=%u).\n",
- cSegsIn, cSegsOut, pVirtq->uQueueSize));
+ LogRelMax(64, ("Too many linked descriptors; check if the guest arranges descriptors in a loop (cSegsIn=%u cSegsOut=%u uQueueSize=%u uDescIdx=%u queue=%s).\n",
+ cSegsIn, cSegsOut, pVirtq->uQueueSize, uDescIdx, pVirtq->szName));
if (ASMAtomicReadU32(&s_cMessages) != 1)
LogRelMax(64, ("(the above error has occured %u times so far)\n", ASMAtomicReadU32(&s_cMessages)));
ASMAtomicWriteU32(&s_cThreshold, ASMAtomicReadU32(&s_cThreshold) * 10);
+#ifdef VIRTIO_REL_INFO_DUMP
+ dbgVirtioDump(pDevIns);
+#endif /* VIRTIO_REL_INFO_DUMP */
}
break;
}
@@ -1031,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);
@@ -1065,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/VirtIO/VirtioCore.h b/src/VBox/Devices/VirtIO/VirtioCore.h
index 00bcb43c..776ac969 100644
--- a/src/VBox/Devices/VirtIO/VirtioCore.h
+++ b/src/VBox/Devices/VirtIO/VirtioCore.h
@@ -32,6 +32,9 @@
# pragma once
#endif
+/* Some temporary printouts to release log in descriptor chain handling */
+//#define VIRTIO_REL_INFO_DUMP 1
+
/* Do not allocate VIRTQBUF from the heap when possible */
#define VIRTIO_VBUF_ON_STACK 1
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;