1## @file
2#  Apply fixup to VTF binary image for FFS Raw section
3#
4#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
5#
6#  SPDX-License-Identifier: BSD-2-Clause-Patent
7#
8
9import sys
10
11filename = sys.argv[1]
12
13if filename.lower().find('ia32') >= 0:
14    d = open(sys.argv[1], 'rb').read()
15    c = ((len(d) + 4 + 7) & ~7) - 4
16    if c > len(d):
17        c -= len(d)
18        f = open(sys.argv[1], 'wb')
19        f.write('\x90' * c)
20        f.write(d)
21        f.close()
22else:
23    from struct import pack
24
25    PAGE_PRESENT             =     0x01
26    PAGE_READ_WRITE          =     0x02
27    PAGE_USER_SUPERVISOR     =     0x04
28    PAGE_WRITE_THROUGH       =     0x08
29    PAGE_CACHE_DISABLE       =    0x010
30    PAGE_ACCESSED            =    0x020
31    PAGE_DIRTY               =    0x040
32    PAGE_PAT                 =    0x080
33    PAGE_GLOBAL              =   0x0100
34    PAGE_2M_MBO              =    0x080
35    PAGE_2M_PAT              =  0x01000
36
37    def NopAlign4k(s):
38        c = ((len(s) + 0xfff) & ~0xfff) - len(s)
39        return ('\x90' * c) + s
40
41    def PageDirectoryEntries4GbOf2MbPages(baseAddress):
42
43        s = ''
44        for i in range(0x800):
45            i = (
46                    baseAddress + long(i << 21) +
47                    PAGE_2M_MBO +
48                    PAGE_CACHE_DISABLE +
49                    PAGE_ACCESSED +
50                    PAGE_DIRTY +
51                    PAGE_READ_WRITE +
52                    PAGE_PRESENT
53                )
54            s += pack('Q', i)
55        return s
56
57    def PageDirectoryPointerTable4GbOf2MbPages(pdeBase):
58        s = ''
59        for i in range(0x200):
60            i = (
61                    pdeBase +
62                    (min(i, 3) << 12) +
63                    PAGE_CACHE_DISABLE +
64                    PAGE_ACCESSED +
65                    PAGE_READ_WRITE +
66                    PAGE_PRESENT
67                )
68            s += pack('Q', i)
69        return s
70
71    def PageMapLevel4Table4GbOf2MbPages(pdptBase):
72        s = ''
73        for i in range(0x200):
74            i = (
75                    pdptBase +
76                    (min(i, 0) << 12) +
77                    PAGE_CACHE_DISABLE +
78                    PAGE_ACCESSED +
79                    PAGE_READ_WRITE +
80                    PAGE_PRESENT
81                )
82            s += pack('Q', i)
83        return s
84
85    def First4GbPageEntries(topAddress):
86        PDE = PageDirectoryEntries4GbOf2MbPages(0L)
87        pml4tBase = topAddress - 0x1000
88        pdptBase = pml4tBase - 0x1000
89        pdeBase = pdptBase - len(PDE)
90        PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase)
91        PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase)
92        return PDE + PDPT + PML4T
93
94    def AlignAndAddPageTables():
95        d = open(sys.argv[1], 'rb').read()
96        code = NopAlign4k(d)
97        topAddress = 0x100000000 - len(code)
98        d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code
99        f = open(sys.argv[1], 'wb')
100        f.write(d)
101        f.close()
102
103    AlignAndAddPageTables()
104
105