mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
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
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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) = '-';
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
* including padding (%-5s, %8d, %08x, %016lx)
|
||||
*
|
||||
* Support planned for:
|
||||
* int64_t / uint64_t (%ld / %lu / %lx)
|
||||
*
|
||||
* 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. */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user