diff --git a/include/stratosphere/firmware_version.hpp b/include/stratosphere/firmware_version.hpp
index 312c68c6..75089223 100644
--- a/include/stratosphere/firmware_version.hpp
+++ b/include/stratosphere/firmware_version.hpp
@@ -24,26 +24,20 @@ enum FirmwareVersion : u32 {
FirmwareVersion_400 = 3,
FirmwareVersion_500 = 4,
FirmwareVersion_600 = 5,
- FirmwareVersion_Current = FirmwareVersion_600,
+ FirmwareVersion_700 = 6,
+ FirmwareVersion_Current = FirmwareVersion_700,
FirmwareVersion_Max = 32,
};
-static inline FirmwareVersion GetRuntimeFirmwareVersion() {
- FirmwareVersion fw = FirmwareVersion_Min;
- if (kernelAbove200()) {
- fw = FirmwareVersion_200;
- }
- if (kernelAbove300()) {
- fw = FirmwareVersion_300;
- }
- if (kernelAbove400()) {
- fw = FirmwareVersion_400;
- }
- if (kernelAbove500()) {
- fw = FirmwareVersion_500;
- }
- if (kernelAbove600()) {
- fw = FirmwareVersion_600;
- }
- return fw;
-}
+enum AtmosphereTargetFirmware : u32 {
+ AtmosphereTargetFirmware_100 = 1,
+ AtmosphereTargetFirmware_200 = 2,
+ AtmosphereTargetFirmware_300 = 3,
+ AtmosphereTargetFirmware_400 = 4,
+ AtmosphereTargetFirmware_500 = 5,
+ AtmosphereTargetFirmware_600 = 6,
+ AtmosphereTargetFirmware_620 = 7,
+ AtmosphereTargetFirmware_700 = 8,
+};
+
+FirmwareVersion GetRuntimeFirmwareVersion();
diff --git a/source/firmware_version.cpp b/source/firmware_version.cpp
new file mode 100644
index 00000000..ec430aee
--- /dev/null
+++ b/source/firmware_version.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+static FirmwareVersion g_firmware_version = FirmwareVersion_Min;
+static bool g_HasCached = 0;
+static Mutex g_Mutex;
+
+static void _CacheValues(void)
+{
+ if (__atomic_load_n(&g_HasCached, __ATOMIC_SEQ_CST))
+ return;
+
+ mutexLock(&g_Mutex);
+
+ if (g_HasCached) {
+ mutexUnlock(&g_Mutex);
+ return;
+ }
+
+ u32 target_fw = 0;
+ GetAtmosphereApiVersion(nullptr, nullptr, nullptr, &target_fw, nullptr);
+
+ switch (static_cast(target_fw)) {
+ case AtmosphereTargetFirmware_100:
+ g_firmware_version = FirmwareVersion_100;
+ break;
+ case AtmosphereTargetFirmware_200:
+ g_firmware_version = FirmwareVersion_200;
+ break;
+ case AtmosphereTargetFirmware_300:
+ g_firmware_version = FirmwareVersion_300;
+ break;
+ case AtmosphereTargetFirmware_400:
+ g_firmware_version = FirmwareVersion_400;
+ break;
+ case AtmosphereTargetFirmware_500:
+ g_firmware_version = FirmwareVersion_500;
+ break;
+ case AtmosphereTargetFirmware_600:
+ case AtmosphereTargetFirmware_620:
+ g_firmware_version = FirmwareVersion_600;
+ break;
+ case AtmosphereTargetFirmware_700:
+ g_firmware_version = FirmwareVersion_700;
+ break;
+ default:
+ std::abort();
+ break;
+ }
+
+ __atomic_store_n(&g_HasCached, true, __ATOMIC_SEQ_CST);
+
+ mutexUnlock(&g_Mutex);
+}
+
+FirmwareVersion GetRuntimeFirmwareVersion() {
+ _CacheValues();
+ return g_firmware_version;
+}