vendorcode/siemens: Add extended info block support to hwilib

Add support for a fourth info block type to hwilib. This block
provides new values and is now variable in length.

Change-Id: Ia928b4a98b806ba3e80fb576b78f60bb8f2ea3fc
Signed-off-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-on: https://review.coreboot.org/15478
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/src/vendorcode/siemens/hwilib/hwilib.c b/src/vendorcode/siemens/hwilib/hwilib.c
index 5d47881..b6cdd90 100644
--- a/src/vendorcode/siemens/hwilib/hwilib.c
+++ b/src/vendorcode/siemens/hwilib/hwilib.c
@@ -21,13 +21,15 @@
 #include "hwilib.h"
 
 
-#define MAX_BLOCK_NUM		3
+#define MAX_BLOCK_NUM		4
 #define LEN_HIB			0x1fd
 #define LEN_SIB			0x121
 #define LEN_EIB			0x0b5
+#define MIN_LEN_XIB		0x201
 #define NEXT_OFFSET_HIB		0x1dc
 #define NEXT_OFFSET_SIB		0x104
 #define NEXT_OFFSET_EIB		0x0b0
+#define NEXT_OFFSET_XIB		0x014
 #define LEN_UNIQUEL_NUM		0x010
 #define LEN_HW_REV		0x002
 #define LEN_MAC_ADDRESS		0x006
@@ -43,6 +45,7 @@
 	BLK_HIB,
 	BLK_SIB,
 	BLK_EIB,
+	BLK_XIB
 };
 
 /* This structure holds a valid position for a given field
@@ -71,6 +74,12 @@
  */
 static uint8_t *all_blocks[MAX_BLOCK_NUM] CAR_GLOBAL;
 
+/* As the length of extended block is variable, save all length to a global
+ * variable so that they can be used later to check boundaries.
+ */
+static uint16_t all_blk_size[MAX_BLOCK_NUM] CAR_GLOBAL;
+
+
 static uint32_t hwilib_read_bytes (const struct param_info *param, uint8_t *dst,
 					uint32_t maxlen);
 
@@ -89,6 +98,9 @@
 	[EIB_VerID] = {
 		.pos[0] = {.blk_type = BLK_EIB, .offset = 0x8, .len = 4},
 		.get_field = hwilib_read_bytes },
+	[XIB_VerID] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x8, .len = 4},
+		.get_field = hwilib_read_bytes },
 	[HIB_HwRev] = {
 		.pos[0] = {.blk_type = BLK_HIB, .offset = 0xbe, .len = 2},
 		.get_field = hwilib_read_bytes },
@@ -151,6 +163,9 @@
 	[MacMapping4] = {
 		.pos[0] = {.blk_type = BLK_HIB, .offset = 0x1d8, .len = 4},
 		.get_field = hwilib_read_bytes },
+	[RTCType] = {
+		.pos[0] = {.blk_type = BLK_HIB, .offset = 0x1e8, .len = 1},
+		.get_field = hwilib_read_bytes },
 	[PF_Color_Depth] = {
 		.pos[0] = {.blk_type = BLK_SIB, .offset = 0xea, .len = 1},
 		.mask = 0x03,
@@ -168,6 +183,196 @@
 	[VddRef] = {
 		.pos[0] = {.blk_type = BLK_EIB, .offset = 0x90, .len = 2},
 		.get_field = hwilib_read_bytes },
+	[XMac1] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0xfc, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac1Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x102, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac2] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x114, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac2Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x11a, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac3] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x12c, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac3Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x132, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac4] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x144, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac4Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x14a, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac5] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x15c, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac5Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x162, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac6] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x174, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac6Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x17a, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac7] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x18c, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac7Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x192, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac8] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1a4, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac8Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1aa, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac9] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1bc, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac9Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1c2, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac10] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1d4, .len = 6},
+		.get_field = hwilib_read_bytes },
+	[XMac10Aux] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1da, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[XMac1Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0xec, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac2Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x104, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac3Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x11c, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac4Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x134, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac5Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x14c, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac6Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x164, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac7Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x17c, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac8Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x194, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac9Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1ac, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[XMac10Mapping] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1c4, .len = 16},
+		.get_field = hwilib_read_bytes },
+	[netKind1] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x103, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind2] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x11b, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind3] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x133, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind4] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x14b, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind5] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x163, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind6] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x17b, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind7] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x193, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind8] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1ab, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind9] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1c3, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[netKind10] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1db, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[T_Warn] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x18, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[T_Crit] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x1c, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANSamplingTime] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x20, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANSetPoint] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x24, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANKp] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x28, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANKi] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x2c, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANKd] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x30, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANHystVal] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x34, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANHystThreshold] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x38, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANHystCtrl] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x3c, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANMaxSpeed] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x40, .len = 2},
+		.get_field = hwilib_read_bytes },
+	[FANStartpeed] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x42, .len = 2},
+		.get_field = hwilib_read_bytes },
+	[FANSensorDelay] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x44, .len = 4},
+		.get_field = hwilib_read_bytes },
+	[FANSensorNum] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x48, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[FANSensorSelect] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x49, .len = 1},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg0] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x4c, .len = 20},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg1] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x60, .len = 20},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg2] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x74, .len = 20},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg3] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x88, .len = 20},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg4] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0x9c, .len = 20},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg5] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0xb0, .len = 20},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg6] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0xc4, .len = 20},
+		.get_field = hwilib_read_bytes },
+	[FANSensorCfg7] = {
+		.pos[0] = {.blk_type = BLK_XIB, .offset = 0xd8, .len = 20},
+		.get_field = hwilib_read_bytes },
+
 };
 
 /** \brief This functions reads the given field from the first valid hwinfo
@@ -181,8 +386,7 @@
 {
 	uint8_t i = 0, *blk = NULL;
 	uint8_t **blk_ptr = car_get_var_ptr(&all_blocks[0]);
-	static const uint16_t all_blk_size[MAX_BLOCK_NUM] =
-						{LEN_HIB, LEN_SIB, LEN_EIB};
+	uint16_t *all_blk_size_ptr = car_get_var_ptr(&all_blk_size[0]);
 
 	if (!param || !dst)
 		return 0;
@@ -200,7 +404,7 @@
 	 */
 	if ((!blk) || (param->pos[i].len > maxlen) ||
 	    (param->pos[i].len + param->pos[i].offset >
-	     all_blk_size[param->pos[i].blk_type]))
+	     all_blk_size_ptr[param->pos[i].blk_type]))
 		return 0;
 	/* We can now copy the wanted data. */
 	memcpy(dst, (blk + param->pos[i].offset), param->pos[i].len);
@@ -248,6 +452,7 @@
 	uint8_t *ptr = NULL, *base = NULL;
 	uint32_t next_offset = 1;
 	uint8_t **blk_ptr = car_get_var_ptr(&all_blocks[0]);
+	uint16_t *all_blk_size_ptr = car_get_var_ptr(&all_blk_size[0]);
 	size_t filesize = 0;
 
 	/* Check for a valid parameter */
@@ -271,6 +476,12 @@
 	memset(blk_ptr, 0, (MAX_BLOCK_NUM * sizeof (uint8_t *)));
 	/* Check which blocks are available by examining the length field. */
 	base = ptr;
+	/* Fill in sizes of all fixed length blocks. */
+	all_blk_size_ptr[BLK_HIB] = LEN_HIB;
+	all_blk_size_ptr[BLK_SIB] = LEN_SIB;
+	all_blk_size_ptr[BLK_EIB] = LEN_EIB;
+	/* Length of BLK_XIB is variable and will be filled if block is found */
+	all_blk_size_ptr[BLK_XIB] = 0;
 	while(!(strncmp((char *)ptr, BLOCK_MAGIC, LEN_MAGIC_NUM)) &&
 		next_offset) {
 		uint16_t len = read16(ptr + LEN_OFFSET);
@@ -294,12 +505,19 @@
 			next_offset = read32(ptr + NEXT_OFFSET_EIB);
 			if (next_offset)
 				ptr = base + next_offset;
+		} else if (len >= MIN_LEN_XIB) {
+			blk_ptr[BLK_XIB] = ptr;
+			next_offset = read32(ptr + NEXT_OFFSET_XIB);
+			all_blk_size_ptr[BLK_XIB] = len;
+			if (next_offset)
+				ptr = base + next_offset;
 		} else {
 			next_offset = 0;
 		}
 	}
 	/* We should have found at least one valid block */
-	if (blk_ptr[BLK_HIB] || blk_ptr[BLK_SIB] || blk_ptr[BLK_EIB])
+	if (blk_ptr[BLK_HIB] || blk_ptr[BLK_SIB] || blk_ptr[BLK_EIB] ||
+	    blk_ptr[BLK_XIB])
 		return CB_SUCCESS;
 	else
 		return CB_ERR;
diff --git a/src/vendorcode/siemens/hwilib/hwilib.h b/src/vendorcode/siemens/hwilib/hwilib.h
index c66a99c..d858091 100644
--- a/src/vendorcode/siemens/hwilib/hwilib.h
+++ b/src/vendorcode/siemens/hwilib/hwilib.h
@@ -24,16 +24,17 @@
 	HIB_VerID = 0,
 	SIB_VerID,
 	EIB_VerID,
+	XIB_VerID,
 	HIB_HwRev,
 	SIB_HwRev,
 	UniqueNum,
 	Mac1,
-	Mac1Aux,
 	Mac2,
-	Mac2Aux,
 	Mac3,
-	Mac3Aux,
 	Mac4,
+	Mac1Aux,
+	Mac2Aux,
+	Mac3Aux,
 	Mac4Aux,
 	SPD,
 	FF_FreezeDis,
@@ -43,11 +44,76 @@
 	MacMapping2,
 	MacMapping3,
 	MacMapping4,
+	RTCType,
 	PF_Color_Depth,
 	PF_DisplType,
 	PF_DisplCon,
 	Edid,
-	VddRef
+	VddRef,
+	T_Warn,
+	T_Crit,
+	FANSamplingTime,
+	FANSetPoint,
+	FANKp,
+	FANKi,
+	FANKd,
+	FANHystVal,
+	FANHystThreshold,
+	FANHystCtrl,
+	FANMaxSpeed,
+	FANStartpeed,
+	FANSensorDelay,
+	FANSensorNum,
+	FANSensorSelect,
+	FANSensorCfg0,
+	FANSensorCfg1,
+	FANSensorCfg2,
+	FANSensorCfg3,
+	FANSensorCfg4,
+	FANSensorCfg5,
+	FANSensorCfg6,
+	FANSensorCfg7,
+	XMac1,
+	XMac2,
+	XMac3,
+	XMac4,
+	XMac5,
+	XMac6,
+	XMac7,
+	XMac8,
+	XMac9,
+	XMac10,
+	XMac1Aux,
+	XMac2Aux,
+	XMac3Aux,
+	XMac4Aux,
+	XMac5Aux,
+	XMac6Aux,
+	XMac7Aux,
+	XMac8Aux,
+	XMac9Aux,
+	XMac10Aux,
+	XMac1Mapping,
+	XMac2Mapping,
+	XMac3Mapping,
+	XMac4Mapping,
+	XMac5Mapping,
+	XMac6Mapping,
+	XMac7Mapping,
+	XMac8Mapping,
+	XMac9Mapping,
+	XMac10Mapping,
+	netKind1,
+	netKind2,
+	netKind3,
+	netKind4,
+	netKind5,
+	netKind6,
+	netKind7,
+	netKind8,
+	netKind9,
+	netKind10
+
 } hwinfo_field_t;
 
 /* Define used values in supported fields */