platform/mosys: Add initial Puff support
V.2: Fix up misc reviewers comments.
V.3: Fix license headers.
BUG=b:143335657
BRANCH=none
TEST=emerge-puff mosys
Change-Id: I9e5aa22bd83eddfe402f317c309b888136dcc7ea
Signed-off-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1879637
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-by: Sam McNally <sammc@chromium.org>
diff --git a/platform/meson.build b/platform/meson.build
index d9001b9..49cb5c3 100644
--- a/platform/meson.build
+++ b/platform/meson.build
@@ -25,6 +25,7 @@
endif
subdir('pinky')
subdir('poppy')
+subdir('puff')
subdir('rambi')
subdir('reef')
subdir('samus')
diff --git a/platform/platform_list.c b/platform/platform_list.c
index b7132af..ad71b97 100644
--- a/platform/platform_list.c
+++ b/platform/platform_list.c
@@ -58,6 +58,7 @@
extern struct platform_intf platform_octopus;
extern struct platform_intf platform_pinky;
extern struct platform_intf platform_poppy;
+extern struct platform_intf platform_puff;
extern struct platform_intf platform_rambi;
extern struct platform_intf platform_reef;
extern struct platform_intf platform_samus;
@@ -84,6 +85,7 @@
&platform_hatch,
&platform_nami,
&platform_poppy,
+ &platform_puff,
&platform_octopus,
&platform_sarien,
&platform_drallion,
diff --git a/platform/puff/eeprom.c b/platform/puff/eeprom.c
new file mode 100644
index 0000000..b17a881
--- /dev/null
+++ b/platform/puff/eeprom.c
@@ -0,0 +1,90 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "mosys/alloc.h"
+#include "mosys/platform.h"
+
+#include "lib/eeprom.h"
+#include "lib/flashrom.h"
+#include "lib/smbios.h"
+
+#include "puff.h"
+
+
+static int host_firmware_size(struct platform_intf *intf)
+{
+ return PUFF_HOST_FIRMWARE_ROM_SIZE_32MB;
+}
+
+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 = 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 puff_eeprom_cb = {
+ .eeprom_list = eeproms,
+};
diff --git a/platform/puff/memory.c b/platform/puff/memory.c
new file mode 100644
index 0000000..0b5ef28
--- /dev/null
+++ b/platform/puff/memory.c
@@ -0,0 +1,14 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "lib/nonspd.h"
+#include "lib/smbios.h"
+#include "puff.h"
+
+struct memory_cb puff_memory_cb = {
+ .dimm_count = smbios_dimm_count,
+ .dimm_speed = smbios_dimm_speed,
+ .nonspd_mem_info = &spd_set_nonspd_info,
+};
diff --git a/platform/puff/meson.build b/platform/puff/meson.build
new file mode 100644
index 0000000..3b6ee45
--- /dev/null
+++ b/platform/puff/meson.build
@@ -0,0 +1,7 @@
+libmosys_src += files(
+ 'eeprom.c',
+ 'nvram.c',
+ 'memory.c',
+ 'sys.c',
+ 'puff.c',
+)
diff --git a/platform/puff/nvram.c b/platform/puff/nvram.c
new file mode 100644
index 0000000..61ee0c2
--- /dev/null
+++ b/platform/puff/nvram.c
@@ -0,0 +1,179 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#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 puff_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 puff_cmos_port[] = { 0x70, 0x72 };
+
+static uint8_t puff_read_cmos(struct platform_intf *intf, int addr, int reg)
+{
+ uint8_t data;
+
+ io_write8(intf, puff_cmos_port[addr], reg);
+ io_read8(intf, puff_cmos_port[addr] + 1, &data);
+ return data;
+}
+
+static void puff_write_cmos(struct platform_intf *intf,
+ int addr, int reg, uint8_t val)
+{
+ io_write8(intf, puff_cmos_port[addr], reg);
+ io_write8(intf, puff_cmos_port[addr] + 1, val);
+}
+
+static int puff_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 |= puff_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 puff_nvram_list(struct platform_intf *intf)
+{
+ int dev, rc = 0;
+
+ /* handle each cmos bank */
+ for (dev = 0; dev < ARRAY_SIZE(puff_cmos_map); dev++)
+ rc |= puff_nvram_list_bank(intf, &puff_cmos_map[dev]);
+
+ return rc;
+}
+
+static int puff_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(puff_cmos_map); dev++) {
+ map = &puff_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] = puff_read_cmos(
+ intf, map->bank, off);
+ break;
+ }
+
+ print_buffer(cmos_data, map->length);
+ mosys_printf("\n");
+ }
+
+ return 0;
+}
+
+static int puff_nvram_clear(struct platform_intf *intf)
+{
+ struct cmos_map *map;
+ int off, dev;
+
+ /* handle each cmos bank */
+ for (dev = 0;
+ dev < (sizeof(puff_cmos_map) / sizeof(struct cmos_map));
+ dev++) {
+ map = &puff_cmos_map[dev];
+
+ switch (map->type) {
+ case CMOS_DEVICE_PCH:
+ for (off = map->clear_start; off < map->length; off++)
+ puff_write_cmos(intf, map->bank, off, 0x00);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+struct nvram_cb puff_nvram_cb = {
+ .list = puff_nvram_list,
+ .dump = puff_nvram_dump,
+ .clear = puff_nvram_clear,
+ .vboot_read = vbnv_flash_vboot_read,
+ .vboot_write = vbnv_flash_vboot_write,
+};
diff --git a/platform/puff/puff.c b/platform/puff/puff.c
new file mode 100644
index 0000000..7fe10ed
--- /dev/null
+++ b/platform/puff/puff.c
@@ -0,0 +1,71 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "mosys/command_list.h"
+#include "mosys/platform.h"
+#include "mosys/intf_list.h"
+
+#include "drivers/google/cros_ec.h"
+
+#include "lib/cros_config.h"
+#include "lib/smbios.h"
+#include "lib/elog.h"
+
+#include "puff.h"
+
+static struct platform_cmd *puff_sub[] = {
+ &cmd_ec,
+ &cmd_eeprom,
+ &cmd_memory,
+ &cmd_nvram,
+ &cmd_pd,
+ &cmd_platform,
+ &cmd_smbios,
+ &cmd_eventlog,
+ NULL
+};
+
+static int puff_probe(struct platform_intf *intf)
+{
+ /* cros_config model.yaml 'platform-name' should match intf.name. */
+ return cros_config_probe(intf, NULL);
+}
+
+/* late setup routine; not critical to core functionality */
+static int puff_setup_post(struct platform_intf *intf)
+{
+ if (cros_ec_setup(intf) < 0)
+ return -1;
+
+ return 0;
+}
+
+static struct eventlog_cb puff_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,
+};
+
+static struct platform_cb puff_cb = {
+ .ec = &cros_ec_cb,
+ .eeprom = &puff_eeprom_cb,
+ .memory = &puff_memory_cb,
+ .nvram = &puff_nvram_cb,
+ .smbios = &smbios_sysinfo_cb,
+ .sys = &puff_sys_cb,
+ .eventlog = &puff_eventlog_cb,
+};
+
+struct platform_intf platform_puff = {
+ .type = PLATFORM_X86_64,
+ .name = "Puff",
+ .sub = puff_sub,
+ .cb = &puff_cb,
+ .probe = &puff_probe,
+ .setup_post = &puff_setup_post,
+};
diff --git a/platform/puff/puff.h b/platform/puff/puff.h
new file mode 100644
index 0000000..ab34786
--- /dev/null
+++ b/platform/puff/puff.h
@@ -0,0 +1,20 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef PLATFORM_PUFF_H__
+#define PLATFORM_PUFF_H__
+
+#include <inttypes.h>
+#include "mosys/platform.h"
+
+#define PUFF_HOST_FIRMWARE_ROM_SIZE_32MB (32768 * 1024)
+
+/* platform callbacks */
+extern struct eeprom_cb puff_eeprom_cb; /* eeprom.c */
+extern struct memory_cb puff_memory_cb; /* memory.c */
+extern struct nvram_cb puff_nvram_cb; /* nvram.c */
+extern struct sys_cb puff_sys_cb; /* sys.c */
+
+#endif /* PLATFORM_PUFF_H_ */
diff --git a/platform/puff/sys.c b/platform/puff/sys.c
new file mode 100644
index 0000000..22fbc5c
--- /dev/null
+++ b/platform/puff/sys.c
@@ -0,0 +1,27 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "mosys/alloc.h"
+#include "mosys/platform.h"
+
+#include "lib/acpi.h"
+#include "lib/sku.h"
+#include "lib/smbios.h"
+#include "lib/string.h"
+
+static char *puff_get_name(struct platform_intf *intf)
+{
+ return mosys_strdup(intf->name);
+}
+
+struct sys_cb puff_sys_cb = {
+ .version = &smbios_sysinfo_get_version,
+ .vendor = &smbios_sysinfo_get_vendor,
+ .name = &puff_get_name,
+ .family = &smbios_sysinfo_get_family,
+ .firmware_vendor = &smbios_bios_get_vendor,
+ .sku_number = &smbios_sysinfo_get_sku_number,
+ .signature_id = sku_get_signature_id,
+};