[edk2-devel] [edk2-platforms][PATCH V3 3/5] Platform/Sgi: Add SSDT table for IO virtualization SoC expansion block

Sami Mujawar sami.mujawar at arm.com
Wed Apr 26 16:17:16 UTC 2023


Hi Vivek,

Thank you for this patch.

Reviewed-by: Sami Mujawar <sami.mujawar at arm.com>

Regards,

Sami Mujawar

On 24/03/2023 11:03 am, Vivek Gautam wrote:
> Arm reference design platforms have multiple IO virtualization blocks
> that allow connecting PCIe root bus or non-PCIe SoC peripherals to the
> system. Each of these IO virtualization blocks consists of an instance
> of SMMUv3, a GIC-ITS and a NCI (network chip interconnect) to support
> traffic flow and address mapping, as required.
>
> The SoC expansion blocks that connect to the IO virtualization block
> include devices such as UARTs, DMAs and few additional memory nodes. For
> platforms having SoC expansion block connected to the IO virtualization
> block add a SSDT table to describe devices included in the SoC expansion
> block. Preprocessor macros are also added in this change to allow
> scalability for platforms that implement multiple instances of these SoC
> expansion blocks.
>
> Signed-off-by: Vivek Gautam <vivek.gautam at arm.com>
> ---
>   Platform/ARM/SgiPkg/SgiPlatform.dec                 |   4 +
>   Platform/ARM/SgiPkg/SgiMemoryMap2.dsc.inc           |   3 +
>   Platform/ARM/SgiPkg/Include/IoVirtSoCExp.h          | 188 ++++++++++++++++++++
>   Platform/ARM/SgiPkg/AcpiTables/SsdtIoVirtSocExp.asl |  96 ++++++++++
>   4 files changed, 291 insertions(+)
>
> diff --git a/Platform/ARM/SgiPkg/SgiPlatform.dec b/Platform/ARM/SgiPkg/SgiPlatform.dec
> index e878af24d56b..1613cc01981e 100644
> --- a/Platform/ARM/SgiPkg/SgiPlatform.dec
> +++ b/Platform/ARM/SgiPkg/SgiPlatform.dec
> @@ -98,5 +98,9 @@
>     # Address bus width
>     gArmSgiTokenSpaceGuid.PcdMaxAddressBitsPerChip|0x0|UINT64|0x00000027
>   
> +  # IO virtualization block
> +  gArmSgiTokenSpaceGuid.PcdIoVirtSocExpBlk0Base|0|UINT64|0x0000002B
> +  gArmSgiTokenSpaceGuid.PcdIoVirtSocExpBlkUartEnable|0|UINT32|0x0000002C
> +
>   [Ppis]
>     gNtFwConfigDtInfoPpiGuid     = { 0x6f606eb3, 0x9123, 0x4e15, { 0xa8, 0x9b, 0x0f, 0xac, 0x66, 0xef, 0xd0, 0x17 } }
> diff --git a/Platform/ARM/SgiPkg/SgiMemoryMap2.dsc.inc b/Platform/ARM/SgiPkg/SgiMemoryMap2.dsc.inc
> index 12dcd82eb132..de1d8ea24b89 100644
> --- a/Platform/ARM/SgiPkg/SgiMemoryMap2.dsc.inc
> +++ b/Platform/ARM/SgiPkg/SgiMemoryMap2.dsc.inc
> @@ -72,3 +72,6 @@
>     gArmSgiTokenSpaceGuid.PcdGpioController0BaseAddress|0x0C1D0000
>     gArmSgiTokenSpaceGuid.PcdGpioController0Size|0x00010000
>     gArmSgiTokenSpaceGuid.PcdGpioController0Interrupt|392
> +
> +  # IO virtualization block
> +  gArmSgiTokenSpaceGuid.PcdIoVirtSocExpBlk0Base|0x1080000000
> diff --git a/Platform/ARM/SgiPkg/Include/IoVirtSoCExp.h b/Platform/ARM/SgiPkg/Include/IoVirtSoCExp.h
> new file mode 100644
> index 000000000000..ab20f7b1413b
> --- /dev/null
> +++ b/Platform/ARM/SgiPkg/Include/IoVirtSoCExp.h
> @@ -0,0 +1,188 @@
> +/** @file
> +*
> +*  Copyright (c) 2023, Arm Limited. All rights reserved.
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +#include "SgiPlatform.h"
> +
> +#define IO_VIRT_BLK_BASE     FixedPcdGet64 (PcdIoVirtSocExpBlk0Base)
> +#define DEV_OFFSET           0x10000000
> +#define RESOURCE_SIZE        0x10000
> +
> +/** Macros to calculate base addresses of UART and DMA devices within IO
> +    virtualization SoC expansion block address space.
> +
> +  @param [in] n         Index of UART or DMA device within SoC expansion block.
> +                        Should be either 0 or 1.
> +
> +  The base address offsets of UART and DMA devices within a SoC expansion block
> +  are shown below. The UARTs are at offset (2 * index * offset), while the DMAs
> +  are at offsets ((2 * index + 1) * offset).
> +  +----------------------------------------------+
> +  | Port # |  Peripheral   | Base address offset |
> +  |--------|---------------|---------------------|
> +  |  x4_0  | PL011_UART0   |     0x0000_0000     |
> +  |--------|---------------|---------------------|
> +  |  x4_1  | PL011_DMA0_NS |     0x1000_0000     |
> +  |--------|---------------|---------------------|
> +  |   x8   | PL011_UART1   |     0x2000_0000     |
> +  |--------|---------------|---------------------|
> +  |   x16  | PL011_DMA1_NS |     0x3000_0000     |
> +  +----------------------------------------------+
> +**/
> +#define UART_START(n)        IO_VIRT_BLK_BASE + (2 * n * DEV_OFFSET)
> +#define DMA_START(n)         IO_VIRT_BLK_BASE + (((2 * n) + 1) * DEV_OFFSET)
> +
> +// Interrupt numbers of PL330 DMA-0 and DMA-1 devices in the SoC expansion
> +// connected to the IO Virtualization block. Each DMA PL330 controller uses
> +// eight data channel interrupts and one instruction channel interrupt to
> +// notify aborts.
> +#define RD_IOVIRT_SOC_EXP_DMA0_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    493, 494, 495, 496, 497, 498, 499, 500, 501                                \
> +  }
> +#define RD_IOVIRT_SOC_EXP_DMA1_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    503, 504, 505, 506, 507, 508, 509, 510, 511                                \
> +  }
> +
> +#define RD_IOVIRT_SOC_EXP_DMA2_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    973, 974, 975, 976, 977, 978, 979, 980, 981                                \
> +  }
> +
> +#define RD_IOVIRT_SOC_EXP_DMA3_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    983, 984, 985, 986, 987, 988, 989, 990, 991                                \
> +  }
> +
> +#define RD_IOVIRT_SOC_EXP_DMA4_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    4557, 4558, 4559, 4560, 4561, 4562, 4563, 4564, 4565                       \
> +  }
> +
> +#define RD_IOVIRT_SOC_EXP_DMA5_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    4567, 4568, 4569, 4570, 4571, 4572, 4573, 4574, 4575                       \
> +  }
> +
> +#define RD_IOVIRT_SOC_EXP_DMA6_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    5037, 5038, 5039, 5040, 5041, 5042, 5043, 5044, 5045                       \
> +  }
> +
> +#define RD_IOVIRT_SOC_EXP_DMA7_INTERRUPTS_INIT                                 \
> +  Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {                 \
> +    5047, 5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055                       \
> +  }
> +
> +/** Macro for PL011 UART controller node instantiation in SSDT table.
> +
> +  See section 5.2.11.2 of ACPI specification v6.4 for the definition of SSDT
> +  table.
> +
> +  @param [in] ComIdx          Index of Com device to be initializaed;
> +                              to be passed as 2-digit index, such as 01 to
> +                              support multichip platforms as well.
> +  @param [in] ChipIdx         Index of chip to which this DMA device belongs
> +  @param [in] StartOff        Starting offset of this device within IO
> +                              virtualization block memory map
> +  @param [in] IrqNum          Interrupt ID used for the device
> +**/
> +#define RD_IOVIRT_SOC_EXP_COM_INIT(ComIdx, ChipIdx, StartOff, IrqNum)          \
> +  Device (COM ##ComIdx) {                                                      \
> +    Name (_HID, "ARMH0011")                                                    \
> +    Name (_UID, ComIdx)                                                        \
> +    Name (_STA, 0xF)                                                           \
> +                                                                               \
> +    Method (_CRS, 0, Serialized) {                                             \
> +      Name (RBUF, ResourceTemplate () {                                        \
> +        QWordMemory (                                                          \
> +          ResourceProducer,                                                    \
> +          PosDecode,                                                           \
> +          MinFixed,                                                            \
> +          MaxFixed,                                                            \
> +          NonCacheable,                                                        \
> +          ReadWrite,                                                           \
> +          0x0,                                                                 \
> +          0,                                                                   \
> +          1,                                                                   \
> +          0x0,                                                                 \
> +          2,                                                                   \
> +          ,                                                                    \
> +          ,                                                                    \
> +          MMI1,                                                                \
> +          AddressRangeMemory,                                                  \
> +          TypeStatic                                                           \
> +        )                                                                      \
> +                                                                               \
> +        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {           \
> +          IrqNum                                                               \
> +        }                                                                      \
> +      }) /* end Name(RBUF) */                                                  \
> +      /* Work around ASL's inability to add in a resource definition */        \
> +      CreateQwordField (RBUF, MMI1._MIN, MIN1)                                 \
> +      CreateQwordField (RBUF, MMI1._MAX, MAX1)                                 \
> +      CreateQwordField (RBUF, MMI1._LEN, LEN1)                                 \
> +      Add (SGI_REMOTE_CHIP_MEM_OFFSET(ChipIdx), StartOff, MIN1)                \
> +      Add (MIN1, RESOURCE_SIZE - 1, MAX1)                                      \
> +      Add (RESOURCE_SIZE, 0, LEN1)                                             \
> +                                                                               \
> +      Return (RBUF)                                                            \
> +    } /* end Method(_CRS) */                                                   \
> +  }
> +
> +/** Macro for PL330 DMA controller node instantiation in SSDT table.
> +
> +  See section 5.2.11.2 of ACPI specification v6.4 for the definition of SSDT
> +  table.
> +
> +  @param [in] DmaIdx          Index of DMA device to be initializaed
> +  @param [in] ChipIdx         Index of chip to which this DMA device belongs
> +  @param [in] StartOff        Starting offset of this device within IO
> +                              virtualization block memory map
> +**/
> +#define RD_IOVIRT_SOC_EXP_DMA_INIT(DmaIdx, ChipIdx, StartOff)                  \
> +  Device (\_SB.DMA ##DmaIdx) {                                                 \
> +    Name (_HID, "ARMH0330")                                                    \
> +    Name (_UID, DmaIdx)                                                        \
> +    Name (_CCA, 1)                                                             \
> +    Name (_STA, 0xF)                                                           \
> +                                                                               \
> +    Method (_CRS, 0, Serialized) {                                             \
> +      Name (RBUF, ResourceTemplate () {                                        \
> +        QWordMemory (                                                          \
> +          ResourceProducer,                                                    \
> +          PosDecode,                                                           \
> +          MinFixed,                                                            \
> +          MaxFixed,                                                            \
> +          NonCacheable,                                                        \
> +          ReadWrite,                                                           \
> +          0x0,                                                                 \
> +          0,                                                                   \
> +          1,                                                                   \
> +          0x0,                                                                 \
> +          2,                                                                   \
> +          ,                                                                    \
> +          ,                                                                    \
> +          MMI2,                                                                \
> +          AddressRangeMemory,                                                  \
> +          TypeStatic                                                           \
> +        )                                                                      \
> +                                                                               \
> +        RD_IOVIRT_SOC_EXP_DMA ##DmaIdx## _INTERRUPTS_INIT                      \
> +      }) /* end Name(RBUF) */                                                  \
> +      /* Work around ASL's inability to add in a resource definition */        \
> +      CreateQwordField (RBUF, MMI2._MIN, MIN2)                                 \
> +      CreateQwordField (RBUF, MMI2._MAX, MAX2)                                 \
> +      CreateQwordField (RBUF, MMI2._LEN, LEN2)                                 \
> +      Add (SGI_REMOTE_CHIP_MEM_OFFSET(ChipIdx), StartOff, MIN2)                \
> +      Add (MIN2, RESOURCE_SIZE - 1, MAX2)                                      \
> +      Add (RESOURCE_SIZE, 0, LEN2)                                             \
> +                                                                               \
> +      Return (RBUF)                                                            \
> +    } /* end Method(_CRS) */                                                   \
> +  }
> diff --git a/Platform/ARM/SgiPkg/AcpiTables/SsdtIoVirtSocExp.asl b/Platform/ARM/SgiPkg/AcpiTables/SsdtIoVirtSocExp.asl
> new file mode 100644
> index 000000000000..d852cf4ffeaa
> --- /dev/null
> +++ b/Platform/ARM/SgiPkg/AcpiTables/SsdtIoVirtSocExp.asl
> @@ -0,0 +1,96 @@
> +/** @file
> +  Secondary System Description Table (SSDT) for IO Virtualization SoC Expansion
> +
> +  The IO virtualization blocks on Arm Reference Design (RD) platforms allow
> +  connecting PCIe root bus as well as other non-PCIe SoC peripherals. Each of
> +  these IO virtualization blocks consists of an instance of SMMUv3, a GIC-ITS
> +  and a NCI (network chip interconnect) to support traffic flow and address
> +  mapping, as required. The PCIe root bus or the SoC peripherals connect to the
> +  IO virtualization block over ports namely x4_0, x4_1, x8 and x16.
> +
> +  Some of the RD platforms utilize one or more IO virtualization blocks to
> +  connect non-PCIe devices mapped in the SoC expansion address space. One
> +  such instance of SoC expansion block consists of a set of non-PCIe devices
> +  that includes two PL011 UART controllers, two PL330 DMA controllers and
> +  few additional memory nodes. The devices in this SoC expansion block are
> +  placed at fixed offsets from a base address in the SoC expansion address
> +  space and the read/write accesses to these devices are routed by the IO
> +  virtualization block.
> +
> +  The table below lists the address offset, address space size and interrupts
> +  used for the devices present in each instance of this SoC expansion block
> +  that is connected to the IO Virtualization block.
> +  +-------------------------------------------------------------------------------+
> +  | Port |  Peripheral   |             Memory map              | Size | Interrupt |
> +  |  #   |               |-------------------------------------|      |    ID     |
> +  |      |               | Start Addr Offset | End Addr Offset |      |           |
> +  +-------------------------------------------------------------------------------+
> +  | x4_0 | PL011_UART0   |     0x0000_0000   |    0x0000_FFFF  | 64KB |    492    |
> +  |-------------------------------------------------------------------------------|
> +  | x4_1 | PL011_DMA0_NS |     0x1000_0000   |    0x1000_FFFF  | 64KB | 493-501   |
> +  |-------------------------------------------------------------------------------|
> +  |  x8  | PL011_UART1   |     0x2000_0000   |    0x2000_FFFF  | 64KB |    502    |
> +  |-------------------------------------------------------------------------------|
> +  |  x16 | PL011_DMA1_NS |     0x3000_0000   |    0x3000_FFFF  | 64KB | 503-511   |
> +  +-------------------------------------------------------------------------------+
> +
> +  This SSDT ACPI table lists the SoC expansion block devices connected via the
> +  IO Virtualization block on RD-N2 platform variants and mapped to SoC expansion
> +  address at an offset of 0x10_8000_0000 from each chip's base address.
> +
> +  Copyright (c) 2023, Arm Limited. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Specification Reference:
> +    - ACPI 6.4, Chapter 5, Section 5.2.11.2, Secondary System Description Table
> +**/
> +
> +#include "IoVirtSoCExp.h"
> +#include "SgiAcpiHeader.h"
> +
> +DefinitionBlock ("SsdtIoVirtSocExp.aml", "SSDT", 2, "ARMLTD", "ARMSGI",
> +                 EFI_ACPI_ARM_OEM_REVISION) {
> +  Scope (_SB)
> +  {
> +
> +    // IO Virtualization SoC Expansion - PL011 UART
> +#if (FixedPcdGet32 (PcdIoVirtSocExpBlkUartEnable) == 1)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(2, 0, UART_START(0), 492)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(3, 0, UART_START(1), 502)
> +
> +#if (FixedPcdGet32 (PcdChipCount) > 1)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(4, 1, UART_START(0), 972)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(5, 1, UART_START(1), 982)
> +#endif
> +
> +#if (FixedPcdGet32 (PcdChipCount) > 2)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(6, 2, UART_START(0), 4556)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(7, 2, UART_START(1), 4566)
> +#endif
> +
> +#if (FixedPcdGet32 (PcdChipCount) > 3)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(8, 3, UART_START(0), 5036)
> +    RD_IOVIRT_SOC_EXP_COM_INIT(9, 3, UART_START(1), 5046)
> +#endif
> +#endif
> +
> +    // IO Virtualization SoC Expansion - PL330 DMA
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(0, 0, DMA_START(0))
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(1, 0, DMA_START(1))
> +
> +#if (FixedPcdGet32 (PcdChipCount) > 1)
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(2, 1, DMA_START(0))
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(3, 1, DMA_START(1))
> +#endif
> +
> +#if (FixedPcdGet32 (PcdChipCount) > 2)
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(4, 2, DMA_START(0))
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(5, 2, DMA_START(1))
> +#endif
> +
> +#if (FixedPcdGet32 (PcdChipCount) > 3)
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(6, 3, DMA_START(0))
> +    RD_IOVIRT_SOC_EXP_DMA_INIT(7, 3, DMA_START(1))
> +#endif
> +  } // Scope(_SB)
> +}


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103657): https://edk2.groups.io/g/devel/message/103657
Mute This Topic: https://groups.io/mt/97821140/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list