1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <acpi/acpi_iort.h>
7 unsigned long acpi_iort_its_entry(unsigned long current
, acpi_iort_t
*iort
,
8 acpi_iort_node_t
**its_out
, u32 its_count
, u32
*identifiers
)
10 acpi_iort_its_group_t
*its_node_data
;
11 acpi_iort_node_t
*its
= (acpi_iort_node_t
*)current
;
12 const unsigned long its_start
= current
;
15 current
+= sizeof(*its
) + sizeof(*its_node_data
);
16 memset(its
, 0, current
- its_start
);
18 its
->type
= ACPI_IORT_NODE_ITS_GROUP
;
20 its
->identifier
= iort
->node_count
++;
22 its_node_data
= (acpi_iort_its_group_t
*)its
->node_data
;
23 its_node_data
->its_count
= its_count
;
25 for (int i
= 0; i
< its_count
; i
++)
26 its_node_data
->identifiers
[i
] = identifiers
[i
];
28 current
+= its_node_data
->its_count
* sizeof(its_node_data
->identifiers
[0]);
29 its
->length
= current
- its_start
;
36 unsigned long acpi_iort_smmuv3_entry(unsigned long current
, acpi_iort_t
*iort
,
37 acpi_iort_node_t
**smmu_v3_out
, u64 base
, u32 flags
)
39 acpi_iort_smmu_v3_t
*smmu_v3_node_data
;
40 acpi_iort_node_t
*smmu_v3
= (acpi_iort_node_t
*)current
;
41 const unsigned long smmu_v3_start
= current
;
44 current
+= sizeof(*smmu_v3
) + sizeof(*smmu_v3_node_data
);
45 memset(smmu_v3
, 0, current
- smmu_v3_start
);
47 smmu_v3
->type
= ACPI_IORT_NODE_SMMU_V3
;
48 smmu_v3
->revision
= 0x5;
49 smmu_v3
->identifier
= iort
->node_count
++; // Unique identifier.
50 smmu_v3
->mapping_offset
= current
- smmu_v3_start
;
52 /* length is further updated by id map entries */
53 smmu_v3
->length
= smmu_v3
->mapping_offset
;
55 smmu_v3_node_data
= (acpi_iort_smmu_v3_t
*)smmu_v3
->node_data
;
56 smmu_v3_node_data
->base_address
= base
;
57 smmu_v3_node_data
->flags
= flags
;
59 *smmu_v3_out
= smmu_v3
;
64 unsigned long acpi_iort_nc_entry(unsigned long current
, acpi_iort_t
*iort
,
65 acpi_iort_node_t
**nc_out
, u32 node_flags
, u64 memory_properties
,
66 u32 memory_address_limit
, char *device_name
)
68 acpi_iort_named_component_t
*nc_node_data
;
69 acpi_iort_node_t
*nc
= (acpi_iort_node_t
*)current
;
70 const unsigned long nc_start
= current
;
71 const u16 device_name_len
= strlen(device_name
);
74 current
+= sizeof(*nc
) + sizeof(*nc_node_data
);
75 memset(nc
, 0, current
- nc_start
);
77 nc
->type
= ACPI_IORT_NODE_NAMED_COMPONENT
;
79 nc
->identifier
= iort
->node_count
++; // Unique identifier.
81 nc_node_data
= (acpi_iort_named_component_t
*)nc
->node_data
;
82 nc_node_data
->node_flags
= node_flags
;
83 nc_node_data
->memory_properties
= memory_properties
;
84 nc_node_data
->memory_address_limit
= memory_address_limit
;
86 /* Path of namespace object */
87 memset(nc_node_data
->device_name
, 0, device_name_len
+ 5);
88 strncpy(nc_node_data
->device_name
, device_name
, device_name_len
+ 1);
90 current
+= device_name_len
+ 2;
91 current
= ALIGN_UP(current
, 4);
93 nc
->mapping_offset
= current
- nc_start
;
95 /* length is further updated by id map entries */
96 nc
->length
= nc
->mapping_offset
;
103 unsigned long acpi_iort_rc_entry(unsigned long current
, acpi_iort_t
*node
,
104 acpi_iort_node_t
**rc_out
, u64 memory_properties
,
105 u32 ats_attribute
, u32 pci_segment_number
,
106 u8 memory_address_limit
, u16 pasid_capabilities
)
108 acpi_iort_root_complex_t
*rc_node_data
;
109 acpi_iort_node_t
*rc
= (acpi_iort_node_t
*)current
;
110 const unsigned long rc_start
= current
;
113 current
+= sizeof(*rc
) + sizeof(*rc_node_data
);
114 memset(rc
, 0, current
- rc_start
);
116 rc
->type
= ACPI_IORT_NODE_PCI_ROOT_COMPLEX
;
118 rc
->identifier
= node
->node_count
++; // Unique identifier.
119 rc
->mapping_offset
= current
- rc_start
;
121 /* length is further updated by id map entries */
122 rc
->length
= rc
->mapping_offset
;
124 rc_node_data
= (acpi_iort_root_complex_t
*)rc
->node_data
;
125 rc_node_data
->memory_properties
= memory_properties
; /* Memory access properties */
126 rc_node_data
->ats_attribute
= ats_attribute
;
127 rc_node_data
->pci_segment_number
= pci_segment_number
;
128 rc_node_data
->memory_address_limit
= memory_address_limit
; /* Memory address size limit */
129 rc_node_data
->pasid_capabilities
= pasid_capabilities
; /* PASID Capabilities */
136 unsigned long acpi_iort_id_map_entry(unsigned long current
, acpi_iort_node_t
*node
, u32 input_base
,
137 u32 id_count
, u32 output_base
, u32 output_reference
, u32 flags
)
139 acpi_iort_id_mapping_t
*id_map
= (acpi_iort_id_mapping_t
*)current
;
142 memset(id_map
, 0, sizeof(acpi_iort_id_mapping_t
));
144 current
+= sizeof(acpi_iort_id_mapping_t
);
146 node
->mapping_count
++;
147 node
->length
+= current
- (unsigned long)id_map
;
149 id_map
->input_base
= input_base
;
150 id_map
->id_count
= id_count
- 1;
151 id_map
->output_base
= output_base
;
152 id_map
->output_reference
= output_reference
;
153 id_map
->flags
= flags
;