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