111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/** @file
211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  I/O Library MMIO Buffer Functions.
34ca0802e08133ada71511b70704922d94c439ea4klu  The implementations are based on EFI_PEI_SERVICE->CpuIo interface.
411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
519388d2960b2fe0347da23799e93ccc52f540214hhtian  Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>
619388d2960b2fe0347da23799e93ccc52f540214hhtian  This program and the accompanying materials
711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  are licensed and made available under the terms and conditions of the BSD License
811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  which accompanies this distribution.  The full text of the license may be found at
92fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  http://opensource.org/licenses/bsd-license.php.
1011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
1111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
1411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
1511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
16c892d8464468618b0aa3c7f35edbdfbc7cc24ee5vanjeff
1711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang#include <PiPei.h>
18c892d8464468618b0aa3c7f35edbdfbc7cc24ee5vanjeff
1911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang#include <Library/IoLib.h>
2011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang#include <Library/DebugLib.h>
2111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang#include <Library/BaseLib.h>
2211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang#include <Library/PeiServicesTablePointerLib.h>
2311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
2411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
2511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region to system memory by using 8-bit access.
2611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
2711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region specified by starting address StartAddress
2811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  to system memory specified by Buffer by using 8-bit access. The total
2911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  number of byte to be copied is specified by Length. Buffer is returned.
3011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
3111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
3211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
3311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
3411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
352fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied from.
3680f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
372fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer receiving the data read.
3811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
3980f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @return Buffer
4011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
4111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
4211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT8 *
4311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
4411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioReadBuffer8 (
4511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       StartAddress,
4611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       Length,
4711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  OUT UINT8       *Buffer
4811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
4911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
5011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  UINT8   *ReturnBuffer;
5111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
5211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
5311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
5411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
5511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = Buffer;
5611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
5742eedea958591087603bbacd1c2227d2494026afyshang  while (Length-- != 0) {
5811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    *(Buffer++) = MmioRead8 (StartAddress++);
5911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
6011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
6111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
6211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
6311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
6411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
6511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region to system memory by using 16-bit access.
6611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
6711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region specified by starting address StartAddress
6811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  to system memory specified by Buffer by using 16-bit access. The total
6911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  number of byte to be copied is specified by Length. Buffer is returned.
7011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
7111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().
7211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
7311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
7411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
7511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
7611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is not aligned on a 16-bit boundary, then ASSERT().
7711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
7811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
792fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied from.
8080f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
812fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer receiving the data read.
8211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
8380f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @return Buffer
8411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
8511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
8611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT16 *
8711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
8811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioReadBuffer16 (
8911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       StartAddress,
9011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       Length,
9111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  OUT UINT16      *Buffer
9211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
9311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
9411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  UINT16    *ReturnBuffer;
9511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
9611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);
9711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
9811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
9911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
10011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
10111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);
10211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);
10311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
10411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = Buffer;
10511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
10642eedea958591087603bbacd1c2227d2494026afyshang  while (Length != 0) {
10711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    *(Buffer++) = MmioRead16 (StartAddress);
10811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    StartAddress += sizeof (UINT16);
10911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    Length -= sizeof (UINT16);
11011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
11111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
11211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
11311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
11411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
11511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
11611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region to system memory by using 32-bit access.
11711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
11811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region specified by starting address StartAddress
11911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  to system memory specified by Buffer by using 32-bit access. The total
12011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  number of byte to be copied is specified by Length. Buffer is returned.
12111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
12211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
12311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
12411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
12511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
12611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
12711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is not aligned on a 32-bit boundary, then ASSERT().
12811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Buffer is not aligned on a 32-bit boundary, then ASSERT().
12911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
1302fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied from.
13180f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
1322fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer receiving the data read.
13311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
13480f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @return Buffer
13511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
13611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
13711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT32 *
13811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
13911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioReadBuffer32 (
14011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       StartAddress,
14111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       Length,
14211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  OUT UINT32      *Buffer
14311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
14411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
14511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  UINT32    *ReturnBuffer;
14611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
14711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
14811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
14911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
15011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
15111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
15211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
15311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
15411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
15511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = Buffer;
15611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
15742eedea958591087603bbacd1c2227d2494026afyshang  while (Length != 0) {
15811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    *(Buffer++) = MmioRead32 (StartAddress);
15911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    StartAddress += sizeof (UINT32);
16011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    Length -= sizeof (UINT32);
16111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
16211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
16311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
16411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
16511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
16611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
16711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region to system memory by using 64-bit access.
16811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
16911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from MMIO region specified by starting address StartAddress
17011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  to system memory specified by Buffer by using 64-bit access. The total
17111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  number of byte to be copied is specified by Length. Buffer is returned.
17211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
17311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().
17411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
17511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
17611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
17711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
17811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is not aligned on a 64-bit boundary, then ASSERT().
17911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Buffer is not aligned on a 64-bit boundary, then ASSERT().
18011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
1812fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied from.
18280f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
1832fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer receiving the data read.
18411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
18580f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @return Buffer
18611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
18711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
18811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT64 *
18911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
19011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioReadBuffer64 (
19111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       StartAddress,
19211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN       Length,
19311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  OUT UINT64      *Buffer
19411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
19511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
19611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  UINT64    *ReturnBuffer;
19711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
19811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);
19911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
20011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
20111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
20211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
20311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);
20411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);
20511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
20611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = Buffer;
20711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
20842eedea958591087603bbacd1c2227d2494026afyshang  while (Length != 0) {
20911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    *(Buffer++) = MmioRead64 (StartAddress);
21011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    StartAddress += sizeof (UINT64);
21111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    Length -= sizeof (UINT64);
21211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
21311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
21411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
21511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
21611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
21711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
21811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
21911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory to MMIO region by using 8-bit access.
22011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
22111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory specified by Buffer to MMIO region specified
22211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  by starting address StartAddress by using 8-bit access. The total number
22311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  of byte to be copied is specified by Length. Buffer is returned.
22411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
22511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
22611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
22711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
22811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
2292fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied to.
23080f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
2312fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer containing the data to write.
23211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
2333222ffc0443923d0b74ad71867d68d10b2b81f72xli  @return Buffer
23411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
23511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
23611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT8 *
23711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
23811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioWriteBuffer8 (
23911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN         StartAddress,
24011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN         Length,
24111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  CONST UINT8   *Buffer
24211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
24311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
24411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  VOID* ReturnBuffer;
24511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
24611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
24711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
24811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
24911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = (UINT8 *) Buffer;
25011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
25142eedea958591087603bbacd1c2227d2494026afyshang  while (Length-- != 0) {
25211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang     MmioWrite8 (StartAddress++, *(Buffer++));
25311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
25411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
25511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
25611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
25711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
25811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
25911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
26011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory to MMIO region by using 16-bit access.
26111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
26211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory specified by Buffer to MMIO region specified
26311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  by starting address StartAddress by using 16-bit access. The total number
2643222ffc0443923d0b74ad71867d68d10b2b81f72xli  of byte to be copied is specified by Length. Buffer is returned.
26511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
26611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().
26711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
26811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
26911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
27011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
27111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is not aligned on a 16-bit boundary, then ASSERT().
27211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
27311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
27411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
2752fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied to.
27680f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
2772fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer containing the data to write.
27811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
2793222ffc0443923d0b74ad71867d68d10b2b81f72xli  @return Buffer
28011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
28111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
28211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT16 *
28311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
28411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioWriteBuffer16 (
28511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN        StartAddress,
28611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN        Length,
28711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  CONST UINT16 *Buffer
28811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
28911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
29011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  UINT16    *ReturnBuffer;
29111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
29211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);
29311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
29411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
29511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
29611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
29711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);
29811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);
29911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
30011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = (UINT16 *) Buffer;
30111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
30242eedea958591087603bbacd1c2227d2494026afyshang  while (Length != 0) {
30311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    MmioWrite16 (StartAddress, *(Buffer++));
30411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
30511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    StartAddress += sizeof (UINT16);
30611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    Length -= sizeof (UINT16);
30711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
30811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
30911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
31011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
31111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
31211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
31311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
31411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory to MMIO region by using 32-bit access.
31511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
31611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory specified by Buffer to MMIO region specified
31711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  by starting address StartAddress by using 32-bit access. The total number
3183222ffc0443923d0b74ad71867d68d10b2b81f72xli  of byte to be copied is specified by Length. Buffer is returned.
31911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
32011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
32111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
32211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
32311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
32411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
32511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is not aligned on a 32-bit boundary, then ASSERT().
32611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
32711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Buffer is not aligned on a 32-bit boundary, then ASSERT().
32811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
3292fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied to.
33080f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
3312fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer containing the data to write.
33211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
3333222ffc0443923d0b74ad71867d68d10b2b81f72xli  @return Buffer
33411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
33511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
33611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT32 *
33711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
33811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioWriteBuffer32 (
33911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN        StartAddress,
34011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN        Length,
34111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  CONST UINT32 *Buffer
34211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
34311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
34411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  UINT32    *ReturnBuffer;
34511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
34611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
34711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
34811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
34911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
35011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
35111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
35211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
35311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
35411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = (UINT32 *) Buffer;
35511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
35642eedea958591087603bbacd1c2227d2494026afyshang  while (Length != 0) {
35711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    MmioWrite32 (StartAddress, *(Buffer++));
35811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
35911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    StartAddress += sizeof (UINT32);
36011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    Length -= sizeof (UINT32);
36111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
36211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
36311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
36411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
36511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
36611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang/**
36711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory to MMIO region by using 64-bit access.
36811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
36911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  Copy data from system memory specified by Buffer to MMIO region specified
37011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  by starting address StartAddress by using 64-bit access. The total number
3713222ffc0443923d0b74ad71867d68d10b2b81f72xli  of byte to be copied is specified by Length. Buffer is returned.
37211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
37311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().
37411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
37511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
37611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
37711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
37811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Length is not aligned on a 64-bit boundary, then ASSERT().
37911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
38011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  If Buffer is not aligned on a 64-bit boundary, then ASSERT().
38111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
3822fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  StartAddress    The starting address for the MMIO region to be copied to.
38380f0c0c44f0a414efc2a0e5a0ff59ca998d595a3klu  @param  Length          The size, in bytes, of Buffer.
3842fc59a003ed9104f9feebe0e418f2a04a50f3284myronporter  @param  Buffer          The pointer to a system memory buffer containing the data to write.
38511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
3863222ffc0443923d0b74ad71867d68d10b2b81f72xli  @return Buffer
38711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
38811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang**/
38911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangUINT64 *
39011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangEFIAPI
39111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshangMmioWriteBuffer64 (
39211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN        StartAddress,
39311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  UINTN        Length,
39411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  IN  CONST UINT64 *Buffer
39511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  )
39611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang{
39711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  UINT64    *ReturnBuffer;
39811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
39911f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);
40011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
40111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
40211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
40311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
40411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);
40511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);
40611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
40711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  ReturnBuffer = (UINT64 *) Buffer;
40811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
40942eedea958591087603bbacd1c2227d2494026afyshang  while (Length != 0) {
41011f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    MmioWrite64 (StartAddress, *(Buffer++));
41111f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
41211f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    StartAddress += sizeof (UINT64);
41311f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang    Length -= sizeof (UINT64);
41411f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  }
41511f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
41611f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang  return ReturnBuffer;
41711f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang}
41811f43dfd8b23702a000e45e8f3f0f6dacaa4f38byshang
419