4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* $Id$ */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Cpu.c - VirtualBox CPU descriptors
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2009-2010 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The contents of this file may alternatively be used under the terms
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * of the Common Development and Distribution License Version 1.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL are applicable instead of those of the GPL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You may elect to license modified versions of this file under the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * terms and conditions of either the GPL or the CDDL or both.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*******************************************************************************
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Header Files *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *******************************************************************************/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Framework/FrameworkInternalFormRepresentation.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseMemoryLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/DebugLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/UefiBootServicesTableLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseMemoryLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/MemoryAllocationLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/UefiLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/HiiLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Guid/DataHubRecords.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Protocol/Cpu.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Protocol/DataHub.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Protocol/FrameworkHii.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Protocol/CpuIo.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynctypedef union {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_CPU_DATA_RECORD *DataRecord;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Raw;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync} EFI_CPU_DATA_RECORD_BUFFER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PROCESSOR_SUBCLASS_VERSION, // Version
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_SUBCLASS_TYPE1_HEADER), // Header Size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // Instance, Initialize later
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUBCLASS_INSTANCE_NON_APPLICABLE, // SubInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 // RecordType, Initialize later
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_GUID gEfiAppleMagicHubGuid = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x64517cc8, 0x6561, 0x4051, {0xb0, 0x3c, 0x59, 0x64, 0xb6, 0x0f, 0x4c, 0x7a }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#pragma pack(1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynctypedef struct {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Pad0[0x10]; /* 0x48 */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 NameLen; /* 0x58 , in bytes */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 ValLen; /* 0x5c */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Data[1]; /* 0x60 Name Value */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync} MAGIC_HUB_DATA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#pragma pack()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyRecord(MAGIC_HUB_DATA* Rec, const CHAR16* Name, VOID* Val, UINT32 ValLen)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Rec->NameLen = (UINT32)StrLen(Name) * sizeof(CHAR16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Rec->ValLen = ValLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem(Rec->Data, Name, Rec->NameLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem(Rec->Data + Rec->NameLen, Val, ValLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0x10 + 4 + 4 + Rec->NameLen + Rec->ValLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS EFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncLogData(EFI_DATA_HUB_PROTOCOL *DataHub,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MAGIC_HUB_DATA *MagicData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 *Name,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 DataSize)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 RecordSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RecordSize = CopyRecord(MagicData, Name, Data, DataSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DataHub->LogData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataHub,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiProcessorSubClassGuid, /* DataRecordGuid */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiAppleMagicHubGuid, /* ProducerName */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DATA_RECORD_CLASS_DATA,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MagicData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RecordSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS EFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuUpdateDataHub(EFI_BOOT_SERVICES * bs,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 FSBFrequency,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TSCFrequency,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 CPUFrequency)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DATA_HUB_PROTOCOL *DataHub;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MAGIC_HUB_DATA *MagicData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate DataHub protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = bs->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID**)&DataHub);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MagicData = (MAGIC_HUB_DATA*)AllocatePool (0x200);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MagicData == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Log data in format some OSes like
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LogData(DataHub, MagicData, L"FSBFrequency", &FSBFrequency, sizeof(FSBFrequency));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // do that twice, as last variable read not really accounted for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LogData(DataHub, MagicData, L"FSBFrequency", &FSBFrequency, sizeof(FSBFrequency));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LogData(DataHub, MagicData, L"TSCFrequency", &TSCFrequency, sizeof(TSCFrequency));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LogData(DataHub, MagicData, L"CPUFrequency", &CPUFrequency, sizeof(CPUFrequency));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (MagicData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}