X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ArmPlatformPkg%2FPrePeiCore%2FMainMPCore.c;h=a98d560133eadd3707551a4984a3bded15347a0a;hb=3222e7b1efc5e01eb17fdacbb1979733e4f25b6a;hp=a369c6e49cb1299c6e7d5ecb1302f44ca31a2313;hpb=55a0d64b883bf8cc4db2a7890e29528ec57a2884;p=mirror_edk2.git diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c index a369c6e49c..a98d560133 100644 --- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c +++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011, ARM Limited. All rights reserved. +* Copyright (c) 2011-2012, ARM Limited. All rights reserved. * * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License @@ -13,12 +13,10 @@ **/ #include -#include -#include -#include "PrePeiCore.h" +#include -extern EFI_PEI_PPI_DESCRIPTOR *gSecPpiTable; +#include "PrePeiCore.h" /* * This is the main function for secondary cores. They loop around until a non Null value is written to @@ -32,26 +30,66 @@ extern EFI_PEI_PPI_DESCRIPTOR *gSecPpiTable; VOID EFIAPI SecondaryMain ( - IN UINTN CoreId + IN UINTN MpId ) { - // Function pointer to Secondary Core entry point - VOID (*secondary_start)(VOID); - UINTN secondary_entry_addr=0; + EFI_STATUS Status; + UINTN PpiListSize; + UINTN PpiListCount; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi; + UINTN Index; + UINTN ArmCoreCount; + ARM_CORE_INFO *ArmCoreInfoTable; + UINT32 ClusterId; + UINT32 CoreId; + VOID (*SecondaryStart)(VOID); + UINTN SecondaryEntryAddr; + + ClusterId = GET_CLUSTER_ID(MpId); + CoreId = GET_CORE_ID(MpId); + + // Get the gArmMpCoreInfoPpiGuid + PpiListSize = 0; + ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList); + PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR); + for (Index = 0; Index < PpiListCount; Index++, PpiList++) { + if (CompareGuid (PpiList->Guid, &gArmMpCoreInfoPpiGuid) == TRUE) { + break; + } + } + + // On MP Core Platform we must implement the ARM MP Core Info PPI + ASSERT (Index != PpiListCount); + + ArmMpCoreInfoPpi = PpiList->Ppi; + ArmCoreCount = 0; + Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); + ASSERT_EFI_ERROR (Status); + + // Find the core in the ArmCoreTable + for (Index = 0; Index < ArmCoreCount; Index++) { + if ((ArmCoreInfoTable[Index].ClusterId == ClusterId) && (ArmCoreInfoTable[Index].CoreId == CoreId)) { + break; + } + } + + // The ARM Core Info Table must define every core + ASSERT (Index != ArmCoreCount); // Clear Secondary cores MailBox - ArmClearMPCoreMailbox(); + MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue); - while (secondary_entry_addr = ArmGetMPCoreMailbox(), secondary_entry_addr == 0) { - ArmCallWFI(); + SecondaryEntryAddr = 0; + while (SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress), SecondaryEntryAddr == 0) { + ArmCallWFI (); // Acknowledge the interrupt and send End of Interrupt signal. - ArmGicAcknowledgeSgiFrom(PcdGet32(PcdGicInterruptInterfaceBase),0/*CoreId*/); + ArmGicAcknowledgeSgiFrom (PcdGet32(PcdGicInterruptInterfaceBase), PRIMARY_CORE_ID); } - secondary_start = (VOID (*)())secondary_entry_addr; - // Jump to secondary core entry point. - secondary_start(); + SecondaryStart = (VOID (*)())SecondaryEntryAddr; + SecondaryStart(); // The secondaries shouldn't reach here ASSERT(FALSE); @@ -64,6 +102,12 @@ PrimaryMain ( ) { EFI_SEC_PEI_HAND_OFF SecCoreData; + UINTN PpiListSize; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINTN TemporaryRamBase; + UINTN TemporaryRamSize; + + CreatePpiList (&PpiListSize, &PpiList); // Enable the GIC Distributor ArmGicEnableDistributor(PcdGet32(PcdGicDistributorBase)); @@ -74,21 +118,31 @@ PrimaryMain ( ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E); } + // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at + // the base of the primary core stack + PpiListSize = ALIGN_VALUE(PpiListSize, 0x4); + TemporaryRamBase = (UINTN)PcdGet32 (PcdCPUCoresStackBase) + PpiListSize; + TemporaryRamSize = (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) - PpiListSize; + + // Make sure the size is 8-byte aligned. Once divided by 2, the size should be 4-byte aligned + // to ensure the stack pointer is 4-byte aligned. + TemporaryRamSize = TemporaryRamSize - (TemporaryRamSize & (0x8-1)); + // // Bind this information into the SEC hand-off state // Note: this must be in sync with the stuff in the asm file // Note also: HOBs (pei temp ram) MUST be above stack // SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF); - SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet32 (PcdNormalFvBaseAddress); - SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdNormalFvSize); - SecCoreData.TemporaryRamBase = (VOID *)(UINTN)PcdGet32 (PcdCPUCoresNonSecStackBase); // We consider we run on the primary core (and so we use the first stack) - SecCoreData.TemporaryRamSize = (UINTN)(UINTN)PcdGet32 (PcdCPUCoresNonSecStackSize); - SecCoreData.PeiTemporaryRamBase = (VOID *)((UINTN)(SecCoreData.TemporaryRamBase) + (SecCoreData.TemporaryRamSize / 2)); + SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet32 (PcdFvBaseAddress); + SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdFvSize); + SecCoreData.TemporaryRamBase = (VOID *)TemporaryRamBase; // We run on the primary core (and so we use the first stack) + SecCoreData.TemporaryRamSize = TemporaryRamSize; + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize / 2; - SecCoreData.StackBase = SecCoreData.TemporaryRamBase; - SecCoreData.StackSize = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize; + SecCoreData.StackBase = (VOID *)ALIGN_VALUE((UINTN)(SecCoreData.TemporaryRamBase) + SecCoreData.PeiTemporaryRamSize, 0x4); + SecCoreData.StackSize = (TemporaryRamBase + TemporaryRamSize) - (UINTN)SecCoreData.StackBase; // Jump to PEI core entry point - (PeiCoreEntryPoint)(&SecCoreData, (VOID *)&gSecPpiTable); + (PeiCoreEntryPoint)(&SecCoreData, PpiList); }