예제 #1
0
/**
  Detect board revision

  @return Board revision
**/
BEAGLEBOARD_REVISION
BeagleBoardGetRevision (
  VOID
  )
{
  UINT32 OldPinDir;
  UINT32 Revision;

  // Read GPIO 171, 172, 173
  OldPinDir = MmioRead32 (GPIO6_BASE + GPIO_OE);
  MmioWrite32(GPIO6_BASE + GPIO_OE, (OldPinDir | BIT11 | BIT12 | BIT13));
  Revision = MmioRead32 (GPIO6_BASE + GPIO_DATAIN);

  // Restore I/O settings
  MmioWrite32 (GPIO6_BASE + GPIO_OE, OldPinDir);

  return (BEAGLEBOARD_REVISION)((Revision >> 11) & 0x7);
}
예제 #2
0
VOID
EFIAPI
ArmGicEnableDistributor (
  IN  INTN          GicDistributorBase
  )
{
  // Turn on the GIC distributor
  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);
}
RETURN_STATUS
AccessSysCfgRegister (
  IN     UINT32   ReadWrite,
  IN     UINT32   Function,
  IN     UINT32   Site,
  IN     UINT32   Position,
  IN     UINT32   Device,
  IN OUT UINT32*  Data
  )
{
  UINT32          SysCfgCtrl;

  if (EfiAtRuntime ()) {
    return RETURN_UNSUPPORTED;
  }

  // Clear the COMPLETE bit
  MmioAnd32(ARM_VE_SYS_CFGSTAT_REG, ~SYS_CFGSTAT_COMPLETE);

  // If writing, then set the data value
  if(ReadWrite == SYS_CFGCTRL_WRITE) {
    MmioWrite32(ARM_VE_SYS_CFGDATA_REG, *Data);
  }

  // Set the control value
  SysCfgCtrl = SYS_CFGCTRL_START | ReadWrite | SYS_CFGCTRL_FUNCTION(Function) | SYS_CFGCTRL_SITE(Site) |
      SYS_CFGCTRL_POSITION(Position) | SYS_CFGCTRL_DEVICE(Device);
  MmioWrite32(ARM_VE_SYS_CFGCTRL_REG, SysCfgCtrl);

  // Wait until the COMPLETE bit is set
  while ((MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_COMPLETE) == 0);

  // Check for errors
  if(MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_ERROR) {
    return RETURN_DEVICE_ERROR;
  }

  // If reading then get the data value
  if(ReadWrite == SYS_CFGCTRL_READ) {
    *Data = MmioRead32(ARM_VE_SYS_CFGDATA_REG);
  }

  return RETURN_SUCCESS;
}
예제 #4
0
EFI_STATUS
EFIAPI
BootLinuxConfig (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
    DEBUG((EFI_D_ERROR,"SMMU CONFIG........."));
    SmmuConfigForLinux();
    DEBUG((EFI_D_ERROR,"Done\n"));

    DEBUG((EFI_D_ERROR,"ITS CONFIG........."));
	ITSCONFIG();
    DEBUG((EFI_D_ERROR,"Done\n"));

    DEBUG((EFI_D_ERROR,"AP CONFIG........."));
    MmioWrite64(FixedPcdGet64(PcdMailBoxAddress), 0x0);
    (void)WriteBackInvalidateDataCacheRange((VOID *) FixedPcdGet64(PcdMailBoxAddress), 8);
    asm("DSB SY");
    asm("ISB");

    CoreSelectBoot();

DEBUG((EFI_D_ERROR,"Done\n"));

    DEBUG((EFI_D_ERROR,"MN CONFIG........."));
    MN_CONFIG ();
    DEBUG((EFI_D_ERROR,"Done\n"));

    DEBUG((EFI_D_ERROR,"RTC CONFIG........."));
    
    MmioWrite32(0xA00021F0, 0xF);

    DEBUG((EFI_D_ERROR,"Done\n"));

    DEBUG((EFI_D_ERROR,"Tsensor CONFIG........."));
    
    MmioWrite32(0x80010000 + 0x5000, 0x1);
    *(volatile UINT32*)0xA0000A8C = 0x1f;

    DEBUG((EFI_D_ERROR,"Done\n"));

    return EFI_SUCCESS;
}
예제 #5
0
STATIC
EFI_STATUS
NorFlashWriteSingleWord (
  IN NOR_FLASH_INSTANCE     *Instance,
  IN UINTN                  WordAddress,
  IN UINT32                 WriteData
  )
{
  EFI_STATUS            Status;
  UINT32                StatusRegister;

  Status = EFI_SUCCESS;

  // Request a write single word command
  SEND_NOR_COMMAND(WordAddress, 0, P30_CMD_WORD_PROGRAM_SETUP);

  // Store the word into NOR Flash;
  MmioWrite32 (WordAddress, WriteData);

  // Wait for the write to complete and then check for any errors; i.e. check the Status Register
  do {
    // Prepare to read the status register
    StatusRegister = NorFlashReadStatusRegister (Instance, WordAddress);
    // The chip is busy while the WRITE bit is not asserted
  } while ((StatusRegister & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE);


  // Perform a full status check:
  // Mask the relevant bits of Status Register.
  // Everything should be zero, if not, we have a problem

  if (StatusRegister & P30_SR_BIT_VPP) {
    DEBUG((EFI_D_ERROR,"NorFlashWriteSingleWord(WordAddress:0x%X): VPP Range Error\n",WordAddress));
    Status = EFI_DEVICE_ERROR;
  }

  if (StatusRegister & P30_SR_BIT_PROGRAM) {
    DEBUG((EFI_D_ERROR,"NorFlashWriteSingleWord(WordAddress:0x%X): Program Error\n",WordAddress));
    Status = EFI_DEVICE_ERROR;
  }

  if (StatusRegister & P30_SR_BIT_BLOCK_LOCKED) {
    DEBUG((EFI_D_ERROR,"NorFlashWriteSingleWord(WordAddress:0x%X): Device Protect Error\n",WordAddress));
    Status = EFI_DEVICE_ERROR;
  }

  if (!EFI_ERROR(Status)) {
    // Clear the Status Register
    SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_CLEAR_STATUS_REGISTER);
  }

  // Put device back into Read Array mode
  SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);

  return Status;
}
예제 #6
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.

**/
STATIC
EFI_STATUS
EFIAPI
SP805SetTimerPeriod (
  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL         *This,
  IN UINT64                                   TimerPeriod   // In 100ns units
  )
{
  EFI_STATUS  Status;
  UINT64      Ticks64bit;

  SP805Unlock ();

  Status = EFI_SUCCESS;

  if (TimerPeriod == 0) {
    // This is a watchdog stop request
    SP805Stop ();
  } else {
    // Calculate the Watchdog ticks required for a delay of (TimerTicks * 100) nanoseconds
    // The SP805 will count down to zero and generate an interrupt.
    //
    // WatchdogTicks = ((TimerPeriod * 100 * SP805_CLOCK_FREQUENCY) / 1GHz);
    //
    // i.e.:
    //
    // WatchdogTicks = (TimerPeriod * SP805_CLOCK_FREQUENCY) / 10 MHz ;

    Ticks64bit = MultU64x32 (TimerPeriod, PcdGet32 (PcdSP805WatchdogClockFrequencyInHz));
    Ticks64bit = DivU64x32 (Ticks64bit, 10 * 1000 * 1000);

    // The registers in the SP805 are only 32 bits
    if (Ticks64bit > MAX_UINT32) {
      // We could load the watchdog with the maximum supported value but
      // if a smaller value was requested, this could have the watchdog
      // triggering before it was intended.
      // Better generate an error to let the caller know.
      Status = EFI_DEVICE_ERROR;
      goto EXIT;
    }

    // Update the watchdog with a 32-bit value.
    MmioWrite32 (SP805_WDOG_LOAD_REG, (UINT32)Ticks64bit);

    // Start the watchdog
    SP805Start ();
  }

  mTimerPeriod = TimerPeriod;

EXIT:
  // Ensure the watchdog is locked before exiting.
  SP805Lock ();
  ASSERT_EFI_ERROR (Status);
  return Status;
}
예제 #7
0
/**
  Writes a 32-bit PCI configuration register.

  Writes the 32-bit PCI configuration register specified by Address with the
  value specified by Value. Value 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  Value   The value to write.

  @return The value written to the PCI configuration register.

**/
UINT32
EFIAPI
PciExpressWrite32 (
  IN      UINTN                     Address,
  IN      UINT32                    Value
  )
{
  ASSERT_INVALID_PCI_ADDRESS (Address);
  return MmioWrite32 ((UINTN) GetPciExpressBaseAddress () + Address, Value);
}
예제 #8
0
EFI_STATUS
OhciSetOperationalReg (
  USB_OHCI_HC_DEV         *Ohc,
  IN UINT32               Offset,
  IN UINT32               *Value
  )
{
  MmioWrite32(Ohc->UsbHostControllerBaseAddress + Offset, *Value);
  return EFI_SUCCESS;
}
예제 #9
0
/**
  Make sure the SP805 registers are unlocked for writing.

  Note: The SP805 Watchdog Timer supports locking of its registers,
  i.e. it inhibits all writes to avoid rogue software accidentally
  corrupting their contents.
**/
STATIC
VOID
SP805Unlock (
  VOID
  )
{
  if (MmioRead32 (SP805_WDOG_LOCK_REG) == SP805_WDOG_LOCK_IS_LOCKED) {
    MmioWrite32 (SP805_WDOG_LOCK_REG, SP805_WDOG_SPECIAL_UNLOCK_CODE);
  }
}
예제 #10
0
파일: ArmGicSec.c 프로젝트: B-Rich/edk2
/*
 * This function configures the all interrupts to be Non-secure.
 *
 */
VOID
EFIAPI
ArmGicSetupNonSecure (
  IN  UINTN         MpId,
  IN  INTN          GicDistributorBase,
  IN  INTN          GicInterruptInterfaceBase
  )
{
  UINTN InterruptId;
  UINTN CachedPriorityMask;
  UINTN Index;

  CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);

  // Set priority Mask so that no interrupts get through to CPU
  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);

  InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);

  // Only try to clear valid interrupts. Ignore spurious interrupts.
  while ((InterruptId & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase))   {
    // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
    MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);

    // Next
    InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
  }

  // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
  if (ArmPlatformIsPrimaryCore (MpId)) {
    // Ensure all GIC interrupts are Non-Secure
    for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {
      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
    }
  } else {
    // The secondary cores only set the Non Secure bit to their banked PPIs
    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);
  }

  // Ensure all interrupts can get through the priority mask
  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);
}
예제 #11
0
파일: Gpio.c 프로젝트: B-Rich/edk2
EFI_STATUS
Set (
  IN  EMBEDDED_GPIO       *This,
  IN  EMBEDDED_GPIO_PIN   Gpio,
  IN  EMBEDDED_GPIO_MODE  Mode
  )
{
  UINTN  Port;
  UINTN  Pin;
  UINT32 OutputEnableRegister;
  UINT32 SetDataOutRegister;
  UINT32 ClearDataOutRegister;

  Port    = GPIO_PORT(Gpio);
  Pin     = GPIO_PIN(Gpio);

  OutputEnableRegister = GpioBase(Port) + GPIO_OE;
  SetDataOutRegister   = GpioBase(Port) + GPIO_SETDATAOUT;
  ClearDataOutRegister = GpioBase(Port) + GPIO_CLEARDATAOUT;

  switch (Mode)
  {
    case GPIO_MODE_INPUT:
      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_INPUT(Pin));
      break;

    case GPIO_MODE_OUTPUT_0:
      MmioWrite32 (ClearDataOutRegister, GPIO_CLEARDATAOUT_BIT(Pin));
      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin));
      break;

    case GPIO_MODE_OUTPUT_1:
      MmioWrite32 (SetDataOutRegister, GPIO_SETDATAOUT_BIT(Pin));
      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin));
      break;

    default:
      return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}
예제 #12
0
/**
  Shutdown our hardware

  DXE Core will disable interrupts and turn off the timer and disable interrupts
  after all the event handlers have run.

  @param[in]  Event   The Event that is being processed
  @param[in]  Context Event Context
**/
STATIC
VOID
EFIAPI
ExitBootServicesEvent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  // Disable all interrupts
  MmioWrite32 (RegBase + BCM2836_INTC_TIMER_CONTROL_OFFSET, 0);
}
예제 #13
0
/**
  Write a 32-bit I/O APIC register.

  If Index is >= 0x100, then ASSERT().
  
  @param  Index  Specifies the I/O APIC register to write.
  @param  Value  Specifies the value to write to the I/O APIC register specified by Index.

  @return  The 32-bit value written to I/O APIC register specified by Index.
**/
UINT32
EFIAPI
IoApicWrite (
  IN UINTN   Index,
  IN UINT32  Value
  )
{
  ASSERT (Index < 0x100);
  MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index);
  return MmioWrite32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET, Value);
}
예제 #14
0
/**
  Make sure the SP805 registers are locked and can not be overwritten.

  Note: The SP805 Watchdog Timer supports locking of its registers,
  i.e. it inhibits all writes to avoid rogue software accidentally
  corrupting their contents.
**/
STATIC
VOID
SP805Lock (
  VOID
  )
{
  if (MmioRead32 (SP805_WDOG_LOCK_REG) == SP805_WDOG_LOCK_IS_UNLOCKED) {
    // To lock it, just write in any number (except the special unlock code).
    MmioWrite32 (SP805_WDOG_LOCK_REG, SP805_WDOG_LOCK_IS_LOCKED);
  }
}
예제 #15
0
VOID
EFIAPI
ArmGicSendSgiTo (
  IN  INTN          GicDistributorBase,
  IN  INTN          TargetListFilter,
  IN  INTN          CPUTargetList,
  IN  INTN          SgiId
  )
{
  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);
}
예제 #16
0
/**
  Signal to the hardware that the End Of Intrrupt state 
  has been reached.

  @param This     Instance pointer for this protocol
  @param Source   Hardware source of the interrupt

  @retval EFI_SUCCESS       Source interrupt EOI'ed.
  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

**/
EFI_STATUS
EFIAPI
EndOfInterrupt (
  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
  IN HARDWARE_INTERRUPT_SOURCE          Source
  )
{
  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
  ArmDataSyncronizationBarrier ();
  return EFI_SUCCESS;
}
예제 #17
0
파일: CpuIoPei.c 프로젝트: shijunjing/edk2
/**
  32-bit memory write operations.

  @param[in] PeiServices  An indirect pointer to the PEI Services Table published
                          by the PEI Foundation.
  @param[in] This         Pointer to local data for the interface.
  @param[in] Address      The physical address of the access.
  @param[in] Data         The data to write.

**/
VOID
EFIAPI
CpuMemWrite32 (
  IN CONST EFI_PEI_SERVICES    **PeiServices,
  IN CONST EFI_PEI_CPU_IO_PPI  *This,
  IN UINT64                    Address,
  IN UINT32                    Data
  )
{
  MmioWrite32 ((UINTN)Address, Data);
}
예제 #18
0
/*
 * This function configures the all interrupts to be Non-secure.
 *
 */
VOID
EFIAPI
ArmGicSetupNonSecure (
  IN  UINTN         MpId,
  IN  INTN          GicDistributorBase,
  IN  INTN          GicInterruptInterfaceBase
  )
{
  UINTN InterruptId;
  UINTN CachedPriorityMask;
  UINTN Index;

  CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);

  // Set priority Mask so that no interrupts get through to CPU
  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);

  // Check if there are any pending interrupts
  //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.
  while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) {
    // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
    InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);

    // Write to End of interrupt signal
    MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);
  }

  // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
  if (IS_PRIMARY_CORE(MpId)) {
    // Ensure all GIC interrupts are Non-Secure
    for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {
      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
    }
  } else {
    // The secondary cores only set the Non Secure bit to their banked PPIs
    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);
  }

  // Ensure all interrupts can get through the priority mask
  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);
}
예제 #19
0
파일: Platform.c 프로젝트: chinni1989/edk2
UINT32 
DetermineCompatibleBoard (
  void
  )
{
  UINTN PciD31F0RegBase = 0;
  UINT32 GpioValue = 0;
  UINT32 TmpVal = 0;
  UINT32 MmioConf0 = 0;
  UINT32 MmioPadval = 0;
  UINT32 PConf0Offset = 0x200; //GPIO_S5_4 pad_conf0 register offset
  UINT32 PValueOffset = 0x208; //GPIO_S5_4 pad_value register offset
  UINT32 SSUSOffset = 0x2000;
  UINT32 IoBase = 0;

  DEBUG ((EFI_D_ERROR, "DetermineCompatibleBoard() Entry\n"));
  PciD31F0RegBase = MmPciAddress (0,
                      0,
                      PCI_DEVICE_NUMBER_PCH_LPC,
                      PCI_FUNCTION_NUMBER_PCH_LPC,
                      0
                    );
  IoBase = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR;
  
  MmioConf0 = IoBase + SSUSOffset + PConf0Offset;
  MmioPadval = IoBase + SSUSOffset + PValueOffset;
  //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of GPIO_S5_4
  DEBUG ((EFI_D_ERROR, "MmioConf0[0x%x], MmioPadval[0x%x]\n", MmioConf0, MmioPadval));
  
  MmioWrite32 (MmioConf0, 0x2003CC00);  

  TmpVal = MmioRead32 (MmioPadval);
  TmpVal &= ~0x6; //Clear bit 1:2
  TmpVal |= 0x2; // Set the pin as GPI
  MmioWrite32 (MmioPadval, TmpVal); 

  GpioValue = MmioRead32 (MmioPadval);

  DEBUG ((EFI_D_ERROR, "Gpio_S5_4 value is 0x%x\n", GpioValue));
  return (GpioValue & 0x1);
}
예제 #20
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
SP805SetTimerPeriod (
  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL   *This,
  IN UINT64                                   TimerPeriod   // In 100ns units
  )
{
  EFI_STATUS  Status = EFI_SUCCESS;
  UINT64      Ticks64bit;

  SP805Unlock();

  if( TimerPeriod == 0 ) {
    // This is a watchdog stop request
    SP805Stop();
    goto EXIT;
  } else {
    // Calculate the Watchdog ticks required for a delay of (TimerTicks * 100) nanoseconds
    // The SP805 will count down to ZERO once, generate an interrupt and
    // then it will again reload the initial value and start again.
    // On the second time when it reaches ZERO, it will actually reset the board.
    // Therefore, we need to load half the required delay.
    //
    // WatchdogTicks = ((TimerPeriod * 100 * SP805_CLOCK_FREQUENCY) / 1GHz) / 2 ;
    //
    // i.e.:
    //
    // WatchdogTicks = (TimerPeriod * SP805_CLOCK_FREQUENCY) / 20 MHz ;

    Ticks64bit = DivU64x32(MultU64x32(TimerPeriod, (UINTN)PcdGet32(PcdSP805WatchdogClockFrequencyInHz)), 20000000);

    // The registers in the SP805 are only 32 bits
    if(Ticks64bit > (UINT64)0xFFFFFFFF) {
      // We could load the watchdog with the maximum supported value but
      // if a smaller value was requested, this could have the watchdog
      // triggering before it was intended.
      // Better generate an error to let the caller know.
      Status = EFI_DEVICE_ERROR;
      goto EXIT;
    }

    // Update the watchdog with a 32-bit value.
    MmioWrite32(SP805_WDOG_LOAD_REG, (UINT32)Ticks64bit);

    // Start the watchdog
    SP805Start();
  }

  EXIT:
  // Ensure the watchdog is locked before exiting.
  SP805Lock();
  return Status;
}
예제 #21
0
파일: ArmGicSec.c 프로젝트: B-Rich/edk2
VOID
EFIAPI
ArmGicDisableInterruptInterface (
  IN  INTN          GicInterruptInterfaceBase
  )
{
  UINT32    ControlValue;

  // Disable CPU interface in Secure world and Non-secure World
  ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);
  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));
}
예제 #22
0
파일: BaseXApicLib.c 프로젝트: etiago/vbox
/**
  Write to a local APIC register.

  This function writes to a local APIC register either in xAPIC or x2APIC mode.
  It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be
  accessed using multiple 32-bit loads or stores, so this function only performs
  32-bit write.

  if the register index is invalid or unsupported in current APIC mode, then ASSERT.

  @param  MmioOffset  The MMIO offset of the local APIC register in xAPIC mode.
                      It must be 16-byte aligned.
  @param  Value       Value to be written to the register.
**/
VOID
EFIAPI
WriteLocalApicReg (
  IN UINTN  MmioOffset,
  IN UINT32 Value
  )
{
  ASSERT ((MmioOffset & 0xf) == 0);
  ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC);

  MmioWrite32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset, Value);
}
예제 #23
0
파일: Sec.c 프로젝트: AshleyDeSimone/edk2
VOID
TimerInit (
  VOID
  )
{
  UINTN  Timer            = FixedPcdGet32(PcdOmap35xxFreeTimer);
  UINT32 TimerBaseAddress = TimerBase(Timer);

  // Set source clock for GPT3 & GPT4 to SYS_CLK
  MmioOr32 (CM_CLKSEL_PER, CM_CLKSEL_PER_CLKSEL_GPT3_SYS | CM_CLKSEL_PER_CLKSEL_GPT4_SYS);

  // Set count & reload registers
  MmioWrite32 (TimerBaseAddress + GPTIMER_TCRR, 0x00000000);
  MmioWrite32 (TimerBaseAddress + GPTIMER_TLDR, 0x00000000);

  // Disable interrupts
  MmioWrite32 (TimerBaseAddress + GPTIMER_TIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_DISABLE | TIER_MAT_IT_DISABLE);

  // Start Timer
  MmioWrite32 (TimerBaseAddress + GPTIMER_TCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);

  //Disable OMAP Watchdog timer (WDT2)
  MmioWrite32 (WDTIMER2_BASE + WSPR, 0xAAAA);
  DEBUG ((EFI_D_ERROR, "Magic delay to disable watchdog timers properly.\n"));
  MmioWrite32 (WDTIMER2_BASE + WSPR, 0x5555);
}
예제 #24
0
파일: Timer.c 프로젝트: AshleyDeSimone/edk2
/**

  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      TimerCount;
  INT32       LoadValue;
  
  if (TimerPeriod == 0) {
    // Turn off GPTIMER3
    MmioWrite32 (TCLR, TCLR_ST_OFF);
    
    Status = gInterrupt->DisableInterruptSource(gInterrupt, gVector);    
  } else {  
    // Calculate required timer count
    TimerCount = DivU64x32(TimerPeriod * 100, PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds));

    // Set GPTIMER3 Load register
    LoadValue = (INT32) -TimerCount;
    MmioWrite32 (TLDR, LoadValue);
    MmioWrite32 (TCRR, LoadValue);

    // Enable Overflow interrupt
    MmioWrite32 (TIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE);

    // Turn on GPTIMER3, it will reload at overflow
    MmioWrite32 (TCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);

    Status = gInterrupt->EnableInterruptSource(gInterrupt, gVector);    
  }

  //
  // Save the new timer period
  //
  mTimerPeriod = TimerPeriod;
  return Status;
}
예제 #25
0
파일: EhcPeim.c 프로젝트: bhanug/virtualbox
/**
  Write the data to the EHCI operation register.

  @param  Ehc       The EHCI device.
  @param  Offset    EHCI operation register offset.
  @param  Data      The data to write.

**/
VOID
EhcWriteOpReg (
  IN PEI_USB2_HC_DEV      *Ehc,
  IN UINT32               Offset,
  IN UINT32               Data
  )
{

  ASSERT (Ehc->CapLen != 0);

  MmioWrite32(Ehc->UsbHostControllerBaseAddress + Ehc->CapLen + Offset, Data);

}
예제 #26
0
VOID
DisableInterruptSource (
  VOID
  )
{
  UINTN Bank;
  UINTN Bit;

  Bank = gVector / 32;
  Bit  = 1UL << (gVector % 32);

  MmioWrite32 (INTCPS_MIR_SET(Bank), Bit);
}
예제 #27
0
/**
  Set PTP interface type.

  @param[in] Register                Pointer to PTP register.
  @param[in] PtpInterface            PTP interface type.
  
  @retval EFI_SUCCESS                PTP interface type is set.
  @retval EFI_INVALID_PARAMETER      PTP interface type is invalid.
  @retval EFI_UNSUPPORTED            PTP interface type is unsupported.
  @retval EFI_WRITE_PROTECTED        PTP interface is locked.
**/
EFI_STATUS
SetPtpInterface (
  IN VOID                 *Register,
  IN UINT8                PtpInterface
  )
{
  UINT8                         PtpInterfaceCurrent;
  PTP_CRB_INTERFACE_IDENTIFIER  InterfaceId;

  PtpInterfaceCurrent = GetPtpInterface (Register);
  if ((PtpInterfaceCurrent != TPM_DEVICE_INTERFACE_PTP_FIFO) && 
      (PtpInterfaceCurrent != TPM_DEVICE_INTERFACE_PTP_CRB)) {
    return EFI_UNSUPPORTED;
  }
  InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
  if (InterfaceId.Bits.IntfSelLock != 0) {
    return EFI_WRITE_PROTECTED;
  }

  switch (PtpInterface) {
  case TPM_DEVICE_INTERFACE_PTP_FIFO:
    if (InterfaceId.Bits.CapFIFO == 0) {
      return EFI_UNSUPPORTED;
    }
    InterfaceId.Bits.InterfaceSelector = PTP_INTERFACE_IDENTIFIER_INTERFACE_SELECTOR_FIFO;
    MmioWrite32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId, InterfaceId.Uint32);
    return EFI_SUCCESS;
  case TPM_DEVICE_INTERFACE_PTP_CRB:
    if (InterfaceId.Bits.CapCRB == 0) {
      return EFI_UNSUPPORTED;
    }
    InterfaceId.Bits.InterfaceSelector = PTP_INTERFACE_IDENTIFIER_INTERFACE_SELECTOR_CRB;
    MmioWrite32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId, InterfaceId.Uint32);
    return EFI_SUCCESS;
  default:
    return EFI_INVALID_PARAMETER;
  }
}
예제 #28
0
/**
  Sets the system wakeup alarm clock time.

  @param  Enabled               Enable or disable the wakeup alarm.
  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.

  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
                                Enable is FALSE, then the wakeup alarm was disabled.
  @retval EFI_INVALID_PARAMETER A time field is out of range.
  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

**/
EFI_STATUS
EFIAPI
LibSetWakeupTime (
  IN BOOLEAN      Enabled,
  OUT EFI_TIME    *Time
  )
{
  UINT32      WakeupSeconds;

  // Convert time to raw seconds
  WakeupSeconds = EfiTimeToEpoch (Time);

  // Issue delayed write to alarm register
  RtcDelayedWrite (RTC_ALARM_2_REG, WakeupSeconds);

  if (Enabled) {
    MmioWrite32 (mArmadaRtcBase + RTC_IRQ_2_CONFIG_REG, RTC_IRQ_ALARM_EN);
  } else {
    MmioWrite32 (mArmadaRtcBase + RTC_IRQ_2_CONFIG_REG, 0);
  }

  return EFI_SUCCESS;
}
예제 #29
0
VOID
EFIAPI
ArmGicEnableDistributor (
  IN  INTN          GicDistributorBase
  )
{
  ARM_GIC_ARCH_REVISION Revision;

  /*
   * Enable GIC distributor in Non-Secure world.
   * Note: The ICDDCR register is banked when Security extensions are implemented
   */
  Revision = ArmGicGetSupportedArchRevision ();
  if (Revision == ARM_GIC_ARCH_REVISION_2) {
    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
  } else {
    if (MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_ARE) {
      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
    } else {
      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
    }
  }
}
예제 #30
0
STATIC
VOID
InitializeSataPorts (
  EFI_PHYSICAL_ADDRESS    AhciBaseAddr,
  UINTN                   PortCount
  )
{
  INTN                    PortNum;
  BOOLEAN                 IsCpd;
  BOOLEAN                 IsMpsp;
  UINT32                  PortRegAddr;
  UINT32                  RegVal;

  // Set Ports Implemented (PI)
  MmioWrite32 (AhciBaseAddr + EFI_AHCI_PI_OFFSET, (1 << PortCount) - 1);

  IsCpd = FixedPcdGetBool (PcdSataPortCpd);
  IsMpsp = FixedPcdGetBool (PcdSataPortMpsp);
  if (!IsCpd && !IsMpsp) {
    return;
  }

  for (PortNum = 0; PortNum < PortCount; PortNum++) {
    PortRegAddr = EFI_AHCI_PORT_OFFSET (PortNum) + EFI_AHCI_PORT_CMD;
    RegVal = MmioRead32(AhciBaseAddr + PortRegAddr);
    if (IsCpd)
      RegVal |= EFI_AHCI_PORT_CMD_CPD;
    else
      RegVal &= ~EFI_AHCI_PORT_CMD_CPD;
    if (IsMpsp)
      RegVal |= EFI_AHCI_PORT_CMD_MPSP;
    else
      RegVal &= ~EFI_AHCI_PORT_CMD_MPSP;
    RegVal |= EFI_AHCI_PORT_CMD_HPCP;
    MmioWrite32(AhciBaseAddr + PortRegAddr, RegVal);
  }
}