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