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 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 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 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 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 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 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 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 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