diff options
-rw-r--r-- | src/acpi/acpi.c | 31 | ||||
-rw-r--r-- | src/include/acpi/acpi.h | 14 | ||||
-rw-r--r-- | src/include/acpi/acpi_crat.h | 205 |
3 files changed, 249 insertions, 1 deletions
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index c319a73aa7..a16800b025 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -878,6 +878,35 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs, header->checksum = acpi_checksum((void *)ivrs, header->length); } +void acpi_create_crat(struct acpi_crat_header *crat, + unsigned long (*acpi_fill_crat)(struct acpi_crat_header *crat_struct, + unsigned long current)) +{ + acpi_header_t *header = &(crat->header); + unsigned long current = (unsigned long)crat + sizeof(struct acpi_crat_header); + + memset((void *)crat, 0, sizeof(struct acpi_crat_header)); + + if (!header) + return; + + /* Fill out header fields. */ + memcpy(header->signature, "CRAT", 4); + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->asl_compiler_id, ASLC, 4); + + header->asl_compiler_revision = asl_revision; + header->length = sizeof(struct acpi_crat_header); + header->revision = get_acpi_table_revision(CRAT); + + current = acpi_fill_crat(crat, current); + + /* (Re)calculate length and checksum. */ + header->length = current - (unsigned long)crat; + header->checksum = acpi_checksum((void *)crat, header->length); +} + unsigned long acpi_write_hpet(const struct device *device, unsigned long current, acpi_rsdp_t *rsdp) { @@ -1634,6 +1663,8 @@ int get_acpi_table_revision(enum acpi_tables table) return 5; case BERT: return 1; + case CRAT: + return 1; default: return -1; } diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h index f6eb772ac7..1c364a0ee8 100644 --- a/src/include/acpi/acpi.h +++ b/src/include/acpi/acpi.h @@ -73,7 +73,7 @@ enum acpi_tables { 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 @@ typedef struct acpi_ivrs { 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 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs, 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 0000000000..b6ae1d64b6 --- /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__ */ |