616c4e73368513b3c835881ff9f2386083afad01vboxsync/* $Id$ */
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync/** @file
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * VBoxAcpi - VirtualBox ACPI manipulation functionality.
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync */
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync/*
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync * Copyright (C) 2009-2013 Oracle Corporation
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync *
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync * available from http://www.virtualbox.org. This file is free software;
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync * you can redistribute it and/or modify it under the terms of the GNU
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync * General Public License (GPL) as published by the Free Software
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync */
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync/*******************************************************************************
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync* Header Files *
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync*******************************************************************************/
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync#include <iprt/cdefs.h>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#if !defined(IN_RING3)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync# error Pure R3 code
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#endif
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
3854599844436d009da0f32760d657fc7690a5a8vboxsync#define LOG_GROUP LOG_GROUP_DEV_ACPI
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/pdmdev.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/pgm.h>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#include <VBox/log.h>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#include <VBox/param.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/cfgm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/mm.h>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#include <iprt/assert.h>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#include <iprt/alloc.h>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#include <iprt/string.h>
70e70d246c1b592db31d93071c48bb43ea61100evboxsync#include <iprt/file.h>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#ifdef VBOX_WITH_DYNAMIC_DSDT
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync/* vbox.dsl - input to generate proper DSDT on the fly */
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync# include <vboxdsl.hex>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#else
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync/* Statically compiled AML */
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync# include <vboxaml.hex>
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync# include <vboxssdt-standard.hex>
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync# include <vboxssdt-cpuhotplug.hex>
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#endif
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync#include "VBoxDD.h"
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#ifdef VBOX_WITH_DYNAMIC_DSDT
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncstatic int prepareDynamicDsdt(PPDMDEVINS pDevIns, void **ppvPtr, size_t *pcbDsdt)
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync{
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync *ppvPtr = NULL;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync *pcbDsdt = 0;
3854599844436d009da0f32760d657fc7690a5a8vboxsync return 0;
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync}
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncstatic int cleanupDynamicDsdt(PPDMDEVINS pDevIns, void *pvPtr)
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync{
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync return 0;
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync}
ecb074924ed761fe89e91113482db5b7374441b0vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync#else /* VBOX_WITH_DYNAMIC_DSDT */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncstatic int patchAml(PPDMDEVINS pDevIns, uint8_t *pabAml, size_t cbAml)
ecb074924ed761fe89e91113482db5b7374441b0vboxsync{
ecb074924ed761fe89e91113482db5b7374441b0vboxsync uint16_t cNumCpus;
ecb074924ed761fe89e91113482db5b7374441b0vboxsync int rc;
616c4e73368513b3c835881ff9f2386083afad01vboxsync
928e1d6581a40f26932a8b35526773805bc69e47vboxsync rc = CFGMR3QueryU16Def(pDevIns->pCfg, "NumCPUs", &cNumCpus, 1);
616c4e73368513b3c835881ff9f2386083afad01vboxsync
ecb074924ed761fe89e91113482db5b7374441b0vboxsync if (RT_FAILURE(rc))
ecb074924ed761fe89e91113482db5b7374441b0vboxsync return rc;
616c4e73368513b3c835881ff9f2386083afad01vboxsync
a2779f5bd9cc55216a2911d7714ede6a77cac3b2vboxsync /* Clear CPU objects at all, if needed */
3854599844436d009da0f32760d657fc7690a5a8vboxsync bool fShowCpu;
928e1d6581a40f26932a8b35526773805bc69e47vboxsync rc = CFGMR3QueryBoolDef(pDevIns->pCfg, "ShowCpu", &fShowCpu, false);
3854599844436d009da0f32760d657fc7690a5a8vboxsync if (RT_FAILURE(rc))
24eb79e9b779a21a256c7e15e5ad8ef97f7b6178vboxsync return rc;
3854599844436d009da0f32760d657fc7690a5a8vboxsync
3854599844436d009da0f32760d657fc7690a5a8vboxsync if (!fShowCpu)
24eb79e9b779a21a256c7e15e5ad8ef97f7b6178vboxsync cNumCpus = 0;
24eb79e9b779a21a256c7e15e5ad8ef97f7b6178vboxsync
616c4e73368513b3c835881ff9f2386083afad01vboxsync /**
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * Now search AML for:
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * AML_PROCESSOR_OP (UINT16) 0x5b83
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * and replace whole block with
616c4e73368513b3c835881ff9f2386083afad01vboxsync * AML_NOOP_OP (UINT16) 0xa3
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * for VCPU not configured
ecb074924ed761fe89e91113482db5b7374441b0vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync for (uint32_t i = 0; i < cbAml - 7; i++)
ecb074924ed761fe89e91113482db5b7374441b0vboxsync {
ecb074924ed761fe89e91113482db5b7374441b0vboxsync /*
616c4e73368513b3c835881ff9f2386083afad01vboxsync * AML_PROCESSOR_OP
ecb074924ed761fe89e91113482db5b7374441b0vboxsync *
616c4e73368513b3c835881ff9f2386083afad01vboxsync * DefProcessor := ProcessorOp PkgLength NameString ProcID
ecb074924ed761fe89e91113482db5b7374441b0vboxsync PblkAddr PblkLen ObjectList
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * ProcessorOp := ExtOpPrefix 0x83
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * ProcID := ByteData
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * PblkAddr := DwordData
ecb074924ed761fe89e91113482db5b7374441b0vboxsync * PblkLen := ByteData
ecb074924ed761fe89e91113482db5b7374441b0vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAml[i] == 0x5b && pabAml[i+1] == 0x83)
ecb074924ed761fe89e91113482db5b7374441b0vboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAml[i+3] != 'C' || pabAml[i+4] != 'P')
ecb074924ed761fe89e91113482db5b7374441b0vboxsync /* false alarm, not named starting CP */
ecb074924ed761fe89e91113482db5b7374441b0vboxsync continue;
616c4e73368513b3c835881ff9f2386083afad01vboxsync
3854599844436d009da0f32760d657fc7690a5a8vboxsync /* Processor ID */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAml[i+7] < cNumCpus)
3854599844436d009da0f32760d657fc7690a5a8vboxsync continue;
ecb074924ed761fe89e91113482db5b7374441b0vboxsync
ecb074924ed761fe89e91113482db5b7374441b0vboxsync /* Will fill unwanted CPU block with NOOPs */
616c4e73368513b3c835881ff9f2386083afad01vboxsync /*
616c4e73368513b3c835881ff9f2386083afad01vboxsync * See 18.2.4 Package Length Encoding in ACPI spec
616c4e73368513b3c835881ff9f2386083afad01vboxsync * for full format
ecb074924ed761fe89e91113482db5b7374441b0vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint32_t cBytes = pabAml[i + 2];
616c4e73368513b3c835881ff9f2386083afad01vboxsync AssertReleaseMsg((cBytes >> 6) == 0,
ecb074924ed761fe89e91113482db5b7374441b0vboxsync ("So far, we only understand simple package length"));
616c4e73368513b3c835881ff9f2386083afad01vboxsync
ecb074924ed761fe89e91113482db5b7374441b0vboxsync /* including AML_PROCESSOR_OP itself */
ecb074924ed761fe89e91113482db5b7374441b0vboxsync for (uint32_t j = 0; j < cBytes + 2; j++)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAml[i+j] = 0xa3;
ecb074924ed761fe89e91113482db5b7374441b0vboxsync
ecb074924ed761fe89e91113482db5b7374441b0vboxsync /* Can increase i by cBytes + 1, but not really worth it */
ecb074924ed761fe89e91113482db5b7374441b0vboxsync }
ecb074924ed761fe89e91113482db5b7374441b0vboxsync }
ecb074924ed761fe89e91113482db5b7374441b0vboxsync
ecb074924ed761fe89e91113482db5b7374441b0vboxsync /* now recompute checksum, whole file byte sum must be 0 */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAml[9] = 0;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t bSum = 0;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync for (uint32_t i = 0; i < cbAml; i++)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync bSum = bSum + pabAml[i];
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAml[9] = (uint8_t)(0 - bSum);
616c4e73368513b3c835881ff9f2386083afad01vboxsync
ecb074924ed761fe89e91113482db5b7374441b0vboxsync return 0;
ecb074924ed761fe89e91113482db5b7374441b0vboxsync}
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync/**
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * Patch the CPU hot-plug SSDT version to
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * only contain the ACPI containers which may have a CPU
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncstatic int patchAmlCpuHotPlug(PPDMDEVINS pDevIns, uint8_t *pabAml, size_t cbAml)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync{
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync uint16_t cNumCpus;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync int rc;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync uint32_t idxAml = 0;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync rc = CFGMR3QueryU16Def(pDevIns->pCfg, "NumCPUs", &cNumCpus, 1);
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync if (RT_FAILURE(rc))
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync return rc;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /**
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * Now search AML for:
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * AML_DEVICE_OP (UINT16) 0x5b82
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * and replace whole block with
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * AML_NOOP_OP (UINT16) 0xa3
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * for VCPU not configured
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync while (idxAml < cbAml - 7)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /*
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * AML_DEVICE_OP
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync *
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * DefDevice := DeviceOp PkgLength NameString ObjectList
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * DeviceOp := ExtOpPrefix 0x82
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAml[idxAml] == 0x5b && pabAml[idxAml+1] == 0x82)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* Check if the enclosed CPU device is configured. */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t *pabAmlPkgLength = &pabAml[idxAml+2];
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync uint32_t cBytes = 0;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint32_t cLengthBytesFollow = pabAmlPkgLength[0] >> 6;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync if (cLengthBytesFollow == 0)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* Simple package length */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync cBytes = pabAmlPkgLength[0];
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync else
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync unsigned idxLengthByte = 1;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync cBytes = pabAmlPkgLength[0] & 0xF;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync while (idxLengthByte <= cLengthBytesFollow)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync cBytes |= pabAmlPkgLength[idxLengthByte] << (4*idxLengthByte);
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync idxLengthByte++;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t *pabAmlDevName = &pabAmlPkgLength[cLengthBytesFollow+1];
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t *pabAmlCpu = &pabAmlDevName[4];
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync bool fCpuConfigured = false;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync bool fCpuFound = false;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if ((pabAmlDevName[0] != 'S') || (pabAmlDevName[1] != 'C') || (pabAmlDevName[2] != 'K'))
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* false alarm, not named starting SCK */
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync idxAml++;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync continue;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync for (uint32_t idxAmlCpu = 0; idxAmlCpu < cBytes - 7; idxAmlCpu++)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /*
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * AML_PROCESSOR_OP
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync *
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * DefProcessor := ProcessorOp PkgLength NameString ProcID
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync PblkAddr PblkLen ObjectList
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * ProcessorOp := ExtOpPrefix 0x83
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * ProcID := ByteData
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * PblkAddr := DwordData
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * PblkLen := ByteData
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if ((pabAmlCpu[idxAmlCpu] == 0x5b) && (pabAmlCpu[idxAmlCpu+1] == 0x83))
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if ((pabAmlCpu[idxAmlCpu+4] != 'C') || (pabAmlCpu[idxAmlCpu+5] != 'P'))
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* false alarm, not named starting CP */
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync continue;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync fCpuFound = true;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* Processor ID */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAmlCpu[idxAmlCpu+8] < cNumCpus)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync LogFlow(("CPU %d is configured\n", pabAmlCpu[idxAmlCpu+8]));
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync fCpuConfigured = true;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync break;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync else
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync LogFlow(("CPU %d is not configured\n", pabAmlCpu[idxAmlCpu+8]));
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync fCpuConfigured = false;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync break;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync Assert(fCpuFound);
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync if (!fCpuConfigured)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* Will fill unwanted CPU block with NOOPs */
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /*
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * See 18.2.4 Package Length Encoding in ACPI spec
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync * for full format
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync */
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* including AML_DEVICE_OP itself */
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync for (uint32_t j = 0; j < cBytes + 2; j++)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAml[idxAml+j] = 0xa3;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync idxAml++;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync else
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync idxAml++;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync /* now recompute checksum, whole file byte sum must be 0 */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAml[9] = 0;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t bSum = 0;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync for (uint32_t i = 0; i < cbAml; i++)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync bSum = bSum + pabAml[i];
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAml[9] = (uint8_t)(0 - bSum);
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync return 0;
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync}
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync#endif /* VBOX_WITH_DYNAMIC_DSDT */
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync/**
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync * Loads an AML file if present in CFGM
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync *
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync * @returns VBox status code
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync * @param pDevIns The device instance
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync * @param pcszCfgName The configuration key holding the file path
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync * @param pcszSignature The signature to check for
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync * @param ppabAmlCode Where to store the pointer to the AML code on success.
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync * @param pcbAmlCode Where to store the number of bytes of the AML code on success.
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncstatic int acpiAmlLoadExternal(PPDMDEVINS pDevIns, const char *pcszCfgName, const char *pcszSignature, uint8_t **ppabAmlCode, size_t *pcbAmlCode)
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync{
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t *pabAmlCode = NULL;
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync size_t cbAmlCode = 0;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync char *pszAmlFilePath = NULL;
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync int rc = CFGMR3QueryStringAlloc(pDevIns->pCfg, pcszCfgName, &pszAmlFilePath);
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync if (RT_SUCCESS(rc))
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync {
70e70d246c1b592db31d93071c48bb43ea61100evboxsync /* Load from file. */
70e70d246c1b592db31d93071c48bb43ea61100evboxsync RTFILE FileAml = NIL_RTFILE;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync rc = RTFileOpen(&FileAml, pszAmlFilePath, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
70e70d246c1b592db31d93071c48bb43ea61100evboxsync if (RT_SUCCESS(rc))
70e70d246c1b592db31d93071c48bb43ea61100evboxsync {
70e70d246c1b592db31d93071c48bb43ea61100evboxsync /*
70e70d246c1b592db31d93071c48bb43ea61100evboxsync * An AML file contains the raw DSDT thus the size of the file
70e70d246c1b592db31d93071c48bb43ea61100evboxsync * is equal to the size of the DSDT.
70e70d246c1b592db31d93071c48bb43ea61100evboxsync */
70e70d246c1b592db31d93071c48bb43ea61100evboxsync uint64_t cbAmlFile = 0;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync rc = RTFileGetSize(FileAml, &cbAmlFile);
70e70d246c1b592db31d93071c48bb43ea61100evboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync cbAmlCode = (size_t)cbAmlFile;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync /* Don't use AML files over 4GB ;) */
70e70d246c1b592db31d93071c48bb43ea61100evboxsync if ( RT_SUCCESS(rc)
70e70d246c1b592db31d93071c48bb43ea61100evboxsync && ((uint64_t)cbAmlCode == cbAmlFile))
70e70d246c1b592db31d93071c48bb43ea61100evboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAmlCode = (uint8_t *)RTMemAllocZ(cbAmlCode);
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAmlCode)
70e70d246c1b592db31d93071c48bb43ea61100evboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync rc = RTFileReadAt(FileAml, 0, pabAmlCode, cbAmlCode, NULL);
70e70d246c1b592db31d93071c48bb43ea61100evboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync /*
70e70d246c1b592db31d93071c48bb43ea61100evboxsync * We fail if reading failed or the identifier at the
70e70d246c1b592db31d93071c48bb43ea61100evboxsync * beginning is wrong.
70e70d246c1b592db31d93071c48bb43ea61100evboxsync */
70e70d246c1b592db31d93071c48bb43ea61100evboxsync if ( RT_FAILURE(rc)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync || strncmp((const char *)pabAmlCode, pcszSignature, 4))
70e70d246c1b592db31d93071c48bb43ea61100evboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync RTMemFree(pabAmlCode);
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAmlCode = NULL;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync /* Return error if file header check failed */
70e70d246c1b592db31d93071c48bb43ea61100evboxsync if (RT_SUCCESS(rc))
70e70d246c1b592db31d93071c48bb43ea61100evboxsync rc = VERR_PARSE_ERROR;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync }
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync else
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync *ppabAmlCode = pabAmlCode;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync *pcbAmlCode = cbAmlCode;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync rc = VINF_SUCCESS;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync }
70e70d246c1b592db31d93071c48bb43ea61100evboxsync }
70e70d246c1b592db31d93071c48bb43ea61100evboxsync else
70e70d246c1b592db31d93071c48bb43ea61100evboxsync rc = VERR_NO_MEMORY;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync }
70e70d246c1b592db31d93071c48bb43ea61100evboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync RTFileClose(FileAml);
70e70d246c1b592db31d93071c48bb43ea61100evboxsync }
70e70d246c1b592db31d93071c48bb43ea61100evboxsync MMR3HeapFree(pszAmlFilePath);
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync }
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync return rc;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync}
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync/** No docs, lazy coder. */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncint acpiPrepareDsdt(PPDMDEVINS pDevIns, void **ppvPtr, size_t *pcbDsdt)
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync{
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync#ifdef VBOX_WITH_DYNAMIC_DSDT
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync return prepareDynamicDsdt(pDevIns, ppvPtr, pcbDsdt);
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync#else
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t *pabAmlCodeDsdt = NULL;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync size_t cbAmlCodeDsdt = 0;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync int rc = acpiAmlLoadExternal(pDevIns, "DsdtFilePath", "DSDT", &pabAmlCodeDsdt, &cbAmlCodeDsdt);
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND)
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync {
70e70d246c1b592db31d93071c48bb43ea61100evboxsync rc = VINF_SUCCESS;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync /* Use the compiled in AML code */
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync cbAmlCodeDsdt = sizeof(AmlCode);
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAmlCodeDsdt = (uint8_t *)RTMemAllocZ(cbAmlCodeDsdt);
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAmlCodeDsdt)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync memcpy(pabAmlCodeDsdt, AmlCode, cbAmlCodeDsdt);
70e70d246c1b592db31d93071c48bb43ea61100evboxsync else
70e70d246c1b592db31d93071c48bb43ea61100evboxsync rc = VERR_NO_MEMORY;
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync }
70e70d246c1b592db31d93071c48bb43ea61100evboxsync else if (RT_FAILURE(rc))
70e70d246c1b592db31d93071c48bb43ea61100evboxsync return PDMDEV_SET_ERROR(pDevIns, rc,
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync N_("Configuration error: Failed to read \"DsdtFilePath\""));
eb90548e8e40e597d65cdcc16ec958a3e09c1d73vboxsync
70e70d246c1b592db31d93071c48bb43ea61100evboxsync if (RT_SUCCESS(rc))
70e70d246c1b592db31d93071c48bb43ea61100evboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync patchAml(pDevIns, pabAmlCodeDsdt, cbAmlCodeDsdt);
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync *ppvPtr = pabAmlCodeDsdt;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync *pcbDsdt = cbAmlCodeDsdt;
70e70d246c1b592db31d93071c48bb43ea61100evboxsync }
70e70d246c1b592db31d93071c48bb43ea61100evboxsync return rc;
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#endif
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync}
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync/** No docs, lazy coder. */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncint acpiCleanupDsdt(PPDMDEVINS pDevIns, void *pvPtr)
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync{
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#ifdef VBOX_WITH_DYNAMIC_DSDT
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync return cleanupDynamicDsdt(pDevIns, pvPtr);
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#else
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pvPtr)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync RTMemFree(pvPtr);
70e70d246c1b592db31d93071c48bb43ea61100evboxsync return VINF_SUCCESS;
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync#endif
7f8a04081173dbe3c72bddd0ffeb237e7f9070b0vboxsync}
616c4e73368513b3c835881ff9f2386083afad01vboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync/** No docs, lazy coder. */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncint acpiPrepareSsdt(PPDMDEVINS pDevIns, void **ppvPtr, size_t *pcbSsdt)
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync{
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t *pabAmlCodeSsdt = NULL;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync size_t cbAmlCodeSsdt = 0;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync int rc = acpiAmlLoadExternal(pDevIns, "SsdtFilePath", "SSDT", &pabAmlCodeSsdt, &cbAmlCodeSsdt);
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND)
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync {
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync bool fCpuHotPlug = false;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync uint8_t *pabAmlCode = NULL;
497a49aa22807122b7dd0bcab3bcdc43d3c479c2vboxsync rc = CFGMR3QueryBoolDef(pDevIns->pCfg, "CpuHotPlug", &fCpuHotPlug, false);
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync if (RT_FAILURE(rc))
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync return rc;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync if (fCpuHotPlug)
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAmlCode = AmlCodeSsdtCpuHotPlug;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync cbAmlCodeSsdt = sizeof(AmlCodeSsdtCpuHotPlug);
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync }
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync else
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAmlCode = AmlCodeSsdtStandard;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync cbAmlCodeSsdt = sizeof(AmlCodeSsdtStandard);
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync }
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync pabAmlCodeSsdt = (uint8_t *)RTMemAllocZ(cbAmlCodeSsdt);
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pabAmlCodeSsdt)
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync memcpy(pabAmlCodeSsdt, pabAmlCode, cbAmlCodeSsdt);
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync if (fCpuHotPlug)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync patchAmlCpuHotPlug(pDevIns, pabAmlCodeSsdt, cbAmlCodeSsdt);
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync else
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync patchAml(pDevIns, pabAmlCodeSsdt, cbAmlCodeSsdt);
dc5705c90aebb694bb66eea8f3ee7415afcf3828vboxsync }
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync else
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync rc = VERR_NO_MEMORY;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync }
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync else if (RT_FAILURE(rc))
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync return PDMDEV_SET_ERROR(pDevIns, rc,
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync N_("Configuration error: Failed to read \"SsdtFilePath\""));
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync if (RT_SUCCESS(rc))
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync {
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync *ppvPtr = pabAmlCodeSsdt;
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync *pcbSsdt = cbAmlCodeSsdt;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync }
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync return VINF_SUCCESS;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync}
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync/** No docs, lazy coder. */
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsyncint acpiCleanupSsdt(PPDMDEVINS pDevIns, void *pvPtr)
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync{
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync if (pvPtr)
70118d62d01079551f31eaf0a3b2227290ddf3eevboxsync RTMemFree(pvPtr);
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync return VINF_SUCCESS;
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync}
ec7708c74d7fc8feb18fbe1f84b320ec86fb11efvboxsync