chiark / gitweb /
efi: fix Usec vs. USec
[elogind.git] / src / shared / efivars.c
index 784ff364d9802c621774f256527f205e1c13ce12..d5cb88cff1504475ca3a1da9242ab25063a681eb 100644 (file)
@@ -93,45 +93,7 @@ int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t *attribute, v
         return 0;
 }
 
-static int read_bogomips(unsigned long *u) {
-        _cleanup_fclose_ FILE *f = NULL;
-
-        f = fopen("/proc/cpuinfo", "re");
-        if (!f)
-                return -errno;
-
-        while (!feof(f)) {
-                char line[LINE_MAX];
-                char *x;
-                unsigned long a, b;
-
-                if (!fgets(line, sizeof(line), f))
-                        return -EIO;
-
-                char_array_0(line);
-                truncate_nl(line);
-
-                if (!startswith(line, "bogomips"))
-                        continue;
-
-                x = line + 8;
-                x += strspn(x, WHITESPACE);
-                if (*x != ':')
-                        continue;
-                x++;
-                x += strspn(x, WHITESPACE);
-
-                if (sscanf(x, "%lu.%lu", &a, &b) != 2)
-                        continue;
-
-                *u = a * 1000000L + b * 10000L;
-                return 0;
-        }
-
-        return -EIO;
-}
-
-static int read_ticks(sd_id128_t vendor, const char *name, unsigned long speed, usec_t *u) {
+static int read_usec(sd_id128_t vendor, const char *name, usec_t *u) {
         _cleanup_free_ void *i = NULL;
         _cleanup_free_ char *j = NULL;
         size_t is;
@@ -153,38 +115,22 @@ static int read_ticks(sd_id128_t vendor, const char *name, unsigned long speed,
         if (r < 0)
                 return r;
 
-        *u = USEC_PER_SEC * x / speed;
+        *u = x;
         return 0;
 }
 
 static int get_boot_usec(usec_t *firmware, usec_t *loader) {
         uint64_t x, y;
         int r;
-        unsigned long bogomips;
 
         assert(firmware);
         assert(loader);
 
-        /* Returns the usec after the CPU was turned on. The two
-         * timestamps are: the firmware finished, and the boot loader
-         * finished. */
-
-        /* We assume that the kernel's bogomips value is calibrated to
-         * twice the CPU frequency, and use this to convert the TSC
-         * ticks into usec. Of course, bogomips are only vaguely
-         * defined. If this breaks one day we can come up with
-         * something better. However, for now this saves us from doing
-         * a local calibration loop. */
-
-        r = read_bogomips(&bogomips);
+        r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeInitUSec", &x);
         if (r < 0)
                 return r;
 
-        r = read_ticks(EFI_VENDOR_LOADER, "LoaderTicksInit", bogomips / 2, &x);
-        if (r < 0)
-                return r;
-
-        r = read_ticks(EFI_VENDOR_LOADER, "LoaderTicksExec", bogomips / 2, &y);
+        r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeExecUSec", &y);
         if (r < 0)
                 return r;
 
@@ -235,3 +181,33 @@ int efi_get_boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, d
 
         return 0;
 }
+
+int efi_get_loader_device_part_uuid(sd_id128_t *u) {
+        _cleanup_free_ void *s = NULL;
+        _cleanup_free_ char *p = NULL;
+        size_t ss;
+        int r, parsed[16];
+        unsigned i;
+
+        assert(u);
+
+        r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderDevicePartUUID", NULL, &s, &ss);
+        if (r < 0)
+                return r;
+
+        p = utf16_to_utf8(s, ss);
+        if (!p)
+                return -ENOMEM;
+
+        if (sscanf(p, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                   &parsed[0], &parsed[1], &parsed[2], &parsed[3],
+                   &parsed[4], &parsed[5], &parsed[6], &parsed[7],
+                   &parsed[8], &parsed[9], &parsed[10], &parsed[11],
+                   &parsed[12], &parsed[13], &parsed[14], &parsed[15]) != 16)
+                return -EIO;
+
+        for (i = 0; i < ELEMENTSOF(parsed); i++)
+                u->bytes[i] = parsed[i];
+
+        return 0;
+}