mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
216 lines
5.8 KiB
C
216 lines
5.8 KiB
C
/* 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 __CROS_EC_UTIL_H
|
|
#define __CROS_EC_UTIL_H
|
|
|
|
#include "common.h"
|
|
#include "compile_time_macros.h"
|
|
#include "panic.h"
|
|
|
|
#include "builtin/assert.h" /* For ASSERT(). */
|
|
#include <stddef.h>
|
|
|
|
/* Standard macros / definitions */
|
|
#ifndef MAX
|
|
#define MAX(a, b) \
|
|
({ \
|
|
__typeof__(a) temp_a = (a); \
|
|
__typeof__(b) temp_b = (b); \
|
|
\
|
|
temp_a > temp_b ? temp_a : temp_b; \
|
|
})
|
|
#endif
|
|
#ifndef MIN
|
|
#define MIN(a, b) \
|
|
({ \
|
|
__typeof__(a) temp_a = (a); \
|
|
__typeof__(b) temp_b = (b); \
|
|
\
|
|
temp_a < temp_b ? temp_a : temp_b; \
|
|
})
|
|
#endif
|
|
#ifndef NULL
|
|
#define NULL ((void *)0)
|
|
#endif
|
|
|
|
/*
|
|
* Convert a pointer to a base struct into a pointer to the struct that
|
|
* contains the base struct. This requires knowing where in the contained
|
|
* struct the base struct resides, this is the member parameter to downcast.
|
|
*/
|
|
#define DOWNCAST(pointer, type, member) \
|
|
((type *)(((uint8_t *) pointer) - offsetof(type, member)))
|
|
|
|
/* True of x is a power of two */
|
|
#define POWER_OF_TWO(x) (x && !(x & (x - 1)))
|
|
|
|
/*
|
|
* macros for integer division with various rounding variants
|
|
* default integer division rounds down.
|
|
*/
|
|
#define DIV_ROUND_UP(x, y) (((x) + ((y) - 1)) / (y))
|
|
#define DIV_ROUND_NEAREST(x, y) (((x) + ((y) / 2)) / (y))
|
|
|
|
/* Standard library functions */
|
|
int atoi(const char *nptr);
|
|
int isdigit(int c);
|
|
int isspace(int c);
|
|
int isalpha(int c);
|
|
int isprint(int c);
|
|
int memcmp(const void *s1, const void *s2, size_t len);
|
|
int safe_memcmp(const void *s1, const void *s2, size_t len);
|
|
void *memcpy(void *dest, const void *src, size_t len);
|
|
__visible void *memset(void *dest, int c, size_t len);
|
|
void *memmove(void *dest, const void *src, size_t len);
|
|
void *memchr(const void *buffer, int c, size_t n);
|
|
int strcasecmp(const char *s1, const char *s2);
|
|
int strncasecmp(const char *s1, const char *s2, size_t size);
|
|
size_t strlen(const char *s);
|
|
size_t strnlen(const char *s, size_t maxlen);
|
|
char *strncpy(char *dest, const char *src, size_t n);
|
|
int strncmp(const char *s1, const char *s2, size_t n);
|
|
|
|
/* Like strtol(), but for integers. */
|
|
int strtoi(const char *nptr, char **endptr, int base);
|
|
uint64_t strtoul(const char *nptr, char **endptr, int base);
|
|
|
|
/* Like strncpy(), but guarantees null termination. */
|
|
char *strzcpy(char *dest, const char *src, int len);
|
|
|
|
/**
|
|
* Parses a boolean option from a string.
|
|
*
|
|
* Strings that set *dest=0 and return 1 (all case-insensitive):
|
|
* "off"
|
|
* "dis*"
|
|
* "n*"
|
|
* "f*"
|
|
*
|
|
* Strings that set *dest=1 and return 1 (all case-insensitive):
|
|
* "on"
|
|
* "ena*"
|
|
* "y*"
|
|
* "t*"
|
|
*
|
|
* Other strings return 0 and leave *dest unchanged.
|
|
*/
|
|
int parse_bool(const char *s, int *dest);
|
|
|
|
int tolower(int c);
|
|
|
|
/* 64-bit divide-and-modulo. Does the equivalent of:
|
|
*
|
|
* r = *n % d;
|
|
* *n /= d;
|
|
* return r;
|
|
*/
|
|
int uint64divmod(uint64_t *v, int by);
|
|
|
|
/**
|
|
* Get-and-clear next bit from mask.
|
|
*
|
|
* Starts with most significant bit.
|
|
*
|
|
* @param mask Bitmask to extract next bit from. Must NOT be zero.
|
|
* @return bit position (0..31)
|
|
*/
|
|
int get_next_bit(uint32_t *mask);
|
|
|
|
/**
|
|
* Reverse's the byte-order of the provided buffer.
|
|
*/
|
|
void reverse(void *dest, size_t len);
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Conditional stuff.
|
|
*
|
|
* We often need to watch for transitions between one state and another, so
|
|
* that we can issue warnings or take action ONCE. This abstracts that "have I
|
|
* already reacted to this" stuff into a single set of functions.
|
|
*
|
|
* For example:
|
|
*
|
|
* cond_t c;
|
|
*
|
|
* cond_init_false(&c);
|
|
*
|
|
* while(1) {
|
|
* int val = read_some_gpio();
|
|
* cond_set(&c, val);
|
|
*
|
|
* if (cond_went_true(&c))
|
|
* host_event(SOMETHING_HAPPENED);
|
|
* }
|
|
*
|
|
*/
|
|
typedef uint8_t cond_t;
|
|
|
|
/* Initialize a conditional to a specific state. Do this first. */
|
|
void cond_init(cond_t *c, int boolean);
|
|
static inline void cond_init_false(cond_t *c) { cond_init(c, 0); }
|
|
static inline void cond_init_true(cond_t *c) { cond_init(c, 1); }
|
|
|
|
/* Set the current state. Do this as often as you like. */
|
|
void cond_set(cond_t *c, int boolean);
|
|
static inline void cond_set_false(cond_t *c) { cond_set(c, 0); }
|
|
static inline void cond_set_true(cond_t *c) { cond_set(c, 1); }
|
|
|
|
/* Get the current state. Do this as often as you like. */
|
|
int cond_is(cond_t *c, int boolean);
|
|
static inline int cond_is_false(cond_t *c) { return cond_is(c, 0); }
|
|
static inline int cond_is_true(cond_t *c) { return cond_is(c, 1); }
|
|
|
|
/* See if the state has transitioned. If it has, the corresponding function
|
|
* will return true ONCE only, until it's changed back.
|
|
*/
|
|
int cond_went(cond_t *c, int boolean);
|
|
static inline int cond_went_false(cond_t *c) { return cond_went(c, 0); }
|
|
static inline int cond_went_true(cond_t *c) { return cond_went(c, 1); }
|
|
|
|
/****************************************************************************/
|
|
/* Console command parsing */
|
|
|
|
/* Parse command-line arguments given integer shift value to obtain
|
|
* offset and size.
|
|
*/
|
|
int parse_offset_size(int argc, char **argv, int shift,
|
|
int *offset, int *size);
|
|
|
|
#ifdef CONFIG_ASSEMBLY_MULA32
|
|
/*
|
|
* Compute (a*b)+c[+d], where a, b, c[, d] are 32-bit integers, and the result
|
|
* is 64-bit long.
|
|
*/
|
|
uint64_t mula32(uint32_t a, uint32_t b, uint32_t c);
|
|
uint64_t mulaa32(uint32_t a, uint32_t b, uint32_t c, uint32_t d);
|
|
#else
|
|
static inline uint64_t mula32(uint32_t a, uint32_t b, uint32_t c)
|
|
{
|
|
uint64_t ret = a;
|
|
|
|
ret *= b;
|
|
ret += c;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static inline uint64_t mulaa32(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
|
{
|
|
uint64_t ret = a;
|
|
|
|
ret *= b;
|
|
ret += c;
|
|
ret += d;
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#endif /* __CROS_EC_UTIL_H */
|