aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2022-09-01 22:23:47 +0200
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2022-09-03 08:16:09 +0200
commita641e36fdbf09a6db046e9afe7531e9c623e70d3 (patch)
tree04c8876a998f4a8551b6afe9fb3fa7bff45b6cdb
parent67fe8cc0016756f3479288b3f67d59a517e512d5 (diff)
downloadu-boot-a641e36fdbf09a6db046e9afe7531e9c623e70d3.zip
u-boot-a641e36fdbf09a6db046e9afe7531e9c623e70d3.tar.gz
u-boot-a641e36fdbf09a6db046e9afe7531e9c623e70d3.tar.bz2
efi_loader: printing UEFI revision in helloworld.efi
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@canonical.com> Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r--lib/efi_loader/helloworld.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index 10666dc..d565f32 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);