Home | History | Annotate | Download | only in PeiLib
      1 /*++
      2 
      3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   Decompress.c
     15 
     16 Abstract:
     17 
     18   Decompressor. Algorithm Ported from OPSD code (Decomp.asm)
     19 
     20 --*/
     21 
     22 #include "TianoCommon.h"
     23 #include EFI_PROTOCOL_DEFINITION (Decompress)
     24 #include EFI_PROTOCOL_DEFINITION (TianoDecompress)
     25 
     26 EFI_STATUS
     27 EFIAPI
     28 EfiGetInfo (
     29   IN      EFI_DECOMPRESS_PROTOCOL *This,
     30   IN      VOID                    *Source,
     31   IN      UINT32                  SrcSize,
     32   OUT     UINT32                  *DstSize,
     33   OUT     UINT32                  *ScratchSize
     34   );
     35 
     36 EFI_STATUS
     37 EFIAPI
     38 EfiDecompress (
     39   IN      EFI_DECOMPRESS_PROTOCOL *This,
     40   IN      VOID                    *Source,
     41   IN      UINT32                  SrcSize,
     42   IN OUT  VOID                    *Destination,
     43   IN      UINT32                  DstSize,
     44   IN OUT  VOID                    *Scratch,
     45   IN      UINT32                  ScratchSize
     46   );
     47 
     48 EFI_STATUS
     49 EFIAPI
     50 TianoGetInfo (
     51   IN      EFI_TIANO_DECOMPRESS_PROTOCOL *This,
     52   IN      VOID                          *Source,
     53   IN      UINT32                        SrcSize,
     54   OUT     UINT32                        *DstSize,
     55   OUT     UINT32                        *ScratchSize
     56   );
     57 
     58 EFI_STATUS
     59 EFIAPI
     60 TianoDecompress (
     61   IN      EFI_TIANO_DECOMPRESS_PROTOCOL *This,
     62   IN      VOID                          *Source,
     63   IN      UINT32                        SrcSize,
     64   IN OUT  VOID                          *Destination,
     65   IN      UINT32                        DstSize,
     66   IN OUT  VOID                          *Scratch,
     67   IN      UINT32                        ScratchSize
     68   );
     69 
     70 //
     71 // The protocol instance
     72 //
     73 
     74 EFI_DECOMPRESS_PROTOCOL       mEfiDecompress = {
     75   EfiGetInfo,
     76   EfiDecompress
     77 };
     78 
     79 EFI_TIANO_DECOMPRESS_PROTOCOL mTianoDecompress = {
     80   TianoGetInfo,
     81   TianoDecompress
     82 };
     83 
     84 EFI_STATUS
     85 InstallEfiDecompress (
     86   IN OUT  EFI_DECOMPRESS_PROTOCOL  **This
     87   )
     88 /*++
     89 
     90 Routine Description:
     91 
     92   Install EFI decompress protocol.
     93 
     94 Arguments:
     95 
     96   This  - Pointer to get decompress protocol as output
     97 
     98 Returns:
     99 
    100   EFI_SUCCESS - EFI decompress protocol successfully installed.
    101 
    102 --*/
    103 {
    104   *This = &mEfiDecompress;
    105   return EFI_SUCCESS;
    106 }
    107 
    108 EFI_STATUS
    109 InstallTianoDecompress (
    110   EFI_TIANO_DECOMPRESS_PROTOCOL  **This
    111   )
    112 /*++
    113 
    114 Routine Description:
    115 
    116   Install Tiano decompress protocol.
    117 
    118 Arguments:
    119 
    120   This  - Pointer to get decompress protocol as output
    121 
    122 Returns:
    123 
    124   EFI_SUCCESS - Tiano decompress protocol successfully installed.
    125 
    126 --*/
    127 {
    128   *This = &mTianoDecompress;
    129   return EFI_SUCCESS;
    130 }
    131 //
    132 // Decompression algorithm begins here
    133 //
    134 #define BITBUFSIZ 32
    135 #define MAXMATCH  256
    136 #define THRESHOLD 3
    137 #define CODE_BIT  16
    138 #ifndef UINT8_MAX
    139 #define UINT8_MAX 0xff
    140 #endif
    141 #define BAD_TABLE - 1
    142 
    143 //
    144 // C: Char&Len Set; P: Position Set; T: exTra Set
    145 //
    146 #define NC      (0xff + MAXMATCH + 2 - THRESHOLD)
    147 #define CBIT    9
    148 #define MAXPBIT 5
    149 #define TBIT    5
    150 #define MAXNP   ((1U << MAXPBIT) - 1)
    151 #define NT      (CODE_BIT + 3)
    152 #if NT > MAXNP
    153 #define NPT NT
    154 #else
    155 #define NPT MAXNP
    156 #endif
    157 
    158 typedef struct {
    159   UINT8   *mSrcBase;  // Starting address of compressed data
    160   UINT8   *mDstBase;  // Starting address of decompressed data
    161   UINT32  mOutBuf;
    162   UINT32  mInBuf;
    163 
    164   UINT16  mBitCount;
    165   UINT32  mBitBuf;
    166   UINT32  mSubBitBuf;
    167   UINT16  mBlockSize;
    168   UINT32  mCompSize;
    169   UINT32  mOrigSize;
    170 
    171   UINT16  mBadTableFlag;
    172 
    173   UINT16  mLeft[2 * NC - 1];
    174   UINT16  mRight[2 * NC - 1];
    175   UINT8   mCLen[NC];
    176   UINT8   mPTLen[NPT];
    177   UINT16  mCTable[4096];
    178   UINT16  mPTTable[256];
    179 
    180   //
    181   // The length of the field 'Position Set Code Length Array Size' in Block Header.
    182   // For EFI 1.1 de/compression algorithm, mPBit = 4
    183   // For Tiano de/compression algorithm, mPBit = 5
    184   //
    185   UINT8   mPBit;
    186 } SCRATCH_DATA;
    187 
    188 STATIC
    189 VOID
    190 FillBuf (
    191   IN  SCRATCH_DATA  *Sd,
    192   IN  UINT16        NumOfBits
    193   )
    194 /*++
    195 
    196 Routine Description:
    197 
    198   Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
    199 
    200 Arguments:
    201 
    202   Sd        - The global scratch data
    203   NumOfBits  - The number of bits to shift and read.
    204 
    205 Returns: (VOID)
    206 
    207 --*/
    208 {
    209   Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
    210 
    211   while (NumOfBits > Sd->mBitCount) {
    212 
    213     Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
    214 
    215     if (Sd->mCompSize > 0) {
    216       //
    217       // Get 1 byte into SubBitBuf
    218       //
    219       Sd->mCompSize--;
    220       Sd->mSubBitBuf  = 0;
    221       Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];
    222       Sd->mBitCount   = 8;
    223 
    224     } else {
    225       //
    226       // No more bits from the source, just pad zero bit.
    227       //
    228       Sd->mSubBitBuf  = 0;
    229       Sd->mBitCount   = 8;
    230 
    231     }
    232   }
    233 
    234   Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
    235   Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
    236 }
    237 
    238 STATIC
    239 UINT32
    240 GetBits (
    241   IN  SCRATCH_DATA  *Sd,
    242   IN  UINT16        NumOfBits
    243   )
    244 /*++
    245 
    246 Routine Description:
    247 
    248   Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
    249   NumOfBits of bits from source. Returns NumOfBits of bits that are
    250   popped out.
    251 
    252 Arguments:
    253 
    254   Sd            - The global scratch data.
    255   NumOfBits     - The number of bits to pop and read.
    256 
    257 Returns:
    258 
    259   The bits that are popped out.
    260 
    261 --*/
    262 {
    263   UINT32  OutBits;
    264 
    265   OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
    266 
    267   FillBuf (Sd, NumOfBits);
    268 
    269   return OutBits;
    270 }
    271 
    272 STATIC
    273 UINT16
    274 MakeTable (
    275   IN  SCRATCH_DATA  *Sd,
    276   IN  UINT16        NumOfChar,
    277   IN  UINT8         *BitLen,
    278   IN  UINT16        TableBits,
    279   OUT UINT16        *Table
    280   )
    281 /*++
    282 
    283 Routine Description:
    284 
    285   Creates Huffman Code mapping table according to code length array.
    286 
    287 Arguments:
    288 
    289   Sd        - The global scratch data
    290   NumOfChar - Number of symbols in the symbol set
    291   BitLen    - Code length array
    292   TableBits - The width of the mapping table
    293   Table     - The table
    294 
    295 Returns:
    296 
    297   0         - OK.
    298   BAD_TABLE - The table is corrupted.
    299 
    300 --*/
    301 {
    302   UINT16  Count[17];
    303   UINT16  Weight[17];
    304   UINT16  Start[18];
    305   UINT16  *Pointer;
    306   UINT16  Index3;
    307   UINT16  Index;
    308   UINT16  Len;
    309   UINT16  Char;
    310   UINT16  JuBits;
    311   UINT16  Avail;
    312   UINT16  NextCode;
    313   UINT16  Mask;
    314 
    315   //
    316   // TableBits should not be greater than 16.
    317   //
    318   if (TableBits >= (sizeof (Count)/sizeof (UINT16))) {
    319     return (UINT16) BAD_TABLE;
    320   }
    321 
    322   //
    323   // Initialize Count array starting from Index 0, as there is a possibility of Count array being uninitialized.
    324   //
    325   for (Index = 0; Index <= 16; Index++) {
    326     Count[Index] = 0;
    327   }
    328 
    329   for (Index = 0; Index < NumOfChar; Index++) {
    330     //
    331     // Count array index should not be greater than or equal to its size.
    332     //
    333     if (BitLen[Index] < (sizeof (Count)/sizeof (UINT16))) {
    334       Count[BitLen[Index]]++;
    335     } else {
    336       return (UINT16) BAD_TABLE;
    337     }
    338   }
    339 
    340   Start[0] = 0;
    341   Start[1] = 0;
    342 
    343   for (Index = 1; Index <= 16; Index++) {
    344     Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
    345   }
    346 
    347   if (Start[17] != 0) {
    348     /*(1U << 16)*/
    349     return (UINT16) BAD_TABLE;
    350   }
    351 
    352   JuBits = (UINT16) (16 - TableBits);
    353 
    354   for (Index = 1; Index <= TableBits; Index++) {
    355     Start[Index] >>= JuBits;
    356     Weight[Index] = (UINT16) (1U << (TableBits - Index));
    357   }
    358 
    359   while (Index <= 16) {
    360     Weight[Index] = (UINT16) (1U << (16 - Index));
    361     Index++;
    362   }
    363 
    364   Index = (UINT16) (Start[TableBits + 1] >> JuBits);
    365 
    366   if (Index != 0) {
    367     Index3 = (UINT16) (1U << TableBits);
    368     while (Index != Index3) {
    369       Table[Index++] = 0;
    370     }
    371   }
    372 
    373   Avail = NumOfChar;
    374   Mask  = (UINT16) (1U << (15 - TableBits));
    375 
    376   for (Char = 0; Char < NumOfChar; Char++) {
    377 
    378     Len = BitLen[Char];
    379     if (Len == 0 || Len >= 17) {
    380       continue;
    381     }
    382 
    383     NextCode = (UINT16) (Start[Len] + Weight[Len]);
    384 
    385     if (Len <= TableBits) {
    386 
    387       for (Index = Start[Len]; Index < NextCode; Index++) {
    388         Table[Index] = Char;
    389       }
    390 
    391     } else {
    392 
    393       Index3  = Start[Len];
    394       Pointer = &Table[Index3 >> JuBits];
    395       Index   = (UINT16) (Len - TableBits);
    396 
    397       while (Index != 0) {
    398         //
    399         // Avail should be lesser than size of mRight and mLeft to prevent buffer overflow.
    400         //
    401         if ((*Pointer == 0) && (Avail < sizeof (Sd->mRight)/sizeof (UINT16)) && (Avail < sizeof (Sd->mLeft)/sizeof (UINT16))) {
    402           Sd->mRight[Avail]                     = Sd->mLeft[Avail] = 0;
    403           *Pointer = Avail++;
    404         }
    405 
    406         //
    407         // *Pointer should be lesser than size of mRight and mLeft to prevent buffer overflow.
    408         //
    409         if ((Index3 & Mask) && (*Pointer < (sizeof (Sd->mRight)/sizeof (UINT16)))) {
    410           Pointer = &Sd->mRight[*Pointer];
    411         } else if (*Pointer < (sizeof (Sd->mLeft)/sizeof (UINT16))) {
    412           Pointer = &Sd->mLeft[*Pointer];
    413         }
    414 
    415         Index3 <<= 1;
    416         Index--;
    417       }
    418 
    419       *Pointer = Char;
    420 
    421     }
    422 
    423     Start[Len] = NextCode;
    424   }
    425   //
    426   // Succeeds
    427   //
    428   return 0;
    429 }
    430 
    431 STATIC
    432 UINT32
    433 DecodeP (
    434   IN  SCRATCH_DATA  *Sd
    435   )
    436 /*++
    437 
    438 Routine Description:
    439 
    440   Decodes a position value.
    441 
    442 Arguments:
    443 
    444   Sd      - the global scratch data
    445 
    446 Returns:
    447 
    448   The position value decoded.
    449 
    450 --*/
    451 {
    452   UINT16  Val;
    453   UINT32  Mask;
    454   UINT32  Pos;
    455 
    456   Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
    457 
    458   if (Val >= MAXNP) {
    459     Mask = 1U << (BITBUFSIZ - 1 - 8);
    460 
    461     do {
    462 
    463       if (Sd->mBitBuf & Mask) {
    464         Val = Sd->mRight[Val];
    465       } else {
    466         Val = Sd->mLeft[Val];
    467       }
    468 
    469       Mask >>= 1;
    470     } while (Val >= MAXNP);
    471   }
    472   //
    473   // Advance what we have read
    474   //
    475   FillBuf (Sd, Sd->mPTLen[Val]);
    476 
    477   Pos = Val;
    478   if (Val > 1) {
    479     Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
    480   }
    481 
    482   return Pos;
    483 }
    484 
    485 STATIC
    486 UINT16
    487 ReadPTLen (
    488   IN  SCRATCH_DATA  *Sd,
    489   IN  UINT16        nn,
    490   IN  UINT16        nbit,
    491   IN  UINT16        Special
    492   )
    493 /*++
    494 
    495 Routine Description:
    496 
    497   Reads code lengths for the Extra Set or the Position Set
    498 
    499 Arguments:
    500 
    501   Sd        - The global scratch data
    502   nn        - Number of symbols
    503   nbit      - Number of bits needed to represent nn
    504   Special   - The special symbol that needs to be taken care of
    505 
    506 Returns:
    507 
    508   0         - OK.
    509   BAD_TABLE - Table is corrupted.
    510 
    511 --*/
    512 {
    513   UINT16  Number;
    514   UINT16  CharC;
    515   UINT16  Index;
    516   UINT32  Mask;
    517 
    518   Number = (UINT16) GetBits (Sd, nbit);
    519 
    520   if ((Number > sizeof (Sd->mPTLen)) || (nn > sizeof (Sd->mPTLen))) {
    521     //
    522     // Fail if Number or nn is greater than size of mPTLen
    523     //
    524     return (UINT16) BAD_TABLE;
    525   }
    526 
    527   if (Number == 0) {
    528     CharC = (UINT16) GetBits (Sd, nbit);
    529 
    530     for (Index = 0; Index < 256; Index++) {
    531       Sd->mPTTable[Index] = CharC;
    532     }
    533 
    534     for (Index = 0; Index < nn; Index++) {
    535       Sd->mPTLen[Index] = 0;
    536     }
    537 
    538     return 0;
    539   }
    540 
    541   Index = 0;
    542 
    543   while (Index < Number) {
    544 
    545     CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
    546 
    547     if (CharC == 7) {
    548       Mask = 1U << (BITBUFSIZ - 1 - 3);
    549       while (Mask & Sd->mBitBuf) {
    550         Mask >>= 1;
    551         CharC += 1;
    552       }
    553     }
    554 
    555     FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
    556 
    557     Sd->mPTLen[Index++] = (UINT8) CharC;
    558 
    559     if (Index == Special) {
    560       CharC = (UINT16) GetBits (Sd, 2);
    561       while ((INT16) (--CharC) >= 0) {
    562         if (Index >= sizeof (Sd->mPTLen)) {
    563           //
    564           // Fail if Index is greater than or equal to mPTLen
    565           //
    566           return (UINT16) BAD_TABLE;
    567         }
    568         Sd->mPTLen[Index++] = 0;
    569       }
    570     }
    571   }
    572 
    573   while (Index < nn) {
    574     Sd->mPTLen[Index++] = 0;
    575   }
    576 
    577   return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
    578 }
    579 
    580 STATIC
    581 VOID
    582 ReadCLen (
    583   SCRATCH_DATA  *Sd
    584   )
    585 /*++
    586 
    587 Routine Description:
    588 
    589   Reads code lengths for Char&Len Set.
    590 
    591 Arguments:
    592 
    593   Sd    - the global scratch data
    594 
    595 Returns: (VOID)
    596 
    597 --*/
    598 {
    599   UINT16  Number;
    600   UINT16  CharC;
    601   UINT16  Index;
    602   UINT32  Mask;
    603 
    604   Number = (UINT16) GetBits (Sd, CBIT);
    605 
    606   if (Number == 0) {
    607     CharC = (UINT16) GetBits (Sd, CBIT);
    608 
    609     for (Index = 0; Index < NC; Index++) {
    610       Sd->mCLen[Index] = 0;
    611     }
    612 
    613     for (Index = 0; Index < 4096; Index++) {
    614       Sd->mCTable[Index] = CharC;
    615     }
    616 
    617     return ;
    618   }
    619 
    620   Index = 0;
    621   while (Index < Number) {
    622 
    623     CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
    624     if (CharC >= NT) {
    625       Mask = 1U << (BITBUFSIZ - 1 - 8);
    626 
    627       do {
    628 
    629         if (Mask & Sd->mBitBuf) {
    630           CharC = Sd->mRight[CharC];
    631         } else {
    632           CharC = Sd->mLeft[CharC];
    633         }
    634 
    635         Mask >>= 1;
    636 
    637       } while (CharC >= NT);
    638     }
    639     //
    640     // Advance what we have read
    641     //
    642     FillBuf (Sd, Sd->mPTLen[CharC]);
    643 
    644     if (CharC <= 2) {
    645 
    646       if (CharC == 0) {
    647         CharC = 1;
    648       } else if (CharC == 1) {
    649         CharC = (UINT16) (GetBits (Sd, 4) + 3);
    650       } else if (CharC == 2) {
    651         CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
    652       }
    653 
    654       while ((INT16) (--CharC) >= 0) {
    655         Sd->mCLen[Index++] = 0;
    656       }
    657 
    658     } else {
    659 
    660       Sd->mCLen[Index++] = (UINT8) (CharC - 2);
    661 
    662     }
    663   }
    664 
    665   while (Index < NC) {
    666     Sd->mCLen[Index++] = 0;
    667   }
    668 
    669   MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
    670 
    671   return ;
    672 }
    673 
    674 STATIC
    675 UINT16
    676 DecodeC (
    677   SCRATCH_DATA  *Sd
    678   )
    679 /*++
    680 
    681 Routine Description:
    682 
    683   Decode a character/length value.
    684 
    685 Arguments:
    686 
    687   Sd    - The global scratch data.
    688 
    689 Returns:
    690 
    691   The value decoded.
    692 
    693 --*/
    694 {
    695   UINT16  Index2;
    696   UINT32  Mask;
    697 
    698   if (Sd->mBlockSize == 0) {
    699     //
    700     // Starting a new block
    701     //
    702     Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);
    703     Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
    704     if (Sd->mBadTableFlag != 0) {
    705       return 0;
    706     }
    707 
    708     ReadCLen (Sd);
    709 
    710     Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
    711     if (Sd->mBadTableFlag != 0) {
    712       return 0;
    713     }
    714   }
    715 
    716   Sd->mBlockSize--;
    717   Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
    718 
    719   if (Index2 >= NC) {
    720     Mask = 1U << (BITBUFSIZ - 1 - 12);
    721 
    722     do {
    723       if (Sd->mBitBuf & Mask) {
    724         Index2 = Sd->mRight[Index2];
    725       } else {
    726         Index2 = Sd->mLeft[Index2];
    727       }
    728 
    729       Mask >>= 1;
    730     } while (Index2 >= NC);
    731   }
    732   //
    733   // Advance what we have read
    734   //
    735   FillBuf (Sd, Sd->mCLen[Index2]);
    736 
    737   return Index2;
    738 }
    739 
    740 STATIC
    741 VOID
    742 Decode (
    743   SCRATCH_DATA  *Sd
    744   )
    745 /*++
    746 
    747 Routine Description:
    748 
    749   Decode the source data and put the resulting data into the destination buffer.
    750 
    751 Arguments:
    752 
    753   Sd            - The global scratch data
    754 
    755 Returns: (VOID)
    756 
    757  --*/
    758 {
    759   UINT16  BytesRemain;
    760   UINT32  DataIdx;
    761   UINT16  CharC;
    762 
    763   BytesRemain = (UINT16) (-1);
    764 
    765   DataIdx     = 0;
    766 
    767   for (;;) {
    768     CharC = DecodeC (Sd);
    769     if (Sd->mBadTableFlag != 0) {
    770       return ;
    771     }
    772 
    773     if (CharC < 256) {
    774       //
    775       // Process an Original character
    776       //
    777       if (Sd->mOutBuf >= Sd->mOrigSize) {
    778         return ;
    779       } else {
    780         Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
    781       }
    782 
    783     } else {
    784       //
    785       // Process a Pointer
    786       //
    787       CharC       = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
    788 
    789       BytesRemain = CharC;
    790 
    791       DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;
    792 
    793       BytesRemain--;
    794       while ((INT16) (BytesRemain) >= 0) {
    795         Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
    796         if (Sd->mOutBuf >= Sd->mOrigSize) {
    797           return ;
    798         }
    799 
    800         BytesRemain--;
    801       }
    802     }
    803   }
    804 }
    805 
    806 EFI_STATUS
    807 GetInfo (
    808   IN      VOID    *Source,
    809   IN      UINT32  SrcSize,
    810   OUT     UINT32  *DstSize,
    811   OUT     UINT32  *ScratchSize
    812   )
    813 /*++
    814 
    815 Routine Description:
    816 
    817   The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
    818 
    819 Arguments:
    820 
    821   Source      - The source buffer containing the compressed data.
    822   SrcSize     - The size of source buffer
    823   DstSize     - The size of destination buffer.
    824   ScratchSize - The size of scratch buffer.
    825 
    826 Returns:
    827 
    828   EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.
    829   EFI_INVALID_PARAMETER - The source data is corrupted
    830 
    831 --*/
    832 {
    833   UINT8 *Src;
    834 
    835   *ScratchSize  = sizeof (SCRATCH_DATA);
    836 
    837   Src           = Source;
    838   if (SrcSize < 8) {
    839     return EFI_INVALID_PARAMETER;
    840   }
    841 
    842   *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
    843   return EFI_SUCCESS;
    844 }
    845 
    846 EFI_STATUS
    847 Decompress (
    848   IN      VOID    *Source,
    849   IN      UINT32  SrcSize,
    850   IN OUT  VOID    *Destination,
    851   IN      UINT32  DstSize,
    852   IN OUT  VOID    *Scratch,
    853   IN      UINT32  ScratchSize,
    854   IN      UINT8   Version
    855   )
    856 /*++
    857 
    858 Routine Description:
    859 
    860   The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
    861 
    862 Arguments:
    863 
    864   Source      - The source buffer containing the compressed data.
    865   SrcSize     - The size of source buffer
    866   Destination - The destination buffer to store the decompressed data
    867   DstSize     - The size of destination buffer.
    868   Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
    869   ScratchSize - The size of scratch buffer.
    870   Version     - The version of de/compression algorithm.
    871                 Version 1 for EFI 1.1 de/compression algorithm.
    872                 Version 2 for Tiano de/compression algorithm.
    873 
    874 Returns:
    875 
    876   EFI_SUCCESS           - Decompression is successfull
    877   EFI_INVALID_PARAMETER - The source data is corrupted
    878 
    879 --*/
    880 {
    881   UINT32        Index;
    882   UINT32        CompSize;
    883   UINT32        OrigSize;
    884   EFI_STATUS    Status;
    885   SCRATCH_DATA  *Sd;
    886   UINT8         *Src;
    887   UINT8         *Dst;
    888 
    889   Status  = EFI_SUCCESS;
    890   Src     = Source;
    891   Dst     = Destination;
    892 
    893   if (ScratchSize < sizeof (SCRATCH_DATA)) {
    894     return EFI_INVALID_PARAMETER;
    895   }
    896 
    897   Sd = (SCRATCH_DATA *) Scratch;
    898 
    899   if (SrcSize < 8) {
    900     return EFI_INVALID_PARAMETER;
    901   }
    902 
    903   CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
    904   OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
    905 
    906   //
    907   // If compressed file size is 0, return
    908   //
    909   if (OrigSize == 0) {
    910     return Status;
    911   }
    912 
    913   if (SrcSize < CompSize + 8) {
    914     return EFI_INVALID_PARAMETER;
    915   }
    916 
    917   if (DstSize != OrigSize) {
    918     return EFI_INVALID_PARAMETER;
    919   }
    920 
    921   Src = Src + 8;
    922 
    923   for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
    924     ((UINT8 *) Sd)[Index] = 0;
    925   }
    926   //
    927   // The length of the field 'Position Set Code Length Array Size' in Block Header.
    928   // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
    929   // For Tiano de/compression algorithm(Version 2), mPBit = 5
    930   //
    931   switch (Version) {
    932   case 1:
    933     Sd->mPBit = 4;
    934     break;
    935 
    936   case 2:
    937     Sd->mPBit = 5;
    938     break;
    939 
    940   default:
    941     //
    942     // Currently, only have 2 versions
    943     //
    944     return EFI_INVALID_PARAMETER;
    945   }
    946 
    947   Sd->mSrcBase  = Src;
    948   Sd->mDstBase  = Dst;
    949   Sd->mCompSize = CompSize;
    950   Sd->mOrigSize = OrigSize;
    951 
    952   //
    953   // Fill the first BITBUFSIZ bits
    954   //
    955   FillBuf (Sd, BITBUFSIZ);
    956 
    957   //
    958   // Decompress it
    959   //
    960   Decode (Sd);
    961 
    962   if (Sd->mBadTableFlag != 0) {
    963     //
    964     // Something wrong with the source
    965     //
    966     Status = EFI_INVALID_PARAMETER;
    967   }
    968 
    969   return Status;
    970 }
    971 
    972 EFI_STATUS
    973 EFIAPI
    974 EfiGetInfo (
    975   IN      EFI_DECOMPRESS_PROTOCOL *This,
    976   IN      VOID                    *Source,
    977   IN      UINT32                  SrcSize,
    978   OUT     UINT32                  *DstSize,
    979   OUT     UINT32                  *ScratchSize
    980   )
    981 /*++
    982 
    983 Routine Description:
    984 
    985   The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
    986 
    987 Arguments:
    988 
    989   This        - The protocol instance pointer
    990   Source      - The source buffer containing the compressed data.
    991   SrcSize     - The size of source buffer
    992   DstSize     - The size of destination buffer.
    993   ScratchSize - The size of scratch buffer.
    994 
    995 Returns:
    996 
    997   EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.
    998   EFI_INVALID_PARAMETER - The source data is corrupted
    999 
   1000 --*/
   1001 {
   1002   return GetInfo (
   1003           Source,
   1004           SrcSize,
   1005           DstSize,
   1006           ScratchSize
   1007           );
   1008 }
   1009 
   1010 EFI_STATUS
   1011 EFIAPI
   1012 EfiDecompress (
   1013   IN      EFI_DECOMPRESS_PROTOCOL *This,
   1014   IN      VOID                    *Source,
   1015   IN      UINT32                  SrcSize,
   1016   IN OUT  VOID                    *Destination,
   1017   IN      UINT32                  DstSize,
   1018   IN OUT  VOID                    *Scratch,
   1019   IN      UINT32                  ScratchSize
   1020   )
   1021 /*++
   1022 
   1023 Routine Description:
   1024 
   1025   The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().
   1026 
   1027 Arguments:
   1028 
   1029   This        - The protocol instance pointer
   1030   Source      - The source buffer containing the compressed data.
   1031   SrcSize     - The size of source buffer
   1032   Destination - The destination buffer to store the decompressed data
   1033   DstSize     - The size of destination buffer.
   1034   Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
   1035   ScratchSize - The size of scratch buffer.
   1036 
   1037 Returns:
   1038 
   1039   EFI_SUCCESS           - Decompression is successfull
   1040   EFI_INVALID_PARAMETER - The source data is corrupted
   1041 
   1042 --*/
   1043 {
   1044   //
   1045   // For EFI 1.1 de/compression algorithm, the version is 1.
   1046   //
   1047   return Decompress (
   1048           Source,
   1049           SrcSize,
   1050           Destination,
   1051           DstSize,
   1052           Scratch,
   1053           ScratchSize,
   1054           1
   1055           );
   1056 }
   1057 
   1058 EFI_STATUS
   1059 EFIAPI
   1060 TianoGetInfo (
   1061   IN      EFI_TIANO_DECOMPRESS_PROTOCOL *This,
   1062   IN      VOID                          *Source,
   1063   IN      UINT32                        SrcSize,
   1064   OUT     UINT32                        *DstSize,
   1065   OUT     UINT32                        *ScratchSize
   1066   )
   1067 /*++
   1068 
   1069 Routine Description:
   1070 
   1071   The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.GetInfo().
   1072 
   1073 Arguments:
   1074 
   1075   This        - The protocol instance pointer
   1076   Source      - The source buffer containing the compressed data.
   1077   SrcSize     - The size of source buffer
   1078   DstSize     - The size of destination buffer.
   1079   ScratchSize - The size of scratch buffer.
   1080 
   1081 Returns:
   1082 
   1083   EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.
   1084   EFI_INVALID_PARAMETER - The source data is corrupted
   1085 
   1086 --*/
   1087 {
   1088   return GetInfo (
   1089           Source,
   1090           SrcSize,
   1091           DstSize,
   1092           ScratchSize
   1093           );
   1094 }
   1095 
   1096 EFI_STATUS
   1097 EFIAPI
   1098 TianoDecompress (
   1099   IN      EFI_TIANO_DECOMPRESS_PROTOCOL *This,
   1100   IN      VOID                          *Source,
   1101   IN      UINT32                        SrcSize,
   1102   IN OUT  VOID                          *Destination,
   1103   IN      UINT32                        DstSize,
   1104   IN OUT  VOID                          *Scratch,
   1105   IN      UINT32                        ScratchSize
   1106   )
   1107 /*++
   1108 
   1109 Routine Description:
   1110 
   1111   The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
   1112 
   1113 Arguments:
   1114 
   1115   This        - The protocol instance pointer
   1116   Source      - The source buffer containing the compressed data.
   1117   SrcSize     - The size of source buffer
   1118   Destination - The destination buffer to store the decompressed data
   1119   DstSize     - The size of destination buffer.
   1120   Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.
   1121   ScratchSize - The size of scratch buffer.
   1122 
   1123 Returns:
   1124 
   1125   EFI_SUCCESS           - Decompression is successfull
   1126   EFI_INVALID_PARAMETER - The source data is corrupted
   1127 
   1128 --*/
   1129 {
   1130   //
   1131   // For Tiano de/compression algorithm, the version is 2.
   1132   //
   1133   return Decompress (
   1134           Source,
   1135           SrcSize,
   1136           Destination,
   1137           DstSize,
   1138           Scratch,
   1139           ScratchSize,
   1140           2
   1141           );
   1142 }
   1143