summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-01-08 15:07:05 -0700
committerCommit Bot <commit-bot@chromium.org>2021-01-09 01:40:05 +0000
commitba9df2aa09deeae5d851c59469d782b1a7a0efe4 (patch)
tree6c7b2e8fcc6f4c6644e04a21c6d303372a10a056
parent61a46cf57de2a1805c5e686ead580958b9cbc667 (diff)
downloadchrome-ec-ba9df2aa09deeae5d851c59469d782b1a7a0efe4.tar.gz
zephyr: switch to platform/ec printf format implementation
Prior to this change, the cprints and cprintf shim implementations used Zephyr's printk to do the output formatting. Our EC code has some custom printf specifiers not supported by Zephyr's printk. We've already attempted to send some of our custom specifiers upstream, but upstream does not want them: https://github.com/zephyrproject-rtos/zephyr/pull/28882 The logical thing to do would be to bring in the vfnprintf function from our EC to the Zephyr build, and use that to do the output formatting instead. That's what this CL does. The binary cost of brining in this second printf implementation appears to be minimal (952 bytes on volteer). BUG=b:177065615 BRANCH=none TEST=on posix-ec and volteer, run gettime and observe output no longer contains %.6lld, but instead the correct system time Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I53cd4edf129223c12a2c5e7d0519623a8d07a328 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2618575
-rw-r--r--common/printf.c12
-rw-r--r--zephyr/CMakeLists.txt1
-rw-r--r--zephyr/shim/src/console.c11
-rw-r--r--zephyr/shim/src/util.c44
-rw-r--r--zephyr/test/hooks/CMakeLists.txt2
-rw-r--r--zephyr/test/i2c/CMakeLists.txt3
6 files changed, 69 insertions, 4 deletions
diff --git a/common/printf.c b/common/printf.c
index f876a1da19..039a83a92f 100644
--- a/common/printf.c
+++ b/common/printf.c
@@ -275,7 +275,9 @@ int vfnprintf(int (*addchar)(void *context, int c), void *context,
continue;
/* %pT - print a timestamp. */
if (ptrspec == 'T' &&
- !IS_ENABLED(NO_UINT64_SUPPORT)) {
+ !IS_ENABLED(NO_UINT64_SUPPORT) &&
+ (!IS_ENABLED(CONFIG_ZEPHYR) ||
+ IS_ENABLED(CONFIG_PLATFORM_EC_TIMER))) {
flags |= PF_64BIT;
if (ptrval == PRINTF_TIMESTAMP_NOW)
v = get_time().val;
@@ -461,6 +463,12 @@ int vfnprintf(int (*addchar)(void *context, int c), void *context,
return EC_SUCCESS;
}
+/*
+ * These symbols are already defined by the Zephyr OS kernel, and we
+ * don't want to use the EC implementation.
+ */
+#ifndef CONFIG_ZEPHYR
+
/* Context for snprintf() */
struct snprintf_context {
char *str;
@@ -516,3 +524,5 @@ int vsnprintf(char *str, int size, const char *format, va_list args)
return (rv == EC_SUCCESS) ? (ctx.str - str) : -rv;
}
+
+#endif /* !CONFIG_ZEPHYR */
diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt
index 68f7382cc6..28620657d4 100644
--- a/zephyr/CMakeLists.txt
+++ b/zephyr/CMakeLists.txt
@@ -40,6 +40,7 @@ add_subdirectory_ifdef(CONFIG_PLATFORM_EC "shim")
# supported by all boards and emulators (including unit tests) using the shim
# layer.
zephyr_sources_ifdef(CONFIG_PLATFORM_EC "${PLATFORM_EC}/common/base32.c"
+ "${PLATFORM_EC}/common/printf.c"
"${PLATFORM_EC}/common/queue.c"
"${PLATFORM_EC}/common/shared_mem.c")
diff --git a/zephyr/shim/src/console.c b/zephyr/shim/src/console.c
index f59bda2f63..f07b56cf2f 100644
--- a/zephyr/shim/src/console.c
+++ b/zephyr/shim/src/console.c
@@ -10,12 +10,19 @@
#include <zephyr.h>
#include "console.h"
+#include "printf.h"
int cputs(enum console_channel channel, const char *str)
{
return cprintf(channel, "%s", str);
}
+static int printk_putchar(void *context, int c)
+{
+ printk("%c", c);
+ return 0;
+}
+
static void console_vprintf(enum console_channel channel, const char *format,
va_list args)
{
@@ -27,7 +34,7 @@ static void console_vprintf(enum console_channel channel, const char *format,
* use shell_ print functions instead of printk function as they could
* be on different uarts (they are not for Chrome OS Apps though).
*/
- vprintk(format, args);
+ vfnprintf(printk_putchar, NULL, format, args);
}
__attribute__((__format__(__printf__, 2, 3))) int
@@ -46,7 +53,7 @@ cprints(enum console_channel channel, const char *format, ...)
{
va_list args;
- cprintf(channel, "[%lld ", k_uptime_get());
+ cprintf(channel, "[%pT ", PRINTF_TIMESTAMP_NOW);
va_start(args, format);
console_vprintf(channel, format, args);
va_end(args);
diff --git a/zephyr/shim/src/util.c b/zephyr/shim/src/util.c
index 3181fccb95..5a7131b23a 100644
--- a/zephyr/shim/src/util.c
+++ b/zephyr/shim/src/util.c
@@ -161,3 +161,47 @@ int parse_offset_size(int argc, char **argv, int shift, int *offset, int *size)
return EC_SUCCESS;
}
+
+int uint64divmod(uint64_t *n, int d)
+{
+ uint64_t q = 0, mask;
+ int r = 0;
+
+ /* Divide-by-zero returns zero */
+ if (!d) {
+ *n = 0;
+ return 0;
+ }
+
+ /* Common powers of 2 = simple shifts */
+ if (d == 2) {
+ r = *n & 1;
+ *n >>= 1;
+ return r;
+ } else if (d == 16) {
+ r = *n & 0xf;
+ *n >>= 4;
+ return r;
+ }
+
+ /* If v fits in 32-bit, we're done. */
+ if (*n <= 0xffffffff) {
+ uint32_t v32 = *n;
+ r = v32 % d;
+ *n = v32 / d;
+ return r;
+ }
+
+ /* Otherwise do integer division the slow way. */
+ for (mask = (1ULL << 63); mask; mask >>= 1) {
+ r <<= 1;
+ if (*n & mask)
+ r |= 1;
+ if (r >= d) {
+ r -= d;
+ q |= mask;
+ }
+ }
+ *n = q;
+ return r;
+}
diff --git a/zephyr/test/hooks/CMakeLists.txt b/zephyr/test/hooks/CMakeLists.txt
index e44ebfe674..2236963762 100644
--- a/zephyr/test/hooks/CMakeLists.txt
+++ b/zephyr/test/hooks/CMakeLists.txt
@@ -23,5 +23,7 @@ zephyr_include_directories(
# Include test file, test under test and console dependency
target_sources(app PRIVATE hooks.c)
+target_sources(app PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../../common/printf.c")
target_sources(app PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../shim/src/hooks.c")
target_sources(app PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../shim/src/console.c")
+target_sources(app PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../shim/src/util.c")
diff --git a/zephyr/test/i2c/CMakeLists.txt b/zephyr/test/i2c/CMakeLists.txt
index 94c5deb8cc..4edbfb9006 100644
--- a/zephyr/test/i2c/CMakeLists.txt
+++ b/zephyr/test/i2c/CMakeLists.txt
@@ -25,4 +25,5 @@ target_sources(app PRIVATE
"${PLATFORM_EC}/zephyr/shim/src/console.c"
"${PLATFORM_EC}/zephyr/shim/src/i2c.c"
"${PLATFORM_EC}/zephyr/shim/src/util.c"
- "${PLATFORM_EC}/common/i2c_controller.c")
+ "${PLATFORM_EC}/common/i2c_controller.c"
+ "${PLATFORM_EC}/common/printf.c")