/** Initialize controllers that must setup at the early stage Some peripherals must be initialized in Secure World. For example, some L2x0 requires to be initialized in Secure World **/ RETURN_STATUS ArmPlatformSecInitialize ( IN UINTN MpId ) { UINT32 Identification; // If it is not the primary core then there is nothing to do if (!ArmPlatformIsPrimaryCore (MpId)) { return RETURN_SUCCESS; } // Configure periodic timer (TIMER0) for 1MHz operation MmioOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER0_TIMCLK); // Configure 1MHz clock MmioOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER1_TIMCLK); // Configure SP810 to use 1MHz clock and disable MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK); // Configure SP810 to use 1MHz clock and disable MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER3_EN, SP810_SYS_CTRL_TIMER3_TIMCLK); // Read the GIC Identification Register Identification = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIDR); // Check if we are GICv3 if (ARM_GIC_ICCIDR_GET_ARCH_VERSION(Identification) >= 0x3) { InitializeGicV3 (); } return RETURN_SUCCESS; }
EFI_STATUS DisableRTD3 ( VOID) { // //Disable RTD3 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x210, (UINT32)~(0x0f000007), (UINT32) (0x00)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x1e0, (UINT32)~(0x0f000007), (UINT32) (0x00)); return EFI_SUCCESS; }
EFI_STATUS InitializeMMCHS ( VOID ) { UINT8 Data; EFI_STATUS Status; DEBUG ((DEBUG_BLKIO, "InitializeMMCHS()\n")); // Select Device group to belong to P1 device group in Power IC. Data = DEV_GRP_P1; Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data); ASSERT_EFI_ERROR(Status); // Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage. Data = VSEL_3_00V; Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data); ASSERT_EFI_ERROR(Status); // After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable. MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1)); // Enable WP GPIO MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23); // Enable Card Detect Data = CARD_DETECT_ENABLE; gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data); return Status; }
EFI_STATUS Set ( IN EMBEDDED_GPIO *This, IN EMBEDDED_GPIO_PIN Gpio, IN EMBEDDED_GPIO_MODE Mode ) { UINTN Port; UINTN Pin; UINT32 OutputEnableRegister; UINT32 SetDataOutRegister; UINT32 ClearDataOutRegister; Port = GPIO_PORT(Gpio); Pin = GPIO_PIN(Gpio); OutputEnableRegister = GpioBase(Port) + GPIO_OE; SetDataOutRegister = GpioBase(Port) + GPIO_SETDATAOUT; ClearDataOutRegister = GpioBase(Port) + GPIO_CLEARDATAOUT; switch (Mode) { case GPIO_MODE_INPUT: MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_INPUT(Pin)); break; case GPIO_MODE_OUTPUT_0: MmioWrite32 (ClearDataOutRegister, GPIO_CLEARDATAOUT_BIT(Pin)); MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin)); break; case GPIO_MODE_OUTPUT_1: MmioWrite32 (SetDataOutRegister, GPIO_SETDATAOUT_BIT(Pin)); MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin)); break; default: return EFI_UNSUPPORTED; } return EFI_SUCCESS; }
/** Initialize controllers that must setup at the early stage Some peripherals must be initialized in Secure World. For example, some L2x0 requires to be initialized in Secure World **/ RETURN_STATUS ArmPlatformSecInitialize ( IN UINTN MpId ) { // If it is not the primary core then there is nothing to do if (!ArmPlatformIsPrimaryCore (MpId)) { return RETURN_SUCCESS; } // Configure periodic timer (TIMER0) for 1MHz operation MmioOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER0_TIMCLK); // Configure 1MHz clock MmioOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER1_TIMCLK); // Configure SP810 to use 1MHz clock and disable MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK); // Configure SP810 to use 1MHz clock and disable MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER3_EN, SP810_SYS_CTRL_TIMER3_TIMCLK); return RETURN_SUCCESS; }
return EFI_SUCCESS; } EFI_STATUS ConfigureMipiCsi ( VOID) { // //Configure the platform clock for MIPI-CSI usage //PLT_CLK0 // MmioAndThenOr32 (IO_BASE_ADDRESS + 0x6a0, (UINT32)~(0x7), (UINT32) (0x01)); // //PLT_CLK1 // MmioAndThenOr32 (IO_BASE_ADDRESS + 0x570, (UINT32)~(0x7), (UINT32) (0x01)); // //PLT_CLK2 // MmioAndThenOr32 (IO_BASE_ADDRESS + 0x5B0, (UINT32)~(0x7), (UINT32) (0x01)); return EFI_SUCCESS; }
/** Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value, followed a bitwise inclusive OR with another 32-bit value. Reads the 32-bit PCI configuration register specified by Address, performs a bitwise AND between the read result and the value specified by AndData, performs a bitwise inclusive OR between the result of the AND operation and the value specified by OrData, and writes the result to the 32-bit PCI configuration register specified by Address. The value written to the PCI configuration register is returned. This function must guarantee that all PCI read and write operations are serialized. If Address > 0x0FFFFFFF, then ASSERT(). If Address is not aligned on a 32-bit boundary, then ASSERT(). @param Address Address that encodes the PCI Bus, Device, Function and Register. @param AndData The value to AND with the PCI configuration register. @param OrData The value to OR with the result of the AND operation. @return The value written back to the PCI configuration register. **/ UINT32 EFIAPI PciExpressAndThenOr32 ( IN UINTN Address, IN UINT32 AndData, IN UINT32 OrData ) { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioAndThenOr32 ( (UINTN) GetPciExpressBaseAddress () + Address, AndData, OrData ); }
VOID UpdateMMCHSClkFrequency ( UINTN NewCLKD ) { DEBUG ((DEBUG_BLKIO, "UpdateMMCHSClkFrequency()\n")); // Set Clock enable to 0x0 to not provide the clock to the card MmioAnd32 (MMCHS_SYSCTL, ~CEN); // Set new clock frequency. MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6); // Poll till Internal Clock Stable while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS); // Set Clock enable to 0x1 to provide the clock to the card MmioOr32 (MMCHS_SYSCTL, CEN); }
EFI_STATUS ConfigureLpeGpio ( IN SYSTEM_CONFIGURATION *SystemConfiguration ) { DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------start\n")); if (SystemConfiguration->PchAzalia == 0) { MmioAndThenOr32 (IO_BASE_ADDRESS + 0x220, (UINT32)~(0x7), (UINT32) (0x01)); MmioAndThenOr32 (IO_BASE_ADDRESS + 0x250, (UINT32)~(0x7), (UINT32) (0x01)); MmioAndThenOr32 (IO_BASE_ADDRESS + 0x240, (UINT32)~(0x7), (UINT32) (0x01)); MmioAndThenOr32 (IO_BASE_ADDRESS + 0x260, (UINT32)~(0x7), (UINT32) (0x01)); MmioAndThenOr32 (IO_BASE_ADDRESS + 0x270, (UINT32)~(0x7), (UINT32) (0x01)); MmioAndThenOr32 (IO_BASE_ADDRESS + 0x230, (UINT32)~(0x7), (UINT32) (0x01)); MmioAndThenOr32 (IO_BASE_ADDRESS + 0x280, (UINT32)~(0x7), (UINT32) (0x01)); MmioAndThenOr32 (IO_BASE_ADDRESS + 0x540, (UINT32)~(0x7), (UINT32) (0x01)); } DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------end\n")); 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 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; }
/** Do any final initialization on SATA controller @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance @param[in] IsSetS3BootScript Is this function called for S3 boot script save @retval EFI_SUCCESS The function completed successfully **/ EFI_STATUS ConfigureSataAtBoot ( IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy, IN BOOLEAN IsSetS3BootScript ) { UINT8 Index; UINT32 AhciBar; UINTN PciD19F0RegBase; UINT16 SataModeSelect; UINT32 PxSctlDet; UINT32 PxCmdSud; UINT32 OrgCmdWord; UINT32 Data32And; UINT32 Data32Or; DEBUG ((EFI_D_INFO, "ConfigureSataAtBoot() Start\n")); // // eSATA port support only up to Gen2 // PciD19F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, 0); // // Make sure SATA device exists. // if (MmioRead16 (PciD19F0RegBase + R_PCH_SATA_ID) != 0xFFFF) { SataModeSelect = MmioRead16 (PciD19F0RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK; if ((SataModeSelect == V_PCH_SATA_MAP_SMS_AHCI) || (SataModeSelect == V_PCH_SATA_MAP_SMS_RAID)) { AhciBar = MmioRead32 (PciD19F0RegBase + R_PCH_SATA_ABAR) & B_PCH_SATA_ABAR_BA; // // Make sure the AhciBar is valid. // if ((AhciBar != 0x00000000) && (AhciBar != B_PCH_SATA_ABAR_BA)) { // // Keep original CMD word, and enable MSE // OrgCmdWord = MmioRead32 (PciD19F0RegBase + R_PCH_SATA_COMMAND); if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) { Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) B_PCH_SATA_COMMAND_MSE; if (!IsSetS3BootScript) { MmioOr32 ((PciD19F0RegBase + R_PCH_SATA_COMMAND), Data32Or); } else { // // Set S3 Boot Script // S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (PciD19F0RegBase + R_PCH_SATA_COMMAND), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } for (Index = 0; Index < PCH_AHCI_MAX_PORTS; Index++) { if (PchPlatformPolicy->SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) { PxSctlDet = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))) & B_PCH_SATA_AHCI_PXSCTL_DET; PxCmdSud = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))) & B_PCH_SATA_AHCI_PxCMD_SUD; // // Limit speed to Gen2 // Data32And = (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD); Data32Or = (UINT32) V_PCH_SATA_AHCI_PXSCTL_SPD_2; if (!IsSetS3BootScript) { MmioAndThenOr32 ( (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), Data32And, Data32Or ); } else { // // Set S3 Boot Script // S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } // // If port is not offline, and it's spin up, need to port reset. // After port reset, clear the SERR. // - Set DET=1, and then set DET=0. // - Finally, set FRE=1. // if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_0) && (PxCmdSud == B_PCH_SATA_AHCI_PxCMD_SUD)) { if (!IsSetS3BootScript) { MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_1); PchPmTimerStall (1000); MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET)); MmioWrite32 (AhciBar + (R_PCH_SATA_AHCI_P0SERR + (0x80 * Index)), (UINT32)~0u); MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), B_PCH_SATA_AHCI_PxCMD_FRE); } else { // // Set S3 Boot Script // Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) V_PCH_SATA_AHCI_PXSCTL_DET_1; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); S3BootScriptSaveStall (1000); Data32And = (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET); Data32Or = (UINT32) 0x00000000; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) 0xFFFFFFFF; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SERR + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) B_PCH_SATA_AHCI_PxCMD_FRE; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } // // If port is offline, and it's not spin up, meets the power bug. // Need to do the W/A to spin up the port and then spin down. // Then entering back to offline and listen. // - Set DET=0, SUD=1, and then set SUD=0, DET=4. // if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_4) && (PxCmdSud == 0)) { if (!IsSetS3BootScript) { MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET)); MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), B_PCH_SATA_AHCI_PxCMD_SUD); PchPmTimerStall (1000); MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PxCMD_SUD)); MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_4); } else { // // Set S3 Boot Script // Data32And = (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET); Data32Or = (UINT32) 0x00000000; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) B_PCH_SATA_AHCI_PxCMD_SUD; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); S3BootScriptSaveStall (1000); Data32And = (UINT32) ~(B_PCH_SATA_AHCI_PxCMD_SUD); Data32Or = (UINT32) 0x00000000; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) V_PCH_SATA_AHCI_PXSCTL_DET_4; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } } } // // Restore original CMD word. // if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) { Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) OrgCmdWord; if (!IsSetS3BootScript) { MmioWrite32 ((PciD19F0RegBase + R_PCH_SATA_COMMAND), Data32Or); } else { S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (PciD19F0RegBase + R_PCH_SATA_COMMAND), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } } // AhciBar is vaild } // SATA mode is AHCI or RAID } // if D19F0 is existed DEBUG ((EFI_D_INFO, "ConfigureSataAtBoot() End\n")); return EFI_SUCCESS; }
EFI_STATUS EFIAPI PeiInitPlatform ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { UINTN SmbusRegBase; EFI_PLATFORM_INFO_HOB PlatformInfo; EFI_STATUS Status= EFI_SUCCESS; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable = NULL; UINTN VariableSize; SYSTEM_CONFIGURATION SystemConfiguration; UINT32 GGC = 0; EFI_PEI_PPI_DESCRIPTOR *mVlvMmioPolicyPpiDesc; VLV_MMIO_POLICY_PPI *mVlvMmioPolicyPpi; ZeroMem (&PlatformInfo, sizeof(PlatformInfo)); Status = InstallMonoStatusCode(FileHandle, PeiServices); ASSERT_EFI_ERROR (Status); // // Initialize Stall PPIs // Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]); ASSERT_EFI_ERROR (Status); Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]); ASSERT_EFI_ERROR (Status); SmbusRegBase = PchPciDeviceMmBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SMBUS, PCI_FUNCTION_NUMBER_PCH_SMBUS ); // // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves // MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS); MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE); PchBaseInit(); // //Todo: confirm if we need program 8254 // // Setting 8254 // Program timer 1 as refresh timer // IoWrite8 (0x43, 0x54); IoWrite8 (0x41, 0x12); // // RTC power failure handling // RtcPowerFailureHandler (PeiServices); PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210; VariableSize = sizeof (SYSTEM_CONFIGURATION); ZeroMem (&SystemConfiguration, VariableSize); // // Obtain variable services // Status = (*PeiServices)->LocatePpi( PeiServices, &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (void **)&Variable ); ASSERT_EFI_ERROR(Status); Status = Variable->GetVariable ( Variable, L"Setup", &gEfiSetupVariableGuid, NULL, &VariableSize, &SystemConfiguration ); if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) { //The setup variable is corrupted VariableSize = sizeof(SYSTEM_CONFIGURATION); Status = Variable->GetVariable( Variable, L"SetupRecovery", &gEfiSetupVariableGuid, NULL, &VariableSize, &SystemConfiguration ); ASSERT_EFI_ERROR (Status); } if (EFI_ERROR (Status)) { GGC = ((2 << 3) | 0x200); PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC); GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50); DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3)); } else { if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) {
/** This is the declaration of an EFI image entry point. This can be the entry point to an application written to this specification, an EFI boot service driver, or an EFI runtime driver. @param ImageHandle Handle that identifies the loaded image. @param SystemTable System Table for this image. @retval EFI_SUCCESS The operation completed successfully. **/ EFI_STATUS EFIAPI LibRtcInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_HANDLE Handle; EFI_STATUS Status; // Obtain RTC device base address mArmadaRtcBase = PcdGet64 (PcdRtcBaseAddress); // Check if the controller can be initialized if (mArmadaRtcBase == 0) { DEBUG ((DEBUG_ERROR, "RTC: None of controllers enabled\n")); return EFI_INVALID_PARAMETER; } // Declare the controller as EFI_MEMORY_RUNTIME Status = gDS->AddMemorySpace ( EfiGcdMemoryTypeMemoryMappedIo, mArmadaRtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "RTC: Failed to add memory space\n")); return Status; } Status = gDS->SetMemorySpaceAttributes ( mArmadaRtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "RTC: Failed to set memory attributes\n")); goto ErrSetMem; } /* Update RTC-MBUS bridge timing parameters */ MmioAndThenOr32 ( mArmadaRtcBase + RTC_BRIDGE_TIMING_CTRL0_REG_OFFS, ~(RTC_WRITE_SETUP_DELAY_MASK | RTC_WRITE_PERIOD_DELAY_MASK), (RTC_WRITE_SETUP_DELAY_DEFAULT | RTC_WRITE_PERIOD_DELAY_DEFAULT) ); MmioAndThenOr32 ( mArmadaRtcBase + RTC_BRIDGE_TIMING_CTRL1_REG_OFFS, ~RTC_READ_OUTPUT_DELAY_MASK, RTC_READ_OUTPUT_DELAY_DEFAULT ); // Install the protocol Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiRealTimeClockArchProtocolGuid, NULL, NULL ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "RTC: Failed to install the protocol\n")); goto ErrSetMem; } // Register for the virtual address change event Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, LibRtcVirtualNotifyEvent, NULL, &gEfiEventVirtualAddressChangeGuid, &mRtcVirtualAddrChangeEvent ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "RTC: Failed to register virtual address change event\n")); goto ErrEvent; } return Status; ErrEvent: gBS->UninstallProtocolInterface (Handle, &gEfiRealTimeClockArchProtocolGuid, NULL); ErrSetMem: gDS->RemoveMemorySpace (mArmadaRtcBase, SIZE_4KB); return Status; }
EFI_STATUS MMCSendCommand ( IN EFI_MMC_HOST_PROTOCOL *This, IN MMC_CMD MmcCmd, IN UINT32 Argument ) { UINTN MmcStatus; UINTN RetryCount = 0; if (IgnoreCommand(MmcCmd)) return EFI_SUCCESS; MmcCmd = TranslateCommand(MmcCmd); //DEBUG ((EFI_D_ERROR, "MMCSendCommand(%d)\n", MmcCmd)); // Check if command line is in use or not. Poll till command line is available. while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED); // Provide the block size. MmioWrite32 (MMCHS_BLK, BLEN_512BYTES); // Setting Data timeout counter value to max value. MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL); // Clear Status register. MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF); // Set command argument register MmioWrite32 (MMCHS_ARG, Argument); //TODO: fix this //Enable interrupt enable events to occur //MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal); // Send a command MmioWrite32 (MMCHS_CMD, MmcCmd); // Check for the command status. while (RetryCount < MAX_RETRY_COUNT) { do { MmcStatus = MmioRead32 (MMCHS_STAT); } while (MmcStatus == 0); // Read status of command response if ((MmcStatus & ERRI) != 0) { // Perform soft-reset for mmci_cmd line. MmioOr32 (MMCHS_SYSCTL, SRC); while ((MmioRead32 (MMCHS_SYSCTL) & SRC)); //DEBUG ((EFI_D_INFO, "MmcStatus: 0x%x\n", MmcStatus)); return EFI_DEVICE_ERROR; } // Check if command is completed. if ((MmcStatus & CC) == CC) { MmioWrite32 (MMCHS_STAT, CC); break; } RetryCount++; } if (RetryCount == MAX_RETRY_COUNT) { DEBUG ((DEBUG_BLKIO, "MMCSendCommand: Timeout\n")); return EFI_TIMEOUT; } return EFI_SUCCESS; }
/** Set interrupt trigger type of an interrupt @param This Instance pointer for this protocol @param Source Hardware source of the interrupt. @param TriggerType Interrupt trigger type. @retval EFI_SUCCESS Source interrupt supported. @retval EFI_UNSUPPORTED Source interrupt is not supported. **/ STATIC EFI_STATUS EFIAPI GicV3SetTriggerType ( IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source, IN EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE TriggerType ) { UINTN RegAddress; UINTN Config1Bit; UINT32 Value; EFI_STATUS Status; BOOLEAN SourceEnabled; if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) { DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \ TriggerType)); ASSERT (FALSE); return EFI_UNSUPPORTED; } Status = GicGetDistributorIcfgBaseAndBit ( Source, &RegAddress, &Config1Bit ); if (EFI_ERROR (Status)) { return Status; } Status = GicV3GetInterruptSourceState ( (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, Source, &SourceEnabled ); if (EFI_ERROR (Status)) { return Status; } Value = (TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) ? ARM_GIC_ICDICFR_EDGE_TRIGGERED : ARM_GIC_ICDICFR_LEVEL_TRIGGERED; // Before changing the value, we must disable the interrupt, // otherwise GIC behavior is UNPREDICTABLE. if (SourceEnabled) { GicV3DisableInterruptSource ( (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, Source ); } MmioAndThenOr32 ( RegAddress, ~(0x1 << Config1Bit), Value << Config1Bit ); // Restore interrupt state if (SourceEnabled) { GicV3EnableInterruptSource ( (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, Source ); } return EFI_SUCCESS; }
EFI_STATUS ConfigureUSBULPI ( VOID) { // //Configure USB ULPI //USB_ULPI_0_CLK // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x338, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x330, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA0 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x388, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x380, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA1 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x368, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x360, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA2 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x318, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x310, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA3 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x378, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x370, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA4 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x308, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x300, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA5 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x398, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x390, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA6 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x328, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x320, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DATA7 // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a8, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a0, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_DIR // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x348, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x340, (UINT32)~(0x187), (UINT32) (0x81)); // //USB_ULPI_0_NXT // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x358, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x350, (UINT32)~(0x187), (UINT32) (0x101)); // //USB_ULPI_0_STP // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b8, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b0, (UINT32)~(0x187), (UINT32) (0x81)); // //USB_ULPI_0_REFCLK // MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x288, (UINT32)~(0x7), (UINT32) (GPI)); MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x280, (UINT32)~(0x187), (UINT32) (0x101)); 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; }
/** 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; }
/** Perform USB erratas after MRC init. **/ VOID PlatformUsbErratasPostMrc ( VOID ) { UINT32 Index; UINT32 TempBar0Addr; UINT16 SaveCmdReg; UINT32 SaveBar0Reg; TempBar0Addr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress); // // Apply EHCI controller erratas. // for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) { if ((PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) { continue; // Device not enabled, skip. } // // Save current settings for PCI CMD/BAR0 registers // SaveCmdReg = PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND); SaveBar0Reg = PciRead32 (IohEhciPciReg[Index] + R_IOH_USB_MEMBAR); // // Temp. assign base address register, Enable Memory Space. // PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr); PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE); // // Set packet buffer OUT/IN thresholds. // MmioAndThenOr32 ( TempBar0Addr + R_IOH_EHCI_INSNREG01, (UINT32) (~(B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_MASK | B_IOH_EHCI_INSNREG01_IN_THRESHOLD_MASK)), (UINT32) ((EHCI_OUT_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP) | (EHCI_IN_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP)) ); // // Restore settings for PCI CMD/BAR0 registers // PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg); PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg); } // // Apply USB device controller erratas. // for (Index = 0; Index < IOH_MAX_USBDEVICE_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) { if ((PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) { continue; // Device not enabled, skip. } // // Save current settings for PCI CMD/BAR0 registers // SaveCmdReg = PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND); SaveBar0Reg = PciRead32 (IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR); // // Temp. assign base address register, Enable Memory Space. // PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr); PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE); // // Erratas for USB Device interrupt registers. // // // 1st Mask interrupts. // MmioWrite32 ( TempBar0Addr + R_IOH_USBDEVICE_D_INTR_MSK_UDC_REG, V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG ); // // 2nd RW/1C of equivalent status bits. // MmioWrite32 ( TempBar0Addr + R_IOH_USBDEVICE_D_INTR_UDC_REG, V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG ); // // 1st Mask end point interrupts. // MmioWrite32 ( TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG, V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG ); // // 2nd RW/1C of equivalent end point status bits. // MmioWrite32 ( TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_UDC_REG, V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG ); // // Restore settings for PCI CMD/BAR0 registers // PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg); PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg); } }
/** 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; }