/* $Id: Cpu.c $ */ /** @file * Cpu.c - VirtualBox CPU descriptors */ /* * Copyright (C) 2009-2019 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. * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the * VirtualBox OSE distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. */ /********************************************************************************************************************************* * Header Files * *********************************************************************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100 typedef union { EFI_CPU_DATA_RECORD *DataRecord; UINT8 *Raw; } EFI_CPU_DATA_RECORD_BUFFER; 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 }; EFI_GUID gEfiAppleMagicHubGuid = { 0x64517cc8, 0x6561, 0x4051, {0xb0, 0x3c, 0x59, 0x64, 0xb6, 0x0f, 0x4c, 0x7a } }; #pragma pack(1) typedef struct { UINT8 Pad0[0x10]; /* 0x48 */ UINT32 NameLen; /* 0x58 , in bytes */ UINT32 ValLen; /* 0x5c */ UINT8 Data[1]; /* 0x60 Name Value */ } MAGIC_HUB_DATA; #pragma pack() UINT32 CopyRecord(MAGIC_HUB_DATA* Rec, const CHAR16* Name, VOID* Val, UINT32 ValLen) { Rec->NameLen = (UINT32)StrLen(Name) * sizeof(CHAR16); Rec->ValLen = ValLen; CopyMem(Rec->Data, Name, Rec->NameLen); CopyMem(Rec->Data + Rec->NameLen, Val, ValLen); return 0x10 + 4 + 4 + Rec->NameLen + Rec->ValLen; } EFI_STATUS EFIAPI LogData(EFI_DATA_HUB_PROTOCOL *DataHub, MAGIC_HUB_DATA *MagicData, CHAR16 *Name, VOID *Data, UINT32 DataSize) { UINT32 RecordSize; EFI_STATUS Status; RecordSize = CopyRecord(MagicData, Name, Data, DataSize); Status = DataHub->LogData ( DataHub, &gEfiProcessorSubClassGuid, /* DataRecordGuid */ &gEfiAppleMagicHubGuid, /* ProducerName */ EFI_DATA_RECORD_CLASS_DATA, MagicData, RecordSize ); ASSERT_EFI_ERROR (Status); return Status; } EFI_STATUS EFIAPI CpuUpdateDataHub(EFI_BOOT_SERVICES * bs, UINT64 FSBFrequency, UINT64 TSCFrequency, UINT64 CPUFrequency) { EFI_STATUS Status; EFI_DATA_HUB_PROTOCOL *DataHub; MAGIC_HUB_DATA *MagicData; // // Locate DataHub protocol. // Status = bs->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID**)&DataHub); if (EFI_ERROR (Status)) { return Status; } MagicData = (MAGIC_HUB_DATA*)AllocatePool (0x200); if (MagicData == NULL) { return EFI_OUT_OF_RESOURCES; } // Log data in format some OSes like LogData(DataHub, MagicData, L"FSBFrequency", &FSBFrequency, sizeof(FSBFrequency)); // do that twice, as last variable read not really accounted for LogData(DataHub, MagicData, L"FSBFrequency", &FSBFrequency, sizeof(FSBFrequency)); LogData(DataHub, MagicData, L"TSCFrequency", &TSCFrequency, sizeof(TSCFrequency)); LogData(DataHub, MagicData, L"CPUFrequency", &CPUFrequency, sizeof(CPUFrequency)); FreePool (MagicData); return EFI_SUCCESS; }