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