Home | History | Annotate | Download | only in QncSmmDispatcher
      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