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