> -----Original Message-----
> From: Leif Lindholm [mailto:leif.lindh...@linaro.org]
> Sent: Thursday, September 5, 2019 10:28 PM
> To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.ch...@hpe.com>
> Subject: Re: [edk2-devel] [edk2-staging/RISC-V-V2 PATCH v1 07/22]:
> MdePkg/BaseIoLibIntrinsic: RISC-V I/O intrinsic functions.
>
> On Wed, Sep 04, 2019 at 06:43:02PM +0800, Abner Chang wrote:
> > RISC-V MMIO library instance. RISC-V only supports memory map I/O.
> > However the first implementation of RISC-V EDK2 port uses PC/AT as the
> > RISC-V platform spec. We have to keep the I/O functions as the temporary
> solution.
>
> Can you expand on the I/O port situation?
> Since the architecture doesn't support it, what do these functions do?
>
> For the pure MMIO ops using compliant C, we really don't need yet another
> implementation pretending it's architecture specific. We should just have a
> single IoLibMmio.c and an IoLibMmioNonCompliant.c if the x86 folks want to
> keep their current one.
Hmm. That was for the old RISC-V PC/AT QEUM version back to 2016. We pulled in
some X86 peripherals to build up RISC-V PC/AT like platform . will remove this.
>
> /
> Leif
>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Abner Chang <abner.ch...@hpe.com>
> > ---
> > .../BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf | 8 +-
> > MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c | 697
> +++++++++++++++++++++
> > 2 files changed, 703 insertions(+), 2 deletions(-) create mode
> > 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
> >
> > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> > b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> > index 457cce9..fbb568e 100644
> > --- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> > +++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> > @@ -2,13 +2,14 @@
> > # Instance of I/O Library using compiler intrinsics.
> > #
> > # I/O Library that uses compiler intrinsics to perform IN and OUT
> > instructions -# for IA-32 and x64. On IPF, I/O port requests are
> > translated
> into MMIO requests.
> > +# for IA-32, x64 and RISC-V. On IPF, I/O port requests are translated
> > into
> MMIO requests.
> > # MMIO requests are forwarded directly to memory. For EBC, I/O port
> > requests # ASSERT().
> > #
> > # Copyright (c) 2007 - 2018, Intel Corporation. All rights
> > reserved.<BR> # Portions copyright (c) 2008 - 2009, Apple Inc. All
> > rights reserved.<BR> # Copyright (c) 2017, AMD Incorporated. All
> > rights reserved.<BR>
> > +# Portinos Copyright (c) 2016, Hewlett Packard Enterprise
> > +Development LP. All rights reserved.<BR>
> > #
> > # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -25,7 +26,7 @@
> >
> >
> > #
> > -# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
> > +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64
> > #
> >
> > [Sources]
> > @@ -55,6 +56,9 @@
> > [Sources.AARCH64]
> > IoLibArm.c
> >
> > +[Sources.RISCV64]
> > + IoLibRiscV.c
> > +
> > [Packages]
> > MdePkg/MdePkg.dec
> >
> > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
> b/MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
> > new file mode 100644
> > index 0000000..6173d25
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
> > @@ -0,0 +1,697 @@
> > +/** @file
> > + Common I/O Library routines for RISC-V
> > +
> > + Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP.
> All rights reserved.<BR>
> > +
> > + This program and the accompanying materials
> > + are licensed and made available under the terms and conditions of the
> BSD License
> > + which accompanies this distribution. The full text of the license may be
> found at
> > + INVALID URI REMOVED
> 3A__opensource.org_licenses_bsd-
> 2Dlicense.php&d=DwIBAg&c=C5b8zRQO1miGmBeVZ2LFWg&r=_SN6FZBN4V
> gi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=tOmBsvsU4Yn-
> 9Wot_rqzblR4u3MnD-
> oQ5vPULboFIFQ&s=1geV760INDGESbgcUE_N2zkIttZ6EuYd54GFw0h3IrY&e=
> > +
> > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +**/
> > +
> > +#include "BaseIoLibIntrinsicInternal.h"
> > +
> > +/**
> > + Reads an 8-bit MMIO register.
> > +
> > + Reads the 8-bit MMIO register specified by Address. The 8-bit read value
> is
> > + returned. This function must guarantee that all MMIO read and write
> > + operations are serialized.
> > +
> > + If 8-bit MMIO register operations are not supported, then ASSERT().
> > +
> > + @param Address The MMIO register to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +MmioRead8 (
> > + IN UINTN Address
> > + )
> > +{
> > + return *(volatile UINT8*)Address;
> > +}
> > +
> > +/**
> > + Writes an 8-bit MMIO register.
> > +
> > + Writes the 8-bit MMIO register specified by Address with the value
> specified
> > + by Value and returns Value. This function must guarantee that all MMIO
> read
> > + and write operations are serialized.
> > +
> > + If 8-bit MMIO register operations are not supported, then ASSERT().
> > +
> > + @param Address The MMIO register to write.
> > + @param Value The value to write to the MMIO register.
> > +
> > + @return Value.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +MmioWrite8 (
> > + IN UINTN Address,
> > + IN UINT8 Value
> > + )
> > +{
> > + *(volatile UINT8 *)Address = Value;
> > + return Value;
> > +}
> > +
> > +/**
> > + Reads a 16-bit MMIO register.
> > +
> > + Reads the 16-bit MMIO register specified by Address. The 16-bit read
> value is
> > + returned. This function must guarantee that all MMIO read and write
> > + operations are serialized.
> > +
> > + If 16-bit MMIO register operations are not supported, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The MMIO register to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +MmioRead16 (
> > + IN UINTN Address
> > + )
> > +{
> > + return *(volatile UINT16 *)Address;
> > +}
> > +
> > +/**
> > + Writes a 16-bit MMIO register.
> > +
> > + Writes the 16-bit MMIO register specified by Address with the value
> specified
> > + by Value and returns Value. This function must guarantee that all MMIO
> read
> > + and write operations are serialized.
> > +
> > + If 16-bit MMIO register operations are not supported, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The MMIO register to write.
> > + @param Value The value to write to the MMIO register.
> > +
> > + @return Value.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +MmioWrite16 (
> > + IN UINTN Address,
> > + IN UINT16 Value
> > + )
> > +{
> > + *(volatile UINT16 *)Address = Value;
> > + return Value;
> > +}
> > +
> > +/**
> > + Reads a 32-bit MMIO register.
> > +
> > + Reads the 32-bit MMIO register specified by Address. The 32-bit read
> value is
> > + returned. This function must guarantee that all MMIO read and write
> > + operations are serialized.
> > +
> > + If 32-bit MMIO register operations are not supported, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The MMIO register to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +MmioRead32 (
> > + IN UINTN Address
> > + )
> > +{
> > + return *(volatile UINT32 *)Address;
> > +}
> > +
> > +/**
> > + Writes a 32-bit MMIO register.
> > +
> > + Writes the 32-bit MMIO register specified by Address with the value
> specified
> > + by Value and returns Value. This function must guarantee that all MMIO
> read
> > + and write operations are serialized.
> > +
> > + If 32-bit MMIO register operations are not supported, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The MMIO register to write.
> > + @param Value The valu return *(volatile UINT8*)Address;
> > + to write to the MMIO register.
> > +
> > + @return Value.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +MmioWrite32 (
> > + IN UINTN Address,
> > + IN UINT32 Value
> > + )
> > +{
> > + *(volatile UINT32 *)Address = Value;
> > + return Value;
> > +}
> > +
> > +/**
> > + Reads a 64-bit MMIO register.
> > +
> > + Reads the 64-bit MMIO register specified by Address. The 64-bit read
> value is
> > + returned. This function must guarantee that all MMIO read and write
> > + operations are serialized.
> > +
> > + If 64-bit MMIO register operations are not supported, then ASSERT().
> > + If Address is not aligned on a 64-bit boundary, then ASSERT().
> > +
> > + @param Address The MMIO register to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +MmioRead64 (
> > + IN UINTN Address
> > + )
> > +{
> > + return *(volatile UINT64 *)Address;
> > +}
> > +
> > +/**
> > + Writes a 64-bit MMIO register.
> > +
> > + Writes the 64-bit MMIO register specified by Address with the value
> specified
> > + by Value and returns Value. This function must guarantee that all MMIO
> read
> > + and write operations are serialized.
> > +
> > + If 64-bit MMIO register operations are not supported, then ASSERT().
> > + If Address is not aligned on a 64-bit boundary, then ASSERT().
> > +
> > + @param Address The MMIO register to write.
> > + @param Value The value to write to the MMIO register.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +MmioWrite64 (
> > + IN UINTN Address,
> > + IN UINT64 Value
> > + )
> > +{
> > + *(volatile UINT64 *)Address = Value;
> > + return Value;
> > +}
> > +
> > +/**
> > + Reads an 8-bit I/O port.
> > +
> > + Reads the 8-bit I/O port specified by Port. The 8-bit read value is
> returned.
> > + This function must guarantee that all I/O read and write operations are
> > + serialized.
> > +
> > + If 8-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +IoRead8 (
> > + IN UINTN Port
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port use PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions for temporary solution.
> > + //
> > + return *(volatile UINT8*)Port;
> > +}
> > +
> > +/**
> > + Writes an 8-bit I/O port.
> > +
> > + Writes the 8-bit I/O port specified by Port with the value specified by
> Value
> > + and returns Value. This function must guarantee that all I/O read and
> write
> > + operations are serialized.
> > +
> > + If 8-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to write.
> > + @param Value The value to write to the I/O port.
> > +
> > + @return The value written the I/O port.
> > +
> > +**/
> > +
> > +UINT8
> > +EFIAPI
> > +IoWrite8 (
> > + IN UINTN Port,
> > + IN UINT8 Value
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + *(volatile UINT8 *)Port = Value;
> > + return Value;
> > +}
> > +
> > +/**
> > + Reads a 16-bit I/O port.
> > +
> > + Reads the 16-bit I/O port specified by Port. The 16-bit read value is
> returned.
> > + This function must guarantee that all I/O read and write operations are
> > + serialized.
> > +
> > + If 16-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +IoRead16 (
> > + IN UINTN Port
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + return *(volatile UINT16*)Port;
> > +}
> > +
> > +/**
> > + Writes a 16-bit I/O port.
> > +
> > + Writes the 16-bit I/O port specified by Port with the value specified by
> Value
> > + and returns Value. This function must guarantee that all I/O read and
> write
> > + operations are serialized.
> > +
> > + If 16-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to write.
> > + @param Value The value to write to the I/O port.
> > +
> > + @return The value written the I/O port.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +IoWrite16 (
> > + IN UINTN Port,
> > + IN UINT16 Value
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + *(volatile UINT16*)Port = Value;
> > + return Value;
> > +}
> > +
> > +/**
> > + Reads a 32-bit I/O port.
> > +
> > + Reads the 32-bit I/O port specified by Port. The 32-bit read value is
> returned.
> > + This function must guarantee that all I/O read and write operations are
> > + serialized.
> > +
> > + If 32-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +IoRead32 (
> > + IN UINTN Port
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + return *(volatile UINT32*)Port;
> > +}
> > +
> > +/**
> > + Writes a 32-bit I/O port.
> > +
> > + Writes the 32-bit I/O port specified by Port with the value specified by
> Value
> > + and returns Value. This function must guarantee that all I/O read and
> write
> > + operations are serialized.
> > +
> > + If 32-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to write.
> > + @param Value The value to write to the I/O port.
> > +
> > + @return The value written the I/O port.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +IoWrite32 (
> > + IN UINTN Port,
> > + IN UINT32 Value
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + *(volatile UINT32*)Port = Value;
> > + return Value;
> > +}
> > +
> > +/**
> > + Reads a 64-bit I/O port.
> > +
> > + Reads the 64-bit I/O port specified by Port. The 64-bit read value is
> returned.
> > + This function must guarantee that all I/O read and write operations are
> > + serialized.
> > +
> > + If 64-bit I/O port operations are not supported, then ASSERT().
> > + If Port is not aligned on a 64-bit boundary, then ASSERT().
> > +
> > + @param Port The I/O port to read.
> > +
> > + @return The value read.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +IoRead64 (
> > + IN UINTN Port
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + return *(volatile UINT64*)Port;
> > +}
> > +
> > +/**
> > + Writes a 64-bit I/O port.
> > +
> > + Writes the 64-bit I/O port specified by Port with the value specified by
> Value
> > + and returns Value. This function must guarantee that all I/O read and
> write
> > + operations are serialized.
> > +
> > + If 64-bit I/O port operations are not supported, then ASSERT().
> > + If Port is not aligned on a 64-bit boundary, then ASSERT().
> > +
> > + @param Port The I/O port to write.
> > + @param Value The value to write to the I/O port.
> > +
> > + @return The value written to the I/O port.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +IoWrite64 (
> > + IN UINTN Port,
> > + IN UINT64 Value
> > + )
> > +{
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + *(volatile UINT64*)Port = Value;
> > + return 0;
> > +}
> > +
> > +/**
> > + Reads an 8-bit I/O port fifo into a block of memory.
> > +
> > + Reads the 8-bit I/O fifo port specified by Port.
> > + The port is read Count times, and the read data is
> > + stored in the provided Buffer.
> > +
> > + This function must guarantee that all I/O read and write operations are
> > + serialized.
> > +
> > + If 8-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to read.
> > + @param Count The number of times to read I/O port.
> > + @param Buffer The buffer to store the read data into.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +IoReadFifo8 (
> > + IN UINTN Port,
> > + IN UINTN Count,
> > + OUT VOID *Buffer
> > + )
> > +{
> > + UINT8 *Buffer8;
> > +
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + Buffer8 = (UINT8 *)Buffer;
> > + while (Count-- > 0) {
> > + *Buffer8++ = *(volatile UINT8 *)Port++;
> > + }
> > +}
> > +
> > +/**
> > + Writes a block of memory into an 8-bit I/O port fifo.
> > +
> > + Writes the 8-bit I/O fifo port specified by Port.
> > + The port is written Count times, and the write data is
> > + retrieved from the provided Buffer.
> > +
> > + This function must guarantee that all I/O write and write operations are
> > + serialized.
> > +
> > + If 8-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to write.
> > + @param Count The number of times to write I/O port.
> > + @param Buffer The buffer to retrieve the write data from.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +IoWriteFifo8 (
> > + IN UINTN Port,
> > + IN UINTN Count,
> > + IN VOID *Buffer
> > + )
> > +{
> > + UINT8 *Buffer8;
> > +
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + Buffer8 = (UINT8 *)Buffer;
> > + while (Count-- > 0) {
> > + *(volatile UINT8 *)Port++ = *Buffer8++;
> > + }
> > +}
> > +
> > +/**
> > + Reads a 16-bit I/O port fifo into a block of memory.
> > +
> > + Reads the 16-bit I/O fifo port specified by Port.
> > + The port is read Count times, and the read data is
> > + stored in the provided Buffer.
> > +
> > + This function must guarantee that all I/O read and write operations are
> > + serialized.
> > +
> > + If 16-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to read.
> > + @param Count The number of times to read I/O port.
> > + @param Buffer The buffer to store the read data into.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +IoReadFifo16 (
> > + IN UINTN Port,
> > + IN UINTN Count,
> > + OUT VOID *Buffer
> > + )
> > +{
> > + UINT16 *Buffer16;
> > +
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + Buffer16 = (UINT16 *)Buffer;
> > + while (Count-- > 0) {
> > + *Buffer16++ = *(volatile UINT16 *)Port++;
> > + }
> > +}
> > +
> > +/**
> > + Writes a block of memory into a 16-bit I/O port fifo.
> > +
> > + Writes the 16-bit I/O fifo port specified by Port.
> > + The port is written Count times, and the write data is
> > + retrieved from the provided Buffer.
> > +
> > + This function must guarantee that all I/O write and write operations are
> > + serialized.
> > +
> > + If 16-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to write.
> > + @param Count The number of times to write I/O port.
> > + @param Buffer The buffer to retrieve the write data from.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +IoWriteFifo16 (
> > + IN UINTN Port,
> > + IN UINTN Count,
> > + IN VOID *Buffer
> > + )
> > +{
> > + UINT16 *Buffer16;
> > +
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + Buffer16 = (UINT16 *)Buffer;
> > + while (Count-- > 0) {
> > + *(volatile UINT16 *)Port++ = *Buffer16++;
> > + }
> > +}
> > +
> > +/**
> > + Reads a 32-bit I/O port fifo into a block of memory.
> > +
> > + Reads the 32-bit I/O fifo port specified by Port.
> > + The port is read Count times, and the read data is
> > + stored in the provided Buffer.
> > +
> > + This function must guarantee that all I/O read and write operations are
> > + serialized.
> > +
> > + If 32-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to read.
> > + @param Count The number of times to read I/O port.
> > + @param Buffer The buffer to store the read data into.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +IoReadFifo32 (
> > + IN UINTN Port,
> > + IN UINTN Count,
> > + OUT VOID *Buffer
> > + )
> > +{
> > + UINT32 *Buffer32;
> > +
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + Buffer32 = (UINT32 *)Buffer;
> > + while (Count-- > 0) {
> > + *Buffer32++ = *(volatile UINT32 *)Port++;
> > + }
> > +}
> > +
> > +/**
> > + Writes a block of memory into a 32-bit I/O port fifo.
> > +
> > + Writes the 32-bit I/O fifo port specified by Port.
> > + The port is written Count times, and the write data is
> > + retrieved from the provided Buffer.
> > +
> > + This function must guarantee that all I/O write and write operations are
> > + serialized.
> > +
> > + If 32-bit I/O port operations are not supported, then ASSERT().
> > +
> > + @param Port The I/O port to write.
> > + @param Count The number of times to write I/O port.
> > + @param Buffer The buffer to retrieve the write data from.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +IoWriteFifo32 (
> > + IN UINTN Port,
> > + IN UINTN Count,
> > + IN VOID *Buffer
> > + )
> > +{
> > + UINT32 *Buffer32;
> > +
> > + //
> > + // RISC-V only supports memory map I/O. However the
> > + // first implementation of RISC-V EDK2 port uses PC/AT
> > + // as the RISC-V platform spec. We have to keep I/O
> > + // functions as the temporary solution.
> > + //
> > + Buffer32 = (UINT32 *)Buffer;
> > + while (Count-- > 0) {
> > + *(volatile UINT32 *)Port++ = *Buffer32++;
> > + }
> > +}
> > --
> > 2.7.4
> >
> >
> >
> >
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#47262): https://edk2.groups.io/g/devel/message/47262
Mute This Topic: https://groups.io/mt/33137129/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-