Changeset 48452 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Sep 12, 2013 3:13:26 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 88908
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/DevEFI.cpp
r48400 r48452 32 32 #include <iprt/asm.h> 33 33 #include <iprt/assert.h> 34 #include <iprt/ctype.h> 34 35 #include <iprt/file.h> 35 36 #include <iprt/mem.h> … … 86 87 /** Pointer to an EFI NVRAM variable. */ 87 88 typedef EFIVAR *PEFIVAR; 89 /** Pointer to a const EFI NVRAM variable. */ 90 typedef EFIVAR const *PCEFIVAR; 88 91 /** Pointer to an EFI NVRAM variable pointer. */ 89 92 typedef PEFIVAR *PPEFIVAR; … … 330 333 } 331 334 335 336 /** 337 * Inserts the EFI variable into the list. 338 * 339 * This enforces the desired list ordering and/or insertion policy. 340 * 341 * @param pThis The EFI state. 342 * @param pEfiVar The variable to insert. 343 */ 344 static void nvramInsertVariable(PDEVEFI pThis, PEFIVAR pEfiVar) 345 { 346 #if 1 347 /* 348 * Sorted by UUID and name. 349 */ 350 PEFIVAR pCurVar; 351 RTListForEach(&pThis->NVRAM.VarList, pCurVar, EFIVAR, ListNode) 352 { 353 int iDiff = RTUuidCompare(&pEfiVar->uuid, &pCurVar->uuid); 354 if (!iDiff) 355 iDiff = strcmp(pEfiVar->szName, pCurVar->szName); 356 if (iDiff < 0) 357 { 358 RTListNodeInsertBefore(&pCurVar->ListNode, &pEfiVar->ListNode); 359 return; 360 } 361 } 362 #endif 363 364 /* 365 * Add it at the end. 366 */ 367 RTListAppend(&pThis->NVRAM.VarList, &pEfiVar->ListNode); 368 } 369 370 332 371 /** 333 372 * Creates an device internal list of variables. … … 372 411 373 412 /* Append it. */ 374 RTListAppend((PRTLISTNODE)&pThis->NVRAM.VarList, &pEfiVar->ListNode);413 nvramInsertVariable(pThis, pEfiVar); 375 414 pThis->NVRAM.cVariables++; 376 415 } … … 602 641 memcpy(pEfiVar->abValue, pThis->NVRAM.VarOpBuf.abValue, pEfiVar->cbValue); 603 642 604 RTListAppend(&pThis->NVRAM.VarList, &pEfiVar->ListNode); 643 nvramInsertVariable(pThis, pEfiVar); 644 pThis->NVRAM.cVariables++; 605 645 pThis->NVRAM.u32Status = EFI_VARIABLE_OP_STATUS_OK; 606 pThis->NVRAM.cVariables++;607 646 } 608 647 else … … 867 906 } 868 907 908 909 /** 910 * Checks if the EFI variable value looks like a printable UTF-8 string. 911 * 912 * @returns true if it is, false if not. 913 * @param pEfiVar The variable. 914 * @param pfZeroTerm Where to return whether the string is zero 915 * terminated. 916 */ 917 static bool efiInfoNvramIsUtf8(PCEFIVAR pEfiVar, bool *pfZeroTerm) 918 { 919 if (pEfiVar->cbValue < 2) 920 return false; 921 const char *pachValue = (const char *)&pEfiVar->abValue[0]; 922 *pfZeroTerm = pachValue[pEfiVar->cbValue - 1] == 0; 923 924 /* Check the length. */ 925 size_t cchValue = RTStrNLen((const char *)pEfiVar->abValue, pEfiVar->cbValue); 926 if (cchValue != pEfiVar->cbValue - *pfZeroTerm) 927 return false; /* stray zeros in the value, forget it. */ 928 929 /* Check that the string is valid UTF-8 and printable. */ 930 const char *pchCur = pachValue; 931 while ((uintptr_t)(pchCur - pachValue) < cchValue) 932 { 933 RTUNICP uc; 934 int rc = RTStrGetCpEx(&pachValue, &uc); 935 if (RT_FAILURE(rc)) 936 return false; 937 /** @todo Missing RTUniCpIsPrintable. */ 938 if (uc < 128 && !RT_C_IS_PRINT(uc)) 939 return false; 940 } 941 942 return true; 943 } 944 945 946 /** 947 * Checks if the EFI variable value looks like a printable UTF-16 string. 948 * 949 * @returns true if it is, false if not. 950 * @param pEfiVar The variable. 951 * @param pfZeroTerm Where to return whether the string is zero 952 * terminated. 953 */ 954 static bool efiInfoNvramIsUtf16(PCEFIVAR pEfiVar, bool *pfZeroTerm) 955 { 956 if (pEfiVar->cbValue < 4 || (pEfiVar->cbValue & 1)) 957 return false; 958 959 PCRTUTF16 pwcValue = (PCRTUTF16)&pEfiVar->abValue[0]; 960 size_t cwcValue = pEfiVar->cbValue / sizeof(RTUTF16); 961 *pfZeroTerm = pwcValue[cwcValue - 1] == 0; 962 if (!*pfZeroTerm && RTUtf16IsHighSurrogate(pwcValue[cwcValue - 1])) 963 return false; /* Catch bad string early, before reading a char too many. */ 964 cwcValue -= *pfZeroTerm; 965 if (cwcValue < 2) 966 return false; 967 968 /* Check that the string is valid UTF-16, printable and spans the whole 969 value length. */ 970 size_t cAscii = 0; 971 PCRTUTF16 pwcCur = pwcValue; 972 while ((uintptr_t)(pwcCur - pwcValue) < cwcValue) 973 { 974 RTUNICP uc; 975 int rc = RTUtf16GetCpEx(&pwcCur, &uc); 976 if (RT_FAILURE(rc)) 977 return false; 978 /** @todo Missing RTUniCpIsPrintable. */ 979 if (uc < 128 && !RT_C_IS_PRINT(uc)) 980 return false; 981 cAscii += uc < 128; 982 } 983 if (cAscii < 2) 984 return false; 985 986 return true; 987 } 988 989 869 990 /** 870 991 * @implement_callback_method{FNDBGFHANDLERDEV} … … 876 997 877 998 pHlp->pfnPrintf(pHlp, "NVRAM variables: %u\n", pThis->NVRAM.cVariables); 878 P EFIVAR pEfiVar;999 PCEFIVAR pEfiVar; 879 1000 RTListForEach(&pThis->NVRAM.VarList, pEfiVar, EFIVAR, ListNode) 880 1001 { 881 pHlp->pfnPrintf(pHlp, 882 "Variable - fAttr=%#04x - '%RTuuid:%s' - cb=%#04x\n" 883 "%.*Rhxd\n", 884 pEfiVar->fAttributes, &pEfiVar->uuid, pEfiVar->szName, pEfiVar->cbValue, 885 pEfiVar->cbValue, pEfiVar->abValue); 1002 /* Detect UTF-8 and UTF-16 strings. */ 1003 bool fZeroTerm = false; 1004 if (efiInfoNvramIsUtf8(pEfiVar, &fZeroTerm)) 1005 pHlp->pfnPrintf(pHlp, 1006 "Variable - fAttr=%#04x - '%RTuuid:%s' - cb=%#04x\n" 1007 "String value (UTF-8%s): \"%.*s\"\n", 1008 pEfiVar->fAttributes, &pEfiVar->uuid, pEfiVar->szName, pEfiVar->cbValue, 1009 fZeroTerm ? "" : ",nz", pEfiVar->cbValue, pEfiVar->abValue); 1010 else if (efiInfoNvramIsUtf16(pEfiVar, &fZeroTerm)) 1011 pHlp->pfnPrintf(pHlp, 1012 "Variable - fAttr=%#04x - '%RTuuid:%s' - cb=%#04x\n" 1013 "String value (UTF-16%s): \"%.*ls\"\n", 1014 pEfiVar->fAttributes, &pEfiVar->uuid, pEfiVar->szName, pEfiVar->cbValue, 1015 fZeroTerm ? "" : ",nz", pEfiVar->cbValue, pEfiVar->abValue); 1016 else 1017 pHlp->pfnPrintf(pHlp, 1018 "Variable - fAttr=%#04x - '%RTuuid:%s' - cb=%#04x\n" 1019 "%.*Rhxd\n", 1020 pEfiVar->fAttributes, &pEfiVar->uuid, pEfiVar->szName, pEfiVar->cbValue, 1021 pEfiVar->cbValue, pEfiVar->abValue); 1022 886 1023 } 887 1024 … … 1317 1454 AssertRCReturnStmt(rc, RTMemFree(pEfiVar), rc); 1318 1455 1319 /* Add it, updating the current variable pointer while we're here. */ 1456 /* Add it (not using nvramInsertVariable to preserve saved order), 1457 updating the current variable pointer while we're here. */ 1458 #if 1 1320 1459 RTListAppend(&pThis->NVRAM.VarList, &pEfiVar->ListNode); 1460 #else 1461 nvramInsertVariable(pThis, pEfiVar); 1462 #endif 1321 1463 if (pThis->NVRAM.idUniqueCurVar == pEfiVar->idUniqueSavedState) 1322 1464 pThis->NVRAM.pCurVar = pEfiVar; … … 1857 1999 N_("Configuration error: Querying \"BootArgs\" as a string failed")); 1858 2000 2001 //strcpy(pThis->szBootArgs, "-v keepsyms=1 io=0xf"); 1859 2002 LogRel(("EFI boot args: %s\n", pThis->szBootArgs)); 1860 2003 … … 1883 2026 1884 2027 /* 1885 * CPU frequencies 1886 */ 1887 /// @todo we need to have VMM API to access TSC increase speed, for now provide reasonable default 1888 pThis->u64TscFrequency = RTMpGetMaxFrequency(0) * 1000 * 1000;// TMCpuTicksPerSecond(PDMDevHlpGetVM(pDevIns)); 1889 if (pThis->u64TscFrequency == 0) 1890 pThis->u64TscFrequency = UINT64_C(2500000000); 1891 /* Multiplier is read from MSR_IA32_PERF_STATUS, and now is hardcoded as 4 */ 2028 * CPU frequencies. 2029 */ 2030 pThis->u64TscFrequency = TMCpuTicksPerSecond(PDMDevHlpGetVM(pDevIns)); 2031 /* Multiplier is read from MSR_IA32_PERF_STATUS, and now is hardcoded as 4. */ 1892 2032 pThis->u64FsbFrequency = pThis->u64TscFrequency / 4; 1893 2033 pThis->u64CpuFrequency = pThis->u64TscFrequency; 1894 2034 1895 2035 /* 1896 * GOP graphics 2036 * GOP graphics. 1897 2037 */ 1898 2038 rc = CFGMR3QueryU32Def(pCfg, "GopMode", &pThis->u32GopMode, 2 /* 1024x768 */); … … 1904 2044 1905 2045 /* 1906 * Uga graphics. 1907 */ 1908 rc = CFGMR3QueryU32Def(pCfg, "UgaHorizontalResolution", &pThis->cxUgaResolution, 0); AssertRC(rc); 1909 if (pThis->cxUgaResolution == 0) 1910 pThis->cxUgaResolution = 1024; /* 1024x768 */ 1911 rc = CFGMR3QueryU32Def(pCfg, "UgaVerticalResolution", &pThis->cyUgaResolution, 0); AssertRC(rc); 1912 if (pThis->cyUgaResolution == 0) 1913 pThis->cyUgaResolution = 768; /* 1024x768 */ 2046 * Uga graphics, default to 1024x768. 2047 */ 2048 rc = CFGMR3QueryU32Def(pCfg, "UgaHorizontalResolution", &pThis->cxUgaResolution, 0); 2049 AssertRCReturn(rc, rc); 2050 rc = CFGMR3QueryU32Def(pCfg, "UgaVerticalResolution", &pThis->cyUgaResolution, 0); 2051 AssertRCReturn(rc, rc); 2052 if (pThis->cxUgaResolution == 0 || pThis->cyUgaResolution == 0) 2053 { 2054 pThis->cxUgaResolution = 1024; 2055 pThis->cyUgaResolution = 768; 2056 } 1914 2057 1915 2058 #ifdef DEVEFI_WITH_VBOXDBG_SCRIPT
Note:
See TracChangeset
for help on using the changeset viewer.