From 706243ac48cf646d503a3f1ec9e6a28c916694bd Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Sat, 5 Mar 2011 10:01:45 -0600 Subject: Merge of PowerHAL project up to commit: dd45c30bd53d8e6c123165b83842d08117558a3c --- src/include/arch/ppc.H | 174 ++++++++++++++++++++++ src/include/assert.h | 31 ++++ src/include/builtins.h | 95 ++++++++++++ src/include/kernel/console.H | 3 +- src/include/kernel/cpu.H | 7 +- src/include/kernel/ppcarch.H | 87 ----------- src/include/kernel/ppcconsts.S | 2 + src/include/kernel/timemgr.H | 4 +- src/include/math.h | 23 +++ src/include/new | 9 ++ src/include/stddef.h | 2 + src/include/stdint.h | 5 + src/include/stdio.h | 16 ++ src/include/string.h | 7 +- src/include/sys/msg.h | 7 +- src/include/sys/vfs.h | 7 +- src/include/util/functor.H | 100 +++++++++++++ src/include/util/locked/list.H | 1 + src/include/util/sprintf.H | 323 +++++++++++++++++++++++++++++++++++++++++ 19 files changed, 805 insertions(+), 98 deletions(-) create mode 100644 src/include/arch/ppc.H create mode 100644 src/include/assert.h create mode 100644 src/include/builtins.h delete mode 100644 src/include/kernel/ppcarch.H create mode 100644 src/include/math.h create mode 100755 src/include/new create mode 100644 src/include/stdio.h mode change 100644 => 100755 src/include/string.h create mode 100644 src/include/util/functor.H create mode 100644 src/include/util/sprintf.H (limited to 'src/include') 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 +#include + +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 + +#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 + +#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 #include +#include -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 -#include +#include +#include // 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 - -__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 -#include +#include #include #include @@ -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 +#include + +#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 old mode 100644 new mode 100755 index 30c878d65..af535832f --- 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 #include +#include #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 + +namespace Util +{ + template + class unary_functor + { + public: + typedef _ARG argument_type; + typedef _RESULT result_type; + + public: + virtual ~unary_functor() {}; + virtual result_type operator()(argument_type) = 0; + }; + + template + 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 + 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 + 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 + 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 + 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 + +}; + +#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 #include 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 +#include +#include + +class Console; + +namespace Util +{ + + class ConsoleTraits + { + public: + enum trait { NONE, HEX, DEC, }; + }; + + template + class ConsoleDisplay + { + public: + template + ALWAYS_INLINE + static size_t display(_F& c, _T value) { return 0; }; + }; + + template + class ConsoleDisplay + { + public: + template + 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 + { + public: + template + ALWAYS_INLINE + static size_t display(_F& c, char value) + { + c(value); + return 1; + } + }; + + template + class ConsoleDisplay<_T, ConsoleTraits::DEC> + { + public: + template + 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 + 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 + class ConsoleDisplay<_T, ConsoleTraits::HEX> + { + public: + template + ALWAYS_INLINE + static size_t display(_F& c, _T value) + { + size_t length = sizeof(_T) * 2; + subdisplay(c, value, length); + return length; + } + + template + 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 + 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::display(output_func, + '%'); + format = false; + } + else + { + format = true; + size = 2; + } + break; + } + case 'c': + { + format = false; + count += ConsoleDisplay + ::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 + ::display(output_func, + (char)va_arg(args,int)); + break; + + case 1: + count += ConsoleDisplay + ::display(output_func, + (short)va_arg(args,int)); + break; + + case 2: + count += ConsoleDisplay + ::display(output_func, + va_arg(args,int)); + break; + + case 3: + case 4: + count += ConsoleDisplay + ::display(output_func, + va_arg(args,long)); + break; + } + break; + } + case 'u': // unsigned decimal + { + format = false; + switch(size) + { + case 0: + count += ConsoleDisplay + ::display(output_func, + (unsigned char) + va_arg(args,unsigned int)); + break; + + case 1: + count += ConsoleDisplay + ::display(output_func, + (unsigned short) + va_arg(args,unsigned int)); + break; + + case 2: + count += ConsoleDisplay + ::display(output_func, + va_arg(args,unsigned int)); + break; + + case 3: + case 4: + count += ConsoleDisplay + ::display(output_func, + va_arg(args,unsigned long)); + break; + } + break; + } + case 'x': // unsigned hex + case 'X': + { + format = false; + switch(size) + { + case 0: + count += ConsoleDisplay + ::display(output_func, + (unsigned char) + va_arg(args,unsigned int)); + break; + + case 1: + count += ConsoleDisplay + ::display(output_func, + (unsigned short) + va_arg(args,unsigned int)); + break; + + case 2: + count += ConsoleDisplay + ::display(output_func, + va_arg(args,unsigned int)); + break; + + case 3: + case 4: + count += ConsoleDisplay + ::display(output_func, + va_arg(args,unsigned long)); + break; + } + break; + } + case 's': // string + { + format = false; + count += ConsoleDisplay + ::display(output_func, + (char*) va_arg(args,void*)); + break; + } + case 'p': // pointer + { + format = false; + count += ConsoleDisplay + ::display(output_func, + '0'); + count += ConsoleDisplay + ::display(output_func, + 'x'); + count += ConsoleDisplay + ::display(output_func, + va_arg(args,unsigned long)); + break; + } + } + else + count += ConsoleDisplay::display(output_func, *fmt_str); + + fmt_str++; + } + + return count; + } + +}; + +#endif -- cgit v1.2.1