1 /** @file
2
3 Copyright (c) 2013-2015 Intel Corporation.
4
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14 **/
15
16 //
17 // Include common header file for this module.
18 //
19 #include "CommonHeader.h"
20
21 #include "QNCSmm.h"
22 #include "QNCSmmHelpers.h"
23
24 //
25 // #define BIT_ZERO 0x00000001
26 //
27 CONST UINT32 BIT_ZERO = 0x00000001;
28
29 //
30 // /////////////////////////////////////////////////////////////////////////////
31 // SUPPORT / HELPER FUNCTIONS (QNC version-independent)
32 //
33 BOOLEAN
CompareEnables(CONST IN QNC_SMM_SOURCE_DESC * Src1,CONST IN QNC_SMM_SOURCE_DESC * Src2)34 CompareEnables (
35 CONST IN QNC_SMM_SOURCE_DESC *Src1,
36 CONST IN QNC_SMM_SOURCE_DESC *Src2
37 )
38 /*++
39
40 Routine Description:
41
42 GC_TODO: Add function description
43
44 Arguments:
45
46 Src1 - GC_TODO: add argument description
47 Src2 - GC_TODO: add argument description
48
49 Returns:
50
51 GC_TODO: add return values
52
53 --*/
54 {
55 BOOLEAN IsEqual;
56 UINTN loopvar;
57
58 IsEqual = TRUE;
59 for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
60 //
61 // It's okay to compare a NULL bit description to a non-NULL bit description.
62 // They are unequal and these tests will generate the correct result.
63 //
64 if (Src1->En[loopvar].Bit != Src2->En[loopvar].Bit ||
65 Src1->En[loopvar].Reg.Type != Src2->En[loopvar].Reg.Type ||
66 Src1->En[loopvar].Reg.Data.raw != Src2->En[loopvar].Reg.Data.raw
67 ) {
68 IsEqual = FALSE;
69 break;
70 //
71 // out of for loop
72 //
73 }
74 }
75
76 return IsEqual;
77 }
78
79 BOOLEAN
CompareStatuses(CONST IN QNC_SMM_SOURCE_DESC * Src1,CONST IN QNC_SMM_SOURCE_DESC * Src2)80 CompareStatuses (
81 CONST IN QNC_SMM_SOURCE_DESC *Src1,
82 CONST IN QNC_SMM_SOURCE_DESC *Src2
83 )
84 /*++
85
86 Routine Description:
87
88 GC_TODO: Add function description
89
90 Arguments:
91
92 Src1 - GC_TODO: add argument description
93 Src2 - GC_TODO: add argument description
94
95 Returns:
96
97 GC_TODO: add return values
98
99 --*/
100 {
101 BOOLEAN IsEqual;
102 UINTN loopvar;
103
104 IsEqual = TRUE;
105
106 for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
107 //
108 // It's okay to compare a NULL bit description to a non-NULL bit description.
109 // They are unequal and these tests will generate the correct result.
110 //
111 if (Src1->Sts[loopvar].Bit != Src2->Sts[loopvar].Bit ||
112 Src1->Sts[loopvar].Reg.Type != Src2->Sts[loopvar].Reg.Type ||
113 Src1->Sts[loopvar].Reg.Data.raw != Src2->Sts[loopvar].Reg.Data.raw
114 ) {
115 IsEqual = FALSE;
116 break;
117 //
118 // out of for loop
119 //
120 }
121 }
122
123 return IsEqual;
124 }
125
126 BOOLEAN
CompareSources(CONST IN QNC_SMM_SOURCE_DESC * Src1,CONST IN QNC_SMM_SOURCE_DESC * Src2)127 CompareSources (
128 CONST IN QNC_SMM_SOURCE_DESC *Src1,
129 CONST IN QNC_SMM_SOURCE_DESC *Src2
130 )
131 /*++
132
133 Routine Description:
134
135 GC_TODO: Add function description
136
137 Arguments:
138
139 Src1 - GC_TODO: add argument description
140 Src2 - GC_TODO: add argument description
141
142 Returns:
143
144 GC_TODO: add return values
145
146 --*/
147 {
148 return (BOOLEAN) (CompareEnables (Src1, Src2) && CompareStatuses (Src1, Src2));
149 }
150
151 BOOLEAN
SourceIsActive(CONST IN QNC_SMM_SOURCE_DESC * Src)152 SourceIsActive (
153 CONST IN QNC_SMM_SOURCE_DESC *Src
154 )
155 /*++
156
157 Routine Description:
158
159 GC_TODO: Add function description
160
161 Arguments:
162
163 Src - GC_TODO: add argument description
164
165 Returns:
166
167 GC_TODO: add return values
168
169 --*/
170 {
171 BOOLEAN IsActive;
172 UINTN loopvar;
173
174 BOOLEAN SciEn;
175
176 IsActive = TRUE;
177
178 SciEn = QNCSmmGetSciEn ();
179
180 if ((Src->Flags & QNC_SMM_SCI_EN_DEPENDENT) && (SciEn)) {
181 //
182 // This source is dependent on SciEn, and SciEn == 1. An ACPI OS is present,
183 // so we shouldn't do anything w/ this source until SciEn == 0.
184 //
185 IsActive = FALSE;
186
187 } else {
188 //
189 // Read each bit desc from hardware and make sure it's a one
190 //
191 for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
192
193 if (!IS_BIT_DESC_NULL (Src->En[loopvar])) {
194
195 if (ReadBitDesc (&Src->En[loopvar]) == 0) {
196 IsActive = FALSE;
197 break;
198 //
199 // out of for loop
200 //
201 }
202
203 }
204 }
205
206 if (IsActive) {
207 //
208 // Read each bit desc from hardware and make sure it's a one
209 //
210 for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
211
212 if (!IS_BIT_DESC_NULL (Src->Sts[loopvar])) {
213
214 if (ReadBitDesc (&Src->Sts[loopvar]) == 0) {
215 IsActive = FALSE;
216 break;
217 //
218 // out of for loop
219 //
220 }
221
222 }
223 }
224 }
225 }
226
227 return IsActive;
228 }
229
230 VOID
QNCSmmEnableSource(CONST QNC_SMM_SOURCE_DESC * SrcDesc)231 QNCSmmEnableSource (
232 CONST QNC_SMM_SOURCE_DESC *SrcDesc
233 )
234 /*++
235
236 Routine Description:
237
238 GC_TODO: Add function description
239
240 Arguments:
241
242 SrcDesc - GC_TODO: add argument description
243
244 Returns:
245
246 GC_TODO: add return values
247
248 --*/
249 {
250 UINTN loopvar;
251
252 //
253 // Set enables to 1 by writing a 1
254 //
255 for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
256 if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
257 WriteBitDesc (&SrcDesc->En[loopvar], 1);
258 }
259 }
260
261 QNCSmmClearSource (SrcDesc);
262
263 }
264
265 VOID
QNCSmmDisableSource(CONST QNC_SMM_SOURCE_DESC * SrcDesc)266 QNCSmmDisableSource (
267 CONST QNC_SMM_SOURCE_DESC *SrcDesc
268 )
269 /*++
270
271 Routine Description:
272
273 GC_TODO: Add function description
274
275 Arguments:
276
277 SrcDesc - GC_TODO: add argument description
278
279 Returns:
280
281 GC_TODO: add return values
282
283 --*/
284 {
285 UINTN loopvar;
286
287 for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
288 if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
289 WriteBitDesc (&SrcDesc->En[loopvar], 0);
290 }
291 }
292 }
293
294 VOID
QNCSmmClearSource(CONST QNC_SMM_SOURCE_DESC * SrcDesc)295 QNCSmmClearSource (
296 CONST QNC_SMM_SOURCE_DESC *SrcDesc
297 )
298 /*++
299
300 Routine Description:
301
302 GC_TODO: Add function description
303
304 Arguments:
305
306 SrcDesc - GC_TODO: add argument description
307
308 Returns:
309
310 GC_TODO: add return values
311
312 --*/
313 {
314 UINTN loopvar;
315 BOOLEAN ValueToWrite;
316
317 ValueToWrite =
318 ((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;
319
320 for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
321 if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
322 WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);
323 }
324 }
325 }
326
327 VOID
QNCSmmClearSourceAndBlock(CONST QNC_SMM_SOURCE_DESC * SrcDesc)328 QNCSmmClearSourceAndBlock (
329 CONST QNC_SMM_SOURCE_DESC *SrcDesc
330 )
331 // GC_TODO: function comment should start with '/*++'
332 /*
333 Sets the source to a 1 or 0 and then waits for it to clear.
334 Be very careful when calling this function -- it will not
335 ASSERT. An acceptable case to call the function is when
336 waiting for the NEWCENTURY_STS bit to clear (which takes
337 3 RTCCLKs).
338 */
339 // GC_TODO: function comment should end with '--*/'
340 // GC_TODO: function comment is missing 'Routine Description:'
341 // GC_TODO: function comment is missing 'Arguments:'
342 // GC_TODO: function comment is missing 'Returns:'
343 // GC_TODO: SrcDesc - add argument and description to function comment
344 {
345 UINTN loopvar;
346 BOOLEAN IsSet;
347 BOOLEAN ValueToWrite;
348
349 ValueToWrite =
350 ((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;
351
352 for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
353
354 if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
355 //
356 // Write the bit
357 //
358 WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);
359
360 //
361 // Don't return until the bit actually clears.
362 //
363 IsSet = TRUE;
364 while (IsSet) {
365 IsSet = ReadBitDesc (&SrcDesc->Sts[loopvar]);
366 //
367 // IsSet will eventually clear -- or else we'll have
368 // an infinite loop.
369 //
370 }
371 }
372 }
373 }
374