ich_descriptors: Update for Intel Skylake

Interpretation of component clocks changed. Also more regions and more
masters are supported now. The number of regions (NR) is now static per
chipset (10 in the 100 Series case) and not coded into the descriptor
any more.

v2: o Use guess_ich_chipset() for read_ich_descriptors_from_dump().
    o Update region extraction in `ich_descriptors_tool`.

TEST=Run `ich_descriptors_tool` over a 100 Series dump and checked
     that output looks sane. Run `ich_descriptors_tool` over dumps
     of five different older systems (1 x Sandy Bridge, 3 x Ivy Bridge,
     1 x Haswell). Beside whitespace changes, regions not accounted
     by `NR` are not printed any more.

Change-Id: Idd60a857d1ecffcb2e437af21134d9de44dcceb8
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/18973
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: David Hendricks <david.hendricks@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/ich_descriptors.h b/ich_descriptors.h
index 920e098..bccea27 100644
--- a/ich_descriptors.h
+++ b/ich_descriptors.h
@@ -62,8 +62,8 @@
 #define VSCC_VCL			(0x1 << VSCC_VCL_OFF)
 					/* 24-31: reserved */
 
-#define ICH_FREG_BASE(flreg)  (((flreg) << 12) & 0x01fff000)
-#define ICH_FREG_LIMIT(flreg) ((((flreg) >> 4) & 0x01fff000) | 0x00000fff)
+#define ICH_FREG_BASE(flreg)  (((flreg) << 12) & 0x07fff000)
+#define ICH_FREG_LIMIT(flreg) ((((flreg) >> 4) & 0x07fff000) | 0x00000fff)
 
 void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity, bool print_vcl);
 
@@ -76,7 +76,7 @@
 				 NC	:2, /* Number Of Components */
 					:6,
 				 FRBA	:8, /* Flash Region Base Address */
-				 NR	:3, /* Number Of Regions */
+				 NR	:3, /* Number Of Regions (reserved from Skylake on) */
 					:5;
 		};
 	};
@@ -116,7 +116,8 @@
 		 * Patsburg:		50		30		5	0:2, 3:5
 		 * Panther Point/7	50		30		5	0:2, 3:5
 		 * Lynx Point/8:	50		30		7	0:3, 4:7
-		 * Wildcat Point/9:	50		?? (multi I/O)	?	?:?, ?:?
+		 * Wildcat Point/9:	50		30 (multi I/O)	7	0:3, 4:7
+		 * Sunrise Point/100:	48		30		7	0:3, 4:7
 		 */
 		struct {
 			uint32_t		:17,
@@ -149,55 +150,49 @@
 		};
 	};
 	union {			/* 0x08 */
-		uint32_t FLPB; /* Flash Partition Boundary Register */
+		uint32_t FLPB; /* Flash Partition Boundary Register, until Panther Point/7 */
 		struct {
 			uint32_t FPBA	:13, /* Flash Partition Boundary Addr */
 					:19;
 		};
-	};
-};
-
-struct ich_desc_region {
-	union {
-		uint32_t FLREGs[5];
+		uint32_t FLILL1; /* Flash Invalid Instructions Register, new since Sunrise Point/100 */
 		struct {
-			struct { /* FLREG0 Flash Descriptor */
-				uint32_t reg0_base	:13,
-							:3,
-					 reg0_limit	:13,
-							:3;
-			};
-			struct { /* FLREG1 BIOS */
-				uint32_t reg1_base	:13,
-							:3,
-					 reg1_limit	:13,
-							:3;
-			};
-			struct { /* FLREG2 ME */
-				uint32_t reg2_base	:13,
-							:3,
-					 reg2_limit	:13,
-							:3;
-			};
-			struct { /* FLREG3 GbE */
-				uint32_t reg3_base	:13,
-							:3,
-					 reg3_limit	:13,
-							:3;
-			};
-			struct { /* FLREG4 Platform */
-				uint32_t reg4_base	:13,
-							:3,
-					 reg4_limit	:13,
-							:3;
-			};
+			uint32_t invalid_instr4	:8,
+				 invalid_instr5	:8,
+				 invalid_instr6	:8,
+				 invalid_instr7	:8;
 		};
 	};
 };
 
+#define MAX_NUM_FLREGS 10 /* 16 on unsupported Lewisburg PCH */
+struct ich_desc_region {
+	/*
+	 * Number of entries and width differ on various generations:
+	 *
+	 * Chipset/Generation				#FLREGs		width (bits)
+	 * ICH8			.. Panther Point/7	 5		13
+	 * Lynx Point/8		.. Wildcat Point/9	 7		15
+	 * Sunrise Point/100	..			10		15
+	 */
+	union {
+		uint32_t FLREGs[MAX_NUM_FLREGS]; /* Flash Descriptor Regions */
+
+		/* only used for bit-field check */
+		struct {
+			uint32_t base	:13,
+					:3,
+				 limit	:13,
+					:3;
+		} old_reg[MAX_NUM_FLREGS];
+	};
+};
+
+#define MAX_NUM_MASTERS 5 /* 6 on unsupported Lewisburg PCH */
 struct ich_desc_master {
 	union {
-		uint32_t FLMSTR1;
+		uint32_t FLMSTRs[MAX_NUM_MASTERS]; /* Flash Masters */
+		/* For pre-Skylake platforms */
 		struct {
 			uint32_t BIOS_req_ID	:16,
 				 BIOS_descr_r	:1,
@@ -212,11 +207,6 @@
 				 BIOS_GbE_w	:1,
 				 BIOS_plat_w	:1,
 						:3;
-		};
-	};
-	union {
-		uint32_t FLMSTR2;
-		struct {
 			uint32_t ME_req_ID	:16,
 				 ME_descr_r	:1,
 				 ME_BIOS_r	:1,
@@ -230,11 +220,6 @@
 				 ME_GbE_w	:1,
 				 ME_plat_w	:1,
 						:3;
-		};
-	};
-	union {
-		uint32_t FLMSTR3;
-		struct {
 			uint32_t GbE_req_ID	:16,
 				 GbE_descr_r	:1,
 				 GbE_BIOS_r	:1,
@@ -249,6 +234,12 @@
 				 GbE_plat_w	:1,
 						:3;
 		};
+		/* From Skylake on */
+		struct {
+			uint32_t	:8,
+				 read	:12,
+				 write	:12;
+		} mstr[MAX_NUM_MASTERS];
 	};
 };
 
@@ -573,16 +564,19 @@
 	struct ich_desc_upper_map upper;
 };
 
+ssize_t ich_number_of_regions(enum ich_chipset cs, const struct ich_desc_content *content);
+ssize_t ich_number_of_masters(enum ich_chipset cs, const struct ich_desc_content *content);
+
 void prettyprint_ich_descriptors(enum ich_chipset cs, const struct ich_descriptors *desc);
 
-void prettyprint_ich_descriptor_content(const struct ich_desc_content *content);
+void prettyprint_ich_descriptor_content(enum ich_chipset cs, const struct ich_desc_content *content);
 void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_descriptors *desc);
-void prettyprint_ich_descriptor_region(const struct ich_descriptors *desc);
-void prettyprint_ich_descriptor_master(const struct ich_desc_master *master);
+void prettyprint_ich_descriptor_region(enum ich_chipset cs, const struct ich_descriptors *desc);
+void prettyprint_ich_descriptor_master(enum ich_chipset cs, const struct ich_descriptors *desc);
 
 void prettyprint_ich_descriptor_upper_map(const struct ich_desc_upper_map *umap);
 void prettyprint_ich_descriptor_straps(enum ich_chipset cs, const struct ich_descriptors *desc);
-int read_ich_descriptors_from_dump(const uint32_t *dump, unsigned int len, struct ich_descriptors *desc);
+int read_ich_descriptors_from_dump(const uint32_t *dump, size_t len, enum ich_chipset *cs, struct ich_descriptors *desc);
 
 int read_ich_descriptors_via_fdo(enum ich_chipset cs, void *spibar, struct ich_descriptors *desc);
 int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx);