VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/SystemTableBuilder.cpp@ 109067

Last change on this file since 109067 was 108749, checked in by vboxsync, 6 weeks ago

Main: bugref:10877 Dont' add the ACPI MADT entry for the GIC ITS if it isn't enabled for the VM.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 61.3 KB
Line 
1/* $Id: SystemTableBuilder.cpp 108749 2025-03-26 08:44:50Z vboxsync $ */
2/** @file
3 * VirtualBox bus slots assignment manager
4 */
5
6/*
7 * Copyright (C) 2010-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#define LOG_GROUP LOG_GROUP_MAIN
33#include "LoggingNew.h"
34
35#include "SystemTableBuilder.h"
36
37#include <VBox/gic.h>
38
39#include <iprt/asm.h>
40#include <iprt/string.h>
41
42
43/*********************************************************************************************************************************
44* Defined Constants And Macros *
45*********************************************************************************************************************************/
46
47/** Locality CRB request register. */
48#define TPM_CRB_LOCALITY_REG_CTRL_REQ 0x40
49
50
51/*********************************************************************************************************************************
52* Structures and Typedefs *
53*********************************************************************************************************************************/
54/**
55 * A system table device.
56 */
57typedef struct SYSTEMTABLEDEVICE
58{
59 const char *pszVBoxName;
60 const char *pszFdtName;
61 const char *pszFdtCompatible;
62 const char *pszAcpiName;
63 const char *pszAcpiHid;
64 bool fEisaId;
65} SYSTEMTABLEDEVICE;
66typedef SYSTEMTABLEDEVICE *PSYSTEMTABLEDEVICE;
67typedef const SYSTEMTABLEDEVICE *PCSYSTEMTABLEDEVICE;
68
69
70/*********************************************************************************************************************************
71* Global Variables *
72*********************************************************************************************************************************/
73static const SYSTEMTABLEDEVICE g_aSysTblDevices[] =
74{
75 { "qemu-fw-cfg", "fw-cfg", "qemu,fw-cfg-mmio", "FWC", "QEMU0002", false },
76 { "arm-pl011", "pl011", "arm,pl011", "SRL", "ARMH0011", false },
77 { "arm-pl061-gpio", "pl061", "arm,pl061", "GPI", "ARMH0061", false },
78 { "pci-generic-ecam", "pcie", "pci-host-ecam-generic", "PCI", "PNP0A08", true },
79};
80
81
82static PCSYSTEMTABLEDEVICE systemTableVBoxDevName2SysTblDevice(const char *pszVBoxName)
83{
84 for (uint32_t i = 0; i < RT_ELEMENTS(g_aSysTblDevices); i++)
85 if (!strcmp(pszVBoxName, g_aSysTblDevices[i].pszVBoxName))
86 return &g_aSysTblDevices[i];
87
88 return NULL;
89}
90
91
92static int systemTableAcpiMmioDevResource(RTACPITBL hDsdt, RTACPIRES hAcpiRes, uint64_t u64AddrBase,
93 uint64_t cbMmio, uint32_t uIrq)
94{
95 uint32_t const fAddrSpace = RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_POS
96 | RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_FIXED
97 | RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_FIXED
98 | RTACPI_RESOURCE_ADDR_RANGE_F_PRODUCER;
99
100 RTAcpiResourceReset(hAcpiRes);
101 int vrc;
102 if (u64AddrBase + cbMmio <= _4G)
103 vrc = RTAcpiResourceAdd32BitFixedMemoryRange(hAcpiRes, u64AddrBase, cbMmio, true /*fRw*/);
104 else
105 vrc = RTAcpiResourceAddQWordMemoryRange(hAcpiRes, kAcpiResMemRangeCacheability_NonCacheable, kAcpiResMemType_Memory, true /*fRw*/,
106 fAddrSpace, u64AddrBase, u64AddrBase + cbMmio - 1, 0 /*u64OffTrans*/, 0 /*u64Granularity*/,
107 cbMmio);
108 if (RT_SUCCESS(vrc))
109 vrc = RTAcpiResourceAddExtendedInterrupt(hAcpiRes, true /*fConsumer*/, false /*fEdgeTriggered*/, false /*fActiveLow*/,
110 false /*fShared*/, false /*fWakeCapable*/, 1, &uIrq);
111 if (RT_SUCCESS(vrc))
112 {
113 vrc = RTAcpiResourceSeal(hAcpiRes);
114 if (RT_SUCCESS(vrc))
115 vrc = RTAcpiTblResourceAppend(hDsdt, hAcpiRes);
116 }
117
118 return vrc;
119}
120
121
122static int systemTableAcpiMmioDevResourceNoIrq(RTACPITBL hDsdt, RTACPIRES hAcpiRes, uint64_t u64AddrBase,
123 uint64_t cbMmio)
124{
125 uint32_t const fAddrSpace = RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_POS
126 | RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_FIXED
127 | RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_FIXED
128 | RTACPI_RESOURCE_ADDR_RANGE_F_PRODUCER;
129
130 RTAcpiResourceReset(hAcpiRes);
131 int vrc = RTAcpiResourceAddQWordMemoryRange(hAcpiRes, kAcpiResMemRangeCacheability_NonCacheable, kAcpiResMemType_Memory, true /*fRw*/,
132 fAddrSpace, u64AddrBase, u64AddrBase + cbMmio - 1, 0 /*u64OffTrans*/, 0 /*u64Granularity*/,
133 cbMmio);
134 if (RT_SUCCESS(vrc))
135 {
136 vrc = RTAcpiResourceSeal(hAcpiRes);
137 if (RT_SUCCESS(vrc))
138 vrc = RTAcpiTblResourceAppend(hDsdt, hAcpiRes);
139 }
140
141 return vrc;
142}
143
144
145int SystemTableBuilderAcpi::initInstance(void)
146{
147 m_fTpm20 = false;
148
149 int vrc = RTAcpiTblCreate(&m_hAcpiDsdt, ACPI_TABLE_HDR_SIGNATURE_DSDT, 6, "ORCL ", "VBOXDSDT", 1, "VBOX", 1);
150 AssertRCReturn(vrc, vrc);
151
152 vrc = RTAcpiResourceCreate(&m_hAcpiRes);
153 AssertRCReturn(vrc, vrc);
154
155 /* Append _SB Scope. */
156 return RTAcpiTblScopeStart(m_hAcpiDsdt, "\\_SB");
157}
158
159
160int SystemTableBuilderAcpi::finishTables(RTGCPHYS GCPhysTblsStart, RTVFSIOSTREAM hVfsIos,
161 PRTGCPHYS pGCPhysTblRoot, size_t *pcbTblRoot, size_t *pcbTbls)
162{
163 int vrc = RTAcpiTblScopeFinalize(m_hAcpiDsdt); /* End \_SB scope */
164 AssertRCReturn(vrc, vrc);
165
166 vrc = RTAcpiTblFinalize(m_hAcpiDsdt);
167 AssertRCReturn(vrc, vrc);
168
169 RTGCPHYS GCPhysDsdt = GCPhysTblsStart;
170
171 size_t cbAcpiTbls = RTAcpiTblGetSize(m_hAcpiDsdt);
172 Assert(cbAcpiTbls);
173
174 /* Write the DSDT. */
175 vrc = RTAcpiTblDumpToVfsIoStrm(m_hAcpiDsdt, RTACPITBLTYPE_AML, hVfsIos);
176 AssertRCReturn(vrc, vrc);
177
178 GCPhysTblsStart += cbAcpiTbls;
179
180 uint32_t cTbls = 0;
181 uint8_t abXsdt[36 + 32 * sizeof(uint64_t)]; RT_ZERO(abXsdt);
182 PACPIXSDT pXsdt = (PACPIXSDT)&abXsdt[0];
183
184 /* Build the FADT. */
185 size_t cbTbl = 0;
186 vrc = buildFadt(hVfsIos, GCPhysDsdt, &cbTbl);
187 AssertRCReturn(vrc, vrc);
188
189 pXsdt->au64AddrTbl[cTbls++] = GCPhysTblsStart;
190 cbAcpiTbls += cbTbl;
191 GCPhysTblsStart += cbTbl;
192
193 /* Build the GTDT. */
194 vrc = buildGtdt(hVfsIos, &cbTbl);
195 AssertRCReturn(vrc, vrc);
196
197 pXsdt->au64AddrTbl[cTbls++] = GCPhysTblsStart;
198 cbAcpiTbls += cbTbl;
199 GCPhysTblsStart += cbTbl;
200
201 /* Build the MADT. */
202 vrc = buildMadt(hVfsIos, &cbTbl);
203 AssertRCReturn(vrc, vrc);
204
205 pXsdt->au64AddrTbl[cTbls++] = GCPhysTblsStart;
206 cbAcpiTbls += cbTbl;
207 GCPhysTblsStart += cbTbl;
208
209 /* Build the MCFG. */
210 vrc = buildMcfg(hVfsIos, &cbTbl);
211 AssertRCReturn(vrc, vrc);
212
213 pXsdt->au64AddrTbl[cTbls++] = GCPhysTblsStart;
214 cbAcpiTbls += cbTbl;
215 GCPhysTblsStart += cbTbl;
216
217 /* Build TPM2 table if configured. */
218 if (m_fTpm20)
219 {
220 vrc = buildTpm20(hVfsIos, &cbTbl);
221 AssertRCReturn(vrc, vrc);
222
223 pXsdt->au64AddrTbl[cTbls++] = GCPhysTblsStart;
224 cbAcpiTbls += cbTbl;
225 GCPhysTblsStart += cbTbl;
226 }
227
228 /* Build XSDT. */
229 RTGCPHYS GCPhysXsdt = GCPhysTblsStart;
230 size_t const cbXsdt = RT_UOFFSETOF_DYN(ACPIXSDT, au64AddrTbl[cTbls]);
231 pXsdt->Hdr.u32Signature = ACPI_TABLE_HDR_SIGNATURE_XSDT;
232 pXsdt->Hdr.cbTbl = RT_UOFFSETOF_DYN(ACPIXSDT, au64AddrTbl[cTbls]);
233 pXsdt->Hdr.bRevision = 6;
234 pXsdt->Hdr.bChkSum = 0;
235 pXsdt->Hdr.u32OemRevision = 1;
236 pXsdt->Hdr.u32CreatorRevision = 1;
237
238 memcpy(&pXsdt->Hdr.abOemId[0], "ORCLVB", 6);
239 memcpy(&pXsdt->Hdr.abOemTblId[0], "ORCL", 4);
240 memcpy(&pXsdt->Hdr.abOemTblId[4], &pXsdt->Hdr.u32Signature, 4);
241 memcpy(&pXsdt->Hdr.abCreatorId[0], "ORCL", 4);
242 RTAcpiTblHdrChecksumGenerate(&pXsdt->Hdr, cbXsdt);
243 vrc = RTVfsIoStrmWrite(hVfsIos, &abXsdt[0], cbXsdt, true /*fBlocking*/, NULL /*pcbWritten*/);
244 AssertRCReturn(vrc, vrc);
245
246 GCPhysTblsStart += cbXsdt;
247 cbAcpiTbls += cbXsdt;
248
249 /* Build XSDP */
250 ACPIRSDP Xsdp; RT_ZERO(Xsdp);
251
252 /* ACPI 1.0 part (RSDP) */
253 memcpy(Xsdp.abSignature, "RSD PTR ", 8);
254 memcpy(Xsdp.abOemId, "ORCLVB", 6);
255 Xsdp.bRevision = 3;
256 Xsdp.u32AddrRsdt = 0;
257 Xsdp.bChkSum = RTAcpiChecksumGenerate(&Xsdp, RT_OFFSETOF(ACPIRSDP, cbRsdp));
258
259 /* ACPI 2.0 part (XSDP) */
260 Xsdp.cbRsdp = RT_H2LE_U32(sizeof(ACPIRSDP));
261 Xsdp.u64AddrXsdt = RT_H2LE_U64(GCPhysXsdt);
262 Xsdp.bExtChkSum = RTAcpiChecksumGenerate(&Xsdp, sizeof(ACPIRSDP));
263
264 vrc = RTVfsIoStrmWrite(hVfsIos, &Xsdp, sizeof(Xsdp), true /*fBlocking*/, NULL /*pcbWritten*/);
265 AssertRCReturn(vrc, vrc);
266 cbAcpiTbls += sizeof(Xsdp);
267
268 *pGCPhysTblRoot = GCPhysTblsStart;
269 *pcbTblRoot = sizeof(Xsdp);
270 *pcbTbls = cbAcpiTbls;
271
272 return VINF_SUCCESS;
273}
274
275
276int SystemTableBuilderAcpi::addCpu(uint32_t idCpu)
277{
278 RTAcpiTblDeviceStartF(m_hAcpiDsdt, "CP%02RX32", idCpu);
279
280 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
281 RTAcpiTblStringAppend(m_hAcpiDsdt, "ACPI0007");
282
283 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
284 RTAcpiTblIntegerAppend(m_hAcpiDsdt, idCpu);
285
286 return RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
287}
288
289
290int SystemTableBuilderAcpi::addMemory(RTGCPHYS GCPhysStart, RTGCPHYS cbMem)
291{
292 RT_NOREF(GCPhysStart, cbMem);
293 return VINF_SUCCESS;
294}
295
296
297int SystemTableBuilderAcpi::addMmioDeviceNoIrq(const char *pszVBoxName, uint32_t uInstance, RTGCPHYS GCPhysMmio, RTGCPHYS cbMmio)
298{
299 PCSYSTEMTABLEDEVICE pSysTblDev = systemTableVBoxDevName2SysTblDevice(pszVBoxName);
300 AssertPtrReturn(pSysTblDev, VERR_NOT_FOUND);
301
302 RTAcpiTblDeviceStartF(m_hAcpiDsdt, "%s%RX32", pSysTblDev->pszAcpiName, uInstance);
303
304 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
305 if (pSysTblDev->fEisaId)
306 RTAcpiTblEisaIdAppend(m_hAcpiDsdt, pSysTblDev->pszAcpiHid);
307 else
308 RTAcpiTblStringAppend(m_hAcpiDsdt, pSysTblDev->pszAcpiHid);
309
310 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
311 RTAcpiTblIntegerAppend(m_hAcpiDsdt, uInstance);
312
313 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CRS");
314 int vrc = systemTableAcpiMmioDevResourceNoIrq(m_hAcpiDsdt, m_hAcpiRes, GCPhysMmio, cbMmio);
315 AssertRCReturn(vrc, vrc);
316
317 return RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
318}
319
320
321int SystemTableBuilderAcpi::addMmioDevice(const char *pszVBoxName, uint32_t uInstance, RTGCPHYS GCPhysMmio, RTGCPHYS cbMmio,
322 uint32_t u32Irq)
323{
324 PCSYSTEMTABLEDEVICE pSysTblDev = systemTableVBoxDevName2SysTblDevice(pszVBoxName);
325 AssertPtrReturn(pSysTblDev, VERR_NOT_FOUND);
326
327 RTAcpiTblDeviceStartF(m_hAcpiDsdt, "%s%RX32", pSysTblDev->pszAcpiName, uInstance);
328
329 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
330 if (pSysTblDev->fEisaId)
331 RTAcpiTblEisaIdAppend(m_hAcpiDsdt, pSysTblDev->pszAcpiHid);
332 else
333 RTAcpiTblStringAppend(m_hAcpiDsdt, pSysTblDev->pszAcpiHid);
334
335 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
336 RTAcpiTblIntegerAppend(m_hAcpiDsdt, uInstance);
337
338 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CRS");
339 int vrc = systemTableAcpiMmioDevResource(m_hAcpiDsdt, m_hAcpiRes, GCPhysMmio, cbMmio, u32Irq + GIC_INTID_RANGE_SPI_START);
340 AssertRCReturn(vrc, vrc);
341
342 return RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
343}
344
345
346int SystemTableBuilderAcpi::configureGic(uint32_t cCpus, RTGCPHYS GCPhysIntcDist, RTGCPHYS cbMmioIntcDist, RTGCPHYS GCPhysIntcReDist,
347 RTGCPHYS cbMmioIntcReDist, RTGCPHYS GCPhysIntcIts, RTGCPHYS cbMmioIntcIts)
348{
349 m_cCpus = cCpus;
350 m_GCPhysIntcDist = GCPhysIntcDist;
351 m_cbMmioIntcDist = cbMmioIntcDist;
352 m_GCPhysIntcReDist = GCPhysIntcReDist;
353 m_cbMmioIntcReDist = cbMmioIntcReDist;
354 m_GCPhysIntcIts = GCPhysIntcIts;
355 m_cbMmioIntcIts = cbMmioIntcIts;
356 return VINF_SUCCESS;
357}
358
359
360int SystemTableBuilderAcpi::configureClock(void)
361{
362 return VINF_SUCCESS;
363}
364
365
366int SystemTableBuilderAcpi::configurePcieRootBus(const char *pszVBoxName, uint32_t aPinIrqs[4], RTGCPHYS GCPhysMmioPio, RTGCPHYS GCPhysMmioEcam, size_t cbPciMmioEcam,
367 RTGCPHYS GCPhysPciMmioBase, RTGCPHYS cbPciMmio, RTGCPHYS GCPhysPciMmio32Base, RTGCPHYS cbPciMmio32)
368{
369 PCSYSTEMTABLEDEVICE pSysTblDev = systemTableVBoxDevName2SysTblDevice(pszVBoxName);
370 AssertPtrReturn(pSysTblDev, VERR_NOT_FOUND);
371
372 m_GCPhysPciMmioEcam = GCPhysMmioEcam; /* Need that for MCFG later. */
373 m_bPciBusMax = 15; /** @todo Make parameter. */
374
375 RTAcpiTblDeviceStartF(m_hAcpiDsdt, "%s%RX32", pSysTblDev->pszAcpiName, 0);
376
377 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
378 RTAcpiTblStringAppend(m_hAcpiDsdt, pSysTblDev->pszAcpiHid);
379
380 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CID");
381 RTAcpiTblEisaIdAppend(m_hAcpiDsdt, "PNP0A03");
382
383 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
384 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
385
386 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CCA"); /* Cache coherency attribute. */
387 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
388
389 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CRS");
390
391 uint32_t const fAddrSpace = RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_POS
392 | RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_FIXED
393 | RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_FIXED
394 | RTACPI_RESOURCE_ADDR_RANGE_F_PRODUCER;
395
396 RTAcpiResourceReset(m_hAcpiRes);
397 int vrc = RTAcpiResourceAddWordBusNumber(m_hAcpiRes, fAddrSpace, 0 /*u16BusMin*/, m_bPciBusMax /*u16BusMax*/,
398 0 /*u16OffTrans*/, 0 /*u16Granularity*/, m_bPciBusMax + 1 /*u16Length*/);
399 AssertRCReturn(vrc, vrc);
400
401 vrc = RTAcpiResourceAddQWordIoRange(m_hAcpiRes, kAcpiResIoRangeType_Translation_Dense, kAcpiResIoRange_Whole,
402 fAddrSpace, 0 /*u64AddrMin*/, UINT16_MAX /*u64AddrMax*/, GCPhysMmioPio,
403 0 /*u64Granularity*/, _64K);
404 AssertRCReturn(vrc, vrc);
405
406 vrc = RTAcpiResourceAddDWordMemoryRange(m_hAcpiRes, kAcpiResMemRangeCacheability_NonCacheable, kAcpiResMemType_Memory, true /*fRw*/,
407 fAddrSpace, (uint32_t)GCPhysPciMmio32Base, (uint32_t)(GCPhysPciMmio32Base + cbPciMmio32 - 1),
408 0 /*u32OffTrans*/, 0 /*u32Granularity*/, (uint32_t)cbPciMmio32);
409 AssertRCReturn(vrc, vrc);
410
411 vrc = RTAcpiResourceAddQWordMemoryRange(m_hAcpiRes, kAcpiResMemRangeCacheability_NonCacheable, kAcpiResMemType_Memory, true /*fRw*/,
412 fAddrSpace, GCPhysPciMmioBase, GCPhysPciMmioBase + cbPciMmio - 1,
413 0 /*u64OffTrans*/, 0 /*u64Granularity*/, cbPciMmio);
414 if (RT_SUCCESS(vrc))
415 {
416 vrc = RTAcpiResourceSeal(m_hAcpiRes);
417 if (RT_SUCCESS(vrc))
418 vrc = RTAcpiTblResourceAppend(m_hAcpiDsdt, m_hAcpiRes);
419 }
420 AssertRCReturn(vrc, vrc);
421
422 /* For the ECAM base we need to define a new device with a new resource template inside the PCI device. */
423 RTAcpiTblDeviceStart(m_hAcpiDsdt, "RES0");
424
425 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
426 RTAcpiTblEisaIdAppend(m_hAcpiDsdt, "PNP0C02");
427
428 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CRS");
429 RTAcpiResourceReset(m_hAcpiRes);
430 vrc = RTAcpiResourceAddQWordMemoryRange(m_hAcpiRes, kAcpiResMemRangeCacheability_NonCacheable, kAcpiResMemType_Memory, true /*fRw*/,
431 fAddrSpace, GCPhysMmioEcam, GCPhysMmioEcam + cbPciMmioEcam - 1,
432 0 /*u64OffTrans*/, 0 /*u64Granularity*/, cbPciMmioEcam);
433 if (RT_SUCCESS(vrc))
434 {
435 vrc = RTAcpiResourceSeal(m_hAcpiRes);
436 if (RT_SUCCESS(vrc))
437 vrc = RTAcpiTblResourceAppend(m_hAcpiDsdt, m_hAcpiRes);
438 }
439 AssertRCReturn(vrc, vrc);
440
441 /* Finish RES0 device. */
442 vrc = RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
443 AssertRCReturn(vrc, vrc);
444
445 /* Build the PCI interrupt routing table (_PRT). */
446 RTAcpiTblNameAppend(m_hAcpiDsdt, "_PRT");
447 RTAcpiTblPackageStart(m_hAcpiDsdt, 32 * 4);
448
449 uint32_t iIrqPinSwizzle = 0;
450
451 for (uint32_t i = 0; i < 32; i++)
452 {
453 for (uint32_t iIrqPin = 0; iIrqPin < 4; iIrqPin++)
454 {
455 RTAcpiTblPackageStart(m_hAcpiDsdt, 4);
456 RTAcpiTblIntegerAppend(m_hAcpiDsdt, (i << 16) | 0xffff); /* ACPI PCI address. */
457 RTAcpiTblIntegerAppend(m_hAcpiDsdt, iIrqPin); /* Interrupt pin (INTA, INTB, ...). */
458 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Interrupt destination, unused. */
459 RTAcpiTblIntegerAppend(m_hAcpiDsdt, GIC_INTID_RANGE_SPI_START
460 + aPinIrqs[(iIrqPinSwizzle + iIrqPin) % 4]); /* GSI of the interrupt. */
461 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
462 }
463
464 iIrqPinSwizzle++;
465 }
466
467 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
468
469 /* Create _CBA for the ECAM base. */
470 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CBA");
471 RTAcpiTblIntegerAppend(m_hAcpiDsdt, GCPhysMmioEcam);
472
473 return RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
474}
475
476
477int SystemTableBuilderAcpi::dumpTables(const char *pszFilename)
478{
479 return RTAcpiTblDumpToFile(m_hAcpiDsdt, RTACPITBLTYPE_AML, pszFilename);
480}
481
482
483int SystemTableBuilderAcpi::buildMadt(RTVFSIOSTREAM hVfsIos, size_t *pcbMadt)
484{
485 uint8_t abMadt[_4K];
486 uint32_t cbMadt = 0;
487
488 RT_ZERO(abMadt);
489
490 PACPIMADT pMadt = (PACPIMADT)&abMadt[0];
491 PACPIMADTGICC pGicc = (PACPIMADTGICC)(pMadt + 1);
492
493 cbMadt += sizeof(*pMadt);
494
495 /* Include a GIC CPU interface for each CPU. */
496 for (uint32_t i = 0; i < m_cCpus; i++)
497 {
498 pGicc->bType = ACPI_MADT_INTR_CTRL_TYPE_GICC;
499 pGicc->cbThis = sizeof(*pGicc);
500 pGicc->u32CpuId = i;
501 pGicc->u32AcpiCpuUid = i;
502 pGicc->fGicc = ACPI_MADT_GICC_F_ENABLED;
503 pGicc->u64Mpidr = i;
504
505 cbMadt += sizeof(*pGicc);
506 pGicc++;
507 }
508
509 /* Build the GICD. */
510 PACPIMADTGICD pGicd = (PACPIMADTGICD)pGicc;
511 pGicd->bType = ACPI_MADT_INTR_CTRL_TYPE_GICD;
512 pGicd->cbThis = sizeof(*pGicd);
513 pGicd->u64PhysAddrBase = m_GCPhysIntcDist;
514 pGicd->bGicVersion = ACPI_MADT_GICD_VERSION_GICv3;
515
516 cbMadt += sizeof(*pGicd);
517
518 /* Build the GICR. */
519 PACPIMADTGICR pGicr = (PACPIMADTGICR)(pGicd + 1);
520 pGicr->bType = ACPI_MADT_INTR_CTRL_TYPE_GICR;
521 pGicr->cbThis = sizeof(*pGicr);
522 pGicr->u64PhysAddrGicrRangeBase = m_GCPhysIntcReDist;
523 pGicr->cbGicrRange = m_cbMmioIntcReDist;
524
525 cbMadt += sizeof(*pGicr);
526
527 /* Build the GITS only if it's enabled for the VM. */
528 if (m_GCPhysIntcIts)
529 {
530 Assert(m_cbMmioIntcIts > 0);
531 Assert(m_GCPhysIntcIts != NIL_RTGCPHYS);
532 PACPIMADTGICITS pGits = (PACPIMADTGICITS)(pGicr + 1);
533 pGits->bType = ACPI_MADT_INTR_CTRL_TYPE_GIC_ITS;
534 pGits->cbThis = sizeof(*pGits);
535 pGits->u64PhysAddrBase = m_GCPhysIntcIts;
536 pGits->u32GicItsId = 0;
537
538 cbMadt += sizeof(*pGits);
539 }
540
541 /* Finalize the MADT. */
542 pMadt->Hdr.u32Signature = ACPI_TABLE_HDR_SIGNATURE_APIC;
543 pMadt->Hdr.cbTbl = cbMadt;
544 pMadt->Hdr.bRevision = 6;
545 pMadt->Hdr.bChkSum = 0;
546 pMadt->Hdr.u32OemRevision = 1;
547 pMadt->Hdr.u32CreatorRevision = 1;
548
549 memcpy(&pMadt->Hdr.abOemId[0], "ORCLVB", 6);
550 memcpy(&pMadt->Hdr.abOemTblId[0], "ORCL", 4);
551 memcpy(&pMadt->Hdr.abOemTblId[4], &pMadt->Hdr.u32Signature, 4);
552 memcpy(&pMadt->Hdr.abCreatorId[0], "ORCL", 4);
553 RTAcpiTblHdrChecksumGenerate(&pMadt->Hdr, cbMadt);
554 *pcbMadt = cbMadt;
555 return RTVfsIoStrmWrite(hVfsIos, pMadt, cbMadt, true /*fBlocking*/, NULL /*pcbWritten*/);
556}
557
558
559int SystemTableBuilderAcpi::buildMcfg(RTVFSIOSTREAM hVfsIos, size_t *pcbMcfg)
560{
561 uint8_t abMcfg[_1K];
562 uint32_t cbMcfg = 0;
563
564 RT_ZERO(abMcfg);
565
566 PACPIMCFG pMcfg = (PACPIMCFG)&abMcfg[0];
567 PACPIMCFGALLOC pAlloc = (PACPIMCFGALLOC)(pMcfg + 1);
568
569 cbMcfg += sizeof(*pMcfg) + sizeof(*pAlloc);
570
571 pAlloc->u64PhysAddrBase = m_GCPhysPciMmioEcam;
572 pAlloc->u16PciSegGrpNr = 0;
573 pAlloc->bPciBusFirst = 0;
574 pAlloc->bPciBusLast = m_bPciBusMax;
575
576 /* Finalize the MADT. */
577 pMcfg->Hdr.u32Signature = ACPI_TABLE_HDR_SIGNATURE_RSVD_MCFG;
578 pMcfg->Hdr.cbTbl = cbMcfg;
579 pMcfg->Hdr.bRevision = 6;
580 pMcfg->Hdr.bChkSum = 0;
581 pMcfg->Hdr.u32OemRevision = 1;
582 pMcfg->Hdr.u32CreatorRevision = 1;
583
584 memcpy(&pMcfg->Hdr.abOemId[0], "ORCLVB", 6);
585 memcpy(&pMcfg->Hdr.abOemTblId[0], "ORCL", 4);
586 memcpy(&pMcfg->Hdr.abOemTblId[4], &pMcfg->Hdr.u32Signature, 4);
587 memcpy(&pMcfg->Hdr.abCreatorId[0], "ORCL", 4);
588 RTAcpiTblHdrChecksumGenerate(&pMcfg->Hdr, cbMcfg);
589 *pcbMcfg = cbMcfg;
590 return RTVfsIoStrmWrite(hVfsIos, pMcfg, cbMcfg, true /*fBlocking*/, NULL /*pcbWritten*/);
591}
592
593
594int SystemTableBuilderAcpi::buildGtdt(RTVFSIOSTREAM hVfsIos, size_t *pcbGtdt)
595{
596 ACPIGTDT Gtdt; RT_ZERO(Gtdt);
597
598#if 1
599 Gtdt.u64PhysAddrCntControlBase = UINT64_MAX;
600 Gtdt.u32Rsvd = 0;
601 Gtdt.u32El1SecTimerGsiv = 0;
602 Gtdt.fEl1SecTimer = 0;
603 Gtdt.u32El1NonSecTimerGsiv = 0x1a; /** @todo */
604 Gtdt.fEl1NonSecTimer = ACPI_GTDT_TIMER_F_INTR_MODE_LEVEL | ACPI_GTDT_TIMER_F_INTR_POLARITY_ACTIVE_HIGH | ACPI_GTDT_TIMER_F_ALWAYS_ON_CAP;
605 Gtdt.u32El1VirtTimerGsiv = 0x1b; /** @todo */
606 Gtdt.fEl1VirtTimer = ACPI_GTDT_TIMER_F_INTR_MODE_LEVEL | ACPI_GTDT_TIMER_F_INTR_POLARITY_ACTIVE_HIGH;
607 Gtdt.u32El2TimerGsiv = 0x1e;
608 Gtdt.fEl2Timer = ACPI_GTDT_TIMER_F_INTR_MODE_LEVEL | ACPI_GTDT_TIMER_F_INTR_POLARITY_ACTIVE_HIGH;
609 Gtdt.u64PhysAddrCndReadBase = UINT64_MAX;
610 Gtdt.cPlatformTimers = 0;
611 Gtdt.offPlatformTimers = 0;
612 Gtdt.u32El2VirtTimerGsiv = 0;
613 Gtdt.fEl2VirtTimer = 0;
614#else /* Nested virt config on AppleSilicon. */
615 Gtdt.u64PhysAddrCntControlBase = UINT64_MAX;
616 Gtdt.u32Rsvd = 0;
617 Gtdt.u32El1SecTimerGsiv = 0;
618 Gtdt.fEl1SecTimer = 0;
619 Gtdt.u32El1NonSecTimerGsiv = 0x1e; /** @todo */
620 Gtdt.fEl1NonSecTimer = ACPI_GTDT_TIMER_F_INTR_MODE_LEVEL | ACPI_GTDT_TIMER_F_INTR_POLARITY_ACTIVE_HIGH | ACPI_GTDT_TIMER_F_ALWAYS_ON_CAP;
621 Gtdt.u32El1VirtTimerGsiv = 0x1b; /** @todo */
622 Gtdt.fEl1VirtTimer = ACPI_GTDT_TIMER_F_INTR_MODE_LEVEL | ACPI_GTDT_TIMER_F_INTR_POLARITY_ACTIVE_HIGH;
623 Gtdt.u32El2TimerGsiv = 0x1a;
624 Gtdt.fEl2Timer = ACPI_GTDT_TIMER_F_INTR_MODE_LEVEL | ACPI_GTDT_TIMER_F_INTR_POLARITY_ACTIVE_HIGH;
625 Gtdt.u64PhysAddrCndReadBase = UINT64_MAX;
626 Gtdt.cPlatformTimers = 0;
627 Gtdt.offPlatformTimers = 0;
628 Gtdt.u32El2VirtTimerGsiv = 0;
629 Gtdt.fEl2VirtTimer = 0;
630#endif
631
632 Gtdt.Hdr.u32Signature = ACPI_TABLE_HDR_SIGNATURE_GTDT;
633 Gtdt.Hdr.cbTbl = sizeof(Gtdt);
634 Gtdt.Hdr.bRevision = 6;
635 Gtdt.Hdr.bChkSum = 0;
636 Gtdt.Hdr.u32OemRevision = 1;
637 Gtdt.Hdr.u32CreatorRevision = 1;
638
639 memcpy(&Gtdt.Hdr.abOemId[0], "ORCLVB", 6);
640 memcpy(&Gtdt.Hdr.abOemTblId[0], "ORCL", 4);
641 memcpy(&Gtdt.Hdr.abOemTblId[4], &Gtdt.Hdr.u32Signature, 4);
642 memcpy(&Gtdt.Hdr.abCreatorId[0], "ORCL", 4);
643 RTAcpiTblHdrChecksumGenerate(&Gtdt.Hdr, sizeof(Gtdt));
644 *pcbGtdt = sizeof(Gtdt);
645 return RTVfsIoStrmWrite(hVfsIos, &Gtdt, sizeof(Gtdt), true /*fBlocking*/, NULL /*pcbWritten*/);
646}
647
648
649int SystemTableBuilderAcpi::buildFadt(RTVFSIOSTREAM hVfsIos, RTGCPHYS GCPhysXDsdt, size_t *pcbFadt)
650{
651 /* Build FADT. */
652 ACPIFADT Fadt; RT_ZERO(Fadt);
653
654 Fadt.fFeatures = ACPI_FADT_F_HW_REDUCED_ACPI;
655 Fadt.fArmBootArch = ACPI_FADT_ARM_BOOT_ARCH_F_PSCI_COMP
656 | ACPI_FADT_ARM_BOOT_ARCH_F_PSCI_USE_HVC;
657 Fadt.bFadtVersionMinor = 3;
658 Fadt.u64AddrXDsdt = GCPhysXDsdt;
659
660 Fadt.Hdr.u32Signature = ACPI_TABLE_HDR_SIGNATURE_FACP;
661 Fadt.Hdr.cbTbl = sizeof(Fadt);
662 Fadt.Hdr.bRevision = 6;
663 Fadt.Hdr.bChkSum = 0;
664 Fadt.Hdr.u32OemRevision = 1;
665 Fadt.Hdr.u32CreatorRevision = 1;
666
667 memcpy(&Fadt.Hdr.abOemId[0], "ORCLVB", 6);
668 memcpy(&Fadt.Hdr.abOemTblId[0], "ORCL", 4);
669 memcpy(&Fadt.Hdr.abOemTblId[4], &Fadt.Hdr.u32Signature, 4);
670 memcpy(&Fadt.Hdr.abCreatorId[0], "ORCL", 4);
671 RTAcpiTblHdrChecksumGenerate(&Fadt.Hdr, sizeof(Fadt));
672 *pcbFadt = sizeof(Fadt);
673 return RTVfsIoStrmWrite(hVfsIos, &Fadt, sizeof(Fadt), true /*fBlocking*/, NULL /*pcbWritten*/);
674}
675
676
677int SystemTableBuilderAcpi::buildTpm20(RTVFSIOSTREAM hVfsIos, size_t *pcbTpm20)
678{
679 Assert(m_fTpm20);
680
681 ACPITPM20 Tpm2;
682 RT_ZERO(Tpm2);
683
684 Tpm2.u32StartMethod = m_fCrb ? ACPITBL_TPM20_START_METHOD_CRB : ACPITBL_TPM20_START_METHOD_TIS12;
685 Tpm2.u64BaseAddrCrbOrFifo = m_fCrb ? m_GCPhysTpm20Mmio + TPM_CRB_LOCALITY_REG_CTRL_REQ : m_GCPhysTpm20Mmio;
686 Tpm2.u16PlatCls = ACPITBL_TPM20_PLAT_CLS_CLIENT;
687
688 Tpm2.Hdr.u32Signature = ACPI_TABLE_HDR_SIGNATURE_RSVD_TPM2;
689 Tpm2.Hdr.cbTbl = sizeof(Tpm2);
690 Tpm2.Hdr.bRevision = ACPI_TPM20_REVISION;
691 Tpm2.Hdr.bChkSum = 0;
692 Tpm2.Hdr.u32OemRevision = 1;
693 Tpm2.Hdr.u32CreatorRevision = 1;
694
695 memcpy(&Tpm2.Hdr.abOemId[0], "ORCLVB", 6);
696 memcpy(&Tpm2.Hdr.abOemTblId[0], "ORCL", 4);
697 memcpy(&Tpm2.Hdr.abOemTblId[4], &Tpm2.Hdr.u32Signature, 4);
698 memcpy(&Tpm2.Hdr.abCreatorId[0], "ORCL", 4);
699 RTAcpiTblHdrChecksumGenerate(&Tpm2.Hdr, sizeof(Tpm2));
700 *pcbTpm20 = sizeof(Tpm2);
701 return RTVfsIoStrmWrite(hVfsIos, &Tpm2, sizeof(Tpm2), true /*fBlocking*/, NULL /*pcbWritten*/);
702}
703
704
705int SystemTableBuilderAcpi::configureTpm2(bool fCrb, RTGCPHYS GCPhysMmioStart, RTGCPHYS cbMmio, uint32_t u32Irq)
706{
707 m_fTpm20 = true;
708 m_fCrb = fCrb;
709 m_GCPhysTpm20Mmio = GCPhysMmioStart;
710
711 RTAcpiTblDeviceStartF(m_hAcpiDsdt, "TPM0");
712
713 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
714 RTAcpiTblStringAppend(m_hAcpiDsdt, "MSFT0101");
715
716 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CID");
717 RTAcpiTblStringAppend(m_hAcpiDsdt, "MSFT0101");
718
719 RTAcpiTblNameAppend(m_hAcpiDsdt, "_STR");
720 RTAcpiTblStringAppend(m_hAcpiDsdt, "TPM 2.0 Device");
721
722 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
723 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
724
725 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CRS");
726 int vrc = systemTableAcpiMmioDevResource(m_hAcpiDsdt, m_hAcpiRes, GCPhysMmioStart, cbMmio, u32Irq + GIC_INTID_RANGE_SPI_START);
727 AssertRCReturn(vrc, vrc);
728
729 RTAcpiTblMethodStart(m_hAcpiDsdt, "_STA", 0, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/);
730 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
731 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x0f);
732 RTAcpiTblMethodFinalize(m_hAcpiDsdt);
733
734 /* Build the PPI interface (this is as a verbatim translation from src/VBox/Devices/PC/vbox-tpm.dsl as possible). */
735 RTAcpiTblMethodStart(m_hAcpiDsdt, "TPFS", 1, RTACPI_METHOD_F_SERIALIZED, 0 /*uSyncLvl*/);
736
737 RTAcpiTblIfStart(m_hAcpiDsdt);
738 /* LGreaterEqual(Arg0, 0x100). */
739 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LGreaterEqual);
740 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 0);
741 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x100);
742
743 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
744 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
745 RTAcpiTblIfFinalize(m_hAcpiDsdt);
746
747 RTAcpiTblOpRegionAppendEx(m_hAcpiDsdt, "TPP1", kAcpiOperationRegionSpace_SystemMemory);
748 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Add); /* Region offset */
749 RTAcpiTblIntegerAppend(m_hAcpiDsdt, m_GCPhysTpm20Mmio + 0x5000);
750 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 0); /* Arg0 */
751 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
752 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* Region size */
753
754 /* Define the field accessor. */
755 const RTACPIFIELDENTRY aPpiTpp1Fields[] =
756 {
757 { "TPPF", 8 },
758 };
759 RTAcpiTblFieldAppend(m_hAcpiDsdt, "TPP1", kAcpiFieldAcc_Any, false /*fLock*/, kAcpiFieldUpdate_Preserve,
760 &aPpiTpp1Fields[0], RT_ELEMENTS(aPpiTpp1Fields));
761 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
762 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPPF");
763
764 RTAcpiTblMethodFinalize(m_hAcpiDsdt);
765
766
767 /* Device specific method. */
768 RTAcpiTblMethodStart(m_hAcpiDsdt, "_DSM", 4, RTACPI_METHOD_F_SERIALIZED, 0 /*uSyncLvl*/);
769
770 /* Define the MMIO region for the PPI interface. */
771 RTAcpiTblOpRegionAppend(m_hAcpiDsdt, "TPMP", kAcpiOperationRegionSpace_SystemMemory,
772 m_GCPhysTpm20Mmio + 0x5100, 0x5a /*cbRegion*/);
773
774 /* Define the field accessors for the PPI interface. */
775 const RTACPIFIELDENTRY aPpiFields[] =
776 {
777 { "PPIN", 8 },
778 { "PPIP", 32 },
779 { "PPRP", 32 },
780 { "PPRQ", 32 },
781 { "PPRM", 32 },
782 { "LPPR", 32 }
783 };
784 RTAcpiTblFieldAppend(m_hAcpiDsdt, "TPMP", kAcpiFieldAcc_Any, false /*fLock*/, kAcpiFieldUpdate_Preserve,
785 &aPpiFields[0], RT_ELEMENTS(aPpiFields));
786
787 /* Define some packages we need later on. */
788 RTAcpiTblNameAppend(m_hAcpiDsdt, "TPB2");
789 RTAcpiTblPackageStart(m_hAcpiDsdt, 2 /*cElements*/);
790 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
791 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
792 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
793
794 RTAcpiTblNameAppend(m_hAcpiDsdt, "TPB3");
795 RTAcpiTblPackageStart(m_hAcpiDsdt, 3 /*cElements*/);
796 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
797 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
798 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
799 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
800
801
802 /*
803 * Check that the UUID in Arg0 contains the Physical Presence Interface Specification UUID.
804 */
805 RTAcpiTblIfStart(m_hAcpiDsdt);
806
807 /* Predicate (LEqual(Arg0, ToUUID("3dddfaa6-361b-4eb4-a424-8d10089d1653")))*/
808 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
809 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 0);
810 RTAcpiTblUuidAppendFromStr(m_hAcpiDsdt, "3dddfaa6-361b-4eb4-a424-8d10089d1653");
811
812 /* Standard _DSM query function. */
813 RTAcpiTblIfStart(m_hAcpiDsdt);
814
815 /* LEqual(Arg2, Zero). */
816 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
817 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
818 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
819
820 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
821 uint8_t abDsmQuery[2] = { 0xff, 0x01 };
822 RTAcpiTblBufferAppend(m_hAcpiDsdt, &abDsmQuery[0], sizeof(abDsmQuery));
823
824 RTAcpiTblIfFinalize(m_hAcpiDsdt);
825
826 /* Query supported PPI revision . */
827 RTAcpiTblIfStart(m_hAcpiDsdt);
828
829 /* LEqual(Arg2, Zero). */
830 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
831 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
832 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
833
834 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
835 RTAcpiTblStringAppend(m_hAcpiDsdt, "1.3");
836
837 RTAcpiTblIfFinalize(m_hAcpiDsdt);
838
839
840 /* Submit TPM Operation Requested to pre-OS environment. */
841 RTAcpiTblIfStart(m_hAcpiDsdt);
842
843 /* LEqual(Arg2, Zero). */
844 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
845 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
846 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 2);
847
848 /* Store(DerefOf(Index(Arg3, Zero)), Local0) */
849 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
850 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_DerefOf);
851 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
852 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 3); /* Arg3 */
853 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Zero */
854 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
855 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0); /* Local0 */
856
857 /* Store (TPFS (Local0), Local1) */
858 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
859 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPFS");
860 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0); /* Local0 */
861 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1); /* Local1 */
862
863 /* If (LEqual (And (Local1, 0x07), Zero)) */
864 RTAcpiTblIfStart(m_hAcpiDsdt);
865 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
866 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_And);
867 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1); /* Local1 */
868 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x7);
869 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
870 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
871
872 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
873 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
874
875 RTAcpiTblIfFinalize(m_hAcpiDsdt);
876
877 /* Store (Local0, PPRQ) */
878 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
879 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0); /* Local0 */
880 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRQ");
881 /* Store (Zero, PPRM) */
882 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
883 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
884 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRM");
885
886 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
887 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
888
889 RTAcpiTblIfFinalize(m_hAcpiDsdt);
890
891
892 /* Get Pending TPM Operation Requested by the OS. */
893 RTAcpiTblIfStart(m_hAcpiDsdt);
894
895 /* LEqual(Arg2, Zero). */
896 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
897 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
898 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 3);
899
900 RTAcpiTblIfStart(m_hAcpiDsdt);
901
902 /* LEqual(Arg1, One). */
903 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
904 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 1);
905 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
906
907 /* Store (PPRQ, Index(TPB2, One) */
908 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
909 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRQ");
910 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
911 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB2");
912 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
913 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
914
915 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
916 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB2");
917
918 RTAcpiTblIfFinalize(m_hAcpiDsdt);
919
920 RTAcpiTblIfStart(m_hAcpiDsdt);
921
922 /* LEqual(Arg1, 0x02). */
923 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
924 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 1);
925 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 2);
926
927 /* Store (PPRQ, Index(TPB3, One) */
928 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
929 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRQ");
930 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
931 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB3");
932 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
933 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
934
935 /* Store (PPRM, Index(TPB3, 0x2) */
936 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
937 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRM");
938 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
939 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB3");
940 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 2);
941 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
942
943 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
944 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB2");
945
946 RTAcpiTblIfFinalize(m_hAcpiDsdt);
947
948 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
949 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB3");
950
951 RTAcpiTblIfFinalize(m_hAcpiDsdt);
952
953
954 /* Get Platform-specific Action to Transition to Pre-OS Environment. */
955 RTAcpiTblIfStart(m_hAcpiDsdt);
956
957 /* LEqual(Arg2, Zero). */
958 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
959 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
960 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 4);
961
962 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
963 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 2); /* Reboot */
964
965 RTAcpiTblIfFinalize(m_hAcpiDsdt);
966
967
968 /* Return TPM Operation Response to OS Environment. */
969 RTAcpiTblIfStart(m_hAcpiDsdt);
970
971 /* LEqual(Arg2, Zero). */
972 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
973 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
974 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 5);
975
976 /* Store (LPPR, Index(TPB3, One) */
977 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
978 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "LPPR");
979 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
980 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB3");
981 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
982 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
983
984 /* Store (PPRP, Index(TPB3, 0x2) */
985 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
986 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRP");
987 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
988 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB3");
989 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 2);
990 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
991
992 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
993 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPB3");
994
995 RTAcpiTblIfFinalize(m_hAcpiDsdt);
996
997
998 /* Submit Preferred user language - deprecated. */
999 RTAcpiTblIfStart(m_hAcpiDsdt);
1000
1001 /* LEqual(Arg2, Zero). */
1002 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1003 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
1004 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 6);
1005
1006 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1007 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 3); /* Not implemented */
1008
1009 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1010
1011
1012 /* Submit TPM Operation Request to Pre-OS Environment 2. */
1013 RTAcpiTblIfStart(m_hAcpiDsdt);
1014
1015 /* LEqual(Arg2, Zero). */
1016 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1017 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
1018 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 7);
1019
1020 /* Store(DerefOf(Index(Arg3, Zero)), Local0) */
1021 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1022 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_DerefOf);
1023 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
1024 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 3); /* Arg3 */
1025 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Zero */
1026 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
1027 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0); /* Local0 */
1028
1029 /* Store (TPFS (Local0), Local1) */
1030 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1031 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPFS");
1032 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0); /* Local0 */
1033 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1); /* Local1 */
1034
1035 /* Store(And(Local1, 0x07), Local1) */
1036 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1037 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_And);
1038 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1); /* Local1 */
1039 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x7);
1040 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
1041 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1); /* Local1 */
1042
1043 /* LEqual(Local1, Zero) */
1044 RTAcpiTblIfStart(m_hAcpiDsdt);
1045
1046 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1047 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1);
1048 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1049
1050 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1051 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
1052
1053 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1054
1055 /* LEqual(Local1, 2) */
1056 RTAcpiTblIfStart(m_hAcpiDsdt);
1057
1058 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1059 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1);
1060 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 2);
1061
1062 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1063 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 3);
1064
1065 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1066
1067 /* LEqual(Arg1, One) */
1068 RTAcpiTblIfStart(m_hAcpiDsdt);
1069
1070 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1071 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 1);
1072 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
1073
1074 /* Store(Local0, PPRQ) */
1075 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1076 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0);
1077 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRQ");
1078
1079 /* Store(Zero, PPRM) */
1080 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1081 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1082 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRM");
1083
1084 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1085
1086 /* LEqual(Arg1, 2) */
1087 RTAcpiTblIfStart(m_hAcpiDsdt);
1088
1089 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1090 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 1);
1091 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 2);
1092
1093 /* Store(DerefOf(Index(Arg3, One)), Local2) */
1094 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1095 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_DerefOf);
1096 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
1097 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 3); /* Arg3 */
1098 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* ONe */
1099 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
1100 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 2); /* Local2 */
1101
1102 /* Store(Local0, PPRQ) */
1103 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1104 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0);
1105 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRQ");
1106
1107 /* Store(Local2, PPRM) */
1108 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1109 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 2);
1110 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PPRM");
1111
1112 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1113
1114 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1115 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1116
1117 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1118
1119
1120 /* Get User Confirmation Status for Operation. */
1121 RTAcpiTblIfStart(m_hAcpiDsdt);
1122
1123 /* LEqual(Arg2, Zero). */
1124 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1125 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
1126 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 8);
1127
1128 /* Store(DerefOf(Index(Arg3, Zero)), Local0) */
1129 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1130 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_DerefOf);
1131 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Index);
1132 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 3); /* Arg3 */
1133 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Zero */
1134 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
1135 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0); /* Local0 */
1136
1137 /* Store (TPFS (Local0), Local1) */
1138 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Store);
1139 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "TPFS");
1140 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 0); /* Local0 */
1141 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1); /* Local1 */
1142
1143 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1144 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_And);
1145 RTAcpiTblLocalOpAppend(m_hAcpiDsdt, 1); /* Local1 */
1146 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x7);
1147 RTAcpiTblNullNameAppend(m_hAcpiDsdt); /* Target -> NullName */
1148
1149 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1150
1151
1152 /* Return Unknown function. */
1153 uint8_t bUnkFunc = 0x00;
1154 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1155 RTAcpiTblBufferAppend(m_hAcpiDsdt, &bUnkFunc, sizeof(bUnkFunc));
1156
1157 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1158
1159
1160 /*
1161 * TCG Platform Reset Attack Mitigation Specification interface.
1162 */
1163 RTAcpiTblIfStart(m_hAcpiDsdt);
1164
1165 /* Predicate (LEqual(Arg0, ToUUID("376054ed-cc13-4675-901c-4756d7f2d45d")))*/
1166 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1167 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 0);
1168 RTAcpiTblUuidAppendFromStr(m_hAcpiDsdt, "376054ed-cc13-4675-901c-4756d7f2d45d");
1169
1170 /* Standard _DSM query function. */
1171 RTAcpiTblIfStart(m_hAcpiDsdt);
1172
1173 /* LEqual(Arg2, Zero). */
1174 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1175 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
1176 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1177
1178 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1179 uint8_t bBuf = 0x03;
1180 RTAcpiTblBufferAppend(m_hAcpiDsdt, &bBuf, sizeof(bBuf));
1181
1182 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1183
1184 /* Set Memory Overwrite Request (MOR) bit to specified value. */
1185 RTAcpiTblIfStart(m_hAcpiDsdt);
1186
1187 /* LEqual(Arg2, Zero). */
1188 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1189 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
1190 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
1191
1192 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1193 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Memory always zeroed on reset. */
1194
1195 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1196
1197 /* Return Unknown function. */
1198 bUnkFunc = 0x00;
1199 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1200 RTAcpiTblBufferAppend(m_hAcpiDsdt, &bUnkFunc, sizeof(bUnkFunc));
1201
1202 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1203
1204 /* Return Unknown function. */
1205 bUnkFunc = 0x00;
1206 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1207 RTAcpiTblBufferAppend(m_hAcpiDsdt, &bUnkFunc, sizeof(bUnkFunc));
1208
1209 RTAcpiTblMethodFinalize(m_hAcpiDsdt);
1210
1211 return RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
1212}
1213
1214
1215int SystemTableBuilderAcpi::configureGpioDevice(const char *pszVBoxName, uint32_t uInstance, RTGCPHYS GCPhysMmio, RTGCPHYS cbMmio, uint32_t u32Irq,
1216 uint16_t u16PinShutdown, uint16_t u16PinSuspend)
1217{
1218 PCSYSTEMTABLEDEVICE pSysTblDev = systemTableVBoxDevName2SysTblDevice(pszVBoxName);
1219 AssertPtrReturn(pSysTblDev, VERR_NOT_FOUND);
1220
1221 RTAcpiTblDeviceStartF(m_hAcpiDsdt, "%s%RX32", pSysTblDev->pszAcpiName, uInstance);
1222
1223 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
1224 RTAcpiTblStringAppend(m_hAcpiDsdt, pSysTblDev->pszAcpiHid);
1225
1226 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
1227 RTAcpiTblIntegerAppend(m_hAcpiDsdt, uInstance);
1228
1229 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CRS");
1230
1231 int vrc = systemTableAcpiMmioDevResource(m_hAcpiDsdt, m_hAcpiRes, GCPhysMmio, cbMmio, u32Irq + GIC_INTID_RANGE_SPI_START);
1232 AssertRCReturn(vrc, vrc);
1233
1234#if 0 /* Works fine with Linux (also older ones), doesn't with Windows (talk about "standards"). */
1235 /* Construct the _AEI containing the GPIO configuration. */
1236 RTAcpiTblNameAppend(m_hAcpiDsdt, "_AEI");
1237
1238 RTAcpiResourceReset(m_hAcpiRes);
1239 vrc = RTAcpiResourceAddGpioInt(m_hAcpiRes, kAcpiResGpioMod_Level, kAcpiResGpioPol_ActiveHigh, kAcpiResGpioShr_Exclusive,
1240 kAcpiResGpioPpi_PullDown, 0 /*u16DebounceWait*/, "GPI0",
1241 &u16PinShutdown, 1 /* cPins */);
1242 if (RT_SUCCESS(vrc))
1243 vrc = RTAcpiResourceAddGpioInt(m_hAcpiRes, kAcpiResGpioMod_Level, kAcpiResGpioPol_ActiveHigh, kAcpiResGpioShr_Exclusive,
1244 kAcpiResGpioPpi_PullDown, 0 /*u16DebounceWait*/, "GPI0",
1245 &u16PinSuspend, 1 /* cPins */);
1246 if (RT_SUCCESS(vrc))
1247 {
1248 vrc = RTAcpiResourceSeal(m_hAcpiRes);
1249 if (RT_SUCCESS(vrc))
1250 vrc = RTAcpiTblResourceAppend(m_hAcpiDsdt, m_hAcpiRes);
1251 }
1252 AssertRCReturn(vrc, vrc);
1253
1254 /* The interrupt methods for the pins. */
1255 RTAcpiTblMethodStartF(m_hAcpiDsdt, 0 /*cArgs*/, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/,
1256 "_L%02RX16", u16PinShutdown);
1257 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Notify);
1258 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "PBTN");
1259 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x80);
1260 RTAcpiTblMethodFinalize(m_hAcpiDsdt);
1261
1262 RTAcpiTblMethodStartF(m_hAcpiDsdt, 0 /*cArgs*/, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/,
1263 "_L%02RX16", u16PinSuspend);
1264 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Notify);
1265 RTAcpiTblNameStringAppend(m_hAcpiDsdt, "SBTN");
1266 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x80);
1267 RTAcpiTblMethodFinalize(m_hAcpiDsdt);
1268
1269 RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
1270
1271 /* Now create the shutdown and suspend button devices. */
1272 RTAcpiTblDeviceStart(m_hAcpiDsdt, "PBTN");
1273
1274 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
1275 RTAcpiTblEisaIdAppend(m_hAcpiDsdt, "PNP0C0C");
1276
1277 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
1278 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1279
1280 RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
1281
1282 RTAcpiTblDeviceStart(m_hAcpiDsdt, "SBTN");
1283
1284 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
1285 RTAcpiTblEisaIdAppend(m_hAcpiDsdt, "PNP0C0E");
1286
1287 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
1288 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1289
1290 return RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
1291#else /* Works on new Linux guests but not Windows so far... */
1292 /* Use the approach from https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/acpi-button-device . */
1293
1294 /* Device specific method. */
1295 RTAcpiTblMethodStart(m_hAcpiDsdt, "_DSM", 4, RTACPI_METHOD_F_SERIALIZED, 0 /*uSyncLvl*/);
1296
1297 RTAcpiTblIfStart(m_hAcpiDsdt);
1298
1299 /* Predicate (LEqual(Arg0, ToUUID("4f248f40-d5e2-499f-834c-27758ea1cd3f")))*/
1300 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1301 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 0);
1302 RTAcpiTblUuidAppendFromStr(m_hAcpiDsdt, "4f248f40-d5e2-499f-834c-27758ea1cd3f");
1303
1304 /* Standard _DSM query function. */
1305 RTAcpiTblIfStart(m_hAcpiDsdt);
1306
1307 /* LEqual(Arg2, Zero). */
1308 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1309 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
1310 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1311
1312 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1313 uint8_t bBuf = 0x03;
1314 RTAcpiTblBufferAppend(m_hAcpiDsdt, &bBuf, sizeof(bBuf));
1315
1316 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1317
1318 /* Mark the pin for the power button as ActiveHigh. */
1319 RTAcpiTblIfStart(m_hAcpiDsdt);
1320
1321 /* LEqual(Arg2, One). */
1322 RTAcpiTblBinaryOpAppend(m_hAcpiDsdt, kAcpiBinaryOp_LEqual);
1323 RTAcpiTblArgOpAppend(m_hAcpiDsdt, 2);
1324 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1);
1325
1326 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1327 RTAcpiTblPackageStart(m_hAcpiDsdt, 2 /*cElements*/);
1328 RTAcpiTblIntegerAppend(m_hAcpiDsdt, u16PinShutdown);
1329 RTAcpiTblIntegerAppend(m_hAcpiDsdt, u16PinSuspend);
1330 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
1331
1332 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1333
1334 /* Return Unknown function. */
1335 uint8_t bUnkFunc = 0x00;
1336 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1337 RTAcpiTblBufferAppend(m_hAcpiDsdt, &bUnkFunc, sizeof(bUnkFunc));
1338
1339 RTAcpiTblIfFinalize(m_hAcpiDsdt);
1340
1341 /* Return Unknown function. */
1342 bUnkFunc = 0x00;
1343 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1344 RTAcpiTblBufferAppend(m_hAcpiDsdt, &bUnkFunc, sizeof(bUnkFunc));
1345
1346 RTAcpiTblMethodFinalize(m_hAcpiDsdt);
1347
1348 RTAcpiTblDeviceFinalize(m_hAcpiDsdt); /* Finish the GPI0 GPIO device. */
1349
1350 RTAcpiTblDeviceStart(m_hAcpiDsdt, "BTNS");
1351
1352 RTAcpiTblNameAppend(m_hAcpiDsdt, "_HID");
1353 RTAcpiTblStringAppend(m_hAcpiDsdt, "ACPI0011");
1354
1355 RTAcpiTblNameAppend(m_hAcpiDsdt, "_UID");
1356 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0);
1357
1358 RTAcpiTblMethodStart(m_hAcpiDsdt, "_STA", 0, RTACPI_METHOD_F_NOT_SERIALIZED, 0 /*uSyncLvl*/);
1359 RTAcpiTblStmtSimpleAppend(m_hAcpiDsdt, kAcpiStmt_Return);
1360 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x0f);
1361 RTAcpiTblMethodFinalize(m_hAcpiDsdt);
1362
1363 /* Build the resource template. */
1364 RTAcpiTblNameAppend(m_hAcpiDsdt, "_CRS");
1365 RTAcpiResourceReset(m_hAcpiRes);
1366 vrc = RTAcpiResourceAddGpioInt(m_hAcpiRes, kAcpiResGpioMod_Edge, kAcpiResGpioPol_ActiveBoth, kAcpiResGpioShr_Exclusive,
1367 kAcpiResGpioPpi_PullDown, 0 /*u16DebounceWait*/, "\\_SB.GPI0",
1368 &u16PinShutdown, 1 /* cPins */);
1369 if (RT_SUCCESS(vrc))
1370 vrc = RTAcpiResourceAddGpioInt(m_hAcpiRes, kAcpiResGpioMod_Edge, kAcpiResGpioPol_ActiveBoth, kAcpiResGpioShr_Exclusive,
1371 kAcpiResGpioPpi_PullDown, 0 /*u16DebounceWait*/, "\\_SB.GPI0",
1372 &u16PinSuspend, 1 /* cPins */);
1373 if (RT_SUCCESS(vrc))
1374 {
1375 vrc = RTAcpiResourceSeal(m_hAcpiRes);
1376 if (RT_SUCCESS(vrc))
1377 vrc = RTAcpiTblResourceAppend(m_hAcpiDsdt, m_hAcpiRes);
1378 }
1379 AssertRCReturn(vrc, vrc);
1380
1381 RTAcpiTblNameAppend(m_hAcpiDsdt, "_DSD");
1382 RTAcpiTblPackageStart(m_hAcpiDsdt, 2 /*cElements*/);
1383 RTAcpiTblUuidAppendFromStr(m_hAcpiDsdt, "fa6bd625-9ce8-470d-a2c7-b3ca36c4282e");
1384 RTAcpiTblPackageStart(m_hAcpiDsdt, 3 /*cElements*/);
1385 RTAcpiTblPackageStart(m_hAcpiDsdt, 5 /*cElements*/);
1386 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Collection */
1387 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* Unique collection ID */
1388 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Top-Level collection */
1389 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x01); /* Usage Page ("Generic Desktop Page") */
1390 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x0d); /* Usage ("Portable Device Control") */
1391 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
1392
1393 RTAcpiTblPackageStart(m_hAcpiDsdt, 5 /*cElements*/);
1394 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* Control */
1395 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0); /* Interrupt index in _CRS for power button */
1396 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* Unique ID of parent collection */
1397 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x01); /* Usage Page ("Generic Desktop Page") */
1398 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x81); /* Usage ("System Power Down") */
1399 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
1400
1401 RTAcpiTblPackageStart(m_hAcpiDsdt, 5 /*cElements*/);
1402 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* Control */
1403 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* Interrupt index in _CRS for power button */
1404 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 1); /* Unique ID of parent collection */
1405 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x01); /* Usage Page ("Generic Desktop Page") */
1406 RTAcpiTblIntegerAppend(m_hAcpiDsdt, 0x82); /* Usage ("System Sleep") */
1407 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
1408
1409 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
1410 RTAcpiTblPackageFinalize(m_hAcpiDsdt);
1411
1412 return RTAcpiTblDeviceFinalize(m_hAcpiDsdt);
1413#endif
1414}
1415
1416
1417int SystemTableBuilder::initInstance(void)
1418{
1419 return VERR_NOT_IMPLEMENTED;
1420}
1421
1422
1423int SystemTableBuilder::finishTables(RTGCPHYS GCPhysTblsStart, RTVFSIOSTREAM hVfsIos,
1424 PRTGCPHYS pGCPhysTblRoot, size_t *pcbTblRoot, size_t *pcbTbls)
1425{
1426 RT_NOREF(GCPhysTblsStart, hVfsIos, pGCPhysTblRoot, pcbTblRoot, pcbTbls);
1427 return VERR_NOT_IMPLEMENTED;
1428}
1429
1430
1431int SystemTableBuilder::addCpu(uint32_t idCpu)
1432{
1433 RT_NOREF(idCpu);
1434 return VERR_NOT_IMPLEMENTED;
1435}
1436
1437
1438int SystemTableBuilder::addMemory(RTGCPHYS GCPhysStart, RTGCPHYS cbMem)
1439{
1440 RT_NOREF(GCPhysStart, cbMem);
1441 return VERR_NOT_IMPLEMENTED;
1442}
1443
1444
1445int SystemTableBuilder::addMmioDeviceNoIrq(const char *pszVBoxName, uint32_t uInstance, RTGCPHYS GCPhysMmio, RTGCPHYS cbMmio)
1446{
1447 RT_NOREF(pszVBoxName, uInstance, GCPhysMmio, cbMmio);
1448 return VERR_NOT_IMPLEMENTED;
1449}
1450
1451
1452int SystemTableBuilder::addMmioDevice(const char *pszVBoxName, uint32_t uInstance, RTGCPHYS GCPhysMmio, RTGCPHYS cbMmio, uint32_t u32Irq)
1453{
1454 RT_NOREF(pszVBoxName, uInstance, GCPhysMmio, cbMmio, u32Irq);
1455 return VERR_NOT_IMPLEMENTED;
1456}
1457
1458
1459int SystemTableBuilder::configureGic(uint32_t cCpus, RTGCPHYS GCPhysIntcDist, RTGCPHYS cbMmioIntcDist, RTGCPHYS GCPhysIntcReDist,
1460 RTGCPHYS cbMmioIntcReDist, RTGCPHYS GCPhysIntcIts, RTGCPHYS cbMmioIntcIts)
1461{
1462 RT_NOREF(cCpus, GCPhysIntcDist, cbMmioIntcDist, GCPhysIntcReDist, cbMmioIntcReDist, GCPhysIntcIts, cbMmioIntcIts);
1463 return VERR_NOT_IMPLEMENTED;
1464}
1465
1466
1467int SystemTableBuilder::configureClock(void)
1468{
1469 return VERR_NOT_IMPLEMENTED;
1470}
1471
1472
1473int SystemTableBuilder::configurePcieRootBus(const char *pszVBoxName, uint32_t aPinIrqs[4], RTGCPHYS GCPhysMmioPio, RTGCPHYS GCPhysMmioEcam, size_t cbPciMmioEcam,
1474 RTGCPHYS GCPhysPciMmioBase, RTGCPHYS cbPciMmio, RTGCPHYS GCPhysPciMmio32Base, RTGCPHYS cbPciMmio32)
1475{
1476 RT_NOREF(pszVBoxName, aPinIrqs, GCPhysMmioPio, GCPhysMmioEcam, cbPciMmioEcam,
1477 GCPhysPciMmioBase, cbPciMmio, GCPhysPciMmio32Base, cbPciMmio32);
1478 return VERR_NOT_IMPLEMENTED;
1479}
1480
1481
1482int SystemTableBuilder::configureTpm2(bool fCrb, RTGCPHYS GCPhysMmioStart, RTGCPHYS cbMmio, uint32_t u32Irq)
1483{
1484 RT_NOREF(fCrb, GCPhysMmioStart, cbMmio, u32Irq);
1485 return VERR_NOT_IMPLEMENTED;
1486}
1487
1488
1489int SystemTableBuilder::configureGpioDevice(const char *pszVBoxName, uint32_t uInstance, RTGCPHYS GCPhysMmio, RTGCPHYS cbMmio, uint32_t u32Irq,
1490 uint16_t u16PinShutdown, uint16_t u16PinSuspend)
1491{
1492 RT_NOREF(pszVBoxName, uInstance, GCPhysMmio, cbMmio, u32Irq, u16PinShutdown, u16PinSuspend);
1493 return VERR_NOT_IMPLEMENTED;
1494}
1495
1496
1497int SystemTableBuilder::dumpTables(const char *pszFilename)
1498{
1499 RT_NOREF(pszFilename);
1500 return VERR_NOT_IMPLEMENTED;
1501}
1502
1503
1504SystemTableBuilder *SystemTableBuilder::createInstance(SYSTEMTABLETYPE enmTableType)
1505{
1506 AssertReturn(enmTableType == kSystemTableType_Acpi, NULL);
1507
1508 SystemTableBuilder *pInstance = new SystemTableBuilderAcpi();
1509 Assert(pInstance);
1510
1511 int vrc = pInstance->initInstance();
1512 if (RT_FAILURE(vrc))
1513 {
1514 delete pInstance;
1515 pInstance = NULL;
1516 }
1517
1518 return pInstance;
1519}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette