summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-03-05 10:01:45 -0600
committerPatrick Williams <iawillia@us.ibm.com>2011-03-05 10:01:45 -0600
commit706243ac48cf646d503a3f1ec9e6a28c916694bd (patch)
tree5d583486a145a9646eccb9d3c4bce4dad45a2a84 /src/include
parent5c20d316d21e231daee6455f0a78d5940d59cf23 (diff)
downloadtalos-hostboot-706243ac48cf646d503a3f1ec9e6a28c916694bd.tar.gz
talos-hostboot-706243ac48cf646d503a3f1ec9e6a28c916694bd.zip
Merge of PowerHAL project up to commit:
dd45c30bd53d8e6c123165b83842d08117558a3c
Diffstat (limited to 'src/include')
-rw-r--r--src/include/arch/ppc.H174
-rw-r--r--src/include/assert.h31
-rw-r--r--src/include/builtins.h95
-rw-r--r--src/include/kernel/console.H3
-rw-r--r--src/include/kernel/cpu.H7
-rw-r--r--src/include/kernel/ppcarch.H87
-rw-r--r--src/include/kernel/ppcconsts.S2
-rw-r--r--src/include/kernel/timemgr.H4
-rw-r--r--src/include/math.h23
-rwxr-xr-xsrc/include/new9
-rw-r--r--src/include/stddef.h2
-rw-r--r--src/include/stdint.h5
-rw-r--r--src/include/stdio.h16
-rwxr-xr-x[-rw-r--r--]src/include/string.h7
-rw-r--r--src/include/sys/msg.h7
-rw-r--r--src/include/sys/vfs.h7
-rw-r--r--src/include/util/functor.H100
-rw-r--r--src/include/util/locked/list.H1
-rw-r--r--src/include/util/sprintf.H323
19 files changed, 805 insertions, 98 deletions
diff --git a/src/include/arch/ppc.H b/src/include/arch/ppc.H
new file mode 100644
index 000000000..003f804a3
--- /dev/null
+++ b/src/include/arch/ppc.H
@@ -0,0 +1,174 @@
+#ifndef __KERNEL_PPCARCH_H
+#define __KERNEL_PPCARCH_H
+
+#include <kernel/types.h>
+#include <builtins.h>
+
+ALWAYS_INLINE
+inline uint64_t getSRR0()
+{
+ register uint64_t srr0 = 0;
+ asm volatile("mfsrr0 %0" : "=r" (srr0));
+ return srr0;
+}
+
+ALWAYS_INLINE
+inline uint64_t getSRR1()
+{
+ register uint64_t srr1 = 0;
+ asm volatile("mfsrr1 %0" : "=r" (srr1));
+ return srr1;
+}
+
+ALWAYS_INLINE
+inline void setSRR0(uint64_t _srr0)
+{
+ register uint64_t srr0 = _srr0;
+ asm volatile("mtsrr0 %0" : : "r" (srr0));
+}
+
+ALWAYS_INLINE
+inline void setSRR1(uint64_t _srr1)
+{
+ register uint64_t srr1 = _srr1;
+ asm volatile("mtsrr1 %0" : : "r" (srr1));
+}
+
+ALWAYS_INLINE
+inline uint64_t getPVR()
+{
+ register uint64_t pvr = 0;
+ asm volatile("mfspr %0, 287" : "=r" (pvr));
+ return pvr;
+}
+
+ALWAYS_INLINE
+inline uint64_t getPIR()
+{
+ register uint64_t pir = 0;
+ asm volatile("mfspr %0, 1023" : "=r" (pir));
+ return pir;
+}
+
+ALWAYS_INLINE
+inline uint64_t getSPRG3()
+{
+ register uint64_t sprg3 = 0;
+ asm volatile("mfsprg3 %0" : "=r" (sprg3));
+ return sprg3;
+}
+
+ALWAYS_INLINE
+inline void setSPRG3(uint64_t _sprg3)
+{
+ register uint64_t sprg3 = _sprg3;
+ asm volatile("mtsprg3 %0" : : "r" (sprg3));
+ return;
+}
+
+ALWAYS_INLINE
+inline uint64_t getMSR()
+{
+ register uint64_t msr = 0;
+ asm volatile("mfmsr %0" : "=r" (msr));
+ return msr;
+}
+
+ALWAYS_INLINE
+inline void setMSR(uint64_t _msr)
+{
+ register uint64_t msr = _msr;
+ asm volatile("mtmsr %0; isync" :: "r" (msr));
+}
+
+ALWAYS_INLINE
+inline uint64_t getDSISR()
+{
+ register uint64_t dsisr = 0;
+ asm volatile("mfspr %0, 18" : "=r" (dsisr));
+ return dsisr;
+}
+
+ALWAYS_INLINE
+inline uint64_t getDAR()
+{
+ register uint64_t dar = 0;
+ asm volatile("mfspr %0, 19" : "=r" (dar));
+ return dar;
+}
+
+ALWAYS_INLINE
+inline uint64_t getTB()
+{
+ register uint64_t tb = 0;
+ asm volatile("mfspr %0, 268" : "=r" (tb));
+ return tb;
+}
+
+ALWAYS_INLINE
+inline void sync()
+{
+ asm volatile("sync");
+}
+
+ALWAYS_INLINE
+inline void lwsync()
+{
+ asm volatile("lwsync");
+}
+
+ALWAYS_INLINE
+inline void isync()
+{
+ asm volatile("isync");
+}
+
+ALWAYS_INLINE
+inline void eieio()
+{
+ asm volatile("eieio");
+}
+
+ALWAYS_INLINE
+inline uint64_t getHMER()
+{
+ register uint64_t hmer = 0;
+ asm volatile("mfspr %0, 336" : "=r" (hmer));
+ return hmer;
+}
+
+ALWAYS_INLINE
+inline void setHMER(uint64_t _hmer)
+{
+ register uint64_t hmer = _hmer;
+ asm volatile("mtspr 336, %0" : : "r" (hmer));
+ return;
+}
+
+ALWAYS_INLINE
+inline void setThreadPriorityLow()
+{
+ asm volatile("or 1,1,1");
+}
+
+ALWAYS_INLINE
+inline void setThreadPriorityHigh()
+{
+ asm volatile("or 3,3,3");
+}
+
+ALWAYS_INLINE
+inline void dcbf(void* _ptr)
+{
+ register void* ptr = _ptr;
+ asm volatile("dcbf 0, %0" : : "b" (ptr) : "memory");
+}
+
+ALWAYS_INLINE
+inline void icbi(void* _ptr)
+{
+ register void* ptr = _ptr;
+ asm volatile("icbi 0, %0" : : "b" (ptr) : "memory");
+}
+
+#endif
diff --git a/src/include/assert.h b/src/include/assert.h
new file mode 100644
index 000000000..13888bee8
--- /dev/null
+++ b/src/include/assert.h
@@ -0,0 +1,31 @@
+#include <builtins.h>
+
+#ifndef _ASSERT_H
+#define _ASSERT_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+NO_RETURN
+void __assert(bool expr, const char *exprStr, const char *file, int line);
+
+#define assert(expr) \
+{\
+ if (!(expr))\
+ {\
+ __assert((expr), #expr, __FILE__, __LINE__);\
+ }\
+}\
+
+#ifdef NDEBUG
+#undef assert
+#define assert(expr) { }
+#endif
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/src/include/builtins.h b/src/include/builtins.h
new file mode 100644
index 000000000..5126b6114
--- /dev/null
+++ b/src/include/builtins.h
@@ -0,0 +1,95 @@
+#include <stdint.h>
+
+#ifndef _BUILTINS_H
+#define _BUILTINS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * This file should be the home of any use of gcc compiler builtins
+ */
+
+/**
+ * Use of this macro will ensure that the functions object code never gets generated without being inlined
+ */
+#define ALWAYS_INLINE __attribute__((always_inline))
+
+/**
+ * Use of this macro will ensure a data structure is aligned on a cacheline boundary
+ */
+#define ALIGN_CACHELINE __attribute__((aligned (128)))
+
+/**
+ * Function declaration macro that tells the compiler to use printf format checking semantics
+ *
+ * TODO Could make this a function macro and pass in the 3 args rather than hard coding
+ */
+#define FORMAT_PRINTF __attribute__((format(printf, 1, 2)))
+
+/**
+ * Function delaration macro that tells the compiler that this function never returns.
+ */
+#define NO_RETURN __attribute__((noreturn))
+
+/**
+ * Function / variable declaration macro that tells the compiler what section this symbol should go into.
+ */
+#define SYMB_SECTION(x) __attribute__((section(#x)))
+
+/**
+ * Get the value of the link register
+ *
+ * @return the value of the link register
+ */
+ALWAYS_INLINE
+static inline void *linkRegister()
+{
+ return __builtin_return_address(1);
+}
+
+/**
+ * Get the value of the stack-frame pointer
+ *
+ * @return The value of the frame pointer.
+ */
+ALWAYS_INLINE
+static inline void *framePointer()
+{
+ return __builtin_frame_address(0);
+}
+
+/**
+ * Counts leading zeros of a uint64_t value
+ *
+ * @param value to check
+ *
+ * @return the number of leading zeros
+ */
+ALWAYS_INLINE
+static inline uint64_t cntlzd(uint64_t value)
+{
+ return __builtin_clzl(value);
+}
+
+/**
+ * Counts trailing zeros of a uint64_t value
+ *
+ * @param value to check
+ *
+ * @return the number of trailing zeros
+ */
+ALWAYS_INLINE
+static inline uint64_t cnttzd(uint64_t value)
+{
+ return __builtin_ctzl(value);
+}
+
+#ifdef __cplusplus
+};
+#endif
+
+
+#endif
diff --git a/src/include/kernel/console.H b/src/include/kernel/console.H
index e12f66a62..964882a66 100644
--- a/src/include/kernel/console.H
+++ b/src/include/kernel/console.H
@@ -3,8 +3,9 @@
#include <stdint.h>
#include <string.h>
+#include <builtins.h>
-void printk(const char*, ...) __attribute__((format (printf, 1, 2)));
+void printk(const char*, ...) FORMAT_PRINTF;
class Console
{
diff --git a/src/include/kernel/cpu.H b/src/include/kernel/cpu.H
index 81b43a57c..2f012700c 100644
--- a/src/include/kernel/cpu.H
+++ b/src/include/kernel/cpu.H
@@ -2,7 +2,8 @@
#define __KERNEL_CPU_H
#include <kernel/types.h>
-#include <kernel/ppcarch.H>
+#include <arch/ppc.H>
+#include <builtins.h>
// Thread ID support only, Power7 (4 threads).
#define KERNEL_MAX_SUPPORTED_CPUS 4
@@ -18,10 +19,10 @@ struct cpu_t
task_t* idle_task;
};
-__attribute__((always_inline))
+ALWAYS_INLINE
inline uint64_t getCpuId()
{
- return ppc_getPIR() & (KERNEL_MAX_SUPPORTED_CPUS - 1);
+ return getPIR() & (KERNEL_MAX_SUPPORTED_CPUS - 1);
}
#endif
diff --git a/src/include/kernel/ppcarch.H b/src/include/kernel/ppcarch.H
deleted file mode 100644
index 3d34bf888..000000000
--- a/src/include/kernel/ppcarch.H
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef __KERNEL_PPCARCH_H
-#define __KERNEL_PPCARCH_H
-
-#include <kernel/types.h>
-
-__attribute__((always_inline))
-inline uint64_t ppc_getSRR1()
-{
- register uint64_t srr1 = 0;
- asm volatile("mfsrr1 %0" : "=r" (srr1));
- return srr1;
-}
-
-__attribute__((always_inline))
-inline uint64_t ppc_getPVR()
-{
- register uint64_t pvr = 0;
- asm volatile("mfspr %0, 287" : "=r" (pvr));
- return pvr;
-}
-
-__attribute__((always_inline))
-inline uint64_t ppc_getPIR()
-{
- register uint64_t pir = 0;
- asm volatile("mfspr %0, 1023" : "=r" (pir));
- return pir;
-}
-
-__attribute__((always_inline))
-inline uint64_t ppc_getSPRG3()
-{
- register uint64_t sprg3 = 0;
- asm volatile("mfsprg3 %0" : "=r" (sprg3));
- return sprg3;
-}
-
-__attribute__((always_inline))
-inline void ppc_setSPRG3(uint64_t _sprg3)
-{
- register uint64_t sprg3 = _sprg3;
- asm volatile("mtsprg3 %0" : : "r" (sprg3));
- return;
-}
-
-__attribute__((always_inline))
-inline uint64_t ppc_getMSR()
-{
- register uint64_t msr = 0;
- asm volatile("mfmsr %0" : "=r" (msr));
- return msr;
-}
-
-__attribute__((always_inline))
-inline void ppc_setMSR(uint64_t _msr)
-{
- register uint64_t msr = _msr;
- asm volatile("mtmsr %0; isync" :: "r" (msr));
-}
-
-__attribute__((always_inline))
-inline uint64_t ppc_getDSISR()
-{
- register uint64_t dsisr = 0;
- asm volatile("mfspr %0, 18" : "=r" (dsisr));
- return dsisr;
-}
-
-__attribute__((always_inline))
-inline uint64_t ppc_getDAR()
-{
- register uint64_t dar = 0;
- asm volatile("mfspr %0, 19" : "=r" (dar));
- return dar;
-}
-
-__attribute__((always_inline))
-inline uint64_t ppc_getTB()
-{
- register uint64_t tb = 0;
- asm volatile("mfspr %0, 268" : "=r" (tb));
- return tb;
-}
-
-
-
-#endif
diff --git a/src/include/kernel/ppcconsts.S b/src/include/kernel/ppcconsts.S
index 0c5e1dc3d..be7162b88 100644
--- a/src/include/kernel/ppcconsts.S
+++ b/src/include/kernel/ppcconsts.S
@@ -86,6 +86,8 @@
.set SDR1,25
.set SRR0,26
.set SRR1,27
+ .set HSRR0,314
+ .set HSRR1,315
.set SPRG0,272
.set SPRG1,273
.set SPRG2,274
diff --git a/src/include/kernel/timemgr.H b/src/include/kernel/timemgr.H
index 78de82216..acd4361c2 100644
--- a/src/include/kernel/timemgr.H
+++ b/src/include/kernel/timemgr.H
@@ -2,7 +2,7 @@
#define __KERNEL_TIMEMGR_H
#include <kernel/types.h>
-#include <kernel/ppcarch.H>
+#include <arch/ppc.H>
#include <util/locked/pqueue.H>
#include <kernel/spinlock.H>
@@ -33,7 +33,7 @@ class TimeManager
static uint64_t getCurrentTimeBase()
{
- return ppc_getTB();
+ return getTB();
};
static uint64_t convertSecToTicks(uint64_t i_sec, uint64_t i_nsec);
diff --git a/src/include/math.h b/src/include/math.h
new file mode 100644
index 000000000..eddb92f64
--- /dev/null
+++ b/src/include/math.h
@@ -0,0 +1,23 @@
+#include <stdint.h>
+#include <builtins.h>
+
+#ifndef _MATH_H
+#define _MATH_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ALWAYS_INLINE
+static inline int64_t log2(uint64_t s)
+{
+ int64_t n = cntlzd(s);
+ return 63-n;
+}
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/src/include/new b/src/include/new
new file mode 100755
index 000000000..3496d75ee
--- /dev/null
+++ b/src/include/new
@@ -0,0 +1,9 @@
+#ifndef __NEW_H
+#define __NEW_H
+
+#ifdef __cplusplus
+extern void *operator new(size_t, void*);
+extern void *operator new[](size_t, void*);
+#endif
+
+#endif
diff --git a/src/include/stddef.h b/src/include/stddef.h
index 10c28e361..49cef0832 100644
--- a/src/include/stddef.h
+++ b/src/include/stddef.h
@@ -9,4 +9,6 @@
#endif
#endif
+#define offsetof(type, member) __builtin_offsetof(type, member)
+
#endif
diff --git a/src/include/stdint.h b/src/include/stdint.h
index 1b7328d80..64d4e5b2a 100644
--- a/src/include/stdint.h
+++ b/src/include/stdint.h
@@ -16,4 +16,9 @@ typedef unsigned long int uint64_t;
typedef uint64_t size_t;
typedef int64_t ssize_t;
+#define UINT8_MAX (255U)
+#define UINT16_MAX (65535U)
+#define UINT32_MAX (4294967295U)
+#define UINT64_MAX (18446744073709551615U)
+
#endif
diff --git a/src/include/stdio.h b/src/include/stdio.h
new file mode 100644
index 000000000..87244b3be
--- /dev/null
+++ b/src/include/stdio.h
@@ -0,0 +1,16 @@
+#ifndef __STDIO_H
+#define __STDIO_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int sprintf(char *str, const char * format, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/string.h b/src/include/string.h
index 30c878d65..af535832f 100644..100755
--- a/src/include/string.h
+++ b/src/include/string.h
@@ -8,10 +8,15 @@ extern "C"
{
#endif
- void* memset(void* s, int c, size_t n);
+ void *memset(void* s, int64_t c, size_t n);
+ void bzero(void *vdest, size_t len);
+ void *memcpy(void *dest, const void *src, size_t num);
+ void *memmove(void *vdest, const void *vsrc, size_t len);
+ int64_t memcmp(const void *p1, const void *p2, size_t len);
char* strcpy(char* d, const char* s);
int strcmp(const char* s1, const char* s2);
+ size_t strlen(const char* s1);
#ifdef __cplusplus
};
diff --git a/src/include/sys/msg.h b/src/include/sys/msg.h
index d7c42f4e3..eec71ea4e 100644
--- a/src/include/sys/msg.h
+++ b/src/include/sys/msg.h
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <stdlib.h>
+#include <builtins.h>
#ifdef __cplusplus
extern "C"
@@ -26,9 +27,9 @@ int msg_q_register(msg_q_t q, const char* name);
msg_q_t msg_q_resolve(const char* name);
// Message interfaces.
-__attribute__((always_inline))
+ALWAYS_INLINE
inline msg_t* msg_allocate() { return (msg_t*)malloc(sizeof(msg_t)); }
-__attribute__((always_inline))
+ALWAYS_INLINE
inline void msg_free(msg_t* m) { free(m); }
int msg_send(msg_q_t q, msg_t* msg);
@@ -36,7 +37,7 @@ int msg_sendrecv(msg_q_t q, msg_t* msg);
int msg_respond(msg_q_t q, msg_t* msg);
msg_t* msg_wait(msg_q_t q);
-__attribute__((always_inline))
+ALWAYS_INLINE
inline uint32_t msg_is_async(msg_t* msg)
{ return 0 == msg->__reserved__async; }
diff --git a/src/include/sys/vfs.h b/src/include/sys/vfs.h
index d55a44710..3b2575139 100644
--- a/src/include/sys/vfs.h
+++ b/src/include/sys/vfs.h
@@ -10,6 +10,12 @@
#define VFS_STRINGIFY(X) #X
#define VFS_TOSTRING(X) VFS_STRINGIFY(X)
+#define VFS_MODULE_DEFINE_START(f) \
+ extern "C" void VFS_SYMBOL_START(void* args) \
+ { \
+ f(args); \
+ }
+
#ifdef __cplusplus
extern "C"
{
@@ -37,7 +43,6 @@ struct VfsSystemModule
extern VfsSystemModule VFS_MODULES[VFS_MODULE_MAX];
extern uint64_t VFS_LAST_ADDRESS;
-
#ifdef __cplusplus
}
#endif
diff --git a/src/include/util/functor.H b/src/include/util/functor.H
new file mode 100644
index 000000000..a9320f292
--- /dev/null
+++ b/src/include/util/functor.H
@@ -0,0 +1,100 @@
+#ifndef __UTIL_FUNCTOR_H
+#define __UTIL_FUNCTOR_H
+
+#include <builtins.h>
+
+namespace Util
+{
+ template <typename _ARG, typename _RESULT>
+ class unary_functor
+ {
+ public:
+ typedef _ARG argument_type;
+ typedef _RESULT result_type;
+
+ public:
+ virtual ~unary_functor() {};
+ virtual result_type operator()(argument_type) = 0;
+ };
+
+ template <typename _ARG1, typename _ARG2, typename _RESULT>
+ class binary_functor
+ {
+ public:
+ typedef _ARG1 first_argument_type;
+ typedef _ARG2 second_argument_type;
+ typedef _RESULT result_type;
+
+ public:
+ virtual ~binary_functor() {};
+ virtual result_type operator()
+ (first_argument_type, second_argument_type) = 0;
+ };
+
+ // Function pointer wrappers for functors.
+
+ template <typename _ARG, typename _RESULT>
+ class ptr_to_unary_function : public unary_functor<_ARG, _RESULT>
+ {
+ public:
+ typedef _RESULT(*function_type)(_ARG);
+
+ private:
+ function_type function;
+
+ public:
+ ptr_to_unary_function(function_type f) : function(f) {};
+
+
+ _RESULT operator()(_ARG t)
+ {
+ return function(t);
+ }
+ };
+
+ template <typename _ARG, typename _RESULT>
+ ALWAYS_INLINE
+ ptr_to_unary_function<_ARG, _RESULT> ptr_fun(_RESULT (*f)(_ARG))
+ {
+ return ptr_to_unary_function<_ARG,_RESULT>(f);
+ }
+
+#define PTR_FUN1_T(ARG_T, RESULT_T) \
+ ptr_to_unary_function<_ARG, _RESULT>
+
+
+ template <typename _ARG, typename _RESULT, typename _CLASS>
+ class mem_ptr_to_unary_function : public unary_functor<_ARG, _RESULT>
+ {
+ public:
+ typedef _CLASS member_type;
+ typedef _RESULT(member_type::*function_type)(_ARG);
+
+ private:
+ member_type& object;
+ function_type function;
+
+ public:
+ mem_ptr_to_unary_function(member_type& o, function_type f)
+ : object(o), function(f) {};
+
+ _RESULT operator()(_ARG t)
+ {
+ return (object.*function)(t);
+ }
+ };
+
+ template <typename _ARG, typename _RESULT, typename _CLASS>
+ ALWAYS_INLINE
+ mem_ptr_to_unary_function<_ARG, _RESULT, _CLASS>
+ mem_ptr_fun(_CLASS& o, _RESULT (_CLASS::*f)(_ARG))
+ {
+ return mem_ptr_to_unary_function<_ARG,_RESULT,_CLASS>(o, f);
+ }
+
+#define MEM_PTR_FUN1_T(CLASS_T, ARG_T, RESULT_T) \
+ mem_ptr_to_unary_function<ARG_T, RESULT_T, CLASS_T>
+
+};
+
+#endif
diff --git a/src/include/util/locked/list.H b/src/include/util/locked/list.H
index e4bc0f99c..ad5b06a3b 100644
--- a/src/include/util/locked/list.H
+++ b/src/include/util/locked/list.H
@@ -1,6 +1,7 @@
#ifndef __UTIL_LOCKED_LIST_H
#define __UTIL_LOCKED_LIST_H
+#include <stddef.h>
#include <util/locked/lock.H>
namespace Util
diff --git a/src/include/util/sprintf.H b/src/include/util/sprintf.H
new file mode 100644
index 000000000..6246b72a0
--- /dev/null
+++ b/src/include/util/sprintf.H
@@ -0,0 +1,323 @@
+#ifndef __UTIL_SPRINTF_H
+#define __UTIL_SPRINTF_H
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <builtins.h>
+
+class Console;
+
+namespace Util
+{
+
+ class ConsoleTraits
+ {
+ public:
+ enum trait { NONE, HEX, DEC, };
+ };
+
+ template <typename _T, ConsoleTraits::trait _S = ConsoleTraits::NONE>
+ class ConsoleDisplay
+ {
+ public:
+ template <typename _F>
+ ALWAYS_INLINE
+ static size_t display(_F& c, _T value) { return 0; };
+ };
+
+ template <ConsoleTraits::trait _S>
+ class ConsoleDisplay<char*, _S>
+ {
+ public:
+ template <typename _F>
+ ALWAYS_INLINE
+ static size_t display(_F& c, char* value)
+ {
+ size_t count = 0;
+ while(*value != '\0')
+ {
+ c(*value);
+ value++;
+ count++;
+ }
+ return count;
+ }
+ };
+
+ template <>
+ class ConsoleDisplay<char, ConsoleTraits::NONE>
+ {
+ public:
+ template <typename _F>
+ ALWAYS_INLINE
+ static size_t display(_F& c, char value)
+ {
+ c(value);
+ return 1;
+ }
+ };
+
+ template <typename _T>
+ class ConsoleDisplay<_T, ConsoleTraits::DEC>
+ {
+ public:
+ template <typename _F>
+ ALWAYS_INLINE
+ static size_t display(_F& c, _T value)
+ {
+ size_t count = 0;
+ if (value == 0)
+ {
+ c('0'); count++;
+ }
+ else if (value < 0)
+ {
+ c('-'); count++;
+ value *= -1;
+ count += subdisplay(c, value);
+ }
+ else
+ count += subdisplay(c, value);
+ return count;
+ }
+
+ template <typename _F>
+ static size_t subdisplay(_F& c, _T value)
+ {
+ size_t count = 0;
+ if (value != 0)
+ {
+ count += subdisplay(c, value / 10);
+ c('0' + (value % 10));
+ count++;
+ }
+ return count;
+ }
+ };
+
+ template<typename _T>
+ class ConsoleDisplay<_T, ConsoleTraits::HEX>
+ {
+ public:
+ template <typename _F>
+ ALWAYS_INLINE
+ static size_t display(_F& c, _T value)
+ {
+ size_t length = sizeof(_T) * 2;
+ subdisplay(c, value, length);
+ return length;
+ }
+
+ template <typename _F>
+ static void subdisplay(_F& c, _T value, size_t length)
+ {
+ if (length == 0) return;
+ subdisplay(c, value / 16, length-1);
+ char nibble = value % 16;
+ if (nibble >= 0x0a)
+ c('A' + (nibble - 0x0a));
+ else
+ c('0' + nibble);
+ }
+ };
+
+ template<typename _F>
+ size_t vasprintf(_F output_func, const char* fmt_str, va_list& args)
+ {
+ size_t count = 0;
+
+ bool format = false;
+ int size = 0;
+
+ while('\0' != *fmt_str)
+ {
+ if (('%' == *fmt_str) || (format))
+ switch (*fmt_str)
+ {
+ case '%':
+ {
+ if (format)
+ {
+ count +=
+ ConsoleDisplay<char>::display(output_func,
+ '%');
+ format = false;
+ }
+ else
+ {
+ format = true;
+ size = 2;
+ }
+ break;
+ }
+ case 'c':
+ {
+ format = false;
+ count += ConsoleDisplay<char>
+ ::display(output_func, (char)va_arg(args,int));
+ break;
+ }
+ case 'h':
+ {
+ size--;
+ break;
+ }
+ case 'l':
+ {
+ size++;
+ break;
+ }
+ case 'z': // size_t or ssize_t
+ {
+ size = 4;
+ break;
+ }
+ case 'd': // decimal
+ {
+ format = false;
+ switch(size)
+ {
+ case 0:
+ count += ConsoleDisplay<char,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ (char)va_arg(args,int));
+ break;
+
+ case 1:
+ count += ConsoleDisplay<short,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ (short)va_arg(args,int));
+ break;
+
+ case 2:
+ count += ConsoleDisplay<int,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ va_arg(args,int));
+ break;
+
+ case 3:
+ case 4:
+ count += ConsoleDisplay<long,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ va_arg(args,long));
+ break;
+ }
+ break;
+ }
+ case 'u': // unsigned decimal
+ {
+ format = false;
+ switch(size)
+ {
+ case 0:
+ count += ConsoleDisplay<unsigned char,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ (unsigned char)
+ va_arg(args,unsigned int));
+ break;
+
+ case 1:
+ count += ConsoleDisplay<unsigned short,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ (unsigned short)
+ va_arg(args,unsigned int));
+ break;
+
+ case 2:
+ count += ConsoleDisplay<unsigned int,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ va_arg(args,unsigned int));
+ break;
+
+ case 3:
+ case 4:
+ count += ConsoleDisplay<unsigned long,
+ ConsoleTraits::DEC>
+ ::display(output_func,
+ va_arg(args,unsigned long));
+ break;
+ }
+ break;
+ }
+ case 'x': // unsigned hex
+ case 'X':
+ {
+ format = false;
+ switch(size)
+ {
+ case 0:
+ count += ConsoleDisplay<unsigned char,
+ ConsoleTraits::HEX>
+ ::display(output_func,
+ (unsigned char)
+ va_arg(args,unsigned int));
+ break;
+
+ case 1:
+ count += ConsoleDisplay<unsigned short,
+ ConsoleTraits::HEX>
+ ::display(output_func,
+ (unsigned short)
+ va_arg(args,unsigned int));
+ break;
+
+ case 2:
+ count += ConsoleDisplay<unsigned int,
+ ConsoleTraits::HEX>
+ ::display(output_func,
+ va_arg(args,unsigned int));
+ break;
+
+ case 3:
+ case 4:
+ count += ConsoleDisplay<unsigned long,
+ ConsoleTraits::HEX>
+ ::display(output_func,
+ va_arg(args,unsigned long));
+ break;
+ }
+ break;
+ }
+ case 's': // string
+ {
+ format = false;
+ count += ConsoleDisplay<char*>
+ ::display(output_func,
+ (char*) va_arg(args,void*));
+ break;
+ }
+ case 'p': // pointer
+ {
+ format = false;
+ count += ConsoleDisplay<char>
+ ::display(output_func,
+ '0');
+ count += ConsoleDisplay<char>
+ ::display(output_func,
+ 'x');
+ count += ConsoleDisplay<unsigned long,
+ ConsoleTraits::HEX>
+ ::display(output_func,
+ va_arg(args,unsigned long));
+ break;
+ }
+ }
+ else
+ count += ConsoleDisplay<char>::display(output_func, *fmt_str);
+
+ fmt_str++;
+ }
+
+ return count;
+ }
+
+};
+
+#endif
OpenPOWER on IntegriCloud