Changeset 108143 in vbox for trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp
- Timestamp:
- Feb 10, 2025 2:44:27 PM (12 days ago)
- svn:sync-xref-src-repo-rev:
- 167444
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp
r108139 r108143 51 51 /* Statically compiled AML */ 52 52 #include <vboxaml.hex> 53 #include <vboxssdt_cpuhotplug.hex>54 53 #ifdef VBOX_WITH_TPM 55 54 # include <vboxssdt_tpm.hex> … … 124 123 } 125 124 125 126 126 /** 127 * Patch the CPU hot-plug SSDT version to 128 * only contain the ACPI containers which may have a CPU 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. 129 135 */ 130 static int patchAmlCpuHotPlug(PPDMDEVINS pDevIns, uint8_t *pabAml, size_tcbAml)136 static int acpiCreateCpuHotplugSsdt(PPDMDEVINS pDevIns, uint8_t **ppabAml, size_t *pcbAml) 131 137 { 132 138 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; … … 137 143 return rc; 138 144 139 /* 140 * Now search AML for: 141 * AML_DEVICE_OP (UINT16) 0x5b82 142 * and replace whole block with 143 * AML_NOOP_OP (UINT16) 0xa3 144 * for VCPU not configured 145 */ 146 uint32_t idxAml = 0; 147 while (idxAml < cbAml - 7) 148 { 149 /* 150 * AML_DEVICE_OP 151 * 152 * DefDevice := DeviceOp PkgLength NameString ObjectList 153 * DeviceOp := ExtOpPrefix 0x82 154 */ 155 if (pabAml[idxAml] == 0x5b && pabAml[idxAml+1] == 0x82) 156 { 157 /* Check if the enclosed CPU device is configured. */ 158 uint8_t *pabAmlPkgLength = &pabAml[idxAml+2]; 159 uint32_t cBytes = 0; 160 uint32_t cLengthBytesFollow = pabAmlPkgLength[0] >> 6; 161 162 if (cLengthBytesFollow == 0) 163 { 164 /* Simple package length */ 165 cBytes = pabAmlPkgLength[0]; 166 } 167 else 168 { 169 unsigned idxLengthByte = 1; 170 171 cBytes = pabAmlPkgLength[0] & 0xF; 172 173 while (idxLengthByte <= cLengthBytesFollow) 174 { 175 cBytes |= pabAmlPkgLength[idxLengthByte] << (4*idxLengthByte); 176 idxLengthByte++; 177 } 178 } 179 180 uint8_t *pabAmlDevName = &pabAmlPkgLength[cLengthBytesFollow+1]; 181 uint8_t *pabAmlCpu = &pabAmlDevName[4]; 182 bool fCpuConfigured = false; 183 #ifdef RT_STRICT 184 bool fCpuFound = false; 185 #endif 186 187 if ((pabAmlDevName[0] != 'S') || (pabAmlDevName[1] != 'C') || (pabAmlDevName[2] != 'K')) 188 { 189 /* false alarm, not named starting SCK */ 190 idxAml++; 191 continue; 192 } 193 194 for (uint32_t idxAmlCpu = 0; idxAmlCpu < cBytes - 7; idxAmlCpu++) 195 { 196 /* 197 * AML_PROCESSOR_OP 198 * 199 * DefProcessor := ProcessorOp PkgLength NameString ProcID 200 PblkAddr PblkLen ObjectList 201 * ProcessorOp := ExtOpPrefix 0x83 202 * ProcID := ByteData 203 * PblkAddr := DwordData 204 * PblkLen := ByteData 205 */ 206 if ((pabAmlCpu[idxAmlCpu] == 0x5b) && (pabAmlCpu[idxAmlCpu+1] == 0x83)) 207 { 208 if ((pabAmlCpu[idxAmlCpu+4] != 'C') || (pabAmlCpu[idxAmlCpu+5] != 'P')) 209 /* false alarm, not named starting CP */ 210 continue; 211 212 #ifdef RT_STRICT 213 fCpuFound = true; 214 #endif 215 216 /* Processor ID */ 217 uint8_t const idAmlCpu = pabAmlCpu[idxAmlCpu + 8]; 218 if (idAmlCpu < cCpus) 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++) 219 276 { 220 LogFlow(("CPU %u is configured\n", idAmlCpu)); 221 fCpuConfigured = true; 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; 222 292 } 223 else 224 { 225 LogFlow(("CPU %u is not configured\n", idAmlCpu)); 226 fCpuConfigured = false; 227 } 228 break; 229 } 230 } 231 232 Assert(fCpuFound); 233 234 if (!fCpuConfigured) 235 { 236 /* Will fill unwanted CPU block with NOOPs */ 237 /* 238 * See 18.2.4 Package Length Encoding in ACPI spec 239 * for full format 240 */ 241 242 /* including AML_DEVICE_OP itself */ 243 for (uint32_t j = 0; j < cBytes + 2; j++) 244 pabAml[idxAml+j] = 0xa3; 245 } 246 247 idxAml++; 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")); 248 304 } 249 305 else 250 idxAml++; 251 } 252 253 /* now recompute checksum, whole file byte sum must be 0 */ 254 pabAml[9] = 0; 255 uint8_t bSum = 0; 256 for (uint32_t i = 0; i < cbAml; i++) 257 bSum = bSum + pabAml[i]; 258 pabAml[9] = (uint8_t)(0 - bSum); 259 260 return VINF_SUCCESS; 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; 261 314 } 262 315 … … 390 443 { 391 444 if (fCpuHotPlug) 392 { 393 cbAmlCodeSsdt = sizeof(AmlCodeSsdtCpuHotPlug); 394 pabAmlCodeSsdt = (uint8_t *)RTMemDup(AmlCodeSsdtCpuHotPlug, sizeof(AmlCodeSsdtCpuHotPlug)); 395 if (pabAmlCodeSsdt) 396 patchAmlCpuHotPlug(pDevIns, pabAmlCodeSsdt, cbAmlCodeSsdt); 397 else 398 rc = VERR_NO_MEMORY; 399 } 445 rc = acpiCreateCpuHotplugSsdt(pDevIns, &pabAmlCodeSsdt, &cbAmlCodeSsdt); 400 446 else 401 447 rc = acpiCreateCpuSsdt(pDevIns, &pabAmlCodeSsdt, &cbAmlCodeSsdt);
Note:
See TracChangeset
for help on using the changeset viewer.