123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /*++
- Copyright (c) 2014 Minoca Corp. All Rights Reserved
- Module Name:
- smp.c
- Abstract:
- This module implements support routines for the second core on OMAP4 SoCs.
- Author:
- Evan Green 31-Mar-2013
- Environment:
- Firmware
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <uefifw.h>
- #include "pandafw.h"
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define OMAP4_CPU0_PARKED_ADDRESS 0x81FFA000
- #define OMAP4_CPU1_PARKED_ADDRESS 0x81FFB000
- #define OMAP4_CPU_PARKED_ADDRESS_SIZE 0x1000
- #define OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE (2 * OMAP4_CPU_PARKED_ADDRESS_SIZE)
- #define ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET 0x0800
- //
- // This SMC command modifies AuxCoreBoot 0.
- //
- #define OMAP4_SMC_COMMAND_MODIFY_AUX_CORE_BOOT_0 0x104
- //
- // This SMC command writes to AuxCoreBoot 1.
- //
- #define OMAP4_SMC_COMMAND_WRITE_AUX_CORE_BOOT_1 0x105
- //
- // This SMC command writes to the Power Status register in the SCU (Snoop
- // Control Unit).
- //
- #define OMAP4_SMC_COMMAND_SET_SCU_POWER_STATUS 0x108
- //
- // Define the value to write into AuxCoreBoot 0 to start the CPU.
- //
- #define OMAP4_AUX_CORE_BOOT_0_START 0x00000200
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- //
- // Internal assembly routines.
- //
- UINT32
- EfipOmap4SmcCommand (
- UINT32 Argument1,
- UINT32 Argument2,
- UINT32 Command
- );
- VOID
- EfipOmap4ProcessorStartup (
- VOID
- );
- VOID
- EfipOmap4SendEvent (
- VOID
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // Define the variables other cores read to boot.
- //
- volatile UINT32 EfiOmap4ProcessorId;
- VOID volatile *EfiOmap4ProcessorJumpAddress;
- extern UINT8 EfipOmap4ParkingLoop;
- extern UINT8 EfipOmap4ParkingLoopEnd;
- //
- // ------------------------------------------------------------------ Functions
- //
- EFI_STATUS
- EfipSmpInitialize (
- VOID
- )
- /*++
- Routine Description:
- This routine initializes and parks the second core on the OMAP4.
- Arguments:
- None.
- Return Value:
- EFI status code.
- --*/
- {
- VOID *Cpu0;
- VOID *Cpu1;
- EFI_PHYSICAL_ADDRESS ParkedAddress;
- EFI_STATUS Status;
- //
- // Allocate the pages for the firmware parked spaces.
- //
- ParkedAddress = OMAP4_CPU0_PARKED_ADDRESS;
- Status = EfiAllocatePages(
- AllocateAddress,
- EfiACPIMemoryNVS,
- EFI_SIZE_TO_PAGES(OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE),
- &ParkedAddress);
- if (EFI_ERROR(Status)) {
- return Status;
- }
- EfiSetMem((VOID *)(UINTN)ParkedAddress,
- OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE,
- 0);
- Cpu0 = (VOID *)(UINTN)ParkedAddress;
- Cpu1 = Cpu0 + OMAP4_CPU_PARKED_ADDRESS_SIZE;
- //
- // Write -1 to the processor number location.
- //
- *((UINT32 *)Cpu0) = -1;
- *((UINT32 *)Cpu1) = -1;
- //
- // Copy the parking protocol loops into the right places.
- //
- EfiCopyMem(Cpu0 + ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET,
- &EfipOmap4ParkingLoop,
- (UINTN)&EfipOmap4ParkingLoopEnd - (UINTN)&EfipOmap4ParkingLoop);
- EfiCopyMem(Cpu1 + ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET,
- &EfipOmap4ParkingLoop,
- (UINTN)&EfipOmap4ParkingLoopEnd - (UINTN)&EfipOmap4ParkingLoop);
- EfiCoreInvalidateInstructionCacheRange(Cpu0,
- OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE);
- EfiOmap4ProcessorId = 1;
- EfiOmap4ProcessorJumpAddress = Cpu1 + ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET;
- //
- // Set AuxCoreBoot 1 to the physical address that it should jump to.
- //
- EfipOmap4SmcCommand((UINTN)EfipOmap4ProcessorStartup,
- 0,
- OMAP4_SMC_COMMAND_WRITE_AUX_CORE_BOOT_1);
- //
- // Set AuxCoreBoot 0 to tell the CPU that it really should jump.
- //
- EfipOmap4SmcCommand(OMAP4_AUX_CORE_BOOT_0_START,
- ~OMAP4_AUX_CORE_BOOT_0_START,
- OMAP4_SMC_COMMAND_MODIFY_AUX_CORE_BOOT_0);
- //
- // Send an event to core 1.
- //
- EfipOmap4SendEvent();
- //
- // Wait for the second CPU to come to life. For some reason marking the
- // variable as volatile doesn't seem to prevent optimization.
- //
- while (EfiReadRegister32(&EfiOmap4ProcessorJumpAddress) != (UINTN)NULL) {
- NOTHING;
- }
- return EFI_SUCCESS;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
|