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