1/** @file 2 3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR> 4 5 6 This program and the accompanying materials are licensed and made available under 7 8 the terms and conditions of the BSD License that accompanies this distribution. 9 10 The full text of the license may be found at 11 12 http://opensource.org/licenses/bsd-license.php. 13 14 15 16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 20 21 22 23Module Name: 24 25 26 LegacyMetronome.c 27 28Abstract: 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// 39EFI_HANDLE mMetronomeHandle = NULL; 40 41// 42// The Metronome Architectural Protocol instance produced by this driver 43// 44EFI_METRONOME_ARCH_PROTOCOL mMetronome = { 45 WaitForTick, 46 TICK_PERIOD 47}; 48 49// 50// The CPU I/O Protocol used to access system hardware 51// 52EFI_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**/ 67VOID 68ScriptWriteIo8 ( 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**/ 92UINT8 93ReadRefresh ( 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**/ 121EFI_STATUS 122EFIAPI 123WaitForTick ( 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**/ 154EFI_STATUS 155EFIAPI 156InstallLegacyMetronome ( 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