Signed-off-by: lzeng14 Reviewed-by: li-elvin git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12753 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			557 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			557 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
 | 
						|
This program and the accompanying materials
 | 
						|
are licensed and made available under the terms and conditions of the BSD License
 | 
						|
which accompanies this distribution.  The full text of the license may be found at
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
Module Name:
 | 
						|
 | 
						|
  Cpu.c
 | 
						|
 | 
						|
Abstract:
 | 
						|
 | 
						|
  Unix Emulation Architectural Protocol Driver as defined in Tiano.
 | 
						|
  This CPU module abstracts the interrupt subsystem of a platform and
 | 
						|
  the CPU-specific setjump/long pair.  Other services are not implemented
 | 
						|
  in this driver.
 | 
						|
 | 
						|
--*/
 | 
						|
#include <FrameworkDxe.h>
 | 
						|
#include <IndustryStandard/SmBios.h>
 | 
						|
#include <Protocol/Cpu.h>
 | 
						|
#include <Protocol/Smbios.h>
 | 
						|
#include <Guid/DataHubRecords.h>
 | 
						|
#include <Protocol/CpuIo2.h>
 | 
						|
#include <Protocol/FrameworkHii.h>
 | 
						|
#include <Protocol/UnixThunk.h>
 | 
						|
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/HiiLib.h>
 | 
						|
#include <Library/UefiLib.h>
 | 
						|
#include <Library/UefiDriverEntryPoint.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/UnixLib.h>
 | 
						|
 | 
						|
#include "CpuDriver.h"
 | 
						|
#include "UnixDxe.h"
 | 
						|
#include <Protocol/UnixIo.h>
 | 
						|
 | 
						|
#define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
 | 
						|
 | 
						|
CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate = {
 | 
						|
  CPU_ARCH_PROT_PRIVATE_SIGNATURE,
 | 
						|
  NULL,
 | 
						|
  {
 | 
						|
    UnixFlushCpuDataCache,
 | 
						|
    UnixEnableInterrupt,
 | 
						|
    UnixDisableInterrupt,
 | 
						|
    UnixGetInterruptState,
 | 
						|
    UnixInit,
 | 
						|
    UnixRegisterInterruptHandler,
 | 
						|
    UnixGetTimerValue,
 | 
						|
    UnixSetMemoryAttributes,
 | 
						|
    0,
 | 
						|
    4
 | 
						|
  },
 | 
						|
  {
 | 
						|
    {
 | 
						|
      CpuMemoryServiceRead,
 | 
						|
      CpuMemoryServiceWrite
 | 
						|
    },
 | 
						|
    {
 | 
						|
      CpuIoServiceRead,
 | 
						|
      CpuIoServiceWrite
 | 
						|
    }
 | 
						|
  },
 | 
						|
  TRUE
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// Service routines for the driver
 | 
						|
//
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixFlushCpuDataCache (
 | 
						|
  IN EFI_CPU_ARCH_PROTOCOL  *This,
 | 
						|
  IN EFI_PHYSICAL_ADDRESS   Start,
 | 
						|
  IN UINT64                 Length,
 | 
						|
  IN EFI_CPU_FLUSH_TYPE     FlushType
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine would provide support for flushing the CPU data cache.
 | 
						|
  In the case of UNIX emulation environment, this flushing is not necessary and
 | 
						|
  is thus not implemented.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Pointer to CPU Architectural Protocol interface
 | 
						|
  Start adddress in memory to flush
 | 
						|
  Length of memory to flush
 | 
						|
  Flush type
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
    EFI_SUCCESS
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    This - add argument and description to function comment
 | 
						|
// TODO:    FlushType - add argument and description to function comment
 | 
						|
// TODO:    EFI_UNSUPPORTED - add return value to function comment
 | 
						|
{
 | 
						|
  if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
 | 
						|
    //
 | 
						|
    // Only WB flush is supported. We actually need do nothing on UNIX emulator
 | 
						|
    // environment. Classify this to follow EFI spec
 | 
						|
    //
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Other flush types are not supported by UNIX emulator
 | 
						|
  //
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixEnableInterrupt (
 | 
						|
  IN EFI_CPU_ARCH_PROTOCOL  *This
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine provides support for emulation of the interrupt enable of the
 | 
						|
  the system.  For our purposes, CPU enable is just a BOOLEAN that the Timer
 | 
						|
  Architectural Protocol observes in order to defer behaviour while in its
 | 
						|
  emulated interrupt, or timer tick.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Pointer to CPU Architectural Protocol interface
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
    EFI_SUCCESS
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    This - add argument and description to function comment
 | 
						|
{
 | 
						|
  CPU_ARCH_PROTOCOL_PRIVATE *Private;
 | 
						|
 | 
						|
  Private                 = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  Private->InterruptState = TRUE;
 | 
						|
  gUnix->EnableInterrupt ();
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixDisableInterrupt (
 | 
						|
  IN EFI_CPU_ARCH_PROTOCOL  *This
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine provides support for emulation of the interrupt disable of the
 | 
						|
  the system.  For our purposes, CPU enable is just a BOOLEAN that the Timer
 | 
						|
  Architectural Protocol observes in order to defer behaviour while in its
 | 
						|
  emulated interrupt, or timer tick.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Pointer to CPU Architectural Protocol interface
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
    EFI_SUCCESS
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    This - add argument and description to function comment
 | 
						|
{
 | 
						|
  CPU_ARCH_PROTOCOL_PRIVATE *Private;
 | 
						|
 | 
						|
  Private                 = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  Private->InterruptState = FALSE;
 | 
						|
  gUnix->DisableInterrupt ();
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixGetInterruptState (
 | 
						|
  IN EFI_CPU_ARCH_PROTOCOL  *This,
 | 
						|
  OUT BOOLEAN               *State
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine provides support for emulation of the interrupt disable of the
 | 
						|
  the system.  For our purposes, CPU enable is just a BOOLEAN that the Timer
 | 
						|
  Architectural Protocol observes in order to defer behaviour while in its
 | 
						|
  emulated interrupt, or timer tick.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Pointer to CPU Architectural Protocol interface
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
    EFI_SUCCESS
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    This - add argument and description to function comment
 | 
						|
// TODO:    State - add argument and description to function comment
 | 
						|
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
 | 
						|
{
 | 
						|
  CPU_ARCH_PROTOCOL_PRIVATE *Private;
 | 
						|
 | 
						|
  if (State == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  *State  = Private->InterruptState;
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixInit (
 | 
						|
  IN EFI_CPU_ARCH_PROTOCOL  *This,
 | 
						|
  IN EFI_CPU_INIT_TYPE      InitType
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine would support generation of a CPU INIT.  At
 | 
						|
  present, this code does not provide emulation.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Pointer to CPU Architectural Protocol interface
 | 
						|
  INIT Type
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
    EFI_UNSUPPORTED - not yet implemented
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    This - add argument and description to function comment
 | 
						|
// TODO:    InitType - add argument and description to function comment
 | 
						|
{
 | 
						|
  CPU_ARCH_PROTOCOL_PRIVATE *Private;
 | 
						|
 | 
						|
  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixRegisterInterruptHandler (
 | 
						|
  IN EFI_CPU_ARCH_PROTOCOL      *This,
 | 
						|
  IN EFI_EXCEPTION_TYPE         InterruptType,
 | 
						|
  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine would support registration of an interrupt handler.  At
 | 
						|
  present, this code does not provide emulation.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Pointer to CPU Architectural Protocol interface
 | 
						|
  Pointer to interrupt handlers
 | 
						|
  Interrupt type
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
    EFI_UNSUPPORTED - not yet implemented
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    This - add argument and description to function comment
 | 
						|
// TODO:    InterruptType - add argument and description to function comment
 | 
						|
// TODO:    InterruptHandler - add argument and description to function comment
 | 
						|
{
 | 
						|
  CPU_ARCH_PROTOCOL_PRIVATE *Private;
 | 
						|
 | 
						|
  //
 | 
						|
  // Do parameter checking for EFI spec conformance
 | 
						|
  //
 | 
						|
  if (InterruptType < 0 || InterruptType > 0xff) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Do nothing for Nt32 emulation
 | 
						|
  //
 | 
						|
  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixGetTimerValue (
 | 
						|
  IN  EFI_CPU_ARCH_PROTOCOL *This,
 | 
						|
  IN  UINT32                TimerIndex,
 | 
						|
  OUT UINT64                *TimerValue,
 | 
						|
  OUT UINT64                *TimerPeriod OPTIONAL
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine would support querying of an on-CPU timer.  At present,
 | 
						|
  this code does not provide timer emulation.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  This        - Pointer to CPU Architectural Protocol interface
 | 
						|
  TimerIndex  - Index of given CPU timer
 | 
						|
  TimerValue  - Output of the timer
 | 
						|
  TimerPeriod - Output of the timer period
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_UNSUPPORTED       - not yet implemented
 | 
						|
  EFI_INVALID_PARAMETER - TimeValue is NULL
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  if (TimerValue == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // No timer supported
 | 
						|
  //
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
UnixSetMemoryAttributes (
 | 
						|
  IN EFI_CPU_ARCH_PROTOCOL  *This,
 | 
						|
  IN EFI_PHYSICAL_ADDRESS   BaseAddress,
 | 
						|
  IN UINT64                 Length,
 | 
						|
  IN UINT64                 Attributes
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This routine would support querying of an on-CPU timer.  At present,
 | 
						|
  this code does not provide timer emulation.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Pointer to CPU Architectural Protocol interface
 | 
						|
  Start address of memory region
 | 
						|
  The size in bytes of the memory region
 | 
						|
  The bit mask of attributes to set for the memory region
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
    EFI_UNSUPPORTED - not yet implemented
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    This - add argument and description to function comment
 | 
						|
// TODO:    BaseAddress - add argument and description to function comment
 | 
						|
// TODO:    Length - add argument and description to function comment
 | 
						|
// TODO:    Attributes - add argument and description to function comment
 | 
						|
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
 | 
						|
{
 | 
						|
  CPU_ARCH_PROTOCOL_PRIVATE *Private;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check for invalid parameter for Spec conformance
 | 
						|
  //
 | 
						|
  if (Length == 0) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Do nothing for Nt32 emulation
 | 
						|
  //
 | 
						|
  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Logs SMBIOS record.
 | 
						|
 | 
						|
  @param  Smbios   Pointer to SMBIOS protocol instance.
 | 
						|
  @param  Buffer   Pointer to the data buffer.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
LogSmbiosData (
 | 
						|
  IN  EFI_SMBIOS_PROTOCOL        *Smbios,
 | 
						|
  IN  UINT8                      *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS         Status;
 | 
						|
  EFI_SMBIOS_HANDLE  SmbiosHandle;
 | 
						|
  
 | 
						|
  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
 | 
						|
  Status = Smbios->Add (
 | 
						|
                     Smbios,
 | 
						|
                     NULL,
 | 
						|
                     &SmbiosHandle,
 | 
						|
                     (EFI_SMBIOS_TABLE_HEADER*)Buffer
 | 
						|
                     );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CpuUpdateSmbios (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  This function will log processor version and frequency data to data hub.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  Event        - Event whose notification function is being invoked.
 | 
						|
  Context      - Pointer to the notification function's context.
 | 
						|
 | 
						|
Returns:
 | 
						|
  None.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  EFI_SMBIOS_PROTOCOL         *Smbios;
 | 
						|
  UINT32                      TotalSize;
 | 
						|
  EFI_HII_HANDLE              HiiHandle;
 | 
						|
  STRING_REF                  Token;
 | 
						|
  UINTN                       CpuVerStrLen;
 | 
						|
  EFI_STRING                  CpuVerStr;
 | 
						|
  SMBIOS_TABLE_TYPE4          *SmbiosRecord;
 | 
						|
  CHAR8                       *OptionalStrStart;
 | 
						|
 | 
						|
  //
 | 
						|
  // Locate Smbios protocol.
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);
 | 
						|
  
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize strings to HII database
 | 
						|
  //
 | 
						|
  HiiHandle = HiiAddPackages (
 | 
						|
                &gEfiCallerIdGuid,
 | 
						|
                NULL,
 | 
						|
                CpuStrings,
 | 
						|
                NULL
 | 
						|
                );
 | 
						|
  ASSERT (HiiHandle != NULL);
 | 
						|
 | 
						|
 | 
						|
  Token  = STRING_TOKEN (STR_INTEL_GENUINE_PROCESSOR);
 | 
						|
  CpuVerStr = HiiGetPackageString(&gEfiCallerIdGuid, Token, NULL);
 | 
						|
  CpuVerStrLen = StrLen(CpuVerStr);
 | 
						|
  ASSERT (CpuVerStrLen <= SMBIOS_STRING_MAX_LENGTH);
 | 
						|
 | 
						|
  TotalSize = sizeof(SMBIOS_TABLE_TYPE4) + CpuVerStrLen + 1 + 1;
 | 
						|
  SmbiosRecord = AllocatePool(TotalSize);
 | 
						|
  ZeroMem(SmbiosRecord, TotalSize);
 | 
						|
 | 
						|
  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION;
 | 
						|
  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4);
 | 
						|
  //
 | 
						|
  // Make handle chosen by smbios protocol.add automatically.
 | 
						|
  //
 | 
						|
  SmbiosRecord->Hdr.Handle = 0;  
 | 
						|
  //
 | 
						|
  // Processor version is the 1st string.
 | 
						|
  //
 | 
						|
  SmbiosRecord->ProcessorVersion = 1;
 | 
						|
  //
 | 
						|
  // Store CPU frequency data record to data hub - It's an emulator so make up a value
 | 
						|
  //
 | 
						|
  SmbiosRecord->CurrentSpeed  = 1234;
 | 
						|
 | 
						|
  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
 | 
						|
  UnicodeStrToAsciiStr(CpuVerStr, OptionalStrStart);
 | 
						|
 | 
						|
  //
 | 
						|
  // Now we have got the full smbios record, call smbios protocol to add this record.
 | 
						|
  //
 | 
						|
  LogSmbiosData(Smbios, (UINT8 *) SmbiosRecord);
 | 
						|
  FreePool (SmbiosRecord);
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InitializeCpu (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Initialize the state information for the CPU Architectural Protocol
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  ImageHandle of the loaded driver
 | 
						|
  Pointer to the System Table
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status
 | 
						|
 | 
						|
  EFI_SUCCESS           - protocol instance can be published
 | 
						|
  EFI_OUT_OF_RESOURCES  - cannot allocate protocol data structure
 | 
						|
  EFI_DEVICE_ERROR      - cannot create the thread
 | 
						|
 | 
						|
--*/
 | 
						|
// TODO:    SystemTable - add argument and description to function comment
 | 
						|
{
 | 
						|
  EFI_STATUS                Status;
 | 
						|
 | 
						|
  CpuUpdateSmbios ();
 | 
						|
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  &mCpuTemplate.Handle,
 | 
						|
                  &gEfiCpuArchProtocolGuid,   &mCpuTemplate.Cpu,
 | 
						|
                  &gEfiCpuIo2ProtocolGuid,    &mCpuTemplate.CpuIo,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  DEBUG ((EFI_D_ERROR, "CPU Architectural Protocol Loaded\n"));
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |