+ entry = numa_hmat_lb->latency[m][n];
+ } else {
+ entry = numa_hmat_lb->bandwidth[m][n];
+ }
+
+ build_append_int_noprefix(table_data, entry, 2);
+ }
+ }
+}
+
/* Build HMAT sub table structures */
static void hmat_build_table_structs(GArray *table_data, NumaState *nstat)
{
uint16_t flags;
- int i;
+ uint32_t num_initiator = 0;
+ uint32_t initiator_pxm[MAX_NODES];
+ int i, hrchy, type;
+ HMAT_LB_Info *numa_hmat_lb;
for (i = 0; i < nstat->num_nodes; i++) {
flags = 0;
@@ -82,6 +151,29 @@ static void hmat_build_table_structs(GArray *table_data,
NumaState *nstat)
build_hmat_mpda(table_data, flags, nstat->nodes[i].initiator, i);
}
+
+ for (i = 0; i < nstat->num_nodes; i++) {
+ if (nstat->nodes[i].has_cpu) {
+ initiator_pxm[num_initiator++] = i;
+ }
+ }
+
+ /*
+ * ACPI 6.3: 5.2.27.4 System Locality Latency and Bandwidth Information
+ * Structure: Table 5-142
+ */
+ for (hrchy = HMAT_LB_MEM_MEMORY;
+ hrchy <= HMAT_LB_MEM_CACHE_3RD_LEVEL; hrchy++) {
+ for (type = HMAT_LB_DATA_ACCESS_LATENCY;
+ type <= HMAT_LB_DATA_WRITE_BANDWIDTH; type++) {
+ numa_hmat_lb = nstat->hmat_lb[hrchy][type];
+
+ if (numa_hmat_lb) {
+ build_hmat_lb(table_data, numa_hmat_lb, num_initiator,
+ nstat->num_nodes, initiator_pxm, type);
+ }
+ }
+ }
}
void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *nstat)
diff --git a/hw/acpi/hmat.h b/hw/acpi/hmat.h
index 574cfba60a..9d5f407b8a 100644
--- a/hw/acpi/hmat.h
+++ b/hw/acpi/hmat.h
@@ -40,6 +40,45 @@
*/
#define HMAT_PROX_INIT_VALID 0x1
+struct HMAT_LB_Info {
+ /*
+ * Indicates total number of Proximity Domains
+ * that can initiate memory access requests.
+ */
+ uint32_t num_initiator;
+ /*
+ * Indicates total number of Proximity Domains
+ * that can act as target.
+ */
+ uint32_t num_target;
+ /*
+ * Indicates it's memory or
+ * the specified level memory side cache.
+ */
+ uint8_t hierarchy;
+ /*
+ * Present the type of data,
+ * access/read/write latency or bandwidth.
+ */
+ uint8_t data_type;
+ /* The base unit for latency in nanoseconds. */
+ uint64_t base_lat;
+ /* The base unit for bandwidth in megabytes per second(MB/s). */
+ uint64_t base_bw;
+ /*
+ * latency[i][j]:
+ * Indicates the latency based on base_lat
+ * from Initiator Proximity Domain i to Target Proximity Domain j.
+ */
+ uint16_t latency[MAX_NODES][MAX_NODES];
+ /*
+ * bandwidth[i][j]:
+ * Indicates the bandwidth based on base_bw
+ * from Initiator Proximity Domain i to Target Proximity Domain j.
+ */
+ uint16_t bandwidth[MAX_NODES][MAX_NODES];
+};
+
void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *nstat);
#endif
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index fcdaae58c4..c0257e936b 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -33,6 +33,7 @@ typedef struct FWCfgEntry FWCfgEntry;
typedef struct FWCfgIoState FWCfgIoState;
typedef struct FWCfgMemState FWCfgMemState;
typedef struct FWCfgState FWCfgState;
+typedef struct HMAT_LB_Info HMAT_LB_Info;
typedef struct HVFX86EmulatorState HVFX86EmulatorState;
typedef struct I2CBus I2CBus;
typedef struct I2SCodec I2SCodec;
diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index 357aaeda80..0b80bc2fa2 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -32,6 +32,9 @@ struct NumaState {
/* NUMA nodes information */
NodeInfo nodes[MAX_NODES];
+
+ /* NUMA modes HMAT Locality Latency and Bandwidth Information */
+ HMAT_LB_Info *hmat_lb[HMAT_LB_LEVELS][HMAT_LB_TYPES];
};
typedef struct NumaState NumaState;
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 61579ae71e..3f83fc0d58 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -124,6 +124,28 @@ extern int mem_prealloc;
#define NUMA_DISTANCE_MAX 254
#define NUMA_DISTANCE_UNREACHABLE 255
+/* the value of AcpiHmatLBInfo flags */
+enum {
+ HMAT_LB_MEM_MEMORY = 0,
+ HMAT_LB_MEM_CACHE_LAST_LEVEL = 1,
+ HMAT_LB_MEM_CACHE_1ST_LEVEL = 2,
+ HMAT_LB_MEM_CACHE_2ND_LEVEL = 3,
+ HMAT_LB_MEM_CACHE_3RD_LEVEL = 4,
+};
+
+/* the value of AcpiHmatLBInfo data type */
+enum {
+ HMAT_LB_DATA_ACCESS_LATENCY = 0,
+ HMAT_LB_DATA_READ_LATENCY = 1,
+ HMAT_LB_DATA_WRITE_LATENCY = 2,
+ HMAT_LB_DATA_ACCESS_BANDWIDTH = 3,
+ HMAT_LB_DATA_READ_BANDWIDTH = 4,
+ HMAT_LB_DATA_WRITE_BANDWIDTH = 5,
+};
+
+#define HMAT_LB_LEVELS (HMAT_LB_MEM_CACHE_3RD_LEVEL + 1)
+#define HMAT_LB_TYPES (HMAT_LB_DATA_WRITE_BANDWIDTH + 1)
+
#define MAX_OPTION_ROMS 16
typedef struct QEMUOptionRom {
const char *name;