mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 15:44:04 +02:00
UefiCpuPkg/CpuMpPei: Update files format to DOS
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18168 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
3fd56a2672
commit
ea0f431cec
@ -1,260 +1,260 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Update and publish processors' BIST information.
|
Update and publish processors' BIST information.
|
||||||
|
|
||||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
http://opensource.org/licenses/bsd-license.php
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "CpuMpPei.h"
|
#include "CpuMpPei.h"
|
||||||
|
|
||||||
EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2Ppi = {
|
EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2Ppi = {
|
||||||
SecPlatformInformation2
|
SecPlatformInformation2
|
||||||
};
|
};
|
||||||
|
|
||||||
EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2Ppi = {
|
EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2Ppi = {
|
||||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||||
&gEfiSecPlatformInformation2PpiGuid,
|
&gEfiSecPlatformInformation2PpiGuid,
|
||||||
&mSecPlatformInformation2Ppi
|
&mSecPlatformInformation2Ppi
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
|
Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
|
||||||
|
|
||||||
@param PeiServices The pointer to the PEI Services Table.
|
@param PeiServices The pointer to the PEI Services Table.
|
||||||
@param StructureSize The pointer to the variable describing size of the input buffer.
|
@param StructureSize The pointer to the variable describing size of the input buffer.
|
||||||
@param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
|
@param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data was successfully returned.
|
@retval EFI_SUCCESS The data was successfully returned.
|
||||||
@retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
|
@retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
|
||||||
hold the record is returned in StructureSize.
|
hold the record is returned in StructureSize.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
SecPlatformInformation2 (
|
SecPlatformInformation2 (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN OUT UINT64 *StructureSize,
|
IN OUT UINT64 *StructureSize,
|
||||||
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
|
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PEI_CPU_MP_DATA *PeiCpuMpData;
|
PEI_CPU_MP_DATA *PeiCpuMpData;
|
||||||
UINTN BistInformationSize;
|
UINTN BistInformationSize;
|
||||||
UINTN CpuIndex;
|
UINTN CpuIndex;
|
||||||
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
|
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
|
||||||
|
|
||||||
PeiCpuMpData = GetMpHobData ();
|
PeiCpuMpData = GetMpHobData ();
|
||||||
|
|
||||||
BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +
|
BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +
|
||||||
sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * PeiCpuMpData->CpuCount;
|
sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * PeiCpuMpData->CpuCount;
|
||||||
//
|
//
|
||||||
// return the information size if input buffer size is too small
|
// return the information size if input buffer size is too small
|
||||||
//
|
//
|
||||||
if ((*StructureSize) < (UINT64) BistInformationSize) {
|
if ((*StructureSize) < (UINT64) BistInformationSize) {
|
||||||
*StructureSize = (UINT64) BistInformationSize;
|
*StructureSize = (UINT64) BistInformationSize;
|
||||||
return EFI_BUFFER_TOO_SMALL;
|
return EFI_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformInformationRecord2->NumberOfCpus = PeiCpuMpData->CpuCount;
|
PlatformInformationRecord2->NumberOfCpus = PeiCpuMpData->CpuCount;
|
||||||
CpuInstance = PlatformInformationRecord2->CpuInstance;
|
CpuInstance = PlatformInformationRecord2->CpuInstance;
|
||||||
for (CpuIndex = 0; CpuIndex < PeiCpuMpData->CpuCount; CpuIndex ++) {
|
for (CpuIndex = 0; CpuIndex < PeiCpuMpData->CpuCount; CpuIndex ++) {
|
||||||
CpuInstance[CpuIndex].CpuLocation = PeiCpuMpData->CpuData[CpuIndex].ApicId;
|
CpuInstance[CpuIndex].CpuLocation = PeiCpuMpData->CpuData[CpuIndex].ApicId;
|
||||||
CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = PeiCpuMpData->CpuData[CpuIndex].Health;
|
CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = PeiCpuMpData->CpuData[CpuIndex].Health;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Worker function to get CPUs' BIST by calling SecPlatformInformationPpi
|
Worker function to get CPUs' BIST by calling SecPlatformInformationPpi
|
||||||
or SecPlatformInformation2Ppi.
|
or SecPlatformInformation2Ppi.
|
||||||
|
|
||||||
@param PeiServices Pointer to PEI Services Table
|
@param PeiServices Pointer to PEI Services Table
|
||||||
@param Guid PPI Guid
|
@param Guid PPI Guid
|
||||||
@param PpiDescriptor Return a pointer to instance of the
|
@param PpiDescriptor Return a pointer to instance of the
|
||||||
EFI_PEI_PPI_DESCRIPTOR
|
EFI_PEI_PPI_DESCRIPTOR
|
||||||
@param BistInformationData Pointer to BIST information data
|
@param BistInformationData Pointer to BIST information data
|
||||||
|
|
||||||
@retval EFI_SUCCESS Retrieve of the BIST data successfully
|
@retval EFI_SUCCESS Retrieve of the BIST data successfully
|
||||||
@retval EFI_NOT_FOUND No sec platform information(2) ppi export
|
@retval EFI_NOT_FOUND No sec platform information(2) ppi export
|
||||||
@retval EFI_DEVICE_ERROR Failed to get CPU Information
|
@retval EFI_DEVICE_ERROR Failed to get CPU Information
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
GetBistInfoFromPpi (
|
GetBistInfoFromPpi (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN CONST EFI_GUID *Guid,
|
IN CONST EFI_GUID *Guid,
|
||||||
OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
|
OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
|
||||||
OUT VOID **BistInformationData
|
OUT VOID **BistInformationData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi;
|
EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi;
|
||||||
EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
|
EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
|
||||||
UINT64 InformationSize;
|
UINT64 InformationSize;
|
||||||
|
|
||||||
Status = PeiServicesLocatePpi (
|
Status = PeiServicesLocatePpi (
|
||||||
Guid, // GUID
|
Guid, // GUID
|
||||||
0, // INSTANCE
|
0, // INSTANCE
|
||||||
PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
|
PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
|
||||||
(VOID **)&SecPlatformInformation2Ppi // PPI
|
(VOID **)&SecPlatformInformation2Ppi // PPI
|
||||||
);
|
);
|
||||||
if (Status == EFI_NOT_FOUND) {
|
if (Status == EFI_NOT_FOUND) {
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status == EFI_SUCCESS) {
|
if (Status == EFI_SUCCESS) {
|
||||||
//
|
//
|
||||||
// Get the size of the sec platform information2(BSP/APs' BIST data)
|
// Get the size of the sec platform information2(BSP/APs' BIST data)
|
||||||
//
|
//
|
||||||
InformationSize = 0;
|
InformationSize = 0;
|
||||||
SecPlatformInformation2 = NULL;
|
SecPlatformInformation2 = NULL;
|
||||||
Status = SecPlatformInformation2Ppi->PlatformInformation2 (
|
Status = SecPlatformInformation2Ppi->PlatformInformation2 (
|
||||||
PeiServices,
|
PeiServices,
|
||||||
&InformationSize,
|
&InformationSize,
|
||||||
SecPlatformInformation2
|
SecPlatformInformation2
|
||||||
);
|
);
|
||||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
Status = PeiServicesAllocatePool (
|
Status = PeiServicesAllocatePool (
|
||||||
(UINTN) InformationSize,
|
(UINTN) InformationSize,
|
||||||
(VOID **) &SecPlatformInformation2
|
(VOID **) &SecPlatformInformation2
|
||||||
);
|
);
|
||||||
if (Status == EFI_SUCCESS) {
|
if (Status == EFI_SUCCESS) {
|
||||||
//
|
//
|
||||||
// Retrieve BIST data
|
// Retrieve BIST data
|
||||||
//
|
//
|
||||||
Status = SecPlatformInformation2Ppi->PlatformInformation2 (
|
Status = SecPlatformInformation2Ppi->PlatformInformation2 (
|
||||||
PeiServices,
|
PeiServices,
|
||||||
&InformationSize,
|
&InformationSize,
|
||||||
SecPlatformInformation2
|
SecPlatformInformation2
|
||||||
);
|
);
|
||||||
if (Status == EFI_SUCCESS) {
|
if (Status == EFI_SUCCESS) {
|
||||||
*BistInformationData = SecPlatformInformation2;
|
*BistInformationData = SecPlatformInformation2;
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Collects BIST data from PPI.
|
Collects BIST data from PPI.
|
||||||
|
|
||||||
This function collects BIST data from Sec Platform Information2 PPI
|
This function collects BIST data from Sec Platform Information2 PPI
|
||||||
or SEC Platform Information PPI.
|
or SEC Platform Information PPI.
|
||||||
|
|
||||||
@param PeiServices Pointer to PEI Services Table
|
@param PeiServices Pointer to PEI Services Table
|
||||||
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
CollectBistDataFromPpi (
|
CollectBistDataFromPpi (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor;
|
EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor;
|
||||||
EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
|
EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
|
||||||
EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation;
|
EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation;
|
||||||
UINTN NumberOfData;
|
UINTN NumberOfData;
|
||||||
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
|
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
|
||||||
EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
|
EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
|
||||||
UINTN ProcessorNumber;
|
UINTN ProcessorNumber;
|
||||||
UINTN CpuIndex;
|
UINTN CpuIndex;
|
||||||
PEI_CPU_DATA *CpuData;
|
PEI_CPU_DATA *CpuData;
|
||||||
|
|
||||||
SecPlatformInformation2 = NULL;
|
SecPlatformInformation2 = NULL;
|
||||||
SecPlatformInformation = NULL;
|
SecPlatformInformation = NULL;
|
||||||
NumberOfData = 0;
|
NumberOfData = 0;
|
||||||
CpuInstance = NULL;
|
CpuInstance = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get BIST information from Sec Platform Information2 Ppi firstly
|
// Get BIST information from Sec Platform Information2 Ppi firstly
|
||||||
//
|
//
|
||||||
Status = GetBistInfoFromPpi (
|
Status = GetBistInfoFromPpi (
|
||||||
PeiServices,
|
PeiServices,
|
||||||
&gEfiSecPlatformInformation2PpiGuid,
|
&gEfiSecPlatformInformation2PpiGuid,
|
||||||
&SecInformationDescriptor,
|
&SecInformationDescriptor,
|
||||||
(VOID *) &SecPlatformInformation2
|
(VOID *) &SecPlatformInformation2
|
||||||
);
|
);
|
||||||
if (Status == EFI_SUCCESS) {
|
if (Status == EFI_SUCCESS) {
|
||||||
//
|
//
|
||||||
// Sec Platform Information2 PPI includes BSP/APs' BIST information
|
// Sec Platform Information2 PPI includes BSP/APs' BIST information
|
||||||
//
|
//
|
||||||
NumberOfData = SecPlatformInformation2->NumberOfCpus;
|
NumberOfData = SecPlatformInformation2->NumberOfCpus;
|
||||||
CpuInstance = SecPlatformInformation2->CpuInstance;
|
CpuInstance = SecPlatformInformation2->CpuInstance;
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// Otherwise, get BIST information from Sec Platform Information Ppi
|
// Otherwise, get BIST information from Sec Platform Information Ppi
|
||||||
//
|
//
|
||||||
Status = GetBistInfoFromPpi (
|
Status = GetBistInfoFromPpi (
|
||||||
PeiServices,
|
PeiServices,
|
||||||
&gEfiSecPlatformInformationPpiGuid,
|
&gEfiSecPlatformInformationPpiGuid,
|
||||||
&SecInformationDescriptor,
|
&SecInformationDescriptor,
|
||||||
(VOID *) &SecPlatformInformation
|
(VOID *) &SecPlatformInformation
|
||||||
);
|
);
|
||||||
if (Status == EFI_SUCCESS) {
|
if (Status == EFI_SUCCESS) {
|
||||||
NumberOfData = 1;
|
NumberOfData = 1;
|
||||||
//
|
//
|
||||||
// SEC Platform Information only includes BSP's BIST information
|
// SEC Platform Information only includes BSP's BIST information
|
||||||
// and does not have BSP's APIC ID
|
// and does not have BSP's APIC ID
|
||||||
//
|
//
|
||||||
BspCpuInstance.CpuLocation = GetInitialApicId ();
|
BspCpuInstance.CpuLocation = GetInitialApicId ();
|
||||||
BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32;
|
BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32;
|
||||||
CpuInstance = &BspCpuInstance;
|
CpuInstance = &BspCpuInstance;
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n"));
|
DEBUG ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ProcessorNumber = 0; ProcessorNumber < PeiCpuMpData->CpuCount; ProcessorNumber ++) {
|
for (ProcessorNumber = 0; ProcessorNumber < PeiCpuMpData->CpuCount; ProcessorNumber ++) {
|
||||||
CpuData = &PeiCpuMpData->CpuData[ProcessorNumber];
|
CpuData = &PeiCpuMpData->CpuData[ProcessorNumber];
|
||||||
for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) {
|
for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) {
|
||||||
ASSERT (CpuInstance != NULL);
|
ASSERT (CpuInstance != NULL);
|
||||||
if (CpuData->ApicId == CpuInstance[CpuIndex].CpuLocation) {
|
if (CpuData->ApicId == CpuInstance[CpuIndex].CpuLocation) {
|
||||||
//
|
//
|
||||||
// Update processor's BIST data if it is already stored before
|
// Update processor's BIST data if it is already stored before
|
||||||
//
|
//
|
||||||
CpuData->Health = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
|
CpuData->Health = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CpuData->Health.Uint32 != 0) {
|
if (CpuData->Health.Uint32 != 0) {
|
||||||
//
|
//
|
||||||
// Report Status Code that self test is failed
|
// Report Status Code that self test is failed
|
||||||
//
|
//
|
||||||
REPORT_STATUS_CODE (
|
REPORT_STATUS_CODE (
|
||||||
EFI_ERROR_CODE | EFI_ERROR_MAJOR,
|
EFI_ERROR_CODE | EFI_ERROR_MAJOR,
|
||||||
(EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
|
(EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
DEBUG ((EFI_D_INFO, " APICID - 0x%08x, BIST - 0x%08x\n",
|
DEBUG ((EFI_D_INFO, " APICID - 0x%08x, BIST - 0x%08x\n",
|
||||||
PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
|
PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
|
||||||
PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32
|
PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SecPlatformInformation2 != NULL && NumberOfData < PeiCpuMpData->CpuCount) {
|
if (SecPlatformInformation2 != NULL && NumberOfData < PeiCpuMpData->CpuCount) {
|
||||||
//
|
//
|
||||||
// Reinstall SecPlatformInformation2 PPI to include new BIST inforamtion
|
// Reinstall SecPlatformInformation2 PPI to include new BIST inforamtion
|
||||||
//
|
//
|
||||||
Status = PeiServicesReInstallPpi (
|
Status = PeiServicesReInstallPpi (
|
||||||
SecInformationDescriptor,
|
SecInformationDescriptor,
|
||||||
&mPeiSecPlatformInformation2Ppi
|
&mPeiSecPlatformInformation2Ppi
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// Install SecPlatformInformation2 PPI to include new BIST inforamtion
|
// Install SecPlatformInformation2 PPI to include new BIST inforamtion
|
||||||
//
|
//
|
||||||
Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
|
Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
|
||||||
ASSERT_EFI_ERROR(Status);
|
ASSERT_EFI_ERROR(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,302 +1,302 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Definitions to install Multiple Processor PPI.
|
Definitions to install Multiple Processor PPI.
|
||||||
|
|
||||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
http://opensource.org/licenses/bsd-license.php
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef _CPU_MP_PEI_H_
|
#ifndef _CPU_MP_PEI_H_
|
||||||
#define _CPU_MP_PEI_H_
|
#define _CPU_MP_PEI_H_
|
||||||
|
|
||||||
#include <PiPei.h>
|
#include <PiPei.h>
|
||||||
|
|
||||||
#include <Ppi/MpServices.h>
|
#include <Ppi/MpServices.h>
|
||||||
#include <Ppi/SecPlatformInformation.h>
|
#include <Ppi/SecPlatformInformation.h>
|
||||||
#include <Ppi/SecPlatformInformation2.h>
|
#include <Ppi/SecPlatformInformation2.h>
|
||||||
#include <Ppi/EndOfPeiPhase.h>
|
#include <Ppi/EndOfPeiPhase.h>
|
||||||
|
|
||||||
#include <Register/LocalApic.h>
|
#include <Register/LocalApic.h>
|
||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/HobLib.h>
|
#include <Library/HobLib.h>
|
||||||
#include <Library/LocalApicLib.h>
|
#include <Library/LocalApicLib.h>
|
||||||
#include <Library/MtrrLib.h>
|
#include <Library/MtrrLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/PeimEntryPoint.h>
|
#include <Library/PeimEntryPoint.h>
|
||||||
#include <Library/PeiServicesLib.h>
|
#include <Library/PeiServicesLib.h>
|
||||||
#include <Library/ReportStatusCodeLib.h>
|
#include <Library/ReportStatusCodeLib.h>
|
||||||
#include <Library/SynchronizationLib.h>
|
#include <Library/SynchronizationLib.h>
|
||||||
#include <Library/TimerLib.h>
|
#include <Library/TimerLib.h>
|
||||||
#include <Library/UefiCpuLib.h>
|
#include <Library/UefiCpuLib.h>
|
||||||
|
|
||||||
#include "Microcode.h"
|
#include "Microcode.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// AP state
|
// AP state
|
||||||
//
|
//
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CpuStateIdle,
|
CpuStateIdle,
|
||||||
CpuStateBusy,
|
CpuStateBusy,
|
||||||
CpuStateDisabled
|
CpuStateDisabled
|
||||||
} CPU_STATE;
|
} CPU_STATE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// AP reset code information
|
// AP reset code information
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT8 *RendezvousFunnelAddress;
|
UINT8 *RendezvousFunnelAddress;
|
||||||
UINTN PModeEntryOffset;
|
UINTN PModeEntryOffset;
|
||||||
UINTN LModeEntryOffset;
|
UINTN LModeEntryOffset;
|
||||||
UINTN RendezvousFunnelSize;
|
UINTN RendezvousFunnelSize;
|
||||||
} MP_ASSEMBLY_ADDRESS_MAP;
|
} MP_ASSEMBLY_ADDRESS_MAP;
|
||||||
|
|
||||||
//
|
//
|
||||||
// CPU exchange information for switch BSP
|
// CPU exchange information for switch BSP
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT8 State; // offset 0
|
UINT8 State; // offset 0
|
||||||
UINTN StackPointer; // offset 4 / 8
|
UINTN StackPointer; // offset 4 / 8
|
||||||
IA32_DESCRIPTOR Gdtr; // offset 8 / 16
|
IA32_DESCRIPTOR Gdtr; // offset 8 / 16
|
||||||
IA32_DESCRIPTOR Idtr; // offset 14 / 26
|
IA32_DESCRIPTOR Idtr; // offset 14 / 26
|
||||||
} CPU_EXCHANGE_ROLE_INFO;
|
} CPU_EXCHANGE_ROLE_INFO;
|
||||||
|
|
||||||
typedef struct _PEI_CPU_MP_DATA PEI_CPU_MP_DATA;
|
typedef struct _PEI_CPU_MP_DATA PEI_CPU_MP_DATA;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
UINT32 LimitLow : 16;
|
UINT32 LimitLow : 16;
|
||||||
UINT32 BaseLow : 16;
|
UINT32 BaseLow : 16;
|
||||||
UINT32 BaseMid : 8;
|
UINT32 BaseMid : 8;
|
||||||
UINT32 Type : 4;
|
UINT32 Type : 4;
|
||||||
UINT32 System : 1;
|
UINT32 System : 1;
|
||||||
UINT32 Dpl : 2;
|
UINT32 Dpl : 2;
|
||||||
UINT32 Present : 1;
|
UINT32 Present : 1;
|
||||||
UINT32 LimitHigh : 4;
|
UINT32 LimitHigh : 4;
|
||||||
UINT32 Software : 1;
|
UINT32 Software : 1;
|
||||||
UINT32 Reserved : 1;
|
UINT32 Reserved : 1;
|
||||||
UINT32 DefaultSize : 1;
|
UINT32 DefaultSize : 1;
|
||||||
UINT32 Granularity : 1;
|
UINT32 Granularity : 1;
|
||||||
UINT32 BaseHigh : 8;
|
UINT32 BaseHigh : 8;
|
||||||
} Bits;
|
} Bits;
|
||||||
UINT64 Uint64;
|
UINT64 Uint64;
|
||||||
} IA32_GDT;
|
} IA32_GDT;
|
||||||
|
|
||||||
//
|
//
|
||||||
// MP CPU exchange information for AP reset code
|
// MP CPU exchange information for AP reset code
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINTN Lock;
|
UINTN Lock;
|
||||||
UINTN StackStart;
|
UINTN StackStart;
|
||||||
UINTN StackSize;
|
UINTN StackSize;
|
||||||
UINTN CFunction;
|
UINTN CFunction;
|
||||||
IA32_DESCRIPTOR GdtrProfile;
|
IA32_DESCRIPTOR GdtrProfile;
|
||||||
IA32_DESCRIPTOR IdtrProfile;
|
IA32_DESCRIPTOR IdtrProfile;
|
||||||
UINTN BufferStart;
|
UINTN BufferStart;
|
||||||
UINTN PmodeOffset;
|
UINTN PmodeOffset;
|
||||||
UINTN NumApsExecuting;
|
UINTN NumApsExecuting;
|
||||||
UINTN LmodeOffset;
|
UINTN LmodeOffset;
|
||||||
UINTN Cr3;
|
UINTN Cr3;
|
||||||
PEI_CPU_MP_DATA *PeiCpuMpData;
|
PEI_CPU_MP_DATA *PeiCpuMpData;
|
||||||
} MP_CPU_EXCHANGE_INFO;
|
} MP_CPU_EXCHANGE_INFO;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 ApicId;
|
UINT32 ApicId;
|
||||||
EFI_HEALTH_FLAGS Health;
|
EFI_HEALTH_FLAGS Health;
|
||||||
CPU_STATE State;
|
CPU_STATE State;
|
||||||
BOOLEAN CpuHealthy;
|
BOOLEAN CpuHealthy;
|
||||||
} PEI_CPU_DATA;
|
} PEI_CPU_DATA;
|
||||||
|
|
||||||
//
|
//
|
||||||
// PEI CPU MP Data save in memory
|
// PEI CPU MP Data save in memory
|
||||||
//
|
//
|
||||||
struct _PEI_CPU_MP_DATA {
|
struct _PEI_CPU_MP_DATA {
|
||||||
UINT32 CpuCount;
|
UINT32 CpuCount;
|
||||||
UINT32 BspNumber;
|
UINT32 BspNumber;
|
||||||
UINTN Buffer;
|
UINTN Buffer;
|
||||||
UINTN CpuApStackSize;
|
UINTN CpuApStackSize;
|
||||||
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
||||||
UINTN WakeupBuffer;
|
UINTN WakeupBuffer;
|
||||||
UINTN BackupBuffer;
|
UINTN BackupBuffer;
|
||||||
UINTN BackupBufferSize;
|
UINTN BackupBufferSize;
|
||||||
UINTN ApFunction;
|
UINTN ApFunction;
|
||||||
UINTN ApFunctionArgument;
|
UINTN ApFunctionArgument;
|
||||||
volatile UINT32 FinishedCount;
|
volatile UINT32 FinishedCount;
|
||||||
BOOLEAN EndOfPeiFlag;
|
BOOLEAN EndOfPeiFlag;
|
||||||
BOOLEAN InitFlag;
|
BOOLEAN InitFlag;
|
||||||
CPU_EXCHANGE_ROLE_INFO BSPInfo;
|
CPU_EXCHANGE_ROLE_INFO BSPInfo;
|
||||||
CPU_EXCHANGE_ROLE_INFO APInfo;
|
CPU_EXCHANGE_ROLE_INFO APInfo;
|
||||||
MTRR_SETTINGS MtrrTable;
|
MTRR_SETTINGS MtrrTable;
|
||||||
PEI_CPU_DATA *CpuData;
|
PEI_CPU_DATA *CpuData;
|
||||||
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
|
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
|
||||||
};
|
};
|
||||||
extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc;
|
extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Assembly code to get starting address and size of the rendezvous entry for APs.
|
Assembly code to get starting address and size of the rendezvous entry for APs.
|
||||||
Information for fixing a jump instruction in the code is also returned.
|
Information for fixing a jump instruction in the code is also returned.
|
||||||
|
|
||||||
@param AddressMap Output buffer for address map information.
|
@param AddressMap Output buffer for address map information.
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
AsmGetAddressMap (
|
AsmGetAddressMap (
|
||||||
OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
|
OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Assembly code to load GDT table and update segment accordingly.
|
Assembly code to load GDT table and update segment accordingly.
|
||||||
|
|
||||||
@param Gdtr Pointer to GDT descriptor
|
@param Gdtr Pointer to GDT descriptor
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
AsmInitializeGdt (
|
AsmInitializeGdt (
|
||||||
IN IA32_DESCRIPTOR *Gdtr
|
IN IA32_DESCRIPTOR *Gdtr
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Assembly code to do CLI-HALT loop.
|
Assembly code to do CLI-HALT loop.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
AsmCliHltLoop (
|
AsmCliHltLoop (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get available system memory below 1MB by specified size.
|
Get available system memory below 1MB by specified size.
|
||||||
|
|
||||||
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
BackupAndPrepareWakeupBuffer(
|
BackupAndPrepareWakeupBuffer(
|
||||||
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Restore wakeup buffer data.
|
Restore wakeup buffer data.
|
||||||
|
|
||||||
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
RestoreWakeupBuffer(
|
RestoreWakeupBuffer(
|
||||||
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Notify function on End Of Pei PPI.
|
Notify function on End Of Pei PPI.
|
||||||
|
|
||||||
On S3 boot, this function will restore wakeup buffer data.
|
On S3 boot, this function will restore wakeup buffer data.
|
||||||
On normal boot, this function will flag wakeup buffer to be un-used type.
|
On normal boot, this function will flag wakeup buffer to be un-used type.
|
||||||
|
|
||||||
@param PeiServices The pointer to the PEI Services Table.
|
@param PeiServices The pointer to the PEI Services Table.
|
||||||
@param NotifyDescriptor Address of the notification descriptor data structure.
|
@param NotifyDescriptor Address of the notification descriptor data structure.
|
||||||
@param Ppi Address of the PPI that was installed.
|
@param Ppi Address of the PPI that was installed.
|
||||||
|
|
||||||
@retval EFI_SUCCESS When everything is OK.
|
@retval EFI_SUCCESS When everything is OK.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CpuMpEndOfPeiCallback (
|
CpuMpEndOfPeiCallback (
|
||||||
IN EFI_PEI_SERVICES **PeiServices,
|
IN EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||||
IN VOID *Ppi
|
IN VOID *Ppi
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function will be called by BSP to wakeup AP.
|
This function will be called by BSP to wakeup AP.
|
||||||
|
|
||||||
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
||||||
@param Broadcast TRUE: Send broadcast IPI to all APs
|
@param Broadcast TRUE: Send broadcast IPI to all APs
|
||||||
FALSE: Send IPI to AP by ApicId
|
FALSE: Send IPI to AP by ApicId
|
||||||
@param ApicId Apic ID for the processor to be waked
|
@param ApicId Apic ID for the processor to be waked
|
||||||
@param Procedure The function to be invoked by AP
|
@param Procedure The function to be invoked by AP
|
||||||
@param ProcedureArgument The argument to be passed into AP function
|
@param ProcedureArgument The argument to be passed into AP function
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
WakeUpAP (
|
WakeUpAP (
|
||||||
IN PEI_CPU_MP_DATA *PeiCpuMpData,
|
IN PEI_CPU_MP_DATA *PeiCpuMpData,
|
||||||
IN BOOLEAN Broadcast,
|
IN BOOLEAN Broadcast,
|
||||||
IN UINT32 ApicId,
|
IN UINT32 ApicId,
|
||||||
IN EFI_AP_PROCEDURE Procedure, OPTIONAL
|
IN EFI_AP_PROCEDURE Procedure, OPTIONAL
|
||||||
IN VOID *ProcedureArgument OPTIONAL
|
IN VOID *ProcedureArgument OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get CPU MP Data pointer from the Guided HOB.
|
Get CPU MP Data pointer from the Guided HOB.
|
||||||
|
|
||||||
@return Pointer to Pointer to PEI CPU MP Data
|
@return Pointer to Pointer to PEI CPU MP Data
|
||||||
**/
|
**/
|
||||||
PEI_CPU_MP_DATA *
|
PEI_CPU_MP_DATA *
|
||||||
GetMpHobData (
|
GetMpHobData (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Find the current Processor number by APIC ID.
|
Find the current Processor number by APIC ID.
|
||||||
|
|
||||||
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
||||||
@param ProcessorNumber Return the pocessor number found
|
@param ProcessorNumber Return the pocessor number found
|
||||||
|
|
||||||
@retval EFI_SUCCESS ProcessorNumber is found and returned.
|
@retval EFI_SUCCESS ProcessorNumber is found and returned.
|
||||||
@retval EFI_NOT_FOUND ProcessorNumber is not found.
|
@retval EFI_NOT_FOUND ProcessorNumber is not found.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
GetProcessorNumber (
|
GetProcessorNumber (
|
||||||
IN PEI_CPU_MP_DATA *PeiCpuMpData,
|
IN PEI_CPU_MP_DATA *PeiCpuMpData,
|
||||||
OUT UINTN *ProcessorNumber
|
OUT UINTN *ProcessorNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Collects BIST data from PPI.
|
Collects BIST data from PPI.
|
||||||
|
|
||||||
This function collects BIST data from Sec Platform Information2 PPI
|
This function collects BIST data from Sec Platform Information2 PPI
|
||||||
or SEC Platform Information PPI.
|
or SEC Platform Information PPI.
|
||||||
|
|
||||||
@param PeiServices Pointer to PEI Services Table
|
@param PeiServices Pointer to PEI Services Table
|
||||||
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
@param PeiCpuMpData Pointer to PEI CPU MP Data
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
CollectBistDataFromPpi (
|
CollectBistDataFromPpi (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
IN PEI_CPU_MP_DATA *PeiCpuMpData
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
|
Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
|
||||||
|
|
||||||
@param PeiServices The pointer to the PEI Services Table.
|
@param PeiServices The pointer to the PEI Services Table.
|
||||||
@param StructureSize The pointer to the variable describing size of the input buffer.
|
@param StructureSize The pointer to the variable describing size of the input buffer.
|
||||||
@param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
|
@param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data was successfully returned.
|
@retval EFI_SUCCESS The data was successfully returned.
|
||||||
@retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
|
@retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
|
||||||
hold the record is returned in StructureSize.
|
hold the record is returned in StructureSize.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
SecPlatformInformation2 (
|
SecPlatformInformation2 (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN OUT UINT64 *StructureSize,
|
IN OUT UINT64 *StructureSize,
|
||||||
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
|
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,90 +1,90 @@
|
|||||||
## @file
|
## @file
|
||||||
# CPU driver installs CPU PI Multi-processor PPI.
|
# CPU driver installs CPU PI Multi-processor PPI.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# 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
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
# http://opensource.org/licenses/bsd-license.php
|
# http://opensource.org/licenses/bsd-license.php
|
||||||
#
|
#
|
||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
|
|
||||||
[Defines]
|
[Defines]
|
||||||
INF_VERSION = 0x00010005
|
INF_VERSION = 0x00010005
|
||||||
BASE_NAME = CpuMpPei
|
BASE_NAME = CpuMpPei
|
||||||
MODULE_UNI_FILE = CpuMpPei.uni
|
MODULE_UNI_FILE = CpuMpPei.uni
|
||||||
FILE_GUID = EDADEB9D-DDBA-48BD-9D22-C1C169C8C5C6
|
FILE_GUID = EDADEB9D-DDBA-48BD-9D22-C1C169C8C5C6
|
||||||
MODULE_TYPE = PEIM
|
MODULE_TYPE = PEIM
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
ENTRY_POINT = CpuMpPeimInit
|
ENTRY_POINT = CpuMpPeimInit
|
||||||
|
|
||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build tools.
|
# The following information is for reference only and not required by the build tools.
|
||||||
#
|
#
|
||||||
# VALID_ARCHITECTURES = IA32 X64
|
# VALID_ARCHITECTURES = IA32 X64
|
||||||
#
|
#
|
||||||
|
|
||||||
[Sources]
|
[Sources]
|
||||||
CpuMpPei.h
|
CpuMpPei.h
|
||||||
CpuMpPei.c
|
CpuMpPei.c
|
||||||
CpuBist.c
|
CpuBist.c
|
||||||
Microcode.h
|
Microcode.h
|
||||||
Microcode.c
|
Microcode.c
|
||||||
PeiMpServices.h
|
PeiMpServices.h
|
||||||
PeiMpServices.c
|
PeiMpServices.c
|
||||||
|
|
||||||
[Sources.IA32]
|
[Sources.IA32]
|
||||||
Ia32/MpEqu.inc
|
Ia32/MpEqu.inc
|
||||||
Ia32/MpFuncs.asm | MSFT
|
Ia32/MpFuncs.asm | MSFT
|
||||||
Ia32/MpFuncs.asm | INTEL
|
Ia32/MpFuncs.asm | INTEL
|
||||||
Ia32/MpFuncs.nasm | GCC
|
Ia32/MpFuncs.nasm | GCC
|
||||||
|
|
||||||
[Sources.X64]
|
[Sources.X64]
|
||||||
X64/MpEqu.inc
|
X64/MpEqu.inc
|
||||||
X64/MpFuncs.asm | MSFT
|
X64/MpFuncs.asm | MSFT
|
||||||
X64/MpFuncs.asm | INTEL
|
X64/MpFuncs.asm | INTEL
|
||||||
X64/MpFuncs.nasm | GCC
|
X64/MpFuncs.nasm | GCC
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
UefiCpuPkg/UefiCpuPkg.dec
|
UefiCpuPkg/UefiCpuPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
DebugLib
|
DebugLib
|
||||||
HobLib
|
HobLib
|
||||||
LocalApicLib
|
LocalApicLib
|
||||||
MtrrLib
|
MtrrLib
|
||||||
PcdLib
|
PcdLib
|
||||||
PeimEntryPoint
|
PeimEntryPoint
|
||||||
PeiServicesLib
|
PeiServicesLib
|
||||||
ReportStatusCodeLib
|
ReportStatusCodeLib
|
||||||
SynchronizationLib
|
SynchronizationLib
|
||||||
TimerLib
|
TimerLib
|
||||||
UefiCpuLib
|
UefiCpuLib
|
||||||
|
|
||||||
[Ppis]
|
[Ppis]
|
||||||
gEfiPeiMpServicesPpiGuid ## PRODUCES
|
gEfiPeiMpServicesPpiGuid ## PRODUCES
|
||||||
gEfiEndOfPeiSignalPpiGuid ## NOTIFY
|
gEfiEndOfPeiSignalPpiGuid ## NOTIFY
|
||||||
gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES
|
gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES
|
||||||
## SOMETIMES_CONSUMES
|
## SOMETIMES_CONSUMES
|
||||||
## SOMETIMES_PRODUCES
|
## SOMETIMES_PRODUCES
|
||||||
gEfiSecPlatformInformation2PpiGuid
|
gEfiSecPlatformInformation2PpiGuid
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiPeiMemoryDiscoveredPpiGuid
|
gEfiPeiMemoryDiscoveredPpiGuid
|
||||||
|
|
||||||
[UserExtensions.TianoCore."ExtraFiles"]
|
[UserExtensions.TianoCore."ExtraFiles"]
|
||||||
CpuMpPeiExtra.uni
|
CpuMpPeiExtra.uni
|
||||||
|
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
;------------------------------------------------------------------------------ ;
|
||||||
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
; This program and the accompanying materials
|
; This program and the accompanying materials
|
||||||
; are licensed and made available under the terms and conditions of the BSD License
|
; 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
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
; http://opensource.org/licenses/bsd-license.php.
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
;
|
;
|
||||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
;
|
;
|
||||||
; Module Name:
|
; Module Name:
|
||||||
;
|
;
|
||||||
; MpEqu.inc
|
; MpEqu.inc
|
||||||
;
|
;
|
||||||
; Abstract:
|
; Abstract:
|
||||||
;
|
;
|
||||||
; This is the equates file for Multiple Processor support
|
; This is the equates file for Multiple Processor support
|
||||||
;
|
;
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
PROTECT_MODE_CS equ 10h
|
PROTECT_MODE_CS equ 10h
|
||||||
PROTECT_MODE_DS equ 18h
|
PROTECT_MODE_DS equ 18h
|
||||||
|
|
||||||
VacantFlag equ 00h
|
VacantFlag equ 00h
|
||||||
NotVacantFlag equ 0ffh
|
NotVacantFlag equ 0ffh
|
||||||
|
|
||||||
CPU_SWITCH_STATE_IDLE equ 0
|
CPU_SWITCH_STATE_IDLE equ 0
|
||||||
CPU_SWITCH_STATE_STORED equ 1
|
CPU_SWITCH_STATE_STORED equ 1
|
||||||
CPU_SWITCH_STATE_LOADED equ 2
|
CPU_SWITCH_STATE_LOADED equ 2
|
||||||
|
|
||||||
LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
|
LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
|
||||||
StackStartAddressLocation equ LockLocation + 04h
|
StackStartAddressLocation equ LockLocation + 04h
|
||||||
StackSizeLocation equ LockLocation + 08h
|
StackSizeLocation equ LockLocation + 08h
|
||||||
ApProcedureLocation equ LockLocation + 0Ch
|
ApProcedureLocation equ LockLocation + 0Ch
|
||||||
GdtrLocation equ LockLocation + 10h
|
GdtrLocation equ LockLocation + 10h
|
||||||
IdtrLocation equ LockLocation + 16h
|
IdtrLocation equ LockLocation + 16h
|
||||||
BufferStartLocation equ LockLocation + 1Ch
|
BufferStartLocation equ LockLocation + 1Ch
|
||||||
PmodeOffsetLocation equ LockLocation + 20h
|
PmodeOffsetLocation equ LockLocation + 20h
|
||||||
NumApsExecutingLoction equ LockLocation + 24h
|
NumApsExecutingLoction equ LockLocation + 24h
|
||||||
|
|
||||||
|
@ -1,276 +1,276 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
;------------------------------------------------------------------------------ ;
|
||||||
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
; This program and the accompanying materials
|
; This program and the accompanying materials
|
||||||
; are licensed and made available under the terms and conditions of the BSD License
|
; 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
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
; http://opensource.org/licenses/bsd-license.php.
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
;
|
;
|
||||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
;
|
;
|
||||||
; Module Name:
|
; Module Name:
|
||||||
;
|
;
|
||||||
; MpFuncs32.asm
|
; MpFuncs32.asm
|
||||||
;
|
;
|
||||||
; Abstract:
|
; Abstract:
|
||||||
;
|
;
|
||||||
; This is the assembly code for MP support
|
; This is the assembly code for MP support
|
||||||
;
|
;
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
.686p
|
.686p
|
||||||
.model flat
|
.model flat
|
||||||
|
|
||||||
include MpEqu.inc
|
include MpEqu.inc
|
||||||
InitializeFloatingPointUnits PROTO C
|
InitializeFloatingPointUnits PROTO C
|
||||||
|
|
||||||
.code
|
.code
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
||||||
;procedure serializes all the AP processors through an Init sequence. It must be
|
;procedure serializes all the AP processors through an Init sequence. It must be
|
||||||
;noted that APs arrive here very raw...ie: real mode, no stack.
|
;noted that APs arrive here very raw...ie: real mode, no stack.
|
||||||
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
||||||
;IS IN MACHINE CODE.
|
;IS IN MACHINE CODE.
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
RendezvousFunnelProc PROC PUBLIC
|
RendezvousFunnelProc PROC PUBLIC
|
||||||
RendezvousFunnelProcStart::
|
RendezvousFunnelProcStart::
|
||||||
; At this point CS = 0x(vv00) and ip= 0x0.
|
; At this point CS = 0x(vv00) and ip= 0x0.
|
||||||
; Save BIST information to ebp firstly
|
; Save BIST information to ebp firstly
|
||||||
db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
|
db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
|
||||||
|
|
||||||
db 8ch,0c8h ; mov ax,cs
|
db 8ch,0c8h ; mov ax,cs
|
||||||
db 8eh,0d8h ; mov ds,ax
|
db 8eh,0d8h ; mov ds,ax
|
||||||
db 8eh,0c0h ; mov es,ax
|
db 8eh,0c0h ; mov es,ax
|
||||||
db 8eh,0d0h ; mov ss,ax
|
db 8eh,0d0h ; mov ss,ax
|
||||||
db 33h,0c0h ; xor ax,ax
|
db 33h,0c0h ; xor ax,ax
|
||||||
db 8eh,0e0h ; mov fs,ax
|
db 8eh,0e0h ; mov fs,ax
|
||||||
db 8eh,0e8h ; mov gs,ax
|
db 8eh,0e8h ; mov gs,ax
|
||||||
|
|
||||||
db 0BEh ; opcode of mov si, mem16
|
db 0BEh ; opcode of mov si, mem16
|
||||||
dw BufferStartLocation ; mov si, BufferStartLocation
|
dw BufferStartLocation ; mov si, BufferStartLocation
|
||||||
db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
|
db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
|
||||||
|
|
||||||
db 0BFh ; opcode of mov di, mem16
|
db 0BFh ; opcode of mov di, mem16
|
||||||
dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
|
dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
|
||||||
db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
|
db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
|
||||||
db 8Bh, 0F8h ; mov di, ax
|
db 8Bh, 0F8h ; mov di, ax
|
||||||
db 83h, 0EFh,06h ; sub di, 06h
|
db 83h, 0EFh,06h ; sub di, 06h
|
||||||
db 66h, 03h, 0C3h ; add eax, ebx
|
db 66h, 03h, 0C3h ; add eax, ebx
|
||||||
db 66h, 89h, 05h ; mov dword ptr [di],eax
|
db 66h, 89h, 05h ; mov dword ptr [di],eax
|
||||||
|
|
||||||
db 0BEh ; opcode of mov si, mem16
|
db 0BEh ; opcode of mov si, mem16
|
||||||
dw GdtrLocation ; mov si, GdtrLocation
|
dw GdtrLocation ; mov si, GdtrLocation
|
||||||
db 66h ; db 66h
|
db 66h ; db 66h
|
||||||
db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
|
db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
|
||||||
|
|
||||||
db 0BEh
|
db 0BEh
|
||||||
dw IdtrLocation ; mov si, IdtrLocation
|
dw IdtrLocation ; mov si, IdtrLocation
|
||||||
db 66h ; db 66h
|
db 66h ; db 66h
|
||||||
db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
|
db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
|
||||||
|
|
||||||
db 33h, 0C0h ; xor ax, ax
|
db 33h, 0C0h ; xor ax, ax
|
||||||
db 8Eh, 0D8h ; mov ds, ax
|
db 8Eh, 0D8h ; mov ds, ax
|
||||||
|
|
||||||
db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
|
db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
|
||||||
db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
|
db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
|
||||||
db 0Fh, 22h, 0C0h ; mov cr0, eax
|
db 0Fh, 22h, 0C0h ; mov cr0, eax
|
||||||
|
|
||||||
db 66h, 67h, 0EAh ; far jump
|
db 66h, 67h, 0EAh ; far jump
|
||||||
dd 0h ; 32-bit offset
|
dd 0h ; 32-bit offset
|
||||||
dw PROTECT_MODE_CS ; 16-bit selector
|
dw PROTECT_MODE_CS ; 16-bit selector
|
||||||
|
|
||||||
Flat32Start:: ; protected mode entry point
|
Flat32Start:: ; protected mode entry point
|
||||||
mov ax, PROTECT_MODE_DS
|
mov ax, PROTECT_MODE_DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov esi, ebx
|
mov esi, ebx
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
mov eax, NotVacantFlag
|
mov eax, NotVacantFlag
|
||||||
|
|
||||||
TestLock:
|
TestLock:
|
||||||
xchg dword ptr [edi], eax
|
xchg dword ptr [edi], eax
|
||||||
cmp eax, NotVacantFlag
|
cmp eax, NotVacantFlag
|
||||||
jz TestLock
|
jz TestLock
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, NumApsExecutingLoction
|
add edi, NumApsExecutingLoction
|
||||||
inc dword ptr [edi]
|
inc dword ptr [edi]
|
||||||
mov ebx, dword ptr [edi]
|
mov ebx, dword ptr [edi]
|
||||||
|
|
||||||
ProgramStack:
|
ProgramStack:
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSizeLocation
|
add edi, StackSizeLocation
|
||||||
mov eax, dword ptr [edi]
|
mov eax, dword ptr [edi]
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStartAddressLocation
|
add edi, StackStartAddressLocation
|
||||||
add eax, dword ptr [edi]
|
add eax, dword ptr [edi]
|
||||||
mov esp, eax
|
mov esp, eax
|
||||||
mov dword ptr [edi], eax
|
mov dword ptr [edi], eax
|
||||||
|
|
||||||
Releaselock:
|
Releaselock:
|
||||||
mov eax, VacantFlag
|
mov eax, VacantFlag
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
xchg dword ptr [edi], eax
|
xchg dword ptr [edi], eax
|
||||||
|
|
||||||
CProcedureInvoke:
|
CProcedureInvoke:
|
||||||
push ebp ; push BIST data at top of AP stack
|
push ebp ; push BIST data at top of AP stack
|
||||||
xor ebp, ebp ; clear ebp for call stack trace
|
xor ebp, ebp ; clear ebp for call stack trace
|
||||||
push ebp
|
push ebp
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
|
|
||||||
mov eax, InitializeFloatingPointUnits
|
mov eax, InitializeFloatingPointUnits
|
||||||
call eax ; Call assembly function to initialize FPU per UEFI spec
|
call eax ; Call assembly function to initialize FPU per UEFI spec
|
||||||
|
|
||||||
push ebx ; Push NumApsExecuting
|
push ebx ; Push NumApsExecuting
|
||||||
mov eax, esi
|
mov eax, esi
|
||||||
add eax, LockLocation
|
add eax, LockLocation
|
||||||
push eax ; push address of exchange info data buffer
|
push eax ; push address of exchange info data buffer
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, ApProcedureLocation
|
add edi, ApProcedureLocation
|
||||||
mov eax, dword ptr [edi]
|
mov eax, dword ptr [edi]
|
||||||
|
|
||||||
call eax ; invoke C function
|
call eax ; invoke C function
|
||||||
|
|
||||||
jmp $ ; never reach here
|
jmp $ ; never reach here
|
||||||
|
|
||||||
RendezvousFunnelProc ENDP
|
RendezvousFunnelProc ENDP
|
||||||
RendezvousFunnelProcEnd::
|
RendezvousFunnelProcEnd::
|
||||||
|
|
||||||
AsmCliHltLoop PROC near C PUBLIC
|
AsmCliHltLoop PROC near C PUBLIC
|
||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
jmp $-2
|
jmp $-2
|
||||||
AsmCliHltLoop ENDP
|
AsmCliHltLoop ENDP
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
; AsmGetAddressMap (&AddressMap);
|
; AsmGetAddressMap (&AddressMap);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
AsmGetAddressMap PROC near C PUBLIC
|
AsmGetAddressMap PROC near C PUBLIC
|
||||||
pushad
|
pushad
|
||||||
mov ebp,esp
|
mov ebp,esp
|
||||||
|
|
||||||
mov ebx, dword ptr [ebp+24h]
|
mov ebx, dword ptr [ebp+24h]
|
||||||
mov dword ptr [ebx], RendezvousFunnelProcStart
|
mov dword ptr [ebx], RendezvousFunnelProcStart
|
||||||
mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
|
mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
|
||||||
mov dword ptr [ebx + 8h], 0
|
mov dword ptr [ebx + 8h], 0
|
||||||
mov dword ptr [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
mov dword ptr [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
||||||
|
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
AsmGetAddressMap ENDP
|
AsmGetAddressMap ENDP
|
||||||
|
|
||||||
PAUSE32 MACRO
|
PAUSE32 MACRO
|
||||||
DB 0F3h
|
DB 0F3h
|
||||||
DB 090h
|
DB 090h
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
||||||
;about to become an AP. It switches it'stack with the current AP.
|
;about to become an AP. It switches it'stack with the current AP.
|
||||||
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
AsmExchangeRole PROC near C PUBLIC
|
AsmExchangeRole PROC near C PUBLIC
|
||||||
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
||||||
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
||||||
pushad
|
pushad
|
||||||
mov ebp,esp
|
mov ebp,esp
|
||||||
|
|
||||||
; esi contains MyInfo pointer
|
; esi contains MyInfo pointer
|
||||||
mov esi, dword ptr [ebp+24h]
|
mov esi, dword ptr [ebp+24h]
|
||||||
|
|
||||||
; edi contains OthersInfo pointer
|
; edi contains OthersInfo pointer
|
||||||
mov edi, dword ptr [ebp+28h]
|
mov edi, dword ptr [ebp+28h]
|
||||||
|
|
||||||
;Store EFLAGS, GDTR and IDTR register to stack
|
;Store EFLAGS, GDTR and IDTR register to stack
|
||||||
pushfd
|
pushfd
|
||||||
mov eax, cr4
|
mov eax, cr4
|
||||||
push eax ; push cr4 firstly
|
push eax ; push cr4 firstly
|
||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
sgdt fword ptr [esi+8]
|
sgdt fword ptr [esi+8]
|
||||||
sidt fword ptr [esi+14]
|
sidt fword ptr [esi+14]
|
||||||
|
|
||||||
; Store the its StackPointer
|
; Store the its StackPointer
|
||||||
mov dword ptr [esi+4],esp
|
mov dword ptr [esi+4],esp
|
||||||
|
|
||||||
; update its switch state to STORED
|
; update its switch state to STORED
|
||||||
mov byte ptr [esi], CPU_SWITCH_STATE_STORED
|
mov byte ptr [esi], CPU_SWITCH_STATE_STORED
|
||||||
|
|
||||||
WaitForOtherStored:
|
WaitForOtherStored:
|
||||||
; wait until the other CPU finish storing its state
|
; wait until the other CPU finish storing its state
|
||||||
cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
|
cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
|
||||||
jz OtherStored
|
jz OtherStored
|
||||||
PAUSE32
|
PAUSE32
|
||||||
jmp WaitForOtherStored
|
jmp WaitForOtherStored
|
||||||
|
|
||||||
OtherStored:
|
OtherStored:
|
||||||
; Since another CPU already stored its state, load them
|
; Since another CPU already stored its state, load them
|
||||||
; load GDTR value
|
; load GDTR value
|
||||||
lgdt fword ptr [edi+8]
|
lgdt fword ptr [edi+8]
|
||||||
|
|
||||||
; load IDTR value
|
; load IDTR value
|
||||||
lidt fword ptr [edi+14]
|
lidt fword ptr [edi+14]
|
||||||
|
|
||||||
; load its future StackPointer
|
; load its future StackPointer
|
||||||
mov esp, dword ptr [edi+4]
|
mov esp, dword ptr [edi+4]
|
||||||
|
|
||||||
; update the other CPU's switch state to LOADED
|
; update the other CPU's switch state to LOADED
|
||||||
mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
|
mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
|
||||||
|
|
||||||
WaitForOtherLoaded:
|
WaitForOtherLoaded:
|
||||||
; wait until the other CPU finish loading new state,
|
; wait until the other CPU finish loading new state,
|
||||||
; otherwise the data in stack may corrupt
|
; otherwise the data in stack may corrupt
|
||||||
cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
|
cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
|
||||||
jz OtherLoaded
|
jz OtherLoaded
|
||||||
PAUSE32
|
PAUSE32
|
||||||
jmp WaitForOtherLoaded
|
jmp WaitForOtherLoaded
|
||||||
|
|
||||||
OtherLoaded:
|
OtherLoaded:
|
||||||
; since the other CPU already get the data it want, leave this procedure
|
; since the other CPU already get the data it want, leave this procedure
|
||||||
pop eax
|
pop eax
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
pop eax
|
pop eax
|
||||||
mov cr4, eax
|
mov cr4, eax
|
||||||
popfd
|
popfd
|
||||||
|
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
AsmExchangeRole ENDP
|
AsmExchangeRole ENDP
|
||||||
|
|
||||||
AsmInitializeGdt PROC near C PUBLIC
|
AsmInitializeGdt PROC near C PUBLIC
|
||||||
push ebp
|
push ebp
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
pushad
|
pushad
|
||||||
mov edi, [ebp + 8] ; Load GDT register
|
mov edi, [ebp + 8] ; Load GDT register
|
||||||
|
|
||||||
mov ax,cs ; Get the selector data from our code image
|
mov ax,cs ; Get the selector data from our code image
|
||||||
mov es,ax
|
mov es,ax
|
||||||
lgdt FWORD PTR es:[edi] ; and update the GDTR
|
lgdt FWORD PTR es:[edi] ; and update the GDTR
|
||||||
|
|
||||||
push PROTECT_MODE_CS
|
push PROTECT_MODE_CS
|
||||||
lea eax, SetCodeSelectorFarJump
|
lea eax, SetCodeSelectorFarJump
|
||||||
push eax
|
push eax
|
||||||
retf
|
retf
|
||||||
SetCodeSelectorFarJump:
|
SetCodeSelectorFarJump:
|
||||||
mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
|
mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
popad
|
popad
|
||||||
pop ebp
|
pop ebp
|
||||||
ret
|
ret
|
||||||
AsmInitializeGdt ENDP
|
AsmInitializeGdt ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -1,255 +1,255 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
;------------------------------------------------------------------------------ ;
|
||||||
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
; This program and the accompanying materials
|
; This program and the accompanying materials
|
||||||
; are licensed and made available under the terms and conditions of the BSD License
|
; 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
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
; http://opensource.org/licenses/bsd-license.php.
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
;
|
;
|
||||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
;
|
;
|
||||||
; Module Name:
|
; Module Name:
|
||||||
;
|
;
|
||||||
; MpFuncs.nasm
|
; MpFuncs.nasm
|
||||||
;
|
;
|
||||||
; Abstract:
|
; Abstract:
|
||||||
;
|
;
|
||||||
; This is the assembly code for MP support
|
; This is the assembly code for MP support
|
||||||
;
|
;
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
%include "MpEqu.inc"
|
%include "MpEqu.inc"
|
||||||
extern ASM_PFX(InitializeFloatingPointUnits)
|
extern ASM_PFX(InitializeFloatingPointUnits)
|
||||||
|
|
||||||
SECTION .text
|
SECTION .text
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
||||||
;procedure serializes all the AP processors through an Init sequence. It must be
|
;procedure serializes all the AP processors through an Init sequence. It must be
|
||||||
;noted that APs arrive here very raw...ie: real mode, no stack.
|
;noted that APs arrive here very raw...ie: real mode, no stack.
|
||||||
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
||||||
;IS IN MACHINE CODE.
|
;IS IN MACHINE CODE.
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
global ASM_PFX(RendezvousFunnelProc)
|
global ASM_PFX(RendezvousFunnelProc)
|
||||||
ASM_PFX(RendezvousFunnelProc):
|
ASM_PFX(RendezvousFunnelProc):
|
||||||
RendezvousFunnelProcStart:
|
RendezvousFunnelProcStart:
|
||||||
; At this point CS = 0x(vv00) and ip= 0x0.
|
; At this point CS = 0x(vv00) and ip= 0x0.
|
||||||
BITS 16
|
BITS 16
|
||||||
mov ebp, eax ; save BIST information
|
mov ebp, eax ; save BIST information
|
||||||
|
|
||||||
mov ax, cs
|
mov ax, cs
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
mov si, BufferStartLocation
|
mov si, BufferStartLocation
|
||||||
mov ebx, [si]
|
mov ebx, [si]
|
||||||
|
|
||||||
mov di, PmodeOffsetLocation
|
mov di, PmodeOffsetLocation
|
||||||
mov eax, [di]
|
mov eax, [di]
|
||||||
mov di, ax
|
mov di, ax
|
||||||
sub di, 06h
|
sub di, 06h
|
||||||
add eax, ebx
|
add eax, ebx
|
||||||
mov [di],eax
|
mov [di],eax
|
||||||
|
|
||||||
mov si, GdtrLocation
|
mov si, GdtrLocation
|
||||||
o32 lgdt [cs:si]
|
o32 lgdt [cs:si]
|
||||||
|
|
||||||
mov si, IdtrLocation
|
mov si, IdtrLocation
|
||||||
o32 lidt [cs:si]
|
o32 lidt [cs:si]
|
||||||
|
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
mov eax, cr0 ;Get control register 0
|
mov eax, cr0 ;Get control register 0
|
||||||
or eax, 000000003h ;Set PE bit (bit #0) & MP
|
or eax, 000000003h ;Set PE bit (bit #0) & MP
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
|
|
||||||
jmp PROTECT_MODE_CS:strict dword 0 ; far jump to protected mode
|
jmp PROTECT_MODE_CS:strict dword 0 ; far jump to protected mode
|
||||||
BITS 32
|
BITS 32
|
||||||
Flat32Start: ; protected mode entry point
|
Flat32Start: ; protected mode entry point
|
||||||
mov ax, PROTECT_MODE_DS
|
mov ax, PROTECT_MODE_DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov esi, ebx
|
mov esi, ebx
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
mov eax, NotVacantFlag
|
mov eax, NotVacantFlag
|
||||||
|
|
||||||
TestLock:
|
TestLock:
|
||||||
xchg [edi], eax
|
xchg [edi], eax
|
||||||
cmp eax, NotVacantFlag
|
cmp eax, NotVacantFlag
|
||||||
jz TestLock
|
jz TestLock
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, NumApsExecutingLoction
|
add edi, NumApsExecutingLoction
|
||||||
inc dword [edi]
|
inc dword [edi]
|
||||||
mov ebx, [edi]
|
mov ebx, [edi]
|
||||||
|
|
||||||
ProgramStack:
|
ProgramStack:
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSizeLocation
|
add edi, StackSizeLocation
|
||||||
mov eax, [edi]
|
mov eax, [edi]
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStartAddressLocation
|
add edi, StackStartAddressLocation
|
||||||
add eax, [edi]
|
add eax, [edi]
|
||||||
mov esp, eax
|
mov esp, eax
|
||||||
mov [edi], eax
|
mov [edi], eax
|
||||||
|
|
||||||
Releaselock:
|
Releaselock:
|
||||||
mov eax, VacantFlag
|
mov eax, VacantFlag
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
xchg [edi], eax
|
xchg [edi], eax
|
||||||
|
|
||||||
CProcedureInvoke:
|
CProcedureInvoke:
|
||||||
push ebp ; push BIST data at top of AP stack
|
push ebp ; push BIST data at top of AP stack
|
||||||
xor ebp, ebp ; clear ebp for call stack trace
|
xor ebp, ebp ; clear ebp for call stack trace
|
||||||
push ebp
|
push ebp
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
|
|
||||||
mov eax, ASM_PFX(InitializeFloatingPointUnits)
|
mov eax, ASM_PFX(InitializeFloatingPointUnits)
|
||||||
call eax ; Call assembly function to initialize FPU per UEFI spec
|
call eax ; Call assembly function to initialize FPU per UEFI spec
|
||||||
|
|
||||||
push ebx ; Push NumApsExecuting
|
push ebx ; Push NumApsExecuting
|
||||||
mov eax, esi
|
mov eax, esi
|
||||||
add eax, LockLocation
|
add eax, LockLocation
|
||||||
push eax ; push address of exchange info data buffer
|
push eax ; push address of exchange info data buffer
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, ApProcedureLocation
|
add edi, ApProcedureLocation
|
||||||
mov eax, [edi]
|
mov eax, [edi]
|
||||||
|
|
||||||
call eax ; invoke C function
|
call eax ; invoke C function
|
||||||
|
|
||||||
jmp $ ; never reach here
|
jmp $ ; never reach here
|
||||||
RendezvousFunnelProcEnd:
|
RendezvousFunnelProcEnd:
|
||||||
|
|
||||||
global ASM_PFX(AsmCliHltLoop)
|
global ASM_PFX(AsmCliHltLoop)
|
||||||
ASM_PFX(AsmCliHltLoop):
|
ASM_PFX(AsmCliHltLoop):
|
||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
jmp $-2
|
jmp $-2
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
; AsmGetAddressMap (&AddressMap);
|
; AsmGetAddressMap (&AddressMap);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
global ASM_PFX(AsmGetAddressMap)
|
global ASM_PFX(AsmGetAddressMap)
|
||||||
ASM_PFX(AsmGetAddressMap):
|
ASM_PFX(AsmGetAddressMap):
|
||||||
pushad
|
pushad
|
||||||
mov ebp,esp
|
mov ebp,esp
|
||||||
|
|
||||||
mov ebx, [ebp + 24h]
|
mov ebx, [ebp + 24h]
|
||||||
mov dword [ebx], RendezvousFunnelProcStart
|
mov dword [ebx], RendezvousFunnelProcStart
|
||||||
mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
|
mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
|
||||||
mov dword [ebx + 8h], 0
|
mov dword [ebx + 8h], 0
|
||||||
mov dword [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
mov dword [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
||||||
|
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
||||||
;about to become an AP. It switches it'stack with the current AP.
|
;about to become an AP. It switches it'stack with the current AP.
|
||||||
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
global ASM_PFX(AsmExchangeRole)
|
global ASM_PFX(AsmExchangeRole)
|
||||||
ASM_PFX(AsmExchangeRole):
|
ASM_PFX(AsmExchangeRole):
|
||||||
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
||||||
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
||||||
pushad
|
pushad
|
||||||
mov ebp,esp
|
mov ebp,esp
|
||||||
|
|
||||||
; esi contains MyInfo pointer
|
; esi contains MyInfo pointer
|
||||||
mov esi, [ebp + 24h]
|
mov esi, [ebp + 24h]
|
||||||
|
|
||||||
; edi contains OthersInfo pointer
|
; edi contains OthersInfo pointer
|
||||||
mov edi, [ebp + 28h]
|
mov edi, [ebp + 28h]
|
||||||
|
|
||||||
;Store EFLAGS, GDTR and IDTR register to stack
|
;Store EFLAGS, GDTR and IDTR register to stack
|
||||||
pushfd
|
pushfd
|
||||||
mov eax, cr4
|
mov eax, cr4
|
||||||
push eax ; push cr4 firstly
|
push eax ; push cr4 firstly
|
||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
sgdt [esi + 8]
|
sgdt [esi + 8]
|
||||||
sidt [esi + 14]
|
sidt [esi + 14]
|
||||||
|
|
||||||
; Store the its StackPointer
|
; Store the its StackPointer
|
||||||
mov [esi + 4],esp
|
mov [esi + 4],esp
|
||||||
|
|
||||||
; update its switch state to STORED
|
; update its switch state to STORED
|
||||||
mov byte [esi], CPU_SWITCH_STATE_STORED
|
mov byte [esi], CPU_SWITCH_STATE_STORED
|
||||||
|
|
||||||
WaitForOtherStored:
|
WaitForOtherStored:
|
||||||
; wait until the other CPU finish storing its state
|
; wait until the other CPU finish storing its state
|
||||||
cmp byte [edi], CPU_SWITCH_STATE_STORED
|
cmp byte [edi], CPU_SWITCH_STATE_STORED
|
||||||
jz OtherStored
|
jz OtherStored
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherStored
|
jmp WaitForOtherStored
|
||||||
|
|
||||||
OtherStored:
|
OtherStored:
|
||||||
; Since another CPU already stored its state, load them
|
; Since another CPU already stored its state, load them
|
||||||
; load GDTR value
|
; load GDTR value
|
||||||
lgdt [edi + 8]
|
lgdt [edi + 8]
|
||||||
|
|
||||||
; load IDTR value
|
; load IDTR value
|
||||||
lidt [edi + 14]
|
lidt [edi + 14]
|
||||||
|
|
||||||
; load its future StackPointer
|
; load its future StackPointer
|
||||||
mov esp, [edi + 4]
|
mov esp, [edi + 4]
|
||||||
|
|
||||||
; update the other CPU's switch state to LOADED
|
; update the other CPU's switch state to LOADED
|
||||||
mov byte [edi], CPU_SWITCH_STATE_LOADED
|
mov byte [edi], CPU_SWITCH_STATE_LOADED
|
||||||
|
|
||||||
WaitForOtherLoaded:
|
WaitForOtherLoaded:
|
||||||
; wait until the other CPU finish loading new state,
|
; wait until the other CPU finish loading new state,
|
||||||
; otherwise the data in stack may corrupt
|
; otherwise the data in stack may corrupt
|
||||||
cmp byte [esi], CPU_SWITCH_STATE_LOADED
|
cmp byte [esi], CPU_SWITCH_STATE_LOADED
|
||||||
jz OtherLoaded
|
jz OtherLoaded
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherLoaded
|
jmp WaitForOtherLoaded
|
||||||
|
|
||||||
OtherLoaded:
|
OtherLoaded:
|
||||||
; since the other CPU already get the data it want, leave this procedure
|
; since the other CPU already get the data it want, leave this procedure
|
||||||
pop eax
|
pop eax
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
pop eax
|
pop eax
|
||||||
mov cr4, eax
|
mov cr4, eax
|
||||||
popfd
|
popfd
|
||||||
|
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
global ASM_PFX(AsmInitializeGdt)
|
global ASM_PFX(AsmInitializeGdt)
|
||||||
ASM_PFX(AsmInitializeGdt):
|
ASM_PFX(AsmInitializeGdt):
|
||||||
push ebp
|
push ebp
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
pushad
|
pushad
|
||||||
mov edi, [ebp + 8] ; Load GDT register
|
mov edi, [ebp + 8] ; Load GDT register
|
||||||
|
|
||||||
lgdt [edi] ; and update the GDTR
|
lgdt [edi] ; and update the GDTR
|
||||||
|
|
||||||
push PROTECT_MODE_CS
|
push PROTECT_MODE_CS
|
||||||
mov eax, ASM_PFX(SetCodeSelectorFarJump)
|
mov eax, ASM_PFX(SetCodeSelectorFarJump)
|
||||||
push eax
|
push eax
|
||||||
retf
|
retf
|
||||||
ASM_PFX(SetCodeSelectorFarJump):
|
ASM_PFX(SetCodeSelectorFarJump):
|
||||||
mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
|
mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
popad
|
popad
|
||||||
pop ebp
|
pop ebp
|
||||||
ret
|
ret
|
||||||
|
@ -1,200 +1,200 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Implementation of loading microcode on processors.
|
Implementation of loading microcode on processors.
|
||||||
|
|
||||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
http://opensource.org/licenses/bsd-license.php
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "CpuMpPei.h"
|
#include "CpuMpPei.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get microcode update signature of currently loaded microcode update.
|
Get microcode update signature of currently loaded microcode update.
|
||||||
|
|
||||||
@return Microcode signature.
|
@return Microcode signature.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
UINT32
|
UINT32
|
||||||
GetCurrentMicrocodeSignature (
|
GetCurrentMicrocodeSignature (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT64 Signature;
|
UINT64 Signature;
|
||||||
|
|
||||||
AsmWriteMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
|
AsmWriteMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
|
||||||
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
|
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
|
||||||
Signature = AsmReadMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID);
|
Signature = AsmReadMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID);
|
||||||
return (UINT32) RShiftU64 (Signature, 32);
|
return (UINT32) RShiftU64 (Signature, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Detect whether specified processor can find matching microcode patch and load it.
|
Detect whether specified processor can find matching microcode patch and load it.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
MicrocodeDetect (
|
MicrocodeDetect (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT64 MicrocodePatchAddress;
|
UINT64 MicrocodePatchAddress;
|
||||||
UINT64 MicrocodePatchRegionSize;
|
UINT64 MicrocodePatchRegionSize;
|
||||||
UINT32 ExtendedTableLength;
|
UINT32 ExtendedTableLength;
|
||||||
UINT32 ExtendedTableCount;
|
UINT32 ExtendedTableCount;
|
||||||
EFI_CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
|
EFI_CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
|
||||||
EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
|
EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
|
||||||
EFI_CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
|
EFI_CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
|
||||||
UINTN MicrocodeEnd;
|
UINTN MicrocodeEnd;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT8 PlatformId;
|
UINT8 PlatformId;
|
||||||
UINT32 RegEax;
|
UINT32 RegEax;
|
||||||
UINT32 LatestRevision;
|
UINT32 LatestRevision;
|
||||||
UINTN TotalSize;
|
UINTN TotalSize;
|
||||||
UINT32 CheckSum32;
|
UINT32 CheckSum32;
|
||||||
BOOLEAN CorrectMicrocode;
|
BOOLEAN CorrectMicrocode;
|
||||||
INT32 CurrentSignature;
|
INT32 CurrentSignature;
|
||||||
MICROCODE_INFO MicrocodeInfo;
|
MICROCODE_INFO MicrocodeInfo;
|
||||||
|
|
||||||
ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));
|
ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));
|
||||||
MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);
|
MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);
|
||||||
MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);
|
MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);
|
||||||
if (MicrocodePatchRegionSize == 0) {
|
if (MicrocodePatchRegionSize == 0) {
|
||||||
//
|
//
|
||||||
// There is no microcode patches
|
// There is no microcode patches
|
||||||
//
|
//
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtendedTableLength = 0;
|
ExtendedTableLength = 0;
|
||||||
//
|
//
|
||||||
// Here data of CPUID leafs have not been collected into context buffer, so
|
// Here data of CPUID leafs have not been collected into context buffer, so
|
||||||
// GetProcessorCpuid() cannot be used here to retrieve CPUID data.
|
// GetProcessorCpuid() cannot be used here to retrieve CPUID data.
|
||||||
//
|
//
|
||||||
AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
|
AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
|
||||||
|
|
||||||
//
|
//
|
||||||
// The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID
|
// The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID
|
||||||
//
|
//
|
||||||
PlatformId = (UINT8) AsmMsrBitFieldRead64 (EFI_MSR_IA32_PLATFORM_ID, 50, 52);
|
PlatformId = (UINT8) AsmMsrBitFieldRead64 (EFI_MSR_IA32_PLATFORM_ID, 50, 52);
|
||||||
|
|
||||||
LatestRevision = 0;
|
LatestRevision = 0;
|
||||||
MicrocodeEnd = (UINTN) (MicrocodePatchAddress + MicrocodePatchRegionSize);
|
MicrocodeEnd = (UINTN) (MicrocodePatchAddress + MicrocodePatchRegionSize);
|
||||||
MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;
|
MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;
|
||||||
do {
|
do {
|
||||||
//
|
//
|
||||||
// Check if the microcode is for the Cpu and the version is newer
|
// Check if the microcode is for the Cpu and the version is newer
|
||||||
// and the update can be processed on the platform
|
// and the update can be processed on the platform
|
||||||
//
|
//
|
||||||
CorrectMicrocode = FALSE;
|
CorrectMicrocode = FALSE;
|
||||||
if (MicrocodeEntryPoint->HeaderVersion == 0x1) {
|
if (MicrocodeEntryPoint->HeaderVersion == 0x1) {
|
||||||
//
|
//
|
||||||
// It is the microcode header. It is not the padding data between microcode patches
|
// It is the microcode header. It is not the padding data between microcode patches
|
||||||
// becasue the padding data should not include 0x00000001 and it should be the repeated
|
// becasue the padding data should not include 0x00000001 and it should be the repeated
|
||||||
// byte format (like 0xXYXYXYXY....).
|
// byte format (like 0xXYXYXYXY....).
|
||||||
//
|
//
|
||||||
if (MicrocodeEntryPoint->ProcessorId == RegEax &&
|
if (MicrocodeEntryPoint->ProcessorId == RegEax &&
|
||||||
MicrocodeEntryPoint->UpdateRevision > LatestRevision &&
|
MicrocodeEntryPoint->UpdateRevision > LatestRevision &&
|
||||||
(MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId))
|
(MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId))
|
||||||
) {
|
) {
|
||||||
if (MicrocodeEntryPoint->DataSize == 0) {
|
if (MicrocodeEntryPoint->DataSize == 0) {
|
||||||
CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, 2048);
|
CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, 2048);
|
||||||
} else {
|
} else {
|
||||||
CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, MicrocodeEntryPoint->DataSize + sizeof(EFI_CPU_MICROCODE_HEADER));
|
CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, MicrocodeEntryPoint->DataSize + sizeof(EFI_CPU_MICROCODE_HEADER));
|
||||||
}
|
}
|
||||||
if (CheckSum32 == 0) {
|
if (CheckSum32 == 0) {
|
||||||
CorrectMicrocode = TRUE;
|
CorrectMicrocode = TRUE;
|
||||||
}
|
}
|
||||||
} else if ((MicrocodeEntryPoint->DataSize != 0) &&
|
} else if ((MicrocodeEntryPoint->DataSize != 0) &&
|
||||||
(MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {
|
(MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {
|
||||||
ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
|
ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
|
||||||
if (ExtendedTableLength != 0) {
|
if (ExtendedTableLength != 0) {
|
||||||
//
|
//
|
||||||
// Extended Table exist, check if the CPU in support list
|
// Extended Table exist, check if the CPU in support list
|
||||||
//
|
//
|
||||||
ExtendedTableHeader = (EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
|
ExtendedTableHeader = (EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
|
||||||
//
|
//
|
||||||
// Calculate Extended Checksum
|
// Calculate Extended Checksum
|
||||||
//
|
//
|
||||||
if ((ExtendedTableLength % 4) == 0) {
|
if ((ExtendedTableLength % 4) == 0) {
|
||||||
CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength);
|
CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength);
|
||||||
if (CheckSum32 == 0) {
|
if (CheckSum32 == 0) {
|
||||||
//
|
//
|
||||||
// Checksum correct
|
// Checksum correct
|
||||||
//
|
//
|
||||||
ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
|
ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
|
||||||
ExtendedTable = (EFI_CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
|
ExtendedTable = (EFI_CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
|
||||||
for (Index = 0; Index < ExtendedTableCount; Index ++) {
|
for (Index = 0; Index < ExtendedTableCount; Index ++) {
|
||||||
CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTable, sizeof(EFI_CPU_MICROCODE_EXTENDED_TABLE));
|
CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTable, sizeof(EFI_CPU_MICROCODE_EXTENDED_TABLE));
|
||||||
if (CheckSum32 == 0) {
|
if (CheckSum32 == 0) {
|
||||||
//
|
//
|
||||||
// Verify Header
|
// Verify Header
|
||||||
//
|
//
|
||||||
if ((ExtendedTable->ProcessorSignature == RegEax) &&
|
if ((ExtendedTable->ProcessorSignature == RegEax) &&
|
||||||
(ExtendedTable->ProcessorFlag & (1 << PlatformId)) ) {
|
(ExtendedTable->ProcessorFlag & (1 << PlatformId)) ) {
|
||||||
//
|
//
|
||||||
// Find one
|
// Find one
|
||||||
//
|
//
|
||||||
CorrectMicrocode = TRUE;
|
CorrectMicrocode = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExtendedTable ++;
|
ExtendedTable ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// It is the padding data between the microcode patches for microcode patches alignment.
|
// It is the padding data between the microcode patches for microcode patches alignment.
|
||||||
// Because the microcode patch is the multiple of 1-KByte, the padding data should not
|
// Because the microcode patch is the multiple of 1-KByte, the padding data should not
|
||||||
// exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode
|
// exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode
|
||||||
// alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to
|
// alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to
|
||||||
// find the next possible microcode patch header.
|
// find the next possible microcode patch header.
|
||||||
//
|
//
|
||||||
MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB);
|
MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Get the next patch.
|
// Get the next patch.
|
||||||
//
|
//
|
||||||
if (MicrocodeEntryPoint->DataSize == 0) {
|
if (MicrocodeEntryPoint->DataSize == 0) {
|
||||||
TotalSize = 2048;
|
TotalSize = 2048;
|
||||||
} else {
|
} else {
|
||||||
TotalSize = MicrocodeEntryPoint->TotalSize;
|
TotalSize = MicrocodeEntryPoint->TotalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CorrectMicrocode) {
|
if (CorrectMicrocode) {
|
||||||
LatestRevision = MicrocodeEntryPoint->UpdateRevision;
|
LatestRevision = MicrocodeEntryPoint->UpdateRevision;
|
||||||
MicrocodeInfo.MicrocodeData = (VOID *)((UINTN)MicrocodeEntryPoint + sizeof (EFI_CPU_MICROCODE_HEADER));
|
MicrocodeInfo.MicrocodeData = (VOID *)((UINTN)MicrocodeEntryPoint + sizeof (EFI_CPU_MICROCODE_HEADER));
|
||||||
MicrocodeInfo.MicrocodeSize = TotalSize;
|
MicrocodeInfo.MicrocodeSize = TotalSize;
|
||||||
MicrocodeInfo.ProcessorId = RegEax;
|
MicrocodeInfo.ProcessorId = RegEax;
|
||||||
}
|
}
|
||||||
|
|
||||||
MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
|
MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
|
||||||
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));
|
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));
|
||||||
|
|
||||||
if (LatestRevision > 0) {
|
if (LatestRevision > 0) {
|
||||||
//
|
//
|
||||||
// Get microcode update signature of currently loaded microcode update
|
// Get microcode update signature of currently loaded microcode update
|
||||||
//
|
//
|
||||||
CurrentSignature = GetCurrentMicrocodeSignature ();
|
CurrentSignature = GetCurrentMicrocodeSignature ();
|
||||||
//
|
//
|
||||||
// If no microcode update has been loaded, then trigger microcode load.
|
// If no microcode update has been loaded, then trigger microcode load.
|
||||||
//
|
//
|
||||||
if (CurrentSignature == 0) {
|
if (CurrentSignature == 0) {
|
||||||
AsmWriteMsr64 (
|
AsmWriteMsr64 (
|
||||||
EFI_MSR_IA32_BIOS_UPDT_TRIG,
|
EFI_MSR_IA32_BIOS_UPDT_TRIG,
|
||||||
(UINT64) (UINTN) MicrocodeInfo.MicrocodeData
|
(UINT64) (UINTN) MicrocodeInfo.MicrocodeData
|
||||||
);
|
);
|
||||||
MicrocodeInfo.Load = TRUE;
|
MicrocodeInfo.Load = TRUE;
|
||||||
} else {
|
} else {
|
||||||
MicrocodeInfo.Load = FALSE;
|
MicrocodeInfo.Load = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,68 +1,68 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Definitions for loading microcode on processors.
|
Definitions for loading microcode on processors.
|
||||||
|
|
||||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
http://opensource.org/licenses/bsd-license.php
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef _CPU_MICROCODE_H_
|
#ifndef _CPU_MICROCODE_H_
|
||||||
#define _CPU_MICROCODE_H_
|
#define _CPU_MICROCODE_H_
|
||||||
|
|
||||||
#define EFI_MSR_IA32_PLATFORM_ID 0x17
|
#define EFI_MSR_IA32_PLATFORM_ID 0x17
|
||||||
#define EFI_MSR_IA32_BIOS_UPDT_TRIG 0x79
|
#define EFI_MSR_IA32_BIOS_UPDT_TRIG 0x79
|
||||||
#define EFI_MSR_IA32_BIOS_SIGN_ID 0x8b
|
#define EFI_MSR_IA32_BIOS_SIGN_ID 0x8b
|
||||||
|
|
||||||
#define MAX_MICROCODE_DESCRIPTOR_LENGTH 100
|
#define MAX_MICROCODE_DESCRIPTOR_LENGTH 100
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VOID *MicrocodeData;
|
VOID *MicrocodeData;
|
||||||
UINTN MicrocodeSize;
|
UINTN MicrocodeSize;
|
||||||
UINT32 ProcessorId;
|
UINT32 ProcessorId;
|
||||||
BOOLEAN Load;
|
BOOLEAN Load;
|
||||||
} MICROCODE_INFO;
|
} MICROCODE_INFO;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Definition for IA32 microcode format
|
// Definition for IA32 microcode format
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 HeaderVersion;
|
UINT32 HeaderVersion;
|
||||||
UINT32 UpdateRevision;
|
UINT32 UpdateRevision;
|
||||||
UINT32 Date;
|
UINT32 Date;
|
||||||
UINT32 ProcessorId;
|
UINT32 ProcessorId;
|
||||||
UINT32 Checksum;
|
UINT32 Checksum;
|
||||||
UINT32 LoaderRevision;
|
UINT32 LoaderRevision;
|
||||||
UINT32 ProcessorFlags;
|
UINT32 ProcessorFlags;
|
||||||
UINT32 DataSize;
|
UINT32 DataSize;
|
||||||
UINT32 TotalSize;
|
UINT32 TotalSize;
|
||||||
UINT8 Reserved[12];
|
UINT8 Reserved[12];
|
||||||
} EFI_CPU_MICROCODE_HEADER;
|
} EFI_CPU_MICROCODE_HEADER;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 ExtendedSignatureCount;
|
UINT32 ExtendedSignatureCount;
|
||||||
UINT32 ExtendedTableChecksum;
|
UINT32 ExtendedTableChecksum;
|
||||||
UINT8 Reserved[12];
|
UINT8 Reserved[12];
|
||||||
} EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER;
|
} EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 ProcessorSignature;
|
UINT32 ProcessorSignature;
|
||||||
UINT32 ProcessorFlag;
|
UINT32 ProcessorFlag;
|
||||||
UINT32 ProcessorChecksum;
|
UINT32 ProcessorChecksum;
|
||||||
} EFI_CPU_MICROCODE_EXTENDED_TABLE;
|
} EFI_CPU_MICROCODE_EXTENDED_TABLE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Detect whether specified processor can find matching microcode patch and load it.
|
Detect whether specified processor can find matching microcode patch and load it.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
MicrocodeDetect (
|
MicrocodeDetect (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,377 +1,377 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Functions prototype of Multiple Processor PPI services.
|
Functions prototype of Multiple Processor PPI services.
|
||||||
|
|
||||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
http://opensource.org/licenses/bsd-license.php
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef _PEI_MP_SERVICES_H_
|
#ifndef _PEI_MP_SERVICES_H_
|
||||||
#define _PEI_MP_SERVICES_H_
|
#define _PEI_MP_SERVICES_H_
|
||||||
|
|
||||||
#include "CpuMpPei.h"
|
#include "CpuMpPei.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// The MP data for switch BSP
|
// The MP data for switch BSP
|
||||||
//
|
//
|
||||||
#define CPU_SWITCH_STATE_IDLE 0
|
#define CPU_SWITCH_STATE_IDLE 0
|
||||||
#define CPU_SWITCH_STATE_STORED 1
|
#define CPU_SWITCH_STATE_STORED 1
|
||||||
#define CPU_SWITCH_STATE_LOADED 2
|
#define CPU_SWITCH_STATE_LOADED 2
|
||||||
|
|
||||||
#define CPU_CHECK_AP_INTERVAL 0x100 // 100 microseconds
|
#define CPU_CHECK_AP_INTERVAL 0x100 // 100 microseconds
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function is called by both the BSP and the AP which is to become the BSP to
|
This function is called by both the BSP and the AP which is to become the BSP to
|
||||||
Exchange execution context including stack between them. After return from this
|
Exchange execution context including stack between them. After return from this
|
||||||
function, the BSP becomes AP and the AP becomes the BSP.
|
function, the BSP becomes AP and the AP becomes the BSP.
|
||||||
|
|
||||||
@param MyInfo Pointer to buffer holding the exchanging information for the executing processor.
|
@param MyInfo Pointer to buffer holding the exchanging information for the executing processor.
|
||||||
@param OthersInfo Pointer to buffer holding the exchanging information for the peer.
|
@param OthersInfo Pointer to buffer holding the exchanging information for the peer.
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
AsmExchangeRole (
|
AsmExchangeRole (
|
||||||
IN CPU_EXCHANGE_ROLE_INFO *MyInfo,
|
IN CPU_EXCHANGE_ROLE_INFO *MyInfo,
|
||||||
IN CPU_EXCHANGE_ROLE_INFO *OthersInfo
|
IN CPU_EXCHANGE_ROLE_INFO *OthersInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This service retrieves the number of logical processor in the platform
|
This service retrieves the number of logical processor in the platform
|
||||||
and the number of those logical processors that are enabled on this boot.
|
and the number of those logical processors that are enabled on this boot.
|
||||||
This service may only be called from the BSP.
|
This service may only be called from the BSP.
|
||||||
|
|
||||||
This function is used to retrieve the following information:
|
This function is used to retrieve the following information:
|
||||||
- The number of logical processors that are present in the system.
|
- The number of logical processors that are present in the system.
|
||||||
- The number of enabled logical processors in the system at the instant
|
- The number of enabled logical processors in the system at the instant
|
||||||
this call is made.
|
this call is made.
|
||||||
|
|
||||||
Because MP Service Ppi provides services to enable and disable processors
|
Because MP Service Ppi provides services to enable and disable processors
|
||||||
dynamically, the number of enabled logical processors may vary during the
|
dynamically, the number of enabled logical processors may vary during the
|
||||||
course of a boot session.
|
course of a boot session.
|
||||||
|
|
||||||
If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
|
If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
|
||||||
If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
|
If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
|
||||||
EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
|
EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
|
||||||
is returned in NumberOfProcessors, the number of currently enabled processor
|
is returned in NumberOfProcessors, the number of currently enabled processor
|
||||||
is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
|
is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
|
||||||
|
|
||||||
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
published by the PEI Foundation.
|
published by the PEI Foundation.
|
||||||
@param[in] This Pointer to this instance of the PPI.
|
@param[in] This Pointer to this instance of the PPI.
|
||||||
@param[out] NumberOfProcessors Pointer to the total number of logical processors in
|
@param[out] NumberOfProcessors Pointer to the total number of logical processors in
|
||||||
the system, including the BSP and disabled APs.
|
the system, including the BSP and disabled APs.
|
||||||
@param[out] NumberOfEnabledProcessors
|
@param[out] NumberOfEnabledProcessors
|
||||||
Number of processors in the system that are enabled.
|
Number of processors in the system that are enabled.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The number of logical processors and enabled
|
@retval EFI_SUCCESS The number of logical processors and enabled
|
||||||
logical processors was retrieved.
|
logical processors was retrieved.
|
||||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
@retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
|
@retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
|
||||||
NumberOfEnabledProcessors is NULL.
|
NumberOfEnabledProcessors is NULL.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PeiGetNumberOfProcessors (
|
PeiGetNumberOfProcessors (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_MP_SERVICES_PPI *This,
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
OUT UINTN *NumberOfProcessors,
|
OUT UINTN *NumberOfProcessors,
|
||||||
OUT UINTN *NumberOfEnabledProcessors
|
OUT UINTN *NumberOfEnabledProcessors
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets detailed MP-related information on the requested processor at the
|
Gets detailed MP-related information on the requested processor at the
|
||||||
instant this call is made. This service may only be called from the BSP.
|
instant this call is made. This service may only be called from the BSP.
|
||||||
|
|
||||||
This service retrieves detailed MP-related information about any processor
|
This service retrieves detailed MP-related information about any processor
|
||||||
on the platform. Note the following:
|
on the platform. Note the following:
|
||||||
- The processor information may change during the course of a boot session.
|
- The processor information may change during the course of a boot session.
|
||||||
- The information presented here is entirely MP related.
|
- The information presented here is entirely MP related.
|
||||||
|
|
||||||
Information regarding the number of caches and their sizes, frequency of operation,
|
Information regarding the number of caches and their sizes, frequency of operation,
|
||||||
slot numbers is all considered platform-related information and is not provided
|
slot numbers is all considered platform-related information and is not provided
|
||||||
by this service.
|
by this service.
|
||||||
|
|
||||||
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
published by the PEI Foundation.
|
published by the PEI Foundation.
|
||||||
@param[in] This Pointer to this instance of the PPI.
|
@param[in] This Pointer to this instance of the PPI.
|
||||||
@param[in] ProcessorNumber Pointer to the total number of logical processors in
|
@param[in] ProcessorNumber Pointer to the total number of logical processors in
|
||||||
the system, including the BSP and disabled APs.
|
the system, including the BSP and disabled APs.
|
||||||
@param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
|
@param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
|
||||||
|
|
||||||
@retval EFI_SUCCESS Processor information was returned.
|
@retval EFI_SUCCESS Processor information was returned.
|
||||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
@retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
|
@retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
|
||||||
@retval EFI_NOT_FOUND The processor with the handle specified by
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
ProcessorNumber does not exist in the platform.
|
ProcessorNumber does not exist in the platform.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PeiGetProcessorInfo (
|
PeiGetProcessorInfo (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_MP_SERVICES_PPI *This,
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
IN UINTN ProcessorNumber,
|
IN UINTN ProcessorNumber,
|
||||||
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This service executes a caller provided function on all enabled APs. APs can
|
This service executes a caller provided function on all enabled APs. APs can
|
||||||
run either simultaneously or one at a time in sequence. This service supports
|
run either simultaneously or one at a time in sequence. This service supports
|
||||||
both blocking requests only. This service may only
|
both blocking requests only. This service may only
|
||||||
be called from the BSP.
|
be called from the BSP.
|
||||||
|
|
||||||
This function is used to dispatch all the enabled APs to the function specified
|
This function is used to dispatch all the enabled APs to the function specified
|
||||||
by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
|
by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
|
||||||
immediately and Procedure is not started on any AP.
|
immediately and Procedure is not started on any AP.
|
||||||
|
|
||||||
If SingleThread is TRUE, all the enabled APs execute the function specified by
|
If SingleThread is TRUE, all the enabled APs execute the function specified by
|
||||||
Procedure one by one, in ascending order of processor handle number. Otherwise,
|
Procedure one by one, in ascending order of processor handle number. Otherwise,
|
||||||
all the enabled APs execute the function specified by Procedure simultaneously.
|
all the enabled APs execute the function specified by Procedure simultaneously.
|
||||||
|
|
||||||
If the timeout specified by TimeoutInMicroSeconds expires before all APs return
|
If the timeout specified by TimeoutInMicroSeconds expires before all APs return
|
||||||
from Procedure, then Procedure on the failed APs is terminated. All enabled APs
|
from Procedure, then Procedure on the failed APs is terminated. All enabled APs
|
||||||
are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
||||||
and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its
|
and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its
|
||||||
content points to the list of processor handle numbers in which Procedure was
|
content points to the list of processor handle numbers in which Procedure was
|
||||||
terminated.
|
terminated.
|
||||||
|
|
||||||
Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
||||||
to make sure that the nature of the code that is executed on the BSP and the
|
to make sure that the nature of the code that is executed on the BSP and the
|
||||||
dispatched APs is well controlled. The MP Services Ppi does not guarantee
|
dispatched APs is well controlled. The MP Services Ppi does not guarantee
|
||||||
that the Procedure function is MP-safe. Hence, the tasks that can be run in
|
that the Procedure function is MP-safe. Hence, the tasks that can be run in
|
||||||
parallel are limited to certain independent tasks and well-controlled exclusive
|
parallel are limited to certain independent tasks and well-controlled exclusive
|
||||||
code. PEI services and Ppis may not be called by APs unless otherwise
|
code. PEI services and Ppis may not be called by APs unless otherwise
|
||||||
specified.
|
specified.
|
||||||
|
|
||||||
In blocking execution mode, BSP waits until all APs finish or
|
In blocking execution mode, BSP waits until all APs finish or
|
||||||
TimeoutInMicroSeconds expires.
|
TimeoutInMicroSeconds expires.
|
||||||
|
|
||||||
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
published by the PEI Foundation.
|
published by the PEI Foundation.
|
||||||
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
||||||
@param[in] Procedure A pointer to the function to be run on enabled APs of
|
@param[in] Procedure A pointer to the function to be run on enabled APs of
|
||||||
the system.
|
the system.
|
||||||
@param[in] SingleThread If TRUE, then all the enabled APs execute the function
|
@param[in] SingleThread If TRUE, then all the enabled APs execute the function
|
||||||
specified by Procedure one by one, in ascending order
|
specified by Procedure one by one, in ascending order
|
||||||
of processor handle number. If FALSE, then all the
|
of processor handle number. If FALSE, then all the
|
||||||
enabled APs execute the function specified by Procedure
|
enabled APs execute the function specified by Procedure
|
||||||
simultaneously.
|
simultaneously.
|
||||||
@param[in] TimeoutInMicroSeconds
|
@param[in] TimeoutInMicroSeconds
|
||||||
Indicates the time limit in microseconds for APs to
|
Indicates the time limit in microseconds for APs to
|
||||||
return from Procedure, for blocking mode only. Zero
|
return from Procedure, for blocking mode only. Zero
|
||||||
means infinity. If the timeout expires before all APs
|
means infinity. If the timeout expires before all APs
|
||||||
return from Procedure, then Procedure on the failed APs
|
return from Procedure, then Procedure on the failed APs
|
||||||
is terminated. All enabled APs are available for next
|
is terminated. All enabled APs are available for next
|
||||||
function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
||||||
or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
|
or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
|
||||||
timeout expires in blocking mode, BSP returns
|
timeout expires in blocking mode, BSP returns
|
||||||
EFI_TIMEOUT.
|
EFI_TIMEOUT.
|
||||||
@param[in] ProcedureArgument The parameter passed into Procedure for all APs.
|
@param[in] ProcedureArgument The parameter passed into Procedure for all APs.
|
||||||
|
|
||||||
@retval EFI_SUCCESS In blocking mode, all APs have finished before the
|
@retval EFI_SUCCESS In blocking mode, all APs have finished before the
|
||||||
timeout expired.
|
timeout expired.
|
||||||
@retval EFI_DEVICE_ERROR Caller processor is AP.
|
@retval EFI_DEVICE_ERROR Caller processor is AP.
|
||||||
@retval EFI_NOT_STARTED No enabled APs exist in the system.
|
@retval EFI_NOT_STARTED No enabled APs exist in the system.
|
||||||
@retval EFI_NOT_READY Any enabled APs are busy.
|
@retval EFI_NOT_READY Any enabled APs are busy.
|
||||||
@retval EFI_TIMEOUT In blocking mode, the timeout expired before all
|
@retval EFI_TIMEOUT In blocking mode, the timeout expired before all
|
||||||
enabled APs have finished.
|
enabled APs have finished.
|
||||||
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PeiStartupAllAPs (
|
PeiStartupAllAPs (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_MP_SERVICES_PPI *This,
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
IN EFI_AP_PROCEDURE Procedure,
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
IN BOOLEAN SingleThread,
|
IN BOOLEAN SingleThread,
|
||||||
IN UINTN TimeoutInMicroSeconds,
|
IN UINTN TimeoutInMicroSeconds,
|
||||||
IN VOID *ProcedureArgument OPTIONAL
|
IN VOID *ProcedureArgument OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This service lets the caller get one enabled AP to execute a caller-provided
|
This service lets the caller get one enabled AP to execute a caller-provided
|
||||||
function. The caller can request the BSP to wait for the completion
|
function. The caller can request the BSP to wait for the completion
|
||||||
of the AP. This service may only be called from the BSP.
|
of the AP. This service may only be called from the BSP.
|
||||||
|
|
||||||
This function is used to dispatch one enabled AP to the function specified by
|
This function is used to dispatch one enabled AP to the function specified by
|
||||||
Procedure passing in the argument specified by ProcedureArgument.
|
Procedure passing in the argument specified by ProcedureArgument.
|
||||||
The execution is in blocking mode. The BSP waits until the AP finishes or
|
The execution is in blocking mode. The BSP waits until the AP finishes or
|
||||||
TimeoutInMicroSecondss expires.
|
TimeoutInMicroSecondss expires.
|
||||||
|
|
||||||
If the timeout specified by TimeoutInMicroseconds expires before the AP returns
|
If the timeout specified by TimeoutInMicroseconds expires before the AP returns
|
||||||
from Procedure, then execution of Procedure by the AP is terminated. The AP is
|
from Procedure, then execution of Procedure by the AP is terminated. The AP is
|
||||||
available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
|
available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
|
||||||
EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
|
EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
|
||||||
|
|
||||||
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
published by the PEI Foundation.
|
published by the PEI Foundation.
|
||||||
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
||||||
@param[in] Procedure A pointer to the function to be run on enabled APs of
|
@param[in] Procedure A pointer to the function to be run on enabled APs of
|
||||||
the system.
|
the system.
|
||||||
@param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
@param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
||||||
total number of logical processors minus 1. The total
|
total number of logical processors minus 1. The total
|
||||||
number of logical processors can be retrieved by
|
number of logical processors can be retrieved by
|
||||||
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
||||||
@param[in] TimeoutInMicroseconds
|
@param[in] TimeoutInMicroseconds
|
||||||
Indicates the time limit in microseconds for APs to
|
Indicates the time limit in microseconds for APs to
|
||||||
return from Procedure, for blocking mode only. Zero
|
return from Procedure, for blocking mode only. Zero
|
||||||
means infinity. If the timeout expires before all APs
|
means infinity. If the timeout expires before all APs
|
||||||
return from Procedure, then Procedure on the failed APs
|
return from Procedure, then Procedure on the failed APs
|
||||||
is terminated. All enabled APs are available for next
|
is terminated. All enabled APs are available for next
|
||||||
function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
|
||||||
or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
|
or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
|
||||||
timeout expires in blocking mode, BSP returns
|
timeout expires in blocking mode, BSP returns
|
||||||
EFI_TIMEOUT.
|
EFI_TIMEOUT.
|
||||||
@param[in] ProcedureArgument The parameter passed into Procedure for all APs.
|
@param[in] ProcedureArgument The parameter passed into Procedure for all APs.
|
||||||
|
|
||||||
@retval EFI_SUCCESS In blocking mode, specified AP finished before the
|
@retval EFI_SUCCESS In blocking mode, specified AP finished before the
|
||||||
timeout expires.
|
timeout expires.
|
||||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
@retval EFI_TIMEOUT In blocking mode, the timeout expired before the
|
@retval EFI_TIMEOUT In blocking mode, the timeout expired before the
|
||||||
specified AP has finished.
|
specified AP has finished.
|
||||||
@retval EFI_NOT_FOUND The processor with the handle specified by
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
ProcessorNumber does not exist.
|
ProcessorNumber does not exist.
|
||||||
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
|
||||||
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PeiStartupThisAP (
|
PeiStartupThisAP (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_MP_SERVICES_PPI *This,
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
IN EFI_AP_PROCEDURE Procedure,
|
IN EFI_AP_PROCEDURE Procedure,
|
||||||
IN UINTN ProcessorNumber,
|
IN UINTN ProcessorNumber,
|
||||||
IN UINTN TimeoutInMicroseconds,
|
IN UINTN TimeoutInMicroseconds,
|
||||||
IN VOID *ProcedureArgument OPTIONAL
|
IN VOID *ProcedureArgument OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This service switches the requested AP to be the BSP from that point onward.
|
This service switches the requested AP to be the BSP from that point onward.
|
||||||
This service changes the BSP for all purposes. This call can only be performed
|
This service changes the BSP for all purposes. This call can only be performed
|
||||||
by the current BSP.
|
by the current BSP.
|
||||||
|
|
||||||
This service switches the requested AP to be the BSP from that point onward.
|
This service switches the requested AP to be the BSP from that point onward.
|
||||||
This service changes the BSP for all purposes. The new BSP can take over the
|
This service changes the BSP for all purposes. The new BSP can take over the
|
||||||
execution of the old BSP and continue seamlessly from where the old one left
|
execution of the old BSP and continue seamlessly from where the old one left
|
||||||
off.
|
off.
|
||||||
|
|
||||||
If the BSP cannot be switched prior to the return from this service, then
|
If the BSP cannot be switched prior to the return from this service, then
|
||||||
EFI_UNSUPPORTED must be returned.
|
EFI_UNSUPPORTED must be returned.
|
||||||
|
|
||||||
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
published by the PEI Foundation.
|
published by the PEI Foundation.
|
||||||
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
||||||
@param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
@param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
||||||
total number of logical processors minus 1. The total
|
total number of logical processors minus 1. The total
|
||||||
number of logical processors can be retrieved by
|
number of logical processors can be retrieved by
|
||||||
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
||||||
@param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled
|
@param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled
|
||||||
AP. Otherwise, it will be disabled.
|
AP. Otherwise, it will be disabled.
|
||||||
|
|
||||||
@retval EFI_SUCCESS BSP successfully switched.
|
@retval EFI_SUCCESS BSP successfully switched.
|
||||||
@retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this
|
@retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this
|
||||||
service returning.
|
service returning.
|
||||||
@retval EFI_UNSUPPORTED Switching the BSP is not supported.
|
@retval EFI_UNSUPPORTED Switching the BSP is not supported.
|
||||||
@retval EFI_SUCCESS The calling processor is an AP.
|
@retval EFI_SUCCESS The calling processor is an AP.
|
||||||
@retval EFI_NOT_FOUND The processor with the handle specified by
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
ProcessorNumber does not exist.
|
ProcessorNumber does not exist.
|
||||||
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
|
||||||
AP.
|
AP.
|
||||||
@retval EFI_NOT_READY The specified AP is busy.
|
@retval EFI_NOT_READY The specified AP is busy.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PeiSwitchBSP (
|
PeiSwitchBSP (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_MP_SERVICES_PPI *This,
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
IN UINTN ProcessorNumber,
|
IN UINTN ProcessorNumber,
|
||||||
IN BOOLEAN EnableOldBSP
|
IN BOOLEAN EnableOldBSP
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This service lets the caller enable or disable an AP from this point onward.
|
This service lets the caller enable or disable an AP from this point onward.
|
||||||
This service may only be called from the BSP.
|
This service may only be called from the BSP.
|
||||||
|
|
||||||
This service allows the caller enable or disable an AP from this point onward.
|
This service allows the caller enable or disable an AP from this point onward.
|
||||||
The caller can optionally specify the health status of the AP by Health. If
|
The caller can optionally specify the health status of the AP by Health. If
|
||||||
an AP is being disabled, then the state of the disabled AP is implementation
|
an AP is being disabled, then the state of the disabled AP is implementation
|
||||||
dependent. If an AP is enabled, then the implementation must guarantee that a
|
dependent. If an AP is enabled, then the implementation must guarantee that a
|
||||||
complete initialization sequence is performed on the AP, so the AP is in a state
|
complete initialization sequence is performed on the AP, so the AP is in a state
|
||||||
that is compatible with an MP operating system.
|
that is compatible with an MP operating system.
|
||||||
|
|
||||||
If the enable or disable AP operation cannot be completed prior to the return
|
If the enable or disable AP operation cannot be completed prior to the return
|
||||||
from this service, then EFI_UNSUPPORTED must be returned.
|
from this service, then EFI_UNSUPPORTED must be returned.
|
||||||
|
|
||||||
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
published by the PEI Foundation.
|
published by the PEI Foundation.
|
||||||
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
||||||
@param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
@param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
||||||
total number of logical processors minus 1. The total
|
total number of logical processors minus 1. The total
|
||||||
number of logical processors can be retrieved by
|
number of logical processors can be retrieved by
|
||||||
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
||||||
@param[in] EnableAP Specifies the new state for the processor for enabled,
|
@param[in] EnableAP Specifies the new state for the processor for enabled,
|
||||||
FALSE for disabled.
|
FALSE for disabled.
|
||||||
@param[in] HealthFlag If not NULL, a pointer to a value that specifies the
|
@param[in] HealthFlag If not NULL, a pointer to a value that specifies the
|
||||||
new health status of the AP. This flag corresponds to
|
new health status of the AP. This flag corresponds to
|
||||||
StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo().
|
StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo().
|
||||||
Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other
|
Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other
|
||||||
bits are ignored. If it is NULL, this parameter is
|
bits are ignored. If it is NULL, this parameter is
|
||||||
ignored.
|
ignored.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
|
@retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
|
||||||
@retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior
|
@retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior
|
||||||
to this service returning.
|
to this service returning.
|
||||||
@retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
|
@retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
|
||||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
@retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
|
@retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
|
||||||
does not exist.
|
does not exist.
|
||||||
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
|
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PeiEnableDisableAP (
|
PeiEnableDisableAP (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_MP_SERVICES_PPI *This,
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
IN UINTN ProcessorNumber,
|
IN UINTN ProcessorNumber,
|
||||||
IN BOOLEAN EnableAP,
|
IN BOOLEAN EnableAP,
|
||||||
IN UINT32 *HealthFlag OPTIONAL
|
IN UINT32 *HealthFlag OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This return the handle number for the calling processor. This service may be
|
This return the handle number for the calling processor. This service may be
|
||||||
called from the BSP and APs.
|
called from the BSP and APs.
|
||||||
|
|
||||||
This service returns the processor handle number for the calling processor.
|
This service returns the processor handle number for the calling processor.
|
||||||
The returned value is in the range from 0 to the total number of logical
|
The returned value is in the range from 0 to the total number of logical
|
||||||
processors minus 1. The total number of logical processors can be retrieved
|
processors minus 1. The total number of logical processors can be retrieved
|
||||||
with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be
|
with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be
|
||||||
called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
|
called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
|
||||||
is returned. Otherwise, the current processors handle number is returned in
|
is returned. Otherwise, the current processors handle number is returned in
|
||||||
ProcessorNumber, and EFI_SUCCESS is returned.
|
ProcessorNumber, and EFI_SUCCESS is returned.
|
||||||
|
|
||||||
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
published by the PEI Foundation.
|
published by the PEI Foundation.
|
||||||
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
@param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
|
||||||
@param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
@param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the
|
||||||
total number of logical processors minus 1. The total
|
total number of logical processors minus 1. The total
|
||||||
number of logical processors can be retrieved by
|
number of logical processors can be retrieved by
|
||||||
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
|
||||||
|
|
||||||
@retval EFI_SUCCESS The current processor handle number was returned in
|
@retval EFI_SUCCESS The current processor handle number was returned in
|
||||||
ProcessorNumber.
|
ProcessorNumber.
|
||||||
@retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
|
@retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PeiWhoAmI (
|
PeiWhoAmI (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
IN EFI_PEI_MP_SERVICES_PPI *This,
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
OUT UINTN *ProcessorNumber
|
OUT UINTN *ProcessorNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,45 +1,45 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
;------------------------------------------------------------------------------ ;
|
||||||
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
; This program and the accompanying materials
|
; This program and the accompanying materials
|
||||||
; are licensed and made available under the terms and conditions of the BSD License
|
; 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
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
; http://opensource.org/licenses/bsd-license.php.
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
;
|
;
|
||||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
;
|
;
|
||||||
; Module Name:
|
; Module Name:
|
||||||
;
|
;
|
||||||
; MpEqu.inc
|
; MpEqu.inc
|
||||||
;
|
;
|
||||||
; Abstract:
|
; Abstract:
|
||||||
;
|
;
|
||||||
; This is the equates file for Multiple Processor support
|
; This is the equates file for Multiple Processor support
|
||||||
;
|
;
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
PROTECT_MODE_CS equ 10h
|
PROTECT_MODE_CS equ 10h
|
||||||
PROTECT_MODE_DS equ 18h
|
PROTECT_MODE_DS equ 18h
|
||||||
LONG_MODE_CS equ 38h
|
LONG_MODE_CS equ 38h
|
||||||
LONG_MODE_DS equ 30h
|
LONG_MODE_DS equ 30h
|
||||||
|
|
||||||
VacantFlag equ 00h
|
VacantFlag equ 00h
|
||||||
NotVacantFlag equ 0ffh
|
NotVacantFlag equ 0ffh
|
||||||
|
|
||||||
CPU_SWITCH_STATE_IDLE equ 0
|
CPU_SWITCH_STATE_IDLE equ 0
|
||||||
CPU_SWITCH_STATE_STORED equ 1
|
CPU_SWITCH_STATE_STORED equ 1
|
||||||
CPU_SWITCH_STATE_LOADED equ 2
|
CPU_SWITCH_STATE_LOADED equ 2
|
||||||
|
|
||||||
LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
|
LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
|
||||||
StackStartAddressLocation equ LockLocation + 08h
|
StackStartAddressLocation equ LockLocation + 08h
|
||||||
StackSizeLocation equ LockLocation + 10h
|
StackSizeLocation equ LockLocation + 10h
|
||||||
ApProcedureLocation equ LockLocation + 18h
|
ApProcedureLocation equ LockLocation + 18h
|
||||||
GdtrLocation equ LockLocation + 20h
|
GdtrLocation equ LockLocation + 20h
|
||||||
IdtrLocation equ LockLocation + 2Ah
|
IdtrLocation equ LockLocation + 2Ah
|
||||||
BufferStartLocation equ LockLocation + 34h
|
BufferStartLocation equ LockLocation + 34h
|
||||||
PmodeOffsetLocation equ LockLocation + 3Ch
|
PmodeOffsetLocation equ LockLocation + 3Ch
|
||||||
NumApsExecutingLoction equ LockLocation + 44h
|
NumApsExecutingLoction equ LockLocation + 44h
|
||||||
LmodeOffsetLocation equ LockLocation + 4Ch
|
LmodeOffsetLocation equ LockLocation + 4Ch
|
||||||
Cr3Location equ LockLocation + 54h
|
Cr3Location equ LockLocation + 54h
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
@ -1,334 +1,334 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
;------------------------------------------------------------------------------ ;
|
||||||
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
; This program and the accompanying materials
|
; This program and the accompanying materials
|
||||||
; are licensed and made available under the terms and conditions of the BSD License
|
; 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
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
; http://opensource.org/licenses/bsd-license.php.
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
;
|
;
|
||||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
;
|
;
|
||||||
; Module Name:
|
; Module Name:
|
||||||
;
|
;
|
||||||
; MpFuncs32.asm
|
; MpFuncs32.asm
|
||||||
;
|
;
|
||||||
; Abstract:
|
; Abstract:
|
||||||
;
|
;
|
||||||
; This is the assembly code for MP support
|
; This is the assembly code for MP support
|
||||||
;
|
;
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
include MpEqu.inc
|
include MpEqu.inc
|
||||||
extern InitializeFloatingPointUnits:PROC
|
extern InitializeFloatingPointUnits:PROC
|
||||||
|
|
||||||
.code
|
.code
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
||||||
;procedure serializes all the AP processors through an Init sequence. It must be
|
;procedure serializes all the AP processors through an Init sequence. It must be
|
||||||
;noted that APs arrive here very raw...ie: real mode, no stack.
|
;noted that APs arrive here very raw...ie: real mode, no stack.
|
||||||
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
||||||
;IS IN MACHINE CODE.
|
;IS IN MACHINE CODE.
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
RendezvousFunnelProc PROC PUBLIC
|
RendezvousFunnelProc PROC PUBLIC
|
||||||
RendezvousFunnelProcStart::
|
RendezvousFunnelProcStart::
|
||||||
; At this point CS = 0x(vv00) and ip= 0x0.
|
; At this point CS = 0x(vv00) and ip= 0x0.
|
||||||
; Save BIST information to ebp firstly
|
; Save BIST information to ebp firstly
|
||||||
db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
|
db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
|
||||||
|
|
||||||
db 8ch,0c8h ; mov ax,cs
|
db 8ch,0c8h ; mov ax,cs
|
||||||
db 8eh,0d8h ; mov ds,ax
|
db 8eh,0d8h ; mov ds,ax
|
||||||
db 8eh,0c0h ; mov es,ax
|
db 8eh,0c0h ; mov es,ax
|
||||||
db 8eh,0d0h ; mov ss,ax
|
db 8eh,0d0h ; mov ss,ax
|
||||||
db 33h,0c0h ; xor ax,ax
|
db 33h,0c0h ; xor ax,ax
|
||||||
db 8eh,0e0h ; mov fs,ax
|
db 8eh,0e0h ; mov fs,ax
|
||||||
db 8eh,0e8h ; mov gs,ax
|
db 8eh,0e8h ; mov gs,ax
|
||||||
|
|
||||||
db 0BEh ; opcode of mov si, mem16
|
db 0BEh ; opcode of mov si, mem16
|
||||||
dw BufferStartLocation ; mov si, BufferStartLocation
|
dw BufferStartLocation ; mov si, BufferStartLocation
|
||||||
db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
|
db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
|
||||||
|
|
||||||
db 0BFh ; opcode of mov di, mem16
|
db 0BFh ; opcode of mov di, mem16
|
||||||
dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
|
dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
|
||||||
db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
|
db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
|
||||||
db 8Bh, 0F8h ; mov di, ax
|
db 8Bh, 0F8h ; mov di, ax
|
||||||
db 83h, 0EFh,06h ; sub di, 06h
|
db 83h, 0EFh,06h ; sub di, 06h
|
||||||
db 66h, 03h, 0C3h ; add eax, ebx
|
db 66h, 03h, 0C3h ; add eax, ebx
|
||||||
db 66h, 89h, 05h ; mov dword ptr [di],eax
|
db 66h, 89h, 05h ; mov dword ptr [di],eax
|
||||||
|
|
||||||
db 0BFh ; opcode of mov di, mem16
|
db 0BFh ; opcode of mov di, mem16
|
||||||
dw LmodeOffsetLocation ; mov di, LmodeOffsetLocation
|
dw LmodeOffsetLocation ; mov di, LmodeOffsetLocation
|
||||||
db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
|
db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
|
||||||
db 8Bh, 0F8h ; mov di, ax
|
db 8Bh, 0F8h ; mov di, ax
|
||||||
db 83h, 0EFh,06h ; sub di, 06h
|
db 83h, 0EFh,06h ; sub di, 06h
|
||||||
db 66h, 03h, 0C3h ; add eax, ebx
|
db 66h, 03h, 0C3h ; add eax, ebx
|
||||||
db 66h, 89h, 05h ; mov dword ptr [di],eax
|
db 66h, 89h, 05h ; mov dword ptr [di],eax
|
||||||
|
|
||||||
db 0BEh
|
db 0BEh
|
||||||
dw Cr3Location ; mov si, Cr3Location
|
dw Cr3Location ; mov si, Cr3Location
|
||||||
db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
|
db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
|
||||||
|
|
||||||
db 0BEh ; opcode of mov si, mem16
|
db 0BEh ; opcode of mov si, mem16
|
||||||
dw GdtrLocation ; mov si, GdtrLocation
|
dw GdtrLocation ; mov si, GdtrLocation
|
||||||
db 66h ; db 66h
|
db 66h ; db 66h
|
||||||
db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
|
db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
|
||||||
|
|
||||||
db 0BEh
|
db 0BEh
|
||||||
dw IdtrLocation ; mov si, IdtrLocation
|
dw IdtrLocation ; mov si, IdtrLocation
|
||||||
db 66h ; db 66h
|
db 66h ; db 66h
|
||||||
db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
|
db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
|
||||||
|
|
||||||
db 33h, 0C0h ; xor ax, ax
|
db 33h, 0C0h ; xor ax, ax
|
||||||
db 8Eh, 0D8h ; mov ds, ax
|
db 8Eh, 0D8h ; mov ds, ax
|
||||||
|
|
||||||
db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
|
db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
|
||||||
db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
|
db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
|
||||||
db 0Fh, 22h, 0C0h ; mov cr0, eax
|
db 0Fh, 22h, 0C0h ; mov cr0, eax
|
||||||
|
|
||||||
db 66h, 67h, 0EAh ; far jump
|
db 66h, 67h, 0EAh ; far jump
|
||||||
dd 0h ; 32-bit offset
|
dd 0h ; 32-bit offset
|
||||||
dw PROTECT_MODE_CS ; 16-bit selector
|
dw PROTECT_MODE_CS ; 16-bit selector
|
||||||
|
|
||||||
Flat32Start:: ; protected mode entry point
|
Flat32Start:: ; protected mode entry point
|
||||||
mov ax, PROTECT_MODE_DS
|
mov ax, PROTECT_MODE_DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
db 0Fh, 20h, 0E0h ; mov eax, cr4
|
db 0Fh, 20h, 0E0h ; mov eax, cr4
|
||||||
db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
|
db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
|
||||||
db 0Fh, 22h, 0E0h ; mov cr4, eax
|
db 0Fh, 22h, 0E0h ; mov cr4, eax
|
||||||
|
|
||||||
db 0Fh, 22h, 0D9h ; mov cr3, ecx
|
db 0Fh, 22h, 0D9h ; mov cr3, ecx
|
||||||
|
|
||||||
db 0B9h
|
db 0B9h
|
||||||
dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
|
dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
|
||||||
db 0Fh, 32h ; rdmsr ; Read EFER.
|
db 0Fh, 32h ; rdmsr ; Read EFER.
|
||||||
db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.
|
db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.
|
||||||
db 0Fh, 30h ; wrmsr ; Write EFER.
|
db 0Fh, 30h ; wrmsr ; Write EFER.
|
||||||
|
|
||||||
db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
|
db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
|
||||||
db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.
|
db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.
|
||||||
db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
|
db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
|
||||||
|
|
||||||
LONG_JUMP:
|
LONG_JUMP:
|
||||||
db 67h, 0EAh ; far jump
|
db 67h, 0EAh ; far jump
|
||||||
dd 0h ; 32-bit offset
|
dd 0h ; 32-bit offset
|
||||||
dw LONG_MODE_CS ; 16-bit selector
|
dw LONG_MODE_CS ; 16-bit selector
|
||||||
|
|
||||||
LongModeStart::
|
LongModeStart::
|
||||||
mov ax, LONG_MODE_DS
|
mov ax, LONG_MODE_DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov esi, ebx
|
mov esi, ebx
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
mov rax, NotVacantFlag
|
mov rax, NotVacantFlag
|
||||||
|
|
||||||
TestLock:
|
TestLock:
|
||||||
xchg qword ptr [edi], rax
|
xchg qword ptr [edi], rax
|
||||||
cmp rax, NotVacantFlag
|
cmp rax, NotVacantFlag
|
||||||
jz TestLock
|
jz TestLock
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, NumApsExecutingLoction
|
add edi, NumApsExecutingLoction
|
||||||
inc dword ptr [edi]
|
inc dword ptr [edi]
|
||||||
mov ebx, dword ptr [edi]
|
mov ebx, dword ptr [edi]
|
||||||
|
|
||||||
ProgramStack:
|
ProgramStack:
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSizeLocation
|
add edi, StackSizeLocation
|
||||||
mov rax, qword ptr [edi]
|
mov rax, qword ptr [edi]
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStartAddressLocation
|
add edi, StackStartAddressLocation
|
||||||
add rax, qword ptr [edi]
|
add rax, qword ptr [edi]
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
mov qword ptr [edi], rax
|
mov qword ptr [edi], rax
|
||||||
|
|
||||||
Releaselock:
|
Releaselock:
|
||||||
mov rax, VacantFlag
|
mov rax, VacantFlag
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
xchg qword ptr [edi], rax
|
xchg qword ptr [edi], rax
|
||||||
|
|
||||||
CProcedureInvoke:
|
CProcedureInvoke:
|
||||||
push rbp ; push BIST data
|
push rbp ; push BIST data
|
||||||
xor rbp, rbp ; clear ebp for call stack trace
|
xor rbp, rbp ; clear ebp for call stack trace
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
mov rax, InitializeFloatingPointUnits
|
mov rax, InitializeFloatingPointUnits
|
||||||
sub rsp, 20h
|
sub rsp, 20h
|
||||||
call rax ; Call assembly function to initialize FPU per UEFI spec
|
call rax ; Call assembly function to initialize FPU per UEFI spec
|
||||||
add rsp, 20h
|
add rsp, 20h
|
||||||
|
|
||||||
mov edx, ebx ; edx is NumApsExecuting
|
mov edx, ebx ; edx is NumApsExecuting
|
||||||
mov ecx, esi
|
mov ecx, esi
|
||||||
add ecx, LockLocation ; rcx is address of exchange info data buffer
|
add ecx, LockLocation ; rcx is address of exchange info data buffer
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, ApProcedureLocation
|
add edi, ApProcedureLocation
|
||||||
mov rax, qword ptr [edi]
|
mov rax, qword ptr [edi]
|
||||||
|
|
||||||
sub rsp, 20h
|
sub rsp, 20h
|
||||||
call rax ; invoke C function
|
call rax ; invoke C function
|
||||||
add rsp, 20h
|
add rsp, 20h
|
||||||
jmp $
|
jmp $
|
||||||
|
|
||||||
RendezvousFunnelProc ENDP
|
RendezvousFunnelProc ENDP
|
||||||
RendezvousFunnelProcEnd::
|
RendezvousFunnelProcEnd::
|
||||||
|
|
||||||
AsmCliHltLoop PROC
|
AsmCliHltLoop PROC
|
||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
jmp $-2
|
jmp $-2
|
||||||
AsmCliHltLoop ENDP
|
AsmCliHltLoop ENDP
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
; AsmGetAddressMap (&AddressMap);
|
; AsmGetAddressMap (&AddressMap);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
AsmGetAddressMap PROC
|
AsmGetAddressMap PROC
|
||||||
mov rax, offset RendezvousFunnelProcStart
|
mov rax, offset RendezvousFunnelProcStart
|
||||||
mov qword ptr [rcx], rax
|
mov qword ptr [rcx], rax
|
||||||
mov qword ptr [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
|
mov qword ptr [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
|
||||||
mov qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
|
mov qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
|
||||||
mov qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
mov qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
||||||
ret
|
ret
|
||||||
AsmGetAddressMap ENDP
|
AsmGetAddressMap ENDP
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
||||||
;about to become an AP. It switches it'stack with the current AP.
|
;about to become an AP. It switches it'stack with the current AP.
|
||||||
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
AsmExchangeRole PROC
|
AsmExchangeRole PROC
|
||||||
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
||||||
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
||||||
|
|
||||||
push rax
|
push rax
|
||||||
push rbx
|
push rbx
|
||||||
push rcx
|
push rcx
|
||||||
push rdx
|
push rdx
|
||||||
push rsi
|
push rsi
|
||||||
push rdi
|
push rdi
|
||||||
push rbp
|
push rbp
|
||||||
push r8
|
push r8
|
||||||
push r9
|
push r9
|
||||||
push r10
|
push r10
|
||||||
push r11
|
push r11
|
||||||
push r12
|
push r12
|
||||||
push r13
|
push r13
|
||||||
push r14
|
push r14
|
||||||
push r15
|
push r15
|
||||||
|
|
||||||
mov rax, cr0
|
mov rax, cr0
|
||||||
push rax
|
push rax
|
||||||
|
|
||||||
mov rax, cr4
|
mov rax, cr4
|
||||||
push rax
|
push rax
|
||||||
|
|
||||||
; rsi contains MyInfo pointer
|
; rsi contains MyInfo pointer
|
||||||
mov rsi, rcx
|
mov rsi, rcx
|
||||||
|
|
||||||
; rdi contains OthersInfo pointer
|
; rdi contains OthersInfo pointer
|
||||||
mov rdi, rdx
|
mov rdi, rdx
|
||||||
|
|
||||||
;Store EFLAGS, GDTR and IDTR regiter to stack
|
;Store EFLAGS, GDTR and IDTR regiter to stack
|
||||||
pushfq
|
pushfq
|
||||||
sgdt fword ptr [rsi + 16]
|
sgdt fword ptr [rsi + 16]
|
||||||
sidt fword ptr [rsi + 26]
|
sidt fword ptr [rsi + 26]
|
||||||
|
|
||||||
; Store the its StackPointer
|
; Store the its StackPointer
|
||||||
mov qword ptr [rsi + 8], rsp
|
mov qword ptr [rsi + 8], rsp
|
||||||
|
|
||||||
; update its switch state to STORED
|
; update its switch state to STORED
|
||||||
mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
|
mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
|
||||||
|
|
||||||
WaitForOtherStored:
|
WaitForOtherStored:
|
||||||
; wait until the other CPU finish storing its state
|
; wait until the other CPU finish storing its state
|
||||||
cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
|
cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
|
||||||
jz OtherStored
|
jz OtherStored
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherStored
|
jmp WaitForOtherStored
|
||||||
|
|
||||||
OtherStored:
|
OtherStored:
|
||||||
; Since another CPU already stored its state, load them
|
; Since another CPU already stored its state, load them
|
||||||
; load GDTR value
|
; load GDTR value
|
||||||
lgdt fword ptr [rdi + 16]
|
lgdt fword ptr [rdi + 16]
|
||||||
|
|
||||||
; load IDTR value
|
; load IDTR value
|
||||||
lidt fword ptr [rdi + 26]
|
lidt fword ptr [rdi + 26]
|
||||||
|
|
||||||
; load its future StackPointer
|
; load its future StackPointer
|
||||||
mov rsp, qword ptr [rdi + 8]
|
mov rsp, qword ptr [rdi + 8]
|
||||||
|
|
||||||
; update the other CPU's switch state to LOADED
|
; update the other CPU's switch state to LOADED
|
||||||
mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
|
mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
|
||||||
|
|
||||||
WaitForOtherLoaded:
|
WaitForOtherLoaded:
|
||||||
; wait until the other CPU finish loading new state,
|
; wait until the other CPU finish loading new state,
|
||||||
; otherwise the data in stack may corrupt
|
; otherwise the data in stack may corrupt
|
||||||
cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED
|
cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED
|
||||||
jz OtherLoaded
|
jz OtherLoaded
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherLoaded
|
jmp WaitForOtherLoaded
|
||||||
|
|
||||||
OtherLoaded:
|
OtherLoaded:
|
||||||
; since the other CPU already get the data it want, leave this procedure
|
; since the other CPU already get the data it want, leave this procedure
|
||||||
popfq
|
popfq
|
||||||
|
|
||||||
pop rax
|
pop rax
|
||||||
mov cr4, rax
|
mov cr4, rax
|
||||||
|
|
||||||
pop rax
|
pop rax
|
||||||
mov cr0, rax
|
mov cr0, rax
|
||||||
|
|
||||||
pop r15
|
pop r15
|
||||||
pop r14
|
pop r14
|
||||||
pop r13
|
pop r13
|
||||||
pop r12
|
pop r12
|
||||||
pop r11
|
pop r11
|
||||||
pop r10
|
pop r10
|
||||||
pop r9
|
pop r9
|
||||||
pop r8
|
pop r8
|
||||||
pop rbp
|
pop rbp
|
||||||
pop rdi
|
pop rdi
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rdx
|
pop rdx
|
||||||
pop rcx
|
pop rcx
|
||||||
pop rbx
|
pop rbx
|
||||||
pop rax
|
pop rax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
AsmExchangeRole ENDP
|
AsmExchangeRole ENDP
|
||||||
|
|
||||||
AsmInitializeGdt PROC
|
AsmInitializeGdt PROC
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
lgdt fword PTR [rcx] ; update the GDTR
|
lgdt fword PTR [rcx] ; update the GDTR
|
||||||
|
|
||||||
sub rsp, 0x10
|
sub rsp, 0x10
|
||||||
lea rax, SetCodeSelectorFarJump
|
lea rax, SetCodeSelectorFarJump
|
||||||
mov [rsp], rax
|
mov [rsp], rax
|
||||||
mov rdx, LONG_MODE_CS
|
mov rdx, LONG_MODE_CS
|
||||||
mov [rsp + 4], dx ; get new CS
|
mov [rsp + 4], dx ; get new CS
|
||||||
jmp fword ptr [rsp]
|
jmp fword ptr [rsp]
|
||||||
SetCodeSelectorFarJump:
|
SetCodeSelectorFarJump:
|
||||||
add rsp, 0x10
|
add rsp, 0x10
|
||||||
|
|
||||||
mov rax, LONG_MODE_DS ; get new DS
|
mov rax, LONG_MODE_DS ; get new DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
pop rbp
|
pop rbp
|
||||||
ret
|
ret
|
||||||
AsmInitializeGdt ENDP
|
AsmInitializeGdt ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -1,327 +1,327 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
;------------------------------------------------------------------------------ ;
|
||||||
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
; This program and the accompanying materials
|
; This program and the accompanying materials
|
||||||
; are licensed and made available under the terms and conditions of the BSD License
|
; 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
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
; http://opensource.org/licenses/bsd-license.php.
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
;
|
;
|
||||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
;
|
;
|
||||||
; Module Name:
|
; Module Name:
|
||||||
;
|
;
|
||||||
; MpFuncs.nasm
|
; MpFuncs.nasm
|
||||||
;
|
;
|
||||||
; Abstract:
|
; Abstract:
|
||||||
;
|
;
|
||||||
; This is the assembly code for MP support
|
; This is the assembly code for MP support
|
||||||
;
|
;
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
%include "MpEqu.inc"
|
%include "MpEqu.inc"
|
||||||
extern ASM_PFX(InitializeFloatingPointUnits)
|
extern ASM_PFX(InitializeFloatingPointUnits)
|
||||||
|
|
||||||
DEFAULT REL
|
DEFAULT REL
|
||||||
|
|
||||||
SECTION .text
|
SECTION .text
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
||||||
;procedure serializes all the AP processors through an Init sequence. It must be
|
;procedure serializes all the AP processors through an Init sequence. It must be
|
||||||
;noted that APs arrive here very raw...ie: real mode, no stack.
|
;noted that APs arrive here very raw...ie: real mode, no stack.
|
||||||
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
||||||
;IS IN MACHINE CODE.
|
;IS IN MACHINE CODE.
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
global ASM_PFX(RendezvousFunnelProc)
|
global ASM_PFX(RendezvousFunnelProc)
|
||||||
ASM_PFX(RendezvousFunnelProc):
|
ASM_PFX(RendezvousFunnelProc):
|
||||||
RendezvousFunnelProcStart:
|
RendezvousFunnelProcStart:
|
||||||
; At this point CS = 0x(vv00) and ip= 0x0.
|
; At this point CS = 0x(vv00) and ip= 0x0.
|
||||||
; Save BIST information to ebp firstly
|
; Save BIST information to ebp firstly
|
||||||
BITS 16
|
BITS 16
|
||||||
|
|
||||||
mov eax, 1234h
|
mov eax, 1234h
|
||||||
mov ebp, eax ; save BIST information
|
mov ebp, eax ; save BIST information
|
||||||
|
|
||||||
mov ax, cs
|
mov ax, cs
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
mov si, BufferStartLocation
|
mov si, BufferStartLocation
|
||||||
mov ebx, [si]
|
mov ebx, [si]
|
||||||
|
|
||||||
mov di, PmodeOffsetLocation
|
mov di, PmodeOffsetLocation
|
||||||
mov eax, [di]
|
mov eax, [di]
|
||||||
mov di, ax
|
mov di, ax
|
||||||
sub di, 06h
|
sub di, 06h
|
||||||
add eax, ebx
|
add eax, ebx
|
||||||
mov [di],eax
|
mov [di],eax
|
||||||
|
|
||||||
mov di, LmodeOffsetLocation
|
mov di, LmodeOffsetLocation
|
||||||
mov eax, [di]
|
mov eax, [di]
|
||||||
mov di, ax
|
mov di, ax
|
||||||
sub di, 06h
|
sub di, 06h
|
||||||
add eax, ebx
|
add eax, ebx
|
||||||
mov [di],eax
|
mov [di],eax
|
||||||
|
|
||||||
|
|
||||||
mov si, Cr3Location
|
mov si, Cr3Location
|
||||||
mov ecx,[si] ; ECX is keeping the value of CR3
|
mov ecx,[si] ; ECX is keeping the value of CR3
|
||||||
|
|
||||||
mov si, GdtrLocation
|
mov si, GdtrLocation
|
||||||
o32 lgdt [cs:si]
|
o32 lgdt [cs:si]
|
||||||
|
|
||||||
mov si, IdtrLocation
|
mov si, IdtrLocation
|
||||||
o32 lidt [cs:si]
|
o32 lidt [cs:si]
|
||||||
|
|
||||||
|
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
mov eax, cr0 ;Get control register 0
|
mov eax, cr0 ;Get control register 0
|
||||||
or eax, 000000003h ;Set PE bit (bit #0) & MP
|
or eax, 000000003h ;Set PE bit (bit #0) & MP
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
|
|
||||||
jmp PROTECT_MODE_CS:strict dword 0 ; far jump to protected mode
|
jmp PROTECT_MODE_CS:strict dword 0 ; far jump to protected mode
|
||||||
BITS 32
|
BITS 32
|
||||||
Flat32Start: ; protected mode entry point
|
Flat32Start: ; protected mode entry point
|
||||||
mov ax, PROTECT_MODE_DS
|
mov ax, PROTECT_MODE_DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov eax, cr4
|
mov eax, cr4
|
||||||
bts eax, 5
|
bts eax, 5
|
||||||
mov cr4, eax
|
mov cr4, eax
|
||||||
|
|
||||||
mov cr3, ecx
|
mov cr3, ecx
|
||||||
|
|
||||||
|
|
||||||
mov ecx, 0c0000080h ; EFER MSR number.
|
mov ecx, 0c0000080h ; EFER MSR number.
|
||||||
rdmsr ; Read EFER.
|
rdmsr ; Read EFER.
|
||||||
bts eax, 8 ; Set LME=1.
|
bts eax, 8 ; Set LME=1.
|
||||||
wrmsr ; Write EFER.
|
wrmsr ; Write EFER.
|
||||||
|
|
||||||
mov eax, cr0 ; Read CR0.
|
mov eax, cr0 ; Read CR0.
|
||||||
bts eax, 31 ; Set PG=1.
|
bts eax, 31 ; Set PG=1.
|
||||||
mov cr0, eax ; Write CR0.
|
mov cr0, eax ; Write CR0.
|
||||||
|
|
||||||
jmp LONG_MODE_CS:strict dword 0 ; far jump to long mode
|
jmp LONG_MODE_CS:strict dword 0 ; far jump to long mode
|
||||||
BITS 64
|
BITS 64
|
||||||
LongModeStart:
|
LongModeStart:
|
||||||
mov ax, LONG_MODE_DS
|
mov ax, LONG_MODE_DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov esi, ebx
|
mov esi, ebx
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
mov rax, NotVacantFlag
|
mov rax, NotVacantFlag
|
||||||
|
|
||||||
TestLock:
|
TestLock:
|
||||||
xchg qword [edi], rax
|
xchg qword [edi], rax
|
||||||
cmp rax, NotVacantFlag
|
cmp rax, NotVacantFlag
|
||||||
jz TestLock
|
jz TestLock
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, NumApsExecutingLoction
|
add edi, NumApsExecutingLoction
|
||||||
inc dword [edi]
|
inc dword [edi]
|
||||||
mov ebx, [edi]
|
mov ebx, [edi]
|
||||||
|
|
||||||
ProgramStack:
|
ProgramStack:
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackSizeLocation
|
add edi, StackSizeLocation
|
||||||
mov rax, qword [edi]
|
mov rax, qword [edi]
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, StackStartAddressLocation
|
add edi, StackStartAddressLocation
|
||||||
add rax, qword [edi]
|
add rax, qword [edi]
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
mov qword [edi], rax
|
mov qword [edi], rax
|
||||||
|
|
||||||
Releaselock:
|
Releaselock:
|
||||||
mov rax, VacantFlag
|
mov rax, VacantFlag
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, LockLocation
|
add edi, LockLocation
|
||||||
xchg qword [edi], rax
|
xchg qword [edi], rax
|
||||||
|
|
||||||
CProcedureInvoke:
|
CProcedureInvoke:
|
||||||
push rbp ; push BIST data at top of AP stack
|
push rbp ; push BIST data at top of AP stack
|
||||||
xor rbp, rbp ; clear ebp for call stack trace
|
xor rbp, rbp ; clear ebp for call stack trace
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
mov rax, ASM_PFX(InitializeFloatingPointUnits)
|
mov rax, ASM_PFX(InitializeFloatingPointUnits)
|
||||||
sub rsp, 20h
|
sub rsp, 20h
|
||||||
call rax ; Call assembly function to initialize FPU per UEFI spec
|
call rax ; Call assembly function to initialize FPU per UEFI spec
|
||||||
add rsp, 20h
|
add rsp, 20h
|
||||||
|
|
||||||
mov edx, ebx ; edx is NumApsExecuting
|
mov edx, ebx ; edx is NumApsExecuting
|
||||||
mov ecx, esi
|
mov ecx, esi
|
||||||
add ecx, LockLocation ; rcx is address of exchange info data buffer
|
add ecx, LockLocation ; rcx is address of exchange info data buffer
|
||||||
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
add edi, ApProcedureLocation
|
add edi, ApProcedureLocation
|
||||||
mov rax, qword [edi]
|
mov rax, qword [edi]
|
||||||
|
|
||||||
sub rsp, 20h
|
sub rsp, 20h
|
||||||
call rax ; invoke C function
|
call rax ; invoke C function
|
||||||
add rsp, 20h
|
add rsp, 20h
|
||||||
|
|
||||||
RendezvousFunnelProcEnd:
|
RendezvousFunnelProcEnd:
|
||||||
|
|
||||||
global ASM_PFX(AsmCliHltLoop)
|
global ASM_PFX(AsmCliHltLoop)
|
||||||
ASM_PFX(AsmCliHltLoop):
|
ASM_PFX(AsmCliHltLoop):
|
||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
jmp $-2
|
jmp $-2
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
; AsmGetAddressMap (&AddressMap);
|
; AsmGetAddressMap (&AddressMap);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
global ASM_PFX(AsmGetAddressMap)
|
global ASM_PFX(AsmGetAddressMap)
|
||||||
ASM_PFX(AsmGetAddressMap):
|
ASM_PFX(AsmGetAddressMap):
|
||||||
mov rax, ASM_PFX(RendezvousFunnelProc)
|
mov rax, ASM_PFX(RendezvousFunnelProc)
|
||||||
mov qword [rcx], rax
|
mov qword [rcx], rax
|
||||||
mov qword [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
|
mov qword [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
|
||||||
mov qword [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
|
mov qword [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
|
||||||
mov qword [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
mov qword [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
|
||||||
;about to become an AP. It switches it'stack with the current AP.
|
;about to become an AP. It switches it'stack with the current AP.
|
||||||
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
|
||||||
;-------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------------
|
||||||
global ASM_PFX(AsmExchangeRole)
|
global ASM_PFX(AsmExchangeRole)
|
||||||
ASM_PFX(AsmExchangeRole):
|
ASM_PFX(AsmExchangeRole):
|
||||||
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
; DO NOT call other functions in this function, since 2 CPU may use 1 stack
|
||||||
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
; at the same time. If 1 CPU try to call a function, stack will be corrupted.
|
||||||
|
|
||||||
push rax
|
push rax
|
||||||
push rbx
|
push rbx
|
||||||
push rcx
|
push rcx
|
||||||
push rdx
|
push rdx
|
||||||
push rsi
|
push rsi
|
||||||
push rdi
|
push rdi
|
||||||
push rbp
|
push rbp
|
||||||
push r8
|
push r8
|
||||||
push r9
|
push r9
|
||||||
push r10
|
push r10
|
||||||
push r11
|
push r11
|
||||||
push r12
|
push r12
|
||||||
push r13
|
push r13
|
||||||
push r14
|
push r14
|
||||||
push r15
|
push r15
|
||||||
|
|
||||||
mov rax, cr0
|
mov rax, cr0
|
||||||
push rax
|
push rax
|
||||||
|
|
||||||
mov rax, cr4
|
mov rax, cr4
|
||||||
push rax
|
push rax
|
||||||
|
|
||||||
; rsi contains MyInfo pointer
|
; rsi contains MyInfo pointer
|
||||||
mov rsi, rcx
|
mov rsi, rcx
|
||||||
|
|
||||||
; rdi contains OthersInfo pointer
|
; rdi contains OthersInfo pointer
|
||||||
mov rdi, rdx
|
mov rdi, rdx
|
||||||
|
|
||||||
;Store EFLAGS, GDTR and IDTR regiter to stack
|
;Store EFLAGS, GDTR and IDTR regiter to stack
|
||||||
pushfq
|
pushfq
|
||||||
sgdt [rsi + 16]
|
sgdt [rsi + 16]
|
||||||
sidt [rsi + 26]
|
sidt [rsi + 26]
|
||||||
|
|
||||||
; Store the its StackPointer
|
; Store the its StackPointer
|
||||||
mov [rsi + 8], rsp
|
mov [rsi + 8], rsp
|
||||||
|
|
||||||
; update its switch state to STORED
|
; update its switch state to STORED
|
||||||
mov byte [rsi], CPU_SWITCH_STATE_STORED
|
mov byte [rsi], CPU_SWITCH_STATE_STORED
|
||||||
|
|
||||||
WaitForOtherStored:
|
WaitForOtherStored:
|
||||||
; wait until the other CPU finish storing its state
|
; wait until the other CPU finish storing its state
|
||||||
cmp byte [rdi], CPU_SWITCH_STATE_STORED
|
cmp byte [rdi], CPU_SWITCH_STATE_STORED
|
||||||
jz OtherStored
|
jz OtherStored
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherStored
|
jmp WaitForOtherStored
|
||||||
|
|
||||||
OtherStored:
|
OtherStored:
|
||||||
; Since another CPU already stored its state, load them
|
; Since another CPU already stored its state, load them
|
||||||
; load GDTR value
|
; load GDTR value
|
||||||
lgdt [rdi + 16]
|
lgdt [rdi + 16]
|
||||||
|
|
||||||
; load IDTR value
|
; load IDTR value
|
||||||
lidt [rdi + 26]
|
lidt [rdi + 26]
|
||||||
|
|
||||||
; load its future StackPointer
|
; load its future StackPointer
|
||||||
mov rsp, [rdi + 8]
|
mov rsp, [rdi + 8]
|
||||||
|
|
||||||
; update the other CPU's switch state to LOADED
|
; update the other CPU's switch state to LOADED
|
||||||
mov byte [rdi], CPU_SWITCH_STATE_LOADED
|
mov byte [rdi], CPU_SWITCH_STATE_LOADED
|
||||||
|
|
||||||
WaitForOtherLoaded:
|
WaitForOtherLoaded:
|
||||||
; wait until the other CPU finish loading new state,
|
; wait until the other CPU finish loading new state,
|
||||||
; otherwise the data in stack may corrupt
|
; otherwise the data in stack may corrupt
|
||||||
cmp byte [rsi], CPU_SWITCH_STATE_LOADED
|
cmp byte [rsi], CPU_SWITCH_STATE_LOADED
|
||||||
jz OtherLoaded
|
jz OtherLoaded
|
||||||
pause
|
pause
|
||||||
jmp WaitForOtherLoaded
|
jmp WaitForOtherLoaded
|
||||||
|
|
||||||
OtherLoaded:
|
OtherLoaded:
|
||||||
; since the other CPU already get the data it want, leave this procedure
|
; since the other CPU already get the data it want, leave this procedure
|
||||||
popfq
|
popfq
|
||||||
|
|
||||||
pop rax
|
pop rax
|
||||||
mov cr4, rax
|
mov cr4, rax
|
||||||
|
|
||||||
pop rax
|
pop rax
|
||||||
mov cr0, rax
|
mov cr0, rax
|
||||||
|
|
||||||
pop r15
|
pop r15
|
||||||
pop r14
|
pop r14
|
||||||
pop r13
|
pop r13
|
||||||
pop r12
|
pop r12
|
||||||
pop r11
|
pop r11
|
||||||
pop r10
|
pop r10
|
||||||
pop r9
|
pop r9
|
||||||
pop r8
|
pop r8
|
||||||
pop rbp
|
pop rbp
|
||||||
pop rdi
|
pop rdi
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rdx
|
pop rdx
|
||||||
pop rcx
|
pop rcx
|
||||||
pop rbx
|
pop rbx
|
||||||
pop rax
|
pop rax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
global ASM_PFX(AsmInitializeGdt)
|
global ASM_PFX(AsmInitializeGdt)
|
||||||
ASM_PFX(AsmInitializeGdt):
|
ASM_PFX(AsmInitializeGdt):
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
||||||
lgdt [rcx] ; update the GDTR
|
lgdt [rcx] ; update the GDTR
|
||||||
|
|
||||||
sub rsp, 0x10
|
sub rsp, 0x10
|
||||||
mov rax, ASM_PFX(SetCodeSelectorFarJump)
|
mov rax, ASM_PFX(SetCodeSelectorFarJump)
|
||||||
mov [rsp], rax
|
mov [rsp], rax
|
||||||
mov rdx, LONG_MODE_CS
|
mov rdx, LONG_MODE_CS
|
||||||
mov [rsp + 4], dx ; get new CS
|
mov [rsp + 4], dx ; get new CS
|
||||||
jmp far dword [rsp] ; far jump with new CS
|
jmp far dword [rsp] ; far jump with new CS
|
||||||
ASM_PFX(SetCodeSelectorFarJump):
|
ASM_PFX(SetCodeSelectorFarJump):
|
||||||
add rsp, 0x10
|
add rsp, 0x10
|
||||||
|
|
||||||
mov rax, LONG_MODE_DS ; get new DS
|
mov rax, LONG_MODE_DS ; get new DS
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
pop rbp
|
pop rbp
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
Loading…
x
Reference in New Issue
Block a user