2011-02-01 06:41:42 +01:00
/** @file
*
* Copyright ( c ) 2011 , 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
* which accompanies this distribution . The full text of the license may be found at
* http : //opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN " AS IS " BASIS ,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND , EITHER EXPRESS OR IMPLIED .
*
* */
2011-09-23 00:59:52 +02:00
# include <Library/ArmGicLib.h>
2011-02-01 06:41:42 +01:00
# include <Library/ArmMPCoreMailBoxLib.h>
# include <Chipset/ArmV7.h>
2011-06-11 14:10:19 +02:00
# include "PrePeiCore.h"
2011-02-01 06:41:42 +01:00
/*
* This is the main function for secondary cores . They loop around until a non Null value is written to
* SYS_FLAGS register . The SYS_FLAGS register is platform specific .
* Note : The secondary cores , while executing secondary_main , assumes that :
* : SGI 0 is configured as Non - secure interrupt
* : Priority Mask is configured to allow SGI 0
* : Interrupt Distributor and CPU interfaces are enabled
*
*/
VOID
EFIAPI
2011-06-11 14:10:19 +02:00
SecondaryMain (
2011-09-23 01:01:13 +02:00
IN UINTN MpId
2011-06-11 14:10:19 +02:00
)
2011-02-01 06:41:42 +01:00
{
2011-06-11 14:10:19 +02:00
// Function pointer to Secondary Core entry point
VOID ( * secondary_start ) ( VOID ) ;
UINTN secondary_entry_addr = 0 ;
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
// Clear Secondary cores MailBox
ArmClearMPCoreMailbox ( ) ;
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
while ( secondary_entry_addr = ArmGetMPCoreMailbox ( ) , secondary_entry_addr = = 0 ) {
ArmCallWFI ( ) ;
// Acknowledge the interrupt and send End of Interrupt signal.
2011-09-23 01:01:13 +02:00
ArmGicAcknowledgeSgiFrom ( PcdGet32 ( PcdGicInterruptInterfaceBase ) , PRIMARY_CORE_ID ) ;
2011-06-11 14:10:19 +02:00
}
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
secondary_start = ( VOID ( * ) ( ) ) secondary_entry_addr ;
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
// Jump to secondary core entry point.
secondary_start ( ) ;
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
// The secondaries shouldn't reach here
ASSERT ( FALSE ) ;
2011-02-01 06:41:42 +01:00
}
2011-06-11 14:10:19 +02:00
VOID
EFIAPI
PrimaryMain (
2011-02-01 06:41:42 +01:00
IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
)
{
2011-06-11 14:10:19 +02:00
EFI_SEC_PEI_HAND_OFF SecCoreData ;
2011-02-01 06:41:42 +01:00
2011-09-23 00:59:52 +02:00
// Enable the GIC Distributor
ArmGicEnableDistributor ( PcdGet32 ( PcdGicDistributorBase ) ) ;
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
// If ArmVe has not been built as Standalone then we need to wake up the secondary cores
2011-09-23 00:59:52 +02:00
if ( FeaturePcdGet ( PcdSendSgiToBringUpSecondaryCores ) ) {
2011-06-11 14:10:19 +02:00
// Sending SGI to all the Secondary CPU interfaces
2011-09-23 00:59:52 +02:00
ArmGicSendSgiTo ( PcdGet32 ( PcdGicDistributorBase ) , ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE , 0x0E ) ;
2011-06-11 14:10:19 +02:00
}
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
//
// 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 ) ;
2011-09-23 01:06:31 +02:00
SecCoreData . BootFirmwareVolumeBase = ( VOID * ) ( UINTN ) PcdGet32 ( PcdFvBaseAddress ) ;
SecCoreData . BootFirmwareVolumeSize = PcdGet32 ( PcdFvSize ) ;
2011-09-23 01:05:20 +02:00
SecCoreData . TemporaryRamBase = ( VOID * ) ( UINTN ) PcdGet32 ( PcdCPUCorePrimaryStackSize ) ; // We consider we run on the primary core (and so we use the first stack)
SecCoreData . TemporaryRamSize = ( UINTN ) ( UINTN ) PcdGet32 ( PcdCPUCorePrimaryStackSize ) ;
2011-06-11 14:10:19 +02:00
SecCoreData . PeiTemporaryRamBase = ( VOID * ) ( ( UINTN ) ( SecCoreData . TemporaryRamBase ) + ( SecCoreData . TemporaryRamSize / 2 ) ) ;
SecCoreData . PeiTemporaryRamSize = SecCoreData . TemporaryRamSize / 2 ;
SecCoreData . StackBase = SecCoreData . TemporaryRamBase ;
SecCoreData . StackSize = SecCoreData . TemporaryRamSize - SecCoreData . PeiTemporaryRamSize ;
2011-02-01 06:41:42 +01:00
2011-06-11 14:10:19 +02:00
// Jump to PEI core entry point
( PeiCoreEntryPoint ) ( & SecCoreData , ( VOID * ) & gSecPpiTable ) ;
2011-02-01 06:41:42 +01:00
}