/** Initialize the state information for the CPU Architectural Protocol @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS InterruptDxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_CPU_ARCH_PROTOCOL *Cpu; // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); // Make sure all interrupts are disabled by default. MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF); MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF); MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF); MmioOr32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR); Status = gBS->InstallMultipleProtocolInterfaces(&gHardwareInterruptHandle, &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol, NULL); ASSERT_EFI_ERROR(Status); // // Get the CPU protocol that this driver requires. // Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); ASSERT_EFI_ERROR(Status); // // Unregister the default exception handler. // Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL); ASSERT_EFI_ERROR(Status); // // Register to receive interrupts // Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler); ASSERT_EFI_ERROR(Status); // Register for an ExitBootServicesEvent Status = gBS->CreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); ASSERT_EFI_ERROR(Status); return Status; }
/** Install Boot Manager Policy Protocol. @param ImageHandle The image handle. @param SystemTable The system table. @retval EFI_SUCEESS The Boot Manager Policy protocol is successfully installed. @retval Other Return status from gBS->InstallMultipleProtocolInterfaces(). **/ EFI_STATUS EFIAPI BootManagerPolicyInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_HANDLE Handle; ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiBootManagerPolicyProtocolGuid); Handle = NULL; return gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiBootManagerPolicyProtocolGuid, &mBootManagerPolicy, NULL ); }
/** The user Entry Point for module CpuIo2Dxe. The user code starts with this function. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI CpuIo2Initialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid); Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiCpuIo2ProtocolGuid, &mCpuIo2, NULL ); ASSERT_EFI_ERROR (Status); return Status; }
/** Initialize the state information for the CPU Architectural Protocol @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS InterruptDxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT CpuArchEvent; // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); Status = gBS->InstallMultipleProtocolInterfaces ( &ImageHandle, &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol, NULL ); ASSERT_EFI_ERROR (Status); // // Install the interrupt handler as soon as the CPU arch protocol appears. // CpuArchEvent = EfiCreateProtocolNotifyEvent ( &gEfiCpuArchProtocolGuid, TPL_CALLBACK, CpuArchEventProtocolNotify, NULL, &mCpuArchProtocolNotifyEventRegistration ); ASSERT (CpuArchEvent != NULL); // Register for an ExitBootServicesEvent Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &mExitBootServicesEvent); ASSERT_EFI_ERROR (Status); return Status; }
/** Entry point of the Watchdog Timer Architectural Protocol driver. @param ImageHandle The image handle of this driver. @param SystemTable The pointer of EFI_SYSTEM_TABLE. @retval EFI_SUCCESS Watchdog Timer Architectural Protocol successfully installed. **/ EFI_STATUS EFIAPI WatchdogTimerDriverInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; // // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet. // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid); // // Create the timer event to implement a simple watchdog timer // Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, WatchdogTimerDriverExpires, NULL, &mWatchdogTimerEvent ); ASSERT_EFI_ERROR (Status); // // Install the Watchdog Timer Arch Protocol onto a new handle // Status = gBS->InstallMultipleProtocolInterfaces ( &mWatchdogTimerHandle, &gEfiWatchdogTimerArchProtocolGuid, &mWatchdogTimer, NULL ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** The driver's entry point. It initializes the Reset Architectural Protocol. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Cannot install ResetArch protocol. **/ EFI_STATUS EFIAPI InitializeResetSystem ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE Handle; // // Make sure the Reset Architectural Protocol is not already installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid); // // Hook the runtime service table // gRT->ResetSystem = ResetSystem; // // Now install the Reset RT AP on a new handle // Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiResetArchProtocolGuid, NULL, &gEfiResetNotificationProtocolGuid, &mResetNotification.ResetNotification, &gEdkiiPlatformSpecificResetFilterProtocolGuid, &mPlatformSpecificResetFilter.ResetNotification, &gEdkiiPlatformSpecificResetHandlerProtocolGuid, &mPlatformSpecificResetHandler.ResetNotification, NULL ); ASSERT_EFI_ERROR (Status); return Status; }
/** Initialize the state information for the Watchdog Timer Architectural Protocol. @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS EFIAPI SP805Initialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE Handle; // Find the interrupt controller protocol. ASSERT if not found. Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&mInterrupt); ASSERT_EFI_ERROR (Status); // Unlock access to the SP805 registers SP805Unlock (); // Stop the watchdog from triggering unexpectedly SP805Stop (); // Set the watchdog to reset the board when triggered // This is a last resort in case the interrupt handler fails if ((MmioRead32 (SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_RESEN) == 0) { MmioOr32 (SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_RESEN); } // Clear any pending interrupts MmioWrite32 (SP805_WDOG_INT_CLR_REG, 0); // write of any value clears the irq // Prohibit any rogue access to SP805 registers SP805Lock (); if (PcdGet32 (PcdSP805WatchdogInterrupt) > 0) { Status = mInterrupt->RegisterInterruptSource (mInterrupt, PcdGet32 (PcdSP805WatchdogInterrupt), SP805InterruptHandler); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a: failed to register watchdog interrupt - %r\n", __FUNCTION__, Status)); return Status; } } else { DEBUG ((DEBUG_WARN, "%a: no interrupt specified, running in RESET mode only\n", __FUNCTION__)); } // // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet. // This will avoid conflicts with the universal watchdog // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid); // Register for an ExitBootServicesEvent Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &mEfiExitBootServicesEvent); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } // Install the Timer Architectural Protocol onto a new handle Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiWatchdogTimerArchProtocolGuid, &mWatchdogTimer, NULL ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } EXIT: ASSERT_EFI_ERROR (Status); return Status; }
EFI_STATUS EFIAPI EmuTimerDriverInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Initialize the Timer Architectural Protocol driver Arguments: ImageHandle - ImageHandle of the loaded driver SystemTable - Pointer to the System Table Returns: EFI_SUCCESS - Timer Architectural Protocol created EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver. EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver. **/ { EFI_STATUS Status; EFI_HANDLE Handle; // // Make sure the Timer Architectural Protocol is not already installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); // // Get the CPU Architectural Protocol instance // Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (void *)&mCpu); ASSERT_EFI_ERROR (Status); // // Start the timer thread at the default timer period // Status = mTimer.SetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); if (EFI_ERROR (Status)) { return Status; } // // Install the Timer Architectural Protocol onto a new handle // Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEfiTimerArchProtocolGuid, EFI_NATIVE_INTERFACE, &mTimer ); if (EFI_ERROR (Status)) { return Status; } return EFI_SUCCESS; }
/** Initialize the state information for the Watchdog Timer Architectural Protocol. @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS EFIAPI SP805Initialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE Handle; // Check if the SP805 hardware watchdog module exists on board Status = SP805Identify(); if (EFI_ERROR(Status)) { Status = EFI_DEVICE_ERROR; goto EXIT; } // Unlock access to the SP805 registers SP805Unlock (); // Stop the watchdog from triggering unexpectedly SP805Stop (); // Set the watchdog to reset the board when triggered if ((MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_RESEN) == 0) { MmioOr32 (SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_RESEN); } // Prohibit any rogue access to SP805 registers SP805Lock(); // // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet. // This will avoid conflicts with the universal watchdog // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid); // Register for an ExitBootServicesEvent Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); if (EFI_ERROR(Status)) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } // Install the Timer Architectural Protocol onto a new handle Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces( &Handle, &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer, NULL ); if (EFI_ERROR(Status)) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } EXIT: if(EFI_ERROR(Status)) { // The watchdog failed to initialize ASSERT(FALSE); } return Status; }
/** Initialize the state information for the CPU Architectural Protocol @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS GicV2DxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Index; UINT32 RegOffset; UINTN RegShift; UINT32 CpuTarget; // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); mGicInterruptInterfaceBase = PcdGet32 (PcdGicInterruptInterfaceBase); mGicDistributorBase = PcdGet32 (PcdGicDistributorBase); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); for (Index = 0; Index < mGicNumInterrupts; Index++) { GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index); // Set Priority RegOffset = Index / 4; RegShift = (Index % 4) * 8; MmioAndThenOr32 ( mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset), ~(0xff << RegShift), ARM_GIC_DEFAULT_PRIORITY << RegShift ); } // // Targets the interrupts to the Primary Cpu // // Only Primary CPU will run this code. We can identify our GIC CPU ID by reading // the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each // connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31. // More Info in the GIC Specification about "Interrupt Processor Targets Registers" // // Read the first Interrupt Processor Targets Register (that corresponds to the 4 // first SGIs) CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR); // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value // is 0 when we run on a uniprocessor platform. if (CpuTarget != 0) { // The 8 first Interrupt Processor Targets Registers are read-only for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) { MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget); } } // Set binary point reg to 0x7 (no preemption) MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCBPR, 0x7); // Set priority mask reg to 0xff to allow all priorities through MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0xff); // Enable gic cpu interface ArmGicEnableInterruptInterface (mGicInterruptInterfaceBase); // Enable gic distributor ArmGicEnableDistributor (mGicDistributorBase); Status = InstallAndRegisterInterruptService ( &gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent); return Status; }
/** Initialize HII Database. @param ImageHandle The image handle. @param SystemTable The system table. @retval EFI_SUCCESS The Hii database is setup correctly. @return Other value if failed to create the default event for gHiiKeyboardLayoutChanged. Check gBS->CreateEventEx for details. Or failed to insatll the protocols. Check gBS->InstallMultipleProtocolInterfaces for details. **/ EFI_STATUS EFIAPI InitializeHiiDatabase ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE Handle; // // There will be only one HII Database in the system // If there is another out there, someone is trying to install us // again. Fail that scenario. // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiDatabaseProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiFontProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiImageProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiStringProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiConfigRoutingProtocolGuid); InitializeListHead (&mPrivate.DatabaseList); InitializeListHead (&mPrivate.DatabaseNotifyList); InitializeListHead (&mPrivate.HiiHandleList); InitializeListHead (&mPrivate.FontInfoList); // // Create a event with EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group type. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, KeyboardLayoutChangeNullEvent, NULL, &gEfiHiiKeyBoardLayoutGuid, &gHiiKeyboardLayoutChanged ); if (EFI_ERROR (Status)) { return Status; } Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiHiiFontProtocolGuid, &mPrivate.HiiFont, &gEfiHiiStringProtocolGuid, &mPrivate.HiiString, &gEfiHiiDatabaseProtocolGuid, &mPrivate.HiiDatabase, &gEfiHiiConfigRoutingProtocolGuid, &mPrivate.ConfigRouting, NULL ); if (EFI_ERROR (Status)) { return Status; } if (FeaturePcdGet (PcdSupportHiiImageProtocol)) { CopyMem (&mPrivate.HiiImage, &mImageProtocol, sizeof (mImageProtocol)); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiHiiImageProtocolGuid, &mPrivate.HiiImage, NULL ); } return Status; }
EFI_STATUS EFIAPI WatchdogTimerDriverInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Initialize the Watchdog Timer Architectural Protocol driver Arguments: ImageHandle - ImageHandle of the loaded driver SystemTable - Pointer to the System Table Returns: EFI_SUCCESS - Timer Architectural Protocol created EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver. EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver. --*/ { EFI_STATUS Status; // // Initialize the EFI Driver Library // EfiInitializeDriverLib (ImageHandle, SystemTable); EfiLibReportStatusCode ( EFI_PROGRESS_CODE, (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_BEGIN), 0, &gEfiCallerIdGuid, NULL ); // // Make sure the Watchdog Timer Architectural Protocol is not already installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid); // // Create the timer event used to implement a simple watchdog timer // Status = gBS->CreateEvent ( EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_NOTIFY, WatchdogTimerDriverExpires, NULL, &mWatchdogTimerEvent ); ASSERT_EFI_ERROR (Status); // // Install the Watchdog Timer Arch Protocol onto a new handle // Status = gBS->InstallMultipleProtocolInterfaces ( &mWatchdogTimerHandle, &gEfiWatchdogTimerArchProtocolGuid, &mWatchdogTimer, NULL ); ASSERT_EFI_ERROR (Status); EfiLibReportStatusCode ( EFI_PROGRESS_CODE, (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_END), 0, &gEfiCallerIdGuid, NULL ); return Status; }
/** Initialize the state information for the CPU Architectural Protocol @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS InterruptDxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Index; UINT32 RegOffset; UINTN RegShift; EFI_CPU_ARCH_PROTOCOL *Cpu; // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase)); for (Index = 0; Index < mGicNumInterrupts; Index++) { DisableInterruptSource (&gHardwareInterruptProtocol, Index); // Set Priority RegOffset = Index / 4; RegShift = (Index % 4) * 8; MmioAndThenOr32 ( PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset), ~(0xff << RegShift), ARM_GIC_DEFAULT_PRIORITY << RegShift ); } // Configure interrupts for cpu 0 for (Index = 0; Index < (mGicNumInterrupts / 4); Index++) { MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), 0x01010101); } // Set binary point reg to 0x7 (no preemption) MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7); // Set priority mask reg to 0xff to allow all priorities through MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff); // Enable gic cpu interface MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1); // Enable gic distributor MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x1); // Initialize the array for the Interrupt Handlers gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts); Status = gBS->InstallMultipleProtocolInterfaces ( &gHardwareInterruptHandle, &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol, NULL ); ASSERT_EFI_ERROR (Status); // // Get the CPU protocol that this driver requires. // Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); ASSERT_EFI_ERROR(Status); // // Unregister the default exception handler. // Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL); ASSERT_EFI_ERROR(Status); // // Register to receive interrupts // Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler); ASSERT_EFI_ERROR(Status); // Register for an ExitBootServicesEvent Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); ASSERT_EFI_ERROR (Status); return Status; }
/** Initialize the state information for the CPU Architectural Protocol @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS InterruptDxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Index; UINT32 RegOffset; UINTN RegShift; EFI_CPU_ARCH_PROTOCOL *Cpu; UINT32 CpuTarget; // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0 DEBUG_CODE_BEGIN(); if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) { DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n")); } DEBUG_CODE_END(); // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase)); mGicNumInterrupts /=8; for (Index = 0; Index < mGicNumInterrupts; Index++) { (VOID)DisableInterruptSource (&gHardwareInterruptProtocol, Index); // Set Priority RegOffset = Index / 4; RegShift = (Index % 4) * 8; MmioAndThenOr32 ( PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset), ~(UINT32)(0xff << RegShift), ARM_GIC_DEFAULT_PRIORITY << RegShift ); } // Configure interrupts for Primary Cpu CpuTarget = (1 << PcdGet32 (PcdGicPrimaryCoreId)); CpuTarget |= CpuTarget << 16; for (Index = 0; Index < (mGicNumInterrupts / 2); Index++) { MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), CpuTarget); } //end_d00183345, 2012-11-17 // Set binary point reg to 0x7 (no preemption) MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x3); // Set priority mask reg to 0xff to allow all priorities through MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff); // Enable gic cpu interface MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1); // Enable gic distributor MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x7); MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISR, ~0); //MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISR, ~0); // Initialize the array for the Interrupt Handlers gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts); Status = gBS->InstallMultipleProtocolInterfaces ( &gHardwareInterruptHandle, &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol, NULL ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { //for fortify return Status; } // // Get the CPU protocol that this driver requires. // Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); ASSERT_EFI_ERROR(Status); if (EFI_ERROR (Status)) { //for fortify return Status; } // // Unregister the default exception handler. // Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_AARCH64_IRQ, NULL); ASSERT_EFI_ERROR(Status); if (EFI_ERROR (Status)) { //for fortify return Status; } // // Register to receive interrupts // Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_AARCH64_IRQ, IrqInterruptHandler); ASSERT_EFI_ERROR(Status); if (EFI_ERROR (Status)) { //for fortify return Status; } // Register for an ExitBootServicesEvent Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { //for fortify return Status; } return Status; }
/** This routine initializes the HII Database. @param ImageHandle Image handle for PCD DXE driver. @param SystemTable Pointer to SystemTable. @retval EFI_SUCCESS The entry point alwasy return successfully. **/ EFI_STATUS EFIAPI InitializeHiiDatabase ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { HII_THUNK_PRIVATE_DATA *Private; EFI_HANDLE Handle; EFI_STATUS Status; UINTN BufferLength; EFI_HII_HANDLE *Buffer; UINTN Index; HII_THUNK_CONTEXT *ThunkContext; ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiCompatibilityProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiFormBrowserCompatibilityProtocolGuid); Private = AllocateCopyPool (sizeof (HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate); ASSERT (Private != NULL); InitializeListHead (&Private->ThunkContextListHead); InitHiiHandleDatabase (); mHiiThunkPrivateData = Private; Status = gBS->LocateProtocol ( &gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabase ); ASSERT_EFI_ERROR (Status); Status = gBS->LocateProtocol ( &gEfiHiiStringProtocolGuid, NULL, (VOID **) &mHiiStringProtocol ); ASSERT_EFI_ERROR (Status); Status = gBS->LocateProtocol ( &gEfiHiiFontProtocolGuid, NULL, (VOID **) &mHiiFontProtocol ); ASSERT_EFI_ERROR (Status); Status = gBS->LocateProtocol ( &gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mHiiConfigRoutingProtocol ); ASSERT_EFI_ERROR (Status); Status = gBS->LocateProtocol ( &gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mFormBrowser2Protocol ); ASSERT_EFI_ERROR (Status); // // Install protocol interface // Status = gBS->InstallProtocolInterface ( &Private->Handle, &gEfiHiiCompatibilityProtocolGuid, EFI_NATIVE_INTERFACE, (VOID *) &Private->Hii ); ASSERT_EFI_ERROR (Status); Status = ListPackageLists (EFI_HII_PACKAGE_STRINGS, NULL, &BufferLength, &Buffer); if (Status == EFI_SUCCESS) { ASSERT (Buffer != NULL); for (Index = 0; Index < BufferLength / sizeof (EFI_HII_HANDLE); Index++) { ThunkContext = CreateThunkContextForUefiHiiHandle (Buffer[Index]); ASSERT (ThunkContext!= NULL); InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link); } FreePool (Buffer); } Status = mHiiDatabase->RegisterPackageNotify ( mHiiDatabase, EFI_HII_PACKAGE_STRINGS, NULL, NewOrAddPackNotify, EFI_HII_DATABASE_NOTIFY_NEW_PACK, &Handle ); ASSERT_EFI_ERROR (Status); Status = mHiiDatabase->RegisterPackageNotify ( mHiiDatabase, EFI_HII_PACKAGE_STRINGS, NULL, NewOrAddPackNotify, EFI_HII_DATABASE_NOTIFY_ADD_PACK, &Handle ); ASSERT_EFI_ERROR (Status); Status = mHiiDatabase->RegisterPackageNotify ( mHiiDatabase, EFI_HII_PACKAGE_FORMS, NULL, NewOrAddPackNotify, EFI_HII_DATABASE_NOTIFY_NEW_PACK, &Handle ); ASSERT_EFI_ERROR (Status); Status = mHiiDatabase->RegisterPackageNotify ( mHiiDatabase, EFI_HII_PACKAGE_FORMS, NULL, NewOrAddPackNotify, EFI_HII_DATABASE_NOTIFY_ADD_PACK, &Handle ); ASSERT_EFI_ERROR (Status); Status = mHiiDatabase->RegisterPackageNotify ( mHiiDatabase, EFI_HII_PACKAGE_STRINGS, NULL, RemovePackNotify, EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, &Handle ); ASSERT_EFI_ERROR (Status); InitSetBrowserStrings (); mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private; Status = gBS->InstallProtocolInterface ( &mBrowserThunkPrivateDataTemplate.Handle, &gEfiFormBrowserCompatibilityProtocolGuid, EFI_NATIVE_INTERFACE, (VOID *) &mBrowserThunkPrivateDataTemplate.FormBrowser ); ASSERT_EFI_ERROR (Status); return Status; }
EFI_STATUS EFIAPI MonotonicCounterDriverInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Arguments: (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) Returns: --*/ { EFI_STATUS Status; UINT32 HighCount; UINTN BufferSize; EfiInitializeDriverLib (ImageHandle, SystemTable); // // Make sure the Monotonic Counter Architectural Protocol is not already installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMonotonicCounterArchProtocolGuid); // // Register our ExitBootServices notify function // Status = gBS->CreateEvent ( EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES, EFI_TPL_NOTIFY, MonotonicCounterDriverExitBootServices, NULL, &mMonotonicCounterNotifyEvent ); ASSERT_EFI_ERROR (Status); // // Register our SetVirtualAddressMap notify function // Status = gBS->CreateEvent ( EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, EFI_TPL_NOTIFY, MonotonicCounterDriverSetVirtualAddressMap, NULL, &mMonotonicCounterSetVirtualAddressMapNotifyEvent ); ASSERT_EFI_ERROR (Status); // // Initialize event to handle overflows // Status = gBS->CreateEvent ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_CALLBACK, EfiMtcEventHandler, NULL, &mEfiMtcEvent ); ASSERT_EFI_ERROR (Status); // // Read the last high part // BufferSize = sizeof (UINT32); Status = gRT->GetVariable ( mEfiMtcName, &mEfiMtcGuid, NULL, &BufferSize, &HighCount ); if (EFI_ERROR (Status)) { HighCount = 0; } // // Set the current value // mEfiMtc = LShiftU64 (HighCount, 32); // // Increment the upper 32 bits for this boot // Continue even if it fails. It will only fail if the variable services are // not functional. // Status = MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount); // // Fill in the EFI Boot Services and EFI Runtime Services Monotonic Counter Fields // gBS->GetNextMonotonicCount = MonotonicCounterDriverGetNextMonotonicCount; gRT->GetNextHighMonotonicCount = MonotonicCounterDriverGetNextHighMonotonicCount; // // Install the Monotonic Counter Architctural Protocol onto a new handle // Status = gBS->InstallMultipleProtocolInterfaces ( &mMonotonicCounterHandle, &gEfiMonotonicCounterArchProtocolGuid, NULL, NULL ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** Initialize the state information for the CPU Architectural Protocol @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS GicV3DxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Index; UINT32 RegOffset; UINTN RegShift; UINT64 CpuTarget; UINT64 MpId; // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); mGicDistributorBase = PcdGet32 (PcdGicDistributorBase); mGicRedistributorsBase = PcdGet32 (PcdGicRedistributorsBase); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); // // We will be driving this GIC in native v3 mode, i.e., with Affinity // Routing enabled. So ensure that the ARE bit is set. // if (!FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { MmioOr32 (mGicDistributorBase + ARM_GIC_ICDDCR, ARM_GIC_ICDDCR_ARE); } for (Index = 0; Index < mGicNumInterrupts; Index++) { GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index); // Set Priority RegOffset = Index / 4; RegShift = (Index % 4) * 8; MmioAndThenOr32 ( mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset), ~(0xff << RegShift), ARM_GIC_DEFAULT_PRIORITY << RegShift ); } // // Targets the interrupts to the Primary Cpu // if (FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { // Only Primary CPU will run this code. We can identify our GIC CPU ID by reading // the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each // connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31. // More Info in the GIC Specification about "Interrupt Processor Targets Registers" // // Read the first Interrupt Processor Targets Register (that corresponds to the 4 // first SGIs) CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR); // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value // is 0 when we run on a uniprocessor platform. if (CpuTarget != 0) { // The 8 first Interrupt Processor Targets Registers are read-only for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) { MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget); } } } else { MpId = ArmReadMpidr (); CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3); if ((MmioRead32 (mGicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_DS) != 0) { // // If the Disable Security (DS) control bit is set, we are dealing with a // GIC that has only one security state. In this case, let's assume we are // executing in non-secure state (which is appropriate for DXE modules) // and that no other firmware has performed any configuration on the GIC. // This means we need to reconfigure all interrupts to non-secure Group 1 // first. // MmioWrite32 (mGicRedistributorsBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDISR, 0xffffffff); for (Index = 32; Index < mGicNumInterrupts; Index += 32) { MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDISR + Index / 8, 0xffffffff); } } // Route the SPIs to the primary CPU. SPIs start at the INTID 32 for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) { MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM); } } // Set binary point reg to 0x7 (no preemption) ArmGicV3SetBinaryPointer (0x7); // Set priority mask reg to 0xff to allow all priorities through ArmGicV3SetPriorityMask (0xff); // Enable gic cpu interface ArmGicV3EnableInterruptInterface (); // Enable gic distributor ArmGicEnableDistributor (mGicDistributorBase); Status = InstallAndRegisterInterruptService ( &gHardwareInterruptV3Protocol, GicV3IrqInterruptHandler, GicV3ExitBootServicesEvent); return Status; }
EFI_STATUS EFIAPI WinNtTimerDriverInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Initialize the Timer Architectural Protocol driver Arguments: ImageHandle - ImageHandle of the loaded driver SystemTable - Pointer to the System Table Returns: EFI_SUCCESS - Timer Architectural Protocol created EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver. EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver. --*/ { EFI_STATUS Status; UINTN Result; EFI_HANDLE Handle; EFI_HANDLE hSourceProcessHandle; EFI_HANDLE hSourceHandle; EFI_HANDLE hTargetProcessHandle; // // Make sure the Timer Architectural Protocol is not already installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); // // Get the CPU Architectural Protocol instance // Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID**)&mCpu); ASSERT_EFI_ERROR (Status); // // Get our handle so the timer tick thread can suspend // hSourceProcessHandle = gWinNt->GetCurrentProcess (); hSourceHandle = gWinNt->GetCurrentThread (); hTargetProcessHandle = gWinNt->GetCurrentProcess (); Result = gWinNt->DuplicateHandle ( hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, &mNtMainThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); if (Result == 0) { return EFI_DEVICE_ERROR; } // // Initialize Critical Section used to update variables shared between the main // thread and the timer interrupt thread. // gWinNt->InitializeCriticalSection (&mNtCriticalSection); // // Start the timer thread at the default timer period // Status = mTimer.SetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); if (EFI_ERROR (Status)) { gWinNt->DeleteCriticalSection (&mNtCriticalSection); return Status; } // // Install the Timer Architectural Protocol onto a new handle // Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEfiTimerArchProtocolGuid, EFI_NATIVE_INTERFACE, &mTimer ); if (EFI_ERROR (Status)) { // // Cancel the timer // mTimer.SetTimerPeriod (&mTimer, 0); gWinNt->DeleteCriticalSection (&mNtCriticalSection); return Status; } return EFI_SUCCESS; }