1 /*---------------------------------------------------*/
3 /* Public Domain version of printf */
4 /* Rud Merriam, Compsult, Inc. Houston, Tx. */
5 /* For Embedded Systems Programming, 1991 */
7 /*---------------------------------------------------*/
8 #include "xil_printf.h"
10 #include "xil_assert.h"
15 static void padding( const s32 l_flag,const struct params_s *par);
16 static void outs(const charptr lp, struct params_s *par);
17 static s32 getnum( charptr* linep);
19 typedef struct params_s {
30 /*---------------------------------------------------*/
31 /* The purpose of this routine is to output data the */
32 /* same as the standard printf function without the */
33 /* overhead most run-time libraries involve. Usually */
34 /* the printf brings in many kilobytes of code and */
35 /* that is unacceptable in most embedded systems. */
36 /*---------------------------------------------------*/
39 /*---------------------------------------------------*/
41 /* This routine puts pad characters into the output */
44 static void padding( const s32 l_flag, const struct params_s *par)
48 if ((par->do_padding != 0) && (l_flag != 0) && (par->len < par->num1)) {
50 for (; i<(par->num1); i++) {
51 #ifdef STDOUT_BASEADDRESS
52 outbyte( par->pad_character);
58 /*---------------------------------------------------*/
60 /* This routine moves a string to the output buffer */
61 /* as directed by the padding and positioning flags. */
63 static void outs(const charptr lp, struct params_s *par)
67 /* pad on left if needed */
68 if(LocalPtr != NULL) {
69 par->len = (s32)strlen( LocalPtr);
71 padding( !(par->left_flag), par);
73 /* Move string to the buffer */
74 while (((*LocalPtr) != (char8)0) && ((par->num2) != 0)) {
76 #ifdef STDOUT_BASEADDRESS
82 /* Pad on right if needed */
83 /* CR 439175 - elided next stmt. Seemed bogus. */
84 /* par->len = strlen( lp) */
85 padding( par->left_flag, par);
88 /*---------------------------------------------------*/
90 /* This routine moves a number to the output buffer */
91 /* as directed by the padding and positioning flags. */
94 static void outnum( const s32 n, const s32 base, struct params_s *par)
99 const char8 digits[] = "0123456789ABCDEF";
101 for(i = 0; i<32; i++) {
105 /* Check if number is negative */
106 if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) {
115 /* Build number (backwards) in outbuf */
118 outbuf[i] = digits[(num % base)];
131 /* Move the converted number to the buffer and */
132 /* add in the padding where needed. */
133 par->len = (s32)strlen(outbuf);
134 padding( !(par->left_flag), par);
135 while (&outbuf[i] >= outbuf) {
136 #ifdef STDOUT_BASEADDRESS
137 outbyte( outbuf[i] );
141 padding( par->left_flag, par);
143 /*---------------------------------------------------*/
145 /* This routine moves a 64-bit number to the output */
146 /* buffer as directed by the padding and positioning */
149 #if defined (__aarch64__)
150 static void outnum1( const s64 n, const s32 base, params_t *par)
155 const char8 digits[] = "0123456789ABCDEF";
157 for(i = 0; i<64; i++) {
161 /* Check if number is negative */
162 if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) {
171 /* Build number (backwards) in outbuf */
174 outbuf[i] = digits[(num % base)];
187 /* Move the converted number to the buffer and */
188 /* add in the padding where needed. */
189 par->len = (s32)strlen(outbuf);
190 padding( !(par->left_flag), par);
191 while (&outbuf[i] >= outbuf) {
192 outbyte( outbuf[i] );
195 padding( par->left_flag, par);
198 /*---------------------------------------------------*/
200 /* This routine gets a number from the format */
203 static s32 getnum( charptr* linep)
206 s32 ResultIsDigit = 0;
211 ResultIsDigit = isdigit(((s32)*cptr));
213 while (ResultIsDigit != 0) {
215 n = ((n*10) + (((s32)*cptr) - (s32)'0'));
218 ResultIsDigit = isdigit(((s32)*cptr));
221 ResultIsDigit = isdigit(((s32)*cptr));
223 *linep = ((charptr )(cptr));
227 /*---------------------------------------------------*/
229 /* This routine operates just like a printf/sprintf */
230 /* routine. It outputs a set of data under the */
231 /* control of a formatting string. Not all of the */
232 /* standard C format control are supported. The ones */
233 /* provided are primarily those needed for embedded */
234 /* systems work. Primarily the floating point */
235 /* routines are omitted. Other formats could be */
236 /* added easily by following the examples shown for */
237 /* the supported formats. */
240 /* void esp_printf( const func_ptr f_ptr,
241 const charptr ctrl1, ...) */
242 #if HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE
243 void xil_printf( const char8 *ctrl1, ...){
244 XPVXenConsole_Printf(ctrl1);
247 void xil_printf( const char8 *ctrl1, ...)
250 #if defined (__aarch64__)
259 char8 *ctrl = (char8 *)ctrl1;
261 va_start( argp, ctrl1);
263 while ((ctrl != NULL) && (*ctrl != (char8)0)) {
265 /* move format string chars to buffer until a */
266 /* format control is found. */
268 #ifdef STDOUT_BASEADDRESS
275 /* initialize all the flags for this format. */
277 #if defined (__aarch64__)
280 par.unsigned_flag = 0;
283 par.pad_character = ' ';
299 if (isdigit((s32)ch) != 0) {
301 par.num2 = getnum(&ctrl);
305 par.pad_character = '0';
308 par.num1 = getnum(&ctrl);
318 switch (tolower((s32)ch)) {
320 #ifdef STDOUT_BASEADDRESS
337 #if defined (__aarch64__)
344 par.unsigned_flag = 1;
348 #if defined (__aarch64__)
350 outnum1((s64)va_arg(argp, s64), 10L, &par);
353 outnum( va_arg(argp, s32), 10L, &par);
356 outnum( va_arg(argp, s32), 10L, &par);
361 #if defined (__aarch64__)
362 par.unsigned_flag = 1;
363 outnum1((s64)va_arg(argp, s64), 16L, &par);
369 par.unsigned_flag = 1;
370 #if defined (__aarch64__)
371 if (long_flag != 0) {
372 outnum1((s64)va_arg(argp, s64), 16L, &par);
375 outnum((s32)va_arg(argp, s32), 16L, &par);
378 outnum((s32)va_arg(argp, s32), 16L, &par);
384 outs( va_arg( argp, char *), &par);
389 #ifdef STDOUT_BASEADDRESS
390 outbyte( va_arg( argp, s32));
398 #ifdef STDOUT_BASEADDRESS
399 outbyte( ((char8)0x07));
403 #ifdef STDOUT_BASEADDRESS
404 outbyte( ((char8)0x08));
408 #ifdef STDOUT_BASEADDRESS
409 outbyte( ((char8)0x0D));
413 #ifdef STDOUT_BASEADDRESS
414 outbyte( ((char8)0x0D));
415 outbyte( ((char8)0x0A));
419 #ifdef STDOUT_BASEADDRESS
443 /*---------------------------------------------------*/