Example #1
0
/**
  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);
}
Example #2
0
/**
  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);
}
Example #3
0
/**
  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);
  }
}
Example #4
0
/**
  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;
}
Example #5
0
/**
  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;
}
Example #6
0
/**
  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;
}
Example #9
0
/**
  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;
}
Example #10
0
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;
}
Example #11
0
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);
}
Example #12
0
/**

  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;
}
Example #13
0
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);
}
Example #14
0
/**
  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
    }
}
Example #15
0
/**
  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;
}
Example #16
0
/**
  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;
}
Example #17
0
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;
}
Example #18
0
/**
  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;
}
Example #19
0
/**
  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;
}
Example #21
0
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);
}
Example #22
0
/**
  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;
}
Example #23
0
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;
}
Example #24
0
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;
}
Example #25
0
/**
  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;
}
Example #26
0
/**
  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;
}
Example #27
0
/**
  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;
}