Commit 8af1da40 authored by Mathieu Malaterre's avatar Mathieu Malaterre Committed by Michael Ellerman

powerpc/prom: Fix %u/%llx usage since prom_printf() change

In commit eae5f709 ("powerpc: Add __printf verification to
prom_printf") __printf attribute was added to prom_printf(), which
means GCC started warning about type/format mismatches. As part of
that commit we changed some "%lx" formats to "%llx" where the type is
actually unsigned long long.

Unfortunately prom_printf() doesn't know how to print "%llx", it just
prints a literal "lx", eg:

  reserved memory map:
    lx - lx
    lx - lx

prom_printf() also doesn't know how to print "%u" (only "%lu"), it
just prints a literal "u", eg:

  Max number of cores passed to firmware: u (NR_CPUS = 2048)

Instead of:

  Max number of cores passed to firmware: 2048 (NR_CPUS = 2048)

This commit adds support for the missing formatters.

Fixes: eae5f709 ("powerpc: Add __printf verification to prom_printf")
Reported-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Reported-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: default avatarMathieu Malaterre <malat@debian.org>
Tested-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 9a6d2022
...@@ -301,6 +301,10 @@ static void __init prom_print(const char *msg) ...@@ -301,6 +301,10 @@ static void __init prom_print(const char *msg)
} }
/*
* Both prom_print_hex & prom_print_dec takes an unsigned long as input so that
* we do not need __udivdi3 or __umoddi3 on 32bits.
*/
static void __init prom_print_hex(unsigned long val) static void __init prom_print_hex(unsigned long val)
{ {
int i, nibbles = sizeof(val)*2; int i, nibbles = sizeof(val)*2;
...@@ -341,6 +345,7 @@ static void __init prom_printf(const char *format, ...) ...@@ -341,6 +345,7 @@ static void __init prom_printf(const char *format, ...)
va_list args; va_list args;
unsigned long v; unsigned long v;
long vs; long vs;
int n = 0;
va_start(args, format); va_start(args, format);
for (p = format; *p != 0; p = q) { for (p = format; *p != 0; p = q) {
...@@ -359,6 +364,10 @@ static void __init prom_printf(const char *format, ...) ...@@ -359,6 +364,10 @@ static void __init prom_printf(const char *format, ...)
++q; ++q;
if (*q == 0) if (*q == 0)
break; break;
while (*q == 'l') {
++q;
++n;
}
switch (*q) { switch (*q) {
case 's': case 's':
++q; ++q;
...@@ -367,39 +376,55 @@ static void __init prom_printf(const char *format, ...) ...@@ -367,39 +376,55 @@ static void __init prom_printf(const char *format, ...)
break; break;
case 'x': case 'x':
++q; ++q;
v = va_arg(args, unsigned long); switch (n) {
case 0:
v = va_arg(args, unsigned int);
break;
case 1:
v = va_arg(args, unsigned long);
break;
case 2:
default:
v = va_arg(args, unsigned long long);
break;
}
prom_print_hex(v); prom_print_hex(v);
break; break;
case 'd': case 'u':
++q; ++q;
vs = va_arg(args, int); switch (n) {
if (vs < 0) { case 0:
prom_print("-"); v = va_arg(args, unsigned int);
vs = -vs; break;
case 1:
v = va_arg(args, unsigned long);
break;
case 2:
default:
v = va_arg(args, unsigned long long);
break;
} }
prom_print_dec(vs); prom_print_dec(v);
break; break;
case 'l': case 'd':
++q; ++q;
if (*q == 0) switch (n) {
case 0:
vs = va_arg(args, int);
break; break;
else if (*q == 'x') { case 1:
++q;
v = va_arg(args, unsigned long);
prom_print_hex(v);
} else if (*q == 'u') { /* '%lu' */
++q;
v = va_arg(args, unsigned long);
prom_print_dec(v);
} else if (*q == 'd') { /* %ld */
++q;
vs = va_arg(args, long); vs = va_arg(args, long);
if (vs < 0) { break;
prom_print("-"); case 2:
vs = -vs; default:
} vs = va_arg(args, long long);
prom_print_dec(vs); break;
} }
if (vs < 0) {
prom_print("-");
vs = -vs;
}
prom_print_dec(vs);
break; break;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment