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