-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathQemuFwCfgAcpi.c.patch
92 lines (88 loc) · 2.88 KB
/
QemuFwCfgAcpi.c.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
index a0b1cfd2be..660007a74e 100644
--- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
+++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
@@ -24,6 +24,8 @@
#include <Library/PcdLib.h>
#include <Library/OrderedCollectionLib.h>
#include <IndustryStandard/Acpi.h>
+#include "vrom.h"
+#include "vrom_table.h"
//
@@ -1107,6 +1110,77 @@ InstallQemuFwCfgTables (
}
}
}
+
+ // modification: add additional SSDT
+ UINT32 VromSize = 256*1024;
+ UINT8* FwData = AllocateRuntimePool(VromSize); // 256*1024 = 256 KB = size of VROM image
+
+ // copy VROM to FwData
+ CopyMem (FwData, VROM_BIN, VROM_BIN_LEN);
+
+ // header of SSDT table: DefinitionBlock ("Ssdt.aml", "SSDT", 1, "REDHAT", "OVMF ", 1)
+ unsigned char Ssdt_header[] = {
+ 0x53, 0x53, 0x44, 0x54, 0x24, 0x00, 0x00, 0x00, 0x01, 0x86, 0x52, 0x45,
+ 0x44, 0x48, 0x41, 0x54, 0x4f, 0x56, 0x4d, 0x46, 0x20, 0x20, 0x20, 0x20,
+ 0x01, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x54, 0x4c, 0x31, 0x08, 0x16, 0x20
+ };
+
+ // byte 4-7: length header + table in little endian (so equal to SsdtSize)
+ // byte 8: version complicance number: nothing needs to change
+ // byte 9: set such that when all bytes are added modulo 256 the sum equals 0
+ // calculate checksum: already implemented as CalculateCheckSum8(offset, length)
+
+ unsigned int Ssdt_header_len = 36;
+
+ UINTN SsdtSize;
+ UINT8 *Ssdt;
+
+ SsdtSize = Ssdt_header_len + 17 + vrom_table_len;
+ Ssdt = AllocatePool (SsdtSize);
+
+ UINT8 *SsdtPtr = Ssdt;
+
+ // copy header to Ssdt table
+ CopyMem (SsdtPtr, Ssdt_header, Ssdt_header_len);
+ SsdtPtr += Ssdt_header_len;
+
+ // build "OperationRegion(FWDT, SystemMemory, 0x12345678, 0x87654321)"
+ //
+ *(SsdtPtr++) = 0x5B; // ExtOpPrefix
+ *(SsdtPtr++) = 0x80; // OpRegionOp
+ *(SsdtPtr++) = 'V';
+ *(SsdtPtr++) = 'B';
+ *(SsdtPtr++) = 'O';
+ *(SsdtPtr++) = 'R';
+ *(SsdtPtr++) = 0x00; // SystemMemory
+ *(SsdtPtr++) = 0x0C; // DWordPrefix
+
+ //
+ // no virtual addressing yet, take the four least significant bytes
+ //
+ CopyMem(SsdtPtr, &FwData, 4);
+ SsdtPtr += 4;
+
+ *(SsdtPtr++) = 0x0C; // DWordPrefix
+
+ *(UINT32*) SsdtPtr = VromSize;
+ SsdtPtr += 4;
+
+ CopyMem (SsdtPtr, vrom_table, vrom_table_len);
+
+ // set the correct size in the header
+ UINT32* size_ptr = (UINT32*) &Ssdt[4];
+ *size_ptr = SsdtSize;
+
+ // set byte 9 of header so the checksum equals 0
+ Ssdt[9] = 0;
+ UINT32 checksum = CalculateCheckSum8(Ssdt, SsdtSize);
+ Ssdt[9] = (256 - checksum) % 256;
+
+ Status = AcpiProtocol->InstallAcpiTable (AcpiProtocol,
+ (VOID *) Ssdt, SsdtSize,
+ &InstalledKey[Installed]);
+ ++Installed;
//
// Translating the condensed QEMU_LOADER_WRITE_POINTER commands to ACPI S3