diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-04-20 13:07:42 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2012-04-20 14:01:11 -0700 |
commit | 9f552ff5aa043eddc5b6d59db09728d83faf97dd (patch) | |
tree | e7f39070eac9b14a9afa6363703eab0950e856cc | |
parent | a05deade13c696643ca6f8cc216f78db015a7ddb (diff) | |
download | chrome-ec-9f552ff5aa043eddc5b6d59db09728d83faf97dd.tar.gz |
Implement 64-bit integer printing in uart_printf()
Signed-off-by: Randall Spangler <rspangler@chromium.org>
BUG=chrome-os-partner:7490
TEST=timerinfo; numbers should look reasonable
Change-Id: I698be99c87bf311013427ac0ed9e93e5687f40c0
-rw-r--r-- | common/charge_state.h | 2 | ||||
-rw-r--r-- | common/uart_buffering.c | 41 | ||||
-rw-r--r-- | common/util.c | 46 | ||||
-rw-r--r-- | core/cortex-m/timer.c | 28 | ||||
-rw-r--r-- | include/uart.h | 11 | ||||
-rw-r--r-- | include/util.h | 22 |
6 files changed, 109 insertions, 41 deletions
diff --git a/common/charge_state.h b/common/charge_state.h index 0fe93b92a0..672dab3e8b 100644 --- a/common/charge_state.h +++ b/common/charge_state.h @@ -10,7 +10,7 @@ #define __CROS_EC_CHARGE_STATE_H /* Time constants */ -#define MSEC ((uint64_t)1000) +#define MSEC (1000ULL) #define SECOND (MSEC * 1000) #define MINUTE (SECOND * 60) #define HOUR (MINUTE * 60) diff --git a/common/uart_buffering.c b/common/uart_buffering.c index 6393ff47be..6d08dbb9af 100644 --- a/common/uart_buffering.c +++ b/common/uart_buffering.c @@ -452,24 +452,40 @@ int uart_printf(const char *format, ...) if (vstr == NULL) vstr = "(NULL)"; } else { - uint32_t v; + uint64_t v; int is_negative = 0; + int is_64bit = 0; int base = 10; - /* TODO: (crosbug.com/p/7490) handle "%l" prefix for - * uint64_t */ + if (c == 'l') { + is_64bit = 1; + c = *format++; + } /* Special-case: %T = current time */ - if (c == 'T') - v = get_time().le.lo; - else + if (c == 'T') { + v = get_time().val; + is_64bit = 1; + } else if (is_64bit) { + v = va_arg(args, uint64_t); + } else { v = va_arg(args, uint32_t); + } switch (c) { case 'd': - if ((int)v < 0) { - is_negative = 1; - v = -v; + if (is_64bit) { + if ((int64_t)v < 0) { + is_negative = 1; + if (v != (1ULL << 63)) + v = -v; + } + } else { + if ((int)v < 0) { + is_negative = 1; + if (v != (1ULL << 31)) + v = -(int)v; + } } break; case 'u': @@ -496,10 +512,9 @@ int uart_printf(const char *format, ...) if (!v) *(--vstr) = '0'; - while (v) { - *(--vstr) = int_chars[v % base]; - v /= base; - } + while (v) + *(--vstr) = int_chars[uint64divmod(&v, base)]; + if (is_negative) *(--vstr) = '-'; } diff --git a/common/util.c b/common/util.c index 40908cc5ce..fe30ffa518 100644 --- a/common/util.c +++ b/common/util.c @@ -144,7 +144,6 @@ void *memset(void *dest, int c, int len) } -/* Like strncpy(), but guarantees null termination */ char *strzcpy(char *dest, const char *src, int len) { char *d = dest; @@ -155,3 +154,48 @@ char *strzcpy(char *dest, const char *src, int len) *d = '\0'; return dest; } + + +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/core/cortex-m/timer.c b/core/cortex-m/timer.c index 8d98287c46..e4915e76ad 100644 --- a/core/cortex-m/timer.c +++ b/core/cortex-m/timer.c @@ -167,29 +167,31 @@ DECLARE_CONSOLE_COMMAND(waitms, command_wait); static int command_get_time(int argc, char **argv) { timestamp_t ts = get_time(); - uart_printf("Time: 0x%08x%08x us (%u %u)\n", ts.le.hi, ts.le.lo, - ts.le.hi, ts.le.lo); - return EC_SUCCESS; + uart_printf("Time: 0x%016lx = %ld us\n", ts.val, ts.val); + return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(gettime, command_get_time); int command_timer_info(int argc, char **argv) { - timestamp_t ts = get_time(); + uint64_t t = get_time().val; + uint64_t deadline = (uint64_t)clksrc_high << 32 | + __hw_clock_event_get(); int tskid; - uart_printf("Time: 0x%08x%08x us\n" - "Deadline: 0x%08x%08x us\n" - "Active timers:\n", - ts.le.hi, ts.le.lo, clksrc_high, - __hw_clock_event_get()); + uart_printf("Time: 0x%016lx us\n" + "Deadline: 0x%016lx -> %10ld us from now\n" + "Active timers:\n", + t, deadline, deadline - t); for (tskid = 0; tskid < TASK_ID_COUNT; tskid++) { - if (timer_running & (1<<tskid)) - uart_printf("Tsk %d tmr 0x%08x%08x\n", tskid, - timer_deadline[tskid].le.hi, - timer_deadline[tskid].le.lo); + if (timer_running & (1<<tskid)) { + uart_printf(" Tsk %2d 0x%016lx -> %10ld\n", tskid, + timer_deadline[tskid].val, + timer_deadline[tskid].val - t); + uart_flush_output(); + } } return EC_SUCCESS; } diff --git a/include/uart.h b/include/uart.h index 3ca34c67f1..67a2968d6c 100644 --- a/include/uart.h +++ b/include/uart.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 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. */ @@ -46,16 +46,13 @@ int uart_puts(const char *outstr); * string (%s) * native int (signed/unsigned) (%d / %u / %x) * int32_t / uint32_t (%d / %x) + * int64_t / uint64_t (%ld / %lu / %lx) * pointer (%p) * And the following special format codes: * current time in us (%T) - * including padding (%-5s, %8d, %08x) - * - * Support planned for: - * int64_t / uint64_t (%ld / %lu / %lx) + * including padding (%-5s, %8d, %08x, %016lx) * - * Note: Floating point output (%f / %g) is not supported. - */ + * Floating point output (%f / %g) is not supported. */ int uart_printf(const char *format, ...); /* Flushes output. Blocks until UART has transmitted all output. */ diff --git a/include/util.h b/include/util.h index d11b3a587f..5b9dd364db 100644 --- a/include/util.h +++ b/include/util.h @@ -1,15 +1,14 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 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. */ /* Various utility functions and macros */ -#ifndef __UTIL_H -#define __UTIL_H - -#include <stdint.h> +#ifndef __CROS_EC_UTIL_H +#define __CROS_EC_UTIL_H +#include "common.h" #include "config.h" /** @@ -60,7 +59,18 @@ void *memset(void *dest, int c, int len); int strcasecmp(const char *s1, const char *s2); int strlen(const char *s); int strtoi(const char *nptr, char **endptr, int base); + +/* Like strncpy(), but guarantees null termination. */ char *strzcpy(char *dest, const char *src, int len); + int tolower(int c); -#endif /* __UTIL_H */ +/* 64-bit divide-and-modulo. Does the equivalent of: + * + * r = *n % d; + * *n /= d; + * return r; + */ +int uint64divmod(uint64_t *v, int by); + +#endif /* __CROS_EC_UTIL_H */ |