CloverBootloader/rEFIt_UEFI/Platform/DataHubCpu.c

545 lines
20 KiB
C
Raw Normal View History

//
/// @file rEFIt_UEFI/Platform/DataHubCpu.c
///
/// VirtualBox CPU descriptors
///
/// VirtualBox CPU descriptors also used to set OS X-used NVRAM variables and DataHub data
///
// Copyright(C) 2009-2010 Oracle Corporation
//
// This file is part of VirtualBox Open Source Edition(OSE), as
// available from http://www.virtualbox.org. This file is free software;
// you can redistribute it and/or modify it under the terms of the GNU
// General Public License(GPL) as published by the Free Software
// Foundation, in version 2 as it comes in the "COPYING" file of the
// VirtualBox OSE distribution. VirtualBox OSE is distributed in the
// hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
//
// CHANGELOG:
//
// 2019/06/08
// vector sigma
// don't inject REV, RBr and EPCI keys if gSettings.REV is zeroed
//
#ifndef DEBUG_ALL
#define DEBUG_DH 1
#else
#define DEBUG_DH DEBUG_ALL
#endif
#if DEBUG_DH == 0
#define DBG(...)
#else
#define DBG(...) DebugLog(DEBUG_DH, __VA_ARGS__)
#endif
#include "Platform.h"
//#include "Version.h"
#include <Guid/DataHubRecords.h>
#define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
// gDataHub
/// A pointer to the DataHubProtocol
EFI_DATA_HUB_PROTOCOL *gDataHub;
EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader = {
EFI_PROCESSOR_SUBCLASS_VERSION, // Version
sizeof(EFI_SUBCLASS_TYPE1_HEADER), // Header Size
0, // Instance (initialize later)
EFI_SUBCLASS_INSTANCE_NON_APPLICABLE, // SubInstance
0 // RecordType (initialize later)
};
// gDataHubPlatformGuid
/// The GUID of the DataHubProtocol
EFI_GUID gDataHubPlatformGuid = {
0x64517cc8, 0x6561, 0x4051, { 0xb0, 0x3c, 0x59, 0x64, 0xb6, 0x0f, 0x4c, 0x7a }
};
extern EFI_GUID gDataHubPlatformGuid;
extern APPLE_SMC_IO_PROTOCOL *gAppleSmc;
extern UINTN RtVariablesNum;
extern RT_VARIABLES *RtVariables;
typedef union {
EFI_CPU_DATA_RECORD *DataRecord;
UINT8 *Raw;
} EFI_CPU_DATA_RECORD_BUFFER;
// PLATFORM_DATA
/// The struct passed to "LogDataHub" holing key and value to be added
#pragma pack(1)
typedef struct {
EFI_SUBCLASS_TYPE1_HEADER Hdr; /// 0x48
UINT32 NameLen; /// 0x58 (in bytes)
UINT32 ValLen; /// 0x5c
UINT8 Data[1]; /// 0x60 Name Value
} PLATFORM_DATA;
#pragma pack()
// CopyRecord
/// Copy the data provided in arguments into a PLATFORM_DATA buffer
///
/// @param Rec The buffer the data should be copied into
/// @param Name The value for the member "name"
/// @param Val The data the object should have
/// @param ValLen The length of the parameter "Val"
///
/// @return The size of the new PLATFORM_DATA object is returned
UINT32 EFIAPI
CopyRecord(IN PLATFORM_DATA *Rec,
IN CONST CHAR16 *Name,
IN VOID *Val,
IN UINT32 ValLen)
{
CopyMem(&Rec->Hdr, &mCpuDataRecordHeader, sizeof(EFI_SUBCLASS_TYPE1_HEADER));
Rec->NameLen = (UINT32)StrLen(Name) * sizeof(CHAR16);
Rec->ValLen = ValLen;
CopyMem(Rec->Data, Name, Rec->NameLen);
CopyMem(Rec->Data + Rec->NameLen, Val, ValLen);
return (sizeof(EFI_SUBCLASS_TYPE1_HEADER) + 8 + Rec->NameLen + Rec->ValLen);
}
// LogDataHub
/// Adds a key-value-pair to the DataHubProtocol
EFI_STATUS EFIAPI
LogDataHub(IN EFI_GUID *TypeGuid,
IN CHAR16 *Name,
IN VOID *Data,
IN UINT32 DataSize)
{
UINT32 RecordSize;
EFI_STATUS Status;
PLATFORM_DATA *PlatformData;
PlatformData = (PLATFORM_DATA*)AllocatePool(sizeof(PLATFORM_DATA) + DataSize + EFI_CPU_DATA_MAXIMUM_LENGTH);
if (PlatformData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
RecordSize = CopyRecord(PlatformData, Name, Data, DataSize);
Status = gDataHub->LogData(gDataHub,
TypeGuid, // DataRecordGuid
&gDataHubPlatformGuid, // ProducerName (always)
EFI_DATA_RECORD_CLASS_DATA,
PlatformData,
RecordSize);
FreePool(PlatformData);
return Status;
}
// SetVariablesForOSX
/** Installs our runtime services overrides. */
/** Original runtime services. */
EFI_RUNTIME_SERVICES gOrgRS;
EFI_STATUS EFIAPI
OvrSetVariable(
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
)
{
EFI_STATUS Status;
UINTN i;
for (i = 0; i < RtVariablesNum; i++) {
if (!CompareGuid(&RtVariables[i].VarGuid, VendorGuid)) {
continue;
}
if (!RtVariables[i].Name || RtVariables[i].Name[0] == L'*' || StrCmp(VariableName, RtVariables[i].Name) == 0) {
return EFI_SUCCESS;
}
}
Status = gOrgRS.SetVariable(VariableName, VendorGuid, Attributes, DataSize, Data);
return Status;
}
EFI_STATUS EFIAPI
OvrRuntimeServices(EFI_RUNTIME_SERVICES *RS)
{
EFI_STATUS Status;
CopyMem(&gOrgRS, RS, sizeof(EFI_RUNTIME_SERVICES));
RS->SetVariable = OvrSetVariable;
RS->Hdr.CRC32 = 0;
Status = gBS->CalculateCrc32(RS, RS->Hdr.HeaderSize, &RS->Hdr.CRC32);
return Status;
}
/// Sets the volatile and non-volatile variables used by OS X
EFI_STATUS EFIAPI
SetVariablesForOSX(LOADER_ENTRY *Entry)
{
// The variable names used should be made global constants to prevent them being allocated multiple times
UINT32 Attributes;
UINT32 Color;
CHAR8 *None;
CHAR8 *NvidiaWebValue;
CHAR16 *KbdPrevLang;
UINTN LangLen;
CHAR8 *VariablePtr;
VOID *OldData;
UINT64 os_version = AsciiOSVersionToUint64(Entry->OSVersion);
CHAR8 *PlatformLang;
//
// firmware Variables
//
if (RtVariablesNum > 0) {
OvrRuntimeServices(gRS);
}
// As found on a real Mac, the system-id variable solely has the BS flag
SetNvramVariable(L"system-id",
&gEfiAppleNvramGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof(gUuid),
&gUuid);
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
if (gSettings.RtMLB != NULL) {
if (AsciiStrLen(gSettings.RtMLB) != 17) {
DBG("** Warning: Your MLB is not suitable for iMessage(must be 17 chars long) !\n");
}
SetNvramVariable(L"MLB",
&gEfiAppleNvramGuid,
Attributes,
AsciiStrLen(gSettings.RtMLB),
gSettings.RtMLB);
}
if (gSettings.RtROM != NULL) {
SetNvramVariable(L"ROM",
&gEfiAppleNvramGuid,
Attributes,
gSettings.RtROMLen,
gSettings.RtROM);
}
SetNvramVariable(L"FirmwareFeatures",
&gEfiAppleNvramGuid,
Attributes,
sizeof(gFwFeatures),
&gFwFeatures);
// Download-Fritz: Should be added to SMBIOS or at least to some other config section
AddNvramVariable(L"FirmwareFeaturesMask",
&gEfiAppleNvramGuid,
Attributes,
sizeof(gFwFeaturesMask),
&gFwFeaturesMask);
// HW_MLB and HW_ROM are also around on some Macs with the same values as MLB and ROM
AddNvramVariable(L"HW_BID", &gEfiAppleNvramGuid, Attributes, AsciiStrLen(gSettings.BoardNumber), gSettings.BoardNumber);
//
// OS X non-volatile Variables
//
// note: some gEfiAppleBootGuid vars present in nvram.plist are already set by PutNvramPlistToRtVars()
// we should think how to handle those vars from nvram.plist and ones set here from gSettings
if ((gFirmwareClover && gDriversFlags.EmuVariableLoaded) || gSettings.KbdPrevLang) {
// using AddNvramVariable content instead of calling the function to do LangLen calculation only when necessary
// Do not mess with prev-lang:kbd on UEFI systems without NVRAM emulation; it's OS X's business
KbdPrevLang = L"prev-lang:kbd";
OldData = GetNvramVariable(KbdPrevLang, &gEfiAppleBootGuid, NULL, NULL);
if (OldData == NULL) {
LangLen = 16;
VariablePtr = &gSettings.Language[15];
for (LangLen = 16; ((*VariablePtr == ' ') || (*VariablePtr == 0)) && (LangLen != 0); --LangLen) {
--VariablePtr;
}
gRT->SetVariable(KbdPrevLang, &gEfiAppleBootGuid, Attributes, LangLen, &gSettings.Language);
} else {
FreePool(OldData);
}
} else {
Attributes |= EFI_VARIABLE_NON_VOLATILE;
}
//#define EFI_PLATFORM_LANG_VARIABLE_NAME L"PlatformLang"
PlatformLang = GetNvramVariable(EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, NULL, NULL);
//
// On some platforms with missing gEfiUnicodeCollation2ProtocolGuid EFI_PLATFORM_LANG_VARIABLE_NAME is set
// to the value different from "en-...". This is not going to work with our driver UEFI Shell load failures.
// We did not overwrite EFI_PLATFORM_LANG_VARIABLE_NAME, but it uses some other language.
//
// if (!PlatformLang || AsciiStrnCmp (PlatformLang, "en-", 3)) {
if (!PlatformLang) {
SetNvramVariable(EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid,
Attributes,
6, "en-US");
}
if (PlatformLang) {
FreePool(PlatformLang);
}
None = "none";
AddNvramVariable(L"security-mode", &gEfiAppleBootGuid, Attributes, 5, (VOID*)None);
// we should have two UUID: platform and system
// NO! Only Platform is the best solution
if (!gSettings.InjectSystemID) {
if (gSettings.SmUUIDConfig) {
SetNvramVariable(L"platform-uuid", &gEfiAppleBootGuid, Attributes, 16, &gUuid);
} else {
AddNvramVariable(L"platform-uuid", &gEfiAppleBootGuid, Attributes, 16, &gUuid);
}
}
// Download-Fritz: Do not mess with BacklightLevel; it's OS X's business
if (gMobile) {
if (gSettings.BacklightLevelConfig) {
SetNvramVariable(L"backlight-level", &gEfiAppleBootGuid, Attributes, sizeof(gSettings.BacklightLevel), &gSettings.BacklightLevel);
} else {
AddNvramVariable(L"backlight-level", &gEfiAppleBootGuid, Attributes, sizeof(gSettings.BacklightLevel), &gSettings.BacklightLevel);
}
}
if (gSettings.DefaultBackgroundColor == 0x80000000) {
DeleteNvramVariable(L"DefaultBackgroundColor", &gEfiAppleNvramGuid);
} else {
UINT16 ActualDensity = 0xE1;
UINT16 DensityThreshold = 0x96;
UINT64 ConfigStatus = 0;
Color = gSettings.DefaultBackgroundColor;
AddNvramVariable(L"DefaultBackgroundColor", &gEfiAppleNvramGuid, Attributes, 4, &Color);
// add some UI variables
AddNvramVariable(L"ActualDensity", &gEfiAppleBootGuid, Attributes, 2, &ActualDensity);
AddNvramVariable(L"DensityThreshold", &gEfiAppleBootGuid, Attributes, 2, &DensityThreshold);
AddNvramVariable(L"gfx-saved-config-restore-status", &gEfiAppleNvramGuid, Attributes, 8, &ConfigStatus);
}
if (gSettings.UIScale == 0x80000000) {
DeleteNvramVariable(L"UIScale", &gEfiAppleNvramGuid);
} else {
SetNvramVariable(L"UIScale", &gEfiAppleNvramGuid, Attributes, 1, &gSettings.UIScale);
}
if (gSettings.EFILoginHiDPI == 0x80000000) {
DeleteNvramVariable(L"EFILoginHiDPI", &gEfiAppleBootGuid);
} else {
SetNvramVariable(L"EFILoginHiDPI", &gEfiAppleBootGuid, Attributes, 4, &gSettings.EFILoginHiDPI);
}
// ->GetVariable(flagstate, gEfiAppleBootGuid, 0/0, 20, 10FE110) = Not Found
if (gSettings.flagstate[3] == 0x80) {
DeleteNvramVariable(L"flagstate", &gEfiAppleBootGuid);
} else {
SetNvramVariable(L"flagstate", &gEfiAppleBootGuid, Attributes, 32, &gSettings.flagstate);
}
// Hack for recovery by Asgorath
if (gSettings.CsrActiveConfig != 0xFFFF) {
SetNvramVariable(L"csr-active-config", &gEfiAppleBootGuid, Attributes, sizeof(gSettings.CsrActiveConfig), &gSettings.CsrActiveConfig);
}
/*
if (gSettings.BooterConfig != 0) {
SetNvramVariable(L"bootercfg", &gEfiAppleBootGuid, Attributes, sizeof(gSettings.BooterConfig), &gSettings.BooterConfig);
}
*/
INTN CfgStrLen = AsciiStrLen(gSettings.BooterCfgStr);
if (CfgStrLen > 0) {
SetNvramVariable(L"bootercfg", &gEfiAppleBootGuid, Attributes, CfgStrLen+1, &gSettings.BooterCfgStr[0]);
} else {
DeleteNvramVariable(L"bootercfg", &gEfiAppleBootGuid);
}
if (gSettings.NvidiaWeb) {
NvidiaWebValue = "1";
SetNvramVariable(L"nvda_drv", &gEfiAppleBootGuid, Attributes, 2, (VOID*)NvidiaWebValue);
} else {
DeleteNvramVariable(L"nvda_drv", &gEfiAppleBootGuid);
}
if (!gDriversFlags.AptioMemFixLoaded) {
DeleteNvramVariable(L"recovery-boot-mode", &gEfiAppleBootGuid);
}
// Check for AptioFix2Drv loaded to store efi-boot-device for special boot
if (gDriversFlags.AptioFix2Loaded || gDriversFlags.AptioFixLoaded ||
gDriversFlags.AptioFix3Loaded || gDriversFlags.AptioMemFixLoaded) {
EFI_STATUS Status;
REFIT_VOLUME *Volume = Entry->Volume;
EFI_DEVICE_PATH_PROTOCOL *DevicePath = Volume->DevicePath;
// We need to remember from which device we boot, to make silence boot while special recovery boot
Status = gRT->SetVariable(L"specialbootdevice", &gEfiAppleBootGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
GetDevicePathSize(DevicePath), (UINT8 *)DevicePath);
if (EFI_ERROR(Status)) {
DBG("can't set specialbootdevice!\n");
}
}
// Sherlocks: to fix "OSInstall.mpkg appears to be missing or damaged" in 10.13+, we should remove this variables.
if (Entry->LoaderType == OSTYPE_OSX_INSTALLER) {
if (os_version > AsciiOSVersionToUint64("10.12")) {
DeleteNvramVariable(L"install-product-url", &gEfiAppleBootGuid);
DeleteNvramVariable(L"previous-system-uuid", &gEfiAppleBootGuid);
}
}
return EFI_SUCCESS;
}
VOID
AddSMCkey(SMC_KEY Key, SMC_DATA_SIZE Size, SMC_KEY_TYPE Type, SMC_DATA *Data)
{
if (gAppleSmc && (gAppleSmc->Signature == NON_APPLE_SMC_SIGNATURE)) {
gAppleSmc->SmcAddKey(gAppleSmc, Key, Size, Type, 0xC0);
gAppleSmc->SmcWriteValue(gAppleSmc, Key, Size, Data);
}
}
// SetupDataForOSX
/// Sets the DataHub data used by OS X
VOID EFIAPI
SetupDataForOSX(BOOLEAN Hibernate)
{
EFI_STATUS Status;
UINT32 DevPathSupportedVal;
UINT64 FrontSideBus;
UINT64 CpuSpeed;
UINT64 TscFrequency;
UINT64 ARTFrequency;
CHAR16* ProductName;
CHAR16* SerialNumber;
UINTN Revision;
UINT16 Zero = 0;
BOOLEAN isRevLess = (gSettings.REV[0] == 0 &&
gSettings.REV[1] == 0 &&
gSettings.REV[2] == 0 &&
gSettings.REV[3] == 0 &&
gSettings.REV[4] == 0 &&
gSettings.REV[5] == 0);
Revision = StrDecimalToUintn(gFirmwareRevision);
// fool proof
FrontSideBus = gCPUStructure.FSBFrequency;
if ((FrontSideBus < (50 * Mega)) || (FrontSideBus > (1000 * Mega))) {
DBG("Wrong FrontSideBus=%d, set to 100MHz\n", FrontSideBus);
FrontSideBus = 100 * Mega;
}
if (gSettings.QEMU) {
FrontSideBus = gCPUStructure.TSCFrequency;
switch (gCPUStructure.Model) {
case CPU_MODEL_DOTHAN:
case CPU_MODEL_YONAH:
case CPU_MODEL_MEROM:
case CPU_MODEL_PENRYN:
FrontSideBus = DivU64x32(FrontSideBus, 4);
break;
default:
break;
}
DBG("Using QEMU FrontSideBus=%ull\n", FrontSideBus);
}
// Save values into gSettings for the genconfig aim
gSettings.BusSpeed = (UINT32)DivU64x32(FrontSideBus, kilo);
CpuSpeed = gCPUStructure.CPUFrequency;
gSettings.CpuFreqMHz = (UINT32)DivU64x32(CpuSpeed, Mega);
// Locate DataHub Protocol
Status = gBS->LocateProtocol(&gEfiDataHubProtocolGuid, NULL, (VOID**)&gDataHub);
if (!EFI_ERROR(Status)) {
ProductName = AllocateZeroPool(128);
AsciiStrToUnicodeStrS(gSettings.ProductName, ProductName, 64);
SerialNumber = AllocateZeroPool(128);
AsciiStrToUnicodeStrS(gSettings.SerialNr, SerialNumber, 64);
LogDataHub(&gEfiProcessorSubClassGuid, L"FSBFrequency", &FrontSideBus, sizeof(UINT64));
if (gCPUStructure.ARTFrequency && gSettings.UseARTFreq) {
ARTFrequency = gCPUStructure.ARTFrequency;
LogDataHub(&gEfiProcessorSubClassGuid, L"ARTFrequency", &ARTFrequency, sizeof(UINT64));
}
TscFrequency = 0; //gCPUStructure.TSCFrequency;
LogDataHub(&gEfiProcessorSubClassGuid, L"InitialTSC", &TscFrequency, sizeof(UINT64));
LogDataHub(&gEfiProcessorSubClassGuid, L"CPUFrequency", &CpuSpeed, sizeof(UINT64));
//gSettings.BoardNumber
LogDataHub(&gEfiMiscSubClassGuid, L"board-id", &gSettings.BoardNumber, (UINT32)iStrLen(gSettings.BoardNumber, 64) + 1);
TscFrequency++;
LogDataHub(&gEfiProcessorSubClassGuid, L"board-rev", &TscFrequency, 1);
DevPathSupportedVal = 1;
LogDataHub(&gEfiMiscSubClassGuid, L"DevicePathsSupported", &DevPathSupportedVal, sizeof(UINT32));
LogDataHub(&gEfiMiscSubClassGuid, L"Model", ProductName, (UINT32)StrSize(ProductName));
LogDataHub(&gEfiMiscSubClassGuid, L"SystemSerialNumber", SerialNumber, (UINT32)StrSize(SerialNumber));
if (gSettings.InjectSystemID) {
LogDataHub(&gEfiMiscSubClassGuid, L"system-id", &gUuid, sizeof(EFI_GUID));
}
LogDataHub(&gEfiProcessorSubClassGuid, L"clovergui-revision", &Revision, sizeof(UINT32));
// collect info about real hardware
LogDataHub(&gEfiMiscSubClassGuid, L"OEMVendor", &gSettings.OEMVendor, (UINT32)iStrLen(gSettings.OEMVendor, 64) + 1);
LogDataHub(&gEfiMiscSubClassGuid, L"OEMProduct", &gSettings.OEMProduct, (UINT32)iStrLen(gSettings.OEMProduct, 64) + 1);
LogDataHub(&gEfiMiscSubClassGuid, L"OEMBoard", &gSettings.OEMBoard, (UINT32)iStrLen(gSettings.OEMBoard, 64) + 1);
// SMC helper
if (!isRevLess) {
LogDataHub(&gEfiMiscSubClassGuid, L"RBr", &gSettings.RBr, 8);
LogDataHub(&gEfiMiscSubClassGuid, L"EPCI", &gSettings.EPCI, 4);
LogDataHub(&gEfiMiscSubClassGuid, L"REV", &gSettings.REV, 6);
}
LogDataHub(&gEfiMiscSubClassGuid, L"RPlt", &gSettings.RPlt, 8);
LogDataHub(&gEfiMiscSubClassGuid, L"BEMB", &gSettings.Mobile, 1);
// all current settings
LogDataHub(&gEfiMiscSubClassGuid, L"Settings", &gSettings, sizeof(gSettings));
}
if (!gAppleSmc) {
return;
}
if (!isRevLess) {
AddSMCkey(SMC_MAKE_KEY('R','B','r',' '), 8, SmcKeyTypeCh8, (SMC_DATA *)&gSettings.RBr);
AddSMCkey(SMC_MAKE_KEY('E','P','C','I'), 4, SmcKeyTypeUint32, (SMC_DATA *)&gSettings.EPCI);
AddSMCkey(SMC_MAKE_KEY('R','E','V',' '), 6, SmcKeyTypeCh8, (SMC_DATA *)&gSettings.REV);
}
AddSMCkey(SMC_MAKE_KEY('R','P','l','t'), 8, SmcKeyTypeCh8, (SMC_DATA *)&gSettings.RPlt);
AddSMCkey(SMC_MAKE_KEY('B','E','M','B'), 1, SmcKeyTypeFlag, (SMC_DATA *)&gSettings.Mobile);
//laptop battery keys will be better to import from nvram.plist or read from ACPI(?)
//they are needed for FileVault2 who want to draw battery status
AddSMCkey(SMC_MAKE_KEY('B','A','T','P'), 1, SmcKeyTypeFlag, (SMC_DATA *)&Zero); //isBatteryPowered
AddSMCkey(SMC_MAKE_KEY('B','N','u','m'), 1, SmcKeyTypeUint8, (SMC_DATA *)&gSettings.Mobile); // Num Batteries
if (gSettings.Mobile) {
AddSMCkey(SMC_MAKE_KEY('B','B','I','N'), 1, SmcKeyTypeUint8, (SMC_DATA *)&gSettings.Mobile); //Battery inserted
}
AddSMCkey(SMC_MAKE_KEY('M','S','T','c'), 1, SmcKeyTypeUint8, (SMC_DATA *)&Zero); // CPU Plimit
AddSMCkey(SMC_MAKE_KEY('M','S','A','c'), 2, SmcKeyTypeUint16, (SMC_DATA *)&Zero);// GPU Plimit
// AddSMCkey(SMC_MAKE_KEY('M','S','L','D'), 1, SmcKeyTypeUint8, (SMC_DATA *)&Zero); //isLidClosed
Zero = Hibernate?((ResumeFromCoreStorage||GlobalConfig.HibernationFixup)?25:29):0;
AddSMCkey(SMC_MAKE_KEY('M','S','W','r'), 1, SmcKeyTypeUint8, (SMC_DATA *)&Zero);
Zero = 1;
AddSMCkey(SMC_MAKE_KEY('M','S','F','W'), 2, SmcKeyTypeUint8, (SMC_DATA *)&Zero);
Zero = 0x300;
AddSMCkey(SMC_MAKE_KEY('M','S','P','S'), 2, SmcKeyTypeUint16, (SMC_DATA *)&Zero);
}