]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/CpuRuntimeDxe/CpuIo.c
We enabled X64 native version NT32, and made it works on Windows 7 X64 OS.
[mirror_edk2.git] / Nt32Pkg / CpuRuntimeDxe / CpuIo.c
CommitLineData
6ae81428 1/**@file\r
9d0c70ff 2\r
f66a43b2 3Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
8f2a5f80 4This program and the accompanying materials \r
9d0c70ff 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 CpuIo.c\r
15\r
16Abstract:\r
17\r
18 This is the code that publishes the CPU I/O Protocol.\r
19 The intent herein is to have a single I/O service that can load\r
20 as early as possible, extend into runtime, and be layered upon by \r
21 the implementations of architectural protocols and the PCI Root\r
22 Bridge I/O Protocol.\r
23\r
6ae81428 24**/\r
9d0c70ff 25\r
26#include <CpuDriver.h>\r
27\r
28#define IA32_MAX_IO_ADDRESS 0xFFFF\r
29#define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF\r
30\r
9d0c70ff 31EFI_STATUS\r
32CpuIoCheckAddressRange (\r
33 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
34 IN UINT64 Address,\r
35 IN UINTN Count,\r
36 IN VOID *Buffer,\r
37 IN UINT64 Limit\r
38 );\r
39\r
40EFI_STATUS\r
41EFIAPI\r
42CpuMemoryServiceRead (\r
b8d5cb49 43 IN EFI_CPU_IO2_PROTOCOL *This,\r
9d0c70ff 44 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
45 IN UINT64 Address,\r
46 IN UINTN Count,\r
47 IN OUT VOID *Buffer\r
48 )\r
49/*++\r
50\r
51Routine Description:\r
52\r
53 Perform the Memory Access Read service for the CPU I/O Protocol\r
54\r
55Arguments:\r
56\r
57 Pointer to an instance of the CPU I/O Protocol\r
58 Width of the Memory Access\r
59 Address of the Memory access\r
60 Count of the number of accesses to perform\r
61 Pointer to the buffer to read or write from memory\r
62\r
63Returns:\r
64\r
65 Status\r
66\r
67 EFI_SUCCESS - The data was read from or written to the EFI \r
68 System.\r
69 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
70 EFI_INVALID_PARAMETER - Buffer is NULL.\r
71 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
72 EFI_UNSUPPORTED - The address range specified by Address, Width, \r
73 and Count is not valid for this EFI System.\r
74\r
75--*/\r
76// TODO: This - add argument and description to function comment\r
77{\r
78 EFI_STATUS Status;\r
79\r
80 if (!Buffer) {\r
81 return EFI_INVALID_PARAMETER;\r
82 }\r
83\r
9c1d98d8 84 if ((Width < 0) || (Width >= EfiCpuIoWidthMaximum)) {\r
85 return EFI_INVALID_PARAMETER;\r
86 }\r
87\r
9d0c70ff 88 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
89 if (EFI_ERROR (Status)) {\r
90 return Status;\r
91 }\r
92\r
93 //\r
94 // Do nothing for Nt32 version\r
95 //\r
2022142e 96 return EFI_UNSUPPORTED;\r
9d0c70ff 97}\r
98\r
99EFI_STATUS\r
100EFIAPI\r
101CpuMemoryServiceWrite (\r
b8d5cb49 102 IN EFI_CPU_IO2_PROTOCOL *This,\r
9d0c70ff 103 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
104 IN UINT64 Address,\r
105 IN UINTN Count,\r
106 IN OUT VOID *Buffer\r
107 )\r
108/*++\r
109\r
110Routine Description:\r
111\r
112 Perform the Memory Access Read service for the CPU I/O Protocol\r
113\r
114Arguments:\r
115\r
116 Pointer to an instance of the CPU I/O Protocol\r
117 Width of the Memory Access\r
118 Address of the Memory access\r
119 Count of the number of accesses to perform\r
120 Pointer to the buffer to read or write from memory\r
121\r
122Returns:\r
123\r
124 Status\r
125\r
126 EFI_SUCCESS - The data was read from or written to the EFI System.\r
127 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
128 EFI_INVALID_PARAMETER - Buffer is NULL.\r
129 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
130 EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
131 Count is not valid for this EFI System.\r
132\r
133--*/\r
134// TODO: This - add argument and description to function comment\r
135{\r
136 EFI_STATUS Status;\r
137\r
138 if (!Buffer) {\r
139 return EFI_INVALID_PARAMETER;\r
140 }\r
141\r
9c1d98d8 142 if ((Width < 0) || (Width >= EfiCpuIoWidthMaximum)) {\r
143 return EFI_INVALID_PARAMETER;\r
144 }\r
145\r
9d0c70ff 146 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
147 if (EFI_ERROR (Status)) {\r
148 return Status;\r
149 }\r
150\r
151 //\r
152 // Do nothing for Nt32 version\r
153 //\r
2022142e 154 return EFI_UNSUPPORTED;\r
9d0c70ff 155}\r
156\r
157EFI_STATUS\r
158EFIAPI\r
159CpuIoServiceRead (\r
b8d5cb49 160 IN EFI_CPU_IO2_PROTOCOL *This,\r
9d0c70ff 161 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
162 IN UINT64 UserAddress,\r
163 IN UINTN Count,\r
164 IN OUT VOID *UserBuffer\r
165 )\r
166/*++\r
167\r
168Routine Description:\r
169 \r
170 This is the service that implements the I/O read\r
171\r
172Arguments:\r
173\r
174 Pointer to an instance of the CPU I/O Protocol\r
175 Width of the Memory Access\r
176 Address of the I/O access\r
177 Count of the number of accesses to perform\r
178 Pointer to the buffer to read or write from I/O space\r
179\r
180Returns:\r
181\r
182 Status\r
183 EFI_SUCCESS - The data was read from or written to the EFI System.\r
184 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
185 EFI_INVALID_PARAMETER - Buffer is NULL.\r
186 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
187 EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
188 Count is not valid for this EFI System.\r
189--*/\r
190// TODO: This - add argument and description to function comment\r
191// TODO: UserAddress - add argument and description to function comment\r
192// TODO: UserBuffer - add argument and description to function comment\r
193{\r
194 UINTN Address;\r
195 EFI_STATUS Status;\r
196\r
197 if (!UserBuffer) {\r
198 return EFI_INVALID_PARAMETER;\r
199 }\r
200\r
201 Address = (UINTN) UserAddress;\r
202\r
9c1d98d8 203 if ((Width < 0) || (Width >= EfiCpuIoWidthMaximum)) {\r
9d0c70ff 204 return EFI_INVALID_PARAMETER;\r
205 }\r
206\r
207 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
208 if (EFI_ERROR (Status)) {\r
209 return Status;\r
210 }\r
211\r
212 //\r
213 // Do nothing for Nt32 version\r
214 //\r
2022142e 215 return EFI_UNSUPPORTED;\r
9d0c70ff 216}\r
217\r
218EFI_STATUS\r
219EFIAPI\r
220CpuIoServiceWrite (\r
b8d5cb49 221 IN EFI_CPU_IO2_PROTOCOL *This,\r
9d0c70ff 222 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
223 IN UINT64 UserAddress,\r
224 IN UINTN Count,\r
225 IN OUT VOID *UserBuffer\r
226 )\r
227/*++\r
228\r
229Routine Description:\r
230\r
231 \r
232 This is the service that implements the I/O Write\r
233\r
234Arguments:\r
235\r
236 Pointer to an instance of the CPU I/O Protocol\r
237 Width of the Memory Access\r
238 Address of the I/O access\r
239 Count of the number of accesses to perform\r
240 Pointer to the buffer to read or write from I/O space\r
241\r
242Returns:\r
243\r
244 Status\r
245\r
246 Status\r
247 EFI_SUCCESS - The data was read from or written to the EFI System.\r
248 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
249 EFI_INVALID_PARAMETER - Buffer is NULL.\r
250 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
251 EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
252 Count is not valid for this EFI System.\r
253\r
254--*/\r
255// TODO: This - add argument and description to function comment\r
256// TODO: UserAddress - add argument and description to function comment\r
257// TODO: UserBuffer - add argument and description to function comment\r
258{\r
259 UINTN Address;\r
260 EFI_STATUS Status;\r
261\r
262 if (!UserBuffer) {\r
263 return EFI_INVALID_PARAMETER;\r
264 }\r
265\r
266 Address = (UINTN) UserAddress;\r
267\r
9c1d98d8 268 if ((Width < 0) || (Width >= EfiCpuIoWidthMaximum)) {\r
9d0c70ff 269 return EFI_INVALID_PARAMETER;\r
270 }\r
271\r
272 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
273 if (EFI_ERROR (Status)) {\r
274 return Status;\r
275 }\r
276\r
277 //\r
278 // Do nothing for Nt32 version\r
279 //\r
2022142e 280 return EFI_UNSUPPORTED;\r
9d0c70ff 281}\r
282\r
283\r
284EFI_STATUS\r
285CpuIoCheckAddressRange (\r
286 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
287 IN UINT64 Address,\r
288 IN UINTN Count,\r
289 IN VOID *Buffer,\r
290 IN UINT64 Limit\r
291 )\r
292/*++\r
293\r
294Routine Description:\r
295\r
296 TODO: Add function description\r
297\r
298Arguments:\r
299\r
300 Width - TODO: add argument description\r
301 Address - TODO: add argument description\r
302 Count - TODO: add argument description\r
303 Buffer - TODO: add argument description\r
304 Limit - TODO: add argument description\r
305\r
306Returns:\r
307\r
308 EFI_UNSUPPORTED - TODO: Add description for return value\r
309 EFI_UNSUPPORTED - TODO: Add description for return value\r
310 EFI_UNSUPPORTED - TODO: Add description for return value\r
311 EFI_SUCCESS - TODO: Add description for return value\r
312\r
313--*/\r
314{\r
315 UINTN AlignMask;\r
316\r
317 if (Address > Limit) {\r
318 return EFI_UNSUPPORTED;\r
319 }\r
320\r
321 //\r
322 // For FiFo type, the target address won't increase during the access, so treat count as 1\r
323 //\r
324 if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {\r
325 Count = 1;\r
326 }\r
327\r
0b94e319 328 Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);\r
f66a43b2 329 if (Address - 1 + ((UINTN)1 << Width) * Count > Limit) {\r
9d0c70ff 330 return EFI_UNSUPPORTED;\r
331 }\r
332\r
f66a43b2 333 AlignMask = ((UINTN)1 << Width) - 1;\r
9d0c70ff 334 if ((UINTN) Buffer & AlignMask) {\r
335 return EFI_UNSUPPORTED;\r
336 }\r
337\r
338 return EFI_SUCCESS;\r
339}\r
340\r
341\r