diff --git a/docs/version-format.md b/docs/version-format.md
new file mode 100644
index 000000000..40b3a8464
--- /dev/null
+++ b/docs/version-format.md
@@ -0,0 +1,58 @@
+Version Formats
+===============
+
+In some circumstances fwupd has to convert from a unsigned integer version
+number into something that has either been used in documentation or has been
+defined in some specification.
+A good example here is the UEFI ESRT table, which specifies a `uint32_t` for
+the version but does not specify how this should be formatted for the user.
+
+As is typical in underspecified specifications, vendors have converted the
+integer in different ways. For instance, Dell uses version strings like 1.2.3
+and Microsoft use versions like 1.2.3.4.
+
+The fwudp daemon can match specific devices and apply the correct version style
+using quirk files. The version format can also be specified in the firmware
+`metainfo.xml` file so that the new version is correctly shown, and so that it
+matches on the LVFS website.
+
+The current version formats supported by fwupd and the LVFS are:
+
+ * `plain`: Use plain integer version numbers with no dots, e.g. `AABBCCDD`
+ * `quad`: Use Dell-style `AA.BB.CC.DD` version numbers
+ * `triplet`: Use Microsoft-style `AA.BB.CCDD` version numbers
+ * `pair`: Use two `AABB.CCDD` version numbers
+ * `bcd`: Use binary coded decimal notation
+ * `intel-me`: Use Intel ME-style notation (`aaa+11.bbbbb.CC.DDDD`)
+ * `intel-me2`: Use alternate Intel ME-style-style `A.B.CC.DDDD` notation
+
+These can be specified in quirk files like this:
+
+ # Vendor Modelname
+ [Guid=5b92717b-2cad-4a96-a13b-9d65781df8bf]
+ VersionFormat = intel-me2
+
+...or in metainfo.xml files like this:
+
+
+ intel-me2
+
+
+Runtime requirements
+--------------------
+
+Versions of fwupd `< 1.2.0` can only support firmware updates with key values
+`LVFS::VersionFormat` of `quad` and `triplet`. Additionally, on older versions
+no quirk `VersionFormat` device fixups are supported.
+
+If want to use one of the additional version formats you should depend on a
+specific version of fwupd in the firmware file:
+
+
+ org.freedesktop.fwupd
+
+
+This is not *strictly* required, as the integer value can be used for update
+calculations if the version is specified in hex (e.g. `0x12345678`) in the
+`` tag, although the user might get a bit confused if the update
+version does not match the update description.
diff --git a/src/fu-common-version.c b/src/fu-common-version.c
index d86fe5698..bc98c2784 100644
--- a/src/fu-common-version.c
+++ b/src/fu-common-version.c
@@ -33,6 +33,8 @@ fu_common_version_format_from_string (const gchar *str)
return FU_VERSION_FORMAT_TRIPLET;
if (g_strcmp0 (str, "quad") == 0)
return FU_VERSION_FORMAT_QUAD;
+ if (g_strcmp0 (str, "intel-me2") == 0)
+ return FU_VERSION_FORMAT_INTEL_ME2;
if (g_strcmp0 (str, "bcd") == 0)
return FU_VERSION_FORMAT_BCD;
if (g_strcmp0 (str, "plain") == 0)
@@ -59,6 +61,8 @@ fu_common_version_format_to_string (FuVersionFormat kind)
return "triplet";
if (kind == FU_VERSION_FORMAT_QUAD)
return "quad";
+ if (kind == FU_VERSION_FORMAT_INTEL_ME2)
+ return "intel-me2";
if (kind == FU_VERSION_FORMAT_BCD)
return "bcd";
if (kind == FU_VERSION_FORMAT_PLAIN)
@@ -123,6 +127,14 @@ fu_common_version_from_uint32 (guint32 val, FuVersionFormat kind)
(val >> 16) & 0xff,
val & 0xffff);
}
+ if (kind == FU_VERSION_FORMAT_INTEL_ME2) {
+ /* A.B.CC.DDDD */
+ return g_strdup_printf ("%u.%u.%u.%u",
+ (val >> 28) & 0x0f,
+ (val >> 24) & 0x0f,
+ (val >> 16) & 0xff,
+ val & 0xffff);
+ }
return NULL;
}
diff --git a/src/fu-common-version.h b/src/fu-common-version.h
index 13cfe4040..8bcbcd059 100644
--- a/src/fu-common-version.h
+++ b/src/fu-common-version.h
@@ -17,7 +17,8 @@
* @FU_VERSION_FORMAT_TRIPLET: Use Microsoft-style AA.BB.CCDD version numbers
* @FU_VERSION_FORMAT_PAIR: Use two AABB.CCDD version numbers
* @FU_VERSION_FORMAT_BCD: Use binary coded decimal notation
- * @FU_VERSION_FORMAT_INTEL_ME: Use Intel ME-style notation
+ * @FU_VERSION_FORMAT_INTEL_ME: Use Intel ME-style bitshifted notation
+ * @FU_VERSION_FORMAT_INTEL_ME2: Use Intel ME-style A.B.CC.DDDD notation notation
*
* The flags used when parsing version numbers.
**/
@@ -29,6 +30,7 @@ typedef enum {
FU_VERSION_FORMAT_PAIR, /* Since: 1.2.0 */
FU_VERSION_FORMAT_BCD, /* Since: 1.2.0 */
FU_VERSION_FORMAT_INTEL_ME, /* Since: 1.2.0 */
+ FU_VERSION_FORMAT_INTEL_ME2, /* Since: 1.2.0 */
/*< private >*/
FU_VERSION_FORMAT_LAST
} FuVersionFormat;
diff --git a/src/fu-self-test.c b/src/fu-self-test.c
index faee350f8..3c774b558 100644
--- a/src/fu-self-test.c
+++ b/src/fu-self-test.c
@@ -2961,6 +2961,8 @@ fu_common_version_func (void)
{ 0xff000100, "4278190336", FU_VERSION_FORMAT_PLAIN },
{ 0x0, "11.0.0.0", FU_VERSION_FORMAT_INTEL_ME },
{ 0xffffffff, "18.31.255.65535", FU_VERSION_FORMAT_INTEL_ME },
+ { 0x0b32057a, "11.11.50.1402", FU_VERSION_FORMAT_INTEL_ME },
+ { 0xb8320d84, "11.8.50.3460", FU_VERSION_FORMAT_INTEL_ME2 },
{ 0, NULL }
};
struct {