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

#include "ArmPlatform.h"
#include <Library/AcpiLib.h>
#include <Library/ArmLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/DebugPort2Table.h>

#pragma pack(1)

#define DBG2_NUM_DEBUG_PORTS                       1
#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS   1
#define DBG2_NAMESPACESTRING_FIELD_SIZE            8
#define PL011_UART_LENGTH                          0x1000

#define NAME_STR_UART1     {'C', 'O', 'M', '1', '\0', '\0', '\0', '\0'}

typedef struct {
  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device;
  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE        BaseAddressRegister;
  UINT32                                        AddressSize;
  UINT8                                         NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE];
} DBG2_DEBUG_DEVICE_INFORMATION;

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


#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 */ \
      DBG2_NAMESPACESTRING_FIELD_SIZE,                                /* 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_5_1_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \
    UartAddrLen,                                     /* UINT32  AddressSize */                                        \
    UartNameStr                                      /* UINT8   NameSpaceString[MAX_DBG2_NAME_LEN] */                 \
  }


STATIC DBG2_TABLE Dbg2 = {
  {
    ARM_ACPI_HEADER (EFI_ACPI_5_1_DEBUG_PORT_2_TABLE_SIGNATURE,
                       DBG2_TABLE,
                       EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION),
    OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo),
    DBG2_NUM_DEBUG_PORTS                                              /* UINT32  NumberDbgDeviceInfo */
  },
  {
    /*
     * Kernel Debug Port
     */
    DBG2_DEBUG_PORT_DDI (DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS,
                          EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART,
                          FixedPcdGet64 (PcdSerialDbgRegisterBase),
                          PL011_UART_LENGTH,
                          NAME_STR_UART1),
  }
};

#pragma pack()

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