@@ -134,14 +134,63 @@ static void build_hmat_lb(GArray *table_data, HMAT_LB_Info *hmat_lb,
}
}
+/* ACPI 6.3: 5.2.27.5 Memory Side Cache Information Structure: Table 5-147 */
+static void build_hmat_cache(GArray *table_data, HMAT_Cache_Info *hmat_cache)
+{
+ /*
+ * Cache Attributes: Bits [3:0] – Total Cache Levels
+ * for this Memory Proximity Domain
+ */
+ uint32_t cache_attr = hmat_cache->total_levels & 0xF;
+
+ /* Bits [7:4] : Cache Level described in this structure */
+ cache_attr |= (hmat_cache->level & 0xF) << 4;
+
+ /* Bits [11:8] - Cache Associativity */
+ cache_attr |= (hmat_cache->associativity & 0xF) << 8;
+
+ /* Bits [15:12] - Write Policy */
+ cache_attr |= (hmat_cache->write_policy & 0xF) << 12;
+
+ /* Bits [31:16] - Cache Line size in bytes */
+ cache_attr |= (hmat_cache->line_size & 0xFFFF) << 16;
+
+ cache_attr = cpu_to_le32(cache_attr);
+
+ /* Type */
+ build_append_int_noprefix(table_data, 2, 2);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 2);
+ /* Length */
+ build_append_int_noprefix(table_data, 32, 4);
+ /* Proximity Domain for the Memory */
+ build_append_int_noprefix(table_data, hmat_cache->mem_proximity, 4);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 4);
+ /* Memory Side Cache Size */
+ build_append_int_noprefix(table_data, hmat_cache->size, 8);
+ /* Cache Attributes */
+ build_append_int_noprefix(table_data, cache_attr, 4);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 2);
+ /*
+ * Number of SMBIOS handles (n)
+ * Linux kernel uses Memory Side Cache Information Structure
+ * without SMBIOS entries for now, so set Number of SMBIOS handles
+ * as 0.
+ */
+ build_append_int_noprefix(table_data, 0, 2);
+}
+
/* Build HMAT sub table structures */
static void hmat_build_table_structs(GArray *table_data, NumaState *nstat)
{
uint16_t flags;
uint32_t num_initiator = 0;
uint32_t initiator_pxm[MAX_NODES];
- int i, hrchy, type;
+ int i, hrchy, type, level;
HMAT_LB_Info *numa_hmat_lb;
+ HMAT_Cache_Info *numa_hmat_cache;
for (i = 0; i < nstat->num_nodes; i++) {
flags = 0;
@@ -175,6 +224,19 @@ static void hmat_build_table_structs(GArray *table_data, NumaState *nstat)
}
}
}
+
+ /*
+ * ACPI 6.3: 5.2.27.5 Memory Side Cache Information Structure:
+ * Table 5-147
+ */
+ for (i = 0; i < nstat->num_nodes; i++) {
+ for (level = 0; level <= MAX_HMAT_CACHE_LEVEL; level++) {
+ numa_hmat_cache = nstat->hmat_cache[i][level];
+ if (numa_hmat_cache) {
+ build_hmat_cache(table_data, numa_hmat_cache);
+ }
+ }
+ }
}
void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *nstat)
@@ -81,6 +81,23 @@ struct HMAT_LB_Info {
uint16_t bandwidth[MAX_NODES][MAX_NODES];
};
+struct HMAT_Cache_Info {
+ /* The memory proximity domain to which the memory belongs. */
+ uint32_t mem_proximity;
+ /* Size of memory side cache in bytes. */
+ uint64_t size;
+ /* Total cache levels for this memory proximity domain. */
+ uint8_t total_levels;
+ /* Cache level described in this structure. */
+ uint8_t level;
+ /* Cache Associativity: None/Direct Mapped/Comple Cache Indexing */
+ uint8_t associativity;
+ /* Write Policy: None/Write Back(WB)/Write Through(WT) */
+ uint8_t write_policy;
+ /* Cache Line size in bytes. */
+ uint16_t line_size;
+};
+
void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *nstat);
#endif
@@ -49,6 +49,7 @@ typedef struct FWCfgEntry FWCfgEntry;
typedef struct FWCfgIoState FWCfgIoState;
typedef struct FWCfgMemState FWCfgMemState;
typedef struct FWCfgState FWCfgState;
+typedef struct HMAT_Cache_Info HMAT_Cache_Info;
typedef struct HMAT_LB_Info HMAT_LB_Info;
typedef struct HostMemoryBackend HostMemoryBackend;
typedef struct HVFX86EmulatorState HVFX86EmulatorState;
@@ -35,6 +35,8 @@ enum {
#define HMAT_LB_LEVELS (HMAT_LB_MEM_CACHE_3RD_LEVEL + 1)
#define HMAT_LB_TYPES (HMAT_LB_DATA_WRITE_BANDWIDTH + 1)
+#define MAX_HMAT_CACHE_LEVEL 3
+
struct NodeInfo {
uint64_t node_mem;
struct HostMemoryBackend *node_memdev;
@@ -65,6 +67,9 @@ struct NumaState {
/* NUMA modes HMAT Locality Latency and Bandwidth Information */
HMAT_LB_Info *hmat_lb[HMAT_LB_LEVELS][HMAT_LB_TYPES];
+
+ /* Memory Side Cache Information Structure */
+ HMAT_Cache_Info *hmat_cache[MAX_NODES][MAX_HMAT_CACHE_LEVEL + 1];
};
typedef struct NumaState NumaState;