Home | History | Annotate | Download | only in PlatformDxe
      1 /** @file
      2 
      3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      9   The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     13 
     15   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     21 
     23 Module Name:
     24 
     25 
     26   IchTcoReset.c
     27 
     28 Abstract:
     29   Implements the programming of events in TCO Reset
     30 
     31 
     32 --*/
     33 
     34 #include "PlatformDxe.h"
     35 #include <Protocol/TcoReset.h>
     36 #include <Protocol/HwWatchdogTimer.h>
     37 
     38 
     39 EFI_STATUS
     40 EFIAPI
     41 EnableTcoReset (
     42   IN      UINT32            *RcrbGcsSaveValue
     43   );
     44 
     45 EFI_STATUS
     46 EFIAPI
     47 DisableTcoReset (
     48   OUT     UINT32    RcrbGcsRestoreValue
     49   );
     50 
     51 EFI_TCO_RESET_PROTOCOL  mTcoResetProtocol = {
     52   EnableTcoReset,
     53   DisableTcoReset
     54 };
     55 
     56 /**
     57 
     58   Enables the TCO timer to reset the system in case of a system hang.  This is
     59   used when writing the clock registers.
     60 
     61   @param RcrbGcsSaveValue   This is the value of the RCRB GCS register before it is
     62                             changed by this procedure.  This will be used to restore
     63                             the settings of this register in PpiDisableTcoReset.
     64 
     65   @retval  EFI_STATUS
     66 
     67 **/
     68 EFI_STATUS
     69 EFIAPI
     70 EnableTcoReset (
     71   IN      UINT32            *RcrbGcsSaveValue
     72   )
     73 {
     74   UINT16          TmpWord;
     75   UINT16          AcpiBase;
     76   EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL  *WatchdogTimerProtocol;
     77   EFI_STATUS          Status;
     78   UINTN           PbtnDisableInterval = 4;  //Default value
     79 
     80   //
     81   // Get Watchdog Timer protocol.
     82   //
     83   Status = gBS->LocateProtocol (
     84                   &gEfiWatchdogTimerDriverProtocolGuid,
     85                   NULL,
     86                   (VOID **)&WatchdogTimerProtocol
     87                   );
     88 
     89   //
     90   // If the protocol is present, shut off the Timer as we enter BDS
     91   //
     92   if (!EFI_ERROR(Status)) {
     93     WatchdogTimerProtocol->RestartWatchdogTimer();
     94     WatchdogTimerProtocol->AllowKnownReset(TRUE);
     95   }
     96 
     97   if (*RcrbGcsSaveValue == 0) {
     98     PbtnDisableInterval = PcdGet32(PcdPBTNDisableInterval);
     99   } else {
    100     PbtnDisableInterval = *RcrbGcsSaveValue * 10 / 6;
    101   }
    102 
    103   //
    104   // Read ACPI Base Address
    105   //
    106   AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
    107 
    108   //
    109   // Stop TCO if not already stopped
    110   //
    111   TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
    112   TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
    113   IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
    114 
    115   //
    116   // Clear second TCO status
    117   //
    118   IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
    119 
    120   //
    121   // Enable reboot on TCO timeout
    122   //
    123   *RcrbGcsSaveValue = MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG);
    124   MmioAnd8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG, (UINT8) ~B_PCH_PMC_PM_CFG_NO_REBOOT);
    125 
    126   //
    127   // Set TCO reload value (interval *.6s)
    128   //
    129   IoWrite32(AcpiBase + R_PCH_TCO_TMR, (UINT32)(PbtnDisableInterval<<16));
    130 
    131   //
    132   // Force TCO to load new value
    133   //
    134   IoWrite8(AcpiBase + R_PCH_TCO_RLD, 4);
    135 
    136   //
    137   // Clear second TCO status
    138   //
    139   IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
    140 
    141   //
    142   // Start TCO timer running
    143   //
    144   TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
    145   TmpWord &= ~(B_PCH_TCO_CNT_TMR_HLT);
    146   IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
    147 
    148   return EFI_SUCCESS;
    149 }
    150 
    151 /**
    152   Disables the TCO timer.  This is used after writing the clock registers.
    153 
    154   @param RcrbGcsRestoreValue   Value saved in PpiEnableTcoReset so that it can
    155                                restored.
    156 
    157   @retval EFI_STATUS
    158 
    159 **/
    160 EFI_STATUS
    161 EFIAPI
    162 DisableTcoReset (
    163   OUT     UINT32    RcrbGcsRestoreValue
    164   )
    165 {
    166   UINT16          TmpWord;
    167   UINT16          AcpiBase;
    168   EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL  *WatchdogTimerProtocol;
    169   EFI_STATUS          Status;
    170 
    171   //
    172   // Read ACPI Base Address
    173   //
    174   AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
    175 
    176   //
    177   // Stop the TCO timer
    178   //
    179   TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
    180   TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
    181   IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
    182 
    183   //
    184   // Get Watchdog Timer protocol.
    185   //
    186   Status = gBS->LocateProtocol (
    187                   &gEfiWatchdogTimerDriverProtocolGuid,
    188                   NULL,
    189                   (VOID **)&WatchdogTimerProtocol
    190                   );
    191 
    192   //
    193   // If the protocol is present, shut off the Timer as we enter BDS
    194   //
    195   if (!EFI_ERROR(Status)) {
    196     WatchdogTimerProtocol->AllowKnownReset(FALSE);
    197   }
    198 
    199   return EFI_SUCCESS;
    200 }
    201 
    202 /**
    203 
    204   Updates the feature policies according to the setup variable.
    205 
    206   @retval Returns   VOID
    207 
    208 **/
    209 VOID
    210 InitTcoReset (
    211   )
    212 {
    213   EFI_HANDLE                        Handle;
    214   EFI_STATUS                        Status;
    215 
    216   Handle = NULL;
    217   Status = gBS->InstallProtocolInterface (
    218                   &Handle,
    219                   &gEfiTcoResetProtocolGuid,
    220                   EFI_NATIVE_INTERFACE,
    221                   &mTcoResetProtocol
    222                   );
    223   ASSERT_EFI_ERROR(Status);
    224 
    225 }
    226