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