[PATCH 1/1] efi_loader: printing UEFI revision in helloworld.efi

Heinrich Schuchardt heinrich.schuchardt at canonical.com
Fri Sep 2 03:09:44 CEST 2022



On 9/2/22 01:52, Simon Glass wrote:
> Hi Heinrich,
> 
> 
> On Thu, 1 Sept 2022 at 14:44, Heinrich Schuchardt
> <heinrich.schuchardt at canonical.com> wrote:
>>
>> We need to support multiple digits in the parts of the UEFI verision
>> number. E.g.
>>
>>      EFI_SPECIFICATION_VERSION = (123 << 16) | 456
>>
>> must be printed as
>>
>>      123.45.6
>>
>> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
>> ---
>>   lib/efi_loader/helloworld.c | 66 ++++++++++++++++++++++++++++++-------
>>   1 file changed, 54 insertions(+), 12 deletions(-)
> 
> Gosh, I'm not sure what to make of this! Could uint2dec() use strtoul()?

This is standalone code. We cannot call any library functions here and 
we convert unsigned to wide string and not string to unsigned.

Best regards

Heinrich

> 
> Regards,
> Simon
> 
> 
>>
>> diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
>> index 10666dc0f2..d565f32745 100644
>> --- a/lib/efi_loader/helloworld.c
>> +++ b/lib/efi_loader/helloworld.c
>> @@ -29,24 +29,66 @@ static struct efi_system_table *systable;
>>   static struct efi_boot_services *boottime;
>>   static struct efi_simple_text_output_protocol *con_out;
>>
>> +/*
>> + * Print an unsigned 32bit value as decimal number to an u16 string
>> + *
>> + * @value:     value to be printed
>> + * @buf:       pointer to buffer address
>> + *             on return position of terminating zero word
>> + */
>> +static void uint2dec(u32 value, u16 **buf)
>> +{
>> +       u16 *pos = *buf;
>> +       int i;
>> +       u16 c;
>> +       u64 f;
>> +
>> +       /*
>> +        * Increment by .5 and multiply with
>> +        * (2 << 60) / 1,000,000,000 = 0x44B82FA0.9B5A52CC
>> +        * to move the first digit to bit 60-63.
>> +        */
>> +       f = 0x225C17D0;
>> +       f += (0x9B5A52DULL * value) >> 28;
>> +       f += 0x44B82FA0ULL * value;
>> +
>> +       for (i = 0; i < 10; ++i) {
>> +               /* Write current digit */
>> +               c = f >> 60;
>> +               if (c || pos != *buf)
>> +                       *pos++ = c + '0';
>> +               /* Eliminate current digit */
>> +               f &= 0xfffffffffffffff;
>> +               /* Get next digit */
>> +               f *= 0xaULL;
>> +       }
>> +       if (pos == *buf)
>> +               *pos++ = '0';
>> +       *pos = 0;
>> +       *buf = pos;
>> +}
>> +
>>   /**
>>    * print_uefi_revision() - print UEFI revision number
>>    */
>>   static void print_uefi_revision(void)
>>   {
>> -       u16 rev[] = u"0.0.0";
>> -
>> -       rev[0] = (systable->hdr.revision >> 16) + '0';
>> -       rev[4] = systable->hdr.revision & 0xffff;
>> -       for (; rev[4] >= 10;) {
>> -               rev[4] -= 10;
>> -               ++rev[2];
>> +       u16 rev[13] = {0};
>> +       u16 *buf = rev;
>> +       u16 digit;
>> +
>> +       uint2dec(systable->hdr.revision >> 16, &buf);
>> +       *buf++ = '.';
>> +       uint2dec(systable->hdr.revision & 0xffff, &buf);
>> +
>> +       /* Minor revision is only to be shown if non-zero */
>> +       digit = *--buf;
>> +       if (digit == '0') {
>> +               *buf = 0;
>> +       } else {
>> +               *buf++ = '.';
>> +               *buf = digit;
>>          }
>> -       /* Third digit is only to be shown if non-zero */
>> -       if (rev[4])
>> -               rev[4] += '0';
>> -       else
>> -               rev[3] = 0;
>>
>>          con_out->output_string(con_out, u"Running on UEFI ");
>>          con_out->output_string(con_out, rev);
>> --
>> 2.37.2
>>


More information about the U-Boot mailing list