1 /** @file
2   I/O Library. The implementations are based on EFI_PEI_SERVICE->CpuIo interface.
3 
4   Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this 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 
16 #include <PiPei.h>
17 
18 #include <Library/IoLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/PeiServicesTablePointerLib.h>
22 
23 /**
24   Reads an 8-bit I/O port.
25 
26   Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
27   This function must guarantee that all I/O read and write operations are
28   serialized.
29 
30   If 8-bit I/O port operations are not supported, then ASSERT().
31 
32   @param  Port  The I/O port to read.
33 
34   @return The value read.
35 
36 **/
37 UINT8
38 EFIAPI
IoRead8(IN UINTN Port)39 IoRead8 (
40   IN      UINTN                     Port
41   )
42 {
43   CONST EFI_PEI_SERVICES            **PeiServices;
44   EFI_PEI_CPU_IO_PPI                *CpuIo;
45 
46   PeiServices = GetPeiServicesTablePointer ();
47   CpuIo       = (*PeiServices)->CpuIo;
48   ASSERT (CpuIo != NULL);
49 
50   return CpuIo->IoRead8 (PeiServices, CpuIo, (UINT64) Port);
51 }
52 
53 /**
54   Writes an 8-bit I/O port.
55 
56   Writes the 8-bit I/O port specified by Port with the value specified by Value
57   and returns Value. This function must guarantee that all I/O read and write
58   operations are serialized.
59 
60   If 8-bit I/O port operations are not supported, then ASSERT().
61 
62   @param  Port  The I/O port to write.
63   @param  Value The value to write to the I/O port.
64 
65   @return The value written the I/O port.
66 
67 **/
68 UINT8
69 EFIAPI
IoWrite8(IN UINTN Port,IN UINT8 Value)70 IoWrite8 (
71   IN      UINTN                     Port,
72   IN      UINT8                     Value
73   )
74 {
75   CONST EFI_PEI_SERVICES            **PeiServices;
76   EFI_PEI_CPU_IO_PPI                *CpuIo;
77 
78   PeiServices = GetPeiServicesTablePointer ();
79   CpuIo       = (*PeiServices)->CpuIo;
80   ASSERT (CpuIo != NULL);
81 
82   CpuIo->IoWrite8 (PeiServices, CpuIo, (UINT64) Port, Value);
83   return Value;
84 }
85 
86 /**
87   Reads a 16-bit I/O port.
88 
89   Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
90   This function must guarantee that all I/O read and write operations are
91   serialized.
92 
93   If 16-bit I/O port operations are not supported, then ASSERT().
94   If Port is not aligned on a 16-bit boundary, then ASSERT().
95 
96   @param  Port  The I/O port to read.
97 
98   @return The value read.
99 
100 **/
101 UINT16
102 EFIAPI
IoRead16(IN UINTN Port)103 IoRead16 (
104   IN      UINTN                     Port
105   )
106 {
107   CONST EFI_PEI_SERVICES            **PeiServices;
108   EFI_PEI_CPU_IO_PPI                *CpuIo;
109 
110   PeiServices = GetPeiServicesTablePointer ();
111   CpuIo       = (*PeiServices)->CpuIo;
112   ASSERT (CpuIo != NULL);
113   //
114   // Make sure Port is aligned on a 16-bit boundary.
115   //
116   ASSERT ((Port & 1) == 0);
117   return CpuIo->IoRead16 (PeiServices, CpuIo, (UINT64) Port);
118 }
119 
120 /**
121   Writes a 16-bit I/O port.
122 
123   Writes the 16-bit I/O port specified by Port with the value specified by Value
124   and returns Value. This function must guarantee that all I/O read and write
125   operations are serialized.
126 
127   If 16-bit I/O port operations are not supported, then ASSERT().
128   If Port is not aligned on a 16-bit boundary, then ASSERT().
129 
130   @param  Port  The I/O port to write.
131   @param  Value The value to write to the I/O port.
132 
133   @return The value written the I/O port.
134 
135 **/
136 UINT16
137 EFIAPI
IoWrite16(IN UINTN Port,IN UINT16 Value)138 IoWrite16 (
139   IN      UINTN                     Port,
140   IN      UINT16                    Value
141   )
142 {
143   CONST EFI_PEI_SERVICES            **PeiServices;
144   EFI_PEI_CPU_IO_PPI                *CpuIo;
145 
146   PeiServices = GetPeiServicesTablePointer ();
147   CpuIo       = (*PeiServices)->CpuIo;
148   ASSERT (CpuIo != NULL);
149   //
150   // Make sure Port is aligned on a 16-bit boundary.
151   //
152   ASSERT ((Port & 1) == 0);
153   CpuIo->IoWrite16 (PeiServices, CpuIo, (UINT64) Port, Value);
154   return Value;
155 }
156 
157 /**
158   Reads a 32-bit I/O port.
159 
160   Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
161   This function must guarantee that all I/O read and write operations are
162   serialized.
163 
164   If 32-bit I/O port operations are not supported, then ASSERT().
165   If Port is not aligned on a 32-bit boundary, then ASSERT().
166 
167   @param  Port  The I/O port to read.
168 
169   @return The value read.
170 
171 **/
172 UINT32
173 EFIAPI
IoRead32(IN UINTN Port)174 IoRead32 (
175   IN      UINTN                     Port
176   )
177 {
178   CONST EFI_PEI_SERVICES            **PeiServices;
179   EFI_PEI_CPU_IO_PPI                *CpuIo;
180 
181   PeiServices = GetPeiServicesTablePointer ();
182   CpuIo       = (*PeiServices)->CpuIo;
183   ASSERT (CpuIo != NULL);
184   //
185   // Make sure Port is aligned on a 32-bit boundary.
186   //
187   ASSERT ((Port & 3) == 0);
188   return CpuIo->IoRead32 (PeiServices, CpuIo, (UINT64) Port);
189 }
190 
191 /**
192   Writes a 32-bit I/O port.
193 
194   Writes the 32-bit I/O port specified by Port with the value specified by Value
195   and returns Value. This function must guarantee that all I/O read and write
196   operations are serialized.
197 
198   If 32-bit I/O port operations are not supported, then ASSERT().
199   If Port is not aligned on a 32-bit boundary, then ASSERT().
200 
201   @param  Port  The I/O port to write.
202   @param  Value The value to write to the I/O port.
203 
204   @return The value written the I/O port.
205 
206 **/
207 UINT32
208 EFIAPI
IoWrite32(IN UINTN Port,IN UINT32 Value)209 IoWrite32 (
210   IN      UINTN                     Port,
211   IN      UINT32                    Value
212   )
213 {
214   CONST EFI_PEI_SERVICES            **PeiServices;
215   EFI_PEI_CPU_IO_PPI                *CpuIo;
216 
217   PeiServices = GetPeiServicesTablePointer ();
218   CpuIo       = (*PeiServices)->CpuIo;
219   ASSERT (CpuIo != NULL);
220   //
221   // Make sure Port is aligned on a 32-bit boundary.
222   //
223   ASSERT ((Port & 3) == 0);
224   CpuIo->IoWrite32 (PeiServices, CpuIo, (UINT64) Port, Value);
225   return Value;
226 }
227 
228 /**
229   Reads a 64-bit I/O port.
230 
231   Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.
232   This function must guarantee that all I/O read and write operations are
233   serialized.
234 
235   If 64-bit I/O port operations are not supported, then ASSERT().
236   If Port is not aligned on a 64-bit boundary, then ASSERT().
237 
238   @param  Port  The I/O port to read.
239 
240   @return The value read.
241 
242 **/
243 UINT64
244 EFIAPI
IoRead64(IN UINTN Port)245 IoRead64 (
246   IN      UINTN                     Port
247   )
248 {
249   CONST EFI_PEI_SERVICES            **PeiServices;
250   EFI_PEI_CPU_IO_PPI                *CpuIo;
251 
252   PeiServices = GetPeiServicesTablePointer ();
253   CpuIo       = (*PeiServices)->CpuIo;
254   ASSERT (CpuIo != NULL);
255   //
256   // Make sure Port is aligned on a 64-bit boundary.
257   //
258   ASSERT ((Port & 7) == 0);
259   return CpuIo->IoRead64 (PeiServices, CpuIo, (UINT64) Port);
260 }
261 
262 /**
263   Writes a 64-bit I/O port.
264 
265   Writes the 64-bit I/O port specified by Port with the value specified by Value
266   and returns Value. This function must guarantee that all I/O read and write
267   operations are serialized.
268 
269   If 64-bit I/O port operations are not supported, then ASSERT().
270   If Port is not aligned on a 64-bit boundary, then ASSERT().
271 
272   @param  Port  The I/O port to write.
273   @param  Value The value to write to the I/O port.
274 
275   @return The value written the I/O port.
276 
277 **/
278 UINT64
279 EFIAPI
IoWrite64(IN UINTN Port,IN UINT64 Value)280 IoWrite64 (
281   IN      UINTN                     Port,
282   IN      UINT64                    Value
283   )
284 {
285   CONST EFI_PEI_SERVICES            **PeiServices;
286   EFI_PEI_CPU_IO_PPI                *CpuIo;
287 
288   PeiServices = GetPeiServicesTablePointer ();
289   CpuIo       = (*PeiServices)->CpuIo;
290   ASSERT (CpuIo != NULL);
291   //
292   // Make sure Port is aligned on a 64-bit boundary.
293   //
294   ASSERT ((Port & 7) == 0);
295   CpuIo->IoWrite64 (PeiServices, CpuIo, (UINT64) Port, Value);
296   return Value;;
297 }
298 
299 /**
300   Reads an 8-bit MMIO register.
301 
302   Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
303   returned. This function must guarantee that all MMIO read and write
304   operations are serialized.
305 
306   If 8-bit MMIO register operations are not supported, then ASSERT().
307 
308   @param  Address The MMIO register to read.
309 
310   @return The value read.
311 
312 **/
313 UINT8
314 EFIAPI
MmioRead8(IN UINTN Address)315 MmioRead8 (
316   IN      UINTN                     Address
317   )
318 {
319   CONST EFI_PEI_SERVICES            **PeiServices;
320   EFI_PEI_CPU_IO_PPI                *CpuIo;
321 
322   PeiServices = GetPeiServicesTablePointer ();
323   CpuIo       = (*PeiServices)->CpuIo;
324   ASSERT (CpuIo != NULL);
325 
326   return CpuIo->MemRead8 (PeiServices, CpuIo, (UINT64) Address);
327 }
328 
329 /**
330   Writes an 8-bit MMIO register.
331 
332   Writes the 8-bit MMIO register specified by Address with the value specified
333   by Value and returns Value. This function must guarantee that all MMIO read
334   and write operations are serialized.
335 
336   If 8-bit MMIO register operations are not supported, then ASSERT().
337 
338   @param  Address The MMIO register to write.
339   @param  Value   The value to write to the MMIO register.
340 
341   @return Value.
342 
343 **/
344 UINT8
345 EFIAPI
MmioWrite8(IN UINTN Address,IN UINT8 Value)346 MmioWrite8 (
347   IN      UINTN                     Address,
348   IN      UINT8                     Value
349   )
350 {
351   CONST EFI_PEI_SERVICES            **PeiServices;
352   EFI_PEI_CPU_IO_PPI                *CpuIo;
353 
354   PeiServices = GetPeiServicesTablePointer ();
355   CpuIo       = (*PeiServices)->CpuIo;
356   ASSERT (CpuIo != NULL);
357 
358   CpuIo->MemWrite8 (PeiServices, CpuIo, (UINT64) Address, Value);
359   return Value;
360 }
361 
362 /**
363   Reads a 16-bit MMIO register.
364 
365   Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
366   returned. This function must guarantee that all MMIO read and write
367   operations are serialized.
368 
369   If 16-bit MMIO register operations are not supported, then ASSERT().
370   If Address is not aligned on a 16-bit boundary, then ASSERT().
371 
372   @param  Address The MMIO register to read.
373 
374   @return The value read.
375 
376 **/
377 UINT16
378 EFIAPI
MmioRead16(IN UINTN Address)379 MmioRead16 (
380   IN      UINTN                     Address
381   )
382 {
383   CONST EFI_PEI_SERVICES            **PeiServices;
384   EFI_PEI_CPU_IO_PPI                *CpuIo;
385 
386   PeiServices = GetPeiServicesTablePointer ();
387   CpuIo       = (*PeiServices)->CpuIo;
388   ASSERT (CpuIo != NULL);
389   //
390   // Make sure Address is aligned on a 16-bit boundary.
391   //
392   ASSERT ((Address & 1) == 0);
393   return CpuIo->MemRead16 (PeiServices, CpuIo, (UINT64) Address);
394 
395 }
396 
397 /**
398   Writes a 16-bit MMIO register.
399 
400   Writes the 16-bit MMIO register specified by Address with the value specified
401   by Value and returns Value. This function must guarantee that all MMIO read
402   and write operations are serialized.
403 
404   If 16-bit MMIO register operations are not supported, then ASSERT().
405   If Address is not aligned on a 16-bit boundary, then ASSERT().
406 
407   @param  Address The MMIO register to write.
408   @param  Value   The value to write to the MMIO register.
409 
410   @return Value.
411 
412 **/
413 UINT16
414 EFIAPI
MmioWrite16(IN UINTN Address,IN UINT16 Value)415 MmioWrite16 (
416   IN      UINTN                     Address,
417   IN      UINT16                    Value
418   )
419 {
420   CONST EFI_PEI_SERVICES            **PeiServices;
421   EFI_PEI_CPU_IO_PPI                *CpuIo;
422 
423   PeiServices = GetPeiServicesTablePointer ();
424   CpuIo       = (*PeiServices)->CpuIo;
425   ASSERT (CpuIo != NULL);
426   //
427   // Make sure Address is aligned on a 16-bit boundary.
428   //
429   ASSERT ((Address & 1) == 0);
430   CpuIo->MemWrite16 (PeiServices, CpuIo, (UINT64) Address, Value);
431   return Value;
432 }
433 
434 /**
435   Reads a 32-bit MMIO register.
436 
437   Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
438   returned. This function must guarantee that all MMIO read and write
439   operations are serialized.
440 
441   If 32-bit MMIO register operations are not supported, then ASSERT().
442   If Address is not aligned on a 32-bit boundary, then ASSERT().
443 
444   @param  Address The MMIO register to read.
445 
446   @return The value read.
447 
448 **/
449 UINT32
450 EFIAPI
MmioRead32(IN UINTN Address)451 MmioRead32 (
452   IN      UINTN                     Address
453   )
454 {
455   CONST EFI_PEI_SERVICES            **PeiServices;
456   EFI_PEI_CPU_IO_PPI                *CpuIo;
457 
458   PeiServices = GetPeiServicesTablePointer ();
459   CpuIo       = (*PeiServices)->CpuIo;
460   ASSERT (CpuIo != NULL);
461   //
462   // Make sure Address is aligned on a 32-bit boundary.
463   //
464   ASSERT ((Address & 3) == 0);
465   return CpuIo->MemRead32 (PeiServices, CpuIo, (UINT64) Address);
466 
467 }
468 
469 /**
470   Writes a 32-bit MMIO register.
471 
472   Writes the 32-bit MMIO register specified by Address with the value specified
473   by Value and returns Value. This function must guarantee that all MMIO read
474   and write operations are serialized.
475 
476   If 32-bit MMIO register operations are not supported, then ASSERT().
477   If Address is not aligned on a 32-bit boundary, then ASSERT().
478 
479   @param  Address The MMIO register to write.
480   @param  Value   The value to write to the MMIO register.
481 
482   @return Value.
483 
484 **/
485 UINT32
486 EFIAPI
MmioWrite32(IN UINTN Address,IN UINT32 Value)487 MmioWrite32 (
488   IN      UINTN                     Address,
489   IN      UINT32                    Value
490   )
491 {
492   CONST EFI_PEI_SERVICES            **PeiServices;
493   EFI_PEI_CPU_IO_PPI                *CpuIo;
494 
495   PeiServices = GetPeiServicesTablePointer ();
496   CpuIo       = (*PeiServices)->CpuIo;
497   ASSERT (CpuIo != NULL);
498   //
499   // Make sure Address is aligned on a 32-bit boundary.
500   //
501   ASSERT ((Address & 3) == 0);
502   CpuIo->MemWrite32 (PeiServices, CpuIo, (UINT64) Address, Value);
503   return Value;
504 }
505 
506 /**
507   Reads a 64-bit MMIO register.
508 
509   Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
510   returned. This function must guarantee that all MMIO read and write
511   operations are serialized.
512 
513   If 64-bit MMIO register operations are not supported, then ASSERT().
514   If Address is not aligned on a 64-bit boundary, then ASSERT().
515 
516   @param  Address The MMIO register to read.
517 
518   @return The value read.
519 
520 **/
521 UINT64
522 EFIAPI
MmioRead64(IN UINTN Address)523 MmioRead64 (
524   IN      UINTN                     Address
525   )
526 {
527   CONST EFI_PEI_SERVICES            **PeiServices;
528   EFI_PEI_CPU_IO_PPI                *CpuIo;
529 
530   PeiServices = GetPeiServicesTablePointer ();
531   CpuIo       = (*PeiServices)->CpuIo;
532   ASSERT (CpuIo != NULL);
533   //
534   // Make sure Address is aligned on a 64-bit boundary.
535   //
536   ASSERT ((Address & (sizeof (UINT64) - 1)) == 0);
537   return CpuIo->MemRead64 (PeiServices, CpuIo, (UINT64) Address);
538 
539 }
540 
541 /**
542   Writes a 64-bit MMIO register.
543 
544   Writes the 64-bit MMIO register specified by Address with the value specified
545   by Value and returns Value. This function must guarantee that all MMIO read
546   and write operations are serialized.
547 
548   If 64-bit MMIO register operations are not supported, then ASSERT().
549   If Address is not aligned on a 64-bit boundary, then ASSERT().
550 
551   @param  Address The MMIO register to write.
552   @param  Value   The value to write to the MMIO register.
553 
554 **/
555 UINT64
556 EFIAPI
MmioWrite64(IN UINTN Address,IN UINT64 Value)557 MmioWrite64 (
558   IN      UINTN                     Address,
559   IN      UINT64                    Value
560   )
561 {
562   CONST EFI_PEI_SERVICES            **PeiServices;
563   EFI_PEI_CPU_IO_PPI                *CpuIo;
564 
565   PeiServices = GetPeiServicesTablePointer ();
566   CpuIo       = (*PeiServices)->CpuIo;
567   ASSERT (CpuIo != NULL);
568   //
569   // Make sure Address is aligned on a 64-bit boundary.
570   //
571   ASSERT ((Address & 7) == 0);
572   CpuIo->MemWrite64 (PeiServices, CpuIo, (UINT64) Address, Value);
573   return Value;
574 }
575