summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--common/Makefile1
-rw-r--r--common/cmd_vbexport_test.c213
-rw-r--r--include/configs/chromeos_seaboard_vboot.h1
-rw-r--r--lib/vbexport/Makefile30
-rw-r--r--lib/vbexport/utility.c95
6 files changed, 341 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index ebce9398f6..b6cbea93e6 100644
--- a/Makefile
+++ b/Makefile
@@ -215,6 +215,7 @@ LIBS += lib/lzma/liblzma.o
LIBS += lib/lzo/liblzo.o
LIBS += lib/zlib/libz.o
LIBS += lib/chromeos/libchromeos.a
+LIBS += lib/vbexport/libvbexport.a
LIBS += board/$(VENDOR)/chromeos/libchromeos_hardware_interface.a
LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
"board/$(VENDOR)/common/lib$(VENDOR).o"; fi)
diff --git a/common/Makefile b/common/Makefile
index c665eff875..c35c90294a 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -81,6 +81,7 @@ COBJS-$(CONFIG_CMD_CROS_NORMAL_FIRMWARE) += cmd_cros_normal_firmware.o
COBJS-$(CONFIG_CMD_CROS_REC) += cmd_cros_rec.o
COBJS-$(CONFIG_CMD_CROS_ONESTOP_FIRMWARE) += cmd_cros_onestop_firmware.o
COBJS-$(CONFIG_CMD_CROS_TPM) += cmd_vboot.o
+COBJS-$(CONFIG_CMD_VBEXPORT_TEST) += cmd_vbexport_test.o
COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o
COBJS-$(CONFIG_CMD_DATE) += cmd_date.o
ifdef CONFIG_4xx
diff --git a/common/cmd_vbexport_test.c b/common/cmd_vbexport_test.c
new file mode 100644
index 0000000000..22b08aac65
--- /dev/null
+++ b/common/cmd_vbexport_test.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/*
+ * Debug commands for testing Verify Boot Export APIs that are implemented by
+ * firmware and exported to vboot_reference. Some of the tests are automatic
+ * but some of them are manual.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <vboot_api.h>
+
+static int do_vbexport_test_debug(
+ cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ const char c = 'K';
+ const char s[] = "Hello! It's \"Chrome OS\".";
+ const int16_t hd = -22222;
+ const uint16_t hu = 44444;
+ const int32_t ld = -1111111111L;
+ const uint32_t lu = 2222222222UL;
+ const int64_t lld = -8888888888888888888LL;
+ const uint64_t llu = 11111111111111111111ULL;
+ VbExDebug("The \"Expect\" and \"Actual\" should be the same...\n");
+ VbExDebug("Expect: K 75 Hello! It's \"Chrome OS\".\n");
+ VbExDebug("Actual: %c %d %s\n", c, c, s);
+ VbExDebug("Expect: -22222 0xa932\n");
+ VbExDebug("Actual: %hd 0x%hx\n", hd, hd);
+ VbExDebug("Expect: 44444 0xad9c\n");
+ VbExDebug("Actual: %hu 0x%hx\n", hu, hu);
+ VbExDebug("Expect: -1111111111 0xbdc5ca39\n");
+ VbExDebug("Actual: %ld 0x%lx\n", ld, ld);
+ VbExDebug("Expect: 2222222222 0x84746b8e\n");
+ VbExDebug("Actual: %lu 0x%lx\n", lu, lu);
+ VbExDebug("Expect: -8888888888888888888 0x84a452a6a1dc71c8\n");
+ VbExDebug("Actual: %lld 0x%llx\n", lld, lld);
+ VbExDebug("Expect: 11111111111111111111 0x9a3298afb5ac71c7\n");
+ VbExDebug("Actual: %llu 0x%llx\n", llu, llu);
+ return 0;
+}
+
+static int do_vbexport_test_malloc_size(uint32_t size)
+{
+ char *mem = VbExMalloc(size);
+ int i;
+ VbExDebug("Trying to malloc a memory block for %lu bytes...", size);
+ if ((uint32_t)mem % CACHE_LINE_SIZE != 0) {
+ VbExDebug("\nMemory not algined with a cache line!\n");
+ VbExFree(mem);
+ return 1;
+ }
+ for (i = 0; i < size; i++) {
+ mem[i] = i % 0x100;
+ }
+ for (i = 0; i < size; i++) {
+ if (mem[i] != i % 0x100) {
+ VbExDebug("\nMemory verification failed!\n");
+ VbExFree(mem);
+ return 1;
+ }
+ }
+ VbExFree(mem);
+ VbExDebug(" - SUCCESS\n");
+ return 0;
+}
+
+static int do_vbexport_test_malloc(
+ cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret = 0;
+ VbExDebug("Preforming the malloc/free tests...\n");
+ ret |= do_vbexport_test_malloc_size(1);
+ ret |= do_vbexport_test_malloc_size(2);
+ ret |= do_vbexport_test_malloc_size(4);
+ ret |= do_vbexport_test_malloc_size(8);
+ ret |= do_vbexport_test_malloc_size(32);
+ ret |= do_vbexport_test_malloc_size(1024);
+ ret |= do_vbexport_test_malloc_size(4 * 1024);
+ ret |= do_vbexport_test_malloc_size(32 * 1024);
+ ret |= do_vbexport_test_malloc_size(1 * 1024 * 1024);
+ ret |= do_vbexport_test_malloc_size(12345);
+ ret |= do_vbexport_test_malloc_size(13579);
+ return ret;
+}
+
+typedef void (*sleep_handler_t)(uint32_t);
+
+static void sleep_ms_handler(uint32_t msec)
+{
+ VbExSleepMs(msec);
+}
+
+static void beep_handler(uint32_t msec)
+{
+ VbExBeep(msec, 4000);
+}
+
+static int do_vbexport_test_sleep_time(sleep_handler_t handler, uint32_t msec)
+{
+ uint32_t start, end, delta, expected;
+ VbExDebug("System is going to sleep for %lu ms...\n", msec);
+ start = VbExGetTimer();
+ (*handler)(msec);
+ end = VbExGetTimer();
+ delta = end - start;
+ VbExDebug("From tick %lu to %lu (delta: %lu)", start, end, delta);
+
+ expected = msec * CONFIG_SYS_HZ;
+ /* The sleeping time should be accurate to within 10%. */
+ if (delta > expected + expected / 10) {
+ VbExDebug("\nSleep too long: expected %lu but actaully %lu!\n",
+ expected, delta);
+ return 1;
+ } else if (delta < expected - expected / 10) {
+ VbExDebug("\nSleep too short: expected %lu but actaully %lu!\n",
+ expected, delta);
+ return 1;
+ }
+ VbExDebug(" - SUCCESS\n");
+ return 0;
+}
+
+static int do_vbexport_test_sleep(
+ cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret = 0;
+ VbExDebug("Preforming the sleep tests...\n");
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 10);
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 50);
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 100);
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 500);
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 1000);
+ return ret;
+}
+
+static int do_vbexport_test_longsleep(
+ cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret = 0;
+ VbExDebug("Preforming the long sleep tests...\n");
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 5000);
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 10000);
+ ret |= do_vbexport_test_sleep_time(&sleep_ms_handler, 50000);
+ return ret;
+}
+
+static int do_vbexport_test_beep(
+ cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret = 0;
+ VbExDebug("Preforming the beep tests...\n");
+ ret |= do_vbexport_test_sleep_time(&beep_handler, 500);
+ return ret;
+}
+
+static int do_vbexport_test_all(
+ cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret = 0;
+ ret |= do_vbexport_test_debug(cmdtp, flag, argc, argv);
+ ret |= do_vbexport_test_malloc(cmdtp, flag, argc, argv);
+ ret |= do_vbexport_test_sleep(cmdtp, flag, argc, argv);
+ ret |= do_vbexport_test_beep(cmdtp, flag, argc, argv);
+ if (!ret)
+ VbExDebug("All tests passed!\n");
+ return ret;
+}
+
+static cmd_tbl_t cmd_vbexport_test_sub[] = {
+ U_BOOT_CMD_MKENT(all, 0, 1, do_vbexport_test_all, "", ""),
+ U_BOOT_CMD_MKENT(debug, 0, 1, do_vbexport_test_debug, "", ""),
+ U_BOOT_CMD_MKENT(malloc, 0, 1, do_vbexport_test_malloc, "", ""),
+ U_BOOT_CMD_MKENT(sleep, 0, 1, do_vbexport_test_sleep, "", ""),
+ U_BOOT_CMD_MKENT(longsleep, 0, 1, do_vbexport_test_longsleep, "", ""),
+ U_BOOT_CMD_MKENT(beep, 0, 1, do_vbexport_test_beep, "", ""),
+};
+
+static int do_vbexport_test(
+ cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ cmd_tbl_t *c;
+
+ if (argc < 2)
+ return cmd_usage(cmdtp);
+ argc--;
+ argv++;
+
+ c = find_cmd_tbl(argv[0], &cmd_vbexport_test_sub[0],
+ ARRAY_SIZE(cmd_vbexport_test_sub));
+ if (c)
+ return c->cmd(c, flag, argc, argv);
+ else
+ return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(vbexport_test, CONFIG_SYS_MAXARGS, 1, do_vbexport_test,
+ "Perform tests for vboot_wrapper",
+ "all - perform all tests\n"
+ "vbexport_test debug - test the debug function\n"
+ "vbexport_test malloc - test the malloc and free functions\n"
+ "vbexport_test sleep - test the sleep and timer functions\n"
+ "vbexport_test longsleep - test the sleep functions for long delays\n"
+ "vbexport_test beep - test the beep functions"
+);
+
diff --git a/include/configs/chromeos_seaboard_vboot.h b/include/configs/chromeos_seaboard_vboot.h
index d1da0e78cb..8eefa1da63 100644
--- a/include/configs/chromeos_seaboard_vboot.h
+++ b/include/configs/chromeos_seaboard_vboot.h
@@ -10,6 +10,7 @@
#include <configs/chromeos_seaboard_common.h>
#define CONFIG_VBOOT_WRAPPER
+#define CONFIG_CMD_VBEXPORT_TEST
#undef CONFIG_BOOTDELAY
#define CONFIG_BOOTDELAY -1 /* disable auto boot */
diff --git a/lib/vbexport/Makefile b/lib/vbexport/Makefile
new file mode 100644
index 0000000000..ab80875948
--- /dev/null
+++ b/lib/vbexport/Makefile
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2011 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.
+#
+# Alternatively, this software may be distributed under the terms of the
+# GNU General Public License ("GPL") version 2 as published by the Free
+# Software Foundation.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)libvbexport.a
+
+COBJS-$(CONFIG_VBOOT_WRAPPER) += utility.o
+
+COBJS := $(COBJS-y)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/lib/vbexport/utility.c b/lib/vbexport/utility.c
new file mode 100644
index 0000000000..a78810c9e2
--- /dev/null
+++ b/lib/vbexport/utility.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/*
+ * Implementation of APIs provided by firmware and exported to vboot_reference.
+ * They includes debug output, memory allocation, timer and delay, etc.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <chromeos/power_management.h>
+
+/* Import the definition of vboot_wrapper interfaces. */
+#include <vboot_api.h>
+
+#define UINT32_MAX (~0UL)
+#define TICKS_PER_MSEC (CONFIG_SYS_HZ / 1000)
+#define MAX_MSEC_PER_LOOP ((UINT32_MAX / TICKS_PER_MSEC) / 2)
+
+static void system_abort(void)
+{
+ /* Wait for 3 seconds to let users see error messages and reboot. */
+ VbExSleepMs(3000);
+ cold_reboot();
+}
+
+void VbExError(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+ system_abort();
+}
+
+void VbExDebug(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+}
+
+void *VbExMalloc(size_t size)
+{
+ void *ptr = memalign(CACHE_LINE_SIZE, size);
+ if (!ptr) {
+ VbExError("Internal malloc error.");
+ }
+ return ptr;
+}
+
+void VbExFree(void *ptr)
+{
+ free(ptr);
+}
+
+uint64_t VbExGetTimer(void)
+{
+ return timer_get_us();
+}
+
+void VbExSleepMs(uint32_t msec)
+{
+ uint32_t delay, start;
+
+ /*
+ * Can't use entire UINT32_MAX range in the max delay, because it
+ * pushes get_timer() too close to wraparound. So use /2.
+ */
+ while(msec > MAX_MSEC_PER_LOOP) {
+ VbExSleepMs(MAX_MSEC_PER_LOOP);
+ msec -= MAX_MSEC_PER_LOOP;
+ }
+
+ delay = msec * TICKS_PER_MSEC;
+ start = get_timer(0);
+
+ while (get_timer(start) < delay)
+ udelay(100);
+}
+
+void VbExBeep(uint32_t msec, uint32_t frequency)
+{
+ /* TODO Implement it later. */
+ VbExSleepMs(msec);
+ VbExDebug("Beep!\n");
+}