/** @file
*  Debug Port Table 2 (DBG2)
*
*  Copyright (c) 2018, ARM Limited. All rights reserved.
*
*  SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/

#include "SgiAcpiHeader.h"
#include <Library/AcpiLib.h>
#include <IndustryStandard/Acpi62.h>
#include <IndustryStandard/DebugPort2Table.h>

#define SGI_DBG2_NUM_DEBUG_PORTS           1
#define SGI_DBG2_NUM_GAS                   1
#define SGI_DBG2_NS_STR_LENGTH             12
#define SGI_PL011_REGISTER_SPACE           0x1000

#pragma pack(1)

typedef struct {
  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device;
  EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE        BaseAddressRegister;
  UINT32                                        AddressSize;
  UINT8                                         NameSpaceString[SGI_DBG2_NS_STR_LENGTH];
} DBG2_DEBUG_DEVICE_INFORMATION;

typedef struct {
  EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE       Description;
  DBG2_DEBUG_DEVICE_INFORMATION                 Dbg2DeviceInfo[SGI_DBG2_NUM_DEBUG_PORTS];
} DBG2_TABLE;

#pragma pack()

#define DBG2_DEBUG_PORT_DDI(NumReg, SubType, UartBase, UartAddrLen, UartNameStr) {                                  \
  {                                                                                                                 \
    EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,         /* UINT8     Revision */                        \
    sizeof (DBG2_DEBUG_DEVICE_INFORMATION),                         /* UINT16    Length */                          \
    NumReg,                                                         /* UINT8     NumberofGenericAddressRegisters */ \
    SGI_DBG2_NS_STR_LENGTH,                                         /* UINT16    NameSpaceStringLength */           \
    OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString),     /* UINT16    NameSpaceStringOffset */           \
    0,                                                              /* UINT16    OemDataLength */                   \
    0,                                                              /* UINT16    OemDataOffset */                   \
    EFI_ACPI_DBG2_PORT_TYPE_SERIAL,                                 /* UINT16    Port Type */                       \
    SubType,                                                        /* UINT16    Port Subtype */                    \
    { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },             /* UINT8     Reserved[2] */                     \
    OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), /* UINT16    BaseAddressRegister Offset */      \
    OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize)          /* UINT16    AddressSize Offset */              \
  },                                                                                                                \
  ARM_GAS32 (UartBase),                            /* EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \
  UartAddrLen,                                     /* UINT32  AddressSize */                                        \
  UartNameStr                                      /* UINT8   NameSpaceString[MAX_DBG2_NAME_LEN] */                 \
}

STATIC DBG2_TABLE Dbg2 = {
  {
    ARM_ACPI_HEADER (
      EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,
      DBG2_TABLE,
      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
    ),
    OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo),
    SGI_DBG2_NUM_DEBUG_PORTS
  },
  {
    // Kernel Debug Port
    DBG2_DEBUG_PORT_DDI (
      SGI_DBG2_NUM_GAS,
      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART,
      FixedPcdGet64 (PcdSerialDbgRegisterBase),
      SGI_PL011_REGISTER_SPACE,
      "\\_SB.COM0"
    )
  }
};

//
// Reference the table being generated to prevent the optimizer from removing
// the data structure from the executable
//
VOID* CONST ReferenceAcpiTable = &Dbg2;
