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