Initial import.
[mirror_edk2.git] / EdkModulePkg / Universal / Runtime / RuntimeDxe / Ipf / PeHotRelocateEx.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PeHotRelocateEx.c
15
16 Abstract:
17
18 Fixes IPF specific relocation types
19
20
21 Revision History
22
23 --*/
24
25 #include "Runtime.h"
26 #include "PeHotRelocateEx.h"
27
28 EFI_STATUS
29 PeHotRelocateImageEx (
30 IN UINT16 *Reloc,
31 IN OUT CHAR8 *Fixup,
32 IN OUT CHAR8 **FixupData,
33 IN UINT64 Adjust
34 )
35 /*++
36
37 Routine Description:
38
39 Performs an IPF specific relocation fixup
40
41 Arguments:
42
43 Reloc - Pointer to the relocation record
44
45 Fixup - Pointer to the address to fix up
46
47 FixupData - Pointer to a buffer to log the fixups
48
49 Adjust - The offset to adjust the fixup
50
51 Returns:
52
53 None
54
55 --*/
56 {
57 UINT64 *F64;
58 UINT64 FixupVal;
59
60 switch ((*Reloc) >> 12) {
61 case EFI_IMAGE_REL_BASED_DIR64:
62 F64 = (UINT64 *) Fixup;
63 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));
64 if (*(UINT64 *) (*FixupData) == *F64) {
65 *F64 = *F64 + (UINT64) Adjust;
66 }
67
68 *FixupData = *FixupData + sizeof (UINT64);
69 break;
70
71 case EFI_IMAGE_REL_BASED_IA64_IMM64:
72 F64 = (UINT64 *) Fixup;
73 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));
74 if (*(UINT64 *) (*FixupData) == *F64) {
75 //
76 // Align it to bundle address before fixing up the
77 // 64-bit immediate value of the movl instruction.
78 //
79 //
80 Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));
81 FixupVal = (UINT64) 0;
82
83 //
84 // Extract the lower 32 bits of IMM64 from bundle
85 //
86 EXT_IMM64 (
87 FixupVal,
88 (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,
89 IMM64_IMM7B_SIZE_X,
90 IMM64_IMM7B_INST_WORD_POS_X,
91 IMM64_IMM7B_VAL_POS_X
92 );
93
94 EXT_IMM64 (
95 FixupVal,
96 (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,
97 IMM64_IMM9D_SIZE_X,
98 IMM64_IMM9D_INST_WORD_POS_X,
99 IMM64_IMM9D_VAL_POS_X
100 );
101
102 EXT_IMM64 (
103 FixupVal,
104 (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,
105 IMM64_IMM5C_SIZE_X,
106 IMM64_IMM5C_INST_WORD_POS_X,
107 IMM64_IMM5C_VAL_POS_X
108 );
109
110 EXT_IMM64 (
111 FixupVal,
112 (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,
113 IMM64_IC_SIZE_X,
114 IMM64_IC_INST_WORD_POS_X,
115 IMM64_IC_VAL_POS_X
116 );
117
118 EXT_IMM64 (
119 FixupVal,
120 (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,
121 IMM64_IMM41a_SIZE_X,
122 IMM64_IMM41a_INST_WORD_POS_X,
123 IMM64_IMM41a_VAL_POS_X
124 );
125
126 //
127 // Update 64-bit address
128 //
129 FixupVal += Adjust;
130
131 //
132 // Insert IMM64 into bundle
133 //
134 INS_IMM64 (
135 FixupVal,
136 ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),
137 IMM64_IMM7B_SIZE_X,
138 IMM64_IMM7B_INST_WORD_POS_X,
139 IMM64_IMM7B_VAL_POS_X
140 );
141
142 INS_IMM64 (
143 FixupVal,
144 ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),
145 IMM64_IMM9D_SIZE_X,
146 IMM64_IMM9D_INST_WORD_POS_X,
147 IMM64_IMM9D_VAL_POS_X
148 );
149
150 INS_IMM64 (
151 FixupVal,
152 ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),
153 IMM64_IMM5C_SIZE_X,
154 IMM64_IMM5C_INST_WORD_POS_X,
155 IMM64_IMM5C_VAL_POS_X
156 );
157
158 INS_IMM64 (
159 FixupVal,
160 ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),
161 IMM64_IC_SIZE_X,
162 IMM64_IC_INST_WORD_POS_X,
163 IMM64_IC_VAL_POS_X
164 );
165
166 INS_IMM64 (
167 FixupVal,
168 ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),
169 IMM64_IMM41a_SIZE_X,
170 IMM64_IMM41a_INST_WORD_POS_X,
171 IMM64_IMM41a_VAL_POS_X
172 );
173
174 INS_IMM64 (
175 FixupVal,
176 ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),
177 IMM64_IMM41b_SIZE_X,
178 IMM64_IMM41b_INST_WORD_POS_X,
179 IMM64_IMM41b_VAL_POS_X
180 );
181
182 INS_IMM64 (
183 FixupVal,
184 ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),
185 IMM64_IMM41c_SIZE_X,
186 IMM64_IMM41c_INST_WORD_POS_X,
187 IMM64_IMM41c_VAL_POS_X
188 );
189
190 INS_IMM64 (
191 FixupVal,
192 ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),
193 IMM64_SIGN_SIZE_X,
194 IMM64_SIGN_INST_WORD_POS_X,
195 IMM64_SIGN_VAL_POS_X
196 );
197
198 *(UINT64 *) (*FixupData) = *F64;
199 }
200
201 *FixupData = *FixupData + sizeof (UINT64);
202 break;
203
204 default:
205 DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));
206 return EFI_UNSUPPORTED;
207 }
208
209 return EFI_SUCCESS;
210 }
211
212
213 //
214 // Cache Flush Routine.
215 //
216 EFI_STATUS
217 FlushCpuCache (
218 IN EFI_PHYSICAL_ADDRESS Start,
219 IN UINT64 Length
220 )
221 /*++
222
223 Routine Description:
224
225 Flush cache with specified range.
226
227 Arguments:
228
229 Start - Start address
230 Length - Length in bytes
231
232 Returns:
233
234 Status code
235
236 EFI_SUCCESS - success
237
238 --*/
239 {
240 SalFlushCache (Start, Length);
241 return EFI_SUCCESS;
242 }