1 | /* $Id: VBoxAcpi.cpp 108144 2025-02-10 14:54:04Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * VBoxAcpi - VirtualBox ACPI manipulation functionality.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2009-2024 Oracle and/or its affiliates.
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox base platform packages, as
|
---|
10 | * available from https://www.virtualbox.org.
|
---|
11 | *
|
---|
12 | * This program is free software; you can redistribute it and/or
|
---|
13 | * modify it under the terms of the GNU General Public License
|
---|
14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
15 | * License.
|
---|
16 | *
|
---|
17 | * This program is distributed in the hope that it will be useful, but
|
---|
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
20 | * General Public License for more details.
|
---|
21 | *
|
---|
22 | * You should have received a copy of the GNU General Public License
|
---|
23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
24 | *
|
---|
25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
26 | */
|
---|
27 |
|
---|
28 |
|
---|
29 | /*********************************************************************************************************************************
|
---|
30 | * Header Files *
|
---|
31 | *********************************************************************************************************************************/
|
---|
32 | #include <iprt/cdefs.h>
|
---|
33 | #if !defined(IN_RING3)
|
---|
34 | # error Pure R3 code
|
---|
35 | #endif
|
---|
36 |
|
---|
37 | #define LOG_GROUP LOG_GROUP_DEV_ACPI
|
---|
38 | #include <VBox/vmm/pdmdev.h>
|
---|
39 | #include <VBox/vmm/pgm.h>
|
---|
40 | #include <VBox/log.h>
|
---|
41 | #include <VBox/param.h>
|
---|
42 | #include <VBox/vmm/cfgm.h>
|
---|
43 | #include <VBox/vmm/mm.h>
|
---|
44 | #include <iprt/acpi.h>
|
---|
45 | #include <iprt/assert.h>
|
---|
46 | #include <iprt/alloc.h>
|
---|
47 | #include <iprt/buildconfig.h>
|
---|
48 | #include <iprt/string.h>
|
---|
49 | #include <iprt/file.h>
|
---|
50 |
|
---|
51 | /* Statically compiled AML */
|
---|
52 | #include <vboxaml.hex>
|
---|
53 | #ifdef VBOX_WITH_TPM
|
---|
54 | # include <vboxssdt_tpm.hex>
|
---|
55 | #endif
|
---|
56 |
|
---|
57 | #include "VBoxDD.h"
|
---|
58 |
|
---|
59 | /** The CPU suffixes being used for processor object names. */
|
---|
60 | static const char g_achCpuSuff[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
|
---|
61 |
|
---|
62 | /**
|
---|
63 | * Creates the SSDT exposing configured CPUs as processor objects.
|
---|
64 | *
|
---|
65 | * @returns VBox status code.
|
---|
66 | * @param pDevIns The PDM device instance data.
|
---|
67 | * @param ppabAml Where to store the pointer to the buffer containing the ACPI table on success.
|
---|
68 | * @param pcbAml Where to store the size of the ACPI table in bytes on success.
|
---|
69 | *
|
---|
70 | * @note This replaces the old vbox-standard.dsl which was patched accordingly.
|
---|
71 | */
|
---|
72 | static int acpiCreateCpuSsdt(PPDMDEVINS pDevIns, uint8_t **ppabAml, size_t *pcbAml)
|
---|
73 | {
|
---|
74 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
75 |
|
---|
76 | uint16_t cCpus;
|
---|
77 | int rc = pHlp->pfnCFGMQueryU16Def(pDevIns->pCfg, "NumCPUs", &cCpus, 1);
|
---|
78 | if (RT_FAILURE(rc))
|
---|
79 | return rc;
|
---|
80 |
|
---|
81 | bool fShowCpu;
|
---|
82 | rc = pHlp->pfnCFGMQueryBoolDef(pDevIns->pCfg, "ShowCpu", &fShowCpu, false);
|
---|
83 | if (RT_FAILURE(rc))
|
---|
84 | return rc;
|
---|
85 |
|
---|
86 | /* Don't expose any CPU object if we are not required to. */
|
---|
87 | if (!fShowCpu)
|
---|
88 | cCpus = 0;
|
---|
89 |
|
---|
90 | RTACPITBL hAcpiTbl;
|
---|
91 | rc = RTAcpiTblCreate(&hAcpiTbl, ACPI_TABLE_HDR_SIGNATURE_SSDT, 1, "VBOX ", "VBOXCPUT", 2, "VBOX", RTBldCfgRevision());
|
---|
92 | if (RT_SUCCESS(rc))
|
---|
93 | {
|
---|
94 | RTAcpiTblScopeStart(hAcpiTbl, "\\_PR");
|
---|
95 | for (uint16_t i = 0; i < cCpus; i++)
|
---|
96 | {
|
---|
97 | uint8_t const cCpuSuff = RT_ELEMENTS(g_achCpuSuff);
|
---|
98 | RTAcpiTblProcessorStartF(hAcpiTbl, i /*bProcId*/, 0 /*u32PBlkAddr*/, 0 /*cbPBlk*/, "CP%c%c",
|
---|
99 | i < cCpuSuff ? 'U' : 'V',
|
---|
100 | g_achCpuSuff[i % cCpuSuff]);
|
---|
101 | rc = RTAcpiTblProcessorFinalize(hAcpiTbl);
|
---|
102 | if (RT_FAILURE(rc))
|
---|
103 | break;
|
---|
104 | }
|
---|
105 | RTAcpiTblScopeFinalize(hAcpiTbl);
|
---|
106 |
|
---|
107 | rc = RTAcpiTblFinalize(hAcpiTbl);
|
---|
108 | if (RT_SUCCESS(rc))
|
---|
109 | {
|
---|
110 | rc = RTAcpiTblDumpToBufferA(hAcpiTbl, RTACPITBLTYPE_AML, ppabAml, pcbAml);
|
---|
111 | if (RT_FAILURE(rc))
|
---|
112 | rc = PDMDEV_SET_ERROR(pDevIns, rc, N_("ACPI error: Failed to dump CPU SSDT"));
|
---|
113 | }
|
---|
114 | else
|
---|
115 | rc = PDMDEV_SET_ERROR(pDevIns, rc, N_("ACPI error: Failed to finalize CPU SSDT"));
|
---|
116 |
|
---|
117 | RTAcpiTblDestroy(hAcpiTbl);
|
---|
118 | }
|
---|
119 | else
|
---|
120 | rc = PDMDEV_SET_ERROR(pDevIns, rc, N_("ACPI error: Failed to create CPU SSDT"));
|
---|
121 |
|
---|
122 | return rc;
|
---|
123 | }
|
---|
124 |
|
---|
125 |
|
---|
126 | /**
|
---|
127 | * Creates the SSDT exposing configured CPUs as processor objects - hotplug variant.
|
---|
128 | *
|
---|
129 | * @returns VBox status code.
|
---|
130 | * @param pDevIns The PDM device instance data.
|
---|
131 | * @param ppabAml Where to store the pointer to the buffer containing the ACPI table on success.
|
---|
132 | * @param pcbAml Where to store the size of the ACPI table in bytes on success.
|
---|
133 | *
|
---|
134 | * @note This replaces the old vbox-cpuhotplug.dsl which was patched accordingly.
|
---|
135 | */
|
---|
136 | static int acpiCreateCpuHotplugSsdt(PPDMDEVINS pDevIns, uint8_t **ppabAml, size_t *pcbAml)
|
---|
137 | {
|
---|
138 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
139 |
|
---|
140 | uint16_t cCpus;
|
---|
141 | int rc = pHlp->pfnCFGMQueryU16Def(pDevIns->pCfg, "NumCPUs", &cCpus, 1);
|
---|
142 | if (RT_FAILURE(rc))
|
---|
143 | return rc;
|
---|
144 |
|
---|
145 | RTACPITBL hAcpiTbl;
|
---|
146 | rc = RTAcpiTblCreate(&hAcpiTbl, ACPI_TABLE_HDR_SIGNATURE_SSDT, 1, "VBOX ", "VBOXCPUT", 2, "VBOX", RTBldCfgRevision());
|
---|
147 | if (RT_SUCCESS(rc))
|
---|
148 | {
|
---|
149 | uint8_t const cCpuSuff = RT_ELEMENTS(g_achCpuSuff);
|
---|
150 |
|
---|
151 | /* Declare externals */
|
---|
152 | RTAcpiTblIfStart(hAcpiTbl);
|
---|
153 | RTAcpiTblIntegerAppend(hAcpiTbl, 0);
|
---|
154 |
|
---|
155 | RTAcpiTblExternalAppend(hAcpiTbl, "CPUC", kAcpiObjType_Unknown, 0 /*cArgs*/);
|
---|
156 | RTAcpiTblExternalAppend(hAcpiTbl, "CPUL", kAcpiObjType_Unknown, 0 /*cArgs*/);
|
---|
157 | RTAcpiTblExternalAppend(hAcpiTbl, "CPEV", kAcpiObjType_Unknown, 0 /*cArgs*/);
|
---|
158 | RTAcpiTblExternalAppend(hAcpiTbl, "CPET", kAcpiObjType_Unknown, 0 /*cArgs*/);
|
---|
159 |
|
---|
160 | RTAcpiTblIfFinalize(hAcpiTbl);
|
---|
161 |
|
---|
162 | /* Define two helper methods. */
|
---|
163 |
|
---|
164 | /* CPCK(Arg0) -> Boolean - Checks whether the CPU identified by the given indes is locked. */
|
---|
165 | RTAcpiTblMethodStart(hAcpiTbl, "CPCK", 1 /*cArgs*/, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/);
|
---|
166 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Store);
|
---|
167 | RTAcpiTblArgOpAppend(hAcpiTbl, 0);
|
---|
168 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPUC");
|
---|
169 |
|
---|
170 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Return);
|
---|
171 | RTAcpiTblBinaryOpAppend(hAcpiTbl, kAcpiBinaryOp_LEqual);
|
---|
172 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPUL");
|
---|
173 | RTAcpiTblIntegerAppend(hAcpiTbl, 1);
|
---|
174 | RTAcpiTblMethodFinalize(hAcpiTbl);
|
---|
175 |
|
---|
176 | /* CPLO(Arg0) -> Nothing - Unlocks the CPU identified by the given index. */
|
---|
177 | RTAcpiTblMethodStart(hAcpiTbl, "CPLO", 1 /*cArgs*/, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/);
|
---|
178 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Store);
|
---|
179 | RTAcpiTblArgOpAppend(hAcpiTbl, 0);
|
---|
180 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPUL");
|
---|
181 | RTAcpiTblMethodFinalize(hAcpiTbl);
|
---|
182 |
|
---|
183 | /* Define all configured CPUs. */
|
---|
184 | RTAcpiTblScopeStart(hAcpiTbl, "\\_SB");
|
---|
185 | for (uint16_t i = 0; i < cCpus; i++)
|
---|
186 | {
|
---|
187 | RTAcpiTblDeviceStartF(hAcpiTbl, "SC%c%c", i < cCpuSuff ? 'K' : 'L', g_achCpuSuff[i % cCpuSuff]);
|
---|
188 |
|
---|
189 | RTAcpiTblNameAppend(hAcpiTbl, "_HID");
|
---|
190 | RTAcpiTblStringAppend(hAcpiTbl, "ACPI0004");
|
---|
191 | RTAcpiTblNameAppend(hAcpiTbl, "_UID");
|
---|
192 | RTAcpiTblStringAppendF(hAcpiTbl, "SCKCP%c%c", i < cCpuSuff ? 'U' : 'V', g_achCpuSuff[i % cCpuSuff]);
|
---|
193 |
|
---|
194 | RTAcpiTblProcessorStartF(hAcpiTbl, i /*bProcId*/, 0 /*u32PBlkAddr*/, 0 /*cbPBlk*/, "CP%c%c",
|
---|
195 | i < cCpuSuff ? 'U' : 'V',
|
---|
196 | g_achCpuSuff[i % cCpuSuff]);
|
---|
197 |
|
---|
198 | RTAcpiTblNameAppend(hAcpiTbl, "_HID");
|
---|
199 | RTAcpiTblStringAppend(hAcpiTbl, "ACPI0007");
|
---|
200 | RTAcpiTblNameAppend(hAcpiTbl, "_UID");
|
---|
201 | RTAcpiTblIntegerAppend(hAcpiTbl, i);
|
---|
202 | RTAcpiTblNameAppend(hAcpiTbl, "_PXM");
|
---|
203 | RTAcpiTblIntegerAppend(hAcpiTbl, 0);
|
---|
204 |
|
---|
205 | uint8_t abBufApic[8] = { 0x00, 0x08, (uint8_t)i, (uint8_t)i, 0, 0, 0, 0};
|
---|
206 | RTAcpiTblNameAppend(hAcpiTbl, "APIC");
|
---|
207 | RTAcpiTblBufferAppend(hAcpiTbl, &abBufApic[0], sizeof(abBufApic));
|
---|
208 |
|
---|
209 | /* _MAT Method. */
|
---|
210 | RTAcpiTblMethodStart(hAcpiTbl, "_MAT", 0 /*cArgs*/, RTACPI_METHOD_F_SERIALIZED, 0 /*uSyncLvl*/);
|
---|
211 | RTAcpiTblIfStart(hAcpiTbl);
|
---|
212 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPCK");
|
---|
213 | RTAcpiTblIntegerAppend(hAcpiTbl, i);
|
---|
214 |
|
---|
215 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Store);
|
---|
216 | RTAcpiTblIntegerAppend(hAcpiTbl, 1);
|
---|
217 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Index);
|
---|
218 | RTAcpiTblNameStringAppend(hAcpiTbl, "APIC");
|
---|
219 | RTAcpiTblIntegerAppend(hAcpiTbl, 4);
|
---|
220 | RTAcpiTblNullNameAppend(hAcpiTbl);
|
---|
221 |
|
---|
222 | RTAcpiTblIfFinalize(hAcpiTbl);
|
---|
223 | RTAcpiTblElseStart(hAcpiTbl);
|
---|
224 | RTAcpiTblElseFinalize(hAcpiTbl);
|
---|
225 |
|
---|
226 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Return);
|
---|
227 | RTAcpiTblNameStringAppend(hAcpiTbl, "APIC");
|
---|
228 | RTAcpiTblMethodFinalize(hAcpiTbl);
|
---|
229 |
|
---|
230 | /* _STA Method. */
|
---|
231 | RTAcpiTblMethodStart(hAcpiTbl, "_STA", 0 /*cArgs*/, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/);
|
---|
232 | RTAcpiTblIfStart(hAcpiTbl);
|
---|
233 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPCK");
|
---|
234 | RTAcpiTblIntegerAppend(hAcpiTbl, i);
|
---|
235 |
|
---|
236 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Return);
|
---|
237 | RTAcpiTblIntegerAppend(hAcpiTbl, 0xf);
|
---|
238 | RTAcpiTblIfFinalize(hAcpiTbl);
|
---|
239 | RTAcpiTblElseStart(hAcpiTbl);
|
---|
240 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Return);
|
---|
241 | RTAcpiTblIntegerAppend(hAcpiTbl, 0x0);
|
---|
242 | RTAcpiTblElseFinalize(hAcpiTbl);
|
---|
243 | RTAcpiTblMethodFinalize(hAcpiTbl);
|
---|
244 |
|
---|
245 | /* _EJ0 Method. */
|
---|
246 | RTAcpiTblMethodStart(hAcpiTbl, "_EJ0", 1 /*cArgs*/, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/);
|
---|
247 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPLO");
|
---|
248 | RTAcpiTblIntegerAppend(hAcpiTbl, i);
|
---|
249 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Return);
|
---|
250 | RTAcpiTblMethodFinalize(hAcpiTbl);
|
---|
251 |
|
---|
252 | RTAcpiTblProcessorFinalize(hAcpiTbl);
|
---|
253 |
|
---|
254 | rc = RTAcpiTblDeviceFinalize(hAcpiTbl);
|
---|
255 | if (RT_FAILURE(rc))
|
---|
256 | break;
|
---|
257 | }
|
---|
258 |
|
---|
259 | if (RT_SUCCESS(rc))
|
---|
260 | {
|
---|
261 | RTAcpiTblScopeFinalize(hAcpiTbl);
|
---|
262 |
|
---|
263 | /* Now the _GPE scope where event processing takes place. */
|
---|
264 | RTAcpiTblScopeStart(hAcpiTbl, "\\_GPE");
|
---|
265 | RTAcpiTblMethodStart(hAcpiTbl, "_L01", 0 /*cArgs*/, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/);
|
---|
266 |
|
---|
267 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Store);
|
---|
268 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPEV");
|
---|
269 | RTAcpiTblLocalOpAppend(hAcpiTbl, 0);
|
---|
270 |
|
---|
271 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Store);
|
---|
272 | RTAcpiTblNameStringAppend(hAcpiTbl, "CPET");
|
---|
273 | RTAcpiTblLocalOpAppend(hAcpiTbl, 1);
|
---|
274 |
|
---|
275 | for (uint16_t i = 0; i < cCpus; i++)
|
---|
276 | {
|
---|
277 | RTAcpiTblIfStart(hAcpiTbl);
|
---|
278 | RTAcpiTblBinaryOpAppend(hAcpiTbl, kAcpiBinaryOp_LEqual);
|
---|
279 | RTAcpiTblLocalOpAppend(hAcpiTbl, 0);
|
---|
280 | RTAcpiTblIntegerAppend(hAcpiTbl, i);
|
---|
281 |
|
---|
282 | RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Notify);
|
---|
283 | RTAcpiTblNameStringAppendF(hAcpiTbl, "\\_SB.SC%c%c.CP%c%c",
|
---|
284 | i < cCpuSuff ? 'K' : 'L',
|
---|
285 | g_achCpuSuff[i % cCpuSuff],
|
---|
286 | i < cCpuSuff ? 'U' : 'V',
|
---|
287 | g_achCpuSuff[i % cCpuSuff]);
|
---|
288 | RTAcpiTblLocalOpAppend(hAcpiTbl, 1);
|
---|
289 | rc = RTAcpiTblIfFinalize(hAcpiTbl);
|
---|
290 | if (RT_FAILURE(rc))
|
---|
291 | break;
|
---|
292 | }
|
---|
293 |
|
---|
294 | RTAcpiTblMethodFinalize(hAcpiTbl);
|
---|
295 | RTAcpiTblScopeFinalize(hAcpiTbl);
|
---|
296 | }
|
---|
297 |
|
---|
298 | rc = RTAcpiTblFinalize(hAcpiTbl);
|
---|
299 | if (RT_SUCCESS(rc))
|
---|
300 | {
|
---|
301 | rc = RTAcpiTblDumpToBufferA(hAcpiTbl, RTACPITBLTYPE_AML, ppabAml, pcbAml);
|
---|
302 | if (RT_FAILURE(rc))
|
---|
303 | rc = PDMDEV_SET_ERROR(pDevIns, rc, N_("ACPI error: Failed to dump CPU SSDT"));
|
---|
304 | }
|
---|
305 | else
|
---|
306 | rc = PDMDEV_SET_ERROR(pDevIns, rc, N_("ACPI error: Failed to finalize CPU SSDT"));
|
---|
307 |
|
---|
308 | RTAcpiTblDestroy(hAcpiTbl);
|
---|
309 | }
|
---|
310 | else
|
---|
311 | rc = PDMDEV_SET_ERROR(pDevIns, rc, N_("ACPI error: Failed to create CPU SSDT"));
|
---|
312 |
|
---|
313 | return rc;
|
---|
314 | }
|
---|
315 |
|
---|
316 |
|
---|
317 | /**
|
---|
318 | * Loads an AML file if present in CFGM
|
---|
319 | *
|
---|
320 | * @returns VBox status code
|
---|
321 | * @param pDevIns The device instance
|
---|
322 | * @param pcszCfgName The configuration key holding the file path
|
---|
323 | * @param pcszSignature The signature to check for
|
---|
324 | * @param ppabAmlCode Where to store the pointer to the AML code on success.
|
---|
325 | * @param pcbAmlCode Where to store the number of bytes of the AML code on success.
|
---|
326 | */
|
---|
327 | static int acpiAmlLoadExternal(PPDMDEVINS pDevIns, const char *pcszCfgName, const char *pcszSignature,
|
---|
328 | uint8_t **ppabAmlCode, size_t *pcbAmlCode)
|
---|
329 | {
|
---|
330 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
331 |
|
---|
332 | char *pszAmlFilePath = NULL;
|
---|
333 | int rc = pHlp->pfnCFGMQueryStringAlloc(pDevIns->pCfg, pcszCfgName, &pszAmlFilePath);
|
---|
334 | if (RT_SUCCESS(rc))
|
---|
335 | {
|
---|
336 | /* Load from file. */
|
---|
337 | RTFILE hFileAml = NIL_RTFILE;
|
---|
338 | rc = RTFileOpen(&hFileAml, pszAmlFilePath, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
|
---|
339 | if (RT_SUCCESS(rc))
|
---|
340 | {
|
---|
341 | /*
|
---|
342 | * An AML file contains the raw DSDT or SSDT thus the size of the file
|
---|
343 | * is equal to the size of the DSDT or SSDT.
|
---|
344 | */
|
---|
345 | uint64_t cbAmlFile = 0;
|
---|
346 | rc = RTFileQuerySize(hFileAml, &cbAmlFile);
|
---|
347 |
|
---|
348 | /* Don't use AML files over 32MiB. */
|
---|
349 | if ( RT_SUCCESS(rc)
|
---|
350 | && cbAmlFile <= _32M)
|
---|
351 | {
|
---|
352 | size_t const cbAmlCode = (size_t)cbAmlFile;
|
---|
353 | uint8_t *pabAmlCode = (uint8_t *)RTMemAllocZ(cbAmlCode);
|
---|
354 | if (pabAmlCode)
|
---|
355 | {
|
---|
356 | rc = RTFileReadAt(hFileAml, 0, pabAmlCode, cbAmlCode, NULL);
|
---|
357 |
|
---|
358 | /*
|
---|
359 | * We fail if reading failed or the identifier at the
|
---|
360 | * beginning is wrong.
|
---|
361 | */
|
---|
362 | if ( RT_FAILURE(rc)
|
---|
363 | || strncmp((const char *)pabAmlCode, pcszSignature, 4))
|
---|
364 | {
|
---|
365 | RTMemFree(pabAmlCode);
|
---|
366 | pabAmlCode = NULL;
|
---|
367 |
|
---|
368 | /* Return error if file header check failed */
|
---|
369 | if (RT_SUCCESS(rc))
|
---|
370 | rc = VERR_PARSE_ERROR;
|
---|
371 | }
|
---|
372 | else
|
---|
373 | {
|
---|
374 | *ppabAmlCode = pabAmlCode;
|
---|
375 | *pcbAmlCode = cbAmlCode;
|
---|
376 | rc = VINF_SUCCESS;
|
---|
377 | }
|
---|
378 | }
|
---|
379 | else
|
---|
380 | rc = VERR_NO_MEMORY;
|
---|
381 | }
|
---|
382 | else if (RT_SUCCESS(rc))
|
---|
383 | rc = VERR_OUT_OF_RANGE;
|
---|
384 |
|
---|
385 | RTFileClose(hFileAml);
|
---|
386 | }
|
---|
387 | PDMDevHlpMMHeapFree(pDevIns, pszAmlFilePath);
|
---|
388 | }
|
---|
389 |
|
---|
390 | return rc;
|
---|
391 | }
|
---|
392 |
|
---|
393 |
|
---|
394 | /** No docs, lazy coder. */
|
---|
395 | int acpiPrepareDsdt(PPDMDEVINS pDevIns, void **ppvPtr, size_t *pcbDsdt)
|
---|
396 | {
|
---|
397 | uint8_t *pabAmlCodeDsdt = NULL;
|
---|
398 | size_t cbAmlCodeDsdt = 0;
|
---|
399 | int rc = acpiAmlLoadExternal(pDevIns, "DsdtFilePath", "DSDT", &pabAmlCodeDsdt, &cbAmlCodeDsdt);
|
---|
400 | if (rc == VERR_CFGM_VALUE_NOT_FOUND)
|
---|
401 | {
|
---|
402 | /* Use the compiled in AML code */
|
---|
403 | cbAmlCodeDsdt = sizeof(AmlCode);
|
---|
404 | pabAmlCodeDsdt = (uint8_t *)RTMemDup(AmlCode, cbAmlCodeDsdt);
|
---|
405 | if (pabAmlCodeDsdt)
|
---|
406 | rc = VINF_SUCCESS;
|
---|
407 | else
|
---|
408 | rc = VERR_NO_MEMORY;
|
---|
409 | }
|
---|
410 | else if (RT_FAILURE(rc))
|
---|
411 | return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"DsdtFilePath\""));
|
---|
412 |
|
---|
413 | if (RT_SUCCESS(rc))
|
---|
414 | {
|
---|
415 | *ppvPtr = pabAmlCodeDsdt;
|
---|
416 | *pcbDsdt = cbAmlCodeDsdt;
|
---|
417 | }
|
---|
418 | return rc;
|
---|
419 | }
|
---|
420 |
|
---|
421 | /** No docs, lazy coder. */
|
---|
422 | int acpiCleanupDsdt(PPDMDEVINS pDevIns, void *pvPtr)
|
---|
423 | {
|
---|
424 | RT_NOREF1(pDevIns);
|
---|
425 | if (pvPtr)
|
---|
426 | RTMemFree(pvPtr);
|
---|
427 | return VINF_SUCCESS;
|
---|
428 | }
|
---|
429 |
|
---|
430 | /** No docs, lazy coder. */
|
---|
431 | int acpiPrepareSsdt(PPDMDEVINS pDevIns, void **ppvPtr, size_t *pcbSsdt)
|
---|
432 | {
|
---|
433 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
434 |
|
---|
435 | uint8_t *pabAmlCodeSsdt = NULL;
|
---|
436 | size_t cbAmlCodeSsdt = 0;
|
---|
437 | int rc = acpiAmlLoadExternal(pDevIns, "SsdtFilePath", "SSDT", &pabAmlCodeSsdt, &cbAmlCodeSsdt);
|
---|
438 | if (rc == VERR_CFGM_VALUE_NOT_FOUND)
|
---|
439 | {
|
---|
440 | bool fCpuHotPlug = false;
|
---|
441 | rc = pHlp->pfnCFGMQueryBoolDef(pDevIns->pCfg, "CpuHotPlug", &fCpuHotPlug, false);
|
---|
442 | if (RT_SUCCESS(rc))
|
---|
443 | {
|
---|
444 | if (fCpuHotPlug)
|
---|
445 | rc = acpiCreateCpuHotplugSsdt(pDevIns, &pabAmlCodeSsdt, &cbAmlCodeSsdt);
|
---|
446 | else
|
---|
447 | rc = acpiCreateCpuSsdt(pDevIns, &pabAmlCodeSsdt, &cbAmlCodeSsdt);
|
---|
448 | }
|
---|
449 | }
|
---|
450 | else if (RT_FAILURE(rc))
|
---|
451 | return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"SsdtFilePath\""));
|
---|
452 |
|
---|
453 | if (RT_SUCCESS(rc))
|
---|
454 | {
|
---|
455 | *ppvPtr = pabAmlCodeSsdt;
|
---|
456 | *pcbSsdt = cbAmlCodeSsdt;
|
---|
457 | }
|
---|
458 | return rc;
|
---|
459 | }
|
---|
460 |
|
---|
461 | /** No docs, lazy coder. */
|
---|
462 | int acpiCleanupSsdt(PPDMDEVINS pDevIns, void *pvPtr)
|
---|
463 | {
|
---|
464 | RT_NOREF1(pDevIns);
|
---|
465 | if (pvPtr)
|
---|
466 | RTMemFree(pvPtr);
|
---|
467 | return VINF_SUCCESS;
|
---|
468 | }
|
---|
469 |
|
---|
470 | #ifdef VBOX_WITH_TPM
|
---|
471 | /** No docs, lazy coder. */
|
---|
472 | int acpiPrepareTpmSsdt(PPDMDEVINS pDevIns, void **ppvPtr, size_t *pcbSsdt)
|
---|
473 | {
|
---|
474 | uint8_t *pabAmlCodeSsdt = NULL;
|
---|
475 | size_t cbAmlCodeSsdt = 0;
|
---|
476 | int rc = acpiAmlLoadExternal(pDevIns, "SsdtTpmFilePath", "SSDT", &pabAmlCodeSsdt, &cbAmlCodeSsdt);
|
---|
477 | if (rc == VERR_CFGM_VALUE_NOT_FOUND)
|
---|
478 | {
|
---|
479 | rc = VINF_SUCCESS;
|
---|
480 | cbAmlCodeSsdt = sizeof(AmlCodeSsdtTpm);
|
---|
481 | pabAmlCodeSsdt = (uint8_t *)RTMemDup(AmlCodeSsdtTpm, sizeof(AmlCodeSsdtTpm));
|
---|
482 | if (!pabAmlCodeSsdt)
|
---|
483 | rc = VERR_NO_MEMORY;
|
---|
484 | }
|
---|
485 | else if (RT_FAILURE(rc))
|
---|
486 | return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"SsdtFilePath\""));
|
---|
487 |
|
---|
488 | if (RT_SUCCESS(rc))
|
---|
489 | {
|
---|
490 | *ppvPtr = pabAmlCodeSsdt;
|
---|
491 | *pcbSsdt = cbAmlCodeSsdt;
|
---|
492 | }
|
---|
493 | return rc;
|
---|
494 | }
|
---|
495 |
|
---|
496 | /** No docs, lazy coder. */
|
---|
497 | int acpiCleanupTpmSsdt(PPDMDEVINS pDevIns, void *pvPtr)
|
---|
498 | {
|
---|
499 | RT_NOREF1(pDevIns);
|
---|
500 | if (pvPtr)
|
---|
501 | RTMemFree(pvPtr);
|
---|
502 | return VINF_SUCCESS;
|
---|
503 | }
|
---|
504 | #endif
|
---|