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