• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   C language wrapper to build DSDT generated data.
4 
5   Copyright (c) 2014 - 2016, AMD Inc. All rights reserved.<BR>
6 
7   This program and the accompanying materials
8   are licensed and made available under the terms and conditions of the BSD License
9   which accompanies this distribution.  The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #include <AmdStyxAcpiLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PcdLib.h>
21 
22 #include <Dsdt.hex>
23 #include <Dsdt.offset.h>
24 
25 
26 UINTN
ShiftLeftByteToUlong(IN UINT8 Byte,IN UINTN Shift)27 ShiftLeftByteToUlong (
28   IN UINT8 Byte,
29   IN UINTN Shift
30   )
31 {
32   UINTN Data;
33 
34   Data = (UINTN)Byte;
35   Data <<= Shift;
36   return Data;
37 }
38 
39 UINTN
AmlGetPkgLength(IN UINT8 * Buffer,OUT UINTN * PkgLength)40 AmlGetPkgLength (
41   IN UINT8 *Buffer,
42   OUT UINTN *PkgLength
43   )
44 {
45   UINTN Bytes, Length;
46 
47   Bytes = (UINTN)((Buffer[0] >> 6) & 0x3) + 1;
48   switch (Bytes) {
49     case 1:
50       Length = (UINTN)Buffer[0];
51       break;
52 
53     case 2:
54       Length = ShiftLeftByteToUlong(Buffer[1], 4) +
55                 (UINTN)(Buffer[0] & 0x0F);
56       break;
57 
58     case 3:
59       Length = ShiftLeftByteToUlong(Buffer[2], 12) +
60                 ShiftLeftByteToUlong(Buffer[1], 4) +
61                  (UINTN)(Buffer[0] & 0x0F);
62       break;
63 
64     default: /* 4 bytes */
65       Length = ShiftLeftByteToUlong(Buffer[3], 20) +
66                 ShiftLeftByteToUlong(Buffer[2], 12) +
67                  ShiftLeftByteToUlong(Buffer[1], 4) +
68                   (UINTN)(Buffer[0] & 0x0F);
69       break;
70   }
71 
72   *PkgLength = Length;
73   return Bytes;
74 }
75 
76 UINT8 *
AmlSearchStringPackage(IN UINT8 * Buffer,IN UINTN Length,IN CHAR8 * String)77 AmlSearchStringPackage (
78   IN UINT8 *Buffer,
79   IN UINTN Length,
80   IN CHAR8 *String
81   )
82 {
83   UINTN StrLength;
84 
85   StrLength = AsciiStrLen (String) + 1;
86   if (Length > StrLength ) {
87     Length -= StrLength;
88     while (AsciiStrCmp((CHAR8 *)Buffer, String) != 0 && Length) {
89       --Length;
90       ++Buffer;
91     }
92     if (Length) {
93       return &Buffer[StrLength];
94     }
95   }
96   return NULL;
97 }
98 
99 VOID
OverrideMacAddr(IN UINT8 * DSD_Data,IN UINT64 MacAddr)100 OverrideMacAddr (
101   IN UINT8 *DSD_Data,
102   IN UINT64 MacAddr
103   )
104 {
105   UINT8 *MacAddrPkg;
106   UINTN Bytes, Length, Index = 0;
107 
108   // AML encoding: PackageOp
109   if (DSD_Data[0] == 0x12) {
110     // AML encoding: PkgLength
111     Bytes = AmlGetPkgLength (&DSD_Data[1], &Length);
112 
113     // Search for "mac-address" property
114     MacAddrPkg = AmlSearchStringPackage (&DSD_Data[Bytes + 1],
115                                         Length - Bytes,
116                                         "mac-address");
117     if (MacAddrPkg &&
118         MacAddrPkg[0] == 0x12 &&        // PackageOp
119         MacAddrPkg[1] == 0x0E &&        // PkgLength
120         MacAddrPkg[2] == 0x06) {        // NumElements (element must have a BytePrefix)
121 
122       MacAddrPkg += 3;
123       do {
124         MacAddrPkg[0] = 0x0A;           // BytePrefix
125         MacAddrPkg[1] = (UINT8)(MacAddr & 0xFF);
126         MacAddrPkg += 2;
127         MacAddr >>= 8;
128       } while (++Index < 6);
129     }
130   }
131 }
132 
133 VOID
OverrideStatus(IN UINT8 * DSD_Data,IN BOOLEAN Enable)134 OverrideStatus (
135   IN UINT8 *DSD_Data,
136   IN BOOLEAN Enable
137   )
138 {
139   if (Enable) {
140     // AML encoding: ReturnOp + BytePrefix
141     if (DSD_Data[1] == 0xA4 && DSD_Data[2] == 0x0A) {
142       DSD_Data[3] = 0x0F;
143     }
144   } else {
145     // AML encoding: ReturnOp
146     if (DSD_Data[1] == 0xA4) {
147       // AML encoding: BytePrefix?
148       if (DSD_Data[2] == 0x0A) {
149         DSD_Data[3] = 0x00;
150       } else {
151         DSD_Data[2] = 0x00;
152       }
153     }
154   }
155 }
156 
157 EFI_ACPI_DESCRIPTION_HEADER *
DsdtHeader(VOID)158 DsdtHeader (
159   VOID
160   )
161 {
162   AML_OFFSET_TABLE_ENTRY *Table;
163   BOOLEAN                EnableOnB1;
164   UINT32                 CpuId = PcdGet32 (PcdSocCpuId);
165 
166   // Enable features on Styx-B1 or later
167   EnableOnB1 = (CpuId & 0xFF0) && (CpuId & 0x00F);
168 
169   Table = &DSDT_SEATTLE__OffsetTable[0];
170   while (Table->Pathname) {
171     if (AsciiStrCmp(Table->Pathname, "_SB_.ETH0._DSD") == 0) {
172       OverrideMacAddr ((UINT8 *)&AmlCode[Table->Offset], PcdGet64 (PcdEthMacA));
173     }
174     else if (AsciiStrCmp(Table->Pathname, "_SB_.ETH1._DSD") == 0) {
175       OverrideMacAddr ((UINT8 *)&AmlCode[Table->Offset], PcdGet64 (PcdEthMacB));
176     }
177     else if (AsciiStrCmp(Table->Pathname, "_SB_.AHC1._STA") == 0) {
178       OverrideStatus ((UINT8 *)&AmlCode[Table->Offset],
179         EnableOnB1 && FixedPcdGet8(PcdSata1PortCount) > 0);
180     }
181     else if (AsciiStrCmp(Table->Pathname, "_SB_.GIO2._STA") == 0) {
182       OverrideStatus ((UINT8 *)&AmlCode[Table->Offset], EnableOnB1);
183     }
184     else if (AsciiStrCmp(Table->Pathname, "_SB_.GIO3._STA") == 0) {
185       OverrideStatus ((UINT8 *)&AmlCode[Table->Offset], EnableOnB1);
186     }
187 
188     ++Table;
189   }
190 
191   return (EFI_ACPI_DESCRIPTION_HEADER *) &AmlCode[0];
192 }
193