acpi: Add cb support to publish CRAT ACPI object

Add cb support to publish CRAT ACPI object in native coreboot.

BUG=b:155307433
BRANCH=Zork

Change-Id: I5fb7c15b11414f6d807645921c0ff1ab927e6e0f
Signed-off-by: Jason Glenesk <jason.glenesk@amd.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/48532
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com>
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h
index f6eb772..1c364a0 100644
--- a/src/include/acpi/acpi.h
+++ b/src/include/acpi/acpi.h
@@ -73,7 +73,7 @@
 	BERT, DBG2, DMAR, DSDT, FACS, FADT, HEST, HPET, IVRS, MADT, MCFG,
 	RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT,
 	/* Additional proprietary tables used by coreboot */
-	VFCT, NHLT, SPMI
+	VFCT, NHLT, SPMI, CRAT
 };
 
 /* RSDP (Root System Description Pointer) */
@@ -307,6 +307,14 @@
 	struct acpi_ivrs_ivhd ivhd;
 } __packed acpi_ivrs_t;
 
+/* CRAT (Component Resource Affinity Table Structure) */
+struct acpi_crat_header {
+	acpi_header_t header;
+	uint32_t total_entries;
+	uint16_t num_nodes;
+	uint8_t reserved[6];
+} __packed;
+
 /* IVHD Type 11h IOMMU Attributes */
 typedef struct ivhd11_iommu_attr {
 	uint32_t reserved1 : 13;
@@ -964,6 +972,10 @@
 		      unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
 		      unsigned long current));
 
+void acpi_create_crat(struct acpi_crat_header *crat,
+		      unsigned long (*acpi_fill_crat)(struct acpi_crat_header *crat_struct,
+		      unsigned long current));
+
 void acpi_create_hpet(acpi_hpet_t *hpet);
 unsigned long acpi_write_hpet(const struct device *device, unsigned long start,
 			      acpi_rsdp_t *rsdp);
diff --git a/src/include/acpi/acpi_crat.h b/src/include/acpi/acpi_crat.h
new file mode 100644
index 0000000..b6ae1d6
--- /dev/null
+++ b/src/include/acpi/acpi_crat.h
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ACPI_CRAT_H__
+#define __ACPI_CRAT_H__
+
+enum crat_entry_type {
+	CRAT_HSA_PROC_UNIT_TYPE,
+	CRAT_MEMORY_TYPE,
+	CRAT_CACHE_TYPE,
+	CRAT_TLB_TYPE,
+	CRAT_FPU_TYPE,
+	CRAT_IO_TYPE,
+	CRAT_MAX_TYPE,
+};
+
+#define CRAT_HSA_PR_FLAG_EN_SHFT		0
+#define CRAT_HSA_PR_FLAG_EN			(0x1 << CRAT_HSA_PR_FLAG_EN_SHFT)
+#define CRAT_HSA_PR_FLAG_HOT_PLUG_SHFT		1
+#define CRAT_HSA_PR_FLAG_HOT_PLUG		(0x1 << CRAT_HSA_PR_FLAG_HOT_PLUG_SHFT)
+#define CRAT_HSA_PR_FLAG_CPU_PRES_SHFT		2
+#define CRAT_HSA_PR_FLAG_CPU_PRES		(0x1 << CRAT_HSA_PR_FLAG_CPU_PRES_SHFT)
+#define CRAT_HSA_PR_FLAG_GPU_PRES_SHFT		3
+#define CRAT_HSA_PR_FLAG_GPU_PRES		(0x1 << CRAT_HSA_PR_FLAG_GPU_PRES_SHFT)
+#define CRAT_HSA_PR_FLAG_CRAT_HSAMMU_SHFT	4
+#define CRAT_HSA_PR_FLAG_CRAT_HSAMMU		(0x1 << CRAT_HSA_PR_FLAG_CRAT_HSAMMU_SHFT)
+#define CRAT_HSA_PR_FLAG_VAL_LIM_SHFT		5
+#define CRAT_HSA_PR_FLAG_VAL_LIM		(0x7 << CRAT_HSA_PR_FLAG_VAL_LIM_SHFT)
+#define CRAT_HSA_PR_FLAG_ATOM_OPS_SHFT		8
+#define CRAT_HSA_PR_FLAG_ATOM_OPS		(0x3 << CRAT_HSA_PR_FLAG_ATOM_OPS_SHFT)
+#define CRAT_HSA_PR_FLAG_SMT_CAPS_SHFT		10
+#define CRAT_HSA_PR_FLAG_SMT_CAPS		(0x3 << CRAT_HSA_PR_FLAG_SMT_CAPS_SHFT)
+
+/* CRAT HSA Processing Unit Affinity Structure */
+struct crat_hsa_processing_unit {
+	uint8_t type;
+	uint8_t length;
+	uint16_t reserved;
+	uint32_t flags;
+	uint32_t proximity_node;
+	uint32_t processor_id_low;
+	uint16_t num_cpu_cores;
+	uint16_t num_simd_cores;
+	uint16_t max_waves_simd;
+	uint16_t io_count;
+	uint16_t hsa_capability;
+	uint16_t lds_size_in_kb;
+	uint8_t wave_front_size;
+	uint8_t num_shader_banks;
+	uint16_t uengine_identifier;
+	uint8_t num_arrays;
+	uint8_t num_cu_per_array;
+	uint8_t num_simd_per_cu;
+	uint8_t max_slots_scratch_cu;
+	uint8_t reserved1[4];
+} __packed;
+
+#define CRAT_L1_CACHE			1
+#define CRAT_L2_CACHE			2
+#define CRAT_L3_CACHE			3
+
+#define CRAT_MEM_FLAG_EN_SHFT		0
+#define CRAT_MEM_FLAG_EN		(0x1 << CRAT_MEM_FLAG_EN_SHFT)
+#define CRAT_MEM_FLAG_HOT_PLUG_SHFT	1
+#define CRAT_MEM_FLAG_HOT_PLUG		(0x1 << CRAT_MEM_FLAG_HOT_PLUG_SHFT)
+#define CRAT_MEM_FLAG_NV_SHFT		2
+#define CRAT_MEM_FLAG_NV		(0x1 << CRAT_MEM_FLAG_NV_SHFT)
+#define CRAT_MEM_FLAG_ATOM_OPS_SHFT	3
+#define CRAT_MEM_FLAG_ATOM_OPS		(0x3 << CRAT_MEM_FLAG_ATOM_OPS_SHFT)
+
+/* CRAT Memory Affinity Structure */
+struct crat_memory {
+	uint8_t type;
+	uint8_t length;
+	uint16_t reserved;
+	uint32_t flags;
+	uint32_t proximity_domain;
+	uint32_t base_address_low;
+	uint32_t base_address_high;
+	uint32_t length_low;
+	uint32_t length_high;
+	uint32_t width;
+	uint8_t reserved1[8];
+} __packed;
+
+#define CRAT_CACHE_FLAG_EN_SHFT			0
+#define CRAT_CACHE_FLAG_EN			(0x1 << CRAT_CACHE_FLAG_EN_SHFT)
+#define CRAT_CACHE_FLAG_DATA_CACHE_SHFT		1
+#define CRAT_CACHE_FLAG_DATA_CACHE		(0x1 << CRAT_CACHE_FLAG_DATA_CACHE_SHFT)
+#define CRAT_CACHE_FLAG_INSTR_CACHE_SHFT	2
+#define CRAT_CACHE_FLAG_INSTR_CACHE		(0x1 << CRAT_CACHE_FLAG_INSTR_CACHE_SHFT)
+#define CRAT_CACHE_FLAG_CPU_CACHE_SHFT		3
+#define CRAT_CACHE_FLAG_CPU_CACHE		(0x1 << CRAT_CACHE_FLAG_CPU_CACHE_SHFT)
+#define CRAT_CACHE_FLAG_SIMD_CACHE_SHFT		4
+#define CRAT_CACHE_FLAG_SIMD_CACHE		(0x1 << CRAT_CACHE_FLAG_SIMD_CACHE_SHFT)
+#define CRAT_CACHE_FLAG_GDS_SHFT		5
+#define CRAT_CACHE_FLAG_GDS			(0x1 << CRAT_CACHE_FLAG_GDS_SHFT)
+#define CRAT_CACHE_FLAG_ATOMIC_OPS_SHFT		6
+#define CRAT_CACHE_FLAG_ATOMIC_OPS		(0x1 << CRAT_CACHE_FLAG_ATOMIC_OPS_SHFT)
+
+/* CRAT Cache Affinity Structure */
+struct crat_cache {
+	uint8_t type;
+	uint8_t length;
+	uint16_t reserved;
+	uint32_t flags;
+	uint32_t proc_id_low;
+	uint8_t sibling_map[32];
+	uint32_t cache_size;
+	uint8_t cache_level;
+	uint8_t lines_per_tag;
+	uint16_t cache_line_size;
+	uint8_t associativity;
+	uint8_t cache_properties;
+	uint16_t cache_latency;
+	uint8_t reserved1[8];
+} __packed;
+
+enum tlb_type {
+	tlb_2m,
+	tlb_4k,
+	tlb_1g,
+	tlb_type_max,
+};
+
+#define CRAT_TLB_FLAG_EN_SHFT			0
+#define CRAT_TLB_FLAG_EN			(0x1 << CRAT_TLB_FLAG_EN_SHFT)
+#define CRAT_TLB_FLAG_DATA_TLB_SHFT		1
+#define CRAT_TLB_FLAG_DATA_TLB			(0x1 << CRAT_TLB_FLAG_DATA_TLB_SHFT)
+#define CRAT_TLB_FLAG_INSTR_TLB_SHFT		2
+#define CRAT_TLB_FLAG_INSTR_TLB			(0x1 << CRAT_TLB_FLAG_INSTR_TLB_SHFT)
+#define CRAT_TLB_FLAG_CPU_TLB_SHFT		3
+#define CRAT_TLB_FLAG_CPU_TLB			(0x1 << CRAT_TLB_FLAG_CPU_TLB_SHFT)
+#define CRAT_TLB_FLAG_SIMD_TLB_SHFT		4
+#define CRAT_TLB_FLAG_SIMD_TLB			(0x1 << CRAT_TLB_FLAG_SIMD_TLB_SHFT)
+#define CRAT_TLB_FLAG_4K_BASE_256_SHFT		5
+#define CRAT_TLB_FLAG_4K_BASE_256		(0x1 << CRAT_TLB_FLAG_4K_BASE_256_SHFT)
+#define CRAT_TLB_FLAG_2MB_BASE_256_SHFT		7
+#define CRAT_TLB_FLAG_2MB_BASE_256		(0x1 << CRAT_TLB_FLAG_2MB_BASE_256_SHFT)
+#define CRAT_TLB_FLAG_1GB_BASE_256_SHFT		9
+#define CRAT_TLB_FLAG_1GB_BASE_256		(0x1 << CRAT_TLB_FLAG_1GB_BASE_256_SHFT)
+
+/* CRAT TLB Affinity Structure */
+struct crat_tlb {
+	uint8_t type;
+	uint8_t length;
+	uint16_t reserved;
+	uint32_t flags;
+	uint32_t proc_id_low;
+	uint8_t sibling_map[32];
+	uint32_t tlb_level;
+	uint8_t data_tlb_2mb_assoc;
+	uint8_t data_tlb_2mb_size;
+	uint8_t instr_tlb_2mb_assoc;
+	uint8_t instr_tlb_2mb_size;
+	uint8_t data_tlb_4k_assoc;
+	uint8_t data_tlb_4k_size;
+	uint8_t instr_tlb_4k_assoc;
+	uint8_t instr_tlb_4k_size;
+	uint8_t data_tlb_1g_assoc;
+	uint8_t data_tlb_1g_size;
+	uint8_t instr_tlb_1g_assoc;
+	uint8_t instr_tlb_1g_size;
+	uint8_t reserved1[4];
+} __packed;
+
+#define CRAT_FPU_FLAG_EN_SHFT		0
+#define CRAT_FPU_FLAG_EN		(0x1 << CRAT_TLB_FLAG_EN_SHFT)
+
+/* CRAT FPU Affinity Structure */
+struct crat_fpu {
+	uint8_t type;
+	uint8_t length;
+	uint16_t reserved;
+	uint32_t flags;
+	uint32_t proc_id_low;
+	uint8_t sibling_map[32];
+	uint32_t fpu_size;
+	uint8_t reserved1[16];
+} __packed;
+
+#define CRAT_IO_FLAG_EN_SHFT		0
+#define CRAT_IO_FLAG_EN			(0x1 << CRAT_IO_FLAG_EN_SHFT)
+#define CRAT_IO_FLAG_COHER_SHFT		1
+#define CRAT_IO_FLAG_COHER		(0x1 << CRAT_IO_FLAG_COHER_SHFT)
+
+/* CRAT IO Affinity Structure */
+struct crat_io {
+	uint8_t type;
+	uint8_t length;
+	uint16_t reserved;
+	uint32_t flags;
+	uint32_t proximity_domain_from;
+	uint32_t proximity_domain_to;
+	uint8_t io_type;
+	uint8_t version_major;
+	uint16_t version_minor;
+	uint32_t minimum_latency;
+	uint32_t maximum_latency;
+	uint32_t minimum_bandwidth;
+	uint32_t maximum_bandwidth;
+	uint32_t recommended_transfer_size;
+	uint8_t reserved1[24];
+} __packed;
+
+#endif /* __ACPI_CRAT_H__ */