/** This function causes a system-wide reset (cold reset), in which all circuitry within the system returns to its initial state. This type of reset is asynchronous to system operation and operates without regard to cycle boundaries. If this function returns, it means that the system does not support cold reset. **/ VOID EFIAPI ResetCold ( VOID ) { //Perform cold reset of the system. MmioOr32 (PRM_RSTCTRL, RST_DPLL3); while ((MmioRead32(PRM_RSTST) & GLOBAL_COLD_RST) != 0x1); }
/** Performs a bitwise inclusive OR of a 32-bit PCI configuration register with a 32-bit value. Reads the 32-bit PCI configuration register specified by Address, performs a bitwise inclusive OR between the read result 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 OrData The value to OR with the PCI configuration register. @return The value written back to the PCI configuration register. **/ UINT32 EFIAPI PciExpressOr32 ( IN UINTN Address, IN UINT32 OrData ) { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioOr32 ((UINTN) GetPciExpressBaseAddress () + Address, OrData); }
/** Starts the SP805 counting down by enabling interrupts. The count down will start from the value stored in the Load register, not from the value where it was previously stopped. **/ STATIC VOID SP805Start ( VOID ) { // Enable interrupts if ((MmioRead32 (SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) == 0) { MmioOr32 (SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_INTEN); } }
/** 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; }
/** Initialize controllers that must setup in the normal world This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim in the PEI phase. **/ RETURN_STATUS ArmPlatformInitialize ( IN UINTN MpId ) { if (!ArmPlatformIsPrimaryCore (MpId)) { return RETURN_SUCCESS; } // Disable memory remapping and return to normal mapping MmioOr32 (SP810_CTRL_BASE, BIT8); return RETURN_SUCCESS; }
/** Initialize the state information for the Timer Architectural Protocol and the Timer Debug support protocol that allows the debugger to break into a running program. @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 TimerInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_HANDLE Handle = NULL; EFI_STATUS Status; UINT32 TimerBaseAddress; // Find the interrupt controller protocol. ASSERT if not found. Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt); ASSERT_EFI_ERROR (Status); // Set up the timer registers TimerBaseAddress = TimerBase (FixedPcdGet32(PcdOmap35xxArchTimer)); TISR = TimerBaseAddress + GPTIMER_TISR; TCLR = TimerBaseAddress + GPTIMER_TCLR; TLDR = TimerBaseAddress + GPTIMER_TLDR; TCRR = TimerBaseAddress + GPTIMER_TCRR; TIER = TimerBaseAddress + GPTIMER_TIER; // Disable the timer Status = TimerDriverSetTimerPeriod (&gTimer, 0); ASSERT_EFI_ERROR (Status); // Install interrupt handler gVector = InterruptVectorForTimer (FixedPcdGet32(PcdOmap35xxArchTimer)); Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler); ASSERT_EFI_ERROR (Status); // Turn on the functional clock for Timer MmioOr32 (CM_FCLKEN_PER, CM_FCLKEN_PER_EN_GPT3_ENABLE); // Set up default timer Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); ASSERT_EFI_ERROR (Status); // Install the Timer Architectural Protocol onto a new handle Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiTimerArchProtocolGuid, &gTimer, NULL ); ASSERT_EFI_ERROR(Status); return Status; }
STATIC VOID SetSataCapabilities ( EFI_PHYSICAL_ADDRESS AhciBaseAddr ) { UINT32 Capability; Capability = 0; if (FixedPcdGetBool (PcdSataSssSupport)) // Staggered Spin-Up Support bit Capability |= EFI_AHCI_CAP_SSS; if (FixedPcdGetBool (PcdSataSmpsSupport)) // Mechanical Presence Support bit Capability |= EFI_AHCI_CAP_SMPS; MmioOr32 (AhciBaseAddr + EFI_AHCI_CAPABILITY_OFFSET, Capability); }
/** 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; }
/** Enable interrupt source Source. @param This Instance pointer for this protocol @param Source Hardware source of the interrupt @retval EFI_SUCCESS Source interrupt enabled. @retval EFI_DEVICE_ERROR Hardware could not be programmed. **/ STATIC EFI_STATUS EFIAPI EnableInterruptSource ( IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source ) { if (Source >= NUM_IRQS) { ASSERT (FALSE); return EFI_UNSUPPORTED; } MmioOr32 (RegBase + BCM2836_INTC_TIMER_CONTROL_OFFSET, 1 << Source); return EFI_SUCCESS; }
EFI_STATUS HwInitializeDisplay ( UINTN VramBaseAddress, UINTN VramSize ) { EFI_STATUS Status; UINT8 Data; EFI_TPL OldTpl; EMBEDDED_EXTERNAL_DEVICE *gTPS65950; // Enable power lines used by TFP410 Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950); ASSERT_EFI_ERROR (Status); OldTpl = gBS->RaiseTPL(TPL_NOTIFY); Data = VAUX_DEV_GRP_P1; Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEV_GRP), 1, &Data); ASSERT_EFI_ERROR(Status); Data = VAUX_DEDICATED_18V; Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEDICATED), 1, &Data); ASSERT_EFI_ERROR (Status); // Power up TFP410 (set GPIO2 on TPS - for BeagleBoard-xM) Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data); ASSERT_EFI_ERROR (Status); Data |= BIT2; Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data); ASSERT_EFI_ERROR (Status); Data = BIT2; Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, SETGPIODATAOUT1), 1, &Data); ASSERT_EFI_ERROR (Status); gBS->RestoreTPL(OldTpl); // Power up TFP410 (set GPIO 170 - for older BeagleBoards) MmioAnd32 (GPIO6_BASE + GPIO_OE, ~BIT10); MmioOr32 (GPIO6_BASE + GPIO_SETDATAOUT, BIT10); return EFI_SUCCESS; }
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); }
/** This function adjusts the period of timer interrupts to the value specified by TimerPeriod. If the timer period is updated, then the selected timer period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. If an error occurs while attempting to update the timer period, then the timer hardware will be put back in its state prior to this call, and EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt is disabled. This is not the same as disabling the CPU's interrupts. Instead, it must either turn off the timer hardware, or it must adjust the interrupt controller so that a CPU interrupt is not generated when the timer interrupt fires. @param This The EFI_TIMER_ARCH_PROTOCOL instance. @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. If the timer is programmable, then the timer period will be rounded up to the nearest timer period that is supported by the timer hardware. If TimerPeriod is set to 0, then the timer interrupts will be disabled. @retval EFI_SUCCESS The timer period was changed. @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. **/ EFI_STATUS EFIAPI TimerDriverSetTimerPeriod ( IN EFI_TIMER_ARCH_PROTOCOL *This, IN UINT64 TimerPeriod ) { EFI_STATUS Status; UINT64 TimerTicks; // always disable the timer MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, ~SP804_TIMER_CTRL_ENABLE); if (TimerPeriod == 0) { // Leave timer disabled from above, and... // Disable timer 0/1 interrupt for a TimerPeriod of 0 Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector); } else { // Convert TimerPeriod into 1MHz clock counts (us units = 100ns units * 10) TimerTicks = DivU64x32 (TimerPeriod, 10); TimerTicks = MultU64x32 (TimerTicks, PcdGet32(PcdSP804TimerFrequencyInMHz)); // if it's larger than 32-bits, pin to highest value if (TimerTicks > 0xffffffff) { TimerTicks = 0xffffffff; } // Program the SP804 timer with the new count value MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_LOAD_REG, TimerTicks); // enable the timer MmioOr32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE); // enable timer 0/1 interrupts Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector); } // Save the new timer period mTimerPeriod = TimerPeriod; return Status; }
VOID ResetSystem ( IN EFI_RESET_TYPE ResetType ) { switch (ResetType) { case EfiResetWarm: //Perform warm reset of the system. GoLittleEndian(PcdGet32(PcdFlashFvMainBase)); break; case EfiResetCold: case EfiResetShutdown: default: //Perform cold reset of the system. MmioOr32(PRM_RSTCTRL, RST_DPLL3); while ((MmioRead32(PRM_RSTST) & GLOBAL_COLD_RST) != 0x1); break; } //Should never come here. ASSERT(FALSE); }
/** Configure ExI. @param ImageHandle Pointer to the loaded image protocol for this driver @param SystemTable Pointer to the EFI System Table @retval EFI_SUCCESS The driver initializes correctly. **/ VOID InitExI ( ) { EFI_STATUS Status; SYSTEM_CONFIGURATION SystemConfiguration; UINTN VarSize; VarSize = sizeof(SYSTEM_CONFIGURATION); Status = gRT->GetVariable( L"Setup", &gEfiNormalSetupGuid, NULL, &VarSize, &SystemConfiguration ); if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { //The setup variable is corrupted VarSize = sizeof(SYSTEM_CONFIGURATION); Status = gRT->GetVariable( L"SetupRecovery", &gEfiNormalSetupGuid, NULL, &VarSize, &SystemConfiguration ); ASSERT_EFI_ERROR (Status); } if (SystemConfiguration.ExISupport == 1) { MmioOr32 ((UINTN) (GetPmcBase() + R_PCH_PMC_MTPMC1), (UINT32) BIT0+BIT1+BIT2); } else if (SystemConfiguration.ExISupport == 0) { MmioAnd32 ((UINTN) (GetPmcBase() + R_PCH_PMC_MTPMC1), ~((UINT32) BIT0+BIT1+BIT2)); //clear bit 0,1,2 } }
/** Do a usb SETUP/OUT transaction by usb debug port. @param DebugPortRegister Pointer to the base address of usb debug port register interface. @param Buffer Pointer to the buffer receiving data. @param Length Number of bytes of the received data. @param Token The token PID for each USB transaction. @param Addr The usb device address for usb transaction. @param Ep The endpoint for usb transaction. @param DataToggle The toggle bit used at usb transaction. @retval RETURN_SUCCESS The IN transaction is executed successfully. @retval RETURN_INVALID_PARAMETER The parameters passed in are invalid. @retval RETURN_DEVICE_ERROR The IN transaction comes across error. **/ RETURN_STATUS EFIAPI UsbDebugPortOut ( IN USB_DEBUG_PORT_REGISTER *DebugPortRegister, IN UINT8 *Buffer, IN UINT8 Length, IN UINT8 Token, IN UINT8 Addr, IN UINT8 Ep, IN UINT8 DataToggle ) { UINT8 Index; if (Length > 8) { return RETURN_INVALID_PARAMETER; } DebugPortRegister->TokenPid = Token; if (DataToggle != 0) { DebugPortRegister->SendPid = DATA1_PID; } else { DebugPortRegister->SendPid = DATA0_PID; } DebugPortRegister->UsbAddress = (UINT8)(Addr & 0x7F); DebugPortRegister->UsbEndPoint = (UINT8)(Ep & 0xF); // // Fill in the data length and corresponding data. // MmioAnd32((UINTN)&DebugPortRegister->ControlStatus, (UINT32)~0xF); MmioOr32((UINTN)&DebugPortRegister->ControlStatus, Length & 0xF); for (Index = 0; Index < Length; Index++) { DebugPortRegister->DataBuffer[Index] = Buffer[Index]; } // // Setting W/R bit to indicate it's a WRITE operation // MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT4); // // Setting GO bit as well as clearing DONE bit // MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT5); // // Wait for completing the request // while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & BIT16) == 0) { if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) { return RETURN_DEVICE_ERROR; } } // // Clearing DONE bit by writing 1 // MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT16); // // Check if the request is executed successfully or not. // if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & BIT6) { return RETURN_DEVICE_ERROR; } // // Make sure the sent data are not beyond the allowable maximum length - 8 byte // if (((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & 0xF) > USB_DEBUG_PORT_MAX_PACKET_SIZE) { return RETURN_DEVICE_ERROR; } return RETURN_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; }
EFI_STATUS DssSetMode ( UINT32 VramBaseAddress, UINTN ModeNumber ) { // Make sure the interface clock is running MmioWrite32 (CM_ICLKEN_DSS, EN_DSS); // Stop the functional clocks MmioAnd32 (CM_FCLKEN_DSS, ~(EN_DSS1 | EN_DSS2 | EN_TV)); // Program the DSS clock divisor MmioWrite32 (CM_CLKSEL_DSS, 0x1000 | (LcdModes[ModeNumber].DssDivisor)); // Start the functional clocks MmioOr32 (CM_FCLKEN_DSS, (EN_DSS1 | EN_DSS2 | EN_TV)); // Wait for DSS to stabilize gBS->Stall(1); // Reset the subsystem MmioWrite32(DSS_SYSCONFIG, DSS_SOFTRESET); while (!(MmioRead32 (DSS_SYSSTATUS) & DSS_RESETDONE)); // Configure LCD parameters MmioWrite32 (DISPC_SIZE_LCD, ((LcdModes[ModeNumber].HorizontalResolution - 1) | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16)) ); MmioWrite32 (DISPC_TIMING_H, ( (LcdModes[ModeNumber].HSync - 1) | ((LcdModes[ModeNumber].HFrontPorch - 1) << 8) | ((LcdModes[ModeNumber].HBackPorch - 1) << 20)) ); MmioWrite32 (DISPC_TIMING_V, ( (LcdModes[ModeNumber].VSync - 1) | ((LcdModes[ModeNumber].VFrontPorch - 1) << 8) | ((LcdModes[ModeNumber].VBackPorch - 1) << 20)) ); // Set the framebuffer to only load frames (no gamma tables) MmioAnd32 (DISPC_CONFIG, CLEARLOADMODE); MmioOr32 (DISPC_CONFIG, LOAD_FRAME_ONLY); // Divisor for the pixel clock MmioWrite32(DISPC_DIVISOR, ((1 << 16) | LcdModes[ModeNumber].DispcDivisor) ); // Set up the graphics layer MmioWrite32 (DISPC_GFX_PRELD, 0x2D8); MmioWrite32 (DISPC_GFX_BA0, VramBaseAddress); MmioWrite32 (DISPC_GFX_SIZE, ((LcdModes[ModeNumber].HorizontalResolution - 1) | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16)) ); MmioWrite32(DISPC_GFX_ATTR, (GFXENABLE | RGB16 | BURSTSIZE16)); // Start it all MmioOr32 (DISPC_CONTROL, (LCDENABLE | ACTIVEMATRIX | DATALINES24 | BYPASS_MODE | LCDENABLESIGNAL)); MmioOr32 (DISPC_CONTROL, GOLCD); return EFI_SUCCESS; }
/** 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; }
/** 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; }
/** Configure OMAP DMA Channel @param Channel DMA Channel to configure @param Dma4 Pointer to structure used to initialize DMA registers for the Channel @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_INVALID_PARAMETER Channel is not valid @retval EFI_DEVICE_ERROR The system hardware could not map the requested information. **/ EFI_STATUS EFIAPI EnableDmaChannel ( IN UINTN Channel, IN OMAP_DMA4 *DMA4 ) { UINT32 RegVal; if (Channel > DMA4_MAX_CHANNEL) { return EFI_INVALID_PARAMETER; } /* 1) Configure the transfer parameters in the logical DMA registers */ /*-------------------------------------------------------------------*/ /* a) Set the data type CSDP[1:0], the Read/Write Port access type CSDP[8:7]/[15:14], the Source/dest endianism CSDP[21]/CSDP[19], write mode CSDP[17:16], source/dest packed or nonpacked CSDP[6]/CSDP[13] */ // Read CSDP RegVal = MmioRead32 (DMA4_CSDP (Channel)); // Build reg RegVal = ((RegVal & ~ 0x3) | DMA4->DataType ); RegVal = ((RegVal & ~(0x3 << 7)) | (DMA4->ReadPortAccessType << 7)); RegVal = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessType << 14)); RegVal = ((RegVal & ~(0x1 << 21)) | (DMA4->SourceEndiansim << 21)); RegVal = ((RegVal & ~(0x1 << 19)) | (DMA4->DestinationEndianism << 19)); RegVal = ((RegVal & ~(0x3 << 16)) | (DMA4->WriteMode << 16)); RegVal = ((RegVal & ~(0x1 << 6)) | (DMA4->SourcePacked << 6)); RegVal = ((RegVal & ~(0x1 << 13)) | (DMA4->DestinationPacked << 13)); // Write CSDP MmioWrite32 (DMA4_CSDP (Channel), RegVal); /* b) Set the number of element per frame CEN[23:0]*/ MmioWrite32 (DMA4_CEN (Channel), DMA4->NumberOfElementPerFrame); /* c) Set the number of frame per block CFN[15:0]*/ MmioWrite32 (DMA4_CFN (Channel), DMA4->NumberOfFramePerTransferBlock); /* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0]*/ MmioWrite32 (DMA4_CSSA (Channel), DMA4->SourceStartAddress); MmioWrite32 (DMA4_CDSA (Channel), DMA4->DestinationStartAddress); /* e) Set the Read Port addressing mode CCR[13:12], the Write Port addressing mode CCR[15:14], read/write priority CCR[6]/CCR[26] I changed LCH CCR[20:19]=00 and CCR[4:0]=00000 to LCH CCR[20:19]= DMA4->WriteRequestNumber and CCR[4:0]=DMA4->ReadRequestNumber */ // Read CCR RegVal = MmioRead32 (DMA4_CCR (Channel)); // Build reg RegVal = ((RegVal & ~0x1f) | DMA4->ReadRequestNumber); RegVal = ((RegVal & ~(BIT20 | BIT19)) | DMA4->WriteRequestNumber << 19); RegVal = ((RegVal & ~(0x3 << 12)) | (DMA4->ReadPortAccessMode << 12)); RegVal = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessMode << 14)); RegVal = ((RegVal & ~(0x1 << 6)) | (DMA4->ReadPriority << 6)); RegVal = ((RegVal & ~(0x1 << 26)) | (DMA4->WritePriority << 26)); // Write CCR MmioWrite32 (DMA4_CCR (Channel), RegVal); /* f)- Set the source element index CSEI[15:0]*/ MmioWrite32 (DMA4_CSEI (Channel), DMA4->SourceElementIndex); /* - Set the source frame index CSFI[15:0]*/ MmioWrite32 (DMA4_CSFI (Channel), DMA4->SourceFrameIndex); /* - Set the destination element index CDEI[15:0]*/ MmioWrite32 (DMA4_CDEI (Channel), DMA4->DestinationElementIndex); /* - Set the destination frame index CDFI[31:0]*/ MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex); MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex); // Enable all the status bits since we are polling MmioWrite32 (DMA4_CICR (Channel), DMA4_CICR_ENABLE_ALL); MmioWrite32 (DMA4_CSR (Channel), DMA4_CSR_RESET); /* 2) Start the DMA transfer by Setting the enable bit CCR[7]=1 */ /*--------------------------------------------------------------*/ //write enable bit MmioOr32 (DMA4_CCR(Channel), DMA4_CCR_ENABLE); //Launch transfer return EFI_SUCCESS; }
STATIC VOID InitSdCard ( IN VOID ) { UINT32 Data; // // LDO16 // 000: 1.75V, 001: 1.8V, 010: 2.4V, 011: 2.6V, 100: 2.7V, // 101: 2.85V, 110: 2.95V, 111: 3.0V. // Data = MmioRead32 (PMIC_LDO16_VSET_REG) & LDO16_VSET_MASK; Data |= 6; MmioWrite32 (PMIC_LDO16_VSET_REG, Data); MmioOr32 (PMIC_LDO16_ONOFF_ECO_REG, LDO16_ONOFF_ECO_LDO16_ENABLE); // // wait regulator stable // MicroSecondDelay (100); // // LDO9 // 000: 1.75V, 001: 1.8V, 010: 1.825V, 011: 2.8V, 100: 2.85V, // 101: 2.95V, 110: 3.0V, 111: 3.3V. // Data = MmioRead32 (PMIC_LDO9_VSET_REG) & LDO9_VSET_MASK; Data |= 5; MmioWrite32 (PMIC_LDO9_VSET_REG, Data); MmioOr32 (PMU_REG_BASE + (0x6a << 2), 2); // // wait regulator stable // MicroSecondDelay (100); // // GPIO203 // MmioWrite32 (IOMG_AO_REG_BASE + (24 << 2), 0); // GPIO function // // SD pinmux // MmioWrite32 (IOMG_MMC0_000_REG, IOMG_FUNC1); // SD_CLK MmioWrite32 (IOMG_MMC0_001_REG, IOMG_FUNC1); // SD_CMD MmioWrite32 (IOMG_MMC0_002_REG, IOMG_FUNC1); // SD_DATA0 MmioWrite32 (IOMG_MMC0_003_REG, IOMG_FUNC1); // SD_DATA1 MmioWrite32 (IOMG_MMC0_004_REG, IOMG_FUNC1); // SD_DATA2 MmioWrite32 (IOMG_MMC0_005_REG, IOMG_FUNC1); // SD_DATA3 MmioWrite32 (IOCG_MMC0_000_REG, IOCG_DRIVE (15)); // SD_CLK float with 32mA MmioWrite32 (IOCG_MMC0_001_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_CMD MmioWrite32 (IOCG_MMC0_002_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA0 MmioWrite32 (IOCG_MMC0_003_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA1 MmioWrite32 (IOCG_MMC0_004_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA2 MmioWrite32 (IOCG_MMC0_005_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA3 // // SC_SEL_SD: // 0xx: 3.2MHz, 100: PPLL0, 101: PPLL1, 11x: PPLL2. // SC_DIV_SD: // divider = value + 1 // do { MmioOr32 ( CRG_CLKDIV4, CLKDIV4_SC_SEL_SD (7) | (CLKDIV4_SC_SEL_SD_MASK << CLKDIV4_SC_MASK_SHIFT) ); Data = MmioRead32 (CRG_CLKDIV4) & CLKDIV4_SC_SEL_SD_MASK; } while (Data != CLKDIV4_SC_SEL_SD (7)); // // Unreset SD controller // MmioWrite32 (CRG_PERRSTDIS4, PERRSTEN4_SD); do { Data = MmioRead32 (CRG_PERRSTSTAT4); } while ((Data & PERRSTEN4_SD) == PERRSTEN4_SD); // // Enable SD controller clock // MmioOr32 (CRG_PEREN0, PEREN0_GT_HCLK_SD); MmioOr32 (CRG_PEREN4, PEREN4_GT_CLK_SD); do { Data = MmioRead32 (CRG_PERCLKEN4); } while ((Data & PEREN4_GT_CLK_SD) != PEREN4_GT_CLK_SD); }
/** Polls a debug device to see if there is any data waiting to be read. Polls a debug device to see if there is any data waiting to be read. If there is data waiting to be read from the debug device, then TRUE is returned. If there is no data waiting to be read from the debug device, then FALSE is returned. @param Handle Debug port handle. @retval TRUE Data is waiting to be read from the debug device. @retval FALSE There is no data waiting to be read from the serial device. **/ BOOLEAN EFIAPI DebugPortPollBuffer ( IN DEBUG_PORT_HANDLE Handle ) { USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle; USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister; UINT8 Length; UINT8 Index; RETURN_STATUS Status; // // If Handle is NULL, it means memory is ready for use. // Use global variable to store handle value. // if (Handle == NULL) { UsbDebugPortHandle = &mUsbDebugPortHandle; } else { UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Handle; } if (NeedReinitializeHardware(UsbDebugPortHandle)) { Status = InitializeUsbDebugHardware(UsbDebugPortHandle); if (RETURN_ERROR(Status)) { return FALSE; } } // // If the data buffer is not empty, then return TRUE directly. // else initialize a usb read transaction and read data to the data buffer. // if (UsbDebugPortHandle->DataCount != 0) { return TRUE; } UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset); UsbDebugPortRegister->TokenPid = INPUT_PID; if (UsbDebugPortHandle->BulkInToggle == 0) { UsbDebugPortRegister->SendPid = DATA0_PID; } else { UsbDebugPortRegister->SendPid = DATA1_PID; } UsbDebugPortRegister->UsbAddress = 0x7F; UsbDebugPortRegister->UsbEndPoint = 0x82 & 0x0F; // // Clearing W/R bit to indicate it's a READ operation // MmioAnd32((UINTN)&UsbDebugPortRegister->ControlStatus, (UINT32)~BIT4); // // Setting GO bit as well as clearing DONE bit // MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, (UINT32)BIT5); // // Wait for completing the request // while ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0) { if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) { return FALSE; } } if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus)) & BIT6) { return FALSE; } Length = (UINT8)(MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & 0xF); if (Length > 8) { return FALSE; } UsbDebugPortHandle->BulkInToggle ^= 1; if (Length == 0) { return FALSE; } for (Index = 0; Index < Length; Index++) { UsbDebugPortHandle->Data[Index] = UsbDebugPortRegister->DataBuffer[Index]; } UsbDebugPortHandle->DataCount = Length; return TRUE; }
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; }
EFI_STATUS MMCNotifyState ( IN EFI_MMC_HOST_PROTOCOL *This, IN MMC_STATE State ) { EFI_STATUS Status; UINTN FreqSel; switch(State) { case MmcInvalidState: ASSERT(0); break; case MmcHwInitializationState: mBitModeSet = FALSE; DEBUG ((DEBUG_BLKIO, "MMCHwInitializationState()\n")); Status = InitializeMMCHS (); if (EFI_ERROR(Status)) { DEBUG ((DEBUG_BLKIO, "Initialize MMC host controller fails. Status: %x\n", Status)); return Status; } // Software reset of the MMCHS host controller. MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET); gBS->Stall(1000); while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE); // Soft reset for all. MmioWrite32 (MMCHS_SYSCTL, SRA); gBS->Stall(1000); while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0); //Voltage capabilities initialization. Activate VS18 and VS30. MmioOr32 (MMCHS_CAPA, (VS30 | VS18)); // Wakeup configuration MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP); MmioOr32 (MMCHS_HCTL, IWE); // MMCHS Controller default initialization MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF)); MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF)); // Enable internal clock MmioOr32 (MMCHS_SYSCTL, ICE); // Set the clock frequency to 80KHz. UpdateMMCHSClkFrequency (CLKD_80KHZ); // Enable SD bus power. MmioOr32 (MMCHS_HCTL, (SDBP_ON)); // Poll till SD bus power bit is set. while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON); // Enable interrupts. MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN)); // Controller INIT procedure start. MmioOr32 (MMCHS_CON, INIT); MmioWrite32 (MMCHS_CMD, 0x00000000); while (!(MmioRead32 (MMCHS_STAT) & CC)); // Wait for 1 ms gBS->Stall (1000); // Set CC bit to 0x1 to clear the flag MmioOr32 (MMCHS_STAT, CC); // Retry INIT procedure. MmioWrite32 (MMCHS_CMD, 0x00000000); while (!(MmioRead32 (MMCHS_STAT) & CC)); // End initialization sequence MmioAnd32 (MMCHS_CON, ~INIT); MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON)); // Change clock frequency to 400KHz to fit protocol UpdateMMCHSClkFrequency(CLKD_400KHZ); MmioOr32 (MMCHS_CON, OD); break; case MmcIdleState: break; case MmcReadyState: break; case MmcIdentificationState: break; case MmcStandByState: CalculateCardCLKD (&FreqSel); UpdateMMCHSClkFrequency (FreqSel); break; case MmcTransferState: if (!mBitModeSet) { Status = MMCSendCommand (This, CMD55, mRca << 16); if (!EFI_ERROR (Status)) { // Set device into 4-bit data bus mode Status = MMCSendCommand (This, ACMD6, 0x2); if (!EFI_ERROR (Status)) { // Set host controler into 4-bit mode MmioOr32 (MMCHS_HCTL, DTW_4_BIT); DEBUG ((DEBUG_BLKIO, "SD Memory Card set to 4-bit mode\n")); mBitModeSet = TRUE; } } } break; case MmcSendingDataState: break; case MmcReceiveDataState: break; case MmcProgrammingState: break; case MmcDisconnectState: default: ASSERT(0); } return EFI_SUCCESS; }
/** Initialize usb debug port hardware. 1. reset ehci host controller. 2. set right port to debug port. 3. find a usb debug device is attached by getting debug device descriptor. 4. set address for the usb debug device. 5. configure the usb debug device to debug mode. @param Handle Debug port handle. @retval TRUE The usb debug port hardware configuration is changed. @retval FALSE The usb debug port hardware configuration is not changed. **/ RETURN_STATUS EFIAPI InitializeUsbDebugHardware ( IN USB_DEBUG_PORT_HANDLE *Handle ) { RETURN_STATUS Status; USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister; USB_DEBUG_PORT_DESCRIPTOR UsbDebugPortDescriptor; UINT16 PciCmd; UINT32 *PortStatus; UINT32 *UsbCmd; UINT32 *UsbStatus; UINT32 *UsbHCSParam; UINT8 DebugPortNumber; UINT8 Length; UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset); PciCmd = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET); UsbHCSParam = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x04); UsbCmd = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x20); UsbStatus = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x24); // // Check if the debug port is enabled and owned by myself. // if (((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE)) != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE)) || (Handle->Initialized == USBDBG_RESET)) { DEBUG (( EFI_D_INFO, "UsbDbg: Need to reset the host controller. ControlStatus = %08x\n", MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) )); // // If the host controller is halted, then reset and restart it. // if ((MmioRead32((UINTN)UsbStatus) & BIT12) != 0) { DEBUG ((EFI_D_INFO, "UsbDbg: Reset the host controller.\n")); // // reset the host controller. // MmioOr32((UINTN)UsbCmd, BIT1); // // ensure that the host controller is reset. // while ((MmioRead32((UINTN)UsbCmd) & BIT1) != 0); MmioOr32((UINTN)UsbCmd, BIT0); // ensure that the host controller is started (HALTED bit must be cleared) while ((MmioRead32((UINTN)UsbStatus) & BIT12) != 0); } // // First get the ownership of port 0. // MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE); MicroSecondDelay (200000); } // // Find out which port is used as debug port. // DebugPortNumber = (UINT8)((MmioRead32((UINTN)UsbHCSParam) & 0x00F00000) >> 20); // // Should find a device is connected at debug port // PortStatus = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x64 + (DebugPortNumber - 1) * 4); if (!(MmioRead32((UINTN)PortStatus) & BIT0)) { Handle->Initialized = USBDBG_NO_DEV; return RETURN_NOT_FOUND; } if (Handle->Initialized != USBDBG_INIT_DONE || (MmioRead32 ((UINTN) &UsbDebugPortRegister->ControlStatus) & USB_DEBUG_PORT_ENABLE) == 0) { DEBUG ((EFI_D_INFO, "UsbDbg: Reset the debug port.\n")); // // Reset the debug port // MmioOr32((UINTN)PortStatus, BIT8); MicroSecondDelay (500000); MmioAnd32((UINTN)PortStatus, (UINT32)~BIT8); while (MmioRead32((UINTN)PortStatus) & BIT8); // // The port enabled bit should be set by HW. // if ((MmioRead32((UINTN)PortStatus) & BIT2) == 0) { Handle->Initialized = USBDBG_NO_DBG_CAB; return RETURN_DEVICE_ERROR; } // // Enable Usb Debug Port Capability // MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_ENABLE); // // initialize the data toggle used by bulk in/out endpoint. // Handle->BulkInToggle = 0; Handle->BulkOutToggle = 0; // // set usb debug device address as 0x7F. // Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mSetDebugAddress, 0x0, 0x0, NULL, NULL); if (RETURN_ERROR(Status)) { // // The device can not work well. // Handle->Initialized = USBDBG_NO_DBG_CAB; return Status; } // // Start to communicate with Usb Debug Device to see if the attached device is usb debug device or not. // Length = (UINT8)sizeof (USB_DEBUG_PORT_DESCRIPTOR); // // Get debug descriptor. // Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mGetDebugDescriptor, 0x7F, 0x0, (UINT8*)&UsbDebugPortDescriptor, &Length); if (RETURN_ERROR(Status)) { // // The device is not a usb debug device. // Handle->Initialized = USBDBG_NO_DBG_CAB; return Status; } if (Length != sizeof(USB_DEBUG_PORT_DESCRIPTOR)) { Handle->Initialized = USBDBG_NO_DBG_CAB; return RETURN_DEVICE_ERROR; } // // enable the usb debug feature. // Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mSetDebugFeature, 0x7F, 0x0, NULL, NULL); if (RETURN_ERROR(Status)) { // // The device can not work well. // Handle->Initialized = USBDBG_NO_DBG_CAB; return Status; } Handle->Initialized = USBDBG_DBG_CAB; } // // Set initialized flag // Handle->Initialized = USBDBG_INIT_DONE; return RETURN_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; // 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; }
/** This function enables I2C controllers. @param I2cControllerIndex Bus Number of I2C controllers. @return Result of the I2C initialization. **/ EFI_STATUS ProgramPciLpssI2C ( IN UINT8 I2cControllerIndex ) { UINT32 PmcBase; UINTN PciMmBase=0; EFI_STATUS Status; EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; UINT32 PmcFunctionDsiable[]= { B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7 }; DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Start\n")); // // Set the VLV Function Disable Register to ZERO // PmcBase = MmioRead32 (PCI_D31F0_REG_BASE + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR; if(MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)&PmcFunctionDsiable[I2cControllerIndex]) { DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End:I2C[%x] is disabled\n",I2cControllerIndex)); return EFI_NOT_READY; } DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C()------------I2cControllerIndex=%x,PMC=%x\n",I2cControllerIndex,MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS))); { PciMmBase = MmPciAddress ( mLpssPciDeviceList[I2cControllerIndex+1].Segment, mLpssPciDeviceList[I2cControllerIndex+1].BusNum, mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, 0 ); DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device %x %x %x PciMmBase:%x\n", \ mLpssPciDeviceList[I2cControllerIndex+1].BusNum, \ mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, \ mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, PciMmBase)); if (MmioRead32 (PciMmBase) != 0xFFFFFFFF) { if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) { // // Get the address allocted. // mLpssPciDeviceList[I2cControllerIndex+1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR); mLpssPciDeviceList[I2cControllerIndex+1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1); DEBUG((EFI_D_ERROR, "ProgramPciLpssI2C() bar0:0x%x bar1:0x%x\n",mLpssPciDeviceList[I2cControllerIndex+1].Bar0, mLpssPciDeviceList[I2cControllerIndex+1].Bar1)); } else { // // Program BAR 0 // ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar0) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 != 0)); MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA)); // // Program BAR 1 // ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar1) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 != 0)); MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA)); // // Bus Master Enable & Memory Space Enable // MmioOr32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32) (B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE)); ASSERT (MmioRead32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0) != 0xFFFFFFFF); } // // Release Resets // MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPIO_I2C_MEM_RESETS,(B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB)); // // Activate Clocks // MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPSS_I2C_MEM_PCP,0x80020003);//No use for A0 DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n")); } // // BDS: already switched to ACPI mode // else { ASSERT(gBS!=NULL); Status = gBS->LocateProtocol ( &gEfiGlobalNvsAreaProtocolGuid, NULL, &GlobalNvsArea ); if (EFI_ERROR(Status)) { DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status)); // // gEfiGlobalNvsAreaProtocolGuid is not ready. // return 0; } mLpssPciDeviceList[I2cControllerIndex + 1].Bar0 = *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]); DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C(): is switched to ACPI 0x:%x \n",mLpssPciDeviceList[I2cControllerIndex + 1].Bar0)); } } DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End\n")); return EFI_SUCCESS; }