Home | History | Annotate | Download | only in Metronome
      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   LegacyMetronome.c
     27 
     28 Abstract:
     29 
     30   This contains the installation function for the driver.
     31 
     32 --*/
     33 
     34 #include "LegacyMetronome.h"
     35 
     36 //
     37 // Handle for the Metronome Architectural Protocol instance produced by this driver
     38 //
     39 EFI_HANDLE                  mMetronomeHandle = NULL;
     40 
     41 //
     42 // The Metronome Architectural Protocol instance produced by this driver
     43 //
     44 EFI_METRONOME_ARCH_PROTOCOL mMetronome = {
     45   WaitForTick,
     46   TICK_PERIOD
     47 };
     48 
     49 //
     50 // The CPU I/O Protocol used to access system hardware
     51 //
     52 EFI_CPU_IO_PROTOCOL         *mCpuIo = NULL;
     53 
     54 //
     55 // Worker Functions
     56 //
     57 
     58 /**
     59   Write an 8 bit value to an I/O port and save it to the S3 script
     60 
     61   @param Port  IO Port
     62   @param Data  Data in IO Port
     63 
     64   @retval None.
     65 
     66 **/
     67 VOID
     68 ScriptWriteIo8 (
     69   UINT16  Port,
     70   UINT8   Data
     71   )
     72 {
     73   mCpuIo->Io.Write (
     74                mCpuIo,
     75                EfiCpuIoWidthUint8,
     76                Port,
     77                1,
     78                &Data
     79                );
     80 
     81 }
     82 
     83 /**
     84 
     85   Read the refresh bit from the REFRESH_PORT
     86 
     87   @param None.
     88 
     89   @retval Refresh bit.
     90 
     91 **/
     92 UINT8
     93 ReadRefresh (
     94   VOID
     95   )
     96 {
     97   UINT8 Data;
     98 
     99   mCpuIo->Io.Read (
    100                mCpuIo,
    101                EfiCpuIoWidthUint8,
    102                REFRESH_PORT,
    103                1,
    104                &Data
    105                );
    106   return (UINT8) (Data & REFRESH_ON);
    107 }
    108 
    109 /**
    110 
    111   Waits for the TickNumber of ticks from a known platform time source.
    112 
    113   @param This                Pointer to the protocol instance.
    114   @param TickNumber          Tick Number to be waited
    115 
    116 
    117   @retval EFI_SUCCESS         If number of ticks occurred.
    118   @retval EFI_NOT_FOUND       Could not locate CPU IO protocol
    119 
    120 **/
    121 EFI_STATUS
    122 EFIAPI
    123 WaitForTick (
    124   IN EFI_METRONOME_ARCH_PROTOCOL  *This,
    125   IN UINT32                       TickNumber
    126   )
    127 {
    128   //
    129   // Wait for TickNumber toggles of the Refresh bit
    130   //
    131   for (; TickNumber != 0x00; TickNumber--) {
    132     while (ReadRefresh () == REFRESH_ON)
    133       ;
    134     while (ReadRefresh () == REFRESH_OFF)
    135       ;
    136   }
    137 
    138   return EFI_SUCCESS;
    139 }
    140 
    141 //
    142 // Driver Entry Point
    143 //
    144 /**
    145   Install the LegacyMetronome driver.  Loads a Metronome Arch Protocol based
    146   on the Port 61 timer.
    147 
    148   @param ImageHandle      Handle for the image of this driver
    149   @param SystemTable      Pointer to the EFI System Table
    150 
    151   @retval EFI_SUCCESS     Metronome Architectural Protocol Installed
    152 
    153 **/
    154 EFI_STATUS
    155 EFIAPI
    156 InstallLegacyMetronome (
    157   IN EFI_HANDLE        ImageHandle,
    158   IN EFI_SYSTEM_TABLE  *SystemTable
    159   )
    160 {
    161   EFI_STATUS  Status;
    162 
    163   //
    164   // Make sure the Metronome Architectural Protocol is not already installed in the system
    165   //
    166   ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMetronomeArchProtocolGuid);
    167 
    168   //
    169   // Get the CPU I/O Protocol that this driver requires
    170   // If the CPU I/O Protocol is not found, then ASSERT because the dependency expression
    171   // should guarantee that it is present in the handle database.
    172   //
    173   Status = gBS->LocateProtocol (
    174                   &gEfiCpuIoProtocolGuid,
    175                   NULL,
    176                   (void **)&mCpuIo
    177                   );
    178   ASSERT_EFI_ERROR (Status);
    179 
    180   //
    181   // Program port 61 timer 1 as refresh timer. We could use ACPI timer in the
    182   // future.
    183   //
    184   ScriptWriteIo8 (TIMER1_CONTROL_PORT, LOAD_COUNTER1_LSB);
    185   ScriptWriteIo8 (TIMER1_COUNT_PORT, COUNTER1_COUNT);
    186 
    187   //
    188   // Install on a new handle
    189   //
    190   Status = gBS->InstallMultipleProtocolInterfaces (
    191                   &mMetronomeHandle,
    192                   &gEfiMetronomeArchProtocolGuid,
    193                   &mMetronome,
    194                   NULL
    195                   );
    196   ASSERT_EFI_ERROR (Status);
    197 
    198   return Status;
    199 }
    200