]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoLib.c
Program SD Cards into 4-bit mode (support for this is required in the spec). This...
[mirror_edk2.git] / IntelFrameworkPkg / Library / DxeIoLibCpuIo / IoLib.c
CommitLineData
79964ac8 1/** @file\r
2 I/O Library.\r
c4fa3eac 3 The implementation of I/O operation for this library instance \r
4 are based on EFI_CPU_IO_PROTOCOL.\r
5 \r
2b3687db
HT
6 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
7 This program and the accompanying materials\r
79964ac8 8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15 Module Name: IoLib.c\r
16\r
17**/\r
18\r
694363f8 19\r
79964ac8 20#include "DxeCpuIoLibInternal.h"\r
21\r
22//\r
23// Globle varible to cache pointer to CpuIo protocol.\r
24//\r
33338afe 25EFI_CPU_IO_PROTOCOL *mCpuIo = NULL;\r
79964ac8 26\r
27/**\r
28 The constructor function caches the pointer to CpuIo protocol.\r
29\r
30 The constructor function locates CpuIo protocol from protocol database.\r
31 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
32\r
33 @param ImageHandle The firmware allocated handle for the EFI image.\r
34 @param SystemTable A pointer to the EFI System Table.\r
35\r
36 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
37\r
38**/\r
39EFI_STATUS\r
40EFIAPI\r
41IoLibConstructor (\r
42 IN EFI_HANDLE ImageHandle,\r
43 IN EFI_SYSTEM_TABLE *SystemTable\r
44 )\r
45{\r
33338afe 46 EFI_STATUS Status;\r
79964ac8 47\r
33338afe 48 Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &mCpuIo);\r
79964ac8 49 ASSERT_EFI_ERROR (Status);\r
50\r
51 return Status;\r
52}\r
53\r
54/**\r
55 Reads registers in the EFI CPU I/O space.\r
56\r
57 Reads the I/O port specified by Port with registers width specified by Width.\r
58 The read value is returned. If such operations are not supported, then ASSERT().\r
59 This function must guarantee that all I/O read and write operations are serialized.\r
60\r
61 @param Port The base address of the I/O operation.\r
62 The caller is responsible for aligning the Address if required.\r
63 @param Width The width of the I/O operation.\r
64\r
65 @return Data read from registers in the EFI CPU I/O space.\r
66\r
67**/\r
68UINT64\r
69EFIAPI\r
70IoReadWorker (\r
33338afe 71 IN UINTN Port,\r
72 IN EFI_CPU_IO_PROTOCOL_WIDTH Width\r
79964ac8 73 )\r
74{\r
75 EFI_STATUS Status;\r
76 UINT64 Data;\r
77\r
33338afe 78 Status = mCpuIo->Io.Read (mCpuIo, Width, Port, 1, &Data);\r
79964ac8 79 ASSERT_EFI_ERROR (Status);\r
80\r
81 return Data;\r
82}\r
83\r
84/**\r
85 Writes registers in the EFI CPU I/O space.\r
86\r
87 Writes the I/O port specified by Port with registers width and value specified by Width\r
88 and Data respectively. Data is returned. If such operations are not supported, then ASSERT().\r
89 This function must guarantee that all I/O read and write operations are serialized.\r
90\r
91 @param Port The base address of the I/O operation.\r
92 The caller is responsible for aligning the Address if required.\r
93 @param Width The width of the I/O operation.\r
94 @param Data The value to write to the I/O port.\r
95\r
96 @return The paramter of Data.\r
97\r
98**/\r
99UINT64\r
100EFIAPI\r
101IoWriteWorker (\r
33338afe 102 IN UINTN Port,\r
103 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
104 IN UINT64 Data\r
79964ac8 105 )\r
106{\r
33338afe 107 EFI_STATUS Status;\r
79964ac8 108\r
33338afe 109 Status = mCpuIo->Io.Write (mCpuIo, Width, Port, 1, &Data);\r
79964ac8 110 ASSERT_EFI_ERROR (Status);\r
111\r
112 return Data;\r
113}\r
114\r
115/**\r
116 Reads memory-mapped registers in the EFI system memory space.\r
117\r
118 Reads the MMIO registers specified by Address with registers width specified by Width.\r
119 The read value is returned. If such operations are not supported, then ASSERT().\r
120 This function must guarantee that all MMIO read and write operations are serialized.\r
121\r
122 @param Address The MMIO register to read.\r
123 The caller is responsible for aligning the Address if required.\r
124 @param Width The width of the I/O operation.\r
125\r
126 @return Data read from registers in the EFI system memory space.\r
127\r
128**/\r
129UINT64\r
130EFIAPI\r
131MmioReadWorker (\r
33338afe 132 IN UINTN Address,\r
133 IN EFI_CPU_IO_PROTOCOL_WIDTH Width\r
79964ac8 134 )\r
135{\r
33338afe 136 EFI_STATUS Status;\r
137 UINT64 Data;\r
79964ac8 138\r
33338afe 139 Status = mCpuIo->Mem.Read (mCpuIo, Width, Address, 1, &Data);\r
79964ac8 140 ASSERT_EFI_ERROR (Status);\r
141\r
142 return Data;\r
143}\r
144\r
145/**\r
146 Writes memory-mapped registers in the EFI system memory space.\r
147\r
148 Writes the MMIO registers specified by Address with registers width and value specified by Width\r
149 and Data respectively. Data is returned. If such operations are not supported, then ASSERT().\r
150 This function must guarantee that all MMIO read and write operations are serialized.\r
151\r
152 @param Address The MMIO register to read.\r
153 The caller is responsible for aligning the Address if required.\r
154 @param Width The width of the I/O operation.\r
7459094d 155 @param Data The value to write to the I/O port.\r
156 \r
79964ac8 157 @return Data read from registers in the EFI system memory space.\r
158\r
159**/\r
160UINT64\r
161EFIAPI\r
162MmioWriteWorker (\r
33338afe 163 IN UINTN Address,\r
164 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
165 IN UINT64 Data\r
79964ac8 166 )\r
167{\r
33338afe 168 EFI_STATUS Status;\r
79964ac8 169\r
33338afe 170 Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data);\r
79964ac8 171 ASSERT_EFI_ERROR (Status);\r
172\r
173 return Data;\r
174}\r
175\r
176/**\r
177 Reads an 8-bit I/O port.\r
178\r
179 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.\r
180 This function must guarantee that all I/O read and write operations are\r
181 serialized.\r
182\r
183 If 8-bit I/O port operations are not supported, then ASSERT().\r
184\r
185 @param Port The I/O port to read.\r
186\r
187 @return The value read.\r
188\r
189**/\r
190UINT8\r
191EFIAPI\r
192IoRead8 (\r
193 IN UINTN Port\r
194 )\r
195{\r
196 return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);\r
197}\r
198\r
199/**\r
200 Writes an 8-bit I/O port.\r
201\r
202 Writes the 8-bit I/O port specified by Port with the value specified by Value\r
203 and returns Value. This function must guarantee that all I/O read and write\r
204 operations are serialized.\r
205\r
206 If 8-bit I/O port operations are not supported, then ASSERT().\r
207\r
208 @param Port The I/O port to write.\r
209 @param Value The value to write to the I/O port.\r
210\r
211 @return The value written the I/O port.\r
212\r
213**/\r
214UINT8\r
215EFIAPI\r
216IoWrite8 (\r
217 IN UINTN Port,\r
218 IN UINT8 Value\r
219 )\r
220{\r
221 return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);\r
222}\r
223\r
224/**\r
225 Reads a 16-bit I/O port.\r
226\r
227 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.\r
228 This function must guarantee that all I/O read and write operations are\r
229 serialized.\r
230\r
596cecff 231 If Port is not aligned on a 16-bit boundary, then ASSERT().\r
232 \r
79964ac8 233 If 16-bit I/O port operations are not supported, then ASSERT().\r
234\r
235 @param Port The I/O port to read.\r
236\r
237 @return The value read.\r
238\r
239**/\r
240UINT16\r
241EFIAPI\r
242IoRead16 (\r
243 IN UINTN Port\r
244 )\r
245{\r
246 //\r
247 // Make sure Port is aligned on a 16-bit boundary.\r
248 //\r
249 ASSERT ((Port & 1) == 0);\r
250 return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);\r
251}\r
252\r
253/**\r
254 Writes a 16-bit I/O port.\r
255\r
256 Writes the 16-bit I/O port specified by Port with the value specified by Value\r
257 and returns Value. This function must guarantee that all I/O read and write\r
258 operations are serialized.\r
259\r
596cecff 260 If Port is not aligned on a 16-bit boundary, then ASSERT().\r
261\r
79964ac8 262 If 16-bit I/O port operations are not supported, then ASSERT().\r
263\r
264 @param Port The I/O port to write.\r
265 @param Value The value to write to the I/O port.\r
266\r
267 @return The value written the I/O port.\r
268\r
269**/\r
270UINT16\r
271EFIAPI\r
272IoWrite16 (\r
273 IN UINTN Port,\r
274 IN UINT16 Value\r
275 )\r
276{\r
277 //\r
278 // Make sure Port is aligned on a 16-bit boundary.\r
279 //\r
280 ASSERT ((Port & 1) == 0);\r
281 return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);\r
282}\r
283\r
284/**\r
285 Reads a 32-bit I/O port.\r
286\r
287 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.\r
288 This function must guarantee that all I/O read and write operations are\r
289 serialized.\r
596cecff 290 \r
291 If Port is not aligned on a 32-bit boundary, then ASSERT().\r
79964ac8 292\r
293 If 32-bit I/O port operations are not supported, then ASSERT().\r
294\r
295 @param Port The I/O port to read.\r
296\r
297 @return The value read.\r
298\r
299**/\r
300UINT32\r
301EFIAPI\r
302IoRead32 (\r
303 IN UINTN Port\r
304 )\r
305{\r
306 //\r
307 // Make sure Port is aligned on a 32-bit boundary.\r
308 //\r
309 ASSERT ((Port & 3) == 0);\r
310 return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);\r
311}\r
312\r
313/**\r
314 Writes a 32-bit I/O port.\r
315\r
316 Writes the 32-bit I/O port specified by Port with the value specified by Value\r
317 and returns Value. This function must guarantee that all I/O read and write\r
318 operations are serialized.\r
319\r
596cecff 320 If Port is not aligned on a 32-bit boundary, then ASSERT().\r
321\r
79964ac8 322 If 32-bit I/O port operations are not supported, then ASSERT().\r
323\r
324 @param Port The I/O port to write.\r
325 @param Value The value to write to the I/O port.\r
326\r
327 @return The value written the I/O port.\r
328\r
329**/\r
330UINT32\r
331EFIAPI\r
332IoWrite32 (\r
333 IN UINTN Port,\r
334 IN UINT32 Value\r
335 )\r
336{\r
337 //\r
338 // Make sure Port is aligned on a 32-bit boundary.\r
339 //\r
340 ASSERT ((Port & 3) == 0);\r
341 return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);\r
342}\r
343\r
344/**\r
345 Reads a 64-bit I/O port.\r
346\r
347 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.\r
348 This function must guarantee that all I/O read and write operations are\r
349 serialized.\r
350\r
596cecff 351 If Port is not aligned on a 64-bit boundary, then ASSERT().\r
352\r
79964ac8 353 If 64-bit I/O port operations are not supported, then ASSERT().\r
354\r
355 @param Port The I/O port to read.\r
356\r
357 @return The value read.\r
358\r
359**/\r
360UINT64\r
361EFIAPI\r
362IoRead64 (\r
363 IN UINTN Port\r
364 )\r
365{\r
366 //\r
367 // Make sure Port is aligned on a 64-bit boundary.\r
368 //\r
369 ASSERT ((Port & 7) == 0);\r
370 return IoReadWorker (Port, EfiCpuIoWidthUint64);\r
371}\r
372\r
373/**\r
374 Writes a 64-bit I/O port.\r
375\r
376 Writes the 64-bit I/O port specified by Port with the value specified by Value\r
377 and returns Value. This function must guarantee that all I/O read and write\r
378 operations are serialized.\r
379\r
596cecff 380 If Port is not aligned on a 64-bit boundary, then ASSERT().\r
381 \r
79964ac8 382 If 64-bit I/O port operations are not supported, then ASSERT().\r
383\r
384 @param Port The I/O port to write.\r
385 @param Value The value to write to the I/O port.\r
386\r
387 @return The value written the I/O port.\r
388\r
389**/\r
390UINT64\r
391EFIAPI\r
392IoWrite64 (\r
393 IN UINTN Port,\r
394 IN UINT64 Value\r
395 )\r
396{\r
397 //\r
398 // Make sure Port is aligned on a 64-bit boundary.\r
399 //\r
400 ASSERT ((Port & 7) == 0);\r
401 return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);\r
402}\r
403\r
404/**\r
405 Reads an 8-bit MMIO register.\r
406\r
407 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is\r
408 returned. This function must guarantee that all MMIO read and write\r
409 operations are serialized.\r
410\r
411 If 8-bit MMIO register operations are not supported, then ASSERT().\r
412\r
413 @param Address The MMIO register to read.\r
414\r
415 @return The value read.\r
416\r
417**/\r
418UINT8\r
419EFIAPI\r
420MmioRead8 (\r
421 IN UINTN Address\r
422 )\r
423{\r
424 return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);\r
425}\r
426\r
427/**\r
428 Writes an 8-bit MMIO register.\r
429\r
430 Writes the 8-bit MMIO register specified by Address with the value specified\r
431 by Value and returns Value. This function must guarantee that all MMIO read\r
432 and write operations are serialized.\r
433\r
434 If 8-bit MMIO register operations are not supported, then ASSERT().\r
435\r
436 @param Address The MMIO register to write.\r
437 @param Value The value to write to the MMIO register.\r
438\r
439**/\r
440UINT8\r
441EFIAPI\r
442MmioWrite8 (\r
443 IN UINTN Address,\r
444 IN UINT8 Value\r
445 )\r
446{\r
447 return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);\r
448}\r
449\r
450/**\r
451 Reads a 16-bit MMIO register.\r
452\r
453 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is\r
454 returned. This function must guarantee that all MMIO read and write\r
455 operations are serialized.\r
456\r
596cecff 457 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
458 \r
79964ac8 459 If 16-bit MMIO register operations are not supported, then ASSERT().\r
460\r
461 @param Address The MMIO register to read.\r
462\r
463 @return The value read.\r
464\r
465**/\r
466UINT16\r
467EFIAPI\r
468MmioRead16 (\r
469 IN UINTN Address\r
470 )\r
471{\r
472 //\r
473 // Make sure Address is aligned on a 16-bit boundary.\r
474 //\r
475 ASSERT ((Address & 1) == 0);\r
476 return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);\r
477}\r
478\r
479/**\r
480 Writes a 16-bit MMIO register.\r
481\r
482 Writes the 16-bit MMIO register specified by Address with the value specified\r
483 by Value and returns Value. This function must guarantee that all MMIO read\r
484 and write operations are serialized.\r
485\r
596cecff 486 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
487 \r
79964ac8 488 If 16-bit MMIO register operations are not supported, then ASSERT().\r
489\r
490 @param Address The MMIO register to write.\r
491 @param Value The value to write to the MMIO register.\r
492\r
493**/\r
494UINT16\r
495EFIAPI\r
496MmioWrite16 (\r
497 IN UINTN Address,\r
498 IN UINT16 Value\r
499 )\r
500{\r
501 //\r
502 // Make sure Address is aligned on a 16-bit boundary.\r
503 //\r
504 ASSERT ((Address & 1) == 0);\r
505 return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);\r
506}\r
507\r
508/**\r
509 Reads a 32-bit MMIO register.\r
510\r
511 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is\r
512 returned. This function must guarantee that all MMIO read and write\r
513 operations are serialized.\r
514\r
596cecff 515 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
516 \r
79964ac8 517 If 32-bit MMIO register operations are not supported, then ASSERT().\r
518\r
519 @param Address The MMIO register to read.\r
520\r
521 @return The value read.\r
522\r
523**/\r
524UINT32\r
525EFIAPI\r
526MmioRead32 (\r
527 IN UINTN Address\r
528 )\r
529{\r
530 //\r
531 // Make sure Address is aligned on a 32-bit boundary.\r
532 //\r
533 ASSERT ((Address & 3) == 0);\r
534 return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);\r
535}\r
536\r
537/**\r
538 Writes a 32-bit MMIO register.\r
539\r
540 Writes the 32-bit MMIO register specified by Address with the value specified\r
541 by Value and returns Value. This function must guarantee that all MMIO read\r
542 and write operations are serialized.\r
543\r
596cecff 544 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
545 \r
79964ac8 546 If 32-bit MMIO register operations are not supported, then ASSERT().\r
547\r
548 @param Address The MMIO register to write.\r
549 @param Value The value to write to the MMIO register.\r
550\r
551**/\r
552UINT32\r
553EFIAPI\r
554MmioWrite32 (\r
555 IN UINTN Address,\r
556 IN UINT32 Value\r
557 )\r
558{\r
559 //\r
560 // Make sure Address is aligned on a 32-bit boundary.\r
561 //\r
562 ASSERT ((Address & 3) == 0);\r
563 return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);\r
564}\r
565\r
566/**\r
567 Reads a 64-bit MMIO register.\r
568\r
569 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is\r
570 returned. This function must guarantee that all MMIO read and write\r
571 operations are serialized.\r
572\r
596cecff 573 If Address is not aligned on a 64-bit boundary, then ASSERT().\r
574 \r
79964ac8 575 If 64-bit MMIO register operations are not supported, then ASSERT().\r
576\r
577 @param Address The MMIO register to read.\r
578\r
579 @return The value read.\r
580\r
581**/\r
582UINT64\r
583EFIAPI\r
584MmioRead64 (\r
585 IN UINTN Address\r
586 )\r
587{\r
588 //\r
589 // Make sure Address is aligned on a 64-bit boundary.\r
590 //\r
591 ASSERT ((Address & 7) == 0);\r
592 return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);\r
593}\r
594\r
595/**\r
596 Writes a 64-bit MMIO register.\r
597\r
598 Writes the 64-bit MMIO register specified by Address with the value specified\r
599 by Value and returns Value. This function must guarantee that all MMIO read\r
600 and write operations are serialized.\r
601\r
596cecff 602 If Address is not aligned on a 64-bit boundary, then ASSERT().\r
603 \r
79964ac8 604 If 64-bit MMIO register operations are not supported, then ASSERT().\r
605\r
606 @param Address The MMIO register to write.\r
607 @param Value The value to write to the MMIO register.\r
608\r
609**/\r
610UINT64\r
611EFIAPI\r
612MmioWrite64 (\r
613 IN UINTN Address,\r
614 IN UINT64 Value\r
615 )\r
616{\r
617 //\r
618 // Make sure Address is aligned on a 64-bit boundary.\r
619 //\r
620 ASSERT ((Address & 7) == 0);\r
621 return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);\r
622}\r