aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Makefile.inc1
-rw-r--r--core/flash-firmware-versions.c173
-rw-r--r--core/flash.c147
-rw-r--r--core/test/Makefile.check18
-rw-r--r--core/test/firmware-versions-input/version-0bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-1bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-10bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-11bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-16bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-2bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-26bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-27bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-29bin0 -> 4096 bytes
-rw-r--r--core/test/firmware-versions-input/version-long2
-rw-r--r--core/test/firmware-versions-input/version-nodash2
-rw-r--r--core/test/firmware-versions-input/version-trunc2
-rw-r--r--core/test/run-flash-firmware-versions.c165
-rw-r--r--core/test/stubs.c1
18 files changed, 364 insertions, 147 deletions
diff --git a/core/Makefile.inc b/core/Makefile.inc
index 3bdfd09..3b43870 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -10,6 +10,7 @@ CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o
CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o
CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o powercap.o psr.o
CORE_OBJS += pci-dt-slot.o direct-controls.o cpufeatures.o
+CORE_OBJS += flash-firmware-versions.o
ifeq ($(SKIBOOT_GCOV),1)
CORE_OBJS += gcov-profiling.o
diff --git a/core/flash-firmware-versions.c b/core/flash-firmware-versions.c
new file mode 100644
index 0000000..59294e4
--- /dev/null
+++ b/core/flash-firmware-versions.c
@@ -0,0 +1,173 @@
+/* Copyright 2013-2018 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include <device.h>
+#include <opal.h>
+#include <libstb/secureboot.h>
+#include <libstb/trustedboot.h>
+
+/* ibm,firmware-versions support */
+static char *version_buf;
+static size_t version_buf_size = 0x2000;
+
+static void __flash_dt_add_fw_version(struct dt_node *fw_version, char* data)
+{
+ static bool first = true;
+ char *prop;
+ int version_len, i;
+ int len = strlen(data);
+ const char *skiboot_version;
+ const char * version_str[] = {"open-power", "buildroot", "skiboot",
+ "hostboot-binaries", "hostboot", "linux",
+ "petitboot", "occ", "capp-ucode", "sbe",
+ "machine-xml", "hcode"};
+
+ if (first) {
+ first = false;
+
+ /* Increment past "key-" */
+ if (memcmp(data, "open-power", strlen("open-power")) == 0)
+ prop = data + strlen("open-power");
+ else
+ prop = strchr(data, '-');
+ if (!prop) {
+ prlog(PR_DEBUG,
+ "FLASH: Invalid fw version format (%s)\n", data);
+ return;
+ }
+ prop++;
+
+ dt_add_property_string(fw_version, "version", prop);
+ return;
+ }
+
+ /*
+ * PNOR version strings are not easily consumable. Split them into
+ * property, value.
+ *
+ * Example input from PNOR :
+ * "open-power-firestone-v1.8"
+ * "linux-4.4.6-openpower1-8420e0f"
+ *
+ * Desired output in device tree:
+ * open-power = "firestone-v1.8";
+ * linux = "4.4.6-openpower1-8420e0f";
+ */
+ for(i = 0; i < ARRAY_SIZE(version_str); i++)
+ {
+ version_len = strlen(version_str[i]);
+ if (len < version_len)
+ continue;
+
+ if (memcmp(data, version_str[i], version_len) != 0)
+ continue;
+
+ /* Found a match, add property */
+ if (dt_find_property(fw_version, version_str[i]))
+ continue;
+
+ /* Increment past "key-" */
+ prop = data + version_len + 1;
+ dt_add_property_string(fw_version, version_str[i], prop);
+
+ /* Sanity check against what Skiboot thinks its version is. */
+ if (strncmp(version_str[i], "skiboot",
+ strlen("skiboot")) == 0) {
+ /*
+ * If Skiboot was built with Buildroot its version may
+ * include a 'skiboot-' prefix; ignore it.
+ */
+ if (strncmp(version, "skiboot-",
+ strlen("skiboot-")) == 0)
+ skiboot_version = version + strlen("skiboot-");
+ else
+ skiboot_version = version;
+ if (strncmp(prop, skiboot_version,
+ strlen(skiboot_version)) != 0)
+ prlog(PR_WARNING, "WARNING! Skiboot version does not match VERSION partition!\n");
+ }
+ }
+}
+
+void flash_dt_add_fw_version(void)
+{
+ uint8_t version_data[80];
+ int rc;
+ int numbytes = 0, i = 0;
+ struct dt_node *fw_version;
+
+ if (version_buf == NULL)
+ return;
+
+ rc = wait_for_resource_loaded(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE);
+ if (rc != OPAL_SUCCESS) {
+ prlog(PR_WARNING, "FLASH: Failed to load VERSION data\n");
+ free(version_buf);
+ return;
+ }
+
+ fw_version = dt_new(dt_root, "ibm,firmware-versions");
+ assert(fw_version);
+
+ if (stb_is_container(version_buf, version_buf_size))
+ numbytes += SECURE_BOOT_HEADERS_SIZE;
+ for ( ; (numbytes < version_buf_size) && version_buf[numbytes]; numbytes++) {
+ if (version_buf[numbytes] == '\n') {
+ version_data[i] = '\0';
+ __flash_dt_add_fw_version(fw_version, version_data);
+ memset(version_data, 0, sizeof(version_data));
+ i = 0;
+ continue;
+ } else if (version_buf[numbytes] == '\t') {
+ continue; /* skip tabs */
+ }
+
+ version_data[i++] = version_buf[numbytes];
+ if (i == sizeof(version_data)) {
+ prlog(PR_WARNING, "VERSION item >%lu chars, skipping\n",
+ sizeof(version_data));
+ break;
+ }
+ }
+
+ free(version_buf);
+}
+
+void flash_fw_version_preload(void)
+{
+ int rc;
+
+ if (proc_gen < proc_gen_p9)
+ return;
+
+ prlog(PR_INFO, "FLASH: Loading VERSION section\n");
+
+ version_buf = malloc(version_buf_size);
+ if (!version_buf) {
+ prlog(PR_WARNING, "FLASH: Failed to allocate memory\n");
+ return;
+ }
+
+ rc = start_preload_resource(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE,
+ version_buf, &version_buf_size);
+ if (rc != OPAL_SUCCESS) {
+ prlog(PR_WARNING,
+ "FLASH: Failed to start loading VERSION data\n");
+ free(version_buf);
+ version_buf = NULL;
+ }
+}
diff --git a/core/flash.c b/core/flash.c
index 08d69ed..5fae0f3 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -49,10 +49,6 @@ static struct lock flash_lock;
static struct flash *nvram_flash;
static u32 nvram_offset, nvram_size;
-/* ibm,firmware-versions support */
-static char *version_buf;
-static size_t version_buf_size = 0x2000;
-
bool flash_reserve(void)
{
bool rc = false;
@@ -165,149 +161,6 @@ out:
return rc;
}
-static void __flash_dt_add_fw_version(struct dt_node *fw_version, char* data)
-{
- static bool first = true;
- char *prop;
- int version_len, i;
- int len = strlen(data);
- const char *skiboot_version;
- const char * version_str[] = {"open-power", "buildroot", "skiboot",
- "hostboot-binaries", "hostboot", "linux",
- "petitboot", "occ", "capp-ucode", "sbe",
- "machine-xml", "hcode"};
-
- if (first) {
- first = false;
-
- /* Increment past "key-" */
- if (memcmp(data, "open-power", strlen("open-power")) == 0)
- prop = data + strlen("open-power");
- else
- prop = strchr(data, '-');
- if (!prop) {
- prlog(PR_DEBUG,
- "FLASH: Invalid fw version format (%s)\n", data);
- return;
- }
- prop++;
-
- dt_add_property_string(fw_version, "version", prop);
- return;
- }
-
- /*
- * PNOR version strings are not easily consumable. Split them into
- * property, value.
- *
- * Example input from PNOR :
- * "open-power-firestone-v1.8"
- * "linux-4.4.6-openpower1-8420e0f"
- *
- * Desired output in device tree:
- * open-power = "firestone-v1.8";
- * linux = "4.4.6-openpower1-8420e0f";
- */
- for(i = 0; i < ARRAY_SIZE(version_str); i++)
- {
- version_len = strlen(version_str[i]);
- if (len < version_len)
- continue;
-
- if (memcmp(data, version_str[i], version_len) != 0)
- continue;
-
- /* Found a match, add property */
- if (dt_find_property(fw_version, version_str[i]))
- continue;
-
- /* Increment past "key-" */
- prop = data + version_len + 1;
- dt_add_property_string(fw_version, version_str[i], prop);
-
- /* Sanity check against what Skiboot thinks its version is. */
- if (strncmp(version_str[i], "skiboot",
- strlen("skiboot")) == 0) {
- /*
- * If Skiboot was built with Buildroot its version may
- * include a 'skiboot-' prefix; ignore it.
- */
- if (strncmp(version, "skiboot-",
- strlen("skiboot-")) == 0)
- skiboot_version = version + strlen("skiboot-");
- else
- skiboot_version = version;
- if (strncmp(prop, skiboot_version,
- strlen(skiboot_version)) != 0)
- prlog(PR_WARNING, "WARNING! Skiboot version does not match VERSION partition!\n");
- }
- }
-}
-
-void flash_dt_add_fw_version(void)
-{
- uint8_t version_data[80];
- int rc;
- int numbytes = 0, i = 0;
- struct dt_node *fw_version;
-
- if (version_buf == NULL)
- return;
-
- rc = wait_for_resource_loaded(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE);
- if (rc != OPAL_SUCCESS) {
- prlog(PR_WARNING, "FLASH: Failed to load VERSION data\n");
- free(version_buf);
- return;
- }
-
- fw_version = dt_new(dt_root, "ibm,firmware-versions");
- assert(fw_version);
-
- if (stb_is_container(version_buf, version_buf_size))
- numbytes += SECURE_BOOT_HEADERS_SIZE;
- for ( ; (numbytes < version_buf_size) && version_buf[numbytes]; numbytes++) {
- if (version_buf[numbytes] == '\n') {
- version_data[i] = '\0';
- __flash_dt_add_fw_version(fw_version, version_data);
- memset(version_data, 0, sizeof(version_data));
- i = 0;
- continue;
- } else if (version_buf[numbytes] == '\t') {
- continue; /* skip tabs */
- }
-
- version_data[i++] = version_buf[numbytes];
- }
-
- free(version_buf);
-}
-
-void flash_fw_version_preload(void)
-{
- int rc;
-
- if (proc_gen < proc_gen_p9)
- return;
-
- prlog(PR_INFO, "FLASH: Loading VERSION section\n");
-
- version_buf = malloc(version_buf_size);
- if (!version_buf) {
- prlog(PR_WARNING, "FLASH: Failed to allocate memory\n");
- return;
- }
-
- rc = start_preload_resource(RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE,
- version_buf, &version_buf_size);
- if (rc != OPAL_SUCCESS) {
- prlog(PR_WARNING,
- "FLASH: Failed to start loading VERSION data\n");
- free(version_buf);
- version_buf = NULL;
- }
-}
-
static int flash_nvram_probe(struct flash *flash, struct ffs_handle *ffs)
{
uint32_t start, size, part;
diff --git a/core/test/Makefile.check b/core/test/Makefile.check
index a5226a8..0fb585e 100644
--- a/core/test/Makefile.check
+++ b/core/test/Makefile.check
@@ -3,6 +3,7 @@ CORE_TEST := \
core/test/run-bitmap \
core/test/run-device \
core/test/run-flash-subpartition \
+ core/test/run-flash-firmware-versions \
core/test/run-mem_region \
core/test/run-malloc \
core/test/run-malloc-speed \
@@ -72,6 +73,23 @@ $(CORE_TEST:%=%-gcov): %-gcov : %.c %
$(CORE_TEST_NOSTUB:%=%-gcov) : %-gcov : %.c %
$(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) $(HOSTGCOVCFLAGS) -I include -I . -I libfdt -lgcov -o $@ $< , $<)
+core/test/run-flash-firmware-versions-gcov-run: core/test/run-flash-firmware-versions-inputs-gcov-run
+
+core/test/run-flash-firmware-versions-inputs-gcov-run: core/test/run-flash-firmware-versions-gcov
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-0 > /dev/null, $< version-0)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-1 > /dev/null, $< version-1)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-2 > /dev/null, $< version-2)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-10 > /dev/null, $< version-10)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-11 > /dev/null, $< version-11)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-16 > /dev/null, $< version-16)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-26 > /dev/null, $< version-26)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-27 > /dev/null, $< version-27)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-29 > /dev/null, $< version-29)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-trunc > /dev/null, $< version-trunc)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-long > /dev/null, $< version-long)
+ $(call Q, TEST-COVERAGE , ./core/test/run-flash-firmware-versions-gcov core/test/firmware-versions-input/version-nodash > /dev/null, $< version-nodash)
+
+
-include $(wildcard core/test/*.d)
clean: core-test-clean
diff --git a/core/test/firmware-versions-input/version-0 b/core/test/firmware-versions-input/version-0
new file mode 100644
index 0000000..2ab241a
--- /dev/null
+++ b/core/test/firmware-versions-input/version-0
Binary files differ
diff --git a/core/test/firmware-versions-input/version-1 b/core/test/firmware-versions-input/version-1
new file mode 100644
index 0000000..746327a
--- /dev/null
+++ b/core/test/firmware-versions-input/version-1
Binary files differ
diff --git a/core/test/firmware-versions-input/version-10 b/core/test/firmware-versions-input/version-10
new file mode 100644
index 0000000..013af60
--- /dev/null
+++ b/core/test/firmware-versions-input/version-10
Binary files differ
diff --git a/core/test/firmware-versions-input/version-11 b/core/test/firmware-versions-input/version-11
new file mode 100644
index 0000000..55e8353
--- /dev/null
+++ b/core/test/firmware-versions-input/version-11
Binary files differ
diff --git a/core/test/firmware-versions-input/version-16 b/core/test/firmware-versions-input/version-16
new file mode 100644
index 0000000..8906af4
--- /dev/null
+++ b/core/test/firmware-versions-input/version-16
Binary files differ
diff --git a/core/test/firmware-versions-input/version-2 b/core/test/firmware-versions-input/version-2
new file mode 100644
index 0000000..f012ffd
--- /dev/null
+++ b/core/test/firmware-versions-input/version-2
Binary files differ
diff --git a/core/test/firmware-versions-input/version-26 b/core/test/firmware-versions-input/version-26
new file mode 100644
index 0000000..adfd5bb
--- /dev/null
+++ b/core/test/firmware-versions-input/version-26
Binary files differ
diff --git a/core/test/firmware-versions-input/version-27 b/core/test/firmware-versions-input/version-27
new file mode 100644
index 0000000..d7ade98
--- /dev/null
+++ b/core/test/firmware-versions-input/version-27
Binary files differ
diff --git a/core/test/firmware-versions-input/version-29 b/core/test/firmware-versions-input/version-29
new file mode 100644
index 0000000..b1476a3
--- /dev/null
+++ b/core/test/firmware-versions-input/version-29
Binary files differ
diff --git a/core/test/firmware-versions-input/version-long b/core/test/firmware-versions-input/version-long
new file mode 100644
index 0000000..f814fa6
--- /dev/null
+++ b/core/test/firmware-versions-input/version-long
@@ -0,0 +1,2 @@
+open-power-whatever-v2.0-10-g1cec21d-dirty
+ Well, I wonder what a short essay here will mean for parsing everything. I hope it is all okay, but we want to get greater than 80 chars.
diff --git a/core/test/firmware-versions-input/version-nodash b/core/test/firmware-versions-input/version-nodash
new file mode 100644
index 0000000..139aa93
--- /dev/null
+++ b/core/test/firmware-versions-input/version-nodash
@@ -0,0 +1,2 @@
+no_dashes_in_version
+ this_is_wrong
diff --git a/core/test/firmware-versions-input/version-trunc b/core/test/firmware-versions-input/version-trunc
new file mode 100644
index 0000000..c9c92a0
--- /dev/null
+++ b/core/test/firmware-versions-input/version-trunc
@@ -0,0 +1,2 @@
+open-power-SUPERMICRO-P8DTU-V2.00.GA2-20161028
+ op
diff --git a/core/test/run-flash-firmware-versions.c b/core/test/run-flash-firmware-versions.c
new file mode 100644
index 0000000..924f3e9
--- /dev/null
+++ b/core/test/run-flash-firmware-versions.c
@@ -0,0 +1,165 @@
+/* Copyright 2018 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdint.h>
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+
+
+#include <interrupts.h>
+#include <bitutils.h>
+
+#include <compiler.h>
+
+/*
+ * Skiboot malloc stubs
+ *
+ * The actual prototypes for these are defined in mem_region-malloc.h,
+ * but that file also #defines malloc, and friends so we don't pull that in
+ * directly.
+ */
+
+#define DEFAULT_ALIGN __alignof__(long)
+
+void *__memalign(size_t blocksize, size_t bytes, const char *location __unused);
+void *__memalign(size_t blocksize, size_t bytes, const char *location __unused)
+{
+ return memalign(blocksize, bytes);
+}
+
+void *__malloc(size_t bytes, const char *location);
+void *__malloc(size_t bytes, const char *location)
+{
+ return __memalign(DEFAULT_ALIGN, bytes, location);
+}
+
+void __free(void *p, const char *location __unused);
+void __free(void *p, const char *location __unused)
+{
+ free(p);
+}
+
+void *__realloc(void *ptr, size_t size, const char *location __unused);
+void *__realloc(void *ptr, size_t size, const char *location __unused)
+{
+ return realloc(ptr, size);
+}
+
+void *__zalloc(size_t bytes, const char *location);
+void *__zalloc(size_t bytes, const char *location)
+{
+ void *p = __malloc(bytes, location);
+
+ if (p)
+ memset(p, 0, bytes);
+ return p;
+}
+
+#include <mem_region-malloc.h>
+
+#include <opal-api.h>
+
+#include "../../libfdt/fdt.c"
+#include "../../libfdt/fdt_ro.c"
+#include "../../libfdt/fdt_sw.c"
+#include "../../libfdt/fdt_strerror.c"
+
+#include "../../core/device.c"
+
+#include "../../libstb/container-utils.h"
+#include "../../libstb/container.h"
+#include "../../libstb/container.c"
+
+#include "../flash-firmware-versions.c"
+#include <assert.h>
+
+char __rodata_start[1], __rodata_end[1];
+
+const char version[]="Hello world!";
+
+enum proc_gen proc_gen = proc_gen_p7;
+
+static char *loaded_version_buf;
+static size_t loaded_version_buf_size;
+
+#define min(x,y) ((x) < (y) ? x : y)
+
+int start_preload_resource(enum resource_id id, uint32_t subid,
+ void *buf, size_t *len)
+{
+ (void)id;
+ (void)subid;
+ (void)buf;
+ if (loaded_version_buf) {
+ *len = min(*len, loaded_version_buf_size);
+ memcpy(buf, loaded_version_buf, *len);
+ } else {
+ *len = 0;
+ }
+
+ return 0;
+}
+
+int wait_for_resource_loaded(enum resource_id id, uint32_t idx)
+{
+ (void)id;
+ (void)idx;
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ struct stat ver_st;
+ int r;
+
+ dt_root = dt_new_root("");
+
+ if (argc > 1) {
+ fd = open(argv[1], O_RDONLY);
+
+ assert(fd > 0);
+ r = fstat(fd, &ver_st);
+ assert(r == 0);
+
+ loaded_version_buf = mmap(NULL, ver_st.st_size,
+ PROT_READ, MAP_PRIVATE, fd, 0);
+ assert(loaded_version_buf != (char*)-1);
+ loaded_version_buf_size = ver_st.st_size;
+ }
+
+ flash_fw_version_preload();
+
+ proc_gen = proc_gen_p9;
+ flash_fw_version_preload();
+ flash_dt_add_fw_version();
+
+ return 0;
+}
+
diff --git a/core/test/stubs.c b/core/test/stubs.c
index 66252f8..3aa1b86 100644
--- a/core/test/stubs.c
+++ b/core/test/stubs.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
+#include <string.h>
#include <stdint.h>
#include <compiler.h>