Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RISC-V: ACPI: RHCT: Add function to get CBO block sizes

Cache Block Operation (CBO) related block size in ACPI is provided by RHCT.
Add support to read the CMO node in RHCT to get this information.

Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Link: https://lore.kernel.org/r/20231018124007.1306159-4-sunilvl@ventanamicro.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

authored by

Sunil V L and committed by
Palmer Dabbelt
9ca87564 a0683522

+93
+6
arch/riscv/include/asm/acpi.h
··· 66 66 unsigned int cpu, const char **isa); 67 67 68 68 static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; } 69 + void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size, 70 + u32 *cboz_size, u32 *cbop_size); 69 71 #else 70 72 static inline void acpi_init_rintc_map(void) { } 71 73 static inline struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu) ··· 80 78 { 81 79 return -EINVAL; 82 80 } 81 + 82 + static inline void acpi_get_cbo_block_size(struct acpi_table_header *table, 83 + u32 *cbom_size, u32 *cboz_size, 84 + u32 *cbop_size) { } 83 85 84 86 #endif /* CONFIG_ACPI */ 85 87
+87
drivers/acpi/riscv/rhct.c
··· 8 8 #define pr_fmt(fmt) "ACPI: RHCT: " fmt 9 9 10 10 #include <linux/acpi.h> 11 + #include <linux/bits.h> 11 12 12 13 static struct acpi_table_rhct *acpi_get_rhct(void) 13 14 { ··· 81 80 } 82 81 83 82 return -1; 83 + } 84 + 85 + static void acpi_parse_hart_info_cmo_node(struct acpi_table_rhct *rhct, 86 + struct acpi_rhct_hart_info *hart_info, 87 + u32 *cbom_size, u32 *cboz_size, u32 *cbop_size) 88 + { 89 + u32 size_hartinfo = sizeof(struct acpi_rhct_hart_info); 90 + u32 size_hdr = sizeof(struct acpi_rhct_node_header); 91 + struct acpi_rhct_node_header *ref_node; 92 + struct acpi_rhct_cmo_node *cmo_node; 93 + u32 *hart_info_node_offset; 94 + 95 + hart_info_node_offset = ACPI_ADD_PTR(u32, hart_info, size_hartinfo); 96 + for (int i = 0; i < hart_info->num_offsets; i++) { 97 + ref_node = ACPI_ADD_PTR(struct acpi_rhct_node_header, 98 + rhct, hart_info_node_offset[i]); 99 + if (ref_node->type == ACPI_RHCT_NODE_TYPE_CMO) { 100 + cmo_node = ACPI_ADD_PTR(struct acpi_rhct_cmo_node, 101 + ref_node, size_hdr); 102 + if (cbom_size && cmo_node->cbom_size <= 30) { 103 + if (!*cbom_size) 104 + *cbom_size = BIT(cmo_node->cbom_size); 105 + else if (*cbom_size != BIT(cmo_node->cbom_size)) 106 + pr_warn("CBOM size is not the same across harts\n"); 107 + } 108 + 109 + if (cboz_size && cmo_node->cboz_size <= 30) { 110 + if (!*cboz_size) 111 + *cboz_size = BIT(cmo_node->cboz_size); 112 + else if (*cboz_size != BIT(cmo_node->cboz_size)) 113 + pr_warn("CBOZ size is not the same across harts\n"); 114 + } 115 + 116 + if (cbop_size && cmo_node->cbop_size <= 30) { 117 + if (!*cbop_size) 118 + *cbop_size = BIT(cmo_node->cbop_size); 119 + else if (*cbop_size != BIT(cmo_node->cbop_size)) 120 + pr_warn("CBOP size is not the same across harts\n"); 121 + } 122 + } 123 + } 124 + } 125 + 126 + /* 127 + * During early boot, the caller should call acpi_get_table() and pass its pointer to 128 + * these functions (and free up later). At run time, since this table can be used 129 + * multiple times, pass NULL so that the table remains in memory. 130 + */ 131 + void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size, 132 + u32 *cboz_size, u32 *cbop_size) 133 + { 134 + u32 size_hdr = sizeof(struct acpi_rhct_node_header); 135 + struct acpi_rhct_node_header *node, *end; 136 + struct acpi_rhct_hart_info *hart_info; 137 + struct acpi_table_rhct *rhct; 138 + 139 + if (acpi_disabled) 140 + return; 141 + 142 + if (table) { 143 + rhct = (struct acpi_table_rhct *)table; 144 + } else { 145 + rhct = acpi_get_rhct(); 146 + if (!rhct) 147 + return; 148 + } 149 + 150 + if (cbom_size) 151 + *cbom_size = 0; 152 + 153 + if (cboz_size) 154 + *cboz_size = 0; 155 + 156 + if (cbop_size) 157 + *cbop_size = 0; 158 + 159 + end = ACPI_ADD_PTR(struct acpi_rhct_node_header, rhct, rhct->header.length); 160 + for (node = ACPI_ADD_PTR(struct acpi_rhct_node_header, rhct, rhct->node_offset); 161 + node < end; 162 + node = ACPI_ADD_PTR(struct acpi_rhct_node_header, node, node->length)) { 163 + if (node->type == ACPI_RHCT_NODE_TYPE_HART_INFO) { 164 + hart_info = ACPI_ADD_PTR(struct acpi_rhct_hart_info, node, size_hdr); 165 + acpi_parse_hart_info_cmo_node(rhct, hart_info, cbom_size, 166 + cboz_size, cbop_size); 167 + } 168 + } 84 169 }