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