Skip to content

Commit

Permalink
acpi: Add IO Remapping Table structures
Browse files Browse the repository at this point in the history
Input Output Remapping Table (IORT) represents the IO topology of an Arm
based system.

Document number: ARM DEN 0049E.e, Sep 2022

Change-Id: I4e8e3323caa714a56882939914cac510bf95d30b
Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/77884
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
  • Loading branch information
nsolanki22 authored and LeanSheng committed Dec 6, 2023
1 parent 67b3c8f commit 6920c6f
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/acpi/Kconfig
Expand Up @@ -86,6 +86,12 @@ config ACPI_GTDT
help
Selected by platforms that implement ARM generic timers

config ACPI_IORT
def_bool n
depends on ARCH_ARM64 && HAVE_ACPI_TABLES
help
Selected by platforms that implement ARM IO Remap table.

config MAX_ACPI_TABLE_SIZE_KB
int
default 144
Expand Down
24 changes: 24 additions & 0 deletions src/acpi/acpi.c
Expand Up @@ -14,6 +14,7 @@
*/

#include <acpi/acpi.h>
#include <acpi/acpi_iort.h>
#include <acpi/acpi_ivrs.h>
#include <acpi/acpigen.h>
#include <cbfs.h>
Expand Down Expand Up @@ -1194,6 +1195,26 @@ unsigned long acpi_gtdt_add_watchdog(unsigned long current, uint64_t refresh_fra
return current + sizeof(struct acpi_gtdt_watchdog);
}

static void acpi_create_iort(acpi_header_t *header, void *unused)
{
if (!CONFIG(ACPI_IORT))
return;

acpi_iort_t *iort = (acpi_iort_t *)header;
unsigned long current = (unsigned long)iort + sizeof(acpi_iort_t);

if (acpi_fill_header(header, "IORT", IORT, sizeof(acpi_iort_t)) != CB_SUCCESS)
return;

iort->node_count = 0;
iort->node_offset = current - (unsigned long)iort;

current = acpi_soc_fill_iort(iort, current);

/* (Re)calculate length */
header->length = current - (unsigned long)iort;
}

unsigned long acpi_create_lpi_desc_ncst(acpi_lpi_desc_ncst_t *lpi_desc, uint16_t uid)
{
memset(lpi_desc, 0, sizeof(acpi_lpi_desc_ncst_t));
Expand Down Expand Up @@ -1409,6 +1430,7 @@ unsigned long write_acpi_tables(const unsigned long start)
{ acpi_create_spcr, NULL, sizeof(acpi_spcr_t) },
{ acpi_create_gtdt, NULL, sizeof(acpi_gtdt_t) },
{ acpi_create_pptt, NULL, sizeof(acpi_pptt_t) },
{ acpi_create_iort, NULL, sizeof(acpi_iort_t) },
};

current = start;
Expand Down Expand Up @@ -1760,6 +1782,8 @@ int get_acpi_table_revision(enum acpi_tables table)
return 3;
case PPTT: /* ACPI 6.4 */
return 3;
case IORT: /* IO Remapping Table E.e */
return 6;
default:
return -1;
}
Expand Down
1 change: 1 addition & 0 deletions src/include/acpi/acpi.h
Expand Up @@ -105,6 +105,7 @@ enum acpi_tables {
XSDT, /* Extended System Description Table */
/* Additional proprietary tables used by coreboot */
CRAT, /* Component Resource Attribute Table */
IORT, /* Input Output Remapping Table */
NHLT, /* Non HD audio Link Table */
SPMI, /* Server Platform Management Interface table */
VFCT /* VBIOS Fetch Table */
Expand Down
113 changes: 113 additions & 0 deletions src/include/acpi/acpi_iort.h
@@ -0,0 +1,113 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __ACPI_IORT_H__
#define __ACPI_IORT_H__

#include <acpi/acpi.h>
#include <types.h>

/* IORT - IO Remapping Table revision 6
* Document number: ARM DEN 0049E.e, Sep 2022
*/
typedef struct acpi_table_iort {
acpi_header_t header; /* Common ACPI table header */
u32 node_count;
u32 node_offset;
u32 reserved;
} __packed acpi_iort_t;

/*
* IORT subtables
*/
typedef struct acpi_iort_node {
u8 type;
u16 length;
u8 revision;
u32 identifier;
u32 mapping_count;
u32 mapping_offset;
char node_data[];
} __packed acpi_iort_node_t;

/* Values for subtable Type above */
enum acpi_iort_node_type {
ACPI_IORT_NODE_ITS_GROUP = 0x00,
ACPI_IORT_NODE_NAMED_COMPONENT = 0x01,
ACPI_IORT_NODE_PCI_ROOT_COMPLEX = 0x02,
ACPI_IORT_NODE_SMMU = 0x03,
ACPI_IORT_NODE_SMMU_V3 = 0x04,
ACPI_IORT_NODE_PMCG = 0x05,
ACPI_IORT_NODE_RMR = 0x06,
};

/* ITS Group revision 1 */
typedef struct acpi_iort_its_group {
u32 its_count;
u32 identifiers[]; /* GIC ITS identifier array */
} __packed acpi_iort_its_group_t;

/* SMMUv3 revision 5 */
typedef struct acpi_iort_smmu_v3 {
u64 base_address; /* SMMUv3 base address */
u32 flags;
u32 reserved;
u64 vatos_address;
u32 model;
u32 event_gsiv;
u32 pri_gsiv;
u32 gerr_gsiv;
u32 sync_gsiv;
u32 pxm;
u32 id_mapping_index;
} __packed acpi_iort_smmu_v3_t;

/* Masks for Flags field above */
#define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE (1)
#define ACPI_IORT_SMMU_V3_HTTU_OVERRIDE (3<<1)
#define ACPI_IORT_SMMU_V3_PXM_VALID (1<<3)
#define ACPI_IORT_SMMU_V3_DEVICEID_VALID (1<<4)

typedef struct acpi_iort_id_mapping {
u32 input_base; /* Lowest value in input range */
u32 id_count; /* Number of IDs */
u32 output_base; /* Lowest value in output range */
u32 output_reference; /* A reference to the output node */
u32 flags;
} __packed acpi_iort_id_mapping_t;

/* Masks for Flags field above for IORT subtable */
#define ACPI_IORT_ID_SINGLE_MAPPING (1)

/* Named Component revision 4 */
typedef struct acpi_iort_named_component {
u32 node_flags;
u64 memory_properties; /* Memory access properties */
u8 memory_address_limit; /* Memory address size limit */
char device_name[]; /* Path of namespace object */
} __packed acpi_iort_named_component_t;

/* Masks for Flags field above */
#define ACPI_IORT_NC_STALL_SUPPORTED (1)
#define ACPI_IORT_NC_PASID_BITS (31<<1)

typedef struct acpi_iort_root_complex {
u64 memory_properties; /* Memory access properties */
u32 ats_attribute;
u32 pci_segment_number;
u8 memory_address_limit;/* Memory address size limit */
u16 pasid_capabilities; /* PASID Capabilities */
u8 reserved; /* Reserved, must be zero */
u32 flags; /* Flags */
} __packed acpi_iort_root_complex_t;

/* Masks for ats_attribute field above */
#define ACPI_IORT_ATS_SUPPORTED (1) /* The root complex ATS support */
#define ACPI_IORT_PRI_SUPPORTED (1<<1) /* The root complex PRI support */
#define ACPI_IORT_PASID_FWD_SUPPORTED (1<<2) /* The root complex PASID forward support */

/* Masks for pasid_capabilities field above */
#define ACPI_IORT_PASID_MAX_WIDTH (0x1F) /* Bits 0-4 */

unsigned long acpi_soc_fill_iort(acpi_iort_t *iort, unsigned long current);

#endif

0 comments on commit 6920c6f

Please sign in to comment.