]> git.proxmox.com Git - mirror_edk2.git/blame - UnixPkg/CpuRuntimeDxe/CpuIo.c
1. Correct File header to ## @file
[mirror_edk2.git] / UnixPkg / CpuRuntimeDxe / CpuIo.c
CommitLineData
804405e7 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
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
24--*/\r
bac49e77 25#include <FrameworkDxe.h>\r
804405e7 26#include <Protocol/Cpu.h>\r
27#include <Protocol/DataHub.h>\r
28#include <Guid/DataHubRecords.h>\r
5161b24d 29#include <Protocol/CpuIo2.h>\r
804405e7 30#include <Protocol/FrameworkHii.h>\r
804405e7 31\r
32#include <Library/BaseLib.h>\r
33#include <Library/DebugLib.h>\r
34#include <Library/HiiLib.h>\r
35#include <Library/UefiLib.h>\r
36#include <Library/UefiDriverEntryPoint.h>\r
37#include <Library/BaseMemoryLib.h>\r
38#include <Library/MemoryAllocationLib.h>\r
39#include <Library/UefiBootServicesTableLib.h>\r
40#include <CpuDriver.h>\r
41\r
42#define IA32_MAX_IO_ADDRESS 0xFFFF\r
43#define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF\r
44\r
804405e7 45EFI_STATUS\r
46CpuIoCheckAddressRange (\r
47 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
48 IN UINT64 Address,\r
49 IN UINTN Count,\r
50 IN VOID *Buffer,\r
51 IN UINT64 Limit\r
52 );\r
53\r
54EFI_STATUS\r
55EFIAPI\r
56CpuMemoryServiceRead (\r
5161b24d 57 IN EFI_CPU_IO2_PROTOCOL *This,\r
804405e7 58 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
59 IN UINT64 Address,\r
60 IN UINTN Count,\r
61 IN OUT VOID *Buffer\r
62 )\r
63/*++\r
64\r
65Routine Description:\r
66\r
67 Perform the Memory Access Read service for the CPU I/O Protocol\r
68\r
69Arguments:\r
70\r
71 Pointer to an instance of the CPU I/O Protocol\r
72 Width of the Memory Access\r
73 Address of the Memory access\r
74 Count of the number of accesses to perform\r
75 Pointer to the buffer to read or write from memory\r
76\r
77Returns:\r
78\r
79 Status\r
80\r
81 EFI_SUCCESS - The data was read from or written to the EFI \r
82 System.\r
83 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
84 EFI_INVALID_PARAMETER - Buffer is NULL.\r
85 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
86 EFI_UNSUPPORTED - The address range specified by Address, Width, \r
87 and Count is not valid for this EFI System.\r
88\r
89--*/\r
90// TODO: This - add argument and description to function comment\r
91{\r
92 EFI_STATUS Status;\r
93\r
94 if (!Buffer) {\r
95 return EFI_INVALID_PARAMETER;\r
96 }\r
97\r
98 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
99 if (EFI_ERROR (Status)) {\r
100 return Status;\r
101 }\r
102\r
103 //\r
104 // Do nothing for Nt32 version\r
105 //\r
106 return EFI_SUCCESS;\r
107}\r
108\r
109EFI_STATUS\r
110EFIAPI\r
111CpuMemoryServiceWrite (\r
5161b24d 112 IN EFI_CPU_IO2_PROTOCOL *This,\r
804405e7 113 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
114 IN UINT64 Address,\r
115 IN UINTN Count,\r
116 IN OUT VOID *Buffer\r
117 )\r
118/*++\r
119\r
120Routine Description:\r
121\r
122 Perform the Memory Access Read service for the CPU I/O Protocol\r
123\r
124Arguments:\r
125\r
126 Pointer to an instance of the CPU I/O Protocol\r
127 Width of the Memory Access\r
128 Address of the Memory access\r
129 Count of the number of accesses to perform\r
130 Pointer to the buffer to read or write from memory\r
131\r
132Returns:\r
133\r
134 Status\r
135\r
136 EFI_SUCCESS - The data was read from or written to the EFI System.\r
137 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
138 EFI_INVALID_PARAMETER - Buffer is NULL.\r
139 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
140 EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
141 Count is not valid for this EFI System.\r
142\r
143--*/\r
144// TODO: This - add argument and description to function comment\r
145{\r
146 EFI_STATUS Status;\r
147\r
148 if (!Buffer) {\r
149 return EFI_INVALID_PARAMETER;\r
150 }\r
151\r
152 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
153 if (EFI_ERROR (Status)) {\r
154 return Status;\r
155 }\r
156\r
157 //\r
158 // Do nothing for Nt32 version\r
159 //\r
160 return EFI_SUCCESS;\r
161}\r
162\r
163EFI_STATUS\r
164EFIAPI\r
165CpuIoServiceRead (\r
5161b24d 166 IN EFI_CPU_IO2_PROTOCOL *This,\r
804405e7 167 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
168 IN UINT64 UserAddress,\r
169 IN UINTN Count,\r
170 IN OUT VOID *UserBuffer\r
171 )\r
172/*++\r
173\r
174Routine Description:\r
175 \r
176 This is the service that implements the I/O read\r
177\r
178Arguments:\r
179\r
180 Pointer to an instance of the CPU I/O Protocol\r
181 Width of the Memory Access\r
182 Address of the I/O access\r
183 Count of the number of accesses to perform\r
184 Pointer to the buffer to read or write from I/O space\r
185\r
186Returns:\r
187\r
188 Status\r
189 EFI_SUCCESS - The data was read from or written to the EFI System.\r
190 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
191 EFI_INVALID_PARAMETER - Buffer is NULL.\r
192 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
193 EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
194 Count is not valid for this EFI System.\r
195--*/\r
196// TODO: This - add argument and description to function comment\r
197// TODO: UserAddress - add argument and description to function comment\r
198// TODO: UserBuffer - add argument and description to function comment\r
199{\r
200 UINTN Address;\r
201 EFI_STATUS Status;\r
202\r
203 if (!UserBuffer) {\r
204 return EFI_INVALID_PARAMETER;\r
205 }\r
206\r
207 Address = (UINTN) UserAddress;\r
208\r
209 if (Width >= EfiCpuIoWidthMaximum) {\r
210 return EFI_INVALID_PARAMETER;\r
211 }\r
212\r
213 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
214 if (EFI_ERROR (Status)) {\r
215 return Status;\r
216 }\r
217\r
218 //\r
219 // Do nothing for Nt32 version\r
220 //\r
221 return EFI_SUCCESS;\r
222}\r
223\r
224EFI_STATUS\r
225EFIAPI\r
226CpuIoServiceWrite (\r
5161b24d 227 IN EFI_CPU_IO2_PROTOCOL *This,\r
804405e7 228 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
229 IN UINT64 UserAddress,\r
230 IN UINTN Count,\r
231 IN OUT VOID *UserBuffer\r
232 )\r
233/*++\r
234\r
235Routine Description:\r
236\r
237 \r
238 This is the service that implements the I/O Write\r
239\r
240Arguments:\r
241\r
242 Pointer to an instance of the CPU I/O Protocol\r
243 Width of the Memory Access\r
244 Address of the I/O access\r
245 Count of the number of accesses to perform\r
246 Pointer to the buffer to read or write from I/O space\r
247\r
248Returns:\r
249\r
250 Status\r
251\r
252 Status\r
253 EFI_SUCCESS - The data was read from or written to the EFI System.\r
254 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
255 EFI_INVALID_PARAMETER - Buffer is NULL.\r
256 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
257 EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
258 Count is not valid for this EFI System.\r
259\r
260--*/\r
261// TODO: This - add argument and description to function comment\r
262// TODO: UserAddress - add argument and description to function comment\r
263// TODO: UserBuffer - add argument and description to function comment\r
264{\r
265 UINTN Address;\r
266 EFI_STATUS Status;\r
267\r
268 if (!UserBuffer) {\r
269 return EFI_INVALID_PARAMETER;\r
270 }\r
271\r
272 Address = (UINTN) UserAddress;\r
273\r
274 if (Width >= EfiCpuIoWidthMaximum) {\r
275 return EFI_INVALID_PARAMETER;\r
276 }\r
277\r
278 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
279 if (EFI_ERROR (Status)) {\r
280 return Status;\r
281 }\r
282\r
283 //\r
284 // Do nothing for Nt32 version\r
285 //\r
286 return EFI_SUCCESS;\r
287}\r
288\r
289\r
290EFI_STATUS\r
291CpuIoCheckAddressRange (\r
292 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
293 IN UINT64 Address,\r
294 IN UINTN Count,\r
295 IN VOID *Buffer,\r
296 IN UINT64 Limit\r
297 )\r
298/*++\r
299\r
300Routine Description:\r
301\r
302 TODO: Add function description\r
303\r
304Arguments:\r
305\r
306 Width - TODO: add argument description\r
307 Address - TODO: add argument description\r
308 Count - TODO: add argument description\r
309 Buffer - TODO: add argument description\r
310 Limit - TODO: add argument description\r
311\r
312Returns:\r
313\r
314 EFI_UNSUPPORTED - TODO: Add description for return value\r
315 EFI_UNSUPPORTED - TODO: Add description for return value\r
316 EFI_UNSUPPORTED - TODO: Add description for return value\r
317 EFI_SUCCESS - TODO: Add description for return value\r
318\r
319--*/\r
320{\r
321 UINTN AlignMask;\r
322\r
323 if (Address > Limit) {\r
324 return EFI_UNSUPPORTED;\r
325 }\r
326\r
327 //\r
328 // For FiFo type, the target address won't increase during the access, so treat count as 1\r
329 //\r
330 if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {\r
331 Count = 1;\r
332 }\r
333\r
334 Width = Width & 0x03;\r
335 if (Address - 1 + (1 << Width) * Count > Limit) {\r
336 return EFI_UNSUPPORTED;\r
337 }\r
338\r
339 AlignMask = (1 << Width) - 1;\r
340 if ((UINTN) Buffer & AlignMask) {\r
341 return EFI_UNSUPPORTED;\r
342 }\r
343\r
344 return EFI_SUCCESS;\r
345}\r
346\r
347\r