1fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff/** @file
248557c6550adecf39e1e8e140b1736275d070dfbqhuang  This file implements CalculateCrc32 Boot Services as defined in
348557c6550adecf39e1e8e140b1736275d070dfbqhuang  Platform Initialization specification 1.0 VOLUME 2 DXE Core Interface.
4fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff
59920ae74af5a38672ddde0a997a7ec0960c96275eric_tian  This Boot Services is in the Runtime Driver because this service is
69920ae74af5a38672ddde0a997a7ec0960c96275eric_tian  also required by SetVirtualAddressMap() when the EFI System Table and
79920ae74af5a38672ddde0a997a7ec0960c96275eric_tian  EFI Runtime Services Table are converted from physical address to
848557c6550adecf39e1e8e140b1736275d070dfbqhuang  virtual addresses.  This requires that the 32-bit CRC be recomputed.
99920ae74af5a38672ddde0a997a7ec0960c96275eric_tian
10cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianCopyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
11cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianThis program and the accompanying materials
12fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffare licensed and made available under the terms and conditions of the BSD License
13fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffwhich accompanies this distribution.  The full text of the license may be found at
14fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffhttp://opensource.org/licenses/bsd-license.php
15f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
16fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
19fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff**/
20f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
21ed7748fe4a5575adea8055c6da5948fbee65fd7avanjeff
2260c93673b3189b7a48acdb5c300f4ee3546ffb85lgao#include <Uefi.h>
23f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
24f2abdc918bc19de53fe612458bf6c26298b65c1cyshangUINT32  mCrcTable[256];
25f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
26fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff/**
27fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  Calculate CRC32 for target data.
28fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff
299fc787529c52ace6b1f20f7118b4eb27cd232b7fqwang  @param  Data                  The target data.
30fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  @param  DataSize              The target data size.
31fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  @param  CrcOut                The CRC32 for target data.
32fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff
33fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  @retval EFI_SUCCESS           The CRC32 for target data is calculated successfully.
34fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  @retval EFI_INVALID_PARAMETER Some parameter is not valid, so the CRC32 is not
35fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff                                calculated.
36fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff
37fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff**/
38f2abdc918bc19de53fe612458bf6c26298b65c1cyshangEFI_STATUS
39f2abdc918bc19de53fe612458bf6c26298b65c1cyshangEFIAPI
40f2abdc918bc19de53fe612458bf6c26298b65c1cyshangRuntimeDriverCalculateCrc32 (
41f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  IN  VOID    *Data,
42f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  IN  UINTN   DataSize,
43f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  OUT UINT32  *CrcOut
44f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  )
45f2abdc918bc19de53fe612458bf6c26298b65c1cyshang{
46f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINT32  Crc;
47f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINTN   Index;
48f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINT8   *Ptr;
49f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
50f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  if (Data == NULL || DataSize == 0 || CrcOut == NULL) {
51f2abdc918bc19de53fe612458bf6c26298b65c1cyshang    return EFI_INVALID_PARAMETER;
52f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  }
53f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
54f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  Crc = 0xffffffff;
55f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {
56f2abdc918bc19de53fe612458bf6c26298b65c1cyshang    Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];
57f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  }
58f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
59f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  *CrcOut = Crc ^ 0xffffffff;
60f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  return EFI_SUCCESS;
61f2abdc918bc19de53fe612458bf6c26298b65c1cyshang}
62f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
63f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
64fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff/**
6548557c6550adecf39e1e8e140b1736275d070dfbqhuang  This internal function reverses bits for 32bit data.
66f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
67fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  @param  Value                 The data to be reversed.
68f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
699fc787529c52ace6b1f20f7118b4eb27cd232b7fqwang  @return                       Data reversed.
70f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
71fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff**/
72fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffUINT32
73fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffReverseBits (
74fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  UINT32  Value
75fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  )
76f2abdc918bc19de53fe612458bf6c26298b65c1cyshang{
77f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINTN   Index;
78f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINT32  NewValue;
79f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
80f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  NewValue = 0;
81f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  for (Index = 0; Index < 32; Index++) {
829fc787529c52ace6b1f20f7118b4eb27cd232b7fqwang    if ((Value & (1 << Index)) != 0) {
83f2abdc918bc19de53fe612458bf6c26298b65c1cyshang      NewValue = NewValue | (1 << (31 - Index));
84f2abdc918bc19de53fe612458bf6c26298b65c1cyshang    }
85f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  }
86f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
87f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  return NewValue;
88f2abdc918bc19de53fe612458bf6c26298b65c1cyshang}
89f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
90fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff/**
91f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  Initialize CRC32 table.
9248557c6550adecf39e1e8e140b1736275d070dfbqhuang
93fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff**/
94fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffVOID
95fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeffRuntimeDriverInitializeCrc32Table (
96fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  VOID
97fb0b259e4e440577dcd6ba6722c252d90605b3e9vanjeff  )
98f2abdc918bc19de53fe612458bf6c26298b65c1cyshang{
99f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINTN   TableEntry;
100f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINTN   Index;
101f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  UINT32  Value;
102f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
103f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  for (TableEntry = 0; TableEntry < 256; TableEntry++) {
104f2abdc918bc19de53fe612458bf6c26298b65c1cyshang    Value = ReverseBits ((UINT32) TableEntry);
105f2abdc918bc19de53fe612458bf6c26298b65c1cyshang    for (Index = 0; Index < 8; Index++) {
1069fc787529c52ace6b1f20f7118b4eb27cd232b7fqwang      if ((Value & 0x80000000) != 0) {
107f2abdc918bc19de53fe612458bf6c26298b65c1cyshang        Value = (Value << 1) ^ 0x04c11db7;
108f2abdc918bc19de53fe612458bf6c26298b65c1cyshang      } else {
109f2abdc918bc19de53fe612458bf6c26298b65c1cyshang        Value = Value << 1;
110f2abdc918bc19de53fe612458bf6c26298b65c1cyshang      }
111f2abdc918bc19de53fe612458bf6c26298b65c1cyshang    }
112f2abdc918bc19de53fe612458bf6c26298b65c1cyshang
113f2abdc918bc19de53fe612458bf6c26298b65c1cyshang    mCrcTable[TableEntry] = ReverseBits (Value);
114f2abdc918bc19de53fe612458bf6c26298b65c1cyshang  }
115f2abdc918bc19de53fe612458bf6c26298b65c1cyshang}
116