diff --git a/external/gard/gard.c b/external/gard/gard.c
index 1624a32968f9..5d4e382b2752 100644
--- a/external/gard/gard.c
+++ b/external/gard/gard.c
@@ -134,83 +134,35 @@ static void show_flash_err(int rc)
 	}
 }
 
-static const char *target_type_to_str(enum target_type t)
+/* FIXME: is this the same on p9? I thought the path types came from the XML
+ * rather than this stuff, maybe it's redundant?
+ *
+ * I don't think it is though since the target types are a bitmask rather than
+ * a plain enum.
+ */
+const struct chip_unit_desc *chip_units;
+int chip_unit_count;
+
+static void set_chip_gen(const struct chip_unit_desc *c)
 {
-	switch (t) {
-		case TYPE_NA:
-			return "Not applicable";
-		case TYPE_SYS:
-			return "System";
-		case TYPE_NODE:
-			return "Node";
-		case TYPE_DIMM:
-			return "Dimm";
-		case TYPE_MEMBUF:
-			return "Memory Buffer";
-		case TYPE_PROC:
-			return "Processor";
-		case TYPE_EX:
-			return "EX";
-		case TYPE_CORE:
-			return "Core";
-		case TYPE_L2:
-			return "L2 cache";
-		case TYPE_L3:
-			return "L3 cache";
-		case TYPE_L4:
-			return "L4 cache";
-		case TYPE_MCS:
-			return "MSC";
-		case TYPE_MBA:
-			return "MBA";
-		case TYPE_XBUS:
-			return "XBUS";
-		case TYPE_ABUS:
-			return "ABUS";
-		case TYPE_PCI:
-			return "PCI";
-		case TYPE_DPSS:
-			return "DPSS";
-		case TYPE_APSS:
-			return "APSS";
-		case TYPE_OCC:
-			return "OCC";
-		case TYPE_PSI:
-			return "PSI";
-		case TYPE_FSP:
-			return "FSP";
-		case TYPE_PNOR:
-			return "PNOR";
-		case TYPE_OSC:
-			return "OSC";
-		case TYPE_TODCLK:
-			return "Time of day clock";
-		case TYPE_CONTROL_NODE:
-			return "Control Node";
-		case TYPE_OSCREFCLK:
-			return "OSC Ref Clock";
-		case TYPE_OSCPCICLK:
-			return "OSC PCI Clock";
-		case TYPE_REFCLKENDPT:
-			return "Ref Clock";
-		case TYPE_PCICLKENDPT:
-			return "PCI Clock";
-		case TYPE_NX:
-			return "NX";
-		case TYPE_PORE:
-			return "PORE";
-		case TYPE_PCIESWITCH:
-			return "PCIE Switch";
-		case TYPE_CAPP:
-			return "CAPP";
-		case TYPE_FSI:
-			return "FSI";
-		case TYPE_TEST_FAIL:
-			return "Test Fail";
-		case TYPE_LAST_IN_RANGE:
-			return "Last";
+	chip_units = c;
+	chip_unit_count = 0;
+
+	while (strcmp("LAST_IN_RANGE", c->desc)) {
+		chip_unit_count++;
+		c++;
 	}
-	return "Unknown";
+}
+
+static const char *target_type_to_str(int type)
+{
+	int i;
+
+	for (i = 0; i < chip_unit_count; i++)
+		if (chip_units[i].type == type)
+			return chip_units[i].desc;
+
+	return "UNKNOWN";
 }
 
 static const char *path_type_to_str(enum path_type t)
@@ -618,6 +570,7 @@ int main(int argc, char **argv)
 
 	ctx = &_ctx;
 	memset(ctx, 0, sizeof(*ctx));
+	set_chip_gen(p8_chip_units);
 
 	if (is_fsp()) {
 		fprintf(stderr, "This is the OpenPower gard tool which does "
diff --git a/external/gard/gard.h b/external/gard/gard.h
index 26997cac9c12..9c814a797284 100644
--- a/external/gard/gard.h
+++ b/external/gard/gard.h
@@ -20,46 +20,7 @@
 #define PATH_TYPE_SHIFT 4
 #define PATH_ELEMENTS_MASK (0x0F)
 
-
-enum target_type {
-	TYPE_NA			= 0x00000000,
-	TYPE_SYS		= 0x00000001,
-	TYPE_NODE		= 0x00000002,
-	TYPE_DIMM		= 0x00000003,
-	TYPE_MEMBUF		= 0x00000004,
-	TYPE_PROC		= 0x00000005,
-	TYPE_EX			= 0x00000006,
-	TYPE_CORE		= 0x00000007,
-	TYPE_L2			= 0x00000008,
-	TYPE_L3			= 0x00000009,
-	TYPE_L4			= 0x0000000A,
-	TYPE_MCS		= 0x0000000B,
-	TYPE_MBA		= 0x0000000D,
-	TYPE_XBUS		= 0x0000000E,
-	TYPE_ABUS		= 0x0000000F,
-	TYPE_PCI		= 0x00000010,
-	TYPE_DPSS		= 0x00000011,
-	TYPE_APSS		= 0x00000012,
-	TYPE_OCC		= 0x00000013,
-	TYPE_PSI		= 0x00000014,
-	TYPE_FSP		= 0x00000015,
-	TYPE_PNOR		= 0x00000016,
-	TYPE_OSC		= 0x00000017,
-	TYPE_TODCLK		= 0x00000018,
-	TYPE_CONTROL_NODE	= 0x00000019,
-	TYPE_OSCREFCLK		= 0x0000001A,
-	TYPE_OSCPCICLK		= 0x0000001B,
-	TYPE_REFCLKENDPT	= 0x0000001C,
-	TYPE_PCICLKENDPT	= 0x0000001D,
-	TYPE_NX			= 0x0000001E,
-	TYPE_PORE		= 0x0000001F,
-	TYPE_PCIESWITCH		= 0x00000020,
-	TYPE_CAPP		= 0x00000021,
-	TYPE_FSI		= 0x00000022,
-	TYPE_TEST_FAIL		= 0x00000023,
-	TYPE_LAST_IN_RANGE	= 0x00000024,
-};
-
+/* see src/include/usr/targeting/common/entitypath.H */
 enum path_type {
 	PATH_NA			= 0x00,
 	PATH_AFFINITY		= 0x01,
@@ -81,15 +42,24 @@ struct entity_path {
 
 } __attribute__((packed));
 
-
-/* defined by hostboot */
+/* From hostboot: src/include/usr/hwas/common/deconfigGard.H:GardRecord */
 struct gard_record {
 	uint32_t		record_id;
 	struct entity_path	target_id;
-	uint8_t			pad0[3];
+	uint8_t			pad0[3]; /* compiler dependent padding */
 	uint32_t		errlog_eid;
 	uint8_t			error_type;
 	uint8_t			resource_recovery;
 	uint8_t			pad1[6];
 } __attribute__((packed));
 
+#define MAX_PATH_SIZE 420
+
+struct chip_unit_desc {
+	int type;
+	const char *desc;
+};
+
+extern const struct chip_unit_desc *chip_units;
+extern const struct chip_unit_desc p8_chip_units[];
+extern const struct chip_unit_desc p9_chip_units[];
diff --git a/external/gard/rules.mk b/external/gard/rules.mk
index a7b967aa6735..a0bcfdc549b0 100644
--- a/external/gard/rules.mk
+++ b/external/gard/rules.mk
@@ -1,7 +1,7 @@
 .DEFAULT_GOAL := all
 
 override CFLAGS += -O2 -Wall -Werror -I.
-OBJS      = version.o gard.o
+OBJS      = version.o gard.o units.o
 LIBFLASH_FILES    := libflash.c libffs.c ecc.c blocklevel.c file.c
 LIBFLASH_OBJS     := $(addprefix libflash-, $(LIBFLASH_FILES:.c=.o))
 LIBFLASH_SRC      := $(addprefix libflash/,$(LIBFLASH_FILES))
diff --git a/external/gard/test/results/01-show_1.out b/external/gard/test/results/01-show_1.out
index be2d3a5a765f..e48d89b833d1 100644
--- a/external/gard/test/results/01-show_1.out
+++ b/external/gard/test/results/01-show_1.out
@@ -3,6 +3,6 @@ Record ID:    0x00000001
 Error ID:     0x90000015
 Error Type:         0xe6
 Path Type: physical
->System, Instance #0
+>Sys, Instance #0
  >Node, Instance #0
-  >Processor, Instance #0
+  >Proc, Instance #0
diff --git a/external/gard/units.c b/external/gard/units.c
new file mode 100644
index 000000000000..554d85c7b4db
--- /dev/null
+++ b/external/gard/units.c
@@ -0,0 +1,143 @@
+#include "gard.h"
+
+/*
+ * Each chip has a set of "units" that are detailed by the System MRW. Granted
+ * they're pretty much fixed for a given chip generation so hardcoding them here
+ * isn't a big deal.
+ *
+ * These tables we generated from obj/genfiles/errl/errludtarget.H. Which is
+ * generated as a part of the hostboot build process. Yeah that's about as
+ * dumb as it sounds, but whatever.
+ */
+
+
+/*
+ * Notes:
+ *
+ * When formatting these as strings we print them into a buffer of MAX_PATH_SIZE
+ * Given there is a max path length of ten units MAX_PATH_SIZE might need a
+ * bump is we start using very detailed unit description strings.
+ */
+
+const struct chip_unit_desc p8_chip_units[] = {
+	{0x00, "NA"},
+	{0x01, "Sys"},
+	{0x02, "Node"},
+	{0x03, "DIMM"},
+	{0x04, "Membuf"},
+	{0x05, "Proc"},
+	{0x06, "EX"},
+	{0x07, "Core"},
+	{0x08, "L2"},
+	{0x09, "L3"},
+	{0x0A, "L4"},
+	{0x0B, "MCS"},
+	{0x0D, "MBA"},
+	{0x0E, "XBUS"},
+	{0x0F, "ABUS"},
+	{0x10, "PCI"},
+	{0x11, "DPSS"},
+	{0x12, "APSS"},
+	{0x13, "OCC"},
+	{0x14, "PSI"},
+	{0x15, "FSP"},
+	{0x16, "PNOR"},
+	{0x17, "OSC"},
+	{0x18, "TODCLK"},
+	{0x19, "CONTROL_NODE"},
+	{0x1A, "OSCREFCLK"},
+	{0x1B, "OSCPCICLK"},
+	{0x1C, "REFCLKENDPT"},
+	{0x1D, "PCICLKENDPT"},
+	{0x1E, "NX"},
+	{0x1F, "PORE"},
+	{0x20, "PCIESWITCH"},
+	{0x21, "CAPP"},
+	{0x22, "FSI"},
+	{0x23, "TPM"},
+	{0x24, "SP"},
+	{0x25, "UART"},
+	{0x26, "PS"},
+	{0x27, "FAN"},
+	{0x28, "VRM"},
+	{0x29, "USB"},
+	{0x2A, "ETH"},
+	{0x2B, "PANEL"},
+	{0x2C, "TEST_FAIL"},
+	{0x2D, "LAST_IN_RANGE"}
+};
+
+const struct chip_unit_desc p9_chip_units[] = {
+	{0x00, "NA"},
+	{0x01, "Sys"},
+	{0x02, "Node"},
+	{0x03, "DIMM"},
+	{0x04, "Membuf"},
+	{0x05, "Proc"},
+	{0x06, "EX"},
+	{0x07, "Core"},
+	{0x08, "L2"},
+	{0x09, "L3"},
+	{0x0A, "L4"},
+	{0x0B, "MCS"},
+	/* a hole! */
+	{0x0D, "MBA"},
+	{0x0E, "XBUS"},
+	{0x0F, "ABUS"},
+	{0x10, "PCI"},
+	{0x11, "DPSS"},
+	{0x12, "APSS"},
+	{0x13, "OCC"},
+	{0x14, "PSI"},
+	{0x15, "FSP"},
+	{0x16, "PNOR"},
+	{0x17, "OSC"},
+	{0x18, "TODCLK"},
+	{0x19, "CONTROL_NODE"},
+	{0x1A, "OSCREFCLK"},
+	{0x1B, "OSCPCICLK"},
+	{0x1C, "REFCLKENDPT"},
+	{0x1D, "PCICLKENDPT"},
+	{0x1E, "NX"},
+	{0x1F, "PORE"},
+	{0x20, "PCIESWITCH"},
+	{0x21, "CAPP"},
+	{0x22, "FSI"},
+	{0x23, "EQ"},
+	{0x24, "MCA"},
+	{0x25, "MCBIST"},
+	{0x26, "MI"},
+	{0x27, "DMI"},
+	{0x28, "OBUS"},
+	{0x2A, "SBE"},
+	{0x2B, "PPE"},
+	{0x2C, "PERV"},
+	{0x2D, "PEC"},
+	{0x2E, "PHB"},
+	{0x2F, "SYSREFCLKENDPT"},
+	{0x30, "MFREFCLKENDPT"},
+	{0x31, "TPM"},
+	{0x32, "SP"},
+	{0x33, "UART"},
+	{0x34, "PS"},
+	{0x35, "FAN"},
+	{0x36, "VRM"},
+	{0x37, "USB"},
+	{0x38, "ETH"},
+	{0x39, "PANEL"},
+	{0x3A, "BMC"},
+	{0x3B, "FLASH"},
+	{0x3C, "SEEPROM"},
+	{0x3D, "TMP"},
+	{0x3E, "GPIO_EXPANDER"},
+	{0x3F, "POWER_SEQUENCER"},
+	{0x40, "RTC"},
+	{0x41, "FANCTLR"},
+	{0x42, "OBUS_BRICK"},
+	{0x43, "NPU"},
+	{0x44, "MC"},
+	{0x45, "TEST_FAIL"},
+	{0x46, "MFREFCLK"},
+	{0x47, "LAST_IN_RANGE"},
+};
+
