support nvram in legacy boot

Signed-off-by: Slice <sergey.slice@gmail.com>
This commit is contained in:
Slice 2023-09-04 21:56:03 +03:00
parent 7d21f54ad6
commit 99fa51da2f
4 changed files with 50 additions and 148 deletions

View File

@ -930,7 +930,7 @@ LoadNvramPlist(
return Status;
}
#define SEARCH_ONLY_EFI 1
#define SEARCH_ONLY_EFI 0
/** Searches all volumes for the most recent nvram.plist and loads it into gNvramDict. */
EFI_STATUS
LoadLatestNvramPlist()
@ -1098,17 +1098,15 @@ LoadLatestNvramPlist()
return Status;
}
void PutDictToNvram(TagDict* NvramDict, size_t count, EFI_GUID& VendorGuid);
/** Puts all vars from nvram.plist to RT vars. Should be used in CloverEFI only
* or if some UEFI boot uses EmuRuntimeDxe driver.
*/
void
PutNvramPlistToRtVars ()
void PutNvramPlistToRtVars()
{
// EFI_STATUS Status;
// const TagStruct* ValTag;
INTN Size;
const VOID *Value;
if (gNvramDict == NULL) {
/*Status = */LoadLatestNvramPlist();
@ -1120,18 +1118,50 @@ PutNvramPlistToRtVars ()
DbgHeader("PutNvramPlistToRtVars");
const TagKey* keyTag;
const TagDict* keyDict;
const TagStruct* valueTag;
EFI_GUID VendorGuid = gEfiAppleBootGuid;
// iterate over dict elements
size_t count = gNvramDict->dictKeyCount(); // ok
DBG("dict count = %ld\n", count);
gNvramDict->getKeyAndValueAtIndex(0, &keyTag, &valueTag);
if (valueTag->isDict()) {
// this is nvram.plist version 2
for (size_t tagIdx = 0 ; tagIdx < count ; tagIdx++ ) {
if ( EFI_ERROR(gNvramDict->getKeyAndValueAtIndex(tagIdx, &keyTag, &valueTag)) ) { //If GetKeyValueAtIndex return success, key and value != NULL
MsgLog("MALFORMED PLIST nvram.plist. A key is expected at pos : %zu\n", tagIdx);
continue;
}
keyDict = static_cast<const TagDict*>(valueTag);
// Key -> VendorGuid
VendorGuid.takeValueFrom(keyTag->keyStringValue());
size_t dictCount= keyDict->dictKeyCount();
DBG("got GUID: %08X-%04X-%04X...\n", VendorGuid.Data1, VendorGuid.Data2, VendorGuid.Data3);
PutDictToNvram(const_cast<TagDict*>(keyDict), dictCount, VendorGuid);
//
}
} else {
// there is version 1
PutDictToNvram(gNvramDict, count, gEfiAppleBootGuid);
}
}
void PutDictToNvram(TagDict* NvramDict, size_t count, EFI_GUID& VendorGuid)
{
INTN Size = 0;
const VOID *Value = nullptr;
for (size_t tagIdx = 0 ; tagIdx < count ; tagIdx++ )
{
const TagKey* keyTag;
const TagStruct* valueTag;
if ( EFI_ERROR(gNvramDict->getKeyAndValueAtIndex(tagIdx, &keyTag, &valueTag)) ) { //If GetKeyValueAtIndex return success, key and value != NULL
if ( EFI_ERROR(NvramDict->getKeyAndValueAtIndex(tagIdx, &keyTag, &valueTag)) ) { //If GetKeyValueAtIndex return success, key and value != NULL
MsgLog("MALFORMED PLIST nvram.plist. A key is expected at pos : %zu\n", tagIdx);
continue;
}
EFI_GUID VendorGuid = gEfiAppleBootGuid;
// process only valid <key> tags
if ( valueTag == NULL ) {
// DBG(" ERROR: ValTag is not NULL\n");
@ -1153,41 +1183,34 @@ PutNvramPlistToRtVars ()
continue;
}
if (keyTag->keyStringValue() == "Boot0082"_XS8 ||
keyTag->keyStringValue() == "BootNext"_XS8 ) {
VendorGuid = gEfiGlobalVariableGuid;
// it may happen only in this case
gSettings.Boot.HibernationFixup = true;
}
// if (keyTag->keyStringValue() == "Boot0082"_XS8 ||
// keyTag->keyStringValue() == "BootNext"_XS8 ) {
// VendorGuid = gEfiGlobalVariableGuid;
// // it may happen only in this case
// gSettings.Boot.HibernationFixup = true;
// }
XStringW KeyBuf = keyTag->keyStringValue();
DBG(" Adding Key: %ls: ", KeyBuf.wc_str());
// AsciiStrToUnicodeStrS(Tag.stringValue(), KeyBuf, 128);
XStringW KeyBuf = keyTag->keyStringValue();
// if (!gSettings.Boot.DebugLog) {
DBG(" Adding Key: %ls: ", KeyBuf.wc_str());
// }
// process value tag
if (valueTag->isString()) {
// <string> element
Value = (void*)valueTag->getString()->stringValue().c_str();
Size = valueTag->getString()->stringValue().length();
// if (!gSettings.Boot.DebugLog) {
DBG("String: Size = %llu, Val = '%s'\n", Size, valueTag->getString()->stringValue().c_str());
// }
DBG("String: Size = %llu, Val = '%s'\n", Size, valueTag->getString()->stringValue().c_str());
} else if (valueTag->isData()) {
// <data> element
Size = valueTag->getData()->dataLenValue();
Value = valueTag->getData()->dataValue();
// if (gSettings.Boot.DebugLog) {
DBG("Size = %llu, Data: ", Size);
for (INTN i = 0; i < Size; i++) {
DBG("%02hhX ", *(((UINT8*)Value) + i));
}
// }
// if (!gSettings.Boot.DebugLog) {
DBG("\n");
//
} else {
DBG("ERROR: Unsupported tag type: %s\n", valueTag->getTypeAsXString8().c_str());
continue;

View File

@ -75,95 +75,7 @@ EFI_STATUS FixDataMatchingTag( CHAR8* buffer, CONST CHAR8* tag,UINT32* lenPtr);
#include "TagFloat.h"
#include "TagInt64.h"
#include "TagString8.h"
//
////UINTN newtagcount = 0;
////UINTN tagcachehit = 0;
//TagStruct* TagStruct::getEmptyTag()
//{
// TagStruct* tag;
//
// if ( gTagsFree.size() > 0 ) {
// tag = &gTagsFree[0];
// gTagsFree.RemoveWithoutFreeingAtIndex(0);
////tagcachehit++;
////DBG("tagcachehit=%lld\n", tagcachehit);
// return tag;
// }
// tag = new TagStruct;
////newtagcount += 1;
////DBG("newtagcount=%lld\n", newtagcount);
// return tag;
//}
//
//TagStruct* TagStruct::getEmptyDictTag()
//{
// TagStruct* newDictTag = getEmptyTag();
// newDictTag->type = kTagTypeDict;
// return newDictTag;
//}
//
//TagStruct* TagStruct::getEmptyArrayTag()
//{
// TagStruct* newArrayTag = getEmptyTag();
// newArrayTag->type = kTagTypeArray;
// return newArrayTag;
//}
//void TagStruct::FreeTag()
//{
// // Clear and free the tag.
// type = kTagTypeNone;
//
// _string.setEmpty();
// _intValue = 0;
// _floatValue = 0;
//
// if ( _data ) {
// FreePool(_data);
// _data = NULL;
// }
// _dataLen = 0;
//
// //while ( tagIdx < _dictOrArrayContent.notEmpty() ) {
// // _dictOrArrayContent[0].FreeTag();
// // _dictOrArrayContent.RemoveWithoutFreeingAtIndex(0);
// //}
// // this loop is better because removing objects from the end don't do any memory copying.
// for (size_t tagIdx = _dictOrArrayContent.size() ; tagIdx > 0 ; ) {
// tagIdx--;
// _dictOrArrayContent[tagIdx].FreeTag();
// _dictOrArrayContent.RemoveWithoutFreeingAtIndex(tagIdx);
// }
//
// gTagsFree.AddReference(this, false);
//}
//TagStruct* GetNextProperty(TagStruct* dict)
//{
// TagStruct* tagList, tag;
//
// if (dict->isDict()) {
// return NULL;
// }
//
// tag = NULL;
// tagList = dict->tag;
// while (tagList)
// {
// tag = tagList;
// tagList = tag->tagNext;
//
// if ( !tag->isKey() || tag->keyValue().isEmpty() ) {
// continue;
//
// }
// return tag->tag;
// }
//
// return NULL;
//}
//
XBool TagStruct::debugIsEqual(const TagStruct& other, const XString8& label) const
{

View File

@ -152,7 +152,6 @@ public:
// Cannot happen if validate has been done properly.
panic("invalid DDRx value");
}
// XBool dgetInUse() const { return Size.isDefined() ? Size.value() > 0 : false; };
};
@ -193,7 +192,7 @@ public:
return max+1;
};
const ModuleDictClass& dgetSoltAtIndex(size_t slotIndex) const {
const ModuleDictClass& dgetSlotAtIndex(size_t slotIndex) const {
for ( size_t idx = 0; idx < size(); ++idx ) {
if ( ElementAt(idx).dgetSlotIndex() == slotIndex )
return ElementAt(idx);
@ -288,7 +287,6 @@ public:
}
const decltype(Device)::ValueType& dgetDevice() const { return Device.isDefined() ? Device.value() : Device.nullValue; };
uint8_t dgetDeviceN() const {
// if ( !Device.isDefined() ) panic("%s: invalid value. Check validate method.", __PRETTY_FUNCTION__);
if ( !Device.isDefined() ) return 0;
if (Device.value().isEqualIC("ATI")) {
return 0;
@ -528,11 +526,8 @@ public:
}
}
if ( EfiVersion.isDefined() ) {
// DebugLog(1, "have EfiVersion=%s\n", EfiVersion.value().c_str());
long long int result = AsciiStrVersionToUint64(ApplePlatformDataArray[dgetModel()].efiversion, 4, 3);
long long int result2 = AsciiStrVersionToUint64(EfiVersion.value(), 4, 3);
// DebugLog(1, "make uint64=%lld vs %lld\n", result, result2);
// DebugLog(1, "compare 1715 %c 1968\n", (result > result2)? '>':'<');
if ( result > result2) {
xmlLiteParser->addWarning(generateErrors, S8Printf("EfiVersion '%s' is older than default ('%s') -> ignored. Dict '%s:%d'.", EfiVersion.value().c_str(), ApplePlatformDataArray[dgetModel()].efiversion.c_str(), xmlPath.c_str(), keyPos.getLine())); // Do not set b to false : we don't want to invalidate the whole dict
xmlLiteParser->productNameNeeded = !getProductName().isDefined();
@ -748,12 +743,6 @@ public:
if ( ExtendedFirmwareFeaturesMask.isDefined() ) return ExtendedFirmwareFeaturesMask.value();
return GetExtFwFeaturesMask(dgetModel());
};
// decltype(FirmwareFeatures)::ValueType dgetFirmwareFeatures() const {
// if ( FirmwareFeatures.isDefined() ) return FirmwareFeatures.value();
// return GetFwFeatures(dgetModel());
// };
};
SmbiosDictClass SMBIOS = SmbiosDictClass();
@ -804,8 +793,6 @@ public:
}
return SMBIOS;
};
};

View File

@ -426,15 +426,6 @@ XBool XmlLiteParser::getSimpleTagValue(const char* expectedTag, size_t expectedT
addXmlError(generateErrors, S8Printf("Expecting a <%s> at line %d col %d", expectedTag, (*xmlParserPosition).line, (*xmlParserPosition).col));
return false;
}
// if ( *valueLength == 0 ) {
// return false;
// // todo Msg
// }
// if ( **value == '#' ) {
// b = skipNextTag();
// if ( !b ) return false;
// return getSimpleTagValue(expectedTag, expectedTagLength, value, valueLength, xmlParserPosition, generateErrors);
// }
return true;
}
@ -463,17 +454,6 @@ printf("\n");
currentPos = *xmlParserPosition;
return false;
}
// if ( *valueLength == 0 ) {
// if ( generateErrors ) addWarning(S8Printf("Expecting text for key tag at line %d col %d. SKipped\n", (*xmlParserPosition).line, (*xmlParserPosition).col));
// b = skipNextTag();
// if ( !b ) return false;
// return getKeyTagValue(value, valueLength, xmlParserPosition, generateErrors);
// }
// if ( **value == '#' ) {
// b = skipNextTag();
// if ( !b ) return false;
// return getKeyTagValue(value, valueLength, xmlParserPosition, generateErrors);
// }
return true;
}