fizz: Enable ddr4 DRAM support
First step in enabling mosys for Fizz with
DDR4.
BUG=b:37674370
BRANCH=None
TEST=mosys memory spd print all
mosys memory spd dump 0
Change-Id: I2713089ce91232862726d4c4ef81a2c1077419b7
Signed-off-by: Shelley Chen <shchen@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/503550
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
diff --git a/configs/x86_defconfig b/configs/x86_defconfig
index f1113ed..bc92283 100644
--- a/configs/x86_defconfig
+++ b/configs/x86_defconfig
@@ -36,6 +36,7 @@
CONFIG_PLATFORM_AURON=y
CONFIG_PLATFORM_BELTINO=y
CONFIG_PLATFORM_CYAN=y
+CONFIG_PLATFORM_FIZZ=y
CONFIG_PLATFORM_GLADOS=y
CONFIG_PLATFORM_LINK=y
CONFIG_PLATFORM_MARIO=y
diff --git a/include/lib/ddr4.h b/include/lib/ddr4.h
new file mode 100644
index 0000000..9072bf3
--- /dev/null
+++ b/include/lib/ddr4.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * DDR4 register map.
+ */
+
+#ifndef LIB_DDR4_H_
+#define LIB_DDR4_H_
+
+enum ddr4_reg_map {
+ /* Base Configuration and DRAM Parameters */
+ DDR4_SPD_REG_SIZE_CRC,
+ DDR4_SPD_REG_REVISION,
+ DDR4_SPD_REG_DEVICE_TYPE,
+ DDR4_SPD_REG_MODULE_TYPE,
+ DDR4_SPD_REG_DENSITY_BANKS,
+ DDR4_SPD_REG_ADDRESSING,
+ DDR4_SPD_REG_VOLTAGE = 11,
+ DDR4_SPD_REG_MODULE_ORG,
+ DDR4_SPD_REG_MODULE_BUS_WIDTH,
+ DDR4_SPD_REG_FTB_MTB_TIMEBASE = 17,
+ DDR4_SPD_REG_TCK_MIN = 18,
+ DDR4_SPD_REG_FINE_OFFSET_TCK_MIN = 125,
+ DDR4_SPD_REG_CRC_0,
+ DDR4_SPD_REG_CRC_1,
+ /* Manufacturing Information */
+ DDR4_SPD_REG_MODULE_MANUF_JEDEC_ID_LSB = 320,
+ DDR4_SPD_REG_MODULE_MANUF_JEDEC_ID_MSB,
+ DDR4_SPD_REG_MODULE_MANUF_LOC,
+ DDR4_SPD_REG_MODULE_MANUF_DATE_YEAR,
+ DDR4_SPD_REG_MODULE_MANUF_DATE_WEEK,
+ DDR4_SPD_REG_MODULE_MANUF_SERIAL_0,
+ DDR4_SPD_REG_MODULE_MANUF_SERIAL_1,
+ DDR4_SPD_REG_MODULE_MANUF_SERIAL_2,
+ DDR4_SPD_REG_MODULE_MANUF_SERIAL_3,
+ DDR4_SPD_REG_MODULE_PART_NUM_0,
+ DDR4_SPD_REG_MODULE_PART_NUM_1,
+ DDR4_SPD_REG_MODULE_PART_NUM_2,
+ DDR4_SPD_REG_MODULE_PART_NUM_3,
+ DDR4_SPD_REG_MODULE_PART_NUM_4,
+ DDR4_SPD_REG_MODULE_PART_NUM_5,
+ DDR4_SPD_REG_MODULE_PART_NUM_6,
+ DDR4_SPD_REG_MODULE_PART_NUM_7,
+ DDR4_SPD_REG_MODULE_PART_NUM_8,
+ DDR4_SPD_REG_MODULE_PART_NUM_9,
+ DDR4_SPD_REG_MODULE_PART_NUM_10,
+ DDR4_SPD_REG_MODULE_PART_NUM_11,
+ DDR4_SPD_REG_MODULE_PART_NUM_12,
+ DDR4_SPD_REG_MODULE_PART_NUM_13,
+ DDR4_SPD_REG_MODULE_PART_NUM_14,
+ DDR4_SPD_REG_MODULE_PART_NUM_15,
+ DDR4_SPD_REG_MODULE_PART_NUM_16,
+ DDR4_SPD_REG_MODULE_PART_NUM_17,
+ DDR4_SPD_REG_MODULE_REVISION_0,
+ DDR4_SPD_REG_DRAM_MANUF_JEDEC_ID_LSB,
+ DDR4_SPD_REG_DRAM_MANUF_JEDEC_ID_MSB,
+};
+
+#endif /* LIB_DDR4_H_ */
diff --git a/include/lib/spd.h b/include/lib/spd.h
index 2722622..5fba093 100644
--- a/include/lib/spd.h
+++ b/include/lib/spd.h
@@ -41,7 +41,7 @@
#define SPD_READ 0
#define SPD_WRITE 1
-#define SPD_MAX_LENGTH 256
+#define SPD_MAX_LENGTH 384
/* forward declarations */
struct kv_pair;
@@ -55,6 +55,7 @@
SPD_DRAM_TYPE_FBDIMM = 0x09,
SPD_DRAM_TYPE_DDR3 = 0x0b,
SPD_DRAM_TYPE_LPDDR3 = 0xf1,
+ SPD_DRAM_TYPE_DDR4 = 0x0c,
SPD_DRAM_TYPE_LPDDR4 = 0x10,
};
@@ -338,6 +339,22 @@
const void *data, enum spd_field_type type);
/*
+ * spd_print_field_ddr4 - add common DDR SPD fields into key=value pair
+ *
+ * @intf: platform interface
+ * @kv: key=value pair
+ * @data: raw spd data
+ * @type: type of field to retrieve
+ *
+ * returns 1 to indicate data added to key=value pair
+ * returns 0 to indicate no data added
+ * returns <0 to indicate error
+ *
+ */
+extern int spd_print_field_ddr4(struct platform_intf *intf, struct kv_pair *kv,
+ const void *data, enum spd_field_type type);
+
+/*
* spd_read_from_cbfs - retrieve SPD info from CBFS
*
* @intf: platform interface
diff --git a/intf/i2c.c b/intf/i2c.c
index cfc455d..06acd23 100644
--- a/intf/i2c.c
+++ b/intf/i2c.c
@@ -50,6 +50,7 @@
#include "lib/math.h"
#include "lib/string.h"
+#include "lib/spd.h"
/* these are exposed only to make testing easier */
#define I2C_DEV_ROOT "/dev"
@@ -216,8 +217,7 @@
int32_t result;
static int read_words = 1;
- /* limit to 256 bytes at a time */
- if (length < 1 || length > 256) {
+ if (length < 1 || length > SPD_MAX_LENGTH) {
lprintf(LOG_NOTICE, "Invalid I2C read length: %d\n", length);
return -1;
}
diff --git a/lib/spd/Makefile b/lib/spd/Makefile
index 00688ae..e4f622f 100644
--- a/lib/spd/Makefile
+++ b/lib/spd/Makefile
@@ -1,6 +1,7 @@
#obj-y += ddr1.o
obj-y += ddr2.o
obj-y += ddr3.o
+obj-y += ddr4.o
#obj-y += fbdimm.o
obj-y += nonspd.o
obj-y += nonspd_modules.o
diff --git a/lib/spd/ddr4.c b/lib/spd/ddr4.c
new file mode 100644
index 0000000..e9279bd
--- /dev/null
+++ b/lib/spd/ddr4.c
@@ -0,0 +1,287 @@
+/* Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * DDR4 field access for DDR4 SPDs.
+ */
+
+#include <ctype.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <valstr.h>
+
+#include "mosys/platform.h"
+#include "mosys/kv_pair.h"
+#include "mosys/log.h"
+
+#include "lib/string.h"
+
+#include "lib/ddr4.h"
+#include "lib/spd.h"
+
+#include "jedec_id.h"
+
+/*
+ * spd_print_field_ddr4 - add common DDR SPD fields into key=value pair
+ *
+ * @intf: platform interface
+ * @kv: key=value pair
+ * @data: raw spd data
+ * @type: type of field to retrieve
+ *
+ * returns 1 to indicate data added to key=value pair
+ * returns 0 to indicate no data added
+ * returns <0 to indicate error
+ *
+ */
+int spd_print_field_ddr4(struct platform_intf *intf, struct kv_pair *kv,
+ const void *data, enum spd_field_type type)
+{
+ int ret;
+ const uint8_t *byte = data;
+
+ ret = 0;
+ switch (type) {
+ case SPD_GET_DRAM_TYPE:
+ kv_pair_add(kv, "dram",
+ (byte[DDR4_SPD_REG_DEVICE_TYPE] ==
+ SPD_DRAM_TYPE_LPDDR4) ? "LPDDR4" : "DDR4");
+ ret = 1;
+ break;
+ case SPD_GET_MODULE_TYPE:
+ kv_pair_add(kv, "module",
+ val2str(byte[DDR4_SPD_REG_MODULE_TYPE],
+ ddr3_module_type_lut));
+ ret = 1;
+ break;
+ case SPD_GET_MFG_ID:
+ {
+ uint8_t manuf_lsb;
+ uint8_t manuf_msb;
+ const char *tstr;
+
+ manuf_lsb = byte[DDR4_SPD_REG_MODULE_MANUF_JEDEC_ID_LSB] & 0x7f;
+ manuf_msb = byte[DDR4_SPD_REG_MODULE_MANUF_JEDEC_ID_MSB] & 0x7f;
+ tstr = jedec_manufacturer(manuf_lsb, manuf_msb);
+
+ if (tstr != NULL) {
+ kv_pair_fmt(kv, "module_mfg", "%u-%u: %s", manuf_lsb + 1,
+ manuf_msb, tstr);
+ } else {
+ kv_pair_fmt(kv, "module_mfg", "%u-%u", manuf_lsb + 1,
+ manuf_msb);
+ }
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_MFG_ID_DRAM:
+ {
+ uint8_t manuf_lsb;
+ uint8_t manuf_msb;
+ const char *tstr;
+
+ manuf_lsb = byte[DDR4_SPD_REG_DRAM_MANUF_JEDEC_ID_LSB] & 0x7f;
+ manuf_msb = byte[DDR4_SPD_REG_DRAM_MANUF_JEDEC_ID_MSB] & 0x7f;
+
+ tstr = jedec_manufacturer(manuf_lsb, manuf_msb);
+
+ if (tstr != NULL) {
+ kv_pair_fmt(kv, "dram_mfg", "%u-%u: %s",
+ manuf_lsb + 1, manuf_msb, tstr);
+ } else {
+ kv_pair_fmt(kv, "dram_mfg", "%u-%u",
+ manuf_lsb + 1, manuf_msb);
+ }
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_MFG_LOC:
+ {
+ kv_pair_fmt(kv, "mfg_loc", "0x%02x",
+ byte[DDR4_SPD_REG_MODULE_MANUF_LOC]);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_MFG_DATE: /* manufacturing date (BCD values) */
+ {
+ uint8_t year;
+ uint8_t week;
+
+ year = byte[DDR4_SPD_REG_MODULE_MANUF_DATE_YEAR];
+ week = byte[DDR4_SPD_REG_MODULE_MANUF_DATE_YEAR];
+ kv_pair_fmt(kv, "mfg_date", "20%02x-wk%02x", week, year);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_SERIAL_NUMBER:
+ {
+ kv_pair_fmt(kv, "serial_number", "%02x%02x%02x%02x",
+ byte[DDR4_SPD_REG_MODULE_MANUF_SERIAL_0],
+ byte[DDR4_SPD_REG_MODULE_MANUF_SERIAL_1],
+ byte[DDR4_SPD_REG_MODULE_MANUF_SERIAL_2],
+ byte[DDR4_SPD_REG_MODULE_MANUF_SERIAL_3]);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_PART_NUMBER:
+ {
+ char part[19];
+
+ memcpy(part, &byte[DDR4_SPD_REG_MODULE_PART_NUM_0], 18);
+ part[18] = '\0';
+ kv_pair_fmt(kv, "part_number", "%s", part);
+
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_REVISION_CODE:
+ {
+ kv_pair_fmt(kv, "revision_code", "0x%02x",
+ byte[DDR4_SPD_REG_MODULE_REVISION_0]);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_SIZE:
+ {
+ /* See "Calculating Module Capacity" section in DDR4 SPD
+ * specification for details. */
+ unsigned int size;
+
+ /* calculate the total size in MB */
+ size = 256 << (byte[DDR4_SPD_REG_DENSITY_BANKS] & 0xf);
+ size >>= 3; /* in terms of bytes instead of bits. */
+ size *= 8 << (byte[DDR4_SPD_REG_MODULE_BUS_WIDTH] & 0x7);
+ size /= 4 << (byte[DDR4_SPD_REG_MODULE_ORG] & 0x7);
+ size *= 1 + ((byte[DDR4_SPD_REG_MODULE_ORG] >> 3) & 0x7);
+
+ kv_pair_fmt(kv, "size_mb", "%u", size);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_ECC:
+ {
+ uint8_t bus_ext_width = byte[DDR4_SPD_REG_MODULE_BUS_WIDTH];
+ bus_ext_width >>= 3;
+ bus_ext_width &= 0x7;
+ kv_pair_add_bool(kv, "ecc", bus_ext_width);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_RANKS:
+ {
+ kv_pair_fmt(kv, "ranks", "%d",
+ 1 + ((byte[DDR4_SPD_REG_MODULE_ORG] >> 3) & 0x7));
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_WIDTH:
+ {
+ /* Total width including ECC. */
+ uint8_t width;
+ width = 8 << (byte[DDR4_SPD_REG_MODULE_BUS_WIDTH] & 0x7);
+ width += 8 * ((byte[DDR4_SPD_REG_MODULE_BUS_WIDTH] >> 3) & 0x7);
+ kv_pair_fmt(kv, "width", "%d", width);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_CHECKSUM:
+ {
+ kv_pair_fmt(kv, "checksum", "0x%02x%02x",
+ byte[DDR4_SPD_REG_CRC_1],
+ byte[DDR4_SPD_REG_CRC_0]);
+ ret = 1;
+ break;
+ }
+
+ case SPD_GET_SPEEDS:
+ {
+ int i, mhz, first_entry;
+ char speeds[128];
+ const struct valstr possible_mhz[] = {
+ { 667, "DDR4-1333" },
+ { 800, "DDR4-1600" },
+ { 1200, "DDR4-2400" },
+ { 0 }
+ };
+ int tck_mtb = byte[DDR4_SPD_REG_TCK_MIN];
+ double tck_ns, mtb_ns = 0.0, ftb_ns = 0.0;
+ /* fine offset is encoded in 2's complement format */
+ int8_t ftb_offset = byte[DDR4_SPD_REG_FINE_OFFSET_TCK_MIN];
+
+ mtb_ns = (double) 0.125;
+ ftb_ns = (double) 0.001;
+ tck_ns = tck_mtb * mtb_ns + (ftb_offset * ftb_ns);
+ mhz = (int)((double)1000/tck_ns);
+
+ lprintf(LOG_DEBUG, "%s: %d * %.03fns + %d * %.03fns = %.02fns,"
+ " mhz = %d\n", __func__,
+ tck_mtb, mtb_ns, ftb_offset, ftb_ns, tck_ns, mhz);
+ memset(speeds, 0, sizeof(speeds));
+ first_entry = 1;
+ for (i = 0; possible_mhz[i].val != 0; i++) {
+ double min = possible_mhz[i].val * 0.99;
+
+ if (min <= mhz) {
+ if (!first_entry)
+ strcat(speeds, ", ");
+ first_entry = 0;
+ if (byte[DDR4_SPD_REG_DEVICE_TYPE] ==
+ SPD_DRAM_TYPE_LPDDR4)
+ strcat(speeds, "LP");
+ strcat(speeds, possible_mhz[i].str);
+ }
+ }
+
+ kv_pair_add(kv, "speeds", speeds);
+ ret = 1;
+ break;
+ }
+
+ default:
+ {
+ ret = 0; /* force "we don't handle this here */
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/lib/spd/spd_fields.c b/lib/spd/spd_fields.c
index 57ea0d4..c2a6c30 100644
--- a/lib/spd/spd_fields.c
+++ b/lib/spd/spd_fields.c
@@ -94,6 +94,9 @@
break;
}
+ case SPD_DRAM_TYPE_DDR4:
+ size = 384;
+ break;
default:
lprintf(LOG_ERR, "SPD type %02x not supported\n", data[2]);
return -1;
@@ -161,6 +164,9 @@
case SPD_DRAM_TYPE_DDR3:
case SPD_DRAM_TYPE_LPDDR3:
return spd_print_field_ddr3(intf, kv, data, type);
+ case SPD_DRAM_TYPE_DDR4:
+ return spd_print_field_ddr4(intf, kv, data, type);
+ break;
default:
lprintf(LOG_ERR, "SPD type %02x not supported\n", byte[2]);
}
diff --git a/platform/google/Kconfig b/platform/google/Kconfig
index 2d26a04..204c8a4 100644
--- a/platform/google/Kconfig
+++ b/platform/google/Kconfig
@@ -29,6 +29,12 @@
bool "Cyclone"
default n
+config PLATFORM_FIZZ
+ depends on PLATFORM_ARCH_X86
+ select CROS_EC_LPC
+ bool "fizz"
+ default n
+
config PLATFORM_GLADOS
depends on PLATFORM_ARCH_X86
select CROS_EC_LPC
diff --git a/platform/google/Makefile b/platform/google/Makefile
index 45dcbdb..e373e15 100644
--- a/platform/google/Makefile
+++ b/platform/google/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_PLATFORM_BELTINO) += beltino/
obj-$(CONFIG_PLATFORM_CYAN) += cyan/
obj-$(CONFIG_PLATFORM_CYCLONE) += cyclone/
+obj-$(CONFIG_PLATFORM_FIZZ) += fizz/
obj-$(CONFIG_PLATFORM_GLADOS) += glados/
obj-$(CONFIG_PLATFORM_GRU) += gru/
obj-$(CONFIG_PLATFORM_MARIO) += mario/
diff --git a/platform/google/fizz/Makefile b/platform/google/fizz/Makefile
new file mode 100644
index 0000000..3eb8d46
--- /dev/null
+++ b/platform/google/fizz/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_PLATFORM_FIZZ) += eeprom.o
+#obj-$(CONFIG_PLATFORM_FIZZ) += gpio.o
+obj-$(CONFIG_PLATFORM_FIZZ) += memory.o
+obj-$(CONFIG_PLATFORM_FIZZ) += nvram.o
+obj-$(CONFIG_PLATFORM_FIZZ) += sys.o
+obj-$(CONFIG_PLATFORM_FIZZ) += fizz.o
diff --git a/platform/google/fizz/eeprom.c b/platform/google/fizz/eeprom.c
new file mode 100644
index 0000000..c29b9e4
--- /dev/null
+++ b/platform/google/fizz/eeprom.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <fmap.h>
+
+#include "mosys/alloc.h"
+#include "mosys/platform.h"
+#include "mosys/log.h"
+
+#include "lib/eeprom.h"
+#include "lib/flashrom.h"
+#include "lib/smbios.h"
+
+#include "fizz.h"
+
+
+static int fizz_host_firmware_size(struct platform_intf *intf)
+{
+ return FIZZ_HOST_FIRMWARE_ROM_SIZE;
+}
+
+static int host_firmware_read(struct platform_intf *intf,
+ struct eeprom *eeprom,
+ unsigned int offset,
+ unsigned int len,
+ void *data)
+{
+ uint8_t *buf;
+ size_t rom_size;
+
+ rom_size = eeprom->device->size(intf);
+ buf = mosys_malloc(rom_size);
+
+ if (flashrom_read(buf, rom_size, HOST_FIRMWARE, NULL) < 0)
+ return -1;
+
+ memcpy(data, &buf[offset], len);
+ free(buf);
+ return 0;
+}
+
+static int host_firmware_read_by_name(struct platform_intf *intf,
+ struct eeprom *eeprom,
+ const char *name,
+ uint8_t **data)
+{
+ return flashrom_read_by_name(data, HOST_FIRMWARE, name);
+}
+
+static int host_firmware_write_by_name(struct platform_intf *intf,
+ struct eeprom *eeprom,
+ const char *name,
+ unsigned int len,
+ uint8_t *data)
+{
+ return flashrom_write_by_name(len, data, HOST_FIRMWARE, name);
+}
+
+static struct eeprom_dev host_firmware = {
+ .size = fizz_host_firmware_size,
+ .read = host_firmware_read,
+ .read_by_name = host_firmware_read_by_name,
+ .write_by_name = host_firmware_write_by_name,
+ .get_map = eeprom_get_fmap,
+};
+
+static struct eeprom_region host_firmware_regions[] = {
+ {
+ .name = "RW_NVRAM",
+ .flag = EEPROM_FLAG_VBNV,
+ },
+ { 0 },
+};
+
+static struct eeprom eeproms[] = {
+ {
+ .name = "host_firmware",
+ .type = EEPROM_TYPE_FW,
+ .flags = EEPROM_FLAG_RDWR | EEPROM_FLAG_FMAP,
+ .device = &host_firmware,
+ .regions = &host_firmware_regions[0],
+ },
+ { 0 },
+};
+
+struct eeprom_cb fizz_eeprom_cb = {
+ .eeprom_list = eeproms,
+};
diff --git a/platform/google/fizz/fizz.c b/platform/google/fizz/fizz.c
new file mode 100644
index 0000000..cabc1b2
--- /dev/null
+++ b/platform/google/fizz/fizz.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "mosys/alloc.h"
+#include "mosys/command_list.h"
+#include "mosys/platform.h"
+#include "mosys/intf_list.h"
+#include "mosys/log.h"
+
+#include "drivers/google/cros_ec.h"
+
+#include "lib/probe.h"
+#include "lib/smbios.h"
+#include "lib/elog.h"
+
+#include "fizz.h"
+
+struct probe_ids {
+ const char *names[2];
+ const char *hwids[2];
+ const char *frids[2];
+};
+
+static const struct probe_ids probe_id_list[] = {
+ { { "Fizz", NULL },
+ { "FIZZ", NULL },
+ { "Fizz", NULL },
+ },
+ { { NULL } }
+};
+
+struct platform_cmd *fizz_sub[] = {
+ &cmd_ec,
+ &cmd_eeprom,
+ &cmd_fp,
+ &cmd_memory,
+ &cmd_nvram,
+ &cmd_pd,
+ &cmd_platform,
+ &cmd_smbios,
+ &cmd_eventlog,
+ NULL
+};
+
+int fizz_probe(struct platform_intf *intf)
+{
+ static int status, probed;
+ const struct probe_ids *pid;
+
+ if (probed)
+ return status;
+
+ for (pid = probe_id_list; pid && pid->names[0]; pid++) {
+ /* HWID */
+ if (probe_hwid((const char **)pid->hwids)) {
+ status = 1;
+ goto fizz_probe_exit;
+ }
+
+ /* FRID */
+ if (probe_frid((const char **)pid->frids)) {
+ status = 1;
+ goto fizz_probe_exit;
+ }
+
+ /* SMBIOS */
+ if (probe_smbios(intf, (const char **)pid->names)) {
+ status = 1;
+ goto fizz_probe_exit;
+ }
+ }
+ return 0;
+
+fizz_probe_exit:
+ probed = 1;
+ /* Update canonical platform name */
+ intf->name = pid->names[0];
+ return status;
+}
+
+/* late setup routine; not critical to core functionality */
+static int fizz_setup_post(struct platform_intf *intf)
+{
+ if (cros_ec_setup(intf) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int fizz_destroy(struct platform_intf *intf)
+{
+ return 0;
+}
+
+struct eventlog_cb fizz_eventlog_cb = {
+ .print_type = &elog_print_type,
+ .print_data = &elog_print_data,
+ .print_multi = &elog_print_multi,
+ .verify = &elog_verify,
+ .verify_header = &elog_verify_header,
+ .fetch = &elog_fetch_from_smbios,
+};
+
+struct platform_cb fizz_cb = {
+ .ec = &cros_ec_cb,
+ .pd = &cros_pd_cb,
+ .fp = &cros_fp_cb,
+ .eeprom = &fizz_eeprom_cb,
+ .memory = &fizz_memory_cb,
+ .nvram = &fizz_nvram_cb,
+ .smbios = &smbios_sysinfo_cb,
+ .sys = &fizz_sys_cb,
+ .eventlog = &fizz_eventlog_cb,
+};
+
+struct platform_intf platform_fizz = {
+ .type = PLATFORM_X86_64,
+ .name = "Fizz",
+ .sub = fizz_sub,
+ .cb = &fizz_cb,
+ .probe = &fizz_probe,
+ .setup_post = &fizz_setup_post,
+ .destroy = &fizz_destroy,
+};
diff --git a/platform/google/fizz/fizz.h b/platform/google/fizz/fizz.h
new file mode 100644
index 0000000..13045c9
--- /dev/null
+++ b/platform/google/fizz/fizz.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FIZZ_H__
+#define FIZZ_H__
+
+#include <inttypes.h>
+#include "mosys/platform.h"
+
+#define FIZZ_HOST_FIRMWARE_ROM_SIZE (16384 * 1024)
+
+/* platform callbacks */
+extern struct eeprom_cb fizz_eeprom_cb; /* eeprom.c */
+extern struct gpio_cb fizz_gpio_cb; /* gpio.c */
+extern struct memory_cb fizz_memory_cb; /* memory.c */
+extern struct nvram_cb fizz_nvram_cb; /* nvram.c */
+extern struct sys_cb fizz_sys_cb; /* sys.c */
+
+/* functions called by setup routines */
+extern int fizz_vpd_setup(struct platform_intf *intf);
+
+#endif /* FIZZ_H_ */
diff --git a/platform/google/fizz/memory.c b/platform/google/fizz/memory.c
new file mode 100644
index 0000000..695ab48
--- /dev/null
+++ b/platform/google/fizz/memory.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mosys/callbacks.h"
+#include "mosys/globals.h"
+#include "mosys/log.h"
+#include "mosys/platform.h"
+
+#include "drivers/gpio.h"
+#include "drivers/intel/series6.h"
+
+#include "lib/file.h"
+#include "lib/flashrom.h"
+#include "lib/spd.h"
+#include "lib/smbios.h"
+
+#include "fizz.h"
+
+#define FIZZ_DIMM_COUNT 2
+
+static int fizz_spd_read(struct platform_intf *intf,
+ int dimm, int reg, int spd_len, uint8_t *spd_buf)
+{
+ int bus;
+ int address;
+
+ bus = intf->cb->memory->dimm_map(intf, DIMM_TO_BUS, dimm);
+ address = intf->cb->memory->dimm_map(intf, DIMM_TO_ADDRESS, dimm);
+
+ return spd_read_i2c(intf, bus, address, reg, spd_len, spd_buf);
+}
+
+/*
+ * dimm_auron_dimm_count - return total number of dimm slots
+ *
+ * @intf: platform interface
+ *
+ * returns dimm slot count
+ */
+static int dimm_fizz_dimm_count(struct platform_intf *intf)
+{
+ return FIZZ_DIMM_COUNT;
+}
+
+/*
+ * dimm_map - Convert logical dimm number to useful values
+ *
+ * @intf: platform interface
+ * @dimm: logical dimm number
+ * @type: conversion type
+ *
+ * returns specified converted value
+ * returns <0 to indicate error
+ */
+static int dimm_fizz_dimm_map(struct platform_intf *intf,
+ enum dimm_map_type type, int dimm)
+{
+ int ret = -1;
+ static struct dimm_map {
+ int node;
+ int channel;
+ int slot;
+ int bus;
+ int address;
+ } fizz_dimm_map[FIZZ_DIMM_COUNT] = {
+ /* Node 0 */
+ { 0, 0, 0, 17, 0x50 },
+ { 0, 0, 0, 17, 0x52 }
+ };
+ static unsigned int first_run = 1;
+ static int bus_offset = 0;
+
+ if (dimm < 0 || dimm >= intf->cb->memory->dimm_count(intf)) {
+ lprintf(LOG_ERR, "Invalid DIMM: %d\n", dimm);
+ return -1;
+ }
+
+ /*
+ * Determine offset for smbus numbering:
+ * 1. Scan known bus numbers for lowest value.
+ * 2. Scan /sys for SMBus entries that match the adapter name.
+ * 3. Calculate the difference between the lowest expected bus number
+ * and the lowest bus number seen in sysfs matching the criteria.
+ */
+ if (first_run) {
+ char path[PATH_MAX];
+ int lowest_known_bus = INT_MAX, x;
+
+ for (x = 0; x < intf->cb->memory->dimm_count(intf); x++) {
+ if (fizz_dimm_map[x].bus < lowest_known_bus)
+ lowest_known_bus = fizz_dimm_map[x].bus;
+ }
+
+ snprintf(path, sizeof(path), "%s/%s",
+ mosys_get_root_prefix(), "/sys/bus/i2c/devices");
+ x = sysfs_lowest_smbus(path, SERIES6_SMBUS_ADAPTER);
+ if (x >= 0) {
+ bus_offset = x - lowest_known_bus;
+ lprintf(LOG_DEBUG, "%s: bus_offset: %d\n",
+ __func__, bus_offset);
+ } else {
+ lprintf(LOG_DEBUG, "%s: unable to determine "
+ "bus offset\n", __func__);
+ bus_offset = 0;
+ }
+
+ first_run = 0;
+ }
+
+ switch (type) {
+ case DIMM_TO_BUS:
+ ret = fizz_dimm_map[dimm].bus + bus_offset;
+ break;
+ case DIMM_TO_ADDRESS:
+ ret = fizz_dimm_map[dimm].address;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int dimm_fizz_spd_read(struct platform_intf *intf,
+ int dimm, int reg, int len, uint8_t *buf)
+{
+ int bus;
+ int address;
+
+ bus = intf->cb->memory->dimm_map(intf, DIMM_TO_BUS, dimm);
+ address = intf->cb->memory->dimm_map(intf, DIMM_TO_ADDRESS, dimm);
+
+ return spd_read_i2c(intf, bus, address, reg, len, buf);
+}
+
+static struct memory_spd_cb fizz_spd_cb = {
+ .read = fizz_spd_read,
+};
+
+static struct memory_spd_cb dimm_fizz_spd_cb = {
+ .read = dimm_fizz_spd_read,
+};
+
+struct memory_cb fizz_memory_cb = {
+ .dimm_count = smbios_dimm_count,
+ .dimm_speed = smbios_dimm_speed,
+ .dimm_map = dimm_fizz_dimm_map,
+ .spd = &fizz_spd_cb,
+};
diff --git a/platform/google/fizz/nvram.c b/platform/google/fizz/nvram.c
new file mode 100644
index 0000000..b1d76a7
--- /dev/null
+++ b/platform/google/fizz/nvram.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <valstr.h>
+
+#include "mosys/kv_pair.h"
+#include "mosys/log.h"
+#include "mosys/platform.h"
+#include "mosys/output.h"
+
+#include "intf/io.h"
+
+#include "lib/eeprom.h"
+#include "lib/math.h"
+
+enum cmos_device {
+ CMOS_DEVICE_PCH,
+};
+
+struct cmos_var_map {
+ uint8_t offset;
+ uint8_t length;
+ char *desc;
+};
+
+struct cmos_map {
+ enum cmos_device type;
+ const char *device;
+ int bank;
+ int length;
+ int clear_start; /* first bytes are usually reserved for RTC */
+ struct cmos_var_map *var_list;
+};
+
+static struct cmos_var_map coreboot_cmos_bank0_vars[] = {
+ { 0x70, 1, "Post Code Bank" },
+ { 0x71, 1, "Post Code Bank 0" },
+ { 0x72, 1, "Post Code Bank 1" },
+ { 0x73, 4, "Post Extra Bank 0" },
+ { 0x77, 4, "Post Extra Bank 1" },
+ { 0 }
+};
+
+static struct cmos_var_map coreboot_cmos_bank1_vars[] = {
+ { 0x12, 4, "Boot Count" }, /* 0x92 */
+ { 0 }
+};
+
+struct cmos_map fizz_cmos_map[] = {
+ { CMOS_DEVICE_PCH, "LPSS0", 0, 128, 0x29, coreboot_cmos_bank0_vars },
+ { CMOS_DEVICE_PCH, "LPSS1", 1, 128, 0x00, coreboot_cmos_bank1_vars },
+};
+
+static const uint16_t fizz_cmos_port[] = { 0x70, 0x72 };
+
+static uint8_t fizz_read_cmos(struct platform_intf *intf,
+ int addr, int reg)
+{
+ uint8_t data;
+
+ io_write8(intf, fizz_cmos_port[addr], reg);
+ io_read8(intf, fizz_cmos_port[addr] + 1, &data);
+ return data;
+}
+
+static void fizz_write_cmos(struct platform_intf *intf,
+ int addr, int reg, uint8_t val)
+{
+ io_write8(intf, fizz_cmos_port[addr], reg);
+ io_write8(intf, fizz_cmos_port[addr] + 1, val);
+}
+
+static int fizz_nvram_list_bank(struct platform_intf *intf,
+ struct cmos_map *map)
+{
+ struct cmos_var_map *var;
+ int i;
+
+ /* handle each cmos bank */
+ for (var = map->var_list; var && var->desc; var++) {
+ struct kv_pair *kv = kv_pair_new();
+ uint32_t val = 0;
+
+ switch (map->type) {
+ case CMOS_DEVICE_PCH:
+ for (i = 0; i < var->length; i++)
+ val |= fizz_read_cmos(
+ intf, map->bank,
+ var->offset + i) << (i*8);
+ break;
+ }
+
+ kv_pair_add(kv, "device", map->device);
+ kv_pair_add(kv, "name", var->desc);
+ kv_pair_fmt(kv, "value", "0x%x", val);
+ kv_pair_print(kv);
+ kv_pair_free(kv);
+ }
+
+ return 0;
+}
+
+static int fizz_nvram_list(struct platform_intf *intf)
+{
+ int dev, rc = 0;
+
+ /* handle each cmos bank */
+ for (dev = 0; dev < ARRAY_SIZE(fizz_cmos_map); dev++)
+ rc |= fizz_nvram_list_bank(intf, &fizz_cmos_map[dev]);
+
+ return rc;
+}
+
+static int fizz_nvram_dump(struct platform_intf *intf)
+{
+ struct cmos_map *map;
+ int off, dev;
+ uint8_t cmos_data[128];
+
+ /* handle each cmos bank */
+ for (dev = 0; dev < ARRAY_SIZE(fizz_cmos_map); dev++) {
+ map = &fizz_cmos_map[dev];
+
+ if (map->length > sizeof(cmos_data))
+ continue;
+ memset(cmos_data, 0, sizeof(cmos_data));
+
+ mosys_printf("%s CMOS Bank %d (%d bytes)\n",
+ map->device, map->bank, map->length);
+
+ switch (map->type) {
+ case CMOS_DEVICE_PCH:
+ for (off = 0; off < map->length; off++)
+ cmos_data[off] = fizz_read_cmos(
+ intf, map->bank, off);
+ break;
+ }
+
+ print_buffer(cmos_data, map->length);
+ mosys_printf("\n");
+ }
+
+ return 0;
+}
+
+static int fizz_nvram_clear(struct platform_intf *intf)
+{
+ struct cmos_map *map;
+ int off, dev;
+
+ /* handle each cmos bank */
+ for (dev = 0;
+ dev < (sizeof(fizz_cmos_map) / sizeof(struct cmos_map));
+ dev++) {
+ map = &fizz_cmos_map[dev];
+
+ switch (map->type) {
+ case CMOS_DEVICE_PCH:
+ for (off = map->clear_start; off < map->length; off++)
+ fizz_write_cmos(intf, map->bank, off, 0x00);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+struct nvram_cb fizz_nvram_cb = {
+ .list = fizz_nvram_list,
+ .dump = fizz_nvram_dump,
+ .clear = fizz_nvram_clear,
+ .vboot_read = vbnv_flash_vboot_read,
+ .vboot_write = vbnv_flash_vboot_write,
+};
diff --git a/platform/google/fizz/sys.c b/platform/google/fizz/sys.c
new file mode 100644
index 0000000..4765102
--- /dev/null
+++ b/platform/google/fizz/sys.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mosys/alloc.h"
+#include "mosys/platform.h"
+
+#include "drivers/google/cros_ec.h"
+
+#include "lib/smbios.h"
+
+static char *fizz_get_name(struct platform_intf *intf)
+{
+ return mosys_strdup(intf->name);
+}
+
+struct sys_cb fizz_sys_cb = {
+ .version = &cros_ec_board_version_str,
+ .vendor = &smbios_sysinfo_get_vendor,
+ .name = &fizz_get_name,
+ .family = &smbios_sysinfo_get_family,
+ .firmware_vendor = &smbios_bios_get_vendor,
+};
diff --git a/platform/platform_list.c b/platform/platform_list.c
index 662e30e..435e7a3 100644
--- a/platform/platform_list.c
+++ b/platform/platform_list.c
@@ -44,6 +44,7 @@
extern struct platform_intf platform_cyan;
extern struct platform_intf platform_cyclone;
extern struct platform_intf platform_daisy;
+extern struct platform_intf platform_fizz;
extern struct platform_intf platform_glados;
extern struct platform_intf platform_gru;
extern struct platform_intf platform_link;
@@ -90,6 +91,9 @@
#ifdef CONFIG_PLATFORM_DAISY
&platform_daisy,
#endif
+#ifdef CONFIG_PLATFORM_FIZZ
+ &platform_fizz,
+#endif
#ifdef CONFIG_PLATFORM_GLADOS
&platform_glados,
#endif