diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 44d8ae11f..4bbcc3571 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -35,6 +35,13 @@ template<> struct CompileTimeAssert<true> {};
 #define CONCAT2(x, y) DO_CONCAT2(x, y)
 #define DO_CONCAT2(x, y) x ## y
 
+// helper macro to properly align structure members.
+// Calling INSERT_PADDING_BYTES will add a new member variable with a name like "pad121",
+// depending on the current source line to make sure variable names are unique.
+#define INSERT_PADDING_BYTES_HELPER1(x, y) x ## y
+#define INSERT_PADDING_BYTES_HELPER2(x, y) INSERT_PADDING_BYTES_HELPER1(x, y)
+#define INSERT_PADDING_BYTES(num_words) u8 INSERT_PADDING_BYTES_HELPER2(pad, __LINE__)[(num_words)]
+
 #ifndef _MSC_VER
 
 #include <errno.h>
diff --git a/src/core/hle/config_mem.cpp b/src/core/hle/config_mem.cpp
index 68d3071f5..b10c19d1d 100644
--- a/src/core/hle/config_mem.cpp
+++ b/src/core/hle/config_mem.cpp
@@ -3,60 +3,54 @@
 // Refer to the license.txt file included.
 
 #include "common/common_types.h"
-#include "common/logging/log.h"
+#include "common/common_funcs.h"
 
+#include "core/core.h"
+#include "core/mem_map.h"
 #include "core/hle/config_mem.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 namespace ConfigMem {
 
-enum {
-    KERNEL_VERSIONREVISION  = 0x1FF80001,
-    KERNEL_VERSIONMINOR     = 0x1FF80002,
-    KERNEL_VERSIONMAJOR     = 0x1FF80003,
-    UPDATEFLAG              = 0x1FF80004,
-    NSTID                   = 0x1FF80008,
-    SYSCOREVER              = 0x1FF80010,
-    UNITINFO                = 0x1FF80014,
-    KERNEL_CTRSDKVERSION    = 0x1FF80018,
-    APPMEMTYPE              = 0x1FF80030,
-    APPMEMALLOC             = 0x1FF80040,
-    FIRM_VERSIONREVISION    = 0x1FF80061,
-    FIRM_VERSIONMINOR       = 0x1FF80062,
-    FIRM_VERSIONMAJOR       = 0x1FF80063,
-    FIRM_SYSCOREVER         = 0x1FF80064,
-    FIRM_CTRSDKVERSION      = 0x1FF80068,
+struct ConfigMemDef {
+    u8  kernel_unk;                      // 0
+    u8  kernel_version_rev;              // 1
+    u8  kernel_version_min;              // 2
+    u8  kernel_version_maj;              // 3
+    u32 update_flag;                     // 4
+    u64 ns_tid;                          // 8
+    u32 sys_core_ver;                    // 10
+    u8  unit_info;                       // 14
+    u8  boot_firm;                       // 15
+    u8  prev_firm;                       // 16
+    INSERT_PADDING_BYTES(0x1);           // 17
+    u32 ctr_sdk_ver;                     // 18
+    INSERT_PADDING_BYTES(0x30 - 0x1C);   // 1C
+    u32 app_mem_type;                    // 30
+    INSERT_PADDING_BYTES(0x40 - 0x34);   // 34
+    u32 app_mem_alloc;                   // 40
+    u32 sys_mem_alloc;                   // 44
+    u32 base_mem_alloc;                  // 48
+    INSERT_PADDING_BYTES(0x60 - 0x4C);   // 4C
+    u8  firm_unk;                        // 60
+    u8  firm_version_rev;                // 61
+    u8  firm_version_min;                // 62
+    u8  firm_version_maj;                // 63
+    u32 firm_sys_core_ver;               // 64
+    u32 firm_ctr_sdk_ver;                // 68
+    INSERT_PADDING_BYTES(0x1000 - 0x6C); // 6C
 };
 
+static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong");
+
+static ConfigMemDef config_mem;
+
 template <typename T>
 inline void Read(T &var, const u32 addr) {
-    switch (addr) {
-
-    // Bit 0 set for Retail
-    case UNITINFO:
-        var = 0x00000001;
-        break;
-
-    // Set app memory size to 64MB?
-    case APPMEMALLOC:
-        var = 0x04000000;
-        break;
-
-    // Unknown - normally set to: 0x08000000 - (APPMEMALLOC + *0x1FF80048)
-    // (Total FCRAM size - APPMEMALLOC - *0x1FF80048)
-    case 0x1FF80044:
-        var = 0x08000000 - (0x04000000 + 0x1400000);
-        break;
-
-    // Unknown - normally set to: 0x1400000 (20MB)
-    case 0x1FF80048:
-        var = 0x1400000;
-        break;
-
-    default:
-        LOG_ERROR(Kernel, "unknown addr=0x%08X", addr);
-    }
+    u32 offset = addr - Memory::CONFIG_MEMORY_VADDR;
+    ASSERT(offset < Memory::CONFIG_MEMORY_SIZE);
+    var = *(reinterpret_cast<T*>(((uintptr_t)&config_mem) + offset));
 }
 
 // Explicitly instantiate template functions because we aren't defining this in the header:
@@ -66,5 +60,21 @@ template void Read<u32>(u32 &var, const u32 addr);
 template void Read<u16>(u16 &var, const u32 addr);
 template void Read<u8>(u8 &var, const u32 addr);
 
+void Init() {
+    config_mem.update_flag = 0; // No update
+    config_mem.sys_core_ver = 0x2;
+    config_mem.unit_info = 0x1; // Bit 0 set for Retail
+    config_mem.prev_firm = 0;
+    config_mem.app_mem_type = 0; // Defualt app mem type
+    config_mem.unit_info = 0x1; // Bit 0 set for Retail
+    config_mem.app_mem_alloc = 0x04000000; // Default app memory size is 64MB
+    config_mem.base_mem_alloc = 0x01400000; // Default base memory is 20MB
+    config_mem.sys_mem_alloc = Memory::FCRAM_SIZE - (config_mem.app_mem_alloc + config_mem.base_mem_alloc);
+    config_mem.firm_unk = 0;
+    config_mem.firm_version_rev = 0;
+    config_mem.firm_version_min = 0x40;
+    config_mem.firm_version_maj = 0x2;
+    config_mem.firm_sys_core_ver = 0x2;
+}
 
 } // namespace
diff --git a/src/core/hle/config_mem.h b/src/core/hle/config_mem.h
index 3975af18f..94853901a 100644
--- a/src/core/hle/config_mem.h
+++ b/src/core/hle/config_mem.h
@@ -18,4 +18,6 @@ namespace ConfigMem {
 template <typename T>
 void Read(T &var, const u32 addr);
 
+void Init();
+
 } // namespace
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
index 529133ca7..b0066e15e 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -7,6 +7,7 @@
 #include "core/arm/arm_interface.h"
 #include "core/mem_map.h"
 #include "core/hle/hle.h"
+#include "core/hle/config_mem.h"
 #include "core/hle/shared_page.h"
 #include "core/hle/kernel/thread.h"
 #include "core/hle/service/service.h"
@@ -75,6 +76,7 @@ void Init() {
 
     RegisterAllModules();
 
+    ConfigMem::Init();
     SharedPage::Init();
 
     LOG_DEBUG(Kernel, "initialized OK");
diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp
index f0726ef09..568dad684 100644
--- a/src/core/hle/shared_page.cpp
+++ b/src/core/hle/shared_page.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include "common/common_types.h"
+#include "common/common_funcs.h"
 
 #include "core/core.h"
 #include "core/mem_map.h"
@@ -13,13 +14,6 @@
 
 namespace SharedPage {
 
-// helper macro to properly align structure members.
-// Calling INSERT_PADDING_BYTES will add a new member variable with a name like "pad121",
-// depending on the current source line to make sure variable names are unique.
-#define INSERT_PADDING_BYTES_HELPER1(x, y) x ## y
-#define INSERT_PADDING_BYTES_HELPER2(x, y) INSERT_PADDING_BYTES_HELPER1(x, y)
-#define INSERT_PADDING_BYTES(num_words) u8 INSERT_PADDING_BYTES_HELPER2(pad, __LINE__)[(num_words)]
-
 // see http://3dbrew.org/wiki/Configuration_Memory#Shared_Memory_Page_For_ARM11_Processes
 
 #pragma pack(1)