Changeset 108230 in vbox for trunk/src/VBox/Runtime/common/acpi/acpi-ns.cpp
- Timestamp:
- Feb 14, 2025 8:49:02 PM (3 months ago)
- svn:sync-xref-src-repo-rev:
- 167551
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/acpi/acpi-ns.cpp
r108221 r108230 41 41 #define LOG_GROUP RTLOGGROUP_ACPI 42 42 #include <iprt/assert.h> 43 #include <iprt/err core.h>43 #include <iprt/err.h> 44 44 #include <iprt/list.h> 45 45 #include <iprt/mem.h> … … 77 77 } 78 78 RTMemFree(pNsEntry); 79 } 80 81 82 static PRTACPINSENTRY rtAcpiNsLookupWorkerSingleNameSeg(PCRTACPINSENTRY pNsEntry, const char *pszNameSeg) 83 { 84 do 85 { 86 PRTACPINSENTRY pIt; 87 RTListForEach(&pNsEntry->LstNsEntries, pIt, RTACPINSENTRY, NdNs) 88 { 89 if (!memcmp(&pIt->achNameSeg[0], pszNameSeg, sizeof(pIt->achNameSeg))) 90 return pIt; 91 } 92 93 pNsEntry = pNsEntry->pParent; 94 } while (pNsEntry); 95 96 return NULL; 79 97 } 80 98 … … 117 135 } 118 136 else 137 { 119 138 pNsEntry = pNsRoot->aNsStack[pNsRoot->idxNsStack]; 139 140 /* For single name segments there is a special search rule which searches recursively upwards in the namespace. */ 141 if (pszNameString[4] == '\0') 142 { 143 if (fExcludeLast) 144 { 145 AssertPtr(ppszNameSegLast); 146 *ppszNameSegLast = pszNameString; 147 return pNsEntry; 148 } 149 else 150 return rtAcpiNsLookupWorkerSingleNameSeg(pNsEntry, pszNameString); 151 } 152 } 120 153 121 154 /* This ASSUMES the namestring has always full 4 character name segments and is well formed. */ … … 157 190 158 191 /** 192 * Looks up a name string under the specified entry. 193 * 194 * @returns Pointer to the namespace entry or NULL if not found. 195 * @param pNsEntry The namespace entry to start searching at. 196 * @param pszNameString The name string to look for. 197 */ 198 static PCRTACPINSENTRY rtAcpiNsLookupSubTree(PCRTACPINSENTRY pNsEntry, const char *pszNameString) 199 { 200 /* This ASSUMES the namestring has always full 4 character name segments and is well formed. */ 201 do 202 { 203 Assert(pszNameString[0] != '\0' && pszNameString[1] != '\0' && pszNameString[2] != '\0' && pszNameString[3] != '\0'); 204 205 PCRTACPINSENTRY pIt; 206 bool fFound = false; 207 RTListForEach(&pNsEntry->LstNsEntries, pIt, RTACPINSENTRY, NdNs) 208 { 209 if (!memcmp(&pIt->achNameSeg[0], pszNameString, sizeof(pIt->achNameSeg))) 210 { 211 pNsEntry = pIt; 212 fFound = true; 213 break; 214 } 215 } 216 217 /* The name path is invalid. */ 218 if (!fFound) 219 return NULL; 220 221 pszNameString += 4; 222 } while (*pszNameString++ == '.'); 223 224 return pNsEntry; 225 } 226 227 228 /** 159 229 * Adds a new entry in the given namespace under the given path. 160 230 * … … 163 233 * @param pszNameString The namestring to add. 164 234 * @param fSwitchTo Flag whether to switch to the new entry. 235 * @param fIgnoreExisting Flag whether to ignore any existing entry in the namespace parents. 165 236 * @param ppNsEntry Where to store the pointer to the created entry on success. 166 237 */ 167 static int rtAcpiNsAddEntryWorker(PRTACPINSROOT pNsRoot, const char *pszNameString, bool fSwitchTo, PRTACPINSENTRY *ppNsEntry)238 static int rtAcpiNsAddEntryWorker(PRTACPINSROOT pNsRoot, const char *pszNameString, bool fSwitchTo, bool fIgnoreExisting, PRTACPINSENTRY *ppNsEntry) 168 239 { 169 240 AssertReturn( !fSwitchTo 170 241 || pNsRoot->idxNsStack < RT_ELEMENTS(pNsRoot->aNsStack), 171 242 VERR_INVALID_STATE); 243 244 /* Does it exist already? */ 245 if (!fIgnoreExisting) 246 { 247 PRTACPINSENTRY pNsEntry = rtAcpiNsLookupWorker(pNsRoot, pszNameString, false /*fExcludeLast*/, NULL); 248 if (pNsEntry) 249 { 250 *ppNsEntry = pNsEntry; 251 if (fSwitchTo) 252 pNsRoot->aNsStack[++pNsRoot->idxNsStack] = pNsEntry; 253 return VERR_ALREADY_EXISTS; 254 } 255 } 172 256 173 257 int rc; … … 209 293 pNsRoot->idxNsStack = 0; 210 294 pNsRoot->aNsStack[pNsRoot->idxNsStack] = &pNsRoot->RootEntry; 295 /* Create the default scopes. */ 296 int rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_SB_", NULL /*pAstNd*/, false /*fSwitchTo*/); 297 if (RT_SUCCESS(rc)) 298 rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_PR_", NULL /*pAstNd*/, false /*fSwitchTo*/); 299 if (RT_SUCCESS(rc)) 300 rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_GPE", NULL /*pAstNd*/, false /*fSwitchTo*/); 301 if (RT_SUCCESS(rc)) 302 rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_SI_", NULL /*pAstNd*/, false /*fSwitchTo*/); 303 if (RT_SUCCESS(rc)) 304 rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_TZ_", NULL /*pAstNd*/, false /*fSwitchTo*/); 305 Assert(RT_SUCCESS(rc) || rc == VERR_NO_MEMORY); 306 if (RT_FAILURE(rc)) 307 { 308 RTMemFree(pNsRoot); 309 pNsRoot = NULL; 310 } 211 311 } 212 312 return pNsRoot; … … 226 326 227 327 328 DECLHIDDEN(int) rtAcpiNsSwitchTo(PRTACPINSROOT pNsRoot, const char *pszNameString) 329 { 330 PRTACPINSENTRY pNsEntry = rtAcpiNsLookup(pNsRoot, pszNameString); 331 if (!pNsEntry) 332 return VERR_NOT_FOUND; 333 334 pNsRoot->aNsStack[++pNsRoot->idxNsStack] = pNsEntry; 335 return VINF_SUCCESS; 336 } 337 338 228 339 DECLHIDDEN(int) rtAcpiNsAddEntryAstNode(PRTACPINSROOT pNsRoot, const char *pszNameString, PCRTACPIASTNODE pAstNd, bool fSwitchTo) 229 340 { 230 341 PRTACPINSENTRY pNsEntry = NULL; 231 int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, fSwitchTo, &pNsEntry); 342 int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, fSwitchTo, false /*fIgnoreExisting*/, &pNsEntry); 343 if (rc == VERR_ALREADY_EXISTS) 344 rc = VINF_SUCCESS; 232 345 if (RT_SUCCESS(rc)) 233 346 { … … 243 356 { 244 357 PRTACPINSENTRY pNsEntry = NULL; 245 int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, &pNsEntry);358 int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, true /*fIgnoreExisting*/, &pNsEntry); 246 359 if (RT_SUCCESS(rc)) 247 360 { … … 259 372 { 260 373 PRTACPINSENTRY pNsEntry = NULL; 261 int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, &pNsEntry);374 int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, false /*fIgnoreExisting*/, &pNsEntry); 262 375 if (RT_SUCCESS(rc)) 263 376 { … … 350 463 351 464 465 DECLHIDDEN(int) rtAcpiNsCompressNameString(PCRTACPINSROOT pNsRoot, PCRTACPINSENTRY pNsEntry, const char *pszNameString, char *pszNameStringComp, size_t cchNameStringComp) 466 { 467 size_t cchNameString = strlen(pszNameString); 468 if (cchNameString > cchNameStringComp) 469 return VERR_BUFFER_OVERFLOW; 470 471 if ( *pszNameString != '\\' 472 || pNsEntry != rtAcpiNsGetCurrent(pNsRoot)) 473 { 474 memcpy(pszNameStringComp, pszNameString, cchNameString + 1); 475 return VINF_SUCCESS; 476 } 477 478 /* Try to remove as many components as possible. */ 479 uint32_t cEntries = 0; 480 PCRTACPINSENTRY aNsEntries[255]; /* Maximum amount of name segments possible. */ 481 do 482 { 483 aNsEntries[cEntries++] = pNsEntry; 484 pNsEntry = pNsEntry->pParent; 485 } while (pNsEntry); 486 487 Assert(cEntries > 0); /* Should have at least the root entry. */ 488 489 /* Remove the \ specifier. */ 490 pszNameString++; 491 cchNameString--; 492 uint32_t idxEntry = 1; 493 while (idxEntry < cEntries) 494 { 495 pNsEntry = aNsEntries[idxEntry++]; 496 if (memcmp(pszNameString, &pNsEntry->achNameSeg[0], sizeof(pNsEntry->achNameSeg))) 497 break; 498 499 Assert(pszNameString[4] == '.'); 500 pszNameString += 5; 501 cchNameString -= 5; 502 } 503 504 /* The remaining string is what we end up with. */ 505 memcpy(pszNameStringComp, pszNameString, cchNameString + 1); 506 return VINF_SUCCESS; 507 } 508 509 510 DECLHIDDEN(int) rtAcpiNsAbsoluteNameStringToRelative(PRTACPINSROOT pNsRoot, PCRTACPINSENTRY pNsEntrySrc, const char *pszNameStringDst, char *pszNameStringRel, size_t cchNameStringRel) 511 { 512 size_t cchNameStringDst = strlen(pszNameStringDst); 513 if (cchNameStringDst > cchNameStringRel) 514 return VERR_BUFFER_OVERFLOW; 515 516 /* Init with the default. */ 517 memcpy(pszNameStringRel, pszNameStringDst, cchNameStringDst + 1); 518 if (*pszNameStringDst != '\\') 519 return VINF_SUCCESS; 520 521 PCRTACPINSENTRY pNsDst = rtAcpiNsLookup(pNsRoot, pszNameStringDst); 522 AssertReturn(pNsDst, VERR_NOT_FOUND); 523 524 uint32_t cEntriesSrc = 0; 525 PCRTACPINSENTRY aNsEntriesSrc[255]; /* Maximum amount of name segments possible. */ 526 do 527 { 528 aNsEntriesSrc[cEntriesSrc++] = pNsEntrySrc; 529 pNsEntrySrc = pNsEntrySrc->pParent; 530 } while (pNsEntrySrc); 531 532 uint32_t cEntriesDst = 0; 533 PCRTACPINSENTRY aNsEntriesDst[255]; /* Maximum amount of name segments possible. */ 534 do 535 { 536 aNsEntriesDst[cEntriesDst++] = pNsDst; 537 pNsDst = pNsDst->pParent; 538 } while (pNsDst); 539 540 Assert(cEntriesSrc > 0 && cEntriesDst > 0); /* Should have at least the root entry. */ 541 uint32_t idxEntrySrc = cEntriesSrc; 542 idxEntrySrc--; 543 cEntriesDst--; 544 Assert(aNsEntriesSrc[idxEntrySrc] == aNsEntriesDst[cEntriesDst]); 545 546 /* Remove the \ specifier. */ 547 size_t cchNameStringNew = cchNameStringDst; 548 pszNameStringDst++; 549 cchNameStringNew--; 550 551 /* Find the first different path entry. */ 552 while ( idxEntrySrc 553 && cEntriesDst) 554 { 555 if ( aNsEntriesSrc[--idxEntrySrc] != aNsEntriesDst[--cEntriesDst] 556 || pszNameStringDst[4] == '\0') 557 break; 558 559 Assert(pszNameStringDst[4] == '.'); 560 pszNameStringDst += 5; 561 cchNameStringNew -= 5; 562 } 563 564 /* 565 * Calculate how many parent prefixes we need to add. 566 * If the remaining name path is just a segment it must be a 567 * direct parent of the source and can be written as a simple name segment 568 * due to the default search rules. 569 */ 570 uint32_t cParentPrefixes = ( rtAcpiNsLookupSubTree(aNsEntriesSrc[idxEntrySrc], pszNameStringDst) 571 || pszNameStringDst[4] == '\0') 572 ? 0 573 : idxEntrySrc + 1; 574 /* Only overwrite with our result if it is shorter. */ 575 if (cParentPrefixes + cchNameStringNew < cchNameStringDst) 576 { 577 for (uint32_t i = 0; i < cParentPrefixes; i++) 578 pszNameStringRel[i] = '^'; 579 memcpy(&pszNameStringRel[cParentPrefixes], pszNameStringDst, cchNameStringNew + 1); 580 } 581 return VINF_SUCCESS; 582 } 583 584 352 585 DECLHIDDEN(int) rtAcpiNsPop(PRTACPINSROOT pNsRoot) 353 586 { … … 358 591 359 592 360 DECLHIDDEN(P CRTACPINSENTRY) rtAcpiNsLookup(PRTACPINSROOT pNsRoot, const char *pszNameString)593 DECLHIDDEN(PRTACPINSENTRY) rtAcpiNsLookup(PRTACPINSROOT pNsRoot, const char *pszNameString) 361 594 { 362 595 return rtAcpiNsLookupWorker(pNsRoot, pszNameString, false /*fExcludeLast*/, NULL /*ppszNameSegLast*/); 363 596 } 597 598 599 DECLHIDDEN(PCRTACPINSENTRY) rtAcpiNsGetCurrent(PCRTACPINSROOT pNsRoot) 600 { 601 return pNsRoot->aNsStack[pNsRoot->idxNsStack]; 602 }
Note:
See TracChangeset
for help on using the changeset viewer.