2 * Initialization and support routines for self-booting
5 * Copyright 2004, Broadcom Corporation
8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
17 * bcmstdlib.c file should be used only to construct an OSL or alone without any OSL
18 * It should not be used with any orbitarary OSL's as there could be a conflict
19 * with some of the routines defined here.
23 #if defined(NDIS) || defined(_MINOSL_) || defined(__vxworks) || \
24 defined(PCBIOS) || defined(LINUXSIM) || defined(EFI)
27 #elif !defined(__IOPOS__)
32 * Define BCMSTDLIB_WIN32_APP if this is a Win32 Application compile
34 #if defined(_WIN32) && !defined(NDIS) && !defined(EFI)
35 #define BCMSTDLIB_WIN32_APP 1
36 #endif /* _WIN32 && !NDIS */
39 * Define BCMSTDLIB_SNPRINTF_ONLY if we only want snprintf & vsnprintf implementations
41 #if (defined(_WIN32) && !defined(EFI)) || defined(__vxworks) || defined(_CFE_)
42 #define BCMSTDLIB_SNPRINTF_ONLY 1
46 #include <bcmstdlib.h>
47 #ifndef BCMSTDLIB_WIN32_APP
51 #ifdef BCMSTDLIB_WIN32_APP
53 /* for a WIN32 application, use _vsnprintf as basis of vsnprintf/snprintf to
54 * support full set of format specifications.
58 vsnprintf(char *buf
, size_t bufsize
, const char *fmt
, va_list ap
)
62 r
= _vsnprintf(buf
, bufsize
, fmt
, ap
);
64 /* Microsoft _vsnprintf() will not null terminate on overflow,
65 * so null terminate at buffer end on error
67 if (r
< 0 && bufsize
> 0)
68 buf
[bufsize
- 1] = '\0';
74 snprintf(char *buf
, size_t bufsize
, const char *fmt
, ...)
80 r
= vsnprintf(buf
, bufsize
, fmt
, ap
);
86 #else /* BCMSTDLIB_WIN32_APP */
90 static const char digits
[17] = "0123456789ABCDEF";
91 static const char ldigits
[17] = "0123456789abcdef";
94 __atox(char *buf
, char * end
, unsigned int num
, unsigned int radix
, int width
,
105 *op
++ = digits
[num
% radix
];
110 if (width
&& (width
> retval
)) {
111 width
= width
- retval
;
119 while (op
!= buffer
) {
130 BCMROMFN(vsnprintf
)(char *buf
, size_t size
, const char *fmt
, va_list ap
)
135 unsigned char *tmpptr
;
146 end
= buf
+ size
- 1;
151 size
= end
- buf
+ 1;
181 while (*iptr
&& bcm_isdigit(*iptr
)) {
182 width
+= (*iptr
- '0');
184 if (bcm_isdigit(*iptr
))
190 while (*iptr
&& bcm_isdigit(*iptr
)) {
191 width2
+= (*iptr
- '0');
193 if (bcm_isdigit(*iptr
)) width2
*= 10;
205 tmpptr
= (unsigned char *) va_arg(ap
, unsigned char *);
206 if (!tmpptr
) tmpptr
= (unsigned char *) "(null)";
207 if ((width
== 0) & (width2
== 0)) {
216 while (width
&& *tmpptr
) {
239 optr
+= __atox(optr
, end
, i
, 10, width
, digits
);
242 x
= va_arg(ap
, unsigned int);
243 optr
+= __atox(optr
, end
, x
, 10, width
, digits
);
247 x
= va_arg(ap
, unsigned int);
248 optr
+= __atox(optr
, end
, x
, 16, width
,
249 (*iptr
== 'X') ? digits
: ldigits
);
253 x
= va_arg(ap
, unsigned int);
254 optr
+= __atox(optr
, end
, x
, 16, 8,
255 (*iptr
== 'P') ? digits
: ldigits
);
275 return (int)(optr
- buf
);
278 return (int)(end
- buf
);
284 BCMROMFN(snprintf
)(char *buf
, size_t bufsize
, const char *fmt
, ...)
290 r
= vsnprintf(buf
, bufsize
, fmt
, ap
);
295 #endif /* !BCMROMOFFLOAD */
297 #endif /* BCMSTDLIB_WIN32_APP */
299 #ifndef BCMSTDLIB_SNPRINTF_ONLY
301 #ifndef BCMROMOFFLOAD
304 BCMROMFN(vsprintf
)(char *buf
, const char *fmt
, va_list ap
)
306 return (vsnprintf(buf
, INT_MAX
, fmt
, ap
));
311 BCMROMFN(sprintf
)(char *buf
, const char *fmt
, ...)
317 count
= vsprintf(buf
, fmt
, ap
);
325 BCMROMFN(memmove
)(void *dest
, const void *src
, size_t n
)
328 const unsigned char *s
;
330 /* only use memmove if dest is after source, otherwise use memcopy */
332 return memcpy(dest
, src
, n
);
334 /* do what memcpy does, but starting at the end and work backwords */
335 d
= (unsigned char *)dest
+ (n
-1);
336 s
= (const unsigned char *)src
+ (n
-1);
348 BCMROMFN(memcmp
)(const void *s1
, const void *s2
, size_t n
)
350 const unsigned char *ss1
;
351 const unsigned char *ss2
;
353 ss1
= (const unsigned char *)s1
;
354 ss2
= (const unsigned char *)s2
;
369 /* Skip over functions that are being used from DriverLibrary to save space */
371 BCMROMFN(strcpy
)(char *dest
, const char *src
)
375 while ((*ptr
++ = *src
++) != '\0')
382 BCMROMFN(strncpy
)(char *dest
, const char *src
, size_t n
)
390 while (p
!= endp
&& (*p
++ = *src
++) != '\0')
393 /* zero fill remainder */
401 BCMROMFN(strlen
)(const char *s
)
414 BCMROMFN(strcmp
)(const char *s1
, const char *s2
)
434 BCMROMFN(strncmp
)(const char *s1
, const char *s2
, size_t n
)
436 while (*s2
&& *s1
&& n
) {
456 BCMROMFN(strchr
)(const char *str
, int c
)
458 char *x
= (char *)str
;
460 while (*x
!= (char)c
) {
468 BCMROMFN(strrchr
)(const char *str
, int c
)
473 if (*str
== (char) c
)
475 } while (*str
++ != '\0');
480 /* Skip over functions that are being used from DriverLibrary to save space */
483 BCMROMFN(strcat
)(char *d
, const char *s
)
485 strcpy(&d
[strlen(d
)], s
);
491 BCMROMFN(index
)(const char *s
, int c
)
493 /* Terminating NUL is considered part of string */
502 /* Skip over functions that are being used from DriverLibrary to save space */
505 BCMROMFN(strstr
)(const char *s
, const char *substr
)
507 int substr_len
= strlen(substr
);
510 if (strncmp(s
, substr
, substr_len
) == 0)
518 BCMROMFN(strspn
)(const char *s
, const char *accept
)
522 while (s
[count
] && index(accept
, s
[count
]))
529 BCMROMFN(strcspn
)(const char *s
, const char *reject
)
533 while (s
[count
] && !index(reject
, s
[count
]))
540 BCMROMFN(memchr
)(const void *s
, int c
, size_t n
)
543 const unsigned char *ptr
= s
;
546 if (*ptr
== (unsigned char)c
)
556 BCMROMFN(strtoul
)(const char *cp
, char **endp
, int base
)
563 while (bcm_isspace(*cp
))
568 else if (cp
[0] == '-') {
575 if ((cp
[1] == 'x') || (cp
[1] == 'X')) {
584 } else if (base
== 16 && (cp
[0] == '0') && ((cp
[1] == 'x') || (cp
[1] == 'X'))) {
590 while (bcm_isxdigit(*cp
) &&
591 (value
= bcm_isdigit(*cp
) ? *cp
- '0' : bcm_toupper(*cp
) - 'A' + 10) <
593 result
= result
* base
+ value
;
598 result
= (ulong
)(result
* -1);
605 #endif /* !BCMROMOFFLOAD */
608 /* memset is not in ROM offload because it is used directly by the compiler in
609 * structure assignments/character array initialization with "".
612 memset(void *dest
, int c
, size_t n
)
620 /* 8 min because we have to create w */
621 if ((n
>= 8) && (((uint
)dest
& 3) == 0)) {
627 ch
= (unsigned char)(c
& 0xff);
636 d
= (unsigned char *)dw
;
639 *d
++ = (unsigned char)c
;
646 /* memcpy is not in ROM offload because it is used directly by the compiler in
647 * structure assignments.
650 memcpy(void *dest
, const void *src
, size_t n
)
655 const unsigned char *s
;
657 sw
= (const uint32
*)src
;
659 if ((n
>= 4) && (((uint
)src
& 3) == 0) && (((uint
)dest
& 3) == 0)) {
665 d
= (unsigned char *)dw
;
666 s
= (const unsigned char *)sw
;
676 /* Include printf if it has already not been defined as NULL */
679 printf(const char *fmt
, ...)
683 char buffer
[PRINTF_BUFLEN
+ 1];
686 count
= vsnprintf(buffer
, sizeof(buffer
), fmt
, ap
);
689 for (i
= 0; i
< count
; i
++) {
693 if (buffer
[i
] == '\n')
703 fputs(const char *s
, FILE *stream
/* UNUSED */)
720 fputc(int c
, FILE *stream
/* UNUSED */)
723 return (int)(unsigned char)c
;
730 static unsigned long seed
= 1;
736 t
= 16807 * lo
- 2836 * hi
;
737 if (t
<= 0) t
+= 0x7fffffff;
741 #endif /* BCMSTDLIB_SNPRINTF_ONLY */