/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * Copyright IBM Corp. 2008
 *
 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
 */

#ifndef _LIBCFLAT_H_
#define _LIBCFLAT_H_

#ifndef __ASSEMBLY__

#include <linux/compiler.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>

#define xstr(s...) xxstr(s)
#define xxstr(s...) #s

#define __ALIGN_MASK(x, mask)	(((x) + (mask)) & ~(mask))
#define __ALIGN(x, a)		__ALIGN_MASK(x, (typeof(x))(a) - 1)
#define ALIGN(x, a)		__ALIGN((x), (a))
#define ALIGN_DOWN(x, a)	__ALIGN((x) - ((a) - 1), (a))
#define IS_ALIGNED(x, a)	(((x) & ((typeof(x))(a) - 1)) == 0)

#define MIN(a, b)		((a) < (b) ? (a) : (b))
#define MAX(a, b)		((a) > (b) ? (a) : (b))

typedef uint8_t		u8;
typedef int8_t		s8;
typedef uint16_t	u16;
typedef int16_t		s16;
typedef uint32_t	u32;
typedef int32_t		s32;
typedef uint64_t	u64;
typedef int64_t		s64;
typedef unsigned long	ulong;

#if __SIZEOF_LONG__ == 8
#  define __PRI32_PREFIX
#  define __PRI64_PREFIX	"l"
#  define __PRIPTR_PREFIX	"l"
#else
#if defined(__U32_LONG_FMT__)
#  define __PRI32_PREFIX        "l"
#else
#  define __PRI32_PREFIX
#endif
#  define __PRI64_PREFIX	"ll"
#  define __PRIPTR_PREFIX
#endif
#define PRId32  __PRI32_PREFIX	"d"
#define PRIu32  __PRI32_PREFIX	"u"
#define PRIx32  __PRI32_PREFIX	"x"
#define PRId64  __PRI64_PREFIX	"d"
#define PRIu64  __PRI64_PREFIX	"u"
#define PRIx64  __PRI64_PREFIX	"x"
#define PRIxPTR __PRIPTR_PREFIX	"x"

typedef u64			phys_addr_t;
#define INVALID_PHYS_ADDR	(~(phys_addr_t)0)

extern void puts(const char *s);
extern int __getchar(void);
extern int getchar(void);
extern void exit(int code) __attribute__((noreturn));
extern void abort(void) __attribute__((noreturn));
extern long atol(const char *ptr);
extern char *getenv(const char *name);

extern int printf(const char *fmt, ...)
					__attribute__((format(printf, 1, 2)));
extern int snprintf(char *buf, int size, const char *fmt, ...)
					__attribute__((format(printf, 3, 4)));
extern int vsnprintf(char *buf, int size, const char *fmt, va_list va)
					__attribute__((format(printf, 3, 0)));
extern int vprintf(const char *fmt, va_list va)
					__attribute__((format(printf, 1, 0)));

void report_prefix_pushf(const char *prefix_fmt, ...)
					__attribute__((format(printf, 1, 2)));
extern void report_prefix_push(const char *prefix);
extern void report_prefix_pop(void);
extern void report(bool pass, const char *msg_fmt, ...)
		__attribute__((format(printf, 2, 3), nonnull(2)));
extern void report_xfail(bool xfail, bool pass, const char *msg_fmt, ...)
		__attribute__((format(printf, 3, 4), nonnull(3)));
extern void report_kfail(bool kfail, bool pass, const char *msg_fmt, ...)
		__attribute__((format(printf, 3, 4), nonnull(3)));
extern void report_abort(const char *msg_fmt, ...)
					__attribute__((format(printf, 1, 2)))
					__attribute__((noreturn));
extern void report_skip(const char *msg_fmt, ...)
					__attribute__((format(printf, 1, 2)));
extern void report_info(const char *msg_fmt, ...)
					__attribute__((format(printf, 1, 2)));
extern void report_pass(const char *msg_fmt, ...)
					__attribute__((format(printf, 1, 2)));
extern void report_fail(const char *msg_fmt, ...)
					__attribute__((format(printf, 1, 2)));
extern void report_passed(void);
extern int report_summary(void);

bool simple_glob(const char *text, const char *pattern);

extern void dump_stack(void);
extern void dump_frame_stack(const void *instruction, const void *frame);

#define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))

#define container_of(ptr, type, member) ({				\
	const typeof( ((type *)0)->member ) *__mptr = (ptr);		\
	(type *)( (char *)__mptr - offsetof(type,member) );})

#define assert(cond)							\
do {									\
	if (!(cond)) {							\
		printf("%s:%d: assert failed: %s\n",			\
		       __FILE__, __LINE__, #cond);			\
		dump_stack();						\
		abort();						\
	}								\
} while (0)

#define assert_msg(cond, fmt, args...)					\
do {									\
	if (!(cond)) {							\
		printf("%s:%d: assert failed: %s: " fmt "\n",		\
		       __FILE__, __LINE__, #cond, ## args);		\
		dump_stack();						\
		abort();						\
	}								\
} while (0)

/*
 * One byte per bit, a ' between each group of 4 bits, and a null terminator.
 */
#define BINSTR_SZ (sizeof(unsigned long) * 8 + sizeof(unsigned long) * 2)
void binstr(unsigned long x, char out[BINSTR_SZ]);
void print_binstr(unsigned long x);

#endif /* !__ASSEMBLY__ */

#define SZ_256			(1 << 8)
#define SZ_4K			(1 << 12)
#define SZ_8K			(1 << 13)
#define SZ_16K			(1 << 14)
#define SZ_64K			(1 << 16)
#define SZ_128K			(1 << 17)
#define SZ_1M			(1 << 20)
#define SZ_2M			(1 << 21)
#define SZ_1G			(1 << 30)
#define SZ_2G			(1ul << 31)

#endif
