| 1 | /*************************************************************** |
|---|
| 2 | ** |
|---|
| 3 | ** Broadcom Corp. Confidential |
|---|
| 4 | ** Copyright 1998-2000 Broadcom Corp. All Rights Reserved. |
|---|
| 5 | ** |
|---|
| 6 | ** THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED |
|---|
| 7 | ** SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM. |
|---|
| 8 | ** YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT |
|---|
| 9 | ** SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 10 | ** |
|---|
| 11 | ** File: ministd.c |
|---|
| 12 | ** Description: subset of standard c functions. |
|---|
| 13 | ****************************************************************/ |
|---|
| 14 | #include "ministd.h" |
|---|
| 15 | #include "serial.h" |
|---|
| 16 | #include "bcmmemmgr.h" |
|---|
| 17 | #include "bchp_hif_cpu_intr1.h" |
|---|
| 18 | #include "bchp_irq0.h" |
|---|
| 19 | #include "bkni_print.h" |
|---|
| 20 | |
|---|
| 21 | #if SUPPORT_DST_PLATFORM |
|---|
| 22 | bcm_heap_t *g_p_sdram_heap = NULL; |
|---|
| 23 | #else |
|---|
| 24 | static bcm_heap_t *g_p_sdram_heap = NULL; |
|---|
| 25 | #endif |
|---|
| 26 | |
|---|
| 27 | static bcm_heap_t g_sdram_heap; |
|---|
| 28 | extern unsigned int _end; |
|---|
| 29 | #ifdef ACB612 |
|---|
| 30 | /* some ACB612 boards have 256 MB DDR */ |
|---|
| 31 | #ifdef CONFIG_AOV_SDRAM_1G |
|---|
| 32 | #define SDRAM_SIZE (128 * 1024 * 1024) |
|---|
| 33 | #else |
|---|
| 34 | #define SDRAM_SIZE (256 * 1024 * 1024) |
|---|
| 35 | #endif |
|---|
| 36 | #else |
|---|
| 37 | #define SDRAM_SIZE (256 * 1024 * 1024) |
|---|
| 38 | #endif |
|---|
| 39 | #define do_div64_32(res, high, low, base) ({ \ |
|---|
| 40 | unsigned long __quot, __mod; \ |
|---|
| 41 | unsigned long __cf, __tmp, __tmp2, __i; \ |
|---|
| 42 | \ |
|---|
| 43 | __asm__(".set push\n\t" \ |
|---|
| 44 | ".set noat\n\t" \ |
|---|
| 45 | ".set noreorder\n\t" \ |
|---|
| 46 | "move %2, $0\n\t" \ |
|---|
| 47 | "move %3, $0\n\t" \ |
|---|
| 48 | "b 1f\n\t" \ |
|---|
| 49 | " li %4, 0x21\n" \ |
|---|
| 50 | "0:\n\t" \ |
|---|
| 51 | "sll $1, %0, 0x1\n\t" \ |
|---|
| 52 | "srl %3, %0, 0x1f\n\t" \ |
|---|
| 53 | "or %0, $1, %5\n\t" \ |
|---|
| 54 | "sll %1, %1, 0x1\n\t" \ |
|---|
| 55 | "sll %2, %2, 0x1\n" \ |
|---|
| 56 | "1:\n\t" \ |
|---|
| 57 | "bnez %3, 2f\n\t" \ |
|---|
| 58 | "sltu %5, %0, %z6\n\t" \ |
|---|
| 59 | "bnez %5, 3f\n\t" \ |
|---|
| 60 | "2:\n\t" \ |
|---|
| 61 | " addiu %4,%4,-1\n\t" \ |
|---|
| 62 | "subu %0, %0, %z6\n\t" \ |
|---|
| 63 | "addiu %2, %2, 1\n" \ |
|---|
| 64 | "3:\n\t" \ |
|---|
| 65 | "bnez %4, 0b\n\t" \ |
|---|
| 66 | " srl %5, %1, 0x1f\n\t" \ |
|---|
| 67 | ".set pop" \ |
|---|
| 68 | : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \ |
|---|
| 69 | "=&r" (__i), "=&r" (__tmp2) \ |
|---|
| 70 | : "Jr" (base), "0" (high), "1" (low)); \ |
|---|
| 71 | \ |
|---|
| 72 | (res) = __quot; \ |
|---|
| 73 | __mod; }) |
|---|
| 74 | |
|---|
| 75 | #if 1 /*defined(SDE_MIPS) || defined(__NEWLIB__) */ |
|---|
| 76 | #define do_div(n,base) ({ \ |
|---|
| 77 | int __res; \ |
|---|
| 78 | __res = ((unsigned long) (n)) % (unsigned) (base); \ |
|---|
| 79 | (n) = ((unsigned long) (n)) / (unsigned) (base); \ |
|---|
| 80 | __res; }) |
|---|
| 81 | |
|---|
| 82 | |
|---|
| 83 | #else |
|---|
| 84 | #define do_div(n, base) ({ \ |
|---|
| 85 | unsigned long long __quot; \ |
|---|
| 86 | unsigned long __upper, __low, __high, __mod; \ |
|---|
| 87 | \ |
|---|
| 88 | __quot = (n); \ |
|---|
| 89 | __high = __quot >> 32; \ |
|---|
| 90 | __low = __quot; \ |
|---|
| 91 | __upper = __high; \ |
|---|
| 92 | \ |
|---|
| 93 | if (__high) \ |
|---|
| 94 | __asm__("divu $0,%z2,%z3" \ |
|---|
| 95 | : "=h" (__upper), "=l" (__high) \ |
|---|
| 96 | : "Jr" (__high), "Jr" (base)); \ |
|---|
| 97 | \ |
|---|
| 98 | __mod = do_div64_32(__low, __upper, __low, base); \ |
|---|
| 99 | \ |
|---|
| 100 | __quot = __high; \ |
|---|
| 101 | __quot = __quot << 32 | __low; \ |
|---|
| 102 | (n) = __quot; \ |
|---|
| 103 | __mod; }) |
|---|
| 104 | #endif |
|---|
| 105 | |
|---|
| 106 | static unsigned |
|---|
| 107 | b_div64_32(unsigned *res, unsigned high, unsigned low, unsigned base) |
|---|
| 108 | { |
|---|
| 109 | unsigned res_; |
|---|
| 110 | unsigned rem; |
|---|
| 111 | rem = do_div64_32(res_, high, low, base); |
|---|
| 112 | *res = res_; |
|---|
| 113 | return rem; |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | /* __udivdi3 calls are generated by gcc due long long division done in the bvdc_window_priv.c PI files |
|---|
| 117 | * to avoid problems linking this function is supplied here |
|---|
| 118 | */ |
|---|
| 119 | |
|---|
| 120 | #if 1 |
|---|
| 121 | unsigned long long __udivdi3(unsigned long long n, unsigned long long d) |
|---|
| 122 | { |
|---|
| 123 | long mod; |
|---|
| 124 | if (d & ~0xffffffff) |
|---|
| 125 | { |
|---|
| 126 | printf("Need true 64-bit/64-bit division\n"); |
|---|
| 127 | __asm__("sdbbp"); |
|---|
| 128 | } |
|---|
| 129 | mod = do_div(n, (uint32_t)d); |
|---|
| 130 | return n; |
|---|
| 131 | } |
|---|
| 132 | #endif |
|---|
| 133 | |
|---|
| 134 | #ifndef __NEWLIB__ |
|---|
| 135 | |
|---|
| 136 | #ifndef va_arg |
|---|
| 137 | #ifndef _VALIST |
|---|
| 138 | #define _VALIST |
|---|
| 139 | typedef char *va_list; |
|---|
| 140 | #endif /* _VALIST */ |
|---|
| 141 | |
|---|
| 142 | |
|---|
| 143 | /* |
|---|
| 144 | * Storage alignment properties |
|---|
| 145 | */ |
|---|
| 146 | |
|---|
| 147 | #define _AUPBND (sizeof (int) - 1) |
|---|
| 148 | #define _ADNBND (sizeof (int) - 1) |
|---|
| 149 | |
|---|
| 150 | /* |
|---|
| 151 | * Variable argument list macro definitions |
|---|
| 152 | */ |
|---|
| 153 | |
|---|
| 154 | #define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) |
|---|
| 155 | #define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) |
|---|
| 156 | #define va_end(ap) (void) 0 |
|---|
| 157 | #define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) |
|---|
| 158 | |
|---|
| 159 | #endif /* va_arg */ |
|---|
| 160 | |
|---|
| 161 | /**************************************************************** |
|---|
| 162 | * put_c() |
|---|
| 163 | ****************************************************************/ |
|---|
| 164 | static inline void put_c(char ch) |
|---|
| 165 | { |
|---|
| 166 | #ifdef CONFIG_ENABLE_UART |
|---|
| 167 | serial_putc(CONSOLE_UART, ch); |
|---|
| 168 | #endif |
|---|
| 169 | |
|---|
| 170 | #ifdef CONFIG_ENABLE_FAST_UART |
|---|
| 171 | SW_EMU_FAST_UART_OUT(ch); |
|---|
| 172 | #endif |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | /**************************************************************** |
|---|
| 176 | * put_str() |
|---|
| 177 | ****************************************************************/ |
|---|
| 178 | static void put_str(char *s) |
|---|
| 179 | { |
|---|
| 180 | char ch; |
|---|
| 181 | |
|---|
| 182 | while ('\0'!=(ch=*s++)) { |
|---|
| 183 | if (ch=='\n') { |
|---|
| 184 | put_c('\r'); |
|---|
| 185 | } |
|---|
| 186 | put_c(ch); |
|---|
| 187 | } |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | /**************************************************************** |
|---|
| 191 | * Other C-Libs that might be provided by OS. |
|---|
| 192 | ****************************************************************/ |
|---|
| 193 | #ifndef TAB |
|---|
| 194 | #define TAB_CH 0x09 |
|---|
| 195 | #endif |
|---|
| 196 | |
|---|
| 197 | #ifndef SPACE |
|---|
| 198 | #define SPACE_CH 0x20 |
|---|
| 199 | #endif |
|---|
| 200 | |
|---|
| 201 | #ifndef SkipWhiteSpace |
|---|
| 202 | #define SkipWhiteSpace(z) while (*z == TAB_CH || *z == SPACE_CH) z++; |
|---|
| 203 | #endif |
|---|
| 204 | |
|---|
| 205 | #ifndef toupper |
|---|
| 206 | #define toupper(x) (x&0xDF) |
|---|
| 207 | #endif |
|---|
| 208 | |
|---|
| 209 | #ifndef isnum |
|---|
| 210 | #define isnum(x) (x >= '0' && x <= '9') ? 1 : 0 |
|---|
| 211 | #endif |
|---|
| 212 | |
|---|
| 213 | #ifndef ishexnum |
|---|
| 214 | #define ishexnum(x) ((x >= '0' && x <= '9') || ((x & 0xDF) >= 'A' && (x & 0xDF) <= 'F')) ? 1 : 0 |
|---|
| 215 | #endif |
|---|
| 216 | |
|---|
| 217 | int sscanf (char* buf, char* fmt, unsigned int * val) |
|---|
| 218 | { |
|---|
| 219 | int valid; |
|---|
| 220 | unsigned int result, base; |
|---|
| 221 | char * pbuf; |
|---|
| 222 | |
|---|
| 223 | if (!buf || !fmt || !val) |
|---|
| 224 | return 0; |
|---|
| 225 | |
|---|
| 226 | SkipWhiteSpace(fmt); |
|---|
| 227 | SkipWhiteSpace(buf); |
|---|
| 228 | |
|---|
| 229 | pbuf = buf; |
|---|
| 230 | |
|---|
| 231 | if (*fmt != '%') |
|---|
| 232 | return 0; |
|---|
| 233 | fmt++; |
|---|
| 234 | if (*fmt == 'x' || *fmt == 'X') |
|---|
| 235 | base = 16; |
|---|
| 236 | else if (*fmt == 'd' || *fmt == 'D') |
|---|
| 237 | base = 10; |
|---|
| 238 | else |
|---|
| 239 | return 0; |
|---|
| 240 | |
|---|
| 241 | for (valid=0,result=0,pbuf=buf; ishexnum(*pbuf); pbuf++) |
|---|
| 242 | { |
|---|
| 243 | result *= base; |
|---|
| 244 | if (isnum (*pbuf)) |
|---|
| 245 | result += (unsigned long) (*pbuf - 0x30); |
|---|
| 246 | else if (base == 16) |
|---|
| 247 | result += (unsigned long) (toupper(*pbuf) - 0x37); |
|---|
| 248 | else |
|---|
| 249 | return 0; |
|---|
| 250 | valid=1; |
|---|
| 251 | } |
|---|
| 252 | if (valid) |
|---|
| 253 | *val = result; |
|---|
| 254 | |
|---|
| 255 | return valid; |
|---|
| 256 | } |
|---|
| 257 | #if 0 |
|---|
| 258 | /**************************************************************** |
|---|
| 259 | * memset() |
|---|
| 260 | ****************************************************************/ |
|---|
| 261 | void *memset(void *dest,int c,size_t count) |
|---|
| 262 | { |
|---|
| 263 | uint8_t *d = dest; |
|---|
| 264 | for(;count>0;count--) { |
|---|
| 265 | *d++ = c; |
|---|
| 266 | } |
|---|
| 267 | return dest; |
|---|
| 268 | } |
|---|
| 269 | #endif |
|---|
| 270 | #if 0 |
|---|
| 271 | /* using fast assembly version */ |
|---|
| 272 | /**************************************************************** |
|---|
| 273 | * memcpy() |
|---|
| 274 | ****************************************************************/ |
|---|
| 275 | void *memcpy(void *dest,const void *src,size_t count) |
|---|
| 276 | { |
|---|
| 277 | char *d,*s; |
|---|
| 278 | int cnt; |
|---|
| 279 | |
|---|
| 280 | s = (char*)src; |
|---|
| 281 | d = (char*)dest; |
|---|
| 282 | cnt = count; |
|---|
| 283 | while(cnt--) |
|---|
| 284 | *d++ = *s++; |
|---|
| 285 | |
|---|
| 286 | return dest; |
|---|
| 287 | } |
|---|
| 288 | #endif |
|---|
| 289 | |
|---|
| 290 | int memcmp(const void *s1,const void *s2, size_t count) |
|---|
| 291 | { |
|---|
| 292 | const uint8_t *b1= s1; |
|---|
| 293 | const uint8_t *b2= s2; |
|---|
| 294 | for(;count>0;count--) { |
|---|
| 295 | int diff = *b1-*b2; |
|---|
| 296 | if (diff) { |
|---|
| 297 | return diff; |
|---|
| 298 | } |
|---|
| 299 | ++b1;++b2; |
|---|
| 300 | } |
|---|
| 301 | return 0; |
|---|
| 302 | } |
|---|
| 303 | |
|---|
| 304 | size_t strlen (const char * str) |
|---|
| 305 | { |
|---|
| 306 | const char *s = str; |
|---|
| 307 | for(;*s;++s) { |
|---|
| 308 | } |
|---|
| 309 | return s-str; |
|---|
| 310 | } |
|---|
| 311 | |
|---|
| 312 | char* strcpy ( char * dst,const char * src) |
|---|
| 313 | { |
|---|
| 314 | char *d1=dst; |
|---|
| 315 | |
|---|
| 316 | while('\0' != (*d1=*src) ) { |
|---|
| 317 | d1++;src++; |
|---|
| 318 | } |
|---|
| 319 | return dst; |
|---|
| 320 | } |
|---|
| 321 | char *strncpy(char *dest, const char *src, size_t n) |
|---|
| 322 | { |
|---|
| 323 | char *d1=dest; |
|---|
| 324 | |
|---|
| 325 | while('\0' != (*d1=*src) ) { |
|---|
| 326 | d1++;src++; |
|---|
| 327 | if (d1 >= (dest + n)) |
|---|
| 328 | { |
|---|
| 329 | break; |
|---|
| 330 | } |
|---|
| 331 | } |
|---|
| 332 | return dest; |
|---|
| 333 | } |
|---|
| 334 | |
|---|
| 335 | int |
|---|
| 336 | strcmp(const char *s1_, const char *s2_) |
|---|
| 337 | { |
|---|
| 338 | const uint8_t *s1 = s1_; |
|---|
| 339 | const uint8_t *s2 = s2_; |
|---|
| 340 | |
|---|
| 341 | for(;;) { |
|---|
| 342 | int ch1 = *s1++; |
|---|
| 343 | int diff = ch1 - *s2++; |
|---|
| 344 | if (diff || /* strings are different */ |
|---|
| 345 | ch1 == 0 /* end of string reached */ |
|---|
| 346 | ) { |
|---|
| 347 | return diff; /* return difference */ |
|---|
| 348 | } |
|---|
| 349 | } |
|---|
| 350 | } |
|---|
| 351 | |
|---|
| 352 | int |
|---|
| 353 | strncmp(const char *s1, const char *s2, int n) |
|---|
| 354 | { |
|---|
| 355 | if (n == 0) |
|---|
| 356 | return (0); |
|---|
| 357 | |
|---|
| 358 | do |
|---|
| 359 | { |
|---|
| 360 | if (*s1 != *s2++) |
|---|
| 361 | return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); |
|---|
| 362 | if (*s1++ == 0) |
|---|
| 363 | break; |
|---|
| 364 | } while (--n != 0); |
|---|
| 365 | return (0); |
|---|
| 366 | } |
|---|
| 367 | |
|---|
| 368 | |
|---|
| 369 | #define _U 0x01 /* upper */ |
|---|
| 370 | #define _L 0x02 /* lower */ |
|---|
| 371 | #define _D 0x04 /* digit */ |
|---|
| 372 | #define _C 0x08 /* cntrl */ |
|---|
| 373 | #define _P 0x10 /* punct */ |
|---|
| 374 | #define _S 0x20 /* white space (space/lf/tab) */ |
|---|
| 375 | #define _X 0x40 /* hex digit */ |
|---|
| 376 | #define _SP 0x80 /* hard space (0x20) */ |
|---|
| 377 | |
|---|
| 378 | const unsigned char _ctype[] = { |
|---|
| 379 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ |
|---|
| 380 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ |
|---|
| 381 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ |
|---|
| 382 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ |
|---|
| 383 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ |
|---|
| 384 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ |
|---|
| 385 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ |
|---|
| 386 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ |
|---|
| 387 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ |
|---|
| 388 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ |
|---|
| 389 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ |
|---|
| 390 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ |
|---|
| 391 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ |
|---|
| 392 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ |
|---|
| 393 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ |
|---|
| 394 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ |
|---|
| 395 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ |
|---|
| 396 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ |
|---|
| 397 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ |
|---|
| 398 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ |
|---|
| 399 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ |
|---|
| 400 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ |
|---|
| 401 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ |
|---|
| 402 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ |
|---|
| 403 | |
|---|
| 404 | |
|---|
| 405 | #define __ismask(x) (_ctype[(int)(unsigned char)(x)]) |
|---|
| 406 | |
|---|
| 407 | #define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) |
|---|
| 408 | #define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) |
|---|
| 409 | #define iscntrl(c) ((__ismask(c)&(_C)) != 0) |
|---|
| 410 | #define isdigit(c) ((__ismask(c)&(_D)) != 0) |
|---|
| 411 | #define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) |
|---|
| 412 | #define islower(c) ((__ismask(c)&(_L)) != 0) |
|---|
| 413 | #define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) |
|---|
| 414 | #define ispunct(c) ((__ismask(c)&(_P)) != 0) |
|---|
| 415 | #define isspace(c) ((__ismask(c)&(_S)) != 0) |
|---|
| 416 | #define isupper(c) ((__ismask(c)&(_U)) != 0) |
|---|
| 417 | #define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) |
|---|
| 418 | |
|---|
| 419 | #define isascii(c) (((unsigned char)(c))<=0x7f) |
|---|
| 420 | #define toascii(c) (((unsigned char)(c))&0x7f) |
|---|
| 421 | |
|---|
| 422 | static inline unsigned char __tolower(unsigned char c) |
|---|
| 423 | { |
|---|
| 424 | if (isupper(c)) |
|---|
| 425 | c -= 'A'-'a'; |
|---|
| 426 | return c; |
|---|
| 427 | } |
|---|
| 428 | |
|---|
| 429 | static inline unsigned char __toupper(unsigned char c) |
|---|
| 430 | { |
|---|
| 431 | if (islower(c)) |
|---|
| 432 | c -= 'a'-'A'; |
|---|
| 433 | return c; |
|---|
| 434 | } |
|---|
| 435 | |
|---|
| 436 | #define tolower(c) __tolower(c) |
|---|
| 437 | #ifdef toupper |
|---|
| 438 | #undef toupper |
|---|
| 439 | #endif |
|---|
| 440 | #define toupper(c) __toupper(c) |
|---|
| 441 | |
|---|
| 442 | int strcasecmp(const char *s1_, const char *s2_) |
|---|
| 443 | { |
|---|
| 444 | const uint8_t *s1 = s1_; |
|---|
| 445 | const uint8_t *s2 = s2_; |
|---|
| 446 | |
|---|
| 447 | for(;;) { |
|---|
| 448 | int ch1 = tolower(*s1++); |
|---|
| 449 | int diff = ch1 - tolower(*s2++); |
|---|
| 450 | if (diff || /* strings are different */ |
|---|
| 451 | ch1 == 0 /* end of string reached */ |
|---|
| 452 | ) { |
|---|
| 453 | return diff; /* return difference */ |
|---|
| 454 | } |
|---|
| 455 | } |
|---|
| 456 | } |
|---|
| 457 | char *getenv(const char *name) |
|---|
| 458 | { |
|---|
| 459 | return NULL; |
|---|
| 460 | } |
|---|
| 461 | |
|---|
| 462 | int atoi(const char **s) |
|---|
| 463 | { |
|---|
| 464 | int i=0; |
|---|
| 465 | |
|---|
| 466 | while (isdigit(**s)) |
|---|
| 467 | i = i*10 + *((*s)++) - '0'; |
|---|
| 468 | return i; |
|---|
| 469 | } |
|---|
| 470 | #if 0 |
|---|
| 471 | /** |
|---|
| 472 | * simple_strtoul - convert a string to an unsigned long |
|---|
| 473 | * @cp: The start of the string |
|---|
| 474 | * @endp: A pointer to the end of the parsed string will be placed here |
|---|
| 475 | * @base: The number base to use |
|---|
| 476 | */ |
|---|
| 477 | static unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) |
|---|
| 478 | { |
|---|
| 479 | unsigned long result = 0,value; |
|---|
| 480 | |
|---|
| 481 | if (!base) { |
|---|
| 482 | base = 10; |
|---|
| 483 | if (*cp == '0') { |
|---|
| 484 | base = 8; |
|---|
| 485 | cp++; |
|---|
| 486 | if ((*cp == 'x') && isxdigit(cp[1])) { |
|---|
| 487 | cp++; |
|---|
| 488 | base = 16; |
|---|
| 489 | } |
|---|
| 490 | } |
|---|
| 491 | } |
|---|
| 492 | while (isxdigit(*cp) && |
|---|
| 493 | (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { |
|---|
| 494 | result = result*base + value; |
|---|
| 495 | cp++; |
|---|
| 496 | } |
|---|
| 497 | if (endp) |
|---|
| 498 | *endp = (char *)cp; |
|---|
| 499 | return result; |
|---|
| 500 | } |
|---|
| 501 | |
|---|
| 502 | /** |
|---|
| 503 | * simple_strtol - convert a string to a signed long |
|---|
| 504 | * @cp: The start of the string |
|---|
| 505 | * @endp: A pointer to the end of the parsed string will be placed here |
|---|
| 506 | * @base: The number base to use |
|---|
| 507 | */ |
|---|
| 508 | static long simple_strtol(const char *cp,char **endp,unsigned int base) |
|---|
| 509 | { |
|---|
| 510 | if(*cp=='-') |
|---|
| 511 | return -simple_strtoul(cp+1,endp,base); |
|---|
| 512 | return simple_strtoul(cp,endp,base); |
|---|
| 513 | } |
|---|
| 514 | |
|---|
| 515 | /** |
|---|
| 516 | * simple_strtoull - convert a string to an unsigned long long |
|---|
| 517 | * @cp: The start of the string |
|---|
| 518 | * @endp: A pointer to the end of the parsed string will be placed here |
|---|
| 519 | * @base: The number base to use |
|---|
| 520 | */ |
|---|
| 521 | static unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) |
|---|
| 522 | { |
|---|
| 523 | unsigned long long result = 0,value; |
|---|
| 524 | |
|---|
| 525 | if (!base) { |
|---|
| 526 | base = 10; |
|---|
| 527 | if (*cp == '0') { |
|---|
| 528 | base = 8; |
|---|
| 529 | cp++; |
|---|
| 530 | if ((*cp == 'x') && isxdigit(cp[1])) { |
|---|
| 531 | cp++; |
|---|
| 532 | base = 16; |
|---|
| 533 | } |
|---|
| 534 | } |
|---|
| 535 | } |
|---|
| 536 | while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) |
|---|
| 537 | ? toupper(*cp) : *cp)-'A'+10) < base) { |
|---|
| 538 | result = result*base + value; |
|---|
| 539 | cp++; |
|---|
| 540 | } |
|---|
| 541 | if (endp) |
|---|
| 542 | *endp = (char *)cp; |
|---|
| 543 | return result; |
|---|
| 544 | } |
|---|
| 545 | |
|---|
| 546 | /** |
|---|
| 547 | * simple_strtoll - convert a string to a signed long long |
|---|
| 548 | * @cp: The start of the string |
|---|
| 549 | * @endp: A pointer to the end of the parsed string will be placed here |
|---|
| 550 | * @base: The number base to use |
|---|
| 551 | */ |
|---|
| 552 | static long long simple_strtoll(const char *cp,char **endp,unsigned int base) |
|---|
| 553 | { |
|---|
| 554 | if(*cp=='-') |
|---|
| 555 | return -simple_strtoull(cp+1,endp,base); |
|---|
| 556 | return simple_strtoull(cp,endp,base); |
|---|
| 557 | } |
|---|
| 558 | #endif |
|---|
| 559 | |
|---|
| 560 | static int skip_atoi(const char **s) |
|---|
| 561 | { |
|---|
| 562 | int i=0; |
|---|
| 563 | |
|---|
| 564 | while (isdigit(**s)) |
|---|
| 565 | i = i*10 + *((*s)++) - '0'; |
|---|
| 566 | return i; |
|---|
| 567 | } |
|---|
| 568 | #define ZEROPAD 1 /* pad with zero */ |
|---|
| 569 | #define SIGN 2 /* unsigned/signed long */ |
|---|
| 570 | #define PLUS 4 /* show plus */ |
|---|
| 571 | #define SPACE 8 /* space if plus */ |
|---|
| 572 | #define LEFT 16 /* left justified */ |
|---|
| 573 | #define SPECIAL 32 /* 0x */ |
|---|
| 574 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ |
|---|
| 575 | |
|---|
| 576 | /* |
|---|
| 577 | * No traps on overflows for any of these... |
|---|
| 578 | */ |
|---|
| 579 | const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
|---|
| 580 | const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
|---|
| 581 | |
|---|
| 582 | static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type) |
|---|
| 583 | { |
|---|
| 584 | char c,sign,tmp[66]; |
|---|
| 585 | const char *digits; |
|---|
| 586 | int i; |
|---|
| 587 | |
|---|
| 588 | digits = (type & LARGE) ? large_digits : small_digits; |
|---|
| 589 | if (type & LEFT) |
|---|
| 590 | type &= ~ZEROPAD; |
|---|
| 591 | if (base < 2 || base > 36) |
|---|
| 592 | return 0; |
|---|
| 593 | c = (type & ZEROPAD) ? '0' : ' '; |
|---|
| 594 | sign = 0; |
|---|
| 595 | if (type & SIGN) { |
|---|
| 596 | if (num < 0) { |
|---|
| 597 | sign = '-'; |
|---|
| 598 | num = -num; |
|---|
| 599 | size--; |
|---|
| 600 | } else if (type & PLUS) { |
|---|
| 601 | sign = '+'; |
|---|
| 602 | size--; |
|---|
| 603 | } else if (type & SPACE) { |
|---|
| 604 | sign = ' '; |
|---|
| 605 | size--; |
|---|
| 606 | } |
|---|
| 607 | } |
|---|
| 608 | if (type & SPECIAL) { |
|---|
| 609 | if (base == 16) |
|---|
| 610 | size -= 2; |
|---|
| 611 | else if (base == 8) |
|---|
| 612 | size--; |
|---|
| 613 | } |
|---|
| 614 | i = 0; |
|---|
| 615 | if (num == 0) |
|---|
| 616 | tmp[i++]='0'; |
|---|
| 617 | else while (num != 0) |
|---|
| 618 | tmp[i++] = digits[do_div(num,base)]; |
|---|
| 619 | if (i > precision) |
|---|
| 620 | precision = i; |
|---|
| 621 | size -= precision; |
|---|
| 622 | if (!(type&(ZEROPAD+LEFT))) { |
|---|
| 623 | while(size-->0) { |
|---|
| 624 | if (buf <= end) |
|---|
| 625 | *buf = ' '; |
|---|
| 626 | ++buf; |
|---|
| 627 | } |
|---|
| 628 | } |
|---|
| 629 | if (sign) { |
|---|
| 630 | if (buf <= end) |
|---|
| 631 | *buf = sign; |
|---|
| 632 | ++buf; |
|---|
| 633 | } |
|---|
| 634 | if (type & SPECIAL) { |
|---|
| 635 | if (base==8) { |
|---|
| 636 | if (buf <= end) |
|---|
| 637 | *buf = '0'; |
|---|
| 638 | ++buf; |
|---|
| 639 | } else if (base==16) { |
|---|
| 640 | if (buf <= end) |
|---|
| 641 | *buf = '0'; |
|---|
| 642 | ++buf; |
|---|
| 643 | if (buf <= end) |
|---|
| 644 | *buf = digits[33]; |
|---|
| 645 | ++buf; |
|---|
| 646 | } |
|---|
| 647 | } |
|---|
| 648 | if (!(type & LEFT)) { |
|---|
| 649 | while (size-- > 0) { |
|---|
| 650 | if (buf <= end) |
|---|
| 651 | *buf = c; |
|---|
| 652 | ++buf; |
|---|
| 653 | } |
|---|
| 654 | } |
|---|
| 655 | while (i < precision--) { |
|---|
| 656 | if (buf <= end) |
|---|
| 657 | *buf = '0'; |
|---|
| 658 | ++buf; |
|---|
| 659 | } |
|---|
| 660 | while (i-- > 0) { |
|---|
| 661 | if (buf <= end) |
|---|
| 662 | *buf = tmp[i]; |
|---|
| 663 | ++buf; |
|---|
| 664 | } |
|---|
| 665 | while (size-- > 0) { |
|---|
| 666 | if (buf <= end) |
|---|
| 667 | *buf = ' '; |
|---|
| 668 | ++buf; |
|---|
| 669 | } |
|---|
| 670 | return buf; |
|---|
| 671 | } |
|---|
| 672 | |
|---|
| 673 | |
|---|
| 674 | /** |
|---|
| 675 | * vsnprintf - Format a string and place it in a buffer |
|---|
| 676 | * @buf: The buffer to place the result into |
|---|
| 677 | * @size: The size of the buffer, including the trailing null space |
|---|
| 678 | * @fmt: The format string to use |
|---|
| 679 | * @args: Arguments for the format string |
|---|
| 680 | * |
|---|
| 681 | * Call this function if you are already dealing with a va_list. |
|---|
| 682 | * You probably want snprintf instead. |
|---|
| 683 | */ |
|---|
| 684 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) |
|---|
| 685 | { |
|---|
| 686 | int len; |
|---|
| 687 | unsigned long long num; |
|---|
| 688 | int i, base; |
|---|
| 689 | char *str, *end, c; |
|---|
| 690 | const char *s; |
|---|
| 691 | |
|---|
| 692 | int flags; /* flags to number() */ |
|---|
| 693 | |
|---|
| 694 | int field_width; /* width of output field */ |
|---|
| 695 | int precision; /* min. # of digits for integers; max |
|---|
| 696 | number of chars for from string */ |
|---|
| 697 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ |
|---|
| 698 | /* 'z' support added 23/7/1999 S.H. */ |
|---|
| 699 | /* 'z' changed to 'Z' --davidm 1/25/99 */ |
|---|
| 700 | |
|---|
| 701 | str = buf; |
|---|
| 702 | end = buf + size - 1; |
|---|
| 703 | |
|---|
| 704 | if (end < buf - 1) { |
|---|
| 705 | end = ((void *) -1); |
|---|
| 706 | size = end - buf + 1; |
|---|
| 707 | } |
|---|
| 708 | |
|---|
| 709 | for (; *fmt ; ++fmt) { |
|---|
| 710 | if (*fmt != '%') { |
|---|
| 711 | if (str <= end) |
|---|
| 712 | *str = *fmt; |
|---|
| 713 | ++str; |
|---|
| 714 | continue; |
|---|
| 715 | } |
|---|
| 716 | |
|---|
| 717 | /* process flags */ |
|---|
| 718 | flags = 0; |
|---|
| 719 | repeat: |
|---|
| 720 | ++fmt; /* this also skips first '%' */ |
|---|
| 721 | switch (*fmt) { |
|---|
| 722 | case '-': flags |= LEFT; goto repeat; |
|---|
| 723 | case '+': flags |= PLUS; goto repeat; |
|---|
| 724 | case ' ': flags |= SPACE; goto repeat; |
|---|
| 725 | case '#': flags |= SPECIAL; goto repeat; |
|---|
| 726 | case '0': flags |= ZEROPAD; goto repeat; |
|---|
| 727 | } |
|---|
| 728 | |
|---|
| 729 | /* get field width */ |
|---|
| 730 | field_width = -1; |
|---|
| 731 | if (isdigit(*fmt)) |
|---|
| 732 | field_width = skip_atoi(&fmt); |
|---|
| 733 | else if (*fmt == '*') { |
|---|
| 734 | ++fmt; |
|---|
| 735 | /* it's the next argument */ |
|---|
| 736 | field_width = va_arg(args, int); |
|---|
| 737 | if (field_width < 0) { |
|---|
| 738 | field_width = -field_width; |
|---|
| 739 | flags |= LEFT; |
|---|
| 740 | } |
|---|
| 741 | } |
|---|
| 742 | |
|---|
| 743 | /* get the precision */ |
|---|
| 744 | precision = -1; |
|---|
| 745 | if (*fmt == '.') { |
|---|
| 746 | ++fmt; |
|---|
| 747 | if (isdigit(*fmt)) |
|---|
| 748 | precision = skip_atoi(&fmt); |
|---|
| 749 | else if (*fmt == '*') { |
|---|
| 750 | ++fmt; |
|---|
| 751 | /* it's the next argument */ |
|---|
| 752 | precision = va_arg(args, int); |
|---|
| 753 | } |
|---|
| 754 | if (precision < 0) |
|---|
| 755 | precision = 0; |
|---|
| 756 | } |
|---|
| 757 | |
|---|
| 758 | /* get the conversion qualifier */ |
|---|
| 759 | qualifier = -1; |
|---|
| 760 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { |
|---|
| 761 | qualifier = *fmt; |
|---|
| 762 | ++fmt; |
|---|
| 763 | if (qualifier == 'l' && *fmt == 'l') { |
|---|
| 764 | qualifier = 'L'; |
|---|
| 765 | ++fmt; |
|---|
| 766 | } |
|---|
| 767 | } |
|---|
| 768 | |
|---|
| 769 | /* default base */ |
|---|
| 770 | base = 10; |
|---|
| 771 | |
|---|
| 772 | switch (*fmt) { |
|---|
| 773 | case 'c': |
|---|
| 774 | if (!(flags & LEFT)) { |
|---|
| 775 | while (--field_width > 0) { |
|---|
| 776 | if (str <= end) |
|---|
| 777 | *str = ' '; |
|---|
| 778 | ++str; |
|---|
| 779 | } |
|---|
| 780 | } |
|---|
| 781 | c = (unsigned char) va_arg(args, int); |
|---|
| 782 | if (str <= end) |
|---|
| 783 | *str = c; |
|---|
| 784 | ++str; |
|---|
| 785 | while (--field_width > 0) { |
|---|
| 786 | if (str <= end) |
|---|
| 787 | *str = ' '; |
|---|
| 788 | ++str; |
|---|
| 789 | } |
|---|
| 790 | continue; |
|---|
| 791 | |
|---|
| 792 | case 's': |
|---|
| 793 | s = va_arg(args, char *); |
|---|
| 794 | if (!s) |
|---|
| 795 | s = "<NULL>"; |
|---|
| 796 | |
|---|
| 797 | len = strnlen(s, precision); |
|---|
| 798 | len = strnlen(s, precision); |
|---|
| 799 | |
|---|
| 800 | if (!(flags & LEFT)) { |
|---|
| 801 | while (len < field_width--) { |
|---|
| 802 | if (str <= end) |
|---|
| 803 | *str = ' '; |
|---|
| 804 | ++str; |
|---|
| 805 | } |
|---|
| 806 | } |
|---|
| 807 | for (i = 0; i < len; ++i) { |
|---|
| 808 | if (str <= end) |
|---|
| 809 | *str = *s; |
|---|
| 810 | ++str; ++s; |
|---|
| 811 | } |
|---|
| 812 | while (len < field_width--) { |
|---|
| 813 | if (str <= end) |
|---|
| 814 | *str = ' '; |
|---|
| 815 | ++str; |
|---|
| 816 | } |
|---|
| 817 | continue; |
|---|
| 818 | |
|---|
| 819 | case 'p': |
|---|
| 820 | if (field_width == -1) { |
|---|
| 821 | field_width = 2*sizeof(void *); |
|---|
| 822 | flags |= ZEROPAD; |
|---|
| 823 | } |
|---|
| 824 | str = number(str, end, |
|---|
| 825 | (unsigned long) va_arg(args, void *), |
|---|
| 826 | 16, field_width, precision, flags); |
|---|
| 827 | continue; |
|---|
| 828 | |
|---|
| 829 | |
|---|
| 830 | case 'n': |
|---|
| 831 | /* FIXME: |
|---|
| 832 | * What does C99 say about the overflow case here? */ |
|---|
| 833 | if (qualifier == 'l') { |
|---|
| 834 | long * ip = va_arg(args, long *); |
|---|
| 835 | *ip = (str - buf); |
|---|
| 836 | } else if (qualifier == 'Z') { |
|---|
| 837 | size_t * ip = va_arg(args, size_t *); |
|---|
| 838 | *ip = (str - buf); |
|---|
| 839 | } else { |
|---|
| 840 | int * ip = va_arg(args, int *); |
|---|
| 841 | *ip = (str - buf); |
|---|
| 842 | } |
|---|
| 843 | continue; |
|---|
| 844 | |
|---|
| 845 | case '%': |
|---|
| 846 | if (str <= end) |
|---|
| 847 | *str = '%'; |
|---|
| 848 | ++str; |
|---|
| 849 | continue; |
|---|
| 850 | |
|---|
| 851 | /* integer number formats - set up the flags and "break" */ |
|---|
| 852 | case 'o': |
|---|
| 853 | base = 8; |
|---|
| 854 | break; |
|---|
| 855 | |
|---|
| 856 | case 'X': |
|---|
| 857 | flags |= LARGE; |
|---|
| 858 | case 'x': |
|---|
| 859 | base = 16; |
|---|
| 860 | break; |
|---|
| 861 | |
|---|
| 862 | case 'd': |
|---|
| 863 | case 'i': |
|---|
| 864 | flags |= SIGN; |
|---|
| 865 | case 'u': |
|---|
| 866 | break; |
|---|
| 867 | |
|---|
| 868 | default: |
|---|
| 869 | if (str <= end) |
|---|
| 870 | *str = '%'; |
|---|
| 871 | ++str; |
|---|
| 872 | if (*fmt) { |
|---|
| 873 | if (str <= end) |
|---|
| 874 | *str = *fmt; |
|---|
| 875 | ++str; |
|---|
| 876 | } else { |
|---|
| 877 | --fmt; |
|---|
| 878 | } |
|---|
| 879 | continue; |
|---|
| 880 | } |
|---|
| 881 | if (qualifier == 'L') |
|---|
| 882 | num = va_arg(args, long long); |
|---|
| 883 | else if (qualifier == 'l') { |
|---|
| 884 | num = va_arg(args, unsigned long); |
|---|
| 885 | if (flags & SIGN) |
|---|
| 886 | num = (signed long) num; |
|---|
| 887 | } else if (qualifier == 'Z') { |
|---|
| 888 | num = va_arg(args, size_t); |
|---|
| 889 | } else if (qualifier == 'h') { |
|---|
| 890 | num = (unsigned short) va_arg(args, int); |
|---|
| 891 | if (flags & SIGN) |
|---|
| 892 | num = (signed short) num; |
|---|
| 893 | } else { |
|---|
| 894 | num = va_arg(args, unsigned int); |
|---|
| 895 | if (flags & SIGN) |
|---|
| 896 | num = (signed int) num; |
|---|
| 897 | } |
|---|
| 898 | str = number(str, end, num, base, |
|---|
| 899 | field_width, precision, flags); |
|---|
| 900 | } |
|---|
| 901 | if (str <= end) |
|---|
| 902 | *str = '\0'; |
|---|
| 903 | else if (size > 0) |
|---|
| 904 | /* don't write out a null byte if the buf size is zero */ |
|---|
| 905 | *end = '\0'; |
|---|
| 906 | /* the trailing null byte doesn't count towards the total |
|---|
| 907 | * ++str; |
|---|
| 908 | */ |
|---|
| 909 | return str-buf; |
|---|
| 910 | } |
|---|
| 911 | |
|---|
| 912 | |
|---|
| 913 | int snprintf(char *str, size_t size, const char *format, ...) |
|---|
| 914 | { |
|---|
| 915 | va_list arg; |
|---|
| 916 | int rv; |
|---|
| 917 | va_start(arg, format); |
|---|
| 918 | rv = vsnprintf(str, size, format, arg); |
|---|
| 919 | va_end(arg); |
|---|
| 920 | return rv; |
|---|
| 921 | } |
|---|
| 922 | |
|---|
| 923 | #if 0 |
|---|
| 924 | |
|---|
| 925 | /* unused */ |
|---|
| 926 | int strcmpn ( const char * first,const char * last,int count) |
|---|
| 927 | { |
|---|
| 928 | if (!count) |
|---|
| 929 | return(0); |
|---|
| 930 | |
|---|
| 931 | while (--count && *first && *first == *last) |
|---|
| 932 | { |
|---|
| 933 | first++; |
|---|
| 934 | last++; |
|---|
| 935 | } |
|---|
| 936 | |
|---|
| 937 | return( *(unsigned char *)first - *(unsigned char *)last ); |
|---|
| 938 | } |
|---|
| 939 | |
|---|
| 940 | /* unused */ |
|---|
| 941 | int strcmpi(const char *dest,const char *src) |
|---|
| 942 | { |
|---|
| 943 | char dc,sc; |
|---|
| 944 | |
|---|
| 945 | while (*src && *dest) { |
|---|
| 946 | dc = __toupper(*dest); |
|---|
| 947 | sc = __toupper(*src); |
|---|
| 948 | if (dc < sc) return -1; |
|---|
| 949 | if (dc > sc) return 1; |
|---|
| 950 | dest++; |
|---|
| 951 | src++; |
|---|
| 952 | } |
|---|
| 953 | |
|---|
| 954 | if (*dest && !*src) return 1; |
|---|
| 955 | if (!*dest && *src) return -1; |
|---|
| 956 | return 0; |
|---|
| 957 | } |
|---|
| 958 | |
|---|
| 959 | #endif |
|---|
| 960 | |
|---|
| 961 | size_t strnlen(const char * s, size_t count) |
|---|
| 962 | { |
|---|
| 963 | const char *sc; |
|---|
| 964 | |
|---|
| 965 | for (sc = s; count-- && *sc != '\0'; ++sc) |
|---|
| 966 | /* nothing */; |
|---|
| 967 | return sc - s; |
|---|
| 968 | } |
|---|
| 969 | |
|---|
| 970 | int perror(const char *str) |
|---|
| 971 | { |
|---|
| 972 | printf(str); printf("\n"); |
|---|
| 973 | return 0; |
|---|
| 974 | } |
|---|
| 975 | |
|---|
| 976 | |
|---|
| 977 | |
|---|
| 978 | /****************************************************************************** |
|---|
| 979 | * INPUTS: none. |
|---|
| 980 | * OUTPUTS: tv - structure containing the current seconds and microseconds. |
|---|
| 981 | * RETURNS: non-zero on failure. |
|---|
| 982 | * FUNCTION: Return the current seconds and microseconds. |
|---|
| 983 | ******************************************************************************/ |
|---|
| 984 | void gettimeofday(b_timeval *tv) |
|---|
| 985 | { |
|---|
| 986 | b_clock clock; |
|---|
| 987 | long long usec_ticks; |
|---|
| 988 | |
|---|
| 989 | /* get running clock */ |
|---|
| 990 | bos_getclock(&clock); |
|---|
| 991 | if(clock.clock_freq>0) { |
|---|
| 992 | usec_ticks = b_div64_32(&tv->tv_sec, clock.clock_hi, clock.clock_low, clock.clock_freq); |
|---|
| 993 | usec_ticks *= (1000000/64); /* scale usec ticks */ |
|---|
| 994 | b_div64_32(&tv->tv_usec, usec_ticks>>32, usec_ticks, (clock.clock_freq/64)); |
|---|
| 995 | } else { |
|---|
| 996 | tv->tv_usec = 0; |
|---|
| 997 | tv->tv_sec = 0; |
|---|
| 998 | } |
|---|
| 999 | return; |
|---|
| 1000 | } |
|---|
| 1001 | |
|---|
| 1002 | |
|---|
| 1003 | |
|---|
| 1004 | |
|---|
| 1005 | #if !SUPPORT_DST_PLATFORM |
|---|
| 1006 | /* in dst platform, we need this function in DHL_OS_GetChar impl. so, make it public. */ |
|---|
| 1007 | static inline |
|---|
| 1008 | #endif |
|---|
| 1009 | int console_getch(void) |
|---|
| 1010 | { |
|---|
| 1011 | volatile UartChannel *uart; |
|---|
| 1012 | |
|---|
| 1013 | #if (BCHP_CHIP!=7550) && ( (BCHP_CHIP!=7552)) |
|---|
| 1014 | unsigned int event; |
|---|
| 1015 | |
|---|
| 1016 | if(s_console) { |
|---|
| 1017 | uart = s_console->uart; |
|---|
| 1018 | uart->rxstat |= RXINTEN; |
|---|
| 1019 | event = (unsigned int)bos_pend_event(s_console->rx.rx_queue,CONSOLE_TIMEOUT); |
|---|
| 1020 | } else { |
|---|
| 1021 | uart = CONSOLE_UART; |
|---|
| 1022 | } |
|---|
| 1023 | #else |
|---|
| 1024 | uart = CONSOLE_UART; |
|---|
| 1025 | #endif |
|---|
| 1026 | return serial_getc(uart, false); /* don't block */ |
|---|
| 1027 | } |
|---|
| 1028 | |
|---|
| 1029 | static int vprintf_poll(const char *format, va_list ap) |
|---|
| 1030 | { |
|---|
| 1031 | static char stdout_buf[128]; /* keep it small */ |
|---|
| 1032 | int rv; |
|---|
| 1033 | rv = vsnprintf(stdout_buf, sizeof(stdout_buf), format, ap); |
|---|
| 1034 | if (rv>0) { |
|---|
| 1035 | put_str(stdout_buf); |
|---|
| 1036 | } |
|---|
| 1037 | return rv; |
|---|
| 1038 | } |
|---|
| 1039 | |
|---|
| 1040 | int printf(const char *format, ...) |
|---|
| 1041 | { |
|---|
| 1042 | int rv = 0; |
|---|
| 1043 | va_list arg; |
|---|
| 1044 | |
|---|
| 1045 | va_start(arg, format); |
|---|
| 1046 | #if 1 |
|---|
| 1047 | rv = BKNI_Print_Vprintf(format, arg); |
|---|
| 1048 | #else |
|---|
| 1049 | #if (BCHP_CHIP!=7550) && (BCHP_CHIP!=7552) |
|---|
| 1050 | if (s_console) { |
|---|
| 1051 | rv = vprintf_console(s_console, format, arg); |
|---|
| 1052 | } else { |
|---|
| 1053 | rv = vprintf_poll(format, arg); |
|---|
| 1054 | } |
|---|
| 1055 | #else |
|---|
| 1056 | rv = vprintf_poll(format, arg); |
|---|
| 1057 | #endif |
|---|
| 1058 | #endif |
|---|
| 1059 | va_end(arg); |
|---|
| 1060 | return rv; |
|---|
| 1061 | } |
|---|
| 1062 | |
|---|
| 1063 | int vprintf(const char *format, va_list arg) |
|---|
| 1064 | { |
|---|
| 1065 | int rv = 0; |
|---|
| 1066 | rv = vprintf_poll(format, arg); |
|---|
| 1067 | return rv; |
|---|
| 1068 | } |
|---|
| 1069 | |
|---|
| 1070 | int getchar(void) |
|---|
| 1071 | { |
|---|
| 1072 | #ifdef CONFIG_GP |
|---|
| 1073 | int ch = -1; |
|---|
| 1074 | int last_ch = -1; |
|---|
| 1075 | #else |
|---|
| 1076 | char ch = 0; |
|---|
| 1077 | char last_ch = 0; |
|---|
| 1078 | #endif |
|---|
| 1079 | do |
|---|
| 1080 | { |
|---|
| 1081 | #ifdef CONFIG_GP |
|---|
| 1082 | if (ch != -1) |
|---|
| 1083 | #else |
|---|
| 1084 | if (ch != 0) |
|---|
| 1085 | #endif |
|---|
| 1086 | { |
|---|
| 1087 | last_ch = ch; |
|---|
| 1088 | printf("%c", ch); |
|---|
| 1089 | } |
|---|
| 1090 | ch = console_getch(); |
|---|
| 1091 | }while ((ch != '\n') && (ch != '\r')); |
|---|
| 1092 | |
|---|
| 1093 | return last_ch; |
|---|
| 1094 | } |
|---|
| 1095 | |
|---|
| 1096 | char *gets(char *s) |
|---|
| 1097 | { |
|---|
| 1098 | #ifdef CONFIG_GP |
|---|
| 1099 | int ch; |
|---|
| 1100 | #else |
|---|
| 1101 | char ch; |
|---|
| 1102 | #endif |
|---|
| 1103 | char *orig_s = s; |
|---|
| 1104 | |
|---|
| 1105 | do |
|---|
| 1106 | { |
|---|
| 1107 | ch = console_getch(); |
|---|
| 1108 | #ifdef CONFIG_GP |
|---|
| 1109 | if (ch != -1) |
|---|
| 1110 | #else |
|---|
| 1111 | if (ch != 0) |
|---|
| 1112 | #endif |
|---|
| 1113 | { |
|---|
| 1114 | /* Don't print backspace if we have reached beginning of string input */ |
|---|
| 1115 | if (ch == '\b') |
|---|
| 1116 | { |
|---|
| 1117 | if (s > orig_s) |
|---|
| 1118 | { |
|---|
| 1119 | printf("\b \b", ch); |
|---|
| 1120 | s--; |
|---|
| 1121 | } |
|---|
| 1122 | continue; |
|---|
| 1123 | } |
|---|
| 1124 | printf("%c", ch); |
|---|
| 1125 | if ((ch != '\n') && (ch != '\r')) |
|---|
| 1126 | { |
|---|
| 1127 | *s++ = ch; |
|---|
| 1128 | } |
|---|
| 1129 | }else{ |
|---|
| 1130 | bos_sleep(20); /* let other task run */ |
|---|
| 1131 | } |
|---|
| 1132 | } while ((ch != '\n') && (ch != '\r')); |
|---|
| 1133 | *s = 0; |
|---|
| 1134 | return orig_s; |
|---|
| 1135 | } |
|---|
| 1136 | |
|---|
| 1137 | |
|---|
| 1138 | char *ngets(char *s,int max_len) |
|---|
| 1139 | { |
|---|
| 1140 | #ifdef CONFIG_GP |
|---|
| 1141 | int ch; |
|---|
| 1142 | #else |
|---|
| 1143 | char ch; |
|---|
| 1144 | #endif |
|---|
| 1145 | char *orig_s = s; |
|---|
| 1146 | |
|---|
| 1147 | do |
|---|
| 1148 | { |
|---|
| 1149 | ch = console_getch(); |
|---|
| 1150 | #ifdef CONFIG_GP |
|---|
| 1151 | if (ch != -1) |
|---|
| 1152 | #else |
|---|
| 1153 | if (ch != 0) |
|---|
| 1154 | #endif |
|---|
| 1155 | { |
|---|
| 1156 | /* Don't print backspace if we have reached beginning of string input */ |
|---|
| 1157 | if (ch == '\b') |
|---|
| 1158 | { |
|---|
| 1159 | if (s > orig_s) |
|---|
| 1160 | { |
|---|
| 1161 | printf("\b \b", ch); |
|---|
| 1162 | s--; |
|---|
| 1163 | } |
|---|
| 1164 | continue; |
|---|
| 1165 | } |
|---|
| 1166 | printf("%c", ch); |
|---|
| 1167 | if ((ch != '\n') && (ch != '\r')) |
|---|
| 1168 | { |
|---|
| 1169 | *s++ = ch; |
|---|
| 1170 | } |
|---|
| 1171 | }else{ |
|---|
| 1172 | bos_sleep(20); /* let other task run */ |
|---|
| 1173 | } |
|---|
| 1174 | if ((unsigned int)s >= (unsigned int)(&orig_s[max_len + 1])) |
|---|
| 1175 | { |
|---|
| 1176 | break; |
|---|
| 1177 | } |
|---|
| 1178 | } while ((ch != '\n') && (ch != '\r')); |
|---|
| 1179 | *s = 0; |
|---|
| 1180 | return orig_s; |
|---|
| 1181 | } |
|---|
| 1182 | |
|---|
| 1183 | int fprintf(int* f, const char *format, ...) |
|---|
| 1184 | { |
|---|
| 1185 | int rv = 0; |
|---|
| 1186 | va_list arg; |
|---|
| 1187 | |
|---|
| 1188 | va_start(arg, format); |
|---|
| 1189 | #if (BCHP_CHIP!=7550) && (BCHP_CHIP!=7552) |
|---|
| 1190 | if (s_console) { |
|---|
| 1191 | rv = vprintf_console(s_console, format, arg); |
|---|
| 1192 | } else { |
|---|
| 1193 | rv = vprintf_poll(format, arg); |
|---|
| 1194 | } |
|---|
| 1195 | #else |
|---|
| 1196 | rv = vprintf_poll(format, arg); |
|---|
| 1197 | #endif |
|---|
| 1198 | va_end(arg); |
|---|
| 1199 | return rv; |
|---|
| 1200 | } |
|---|
| 1201 | |
|---|
| 1202 | #ifdef CONFIG_GP |
|---|
| 1203 | void GP_putchar(char ch) |
|---|
| 1204 | { |
|---|
| 1205 | put_c(ch); |
|---|
| 1206 | } |
|---|
| 1207 | |
|---|
| 1208 | int GP_getchar(void) |
|---|
| 1209 | { |
|---|
| 1210 | int v = console_getch(); |
|---|
| 1211 | while (v==-1) { |
|---|
| 1212 | bos_sleep(20); |
|---|
| 1213 | v = console_getch(); |
|---|
| 1214 | } |
|---|
| 1215 | return v; |
|---|
| 1216 | } |
|---|
| 1217 | #endif |
|---|
| 1218 | |
|---|
| 1219 | static unsigned int rand_table_idx = 0; |
|---|
| 1220 | static const unsigned short rand_table[] = |
|---|
| 1221 | { |
|---|
| 1222 | 840,394,783,798,911,197,335,768,277,553, |
|---|
| 1223 | 477,628,364,513,952,916,635,717,141,606, |
|---|
| 1224 | 16,242,137,804,156,400,129,108,998,218, |
|---|
| 1225 | 512,839,612,296,637,524,493,972,292,771, |
|---|
| 1226 | 526,769,400,891,283,352,807,919,69,949, |
|---|
| 1227 | 525,86,192,663,890,348,64,20,457,63, |
|---|
| 1228 | 238,970,902,850,266,539,375,760,512,667, |
|---|
| 1229 | 531,39,437,931,930,720,284,738,639,354, |
|---|
| 1230 | 687,165,440,880,829,330,228,893,350,686, |
|---|
| 1231 | 956,588,657,858,439,923,398,814,684,910, |
|---|
| 1232 | 482,215,950,920,147,881,641,431,619,281, |
|---|
| 1233 | 786,307,447,226,187,276,556,416,169,906, |
|---|
| 1234 | 103,126,495,760,984,935,684,383,749,368, |
|---|
| 1235 | 294,232,584,244,152,732,125,793,164,745, |
|---|
| 1236 | 74,950,52,521,176,240,797,732,656,967, |
|---|
| 1237 | 639,759,93,134,520,78,69,204,461,819, |
|---|
| 1238 | 573,755,51,157,999,204,889,125,997,54, |
|---|
| 1239 | 870,72,4,923,593,180,163,391,913,819, |
|---|
| 1240 | 359,552,579,452,687,99,530,757,304,992, |
|---|
| 1241 | 576,877,747,628,35,747,833,925,873,831, |
|---|
| 1242 | 979,743,903,983,666,497,163,830,888,76, |
|---|
| 1243 | 649,248,629,229,700,316,328,231,74,633, |
|---|
| 1244 | 223,651,510,971,280,546,719,113,471,592, |
|---|
| 1245 | 944,450,336,847,434,3,344,598,833,233, |
|---|
| 1246 | 675,482,481,304,712,182,621,40,413,695, |
|---|
| 1247 | 673,637,347,184,609,627,730,328,740,202, |
|---|
| 1248 | 920,684,653,257,532,87,260,877,686,93, |
|---|
| 1249 | 111,361,576,593,666,288,775,288,329,189, |
|---|
| 1250 | 984,3,827,331,188,436,958,918,764,699, |
|---|
| 1251 | 121,685,383,774,943,916,861,203,793,548, |
|---|
| 1252 | 297,904,909,873,498,576,162,273,864,492, |
|---|
| 1253 | 463,848,495,291,180,684,727,139,603,492, |
|---|
| 1254 | 838,724,178,221,498,121,138,360,324,931, |
|---|
| 1255 | 908,622,836,818,496,334,394,658,608,258, |
|---|
| 1256 | 151,72,107,647,363,288,331,91,427,934, |
|---|
| 1257 | 583,265,658,761,487,157,883,625,517,207, |
|---|
| 1258 | 557,426,829,394,244,326,729,638,984,338, |
|---|
| 1259 | 897,136,410,5,783,774,293,114,865,721, |
|---|
| 1260 | 49,449,986,707,210,473,865,93,99,382, |
|---|
| 1261 | 301,657,809,131,51,53,457,780,692,442, |
|---|
| 1262 | 119,589,578,529,595,361,304,888,476,169, |
|---|
| 1263 | 609,525,618,596,233,829,70,98,923,169, |
|---|
| 1264 | 481,225,826,290,357,878,344,814,659,36, |
|---|
| 1265 | 257,778,625,836,308,221,198,612,109,674, |
|---|
| 1266 | 782,719,200,401,315,434,230,385,532,154, |
|---|
| 1267 | 555,14,380,382,305,737,260,649,552,919, |
|---|
| 1268 | 685,809,697,311,645,6,532,843,618,642, |
|---|
| 1269 | 518,400,362,718,801,677,152,32,63,685, |
|---|
| 1270 | 187,618,700,567,1,5,305,261,655,857, |
|---|
| 1271 | 181,341,667,879,653,313,885,186,157,503, |
|---|
| 1272 | 828,675,904,191,394,706,868,547,738,932, |
|---|
| 1273 | 233,926,551,933,494,552,939,799,814,594, |
|---|
| 1274 | 657,995,935,324,874,589,637,759,775,794, |
|---|
| 1275 | 262,604,470,166,795,865,873,664,412,611, |
|---|
| 1276 | 596,645,538,148,579,32,700,518,832,515, |
|---|
| 1277 | 112,489,510,48,814,384,637,452,143,413, |
|---|
| 1278 | 247,406,17,717,573,812,582,446,477,995, |
|---|
| 1279 | 58,74,640,597,222,219,630,923,737,462, |
|---|
| 1280 | 438,850,952,948,899,767,333,536,219,477, |
|---|
| 1281 | 949,466,884,967,183,458,780,766,904,257, |
|---|
| 1282 | 761,963,331,402,560,554,622,191,477,360, |
|---|
| 1283 | 653,916,210,606,865,109,373,199,646,592, |
|---|
| 1284 | 676,596,58,560,563,242,18,343,9,923, |
|---|
| 1285 | 601,770,887,933,173,447,487,795,639,965, |
|---|
| 1286 | 155,292,882,366,899,747,475,272,946,122, |
|---|
| 1287 | 865,623,718,924,184,282,167,202,626,176, |
|---|
| 1288 | 126,227,946,13,160,119,461,648,915,100, |
|---|
| 1289 | 614,70,393,496,436,293,244,912,566,190, |
|---|
| 1290 | 34,431,813,753,356,997,35,523,200,661, |
|---|
| 1291 | 699,327,889,646,341,50,766,803,698,681, |
|---|
| 1292 | 904,312,752,297,809,189,591,53,101,157, |
|---|
| 1293 | 244,136,589,58,889,945,56,925,469,256, |
|---|
| 1294 | 587,168,584,476,815,926,526,582,729,225, |
|---|
| 1295 | 264,633,538,16,931,347,205,522,400,307, |
|---|
| 1296 | 679,645,443,269,703,332,214,759,258,683, |
|---|
| 1297 | 16,845,852,600,321,667,526,848,250,256, |
|---|
| 1298 | 73,514,889,611,531,821,958,736,343,359, |
|---|
| 1299 | 43,23,5,487,292,708,820,507,467,78, |
|---|
| 1300 | 190,483,923,43,84,244,711,611,92,961, |
|---|
| 1301 | 867,166,475,757,777,6,578,736,743,922, |
|---|
| 1302 | 96,787,946,101,274,239,809,95,746,277, |
|---|
| 1303 | 173,937,760,96,981,845,341,692,456,434, |
|---|
| 1304 | 654,323,600,129,81,377,136,659,114,880, |
|---|
| 1305 | 582,210,668,528,312,943,768,122,38,514, |
|---|
| 1306 | 399,211,452,160,308,433,5,649,126,461, |
|---|
| 1307 | 84,780,785,684,910,867,62,47,527,177, |
|---|
| 1308 | 927,109,387,596,638,700,539,406,822,577, |
|---|
| 1309 | 921,221,789,374,381,97,807,387,747,934, |
|---|
| 1310 | 849,831,714,635,516,624,502,578,671,29, |
|---|
| 1311 | 755,599,139,143,195,777,844,735,184,666, |
|---|
| 1312 | 312,105,888,102,479,270,199,287,657,947, |
|---|
| 1313 | 221,506,778,936,142,294,561,644,873,232, |
|---|
| 1314 | 673,629,832,812,773,28,590,617,763,774, |
|---|
| 1315 | 284,76,880,172,178,359,443,378,647,100, |
|---|
| 1316 | 325,869,607,104,805,749,398,366,394,272, |
|---|
| 1317 | 599,68,901,432,881,674,460,471,292,224, |
|---|
| 1318 | 246,576,301,126,749,480,485,192,858,133, |
|---|
| 1319 | 293,184,2,900,288,808,650,687,175,44, |
|---|
| 1320 | 959,775,112,861,207,994,536,667,465,828, |
|---|
| 1321 | 892,711,405,193,837,154,673,323,347,532, |
|---|
| 1322 | }; |
|---|
| 1323 | |
|---|
| 1324 | unsigned int rand(void) |
|---|
| 1325 | { |
|---|
| 1326 | unsigned int reg ; |
|---|
| 1327 | reg = rand_table[rand_table_idx++]; |
|---|
| 1328 | if (rand_table_idx == RAND_MAX) |
|---|
| 1329 | { |
|---|
| 1330 | rand_table_idx = 0; |
|---|
| 1331 | } |
|---|
| 1332 | return reg; |
|---|
| 1333 | } |
|---|
| 1334 | |
|---|
| 1335 | void srand(unsigned int seed) |
|---|
| 1336 | { |
|---|
| 1337 | rand_table_idx = seed % RAND_MAX; |
|---|
| 1338 | if (rand_table_idx == RAND_MAX) |
|---|
| 1339 | { |
|---|
| 1340 | rand_table_idx = 0; |
|---|
| 1341 | } |
|---|
| 1342 | } |
|---|
| 1343 | |
|---|
| 1344 | |
|---|
| 1345 | #endif /* __NEWLIB__ */ |
|---|
| 1346 | |
|---|
| 1347 | /* |
|---|
| 1348 | Summary: |
|---|
| 1349 | Calculate the UTC time offset from Jan 6th 1980. |
|---|
| 1350 | NOTE: This function only works for times after Jan 6th, 1980 |
|---|
| 1351 | |
|---|
| 1352 | */ |
|---|
| 1353 | #ifndef LINUX |
|---|
| 1354 | /* Jan 6, 1980 => Sunday */ |
|---|
| 1355 | #define START_DAY 0 |
|---|
| 1356 | #define START_YEAR 1980 |
|---|
| 1357 | #else |
|---|
| 1358 | /* Jan 1, 1970 => Thursday */ |
|---|
| 1359 | #define START_DAY 3 |
|---|
| 1360 | #endif |
|---|
| 1361 | |
|---|
| 1362 | /* Days/month for non-leap year */ |
|---|
| 1363 | const unsigned char s_days_per_mon[] = |
|---|
| 1364 | { |
|---|
| 1365 | 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, |
|---|
| 1366 | 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, |
|---|
| 1367 | }; |
|---|
| 1368 | |
|---|
| 1369 | #define IS_LEAP_YEAR(y) ( !((y + START_YEAR) % 4) && ( ((y + START_YEAR) % 100) || !((y + START_YEAR) % 400) ) ) |
|---|
| 1370 | void utctime(unsigned int secs,b_tm *p_tm) |
|---|
| 1371 | { |
|---|
| 1372 | unsigned int yday,mon,t_val; |
|---|
| 1373 | unsigned char *p_dpm = (unsigned char*)s_days_per_mon; |
|---|
| 1374 | |
|---|
| 1375 | memset(p_tm,0,sizeof(b_tm)); |
|---|
| 1376 | |
|---|
| 1377 | /* seconds */ |
|---|
| 1378 | p_tm->tm_sec = secs % 60; |
|---|
| 1379 | t_val = secs / 60; /* minutes */ |
|---|
| 1380 | |
|---|
| 1381 | /* minutes */ |
|---|
| 1382 | p_tm->tm_min = t_val % 60; |
|---|
| 1383 | t_val /= 60; /* hours */ |
|---|
| 1384 | |
|---|
| 1385 | /* hours */ |
|---|
| 1386 | p_tm->tm_hour = t_val % 24; |
|---|
| 1387 | t_val /= 24; |
|---|
| 1388 | |
|---|
| 1389 | /* day of week */ |
|---|
| 1390 | p_tm->tm_wday = t_val % 7; |
|---|
| 1391 | p_tm->tm_wday = (t_val - START_DAY) % 7; |
|---|
| 1392 | |
|---|
| 1393 | /* offset value to start of the year */ |
|---|
| 1394 | #ifndef LINUX |
|---|
| 1395 | t_val += 5; |
|---|
| 1396 | #endif |
|---|
| 1397 | /* year */ |
|---|
| 1398 | p_tm->tm_yday = t_val; |
|---|
| 1399 | p_tm->tm_year = 0; |
|---|
| 1400 | |
|---|
| 1401 | /* day of current year */ |
|---|
| 1402 | while ((IS_LEAP_YEAR(p_tm->tm_year) && (p_tm->tm_yday > 365)) || |
|---|
| 1403 | (!IS_LEAP_YEAR(p_tm->tm_year) && (p_tm->tm_yday > 364))) |
|---|
| 1404 | { |
|---|
| 1405 | if (IS_LEAP_YEAR(p_tm->tm_year)) |
|---|
| 1406 | p_tm->tm_yday -= 366; |
|---|
| 1407 | else |
|---|
| 1408 | p_tm->tm_yday -= 365; |
|---|
| 1409 | p_tm->tm_year++; |
|---|
| 1410 | } |
|---|
| 1411 | |
|---|
| 1412 | if (IS_LEAP_YEAR(p_tm->tm_year)) |
|---|
| 1413 | p_dpm += 12; |
|---|
| 1414 | |
|---|
| 1415 | yday = p_tm->tm_yday + 1; |
|---|
| 1416 | mon = 0; |
|---|
| 1417 | while(yday > p_dpm[mon]) |
|---|
| 1418 | { |
|---|
| 1419 | yday -= p_dpm[mon]; |
|---|
| 1420 | mon++; |
|---|
| 1421 | } |
|---|
| 1422 | |
|---|
| 1423 | /* month */ |
|---|
| 1424 | p_tm->tm_mon = mon; |
|---|
| 1425 | |
|---|
| 1426 | /* day of month */ |
|---|
| 1427 | p_tm->tm_mday = yday; |
|---|
| 1428 | |
|---|
| 1429 | } |
|---|
| 1430 | |
|---|
| 1431 | /****************************************************************************** |
|---|
| 1432 | * INPUTS: size - number of bytes to allocate |
|---|
| 1433 | * alignbits - alignment in number of lsb bits. |
|---|
| 1434 | * file,line for debugging purposes |
|---|
| 1435 | * OUTPUTS: None. |
|---|
| 1436 | * RETURNS: the buffer allocated |
|---|
| 1437 | * FUNCTION: allocate memory from primary heap |
|---|
| 1438 | ******************************************************************************/ |
|---|
| 1439 | |
|---|
| 1440 | #ifdef BCM_DEBUG |
|---|
| 1441 | void *malloc_align_dbg(size_t size,char alignbits, char* file, int line) |
|---|
| 1442 | #else |
|---|
| 1443 | void *malloc_align(size_t size,char alignbits) |
|---|
| 1444 | #endif |
|---|
| 1445 | { |
|---|
| 1446 | char* p_ref; |
|---|
| 1447 | |
|---|
| 1448 | if (!g_p_sdram_heap) |
|---|
| 1449 | { |
|---|
| 1450 | unsigned int offset = (unsigned int)&_end; |
|---|
| 1451 | offset &= 0x0FFFFFFF; |
|---|
| 1452 | |
|---|
| 1453 | /*RLQ, don't printout here as BKNI_Print_Init is not complete yet as first one is called BKNI_CreateEvent */ |
|---|
| 1454 | //printf("%15s SDRAM_SIZE = %d\n\n",strrchr(__FILE__,'/')? strrchr(__FILE__,'/')+1 : __FILE__,SDRAM_SIZE/(1024 * 1024)); |
|---|
| 1455 | |
|---|
| 1456 | heap_init(&g_sdram_heap, (unsigned long *)&_end, SDRAM_SIZE - offset); |
|---|
| 1457 | g_p_sdram_heap = &g_sdram_heap; |
|---|
| 1458 | } |
|---|
| 1459 | |
|---|
| 1460 | /* Make sure size is a multiple of 4 bytes */ |
|---|
| 1461 | /* This insures that we never attempt to access one of the 32- */ |
|---|
| 1462 | /* bit signature values on anything other than a 4-byte aligned */ |
|---|
| 1463 | /* address. */ |
|---|
| 1464 | size = (size+3)&(~3); |
|---|
| 1465 | |
|---|
| 1466 | #ifdef BCM_DEBUG |
|---|
| 1467 | p_ref = mem_tagalloc(g_p_sdram_heap,size,alignbits,file,line); |
|---|
| 1468 | #else |
|---|
| 1469 | p_ref = mem_tagalloc(g_p_sdram_heap,size,alignbits, NULL, 0); |
|---|
| 1470 | #endif |
|---|
| 1471 | return p_ref; |
|---|
| 1472 | } |
|---|
| 1473 | /****************************************************************************** |
|---|
| 1474 | * INPUTS: size - number of bytes to allocate |
|---|
| 1475 | * file,line for debugging purposes |
|---|
| 1476 | * OUTPUTS: None. |
|---|
| 1477 | * RETURNS: the buffer allocated |
|---|
| 1478 | * FUNCTION: allocate memory from primary heap |
|---|
| 1479 | ******************************************************************************/ |
|---|
| 1480 | #include "bkni.h" |
|---|
| 1481 | #include "bkni_multi.h" |
|---|
| 1482 | |
|---|
| 1483 | static void malloc_lock(int bLock) |
|---|
| 1484 | { |
|---|
| 1485 | static BKNI_MutexHandle bMutex = NULL; |
|---|
| 1486 | static int nCount = 0; |
|---|
| 1487 | if (bLock) nCount++; |
|---|
| 1488 | if(nCount == 1000 && bMutex == NULL) |
|---|
| 1489 | { |
|---|
| 1490 | BKNI_CreateMutex(&bMutex); |
|---|
| 1491 | } |
|---|
| 1492 | if (bLock) |
|---|
| 1493 | { |
|---|
| 1494 | BKNI_AcquireMutex(bMutex); |
|---|
| 1495 | } |
|---|
| 1496 | else |
|---|
| 1497 | { |
|---|
| 1498 | BKNI_ReleaseMutex(bMutex); |
|---|
| 1499 | } |
|---|
| 1500 | } |
|---|
| 1501 | |
|---|
| 1502 | #ifdef BCM_DEBUG |
|---|
| 1503 | void *malloc_dbg(size_t size, char* file, int line) |
|---|
| 1504 | #else |
|---|
| 1505 | void *malloc(size_t size) |
|---|
| 1506 | #endif |
|---|
| 1507 | { |
|---|
| 1508 | malloc_lock(1); |
|---|
| 1509 | #ifdef BCM_DEBUG |
|---|
| 1510 | void *p = malloc_align_dbg(size,DEFAULT_ALIGN_BITS,file,line); |
|---|
| 1511 | #else |
|---|
| 1512 | void *p = malloc_align(size,DEFAULT_ALIGN_BITS); |
|---|
| 1513 | #endif |
|---|
| 1514 | malloc_lock(0); |
|---|
| 1515 | return p; |
|---|
| 1516 | } |
|---|
| 1517 | /****************************************************************************** |
|---|
| 1518 | * INPUTS: ptr - memory block to free |
|---|
| 1519 | * file, line - file and line where allocation is freed |
|---|
| 1520 | * OUTPUTS: None. |
|---|
| 1521 | * RETURNS: none. |
|---|
| 1522 | * FUNCTION: Free memory from primary heap |
|---|
| 1523 | ******************************************************************************/ |
|---|
| 1524 | #ifdef BCM_DEBUG |
|---|
| 1525 | void free_dbg(void *ptr, char* file, int line) |
|---|
| 1526 | #else |
|---|
| 1527 | void free(void *ptr) |
|---|
| 1528 | #endif |
|---|
| 1529 | { |
|---|
| 1530 | malloc_lock(1); |
|---|
| 1531 | #ifdef BCM_DEBUG |
|---|
| 1532 | mem_tagfree(g_p_sdram_heap,ptr,file,line); |
|---|
| 1533 | #else |
|---|
| 1534 | mem_tagfree(g_p_sdram_heap,ptr, NULL, 0); |
|---|
| 1535 | #endif |
|---|
| 1536 | malloc_lock(0); |
|---|
| 1537 | } |
|---|
| 1538 | #ifdef BCM_DEBUG |
|---|
| 1539 | /* libstdc++ seems to generate unavoidable calls to malloc,free and realloc */ |
|---|
| 1540 | #undef malloc |
|---|
| 1541 | #undef free |
|---|
| 1542 | void *malloc(size_t size) |
|---|
| 1543 | { |
|---|
| 1544 | return malloc_dbg(size,__FILE__,__LINE__); |
|---|
| 1545 | } |
|---|
| 1546 | void free(void *ptr) |
|---|
| 1547 | { |
|---|
| 1548 | free_dbg(ptr,__FILE__,__LINE__); |
|---|
| 1549 | } |
|---|
| 1550 | void *realloc(void *ptr,size_t size) |
|---|
| 1551 | { |
|---|
| 1552 | void *nptr; |
|---|
| 1553 | if (!ptr) |
|---|
| 1554 | return malloc(size); |
|---|
| 1555 | |
|---|
| 1556 | nptr = malloc(size); |
|---|
| 1557 | |
|---|
| 1558 | if (!nptr) |
|---|
| 1559 | return NULL; |
|---|
| 1560 | |
|---|
| 1561 | memcpy(nptr,ptr,size); |
|---|
| 1562 | free(ptr); |
|---|
| 1563 | return nptr; |
|---|
| 1564 | } |
|---|
| 1565 | |
|---|
| 1566 | #endif |
|---|
| 1567 | |
|---|
| 1568 | /****************************************************************************** |
|---|
| 1569 | * INPUTS: none |
|---|
| 1570 | * OUTPUTS: None. |
|---|
| 1571 | * RETURNS: none. |
|---|
| 1572 | * FUNCTION: Report memory heap info |
|---|
| 1573 | ******************************************************************************/ |
|---|
| 1574 | void m_report(void) |
|---|
| 1575 | { |
|---|
| 1576 | #ifdef BCM_DEBUG |
|---|
| 1577 | mem_reportbrief(g_p_sdram_heap); |
|---|
| 1578 | #else |
|---|
| 1579 | printf("Largest unused block = %d bytes\n",mem_available(g_p_sdram_heap)); |
|---|
| 1580 | #endif |
|---|
| 1581 | } |
|---|
| 1582 | |
|---|
| 1583 | void console_init(volatile void *uart) |
|---|
| 1584 | { |
|---|
| 1585 | /* setup FIFO control register */ |
|---|
| 1586 | CONSOLE_UART->sdw_iir_fcr = 7; /* reset XMIT and RCVR FIFO */ |
|---|
| 1587 | } |
|---|
| 1588 | |
|---|
| 1589 | void console_flush(void) |
|---|
| 1590 | { |
|---|
| 1591 | #ifdef CONFIG_GP |
|---|
| 1592 | while ((serial_getc(CONSOLE_UART, false) != -1)); |
|---|
| 1593 | #else |
|---|
| 1594 | while (serial_getc(CONSOLE_UART, false)); |
|---|
| 1595 | #endif |
|---|
| 1596 | } |
|---|
| 1597 | |
|---|
| 1598 | void console_shutdown(void) |
|---|
| 1599 | { |
|---|
| 1600 | #if (BCHP_CHIP==7550) |
|---|
| 1601 | /* disable interrupts if any */ |
|---|
| 1602 | CONSOLE_UART->sdw_dlh_ier = 0; |
|---|
| 1603 | #endif |
|---|
| 1604 | |
|---|
| 1605 | console_flush(); |
|---|
| 1606 | #if (BCHP_CHIP==7550) |
|---|
| 1607 | /* setup FIFO control register */ |
|---|
| 1608 | /* TODO to set FIFO buffer triggers */ |
|---|
| 1609 | CONSOLE_UART->sdw_iir_fcr = 0x6; |
|---|
| 1610 | CONSOLE_UART->sdw_iir_fcr = FIFOE; |
|---|
| 1611 | |
|---|
| 1612 | /* assume that other UART paramters, baud rate, stop bit, parity are set correctly */ |
|---|
| 1613 | #endif |
|---|
| 1614 | } |
|---|
| 1615 | |
|---|
| 1616 | |
|---|
| 1617 | |
|---|
| 1618 | #if SUPPORT_DST_PLATFORM |
|---|
| 1619 | char *strchr(const char *str, int c) |
|---|
| 1620 | { |
|---|
| 1621 | char *pstr = (char *)str; |
|---|
| 1622 | char temp; |
|---|
| 1623 | |
|---|
| 1624 | if(c == 0) |
|---|
| 1625 | { |
|---|
| 1626 | while(*pstr++); |
|---|
| 1627 | |
|---|
| 1628 | return pstr - 1; |
|---|
| 1629 | } |
|---|
| 1630 | |
|---|
| 1631 | while((temp = *pstr++)) |
|---|
| 1632 | { |
|---|
| 1633 | if(temp == c) |
|---|
| 1634 | { |
|---|
| 1635 | return pstr - 1; |
|---|
| 1636 | } |
|---|
| 1637 | } |
|---|
| 1638 | return 0; |
|---|
| 1639 | } |
|---|
| 1640 | |
|---|
| 1641 | int sprintf(char *str, const char *format, ...) |
|---|
| 1642 | { |
|---|
| 1643 | va_list arg; |
|---|
| 1644 | int rv; |
|---|
| 1645 | size_t size = 4096; // actually, sprintf do not limit size. use numbers big enough. |
|---|
| 1646 | |
|---|
| 1647 | va_start(arg, format); |
|---|
| 1648 | rv = vsnprintf(str, size, format, arg); |
|---|
| 1649 | va_end(arg); |
|---|
| 1650 | return rv; |
|---|
| 1651 | } |
|---|
| 1652 | char *strcat(char *dest, const char *src) |
|---|
| 1653 | { |
|---|
| 1654 | return strcpy(dest + strlen(dest), src); |
|---|
| 1655 | } |
|---|
| 1656 | |
|---|
| 1657 | char *strstr(const char *s, const char *s2) |
|---|
| 1658 | { |
|---|
| 1659 | char c, *p; |
|---|
| 1660 | int len; |
|---|
| 1661 | |
|---|
| 1662 | if (!s2 || !*s2) |
|---|
| 1663 | return (char *)s; // check this is correct. |
|---|
| 1664 | |
|---|
| 1665 | c = *s2; |
|---|
| 1666 | p = (char *)s; |
|---|
| 1667 | len = strlen(s2); |
|---|
| 1668 | |
|---|
| 1669 | while (*p) { |
|---|
| 1670 | if (*p == c) { |
|---|
| 1671 | // ok, fist char is matched. lets check full string. |
|---|
| 1672 | if (!strncmp(p, s2, len)) |
|---|
| 1673 | return p; |
|---|
| 1674 | } |
|---|
| 1675 | p++; |
|---|
| 1676 | } |
|---|
| 1677 | return NULL; // needle not found. |
|---|
| 1678 | } |
|---|
| 1679 | |
|---|
| 1680 | void *memmove(void *dest, const void *src, size_t n) |
|---|
| 1681 | { |
|---|
| 1682 | return memcpy(dest, src, n); |
|---|
| 1683 | } |
|---|
| 1684 | |
|---|
| 1685 | |
|---|
| 1686 | |
|---|
| 1687 | /////BKTEMP |
|---|
| 1688 | typedef struct mem_io_t |
|---|
| 1689 | { |
|---|
| 1690 | char *name; |
|---|
| 1691 | bool open; |
|---|
| 1692 | uint8_t *data; |
|---|
| 1693 | unsigned int *size; |
|---|
| 1694 | unsigned int cnt; |
|---|
| 1695 | }mem_io_t; |
|---|
| 1696 | |
|---|
| 1697 | static mem_io_t g_files[] = |
|---|
| 1698 | { |
|---|
| 1699 | { "",false,0,0,0}, |
|---|
| 1700 | }; |
|---|
| 1701 | |
|---|
| 1702 | size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) |
|---|
| 1703 | { |
|---|
| 1704 | mem_io_t *file = (mem_io_t*)stream; |
|---|
| 1705 | BDBG_ASSERT(file); |
|---|
| 1706 | |
|---|
| 1707 | size = size * nmemb; |
|---|
| 1708 | if (file->cnt + size > *(file->size)) |
|---|
| 1709 | { |
|---|
| 1710 | printf("Requesting more bytes than available (cnt = %d, size = %d,total = %d)\n", |
|---|
| 1711 | file->cnt,size,*(file->size)); |
|---|
| 1712 | size = *(file->size) - file->cnt; |
|---|
| 1713 | } |
|---|
| 1714 | |
|---|
| 1715 | memcpy(ptr,&(file->data[file->cnt]),size); |
|---|
| 1716 | file->cnt += size; |
|---|
| 1717 | |
|---|
| 1718 | return size; |
|---|
| 1719 | } |
|---|
| 1720 | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) |
|---|
| 1721 | { |
|---|
| 1722 | mem_io_t *file = (mem_io_t*)stream; |
|---|
| 1723 | BDBG_ASSERT(file); |
|---|
| 1724 | |
|---|
| 1725 | size = size * nmemb; |
|---|
| 1726 | if (file->cnt + size > *(file->size)) |
|---|
| 1727 | { |
|---|
| 1728 | printf("Attempt to write more bytes than available (cnt = %d, size = %d,total = %d)\n", |
|---|
| 1729 | file->cnt,size,*(file->size)); |
|---|
| 1730 | size = *(file->size) - file->cnt; |
|---|
| 1731 | } |
|---|
| 1732 | |
|---|
| 1733 | memcpy(&(file->data[file->cnt]),ptr,size); |
|---|
| 1734 | file->cnt += size; |
|---|
| 1735 | return size; |
|---|
| 1736 | } |
|---|
| 1737 | FILE *fopen(const char *path, const char *mode) |
|---|
| 1738 | { |
|---|
| 1739 | int idx = 0; |
|---|
| 1740 | |
|---|
| 1741 | while(g_files[idx].data != NULL) |
|---|
| 1742 | { |
|---|
| 1743 | if ((strcmp(path,g_files[idx].name) == 0) && !g_files[idx].open) |
|---|
| 1744 | { |
|---|
| 1745 | g_files[idx].open = true; |
|---|
| 1746 | g_files[idx].cnt = 0; |
|---|
| 1747 | return &(g_files[idx]); |
|---|
| 1748 | } |
|---|
| 1749 | idx++; |
|---|
| 1750 | } |
|---|
| 1751 | return NULL; |
|---|
| 1752 | } |
|---|
| 1753 | int fclose(FILE *stream) |
|---|
| 1754 | { |
|---|
| 1755 | mem_io_t *file = (mem_io_t*)stream; |
|---|
| 1756 | BDBG_ASSERT(file); |
|---|
| 1757 | file->open = false; |
|---|
| 1758 | return 0; |
|---|
| 1759 | } |
|---|
| 1760 | int fseek(FILE *stream, long offset, int whence) |
|---|
| 1761 | { |
|---|
| 1762 | mem_io_t *file = (mem_io_t*)stream; |
|---|
| 1763 | switch(whence) |
|---|
| 1764 | { |
|---|
| 1765 | default: |
|---|
| 1766 | case SEEK_SET: file->cnt = offset; break; |
|---|
| 1767 | case SEEK_CUR: file->cnt += offset; break; |
|---|
| 1768 | case SEEK_END: file->size += offset; break; |
|---|
| 1769 | } |
|---|
| 1770 | return file->cnt; |
|---|
| 1771 | } |
|---|
| 1772 | |
|---|
| 1773 | long ftell(FILE *stream) |
|---|
| 1774 | { |
|---|
| 1775 | mem_io_t *file = (mem_io_t*)stream; |
|---|
| 1776 | return (long) file->cnt; |
|---|
| 1777 | } |
|---|
| 1778 | |
|---|
| 1779 | int fflush(FILE *stream) |
|---|
| 1780 | { |
|---|
| 1781 | return 0; |
|---|
| 1782 | } |
|---|
| 1783 | |
|---|
| 1784 | #endif |
|---|
| 1785 | |
|---|
| 1786 | |
|---|