cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

utprint.c (16844B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: utprint - Formatted printing routines
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12
     13#define _COMPONENT          ACPI_UTILITIES
     14ACPI_MODULE_NAME("utprint")
     15
     16#define ACPI_FORMAT_SIGN            0x01
     17#define ACPI_FORMAT_SIGN_PLUS       0x02
     18#define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
     19#define ACPI_FORMAT_ZERO            0x08
     20#define ACPI_FORMAT_LEFT            0x10
     21#define ACPI_FORMAT_UPPER           0x20
     22#define ACPI_FORMAT_PREFIX          0x40
     23/* Local prototypes */
     24static acpi_size
     25acpi_ut_bound_string_length(const char *string, acpi_size count);
     26
     27static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
     28
     29static char *acpi_ut_format_number(char *string,
     30				   char *end,
     31				   u64 number,
     32				   u8 base, s32 width, s32 precision, u8 type);
     33
     34static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
     35
     36/*******************************************************************************
     37 *
     38 * FUNCTION:    acpi_ut_bound_string_length
     39 *
     40 * PARAMETERS:  string              - String with boundary
     41 *              count               - Boundary of the string
     42 *
     43 * RETURN:      Length of the string. Less than or equal to Count.
     44 *
     45 * DESCRIPTION: Calculate the length of a string with boundary.
     46 *
     47 ******************************************************************************/
     48
     49static acpi_size
     50acpi_ut_bound_string_length(const char *string, acpi_size count)
     51{
     52	u32 length = 0;
     53
     54	while (*string && count) {
     55		length++;
     56		string++;
     57		count--;
     58	}
     59
     60	return (length);
     61}
     62
     63/*******************************************************************************
     64 *
     65 * FUNCTION:    acpi_ut_bound_string_output
     66 *
     67 * PARAMETERS:  string              - String with boundary
     68 *              end                 - Boundary of the string
     69 *              c                   - Character to be output to the string
     70 *
     71 * RETURN:      Updated position for next valid character
     72 *
     73 * DESCRIPTION: Output a character into a string with boundary check.
     74 *
     75 ******************************************************************************/
     76
     77static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
     78{
     79
     80	if (string < end) {
     81		*string = c;
     82	}
     83
     84	++string;
     85	return (string);
     86}
     87
     88/*******************************************************************************
     89 *
     90 * FUNCTION:    acpi_ut_put_number
     91 *
     92 * PARAMETERS:  string              - Buffer to hold reverse-ordered string
     93 *              number              - Integer to be converted
     94 *              base                - Base of the integer
     95 *              upper               - Whether or not using upper cased digits
     96 *
     97 * RETURN:      Updated position for next valid character
     98 *
     99 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
    100 *              reversed ordered number without the trailing zero.
    101 *
    102 ******************************************************************************/
    103
    104static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
    105{
    106	const char *digits;
    107	u64 digit_index;
    108	char *pos;
    109
    110	pos = string;
    111	digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
    112
    113	if (number == 0) {
    114		*(pos++) = '0';
    115	} else {
    116		while (number) {
    117			(void)acpi_ut_divide(number, base, &number,
    118					     &digit_index);
    119			*(pos++) = digits[digit_index];
    120		}
    121	}
    122
    123	/* *(Pos++) = '0'; */
    124	return (pos);
    125}
    126
    127/*******************************************************************************
    128 *
    129 * FUNCTION:    acpi_ut_scan_number
    130 *
    131 * PARAMETERS:  string              - String buffer
    132 *              number_ptr          - Where the number is returned
    133 *
    134 * RETURN:      Updated position for next valid character
    135 *
    136 * DESCRIPTION: Scan a string for a decimal integer.
    137 *
    138 ******************************************************************************/
    139
    140const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
    141{
    142	u64 number = 0;
    143
    144	while (isdigit((int)*string)) {
    145		acpi_ut_short_multiply(number, 10, &number);
    146		number += *(string++) - '0';
    147	}
    148
    149	*number_ptr = number;
    150	return (string);
    151}
    152
    153/*******************************************************************************
    154 *
    155 * FUNCTION:    acpi_ut_print_number
    156 *
    157 * PARAMETERS:  string              - String buffer
    158 *              number              - The number to be converted
    159 *
    160 * RETURN:      Updated position for next valid character
    161 *
    162 * DESCRIPTION: Print a decimal integer into a string.
    163 *
    164 ******************************************************************************/
    165
    166const char *acpi_ut_print_number(char *string, u64 number)
    167{
    168	char ascii_string[20];
    169	const char *pos1;
    170	char *pos2;
    171
    172	pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
    173	pos2 = string;
    174
    175	while (pos1 != ascii_string) {
    176		*(pos2++) = *(--pos1);
    177	}
    178
    179	*pos2 = 0;
    180	return (string);
    181}
    182
    183/*******************************************************************************
    184 *
    185 * FUNCTION:    acpi_ut_format_number
    186 *
    187 * PARAMETERS:  string              - String buffer with boundary
    188 *              end                 - Boundary of the string
    189 *              number              - The number to be converted
    190 *              base                - Base of the integer
    191 *              width               - Field width
    192 *              precision           - Precision of the integer
    193 *              type                - Special printing flags
    194 *
    195 * RETURN:      Updated position for next valid character
    196 *
    197 * DESCRIPTION: Print an integer into a string with any base and any precision.
    198 *
    199 ******************************************************************************/
    200
    201static char *acpi_ut_format_number(char *string,
    202				   char *end,
    203				   u64 number,
    204				   u8 base, s32 width, s32 precision, u8 type)
    205{
    206	char *pos;
    207	char sign;
    208	char zero;
    209	u8 need_prefix;
    210	u8 upper;
    211	s32 i;
    212	char reversed_string[66];
    213
    214	/* Parameter validation */
    215
    216	if (base < 2 || base > 16) {
    217		return (NULL);
    218	}
    219
    220	if (type & ACPI_FORMAT_LEFT) {
    221		type &= ~ACPI_FORMAT_ZERO;
    222	}
    223
    224	need_prefix = ((type & ACPI_FORMAT_PREFIX)
    225		       && base != 10) ? TRUE : FALSE;
    226	upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
    227	zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
    228
    229	/* Calculate size according to sign and prefix */
    230
    231	sign = '\0';
    232	if (type & ACPI_FORMAT_SIGN) {
    233		if ((s64)number < 0) {
    234			sign = '-';
    235			number = -(s64)number;
    236			width--;
    237		} else if (type & ACPI_FORMAT_SIGN_PLUS) {
    238			sign = '+';
    239			width--;
    240		} else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
    241			sign = ' ';
    242			width--;
    243		}
    244	}
    245	if (need_prefix) {
    246		width--;
    247		if (base == 16) {
    248			width--;
    249		}
    250	}
    251
    252	/* Generate full string in reverse order */
    253
    254	pos = acpi_ut_put_number(reversed_string, number, base, upper);
    255	i = (s32)ACPI_PTR_DIFF(pos, reversed_string);
    256
    257	/* Printing 100 using %2d gives "100", not "00" */
    258
    259	if (i > precision) {
    260		precision = i;
    261	}
    262
    263	width -= precision;
    264
    265	/* Output the string */
    266
    267	if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
    268		while (--width >= 0) {
    269			string = acpi_ut_bound_string_output(string, end, ' ');
    270		}
    271	}
    272	if (sign) {
    273		string = acpi_ut_bound_string_output(string, end, sign);
    274	}
    275	if (need_prefix) {
    276		string = acpi_ut_bound_string_output(string, end, '0');
    277		if (base == 16) {
    278			string =
    279			    acpi_ut_bound_string_output(string, end,
    280							upper ? 'X' : 'x');
    281		}
    282	}
    283	if (!(type & ACPI_FORMAT_LEFT)) {
    284		while (--width >= 0) {
    285			string = acpi_ut_bound_string_output(string, end, zero);
    286		}
    287	}
    288
    289	while (i <= --precision) {
    290		string = acpi_ut_bound_string_output(string, end, '0');
    291	}
    292	while (--i >= 0) {
    293		string = acpi_ut_bound_string_output(string, end,
    294						     reversed_string[i]);
    295	}
    296	while (--width >= 0) {
    297		string = acpi_ut_bound_string_output(string, end, ' ');
    298	}
    299
    300	return (string);
    301}
    302
    303/*******************************************************************************
    304 *
    305 * FUNCTION:    vsnprintf
    306 *
    307 * PARAMETERS:  string              - String with boundary
    308 *              size                - Boundary of the string
    309 *              format              - Standard printf format
    310 *              args                - Argument list
    311 *
    312 * RETURN:      Number of bytes actually written.
    313 *
    314 * DESCRIPTION: Formatted output to a string using argument list pointer.
    315 *
    316 ******************************************************************************/
    317
    318int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
    319{
    320	u8 base;
    321	u8 type;
    322	s32 width;
    323	s32 precision;
    324	char qualifier;
    325	u64 number;
    326	char *pos;
    327	char *end;
    328	char c;
    329	const char *s;
    330	const void *p;
    331	s32 length;
    332	int i;
    333
    334	pos = string;
    335
    336	if (size != ACPI_UINT32_MAX) {
    337		end = string + size;
    338	} else {
    339		end = ACPI_CAST_PTR(char, ACPI_UINT32_MAX);
    340	}
    341
    342	for (; *format; ++format) {
    343		if (*format != '%') {
    344			pos = acpi_ut_bound_string_output(pos, end, *format);
    345			continue;
    346		}
    347
    348		type = 0;
    349		base = 10;
    350
    351		/* Process sign */
    352
    353		do {
    354			++format;
    355			if (*format == '#') {
    356				type |= ACPI_FORMAT_PREFIX;
    357			} else if (*format == '0') {
    358				type |= ACPI_FORMAT_ZERO;
    359			} else if (*format == '+') {
    360				type |= ACPI_FORMAT_SIGN_PLUS;
    361			} else if (*format == ' ') {
    362				type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
    363			} else if (*format == '-') {
    364				type |= ACPI_FORMAT_LEFT;
    365			} else {
    366				break;
    367			}
    368
    369		} while (1);
    370
    371		/* Process width */
    372
    373		width = -1;
    374		if (isdigit((int)*format)) {
    375			format = acpi_ut_scan_number(format, &number);
    376			width = (s32)number;
    377		} else if (*format == '*') {
    378			++format;
    379			width = va_arg(args, int);
    380			if (width < 0) {
    381				width = -width;
    382				type |= ACPI_FORMAT_LEFT;
    383			}
    384		}
    385
    386		/* Process precision */
    387
    388		precision = -1;
    389		if (*format == '.') {
    390			++format;
    391			if (isdigit((int)*format)) {
    392				format = acpi_ut_scan_number(format, &number);
    393				precision = (s32)number;
    394			} else if (*format == '*') {
    395				++format;
    396				precision = va_arg(args, int);
    397			}
    398
    399			if (precision < 0) {
    400				precision = 0;
    401			}
    402		}
    403
    404		/* Process qualifier */
    405
    406		qualifier = -1;
    407		if (*format == 'h' || *format == 'l' || *format == 'L') {
    408			qualifier = *format;
    409			++format;
    410
    411			if (qualifier == 'l' && *format == 'l') {
    412				qualifier = 'L';
    413				++format;
    414			}
    415		}
    416
    417		switch (*format) {
    418		case '%':
    419
    420			pos = acpi_ut_bound_string_output(pos, end, '%');
    421			continue;
    422
    423		case 'c':
    424
    425			if (!(type & ACPI_FORMAT_LEFT)) {
    426				while (--width > 0) {
    427					pos =
    428					    acpi_ut_bound_string_output(pos,
    429									end,
    430									' ');
    431				}
    432			}
    433
    434			c = (char)va_arg(args, int);
    435			pos = acpi_ut_bound_string_output(pos, end, c);
    436
    437			while (--width > 0) {
    438				pos =
    439				    acpi_ut_bound_string_output(pos, end, ' ');
    440			}
    441			continue;
    442
    443		case 's':
    444
    445			s = va_arg(args, char *);
    446			if (!s) {
    447				s = "<NULL>";
    448			}
    449			length = (s32)acpi_ut_bound_string_length(s, precision);
    450			if (!(type & ACPI_FORMAT_LEFT)) {
    451				while (length < width--) {
    452					pos =
    453					    acpi_ut_bound_string_output(pos,
    454									end,
    455									' ');
    456				}
    457			}
    458
    459			for (i = 0; i < length; ++i) {
    460				pos = acpi_ut_bound_string_output(pos, end, *s);
    461				++s;
    462			}
    463
    464			while (length < width--) {
    465				pos =
    466				    acpi_ut_bound_string_output(pos, end, ' ');
    467			}
    468			continue;
    469
    470		case 'o':
    471
    472			base = 8;
    473			break;
    474
    475		case 'X':
    476
    477			type |= ACPI_FORMAT_UPPER;
    478			ACPI_FALLTHROUGH;
    479
    480		case 'x':
    481
    482			base = 16;
    483			break;
    484
    485		case 'd':
    486		case 'i':
    487
    488			type |= ACPI_FORMAT_SIGN;
    489
    490		case 'u':
    491
    492			break;
    493
    494		case 'p':
    495
    496			if (width == -1) {
    497				width = 2 * sizeof(void *);
    498				type |= ACPI_FORMAT_ZERO;
    499			}
    500
    501			p = va_arg(args, void *);
    502			pos =
    503			    acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
    504						  16, width, precision, type);
    505			continue;
    506
    507		default:
    508
    509			pos = acpi_ut_bound_string_output(pos, end, '%');
    510			if (*format) {
    511				pos =
    512				    acpi_ut_bound_string_output(pos, end,
    513								*format);
    514			} else {
    515				--format;
    516			}
    517			continue;
    518		}
    519
    520		if (qualifier == 'L') {
    521			number = va_arg(args, u64);
    522			if (type & ACPI_FORMAT_SIGN) {
    523				number = (s64)number;
    524			}
    525		} else if (qualifier == 'l') {
    526			number = va_arg(args, unsigned long);
    527			if (type & ACPI_FORMAT_SIGN) {
    528				number = (s32)number;
    529			}
    530		} else if (qualifier == 'h') {
    531			number = (u16)va_arg(args, int);
    532			if (type & ACPI_FORMAT_SIGN) {
    533				number = (s16)number;
    534			}
    535		} else {
    536			number = va_arg(args, unsigned int);
    537			if (type & ACPI_FORMAT_SIGN) {
    538				number = (signed int)number;
    539			}
    540		}
    541
    542		pos = acpi_ut_format_number(pos, end, number, base,
    543					    width, precision, type);
    544	}
    545
    546	if (size > 0) {
    547		if (pos < end) {
    548			*pos = '\0';
    549		} else {
    550			end[-1] = '\0';
    551		}
    552	}
    553
    554	return ((int)ACPI_PTR_DIFF(pos, string));
    555}
    556
    557/*******************************************************************************
    558 *
    559 * FUNCTION:    snprintf
    560 *
    561 * PARAMETERS:  string              - String with boundary
    562 *              size                - Boundary of the string
    563 *              Format, ...         - Standard printf format
    564 *
    565 * RETURN:      Number of bytes actually written.
    566 *
    567 * DESCRIPTION: Formatted output to a string.
    568 *
    569 ******************************************************************************/
    570
    571int snprintf(char *string, acpi_size size, const char *format, ...)
    572{
    573	va_list args;
    574	int length;
    575
    576	va_start(args, format);
    577	length = vsnprintf(string, size, format, args);
    578	va_end(args);
    579
    580	return (length);
    581}
    582
    583/*******************************************************************************
    584 *
    585 * FUNCTION:    sprintf
    586 *
    587 * PARAMETERS:  string              - String with boundary
    588 *              Format, ...         - Standard printf format
    589 *
    590 * RETURN:      Number of bytes actually written.
    591 *
    592 * DESCRIPTION: Formatted output to a string.
    593 *
    594 ******************************************************************************/
    595
    596int sprintf(char *string, const char *format, ...)
    597{
    598	va_list args;
    599	int length;
    600
    601	va_start(args, format);
    602	length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
    603	va_end(args);
    604
    605	return (length);
    606}
    607
    608#ifdef ACPI_APPLICATION
    609/*******************************************************************************
    610 *
    611 * FUNCTION:    vprintf
    612 *
    613 * PARAMETERS:  format              - Standard printf format
    614 *              args                - Argument list
    615 *
    616 * RETURN:      Number of bytes actually written.
    617 *
    618 * DESCRIPTION: Formatted output to stdout using argument list pointer.
    619 *
    620 ******************************************************************************/
    621
    622int vprintf(const char *format, va_list args)
    623{
    624	acpi_cpu_flags flags;
    625	int length;
    626
    627	flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
    628	length = vsnprintf(acpi_gbl_print_buffer,
    629			   sizeof(acpi_gbl_print_buffer), format, args);
    630
    631	(void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
    632	acpi_os_release_lock(acpi_gbl_print_lock, flags);
    633
    634	return (length);
    635}
    636
    637/*******************************************************************************
    638 *
    639 * FUNCTION:    printf
    640 *
    641 * PARAMETERS:  Format, ...         - Standard printf format
    642 *
    643 * RETURN:      Number of bytes actually written.
    644 *
    645 * DESCRIPTION: Formatted output to stdout.
    646 *
    647 ******************************************************************************/
    648
    649int printf(const char *format, ...)
    650{
    651	va_list args;
    652	int length;
    653
    654	va_start(args, format);
    655	length = vprintf(format, args);
    656	va_end(args);
    657
    658	return (length);
    659}
    660
    661/*******************************************************************************
    662 *
    663 * FUNCTION:    vfprintf
    664 *
    665 * PARAMETERS:  file                - File descriptor
    666 *              format              - Standard printf format
    667 *              args                - Argument list
    668 *
    669 * RETURN:      Number of bytes actually written.
    670 *
    671 * DESCRIPTION: Formatted output to a file using argument list pointer.
    672 *
    673 ******************************************************************************/
    674
    675int vfprintf(FILE * file, const char *format, va_list args)
    676{
    677	acpi_cpu_flags flags;
    678	int length;
    679
    680	flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
    681	length = vsnprintf(acpi_gbl_print_buffer,
    682			   sizeof(acpi_gbl_print_buffer), format, args);
    683
    684	(void)fwrite(acpi_gbl_print_buffer, length, 1, file);
    685	acpi_os_release_lock(acpi_gbl_print_lock, flags);
    686
    687	return (length);
    688}
    689
    690/*******************************************************************************
    691 *
    692 * FUNCTION:    fprintf
    693 *
    694 * PARAMETERS:  file                - File descriptor
    695 *              Format, ...         - Standard printf format
    696 *
    697 * RETURN:      Number of bytes actually written.
    698 *
    699 * DESCRIPTION: Formatted output to a file.
    700 *
    701 ******************************************************************************/
    702
    703int fprintf(FILE * file, const char *format, ...)
    704{
    705	va_list args;
    706	int length;
    707
    708	va_start(args, format);
    709	length = vfprintf(file, format, args);
    710	va_end(args);
    711
    712	return (length);
    713}
    714#endif