VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp@ 20918

Last change on this file since 20918 was 20918, checked in by vboxsync, 15 years ago

We actually need only one ACPI CPU object per physical processor.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.3 KB
Line 
1/* $Id: VBoxAcpi.cpp 20918 2009-06-25 09:33:58Z vboxsync $ */
2/** @file
3 * VBoxAcpi - VirtualBox ACPI maniputation functionality.
4 */
5
6/*
7 * Copyright (C) 2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#if !defined(IN_RING3)
23#error Pure R3 code
24#endif
25
26#define LOG_GROUP LOG_GROUP_DEV_ACPI
27#include <VBox/pdmdev.h>
28#include <VBox/pgm.h>
29#include <VBox/log.h>
30#include <VBox/param.h>
31#include <iprt/assert.h>
32#include <iprt/alloc.h>
33#include <iprt/string.h>
34
35#ifdef VBOX_WITH_DYNAMIC_DSDT
36/* vbox.dsl - input to generate proper DSDT on the fly */
37# include <vboxdsl.hex>
38#else
39/* Statically compiled AML */
40# include <vboxaml.hex>
41#endif
42
43#ifdef VBOX_WITH_DYNAMIC_DSDT
44static int prepareDynamicDsdt(PPDMDEVINS pDevIns,
45 void* *ppPtr,
46 size_t *puDsdtLen)
47{
48 *ppPtr = NULL;
49 *puDsdtLen = 0;
50 return 0;
51}
52
53static int cleanupDynamicDsdt(PPDMDEVINS pDevIns,
54 void* pPtr)
55{
56 return 0;
57}
58
59#else
60static int patchAml(PPDMDEVINS pDevIns, uint8_t* pAml, size_t uAmlLen)
61{
62 uint16_t cNumCpus;
63 int rc;
64
65 rc = CFGMR3QueryU16Def(pDevIns->pCfgHandle, "NumCPUs", &cNumCpus, 1);
66
67 if (RT_FAILURE(rc))
68 return rc;
69
70 /* Clear CPU objects at all, if needed */
71 bool fShowCpu;
72 rc = CFGMR3QueryBoolDef(pDevIns->pCfgHandle, "ShowCpu", &fShowCpu, false);
73 if (RT_FAILURE(rc))
74 return rc;
75
76 if (!fShowCpu)
77 cNumCpus = 0;
78
79#ifdef VBOX_WITH_MULTI_CORE
80 /* One physical package with multiple cores. */
81 cNumCpus = 1;
82#endif
83
84 /**
85 * Now search AML for:
86 * AML_PROCESSOR_OP (UINT16) 0x5b83
87 * and replace whole block with
88 * AML_NOOP_OP (UINT16) 0xa3
89 * for VCPU not configured
90 */
91 for (uint32_t i = 0; i < uAmlLen - 7; i++)
92 {
93 /*
94 * AML_PROCESSOR_OP
95 *
96 * DefProcessor := ProcessorOp PkgLength NameString ProcID
97 PblkAddr PblkLen ObjectList
98 * ProcessorOp := ExtOpPrefix 0x83
99 * ProcID := ByteData
100 * PblkAddr := DwordData
101 * PblkLen := ByteData
102 */
103 if ((pAml[i] == 0x5b) && (pAml[i+1] == 0x83))
104 {
105 if ((pAml[i+3] != 'C') || (pAml[i+4] != 'P'))
106 /* false alarm, not named starting CP */
107 continue;
108
109 /* Processor ID */
110 if (pAml[i+7] < cNumCpus)
111 continue;
112
113 /* Will fill unwanted CPU block with NOOPs */
114 /*
115 * See 18.2.4 Package Length Encoding in ACPI spec
116 * for full format
117 */
118 uint32_t cBytes = pAml[i + 2];
119 AssertReleaseMsg((cBytes >> 6) == 0,
120 ("So far, we only understand simple package length"));
121
122 /* including AML_PROCESSOR_OP itself */
123 for (uint32_t j = 0; j < cBytes + 2; j++)
124 pAml[i+j] = 0xa3;
125
126 /* Can increase i by cBytes + 1, but not really worth it */
127 }
128 }
129
130 /* now recompute checksum, whole file byte sum must be 0 */
131 pAml[9] = 0;
132 uint8_t aSum = 0;
133 for (uint32_t i = 0; i < uAmlLen; i++)
134 aSum = aSum + (uint8_t)pAml[i];
135 pAml[9] = (uint8_t) (0 - aSum);
136
137 return 0;
138}
139#endif
140
141/* Two only public functions */
142int acpiPrepareDsdt(PPDMDEVINS pDevIns, void * *ppPtr, size_t *puDsdtLen)
143{
144#ifdef VBOX_WITH_DYNAMIC_DSDT
145 return prepareDynamicDsdt(pDevIns, ppPtr, puDsdtLen);
146#else
147 patchAml(pDevIns, AmlCode, sizeof(AmlCode));
148 *ppPtr = AmlCode;
149 *puDsdtLen = sizeof(AmlCode);
150 return 0;
151#endif
152}
153
154int acpiCleanupDsdt(PPDMDEVINS pDevIns, void * pPtr)
155{
156#ifdef VBOX_WITH_DYNAMIC_DSDT
157 return cleanupDynamicDsdt(pDevIns, pPtr);
158#else
159 /* Do nothing */
160 return 0;
161#endif
162}
163
Note: See TracBrowser for help on using the repository browser.

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