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