diff --git a/README.md b/README.md
index 73219487..116ce457 100644
--- a/README.md
+++ b/README.md
@@ -84,12 +84,14 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
```
3. Move the cloned folder into `build/`.
4. Insert your `Source/stratosphere` folder into `build/`.
-5. Run:
+5. Run: (On Windows you need to use "make -j %NUMBER_OF_PROCESSORS%")
```bash
./build.sh
```
+
+
To build the Configurator:
```bash
diff --git a/Source/Atmosphere-Patches/secmon_define_emc_access_table.inc b/Source/Atmosphere-Patches/secmon_define_emc_access_table.inc
new file mode 100644
index 00000000..161f77c6
--- /dev/null
+++ b/Source/Atmosphere-Patches/secmon_define_emc_access_table.inc
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 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 .
+ */
+
+#define __ACCESS_TABLE_NAME__ EmcAccessTable
+#define __ACCESS_TABLE_ADDRESS__ MemoryRegionPhysicalDeviceExternalMemoryController.GetAddress()
+#define __ACCESS_TABLE_INC__ "secmon_emc_access_table_data.inc"
+
+#include "secmon_define_access_table.inc"
+
+#undef __ACCESS_TABLE_INC__
+#undef __ACCESS_TABLE_ADDRESS__
+#undef __ACCESS_TABLE_NAME__
diff --git a/Source/Atmosphere-Patches/secmon_emc_access_table_data.inc b/Source/Atmosphere-Patches/secmon_emc_access_table_data.inc
new file mode 100644
index 00000000..6089047e
--- /dev/null
+++ b/Source/Atmosphere-Patches/secmon_emc_access_table_data.inc
@@ -0,0 +1,967 @@
+/*
+ * Copyright (c) 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 .
+ */
+
+SetRegisterAllowed(0x0);
+SetRegisterAllowed(0x4);
+SetRegisterAllowed(0x8);
+SetRegisterAllowed(0xC);
+SetRegisterAllowed(0x10);
+SetRegisterAllowed(0x14);
+SetRegisterAllowed(0x18);
+SetRegisterAllowed(0x1C);
+SetRegisterAllowed(0x20);
+SetRegisterAllowed(0x24);
+SetRegisterAllowed(0x28);
+SetRegisterAllowed(0x2C);
+SetRegisterAllowed(0x30);
+SetRegisterAllowed(0x34);
+SetRegisterAllowed(0x38);
+SetRegisterAllowed(0x3C);
+SetRegisterAllowed(0x40);
+SetRegisterAllowed(0x44);
+SetRegisterAllowed(0x48);
+SetRegisterAllowed(0x4C);
+SetRegisterAllowed(0x50);
+SetRegisterAllowed(0x54);
+SetRegisterAllowed(0x58);
+SetRegisterAllowed(0x5C);
+SetRegisterAllowed(0x60);
+SetRegisterAllowed(0x64);
+SetRegisterAllowed(0x68);
+SetRegisterAllowed(0x6C);
+SetRegisterAllowed(0x70);
+SetRegisterAllowed(0x74);
+SetRegisterAllowed(0x78);
+SetRegisterAllowed(0x7C);
+SetRegisterAllowed(0x80);
+SetRegisterAllowed(0x84);
+SetRegisterAllowed(0x88);
+SetRegisterAllowed(0x8C);
+SetRegisterAllowed(0x90);
+SetRegisterAllowed(0x94);
+SetRegisterAllowed(0x98);
+SetRegisterAllowed(0x9C);
+SetRegisterAllowed(0xA0);
+SetRegisterAllowed(0xA4);
+SetRegisterAllowed(0xA8);
+SetRegisterAllowed(0xAC);
+SetRegisterAllowed(0xB0);
+SetRegisterAllowed(0xB4);
+SetRegisterAllowed(0xB8);
+SetRegisterAllowed(0xBC);
+SetRegisterAllowed(0xC0);
+SetRegisterAllowed(0xC4);
+SetRegisterAllowed(0xC8);
+SetRegisterAllowed(0xCC);
+SetRegisterAllowed(0xD0);
+SetRegisterAllowed(0xD4);
+SetRegisterAllowed(0xD8);
+SetRegisterAllowed(0xDC);
+SetRegisterAllowed(0xE0);
+SetRegisterAllowed(0xE4);
+SetRegisterAllowed(0xE8);
+SetRegisterAllowed(0xEC);
+SetRegisterAllowed(0xF0);
+SetRegisterAllowed(0xF4);
+SetRegisterAllowed(0xF8);
+SetRegisterAllowed(0xFC);
+SetRegisterAllowed(0x100);
+SetRegisterAllowed(0x104);
+SetRegisterAllowed(0x108);
+SetRegisterAllowed(0x10C);
+SetRegisterAllowed(0x110);
+SetRegisterAllowed(0x114);
+SetRegisterAllowed(0x118);
+SetRegisterAllowed(0x11C);
+SetRegisterAllowed(0x120);
+SetRegisterAllowed(0x124);
+SetRegisterAllowed(0x128);
+SetRegisterAllowed(0x12C);
+SetRegisterAllowed(0x130);
+SetRegisterAllowed(0x134);
+SetRegisterAllowed(0x138);
+SetRegisterAllowed(0x13C);
+SetRegisterAllowed(0x140);
+SetRegisterAllowed(0x144);
+SetRegisterAllowed(0x148);
+SetRegisterAllowed(0x14C);
+SetRegisterAllowed(0x150);
+SetRegisterAllowed(0x154);
+SetRegisterAllowed(0x158);
+SetRegisterAllowed(0x15C);
+SetRegisterAllowed(0x160);
+SetRegisterAllowed(0x164);
+SetRegisterAllowed(0x168);
+SetRegisterAllowed(0x16C);
+SetRegisterAllowed(0x170);
+SetRegisterAllowed(0x174);
+SetRegisterAllowed(0x178);
+SetRegisterAllowed(0x17C);
+SetRegisterAllowed(0x180);
+SetRegisterAllowed(0x184);
+SetRegisterAllowed(0x188);
+SetRegisterAllowed(0x18C);
+SetRegisterAllowed(0x190);
+SetRegisterAllowed(0x194);
+SetRegisterAllowed(0x198);
+SetRegisterAllowed(0x19C);
+SetRegisterAllowed(0x1A0);
+SetRegisterAllowed(0x1A4);
+SetRegisterAllowed(0x1A8);
+SetRegisterAllowed(0x1AC);
+SetRegisterAllowed(0x1B0);
+SetRegisterAllowed(0x1B4);
+SetRegisterAllowed(0x1B8);
+SetRegisterAllowed(0x1BC);
+SetRegisterAllowed(0x1C0);
+SetRegisterAllowed(0x1C4);
+SetRegisterAllowed(0x1C8);
+SetRegisterAllowed(0x1CC);
+SetRegisterAllowed(0x1D0);
+SetRegisterAllowed(0x1D4);
+SetRegisterAllowed(0x1D8);
+SetRegisterAllowed(0x1DC);
+SetRegisterAllowed(0x1E0);
+SetRegisterAllowed(0x1E4);
+SetRegisterAllowed(0x1E8);
+SetRegisterAllowed(0x1EC);
+SetRegisterAllowed(0x1F0);
+SetRegisterAllowed(0x1F4);
+SetRegisterAllowed(0x1F8);
+SetRegisterAllowed(0x1FC);
+SetRegisterAllowed(0x200);
+SetRegisterAllowed(0x204);
+SetRegisterAllowed(0x208);
+SetRegisterAllowed(0x20C);
+SetRegisterAllowed(0x210);
+SetRegisterAllowed(0x214);
+SetRegisterAllowed(0x218);
+SetRegisterAllowed(0x21C);
+SetRegisterAllowed(0x220);
+SetRegisterAllowed(0x224);
+SetRegisterAllowed(0x228);
+SetRegisterAllowed(0x22C);
+SetRegisterAllowed(0x230);
+SetRegisterAllowed(0x234);
+SetRegisterAllowed(0x238);
+SetRegisterAllowed(0x23C);
+SetRegisterAllowed(0x240);
+SetRegisterAllowed(0x244);
+SetRegisterAllowed(0x248);
+SetRegisterAllowed(0x24C);
+SetRegisterAllowed(0x250);
+SetRegisterAllowed(0x254);
+SetRegisterAllowed(0x258);
+SetRegisterAllowed(0x25C);
+SetRegisterAllowed(0x260);
+SetRegisterAllowed(0x264);
+SetRegisterAllowed(0x268);
+SetRegisterAllowed(0x26C);
+SetRegisterAllowed(0x270);
+SetRegisterAllowed(0x274);
+SetRegisterAllowed(0x278);
+SetRegisterAllowed(0x27C);
+SetRegisterAllowed(0x280);
+SetRegisterAllowed(0x284);
+SetRegisterAllowed(0x288);
+SetRegisterAllowed(0x28C);
+SetRegisterAllowed(0x290);
+SetRegisterAllowed(0x294);
+SetRegisterAllowed(0x298);
+SetRegisterAllowed(0x29C);
+SetRegisterAllowed(0x2A0);
+SetRegisterAllowed(0x2A4);
+SetRegisterAllowed(0x2A8);
+SetRegisterAllowed(0x2AC);
+SetRegisterAllowed(0x2B0);
+SetRegisterAllowed(0x2B4);
+SetRegisterAllowed(0x2B8);
+SetRegisterAllowed(0x2BC);
+SetRegisterAllowed(0x2C0);
+SetRegisterAllowed(0x2C4);
+SetRegisterAllowed(0x2C8);
+SetRegisterAllowed(0x2CC);
+SetRegisterAllowed(0x2D0);
+SetRegisterAllowed(0x2D4);
+SetRegisterAllowed(0x2D8);
+SetRegisterAllowed(0x2DC);
+SetRegisterAllowed(0x2E0);
+SetRegisterAllowed(0x2E4);
+SetRegisterAllowed(0x2E8);
+SetRegisterAllowed(0x2EC);
+SetRegisterAllowed(0x2F0);
+SetRegisterAllowed(0x2F4);
+SetRegisterAllowed(0x2F8);
+SetRegisterAllowed(0x2FC);
+SetRegisterAllowed(0x300);
+SetRegisterAllowed(0x304);
+SetRegisterAllowed(0x308);
+SetRegisterAllowed(0x30C);
+SetRegisterAllowed(0x310);
+SetRegisterAllowed(0x314);
+SetRegisterAllowed(0x318);
+SetRegisterAllowed(0x31C);
+SetRegisterAllowed(0x320);
+SetRegisterAllowed(0x324);
+SetRegisterAllowed(0x328);
+SetRegisterAllowed(0x32C);
+SetRegisterAllowed(0x330);
+SetRegisterAllowed(0x334);
+SetRegisterAllowed(0x338);
+SetRegisterAllowed(0x33C);
+SetRegisterAllowed(0x340);
+SetRegisterAllowed(0x344);
+SetRegisterAllowed(0x348);
+SetRegisterAllowed(0x34C);
+SetRegisterAllowed(0x350);
+SetRegisterAllowed(0x354);
+SetRegisterAllowed(0x358);
+SetRegisterAllowed(0x35C);
+SetRegisterAllowed(0x360);
+SetRegisterAllowed(0x364);
+SetRegisterAllowed(0x368);
+SetRegisterAllowed(0x36C);
+SetRegisterAllowed(0x370);
+SetRegisterAllowed(0x374);
+SetRegisterAllowed(0x378);
+SetRegisterAllowed(0x37C);
+SetRegisterAllowed(0x380);
+SetRegisterAllowed(0x384);
+SetRegisterAllowed(0x388);
+SetRegisterAllowed(0x38C);
+SetRegisterAllowed(0x390);
+SetRegisterAllowed(0x394);
+SetRegisterAllowed(0x398);
+SetRegisterAllowed(0x39C);
+SetRegisterAllowed(0x3A0);
+SetRegisterAllowed(0x3A4);
+SetRegisterAllowed(0x3A8);
+SetRegisterAllowed(0x3AC);
+SetRegisterAllowed(0x3B0);
+SetRegisterAllowed(0x3B4);
+SetRegisterAllowed(0x3B8);
+SetRegisterAllowed(0x3BC);
+SetRegisterAllowed(0x3C0);
+SetRegisterAllowed(0x3C4);
+SetRegisterAllowed(0x3C8);
+SetRegisterAllowed(0x3CC);
+SetRegisterAllowed(0x3D0);
+SetRegisterAllowed(0x3D4);
+SetRegisterAllowed(0x3D8);
+SetRegisterAllowed(0x3DC);
+SetRegisterAllowed(0x3E0);
+SetRegisterAllowed(0x3E4);
+SetRegisterAllowed(0x3E8);
+SetRegisterAllowed(0x3EC);
+SetRegisterAllowed(0x3F0);
+SetRegisterAllowed(0x3F4);
+SetRegisterAllowed(0x3F8);
+SetRegisterAllowed(0x3FC);
+SetRegisterAllowed(0x400);
+SetRegisterAllowed(0x404);
+SetRegisterAllowed(0x408);
+SetRegisterAllowed(0x40C);
+SetRegisterAllowed(0x410);
+SetRegisterAllowed(0x414);
+SetRegisterAllowed(0x418);
+SetRegisterAllowed(0x41C);
+SetRegisterAllowed(0x420);
+SetRegisterAllowed(0x424);
+SetRegisterAllowed(0x428);
+SetRegisterAllowed(0x42C);
+SetRegisterAllowed(0x430);
+SetRegisterAllowed(0x434);
+SetRegisterAllowed(0x438);
+SetRegisterAllowed(0x43C);
+SetRegisterAllowed(0x440);
+SetRegisterAllowed(0x444);
+SetRegisterAllowed(0x448);
+SetRegisterAllowed(0x44C);
+SetRegisterAllowed(0x450);
+SetRegisterAllowed(0x454);
+SetRegisterAllowed(0x458);
+SetRegisterAllowed(0x45C);
+SetRegisterAllowed(0x460);
+SetRegisterAllowed(0x464);
+SetRegisterAllowed(0x468);
+SetRegisterAllowed(0x46C);
+SetRegisterAllowed(0x470);
+SetRegisterAllowed(0x474);
+SetRegisterAllowed(0x478);
+SetRegisterAllowed(0x47C);
+SetRegisterAllowed(0x480);
+SetRegisterAllowed(0x484);
+SetRegisterAllowed(0x488);
+SetRegisterAllowed(0x48C);
+SetRegisterAllowed(0x490);
+SetRegisterAllowed(0x494);
+SetRegisterAllowed(0x498);
+SetRegisterAllowed(0x49C);
+SetRegisterAllowed(0x4A0);
+SetRegisterAllowed(0x4A4);
+SetRegisterAllowed(0x4A8);
+SetRegisterAllowed(0x4AC);
+SetRegisterAllowed(0x4B0);
+SetRegisterAllowed(0x4B4);
+SetRegisterAllowed(0x4B8);
+SetRegisterAllowed(0x4BC);
+SetRegisterAllowed(0x4C0);
+SetRegisterAllowed(0x4C4);
+SetRegisterAllowed(0x4C8);
+SetRegisterAllowed(0x4CC);
+SetRegisterAllowed(0x4D0);
+SetRegisterAllowed(0x4D4);
+SetRegisterAllowed(0x4D8);
+SetRegisterAllowed(0x4DC);
+SetRegisterAllowed(0x4E0);
+SetRegisterAllowed(0x4E4);
+SetRegisterAllowed(0x4E8);
+SetRegisterAllowed(0x4EC);
+SetRegisterAllowed(0x4F0);
+SetRegisterAllowed(0x4F4);
+SetRegisterAllowed(0x4F8);
+SetRegisterAllowed(0x4FC);
+SetRegisterAllowed(0x500);
+SetRegisterAllowed(0x504);
+SetRegisterAllowed(0x508);
+SetRegisterAllowed(0x50C);
+SetRegisterAllowed(0x510);
+SetRegisterAllowed(0x514);
+SetRegisterAllowed(0x518);
+SetRegisterAllowed(0x51C);
+SetRegisterAllowed(0x520);
+SetRegisterAllowed(0x524);
+SetRegisterAllowed(0x528);
+SetRegisterAllowed(0x52C);
+SetRegisterAllowed(0x530);
+SetRegisterAllowed(0x534);
+SetRegisterAllowed(0x538);
+SetRegisterAllowed(0x53C);
+SetRegisterAllowed(0x540);
+SetRegisterAllowed(0x544);
+SetRegisterAllowed(0x548);
+SetRegisterAllowed(0x54C);
+SetRegisterAllowed(0x550);
+SetRegisterAllowed(0x554);
+SetRegisterAllowed(0x558);
+SetRegisterAllowed(0x55C);
+SetRegisterAllowed(0x560);
+SetRegisterAllowed(0x564);
+SetRegisterAllowed(0x568);
+SetRegisterAllowed(0x56C);
+SetRegisterAllowed(0x570);
+SetRegisterAllowed(0x574);
+SetRegisterAllowed(0x578);
+SetRegisterAllowed(0x57C);
+SetRegisterAllowed(0x580);
+SetRegisterAllowed(0x584);
+SetRegisterAllowed(0x588);
+SetRegisterAllowed(0x58C);
+SetRegisterAllowed(0x590);
+SetRegisterAllowed(0x594);
+SetRegisterAllowed(0x598);
+SetRegisterAllowed(0x59C);
+SetRegisterAllowed(0x5A0);
+SetRegisterAllowed(0x5A4);
+SetRegisterAllowed(0x5A8);
+SetRegisterAllowed(0x5AC);
+SetRegisterAllowed(0x5B0);
+SetRegisterAllowed(0x5B4);
+SetRegisterAllowed(0x5B8);
+SetRegisterAllowed(0x5BC);
+SetRegisterAllowed(0x5C0);
+SetRegisterAllowed(0x5C4);
+SetRegisterAllowed(0x5C8);
+SetRegisterAllowed(0x5CC);
+SetRegisterAllowed(0x5D0);
+SetRegisterAllowed(0x5D4);
+SetRegisterAllowed(0x5D8);
+SetRegisterAllowed(0x5DC);
+SetRegisterAllowed(0x5E0);
+SetRegisterAllowed(0x5E4);
+SetRegisterAllowed(0x5E8);
+SetRegisterAllowed(0x5EC);
+SetRegisterAllowed(0x5F0);
+SetRegisterAllowed(0x5F4);
+SetRegisterAllowed(0x5F8);
+SetRegisterAllowed(0x5FC);
+SetRegisterAllowed(0x600);
+SetRegisterAllowed(0x604);
+SetRegisterAllowed(0x608);
+SetRegisterAllowed(0x60C);
+SetRegisterAllowed(0x610);
+SetRegisterAllowed(0x614);
+SetRegisterAllowed(0x618);
+SetRegisterAllowed(0x61C);
+SetRegisterAllowed(0x620);
+SetRegisterAllowed(0x624);
+SetRegisterAllowed(0x628);
+SetRegisterAllowed(0x62C);
+SetRegisterAllowed(0x630);
+SetRegisterAllowed(0x634);
+SetRegisterAllowed(0x638);
+SetRegisterAllowed(0x63C);
+SetRegisterAllowed(0x640);
+SetRegisterAllowed(0x644);
+SetRegisterAllowed(0x648);
+SetRegisterAllowed(0x64C);
+SetRegisterAllowed(0x650);
+SetRegisterAllowed(0x654);
+SetRegisterAllowed(0x658);
+SetRegisterAllowed(0x65C);
+SetRegisterAllowed(0x660);
+SetRegisterAllowed(0x664);
+SetRegisterAllowed(0x668);
+SetRegisterAllowed(0x66C);
+SetRegisterAllowed(0x670);
+SetRegisterAllowed(0x674);
+SetRegisterAllowed(0x678);
+SetRegisterAllowed(0x67C);
+SetRegisterAllowed(0x680);
+SetRegisterAllowed(0x684);
+SetRegisterAllowed(0x688);
+SetRegisterAllowed(0x68C);
+SetRegisterAllowed(0x690);
+SetRegisterAllowed(0x694);
+SetRegisterAllowed(0x698);
+SetRegisterAllowed(0x69C);
+SetRegisterAllowed(0x6A0);
+SetRegisterAllowed(0x6A4);
+SetRegisterAllowed(0x6A8);
+SetRegisterAllowed(0x6AC);
+SetRegisterAllowed(0x6B0);
+SetRegisterAllowed(0x6B4);
+SetRegisterAllowed(0x6B8);
+SetRegisterAllowed(0x6BC);
+SetRegisterAllowed(0x6C0);
+SetRegisterAllowed(0x6C4);
+SetRegisterAllowed(0x6C8);
+SetRegisterAllowed(0x6CC);
+SetRegisterAllowed(0x6D0);
+SetRegisterAllowed(0x6D4);
+SetRegisterAllowed(0x6D8);
+SetRegisterAllowed(0x6DC);
+SetRegisterAllowed(0x6E0);
+SetRegisterAllowed(0x6E4);
+SetRegisterAllowed(0x6E8);
+SetRegisterAllowed(0x6EC);
+SetRegisterAllowed(0x6F0);
+SetRegisterAllowed(0x6F4);
+SetRegisterAllowed(0x6F8);
+SetRegisterAllowed(0x6FC);
+SetRegisterAllowed(0x700);
+SetRegisterAllowed(0x704);
+SetRegisterAllowed(0x708);
+SetRegisterAllowed(0x70C);
+SetRegisterAllowed(0x710);
+SetRegisterAllowed(0x714);
+SetRegisterAllowed(0x718);
+SetRegisterAllowed(0x71C);
+SetRegisterAllowed(0x720);
+SetRegisterAllowed(0x724);
+SetRegisterAllowed(0x728);
+SetRegisterAllowed(0x72C);
+SetRegisterAllowed(0x730);
+SetRegisterAllowed(0x734);
+SetRegisterAllowed(0x738);
+SetRegisterAllowed(0x73C);
+SetRegisterAllowed(0x740);
+SetRegisterAllowed(0x744);
+SetRegisterAllowed(0x748);
+SetRegisterAllowed(0x74C);
+SetRegisterAllowed(0x750);
+SetRegisterAllowed(0x754);
+SetRegisterAllowed(0x758);
+SetRegisterAllowed(0x75C);
+SetRegisterAllowed(0x760);
+SetRegisterAllowed(0x764);
+SetRegisterAllowed(0x768);
+SetRegisterAllowed(0x76C);
+SetRegisterAllowed(0x770);
+SetRegisterAllowed(0x774);
+SetRegisterAllowed(0x778);
+SetRegisterAllowed(0x77C);
+SetRegisterAllowed(0x780);
+SetRegisterAllowed(0x784);
+SetRegisterAllowed(0x788);
+SetRegisterAllowed(0x78C);
+SetRegisterAllowed(0x790);
+SetRegisterAllowed(0x794);
+SetRegisterAllowed(0x798);
+SetRegisterAllowed(0x79C);
+SetRegisterAllowed(0x7A0);
+SetRegisterAllowed(0x7A4);
+SetRegisterAllowed(0x7A8);
+SetRegisterAllowed(0x7AC);
+SetRegisterAllowed(0x7B0);
+SetRegisterAllowed(0x7B4);
+SetRegisterAllowed(0x7B8);
+SetRegisterAllowed(0x7BC);
+SetRegisterAllowed(0x7C0);
+SetRegisterAllowed(0x7C4);
+SetRegisterAllowed(0x7C8);
+SetRegisterAllowed(0x7CC);
+SetRegisterAllowed(0x7D0);
+SetRegisterAllowed(0x7D4);
+SetRegisterAllowed(0x7D8);
+SetRegisterAllowed(0x7DC);
+SetRegisterAllowed(0x7E0);
+SetRegisterAllowed(0x7E4);
+SetRegisterAllowed(0x7E8);
+SetRegisterAllowed(0x7EC);
+SetRegisterAllowed(0x7F0);
+SetRegisterAllowed(0x7F4);
+SetRegisterAllowed(0x7F8);
+SetRegisterAllowed(0x7FC);
+SetRegisterAllowed(0x800);
+SetRegisterAllowed(0x804);
+SetRegisterAllowed(0x808);
+SetRegisterAllowed(0x80C);
+SetRegisterAllowed(0x810);
+SetRegisterAllowed(0x814);
+SetRegisterAllowed(0x818);
+SetRegisterAllowed(0x81C);
+SetRegisterAllowed(0x820);
+SetRegisterAllowed(0x824);
+SetRegisterAllowed(0x828);
+SetRegisterAllowed(0x82C);
+SetRegisterAllowed(0x830);
+SetRegisterAllowed(0x834);
+SetRegisterAllowed(0x838);
+SetRegisterAllowed(0x83C);
+SetRegisterAllowed(0x840);
+SetRegisterAllowed(0x844);
+SetRegisterAllowed(0x848);
+SetRegisterAllowed(0x84C);
+SetRegisterAllowed(0x850);
+SetRegisterAllowed(0x854);
+SetRegisterAllowed(0x858);
+SetRegisterAllowed(0x85C);
+SetRegisterAllowed(0x860);
+SetRegisterAllowed(0x864);
+SetRegisterAllowed(0x868);
+SetRegisterAllowed(0x86C);
+SetRegisterAllowed(0x870);
+SetRegisterAllowed(0x874);
+SetRegisterAllowed(0x878);
+SetRegisterAllowed(0x87C);
+SetRegisterAllowed(0x880);
+SetRegisterAllowed(0x884);
+SetRegisterAllowed(0x888);
+SetRegisterAllowed(0x88C);
+SetRegisterAllowed(0x890);
+SetRegisterAllowed(0x894);
+SetRegisterAllowed(0x898);
+SetRegisterAllowed(0x89C);
+SetRegisterAllowed(0x8A0);
+SetRegisterAllowed(0x8A4);
+SetRegisterAllowed(0x8A8);
+SetRegisterAllowed(0x8AC);
+SetRegisterAllowed(0x8B0);
+SetRegisterAllowed(0x8B4);
+SetRegisterAllowed(0x8B8);
+SetRegisterAllowed(0x8BC);
+SetRegisterAllowed(0x8C0);
+SetRegisterAllowed(0x8C4);
+SetRegisterAllowed(0x8C8);
+SetRegisterAllowed(0x8CC);
+SetRegisterAllowed(0x8D0);
+SetRegisterAllowed(0x8D4);
+SetRegisterAllowed(0x8D8);
+SetRegisterAllowed(0x8DC);
+SetRegisterAllowed(0x8E0);
+SetRegisterAllowed(0x8E4);
+SetRegisterAllowed(0x8E8);
+SetRegisterAllowed(0x8EC);
+SetRegisterAllowed(0x8F0);
+SetRegisterAllowed(0x8F4);
+SetRegisterAllowed(0x8F8);
+SetRegisterAllowed(0x8FC);
+SetRegisterAllowed(0x900);
+SetRegisterAllowed(0x904);
+SetRegisterAllowed(0x908);
+SetRegisterAllowed(0x90C);
+SetRegisterAllowed(0x910);
+SetRegisterAllowed(0x914);
+SetRegisterAllowed(0x918);
+SetRegisterAllowed(0x91C);
+SetRegisterAllowed(0x920);
+SetRegisterAllowed(0x924);
+SetRegisterAllowed(0x928);
+SetRegisterAllowed(0x92C);
+SetRegisterAllowed(0x930);
+SetRegisterAllowed(0x934);
+SetRegisterAllowed(0x938);
+SetRegisterAllowed(0x93C);
+SetRegisterAllowed(0x940);
+SetRegisterAllowed(0x944);
+SetRegisterAllowed(0x948);
+SetRegisterAllowed(0x94C);
+SetRegisterAllowed(0x950);
+SetRegisterAllowed(0x954);
+SetRegisterAllowed(0x958);
+SetRegisterAllowed(0x95C);
+SetRegisterAllowed(0x960);
+SetRegisterAllowed(0x964);
+SetRegisterAllowed(0x968);
+SetRegisterAllowed(0x96C);
+SetRegisterAllowed(0x970);
+SetRegisterAllowed(0x974);
+SetRegisterAllowed(0x978);
+SetRegisterAllowed(0x97C);
+SetRegisterAllowed(0x980);
+SetRegisterAllowed(0x984);
+SetRegisterAllowed(0x988);
+SetRegisterAllowed(0x98C);
+SetRegisterAllowed(0x990);
+SetRegisterAllowed(0x994);
+SetRegisterAllowed(0x998);
+SetRegisterAllowed(0x99C);
+SetRegisterAllowed(0x9A0);
+SetRegisterAllowed(0x9A4);
+SetRegisterAllowed(0x9A8);
+SetRegisterAllowed(0x9AC);
+SetRegisterAllowed(0x9B0);
+SetRegisterAllowed(0x9B4);
+SetRegisterAllowed(0x9B8);
+SetRegisterAllowed(0x9BC);
+SetRegisterAllowed(0x9C0);
+SetRegisterAllowed(0x9C4);
+SetRegisterAllowed(0x9C8);
+SetRegisterAllowed(0x9CC);
+SetRegisterAllowed(0x9D0);
+SetRegisterAllowed(0x9D4);
+SetRegisterAllowed(0x9D8);
+SetRegisterAllowed(0x9DC);
+SetRegisterAllowed(0x9E0);
+SetRegisterAllowed(0x9E4);
+SetRegisterAllowed(0x9E8);
+SetRegisterAllowed(0x9EC);
+SetRegisterAllowed(0x9F0);
+SetRegisterAllowed(0x9F4);
+SetRegisterAllowed(0x9F8);
+SetRegisterAllowed(0x9FC);
+SetRegisterAllowed(0xA00);
+SetRegisterAllowed(0xA04);
+SetRegisterAllowed(0xA08);
+SetRegisterAllowed(0xA0C);
+SetRegisterAllowed(0xA10);
+SetRegisterAllowed(0xA14);
+SetRegisterAllowed(0xA18);
+SetRegisterAllowed(0xA1C);
+SetRegisterAllowed(0xA20);
+SetRegisterAllowed(0xA24);
+SetRegisterAllowed(0xA28);
+SetRegisterAllowed(0xA2C);
+SetRegisterAllowed(0xA30);
+SetRegisterAllowed(0xA34);
+SetRegisterAllowed(0xA38);
+SetRegisterAllowed(0xA3C);
+SetRegisterAllowed(0xA40);
+SetRegisterAllowed(0xA44);
+SetRegisterAllowed(0xA48);
+SetRegisterAllowed(0xA4C);
+SetRegisterAllowed(0xA50);
+SetRegisterAllowed(0xA54);
+SetRegisterAllowed(0xA58);
+SetRegisterAllowed(0xA5C);
+SetRegisterAllowed(0xA60);
+SetRegisterAllowed(0xA64);
+SetRegisterAllowed(0xA68);
+SetRegisterAllowed(0xA6C);
+SetRegisterAllowed(0xA70);
+SetRegisterAllowed(0xA74);
+SetRegisterAllowed(0xA78);
+SetRegisterAllowed(0xA7C);
+SetRegisterAllowed(0xA80);
+SetRegisterAllowed(0xA84);
+SetRegisterAllowed(0xA88);
+SetRegisterAllowed(0xA8C);
+SetRegisterAllowed(0xA90);
+SetRegisterAllowed(0xA94);
+SetRegisterAllowed(0xA98);
+SetRegisterAllowed(0xA9C);
+SetRegisterAllowed(0xAA0);
+SetRegisterAllowed(0xAA4);
+SetRegisterAllowed(0xAA8);
+SetRegisterAllowed(0xAAC);
+SetRegisterAllowed(0xAB0);
+SetRegisterAllowed(0xAB4);
+SetRegisterAllowed(0xAB8);
+SetRegisterAllowed(0xABC);
+SetRegisterAllowed(0xAC0);
+SetRegisterAllowed(0xAC4);
+SetRegisterAllowed(0xAC8);
+SetRegisterAllowed(0xACC);
+SetRegisterAllowed(0xAD0);
+SetRegisterAllowed(0xAD4);
+SetRegisterAllowed(0xAD8);
+SetRegisterAllowed(0xADC);
+SetRegisterAllowed(0xAE0);
+SetRegisterAllowed(0xAE4);
+SetRegisterAllowed(0xAE8);
+SetRegisterAllowed(0xAEC);
+SetRegisterAllowed(0xAF0);
+SetRegisterAllowed(0xAF4);
+SetRegisterAllowed(0xAF8);
+SetRegisterAllowed(0xAFC);
+SetRegisterAllowed(0xB00);
+SetRegisterAllowed(0xB04);
+SetRegisterAllowed(0xB08);
+SetRegisterAllowed(0xB0C);
+SetRegisterAllowed(0xB10);
+SetRegisterAllowed(0xB14);
+SetRegisterAllowed(0xB18);
+SetRegisterAllowed(0xB1C);
+SetRegisterAllowed(0xB20);
+SetRegisterAllowed(0xB24);
+SetRegisterAllowed(0xB28);
+SetRegisterAllowed(0xB2C);
+SetRegisterAllowed(0xB30);
+SetRegisterAllowed(0xB34);
+SetRegisterAllowed(0xB38);
+SetRegisterAllowed(0xB3C);
+SetRegisterAllowed(0xB40);
+SetRegisterAllowed(0xB44);
+SetRegisterAllowed(0xB48);
+SetRegisterAllowed(0xB4C);
+SetRegisterAllowed(0xB50);
+SetRegisterAllowed(0xB54);
+SetRegisterAllowed(0xB58);
+SetRegisterAllowed(0xB5C);
+SetRegisterAllowed(0xB60);
+SetRegisterAllowed(0xB64);
+SetRegisterAllowed(0xB68);
+SetRegisterAllowed(0xB6C);
+SetRegisterAllowed(0xB70);
+SetRegisterAllowed(0xB74);
+SetRegisterAllowed(0xB78);
+SetRegisterAllowed(0xB7C);
+SetRegisterAllowed(0xB80);
+SetRegisterAllowed(0xB84);
+SetRegisterAllowed(0xB88);
+SetRegisterAllowed(0xB8C);
+SetRegisterAllowed(0xB90);
+SetRegisterAllowed(0xB94);
+SetRegisterAllowed(0xB98);
+SetRegisterAllowed(0xB9C);
+SetRegisterAllowed(0xBA0);
+SetRegisterAllowed(0xBA4);
+SetRegisterAllowed(0xBA8);
+SetRegisterAllowed(0xBAC);
+SetRegisterAllowed(0xBB0);
+SetRegisterAllowed(0xBB4);
+SetRegisterAllowed(0xBB8);
+SetRegisterAllowed(0xBBC);
+SetRegisterAllowed(0xBC0);
+SetRegisterAllowed(0xBC4);
+SetRegisterAllowed(0xBC8);
+SetRegisterAllowed(0xBCC);
+SetRegisterAllowed(0xBD0);
+SetRegisterAllowed(0xBD4);
+SetRegisterAllowed(0xBD8);
+SetRegisterAllowed(0xBDC);
+SetRegisterAllowed(0xBE0);
+SetRegisterAllowed(0xBE4);
+SetRegisterAllowed(0xBE8);
+SetRegisterAllowed(0xBEC);
+SetRegisterAllowed(0xBF0);
+SetRegisterAllowed(0xBF4);
+SetRegisterAllowed(0xBF8);
+SetRegisterAllowed(0xBFC);
+SetRegisterAllowed(0xC00);
+SetRegisterAllowed(0xC04);
+SetRegisterAllowed(0xC08);
+SetRegisterAllowed(0xC0C);
+SetRegisterAllowed(0xC10);
+SetRegisterAllowed(0xC14);
+SetRegisterAllowed(0xC18);
+SetRegisterAllowed(0xC1C);
+SetRegisterAllowed(0xC20);
+SetRegisterAllowed(0xC24);
+SetRegisterAllowed(0xC28);
+SetRegisterAllowed(0xC2C);
+SetRegisterAllowed(0xC30);
+SetRegisterAllowed(0xC34);
+SetRegisterAllowed(0xC38);
+SetRegisterAllowed(0xC3C);
+SetRegisterAllowed(0xC40);
+SetRegisterAllowed(0xC44);
+SetRegisterAllowed(0xC48);
+SetRegisterAllowed(0xC4C);
+SetRegisterAllowed(0xC50);
+SetRegisterAllowed(0xC54);
+SetRegisterAllowed(0xC58);
+SetRegisterAllowed(0xC5C);
+SetRegisterAllowed(0xC60);
+SetRegisterAllowed(0xC64);
+SetRegisterAllowed(0xC68);
+SetRegisterAllowed(0xC6C);
+SetRegisterAllowed(0xC70);
+SetRegisterAllowed(0xC74);
+SetRegisterAllowed(0xC78);
+SetRegisterAllowed(0xC7C);
+SetRegisterAllowed(0xC80);
+SetRegisterAllowed(0xC84);
+SetRegisterAllowed(0xC88);
+SetRegisterAllowed(0xC8C);
+SetRegisterAllowed(0xC90);
+SetRegisterAllowed(0xC94);
+SetRegisterAllowed(0xC98);
+SetRegisterAllowed(0xC9C);
+SetRegisterAllowed(0xCA0);
+SetRegisterAllowed(0xCA4);
+SetRegisterAllowed(0xCA8);
+SetRegisterAllowed(0xCAC);
+SetRegisterAllowed(0xCB0);
+SetRegisterAllowed(0xCB4);
+SetRegisterAllowed(0xCB8);
+SetRegisterAllowed(0xCBC);
+SetRegisterAllowed(0xCC0);
+SetRegisterAllowed(0xCC4);
+SetRegisterAllowed(0xCC8);
+SetRegisterAllowed(0xCCC);
+SetRegisterAllowed(0xCD0);
+SetRegisterAllowed(0xCD4);
+SetRegisterAllowed(0xCD8);
+SetRegisterAllowed(0xCDC);
+SetRegisterAllowed(0xCE0);
+SetRegisterAllowed(0xCE4);
+SetRegisterAllowed(0xCE8);
+SetRegisterAllowed(0xCEC);
+SetRegisterAllowed(0xCF0);
+SetRegisterAllowed(0xCF4);
+SetRegisterAllowed(0xCF8);
+SetRegisterAllowed(0xCFC);
+SetRegisterAllowed(0xD00);
+SetRegisterAllowed(0xD04);
+SetRegisterAllowed(0xD08);
+SetRegisterAllowed(0xD0C);
+SetRegisterAllowed(0xD10);
+SetRegisterAllowed(0xD14);
+SetRegisterAllowed(0xD18);
+SetRegisterAllowed(0xD1C);
+SetRegisterAllowed(0xD20);
+SetRegisterAllowed(0xD24);
+SetRegisterAllowed(0xD28);
+SetRegisterAllowed(0xD2C);
+SetRegisterAllowed(0xD30);
+SetRegisterAllowed(0xD34);
+SetRegisterAllowed(0xD38);
+SetRegisterAllowed(0xD3C);
+SetRegisterAllowed(0xD40);
+SetRegisterAllowed(0xD44);
+SetRegisterAllowed(0xD48);
+SetRegisterAllowed(0xD4C);
+SetRegisterAllowed(0xD50);
+SetRegisterAllowed(0xD54);
+SetRegisterAllowed(0xD58);
+SetRegisterAllowed(0xD5C);
+SetRegisterAllowed(0xD60);
+SetRegisterAllowed(0xD64);
+SetRegisterAllowed(0xD68);
+SetRegisterAllowed(0xD6C);
+SetRegisterAllowed(0xD70);
+SetRegisterAllowed(0xD74);
+SetRegisterAllowed(0xD78);
+SetRegisterAllowed(0xD7C);
+SetRegisterAllowed(0xD80);
+SetRegisterAllowed(0xD84);
+SetRegisterAllowed(0xD88);
+SetRegisterAllowed(0xD8C);
+SetRegisterAllowed(0xD90);
+SetRegisterAllowed(0xD94);
+SetRegisterAllowed(0xD98);
+SetRegisterAllowed(0xD9C);
+SetRegisterAllowed(0xDA0);
+SetRegisterAllowed(0xDA4);
+SetRegisterAllowed(0xDA8);
+SetRegisterAllowed(0xDAC);
+SetRegisterAllowed(0xDB0);
+SetRegisterAllowed(0xDB4);
+SetRegisterAllowed(0xDB8);
+SetRegisterAllowed(0xDBC);
+SetRegisterAllowed(0xDC0);
+SetRegisterAllowed(0xDC4);
+SetRegisterAllowed(0xDC8);
+SetRegisterAllowed(0xDCC);
+SetRegisterAllowed(0xDD0);
+SetRegisterAllowed(0xDD4);
+SetRegisterAllowed(0xDD8);
+SetRegisterAllowed(0xDDC);
+SetRegisterAllowed(0xDE0);
+SetRegisterAllowed(0xDE4);
+SetRegisterAllowed(0xDE8);
+SetRegisterAllowed(0xDEC);
+SetRegisterAllowed(0xDF0);
+SetRegisterAllowed(0xDF4);
+SetRegisterAllowed(0xDF8);
+SetRegisterAllowed(0xDFC);
+SetRegisterAllowed(0xE00);
+SetRegisterAllowed(0xE04);
+SetRegisterAllowed(0xE08);
+SetRegisterAllowed(0xE0C);
+SetRegisterAllowed(0xE10);
+SetRegisterAllowed(0xE14);
+SetRegisterAllowed(0xE18);
+SetRegisterAllowed(0xE1C);
+SetRegisterAllowed(0xE20);
+SetRegisterAllowed(0xE24);
+SetRegisterAllowed(0xE28);
+SetRegisterAllowed(0xE2C);
+SetRegisterAllowed(0xE30);
+SetRegisterAllowed(0xE34);
+SetRegisterAllowed(0xE38);
+SetRegisterAllowed(0xE3C);
+SetRegisterAllowed(0xE40);
+SetRegisterAllowed(0xE44);
+SetRegisterAllowed(0xE48);
+SetRegisterAllowed(0xE4C);
+SetRegisterAllowed(0xE50);
+SetRegisterAllowed(0xE54);
+SetRegisterAllowed(0xE58);
+SetRegisterAllowed(0xE5C);
+SetRegisterAllowed(0xE60);
+SetRegisterAllowed(0xE64);
+SetRegisterAllowed(0xE68);
+SetRegisterAllowed(0xE6C);
+SetRegisterAllowed(0xE70);
+SetRegisterAllowed(0xE74);
+SetRegisterAllowed(0xE78);
+SetRegisterAllowed(0xE7C);
+SetRegisterAllowed(0xE80);
+SetRegisterAllowed(0xE84);
+SetRegisterAllowed(0xE88);
+SetRegisterAllowed(0xE8C);
+SetRegisterAllowed(0xE90);
+SetRegisterAllowed(0xE94);
+SetRegisterAllowed(0xE98);
+SetRegisterAllowed(0xE9C);
+SetRegisterAllowed(0xEA0);
+SetRegisterAllowed(0xEA4);
+SetRegisterAllowed(0xEA8);
+SetRegisterAllowed(0xEAC);
+SetRegisterAllowed(0xEB0);
+SetRegisterAllowed(0xEB4);
+SetRegisterAllowed(0xEB8);
+SetRegisterAllowed(0xEBC);
+SetRegisterAllowed(0xEC0);
+SetRegisterAllowed(0xEC4);
+SetRegisterAllowed(0xEC8);
+SetRegisterAllowed(0xECC);
+SetRegisterAllowed(0xED0);
+SetRegisterAllowed(0xED4);
+SetRegisterAllowed(0xED8);
diff --git a/Source/Atmosphere-Patches/secmon_memory_layout.hpp b/Source/Atmosphere-Patches/secmon_memory_layout.hpp
new file mode 100644
index 00000000..891d9d98
--- /dev/null
+++ b/Source/Atmosphere-Patches/secmon_memory_layout.hpp
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 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 .
+ */
+#pragma once
+#include
+#include
+
+namespace ams::secmon {
+
+ using Address = u64;
+
+ struct MemoryRegion {
+ private:
+ Address m_start_address;
+ Address m_end_address;
+ public:
+ consteval MemoryRegion(Address address, size_t size) : m_start_address(address), m_end_address(address + size) {
+ if (m_end_address < m_start_address) {
+ __builtin_unreachable();
+ }
+ }
+
+ constexpr Address GetStartAddress() const {
+ return m_start_address;
+ }
+
+ constexpr Address GetAddress() const {
+ return this->GetStartAddress();
+ }
+
+ constexpr Address GetEndAddress() const {
+ return m_end_address;
+ }
+
+ constexpr Address GetLastAddress() const {
+ return m_end_address - 1;
+ }
+
+ constexpr size_t GetSize() const {
+ return m_end_address - m_start_address;
+ }
+
+ constexpr bool Contains(Address address, size_t size) const {
+ return m_start_address <= address && (address + size - 1) <= this->GetLastAddress();
+ }
+
+ constexpr bool Contains(const MemoryRegion &rhs) const {
+ return this->Contains(rhs.GetStartAddress(), rhs.GetSize());
+ }
+
+ template requires (std::is_same::value || util::is_pod::value)
+ ALWAYS_INLINE T *GetPointer() const {
+ return reinterpret_cast(this->GetAddress());
+ }
+
+ template requires (std::is_same::value || util::is_pod::value)
+ ALWAYS_INLINE T *GetEndPointer() const {
+ return reinterpret_cast(this->GetEndAddress());
+ }
+ };
+
+ constexpr inline const MemoryRegion MemoryRegionVirtual = MemoryRegion(UINT64_C(0x1F0000000), 2_MB);
+ constexpr inline const MemoryRegion MemoryRegionPhysical = MemoryRegion(UINT64_C( 0x40000000), 1_GB);
+ constexpr inline const MemoryRegion MemoryRegionDram = MemoryRegion(UINT64_C( 0x80000000), 2_GB);
+ constexpr inline const MemoryRegion MemoryRegionDramHigh = MemoryRegion(MemoryRegionDram.GetEndAddress(), 2_GB);
+
+ constexpr inline const MemoryRegion MemoryRegionDramForMarikoProgram = MemoryRegion(UINT64_C(0xC0000000), 1_GB);
+ constexpr inline const MemoryRegion MemoryRegionDramDcFramebuffer = MemoryRegion(UINT64_C(0xC0000000), 4_MB);
+ static_assert(MemoryRegionDram.Contains(MemoryRegionDramForMarikoProgram));
+ static_assert(MemoryRegionDramForMarikoProgram.Contains(MemoryRegionDramDcFramebuffer));
+
+ constexpr inline const MemoryRegion MemoryRegionDramGpuCarveout = MemoryRegion(UINT64_C(0x80020000), UINT64_C(0x40000));
+ static_assert(MemoryRegionDram.Contains(MemoryRegionDramGpuCarveout));
+
+ constexpr inline const MemoryRegion MemoryRegionDramDefaultKernelCarveout = MemoryRegion(UINT64_C(0x80060000), UINT64_C(0x1FFE0000));
+ static_assert(MemoryRegionDram.Contains(MemoryRegionDramDefaultKernelCarveout));
+
+ constexpr inline const MemoryRegion MemoryRegionDramPackage2Payloads = MemoryRegion(MemoryRegionDram.GetAddress(), 8_MB);
+ static_assert(MemoryRegionDram.Contains(MemoryRegionDramPackage2Payloads));
+
+ constexpr inline const MemoryRegion MemoryRegionDramPackage2 = MemoryRegion(UINT64_C(0xA9800000), UINT64_C(0x07FC0000));
+ static_assert(MemoryRegionDram.Contains(MemoryRegionDramPackage2));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIram = MemoryRegion(UINT64_C(0x40000000), 0x40000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzram = MemoryRegion(UINT64_C(0x7C010000), 0x10000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramMariko = MemoryRegion(UINT64_C(0x7C010000), 0x40000);
+ static_assert(MemoryRegionPhysical.Contains(MemoryRegionPhysicalIram));
+ static_assert(MemoryRegionPhysical.Contains(MemoryRegionPhysicalTzram));
+ static_assert(MemoryRegionPhysicalTzramMariko.Contains(MemoryRegionPhysicalTzram));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramVolatile(UINT64_C(0x7C010000), 0x2000);
+ static_assert(MemoryRegionPhysicalTzram.Contains(MemoryRegionPhysicalTzramVolatile));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramNonVolatile(UINT64_C(0x7C012000), 0xE000);
+ static_assert(MemoryRegionPhysicalTzram.Contains(MemoryRegionPhysicalTzramNonVolatile));
+
+ static_assert(MemoryRegionPhysicalTzram.GetSize() == MemoryRegionPhysicalTzramNonVolatile.GetSize() + MemoryRegionPhysicalTzramVolatile.GetSize());
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualL1 = MemoryRegion(util::AlignDown(MemoryRegionVirtual.GetAddress(), mmu::L1EntrySize), mmu::L1EntrySize);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalL1 = MemoryRegion(util::AlignDown(MemoryRegionPhysical.GetAddress(), mmu::L1EntrySize), mmu::L1EntrySize);
+ static_assert(MemoryRegionVirtualL1.Contains(MemoryRegionVirtual));
+ static_assert(MemoryRegionPhysicalL1.Contains(MemoryRegionPhysical));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualL2 = MemoryRegion(util::AlignDown(MemoryRegionVirtual.GetAddress(), mmu::L2EntrySize), mmu::L2EntrySize);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramL2 = MemoryRegion(util::AlignDown(MemoryRegionPhysicalIram.GetAddress(), mmu::L2EntrySize), mmu::L2EntrySize);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramL2 = MemoryRegion(util::AlignDown(MemoryRegionPhysicalTzram.GetAddress(), mmu::L2EntrySize), mmu::L2EntrySize);
+ static_assert(MemoryRegionVirtualL2.Contains(MemoryRegionVirtual));
+ static_assert(MemoryRegionPhysicalIramL2.Contains(MemoryRegionPhysicalIram));
+ static_assert(MemoryRegionPhysicalTzramL2.Contains(MemoryRegionPhysicalTzram));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootCode = MemoryRegion(UINT64_C(0x40020000), 0x20000);
+ static_assert(MemoryRegionPhysicalIram.Contains(MemoryRegionPhysicalIramBootCode));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDevice = MemoryRegion(UINT64_C(0x1F0040000), UINT64_C(0x40000));
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualDevice));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDeviceEmpty = MemoryRegion(MemoryRegionVirtualDevice.GetStartAddress(), 0);
+
+ #define AMS_SECMON_FOREACH_DEVICE_REGION(HANDLER, ...) \
+ HANDLER(GicDistributor, Empty, UINT64_C(0x50041000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(GicCpuInterface, GicDistributor, UINT64_C(0x50042000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
+ HANDLER(Uart, GicCpuInterface, UINT64_C(0x70006000), UINT64_C(0x1000), false, ## __VA_ARGS__) \
+ HANDLER(ClkRst, Uart, UINT64_C(0x60006000), UINT64_C(0x1000), false, ## __VA_ARGS__) \
+ HANDLER(RtcPmc, ClkRst, UINT64_C(0x7000E000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(Timer, RtcPmc, UINT64_C(0x60005000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(System, Timer, UINT64_C(0x6000C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(SecurityEngine, System, UINT64_C(0x70012000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
+ HANDLER(SecurityEngine2, SecurityEngine, UINT64_C(0x70412000), UINT64_C(0x2000), true, ## __VA_ARGS__) \
+ HANDLER(SysCtr0, SecurityEngine2, UINT64_C(0x700F0000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(MemoryController, SysCtr0, UINT64_C(0x70019000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(ExternalMemoryController, MemoryController, UINT64_C(0x7001b000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(FuseKFuse, ExternalMemoryController, UINT64_C(0x7000F000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(ApbMisc, FuseKFuse, UINT64_C(0x70000000), UINT64_C(0x4000), true, ## __VA_ARGS__) \
+ HANDLER(FlowController, ApbMisc, UINT64_C(0x60007000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(BootloaderParams, FlowController, UINT64_C(0x40000000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(I2c5, BootloaderParams, UINT64_C(0x7000D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(Gpio, I2c5, UINT64_C(0x6000D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(I2c1, Gpio, UINT64_C(0x7000C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(ExceptionVectors, I2c1, UINT64_C(0x6000F000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(MemoryController0, ExceptionVectors, UINT64_C(0x7001C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(MemoryController1, MemoryController0, UINT64_C(0x7001D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(Sdmmc, MemoryController1, UINT64_C(0x700B0000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(Disp1, Sdmmc, UINT64_C(0x54200000), UINT64_C(0x3000), true, ## __VA_ARGS__) \
+ HANDLER(Dsi, Disp1, UINT64_C(0x54300000), UINT64_C(0x1000), true, ## __VA_ARGS__) \
+ HANDLER(MipiCal, Dsi, UINT64_C(0x700E3000), UINT64_C(0x1000), true, ## __VA_ARGS__)
+
+ #define DEFINE_DEVICE_REGION(_NAME_, _PREV_, _ADDRESS_, _SIZE_, _SECURE_) \
+ constexpr inline const MemoryRegion MemoryRegionVirtualDevice##_NAME_ = MemoryRegion(MemoryRegionVirtualDevice##_PREV_.GetEndAddress() + 0x1000, _SIZE_); \
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDevice##_NAME_ = MemoryRegion(_ADDRESS_, _SIZE_); \
+ static_assert(MemoryRegionVirtualDevice.Contains(MemoryRegionVirtualDevice##_NAME_)); \
+ static_assert(MemoryRegionPhysical.Contains(MemoryRegionPhysicalDevice##_NAME_));
+
+ AMS_SECMON_FOREACH_DEVICE_REGION(DEFINE_DEVICE_REGION)
+
+ #undef DEFINE_DEVICE_REGION
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDeviceFuses = MemoryRegion(MemoryRegionVirtualDeviceFuseKFuse.GetAddress() + 0x800, 0x400);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDeviceFuses = MemoryRegion(MemoryRegionPhysicalDeviceFuseKFuse.GetAddress() + 0x800, 0x400);
+ static_assert(MemoryRegionVirtualDeviceFuseKFuse.Contains(MemoryRegionVirtualDeviceFuses));
+ static_assert(MemoryRegionPhysicalDeviceFuseKFuse.Contains(MemoryRegionPhysicalDeviceFuses));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDeviceActivityMonitor = MemoryRegion(MemoryRegionVirtualDeviceSystem.GetAddress() + 0x800, 0x400);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDeviceActivityMonitor = MemoryRegion(MemoryRegionPhysicalDeviceSystem.GetAddress() + 0x800, 0x400);
+ static_assert(MemoryRegionVirtualDeviceSystem.Contains(MemoryRegionVirtualDeviceActivityMonitor));
+ static_assert(MemoryRegionPhysicalDeviceSystem.Contains(MemoryRegionPhysicalDeviceActivityMonitor));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDeviceUartA = MemoryRegion(MemoryRegionVirtualDeviceUart.GetAddress() + 0x000, 0x040);
+ constexpr inline const MemoryRegion MemoryRegionVirtualDeviceUartB = MemoryRegion(MemoryRegionVirtualDeviceUart.GetAddress() + 0x040, 0x040);
+ constexpr inline const MemoryRegion MemoryRegionVirtualDeviceUartC = MemoryRegion(MemoryRegionVirtualDeviceUart.GetAddress() + 0x200, 0x100);
+ static_assert(MemoryRegionVirtualDeviceUart.Contains(MemoryRegionVirtualDeviceUartA));
+ static_assert(MemoryRegionVirtualDeviceUart.Contains(MemoryRegionVirtualDeviceUartB));
+ static_assert(MemoryRegionVirtualDeviceUart.Contains(MemoryRegionVirtualDeviceUartC));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDeviceUartA = MemoryRegion(MemoryRegionPhysicalDeviceUart.GetAddress() + 0x000, 0x040);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDeviceUartB = MemoryRegion(MemoryRegionPhysicalDeviceUart.GetAddress() + 0x040, 0x040);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDeviceUartC = MemoryRegion(MemoryRegionPhysicalDeviceUart.GetAddress() + 0x200, 0x100);
+ static_assert(MemoryRegionPhysicalDeviceUart.Contains(MemoryRegionPhysicalDeviceUartA));
+ static_assert(MemoryRegionPhysicalDeviceUart.Contains(MemoryRegionPhysicalDeviceUartB));
+ static_assert(MemoryRegionPhysicalDeviceUart.Contains(MemoryRegionPhysicalDeviceUartC));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDevicePmc = MemoryRegion(MemoryRegionVirtualDeviceRtcPmc.GetAddress() + 0x400, 0xC00);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDevicePmc = MemoryRegion(MemoryRegionPhysicalDeviceRtcPmc.GetAddress() + 0x400, 0xC00);
+ static_assert(MemoryRegionVirtualDeviceRtcPmc.Contains(MemoryRegionVirtualDevicePmc));
+ static_assert(MemoryRegionPhysicalDeviceRtcPmc.Contains(MemoryRegionPhysicalDevicePmc));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramReadOnlyAlias = MemoryRegion(UINT64_C(0x1F00A0000), MemoryRegionPhysicalTzram.GetSize());
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramReadOnlyAlias = MemoryRegion(MemoryRegionPhysicalTzram.GetAddress(), MemoryRegionPhysicalTzram.GetSize());
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualTzramReadOnlyAlias));
+ static_assert(MemoryRegionPhysicalTzram.Contains(MemoryRegionPhysicalTzramReadOnlyAlias));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramProgram(UINT64_C(0x1F00C0000), 0xC000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualTzramProgram));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramProgramExceptionVectors(UINT64_C(0x1F00C0000), 0x800);
+ static_assert(MemoryRegionVirtualTzramProgram.Contains(MemoryRegionVirtualTzramProgramExceptionVectors));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramMarikoProgram(UINT64_C(0x1F00D0000), 0x20000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramMarikoProgram(UINT64_C(0x7C020000), 0x20000);
+ static_assert(MemoryRegionPhysicalTzramMariko.Contains(MemoryRegionPhysicalTzramMarikoProgram));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramMarikoProgramFatalErrorContext(UINT64_C(0x1F00EF000), 0x1000);
+ static_assert(MemoryRegionVirtualTzramMarikoProgram.Contains(MemoryRegionVirtualTzramMarikoProgramFatalErrorContext));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramFatalErrorContext(UINT64_C(0x4003E000), 0x1000);
+ static_assert(MemoryRegionPhysicalIram.Contains(MemoryRegionPhysicalIramFatalErrorContext));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramMarikoProgramStack(UINT64_C(0x1F00F4000), 0x8000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramMarikoProgramStack(UINT64_C(0x7C040000), 0x8000);
+ static_assert(MemoryRegionPhysicalTzramMariko.Contains(MemoryRegionPhysicalTzramMarikoProgramStack));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalMarikoProgramImage(UINT64_C(0x80020000), 0x20000);
+ static_assert(MemoryRegionDram.Contains(MemoryRegionPhysicalMarikoProgramImage));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramProgramMain(UINT64_C(0x1F00C0800), 0xB800);
+ static_assert(MemoryRegionVirtualTzramProgram.Contains(MemoryRegionVirtualTzramProgramMain));
+
+ static_assert(MemoryRegionVirtualTzramProgram.GetSize() == MemoryRegionVirtualTzramProgramExceptionVectors.GetSize() + MemoryRegionVirtualTzramProgramMain.GetSize());
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramProgram(UINT64_C(0x7C012000), 0xC000);
+ static_assert(MemoryRegionPhysicalTzramNonVolatile.Contains(MemoryRegionPhysicalTzramProgram));
+
+ constexpr inline const Address PhysicalTzramProgramResetVector = MemoryRegionPhysicalTzramProgram.GetAddress() + MemoryRegionVirtualTzramProgramExceptionVectors.GetSize();
+ static_assert(static_cast(PhysicalTzramProgramResetVector) == PhysicalTzramProgramResetVector);
+
+ constexpr uintptr_t GetPhysicalTzramProgramAddress(uintptr_t virtual_address) {
+ return virtual_address - MemoryRegionVirtualTzramProgram.GetStartAddress() + MemoryRegionPhysicalTzramNonVolatile.GetStartAddress();
+ }
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualIramSc7Work = MemoryRegion(UINT64_C(0x1F0120000), MemoryRegionPhysicalTzram.GetSize());
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramSc7Work = MemoryRegion( UINT64_C(0x40020000), MemoryRegionPhysicalTzram.GetSize());
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualIramSc7Work));
+ static_assert(MemoryRegionPhysicalIram.Contains(MemoryRegionPhysicalIramSc7Work));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualIramSc7Firmware = MemoryRegion(UINT64_C(0x1F0140000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramSc7Firmware = MemoryRegion( UINT64_C(0x40003000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualIramSc7Firmware));
+ static_assert(MemoryRegionPhysicalIram.Contains(MemoryRegionPhysicalIramSc7Firmware));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramSecureMonitorDebug(UINT64_C(0x40034000), 0x4000);
+ static_assert(MemoryRegionPhysicalIram.Contains(MemoryRegionPhysicalIramSecureMonitorDebug));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDebugCode = MemoryRegion(UINT64_C(0x1F0150000), 0x4000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDebugCode = MemoryRegion(UINT64_C(0x40034000), 0x4000);
+ static_assert(MemoryRegionPhysicalIramSecureMonitorDebug.Contains(MemoryRegionPhysicalDebugCode));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDebug = MemoryRegion(UINT64_C(0x1F0160000), 0x10000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualDebug));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramBootCode = MemoryRegion(UINT64_C(0x1F01C0000), 0x2000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramBootCode = MemoryRegion( UINT64_C(0x7C010000), 0x2000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualTzramBootCode));
+ static_assert(MemoryRegionPhysicalTzramVolatile.Contains(MemoryRegionPhysicalTzramBootCode));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramMonitorConfiguration = MemoryRegion( UINT64_C(0x8000F000), 0x1000);
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramSecureDataStore = MemoryRegion(UINT64_C(0x1F0100000), 0x10000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramSecureDataStore = MemoryRegion( UINT64_C(0x80010000), 0x10000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualDramSecureDataStore));
+ static_assert(MemoryRegionDram.Contains(MemoryRegionPhysicalDramSecureDataStore));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramDebugDataStore = MemoryRegion(UINT64_C(0x1F0110000), 0x4000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramDebugDataStore = MemoryRegion( UINT64_C(0x8000C000), 0x4000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualDramSecureDataStore));
+ static_assert(MemoryRegionDram.Contains(MemoryRegionPhysicalDramSecureDataStore));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramSdmmcMappedData = MemoryRegion(UINT64_C(0x1F0100000), 0xC000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramSdmmcMappedData = MemoryRegion(UINT64_C(0x80010000), 0xC000);
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramDcL0DevicePageTable = MemoryRegion(UINT64_C(0x1F010C000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramDcL0DevicePageTable = MemoryRegion( UINT64_C(0x8001C000), 0x1000);
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramSdmmc1L0DevicePageTable = MemoryRegion(UINT64_C(0x1F010E000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramSdmmc1L0DevicePageTable = MemoryRegion( UINT64_C(0x8001E000), 0x1000);
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramSdmmc1L1DevicePageTable = MemoryRegion(UINT64_C(0x1F010F000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramSdmmc1L1DevicePageTable = MemoryRegion( UINT64_C(0x8001F000), 0x1000);
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramSecureDataStoreTzram = MemoryRegion(UINT64_C(0x1F0100000), 0xE000);
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramSecureDataStoreWarmbootFirmware = MemoryRegion(UINT64_C(0x1F010E000), 0x17C0);
+ constexpr inline const MemoryRegion MemoryRegionVirtualDramSecureDataStoreSecurityEngineState = MemoryRegion(UINT64_C(0x1F010F7C0), 0x0840);
+ static_assert(MemoryRegionVirtualDramSecureDataStore.Contains(MemoryRegionVirtualDramSecureDataStoreTzram));
+ static_assert(MemoryRegionVirtualDramSecureDataStore.Contains(MemoryRegionVirtualDramSecureDataStoreWarmbootFirmware));
+ static_assert(MemoryRegionVirtualDramSecureDataStore.Contains(MemoryRegionVirtualDramSecureDataStoreSecurityEngineState));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramSecureDataStoreTzram = MemoryRegion(UINT64_C(0x80010000), 0xE000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramSecureDataStoreWarmbootFirmware = MemoryRegion(UINT64_C(0x8001E000), 0x17C0);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalDramSecureDataStoreSecurityEngineState = MemoryRegion(UINT64_C(0x8001F7C0), 0x0840);
+ static_assert(MemoryRegionPhysicalDramSecureDataStore.Contains(MemoryRegionPhysicalDramSecureDataStoreTzram));
+ static_assert(MemoryRegionPhysicalDramSecureDataStore.Contains(MemoryRegionPhysicalDramSecureDataStoreWarmbootFirmware));
+ static_assert(MemoryRegionPhysicalDramSecureDataStore.Contains(MemoryRegionPhysicalDramSecureDataStoreSecurityEngineState));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualAtmosphereIramPage = MemoryRegion(UINT64_C(0x1F01F0000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualAtmosphereIramPage));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualAtmosphereUserPage = MemoryRegion(UINT64_C(0x1F01F2000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualAtmosphereUserPage));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualSmcUserPage = MemoryRegion(UINT64_C(0x1F01F4000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualSmcUserPage));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramVolatileData = MemoryRegion(UINT64_C(0x1F01F6000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramVolatileData = MemoryRegion( UINT64_C(0x7C010000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualTzramVolatileData));
+ static_assert(MemoryRegionPhysicalTzramVolatile.Contains(MemoryRegionPhysicalTzramVolatileData));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramVolatileStack = MemoryRegion(UINT64_C(0x1F01F8000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramVolatileStack = MemoryRegion( UINT64_C(0x7C011000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualTzramVolatileStack));
+ static_assert(MemoryRegionPhysicalTzramVolatile.Contains(MemoryRegionPhysicalTzramVolatileStack));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramConfigurationData = MemoryRegion(UINT64_C(0x1F01FA000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramConfigurationData = MemoryRegion( UINT64_C(0x7C01E000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualTzramConfigurationData));
+ static_assert(MemoryRegionPhysicalTzramNonVolatile.Contains(MemoryRegionPhysicalTzramConfigurationData));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramL1PageTable = MemoryRegion(UINT64_C(0x1F01FCFC0), 0x40);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramL1PageTable = MemoryRegion( UINT64_C(0x7C01EFC0), 0x40);
+ static_assert(MemoryRegionPhysicalTzramConfigurationData.Contains(MemoryRegionPhysicalTzramL1PageTable));
+
+ constexpr inline const MemoryRegion MemoryRegionVirtualTzramL2L3PageTable = MemoryRegion(UINT64_C(0x1F01FE000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramL2L3PageTable = MemoryRegion( UINT64_C(0x7C01F000), 0x1000);
+ static_assert(MemoryRegionVirtual.Contains(MemoryRegionVirtualTzramL2L3PageTable));
+ static_assert(MemoryRegionPhysicalTzramNonVolatile.Contains(MemoryRegionPhysicalTzramL2L3PageTable));
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalTzramFullProgramImage = MemoryRegion(UINT64_C(0x7C010800), 0xD800);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootCodeImage = MemoryRegion(UINT64_C(0x40032000), 0xC000);
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootCodeCode = MemoryRegion(UINT64_C(0x40032000), 0x1000);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootCodeKeys = MemoryRegion(UINT64_C(0x40033000), 0x1000);
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramWarmbootBin = MemoryRegion(UINT64_C(0x4003E000), 0x17F0);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootConfig = MemoryRegion(UINT64_C(0x4003F800), 0x400);
+
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramRebootStub = MemoryRegion(UINT64_C(0x4003F000), 0x1000);
+
+}
diff --git a/Source/Atmosphere-Patches/secmon_smc_register_access.cpp b/Source/Atmosphere-Patches/secmon_smc_register_access.cpp
new file mode 100644
index 00000000..eae2933c
--- /dev/null
+++ b/Source/Atmosphere-Patches/secmon_smc_register_access.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 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 "../secmon_error.hpp"
+#include "secmon_smc_register_access.hpp"
+
+namespace ams::secmon::smc {
+
+ namespace {
+
+ template
+ constexpr void SetRegisterTableAllowed(std::array &arr, uintptr_t reg) {
+ /* All registers should be four byte aligned. */
+ AMS_ASSUME(reg % sizeof(u32) == 0);
+
+ /* Reduce the register to an index. */
+ reg /= sizeof(u32);
+
+ /* Get the index and mask. */
+ const auto index = reg / BITSIZEOF(u8);
+ const auto mask = (1u << (reg % BITSIZEOF(u8)));
+
+ /* Check that the permission bit isn't already set. */
+ AMS_ASSUME((arr[index] & mask) == 0);
+
+ /* Set the permission bit. */
+ arr[index] |= mask;
+
+ /* Ensure that indices are set in sorted order. */
+ for (auto i = (reg % BITSIZEOF(u8)) + 1; i < 8; ++i) {
+ AMS_ASSUME((arr[index] & (1u << i)) == 0);
+ }
+
+ for (auto i = index + 1; i < arr.size(); ++i) {
+ AMS_ASSUME(arr[i] == 0);
+ }
+ }
+
+ template
+ consteval std::pair GetReducedAccessTableInfo(const std::array &arr) {
+ for (int last = arr.size() - 1; last >= 0; --last) {
+ if (arr[last] != 0) {
+ const int end = last + 1;
+ for (int start = 0; start < end; ++start) {
+ if (arr[start] != 0) {
+ return std::make_pair(static_cast(start), static_cast(end));
+ }
+ }
+ return std::make_pair(static_cast(0), static_cast(end));
+ }
+ }
+
+ /* All empty perm table is disallowed. */
+ AMS_ASSUME(false);
+ }
+
+
+ template
+ struct AccessTable {
+ static constexpr inline auto ReducedAccessTableInfo = GetReducedAccessTableInfo(RawTable);
+ static constexpr inline size_t ReducedAccessTableSize = ReducedAccessTableInfo.second - ReducedAccessTableInfo.first;
+ static constexpr inline auto ReducedAccessTable = []() -> std::array {
+ std::array reduced = {};
+
+ for (size_t i = ReducedAccessTableInfo.first; i < ReducedAccessTableInfo.second; ++i) {
+ reduced[i - ReducedAccessTableInfo.first] = RawTable[i];
+ }
+
+ return reduced;
+ }();
+
+ static constexpr u32 Address = _Address + (ReducedAccessTableInfo.first * sizeof(u32) * BITSIZEOF(u8));
+ static constexpr u32 Size = static_cast(ReducedAccessTableSize * sizeof(u32) * BITSIZEOF(u8));
+
+ static_assert(Size <= 0x1000);
+ };
+
+ struct AccessTableEntry {
+ const u8 * const table;
+ uintptr_t virtual_address;
+ u32 address;
+ u32 size;
+ };
+
+ /* Include the access tables. */
+ #include "secmon_define_pmc_access_table.inc"
+ #include "secmon_define_mc_access_table.inc"
+ #include "secmon_define_emc_access_table.inc"
+ #include "secmon_define_mc01_access_table.inc"
+
+ constexpr const AccessTableEntry AccessTables[] = {
+ { PmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDevicePmc.GetAddress(), PmcAccessTable::Address, PmcAccessTable::Size, },
+ { McAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController.GetAddress(), McAccessTable::Address, McAccessTable::Size, },
+ { EmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController.GetAddress(), EmcAccessTable::Address, EmcAccessTable::Size, },
+ { Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, },
+ { Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },
+ };
+
+ constexpr bool IsAccessAllowed(const AccessTableEntry &entry, uintptr_t address) {
+ /* Check if the address is within range. */
+ if (!(entry.address <= address && address < entry.address + entry.size)) {
+ return false;
+ }
+
+ /* Get the offset. */
+ const auto offset = address - entry.address;
+
+ /* Convert it to an index. */
+ const auto reg_index = offset / sizeof(u32);
+
+ /* Get the bit fields. */
+ const auto index = reg_index / BITSIZEOF(u8);
+ const auto mask = (1u << (reg_index % BITSIZEOF(u8)));
+
+ /* Validate that we're not going out of bounds. */
+ if (index >= entry.size / sizeof(u32)) {
+ return false;
+ }
+
+ return (entry.table[index] & mask) != 0;
+ }
+
+ constexpr const AccessTableEntry *GetAccessTableEntry(uintptr_t address) {
+ for (const auto &entry : AccessTables) {
+ if (IsAccessAllowed(entry, address)) {
+ return std::addressof(entry);
+ }
+ }
+
+ return nullptr;
+ }
+
+ }
+
+ SmcResult SmcReadWriteRegister(SmcArguments &args) {
+ /* Get the arguments. */
+ const uintptr_t address = args.r[1];
+ const u32 mask = args.r[2];
+ const u32 value = args.r[3];
+
+ /* Validate that the address is aligned. */
+ SMC_R_UNLESS(util::IsAligned(address, alignof(u32)), InvalidArgument);
+
+ /* Find the access table. */
+ const AccessTableEntry * const entry = GetAccessTableEntry(address);
+
+ /* Translate our entry into an address to access. */
+ uintptr_t virtual_address = 0;
+ if (entry != nullptr) {
+ /* Get the address to read or write. */
+ virtual_address = entry->virtual_address + (address - entry->address);
+ } else {
+ /* For no clearly discernable reason, SmcReadWriteRegister returns success despite not doing the read/write */
+ /* when accessing the SMMU controls for the BPMP and for APB-DMA. */
+ /* This is "probably" to fuck with hackers who got access to the SMC and are trying to get control of the */
+ /* BPMP to exploit jamais vu, deja vu, or other related DMA/wake-from-sleep vulnerabilities. */
+ constexpr uintptr_t MC = MemoryRegionPhysicalDeviceMemoryController.GetAddress();
+ SMC_R_UNLESS((address == (MC + MC_SMMU_AVPC_ASID) || address == (MC + MC_SMMU_PPCS1_ASID)), InvalidArgument);
+
+ /* For backwards compatibility, we'll allow access to these devices on 1.0.0. */
+ if (GetTargetFirmware() < TargetFirmware_2_0_0) {
+ virtual_address = MemoryRegionVirtualDeviceMemoryController.GetAddress() + (address - MC);
+ }
+ }
+
+ /* Perform the read or write, if we should. */
+ if (virtual_address != 0) {
+ u32 out = 0;
+
+ if (mask != ~static_cast(0)) {
+ out = reg::Read(virtual_address);
+ }
+ if (mask != static_cast(0)) {
+ reg::Write(virtual_address, (out & ~mask) | (value & mask));
+ }
+
+ args.r[1] = out;
+ }
+
+ return SmcResult::Success;
+ }
+
+}
diff --git a/Source/ams_patch.bat b/Source/ams_patch.bat
new file mode 100644
index 00000000..02428619
--- /dev/null
+++ b/Source/ams_patch.bat
@@ -0,0 +1,10 @@
+@echo off
+set ROOT=Atmosphere-MTC-Unlock
+set PATCHES=Atmosphere-Patches
+copy "%PATCHES%\secmon_memory_layout.hpp" "%ROOT%\libraries\libexosphere/include/exosphere/secmon/" /Y
+copy "%PATCHES%\secmon_emc_access_table_data.inc" "%ROOT%\exosphere/program/source/smc/" /Y
+copy "%PATCHES%\secmon_define_emc_access_table.inc" "%ROOT%\exosphere/program/source/smc/" /Y
+copy "%PATCHES%\secmon_smc_register_access.cpp" "%ROOT%\exosphere/program/source/smc/" /Y
+
+echo Patched!
+pause
diff --git a/Source/sys-clk/common/include/sysclk/config.h b/Source/sys-clk/common/include/sysclk/config.h
index a29137ec..b38dd62e 100644
--- a/Source/sys-clk/common/include/sysclk/config.h
+++ b/Source/sys-clk/common/include/sysclk/config.h
@@ -60,6 +60,8 @@ typedef enum {
HocClkConfigValue_EnforceBoardLimit,
+ HocClkConfigValue_EMCVdd2VoltageUV,
+
SysClkConfigValue_EnumMax,
} SysClkConfigValue;
@@ -122,7 +124,10 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
case HocClkConfigValue_TDPCycleLimit:
return pretty ? "TDP Cycle Limit" : "tdp_limit_c";
-
+ case HocClkConfigValue_EnforceBoardLimit:
+ return pretty ? "Enforce Board Limit" : "enforce_board_limit";
+ case HocClkConfigValue_EMCVdd2VoltageUV:
+ return pretty ? "EMC Vdd2 Voltage" : "emc_vdd2_voltage_uv";
default:
return pretty ? "Null" : "null";
}
@@ -159,6 +164,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
case HocClkConfigValue_DockedGovernor:
case HocClkConfigValue_HandheldGovernor:
case HocClkConfigValue_HandheldTDP:
+ case HocClkConfigValue_EnforceBoardLimit:
return 1ULL;
case HocClkConfigValue_ThermalThrottleThreshold:
return 70ULL;
@@ -168,6 +174,8 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
return 6400ULL;
case HocClkConfigValue_TDPCycleLimit:
return 10ULL;
+ case HocClkConfigValue_EMCVdd2VoltageUV:
+ return 1175000ULL;
default:
return 0ULL;
}
@@ -193,6 +201,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case SysClkConfigValue_PowerLogIntervalMs:
case SysClkConfigValue_CsvWriteIntervalMs:
case HocClkConfigValue_TDPCycleLimit:
+ case HocClkConfigValue_EMCVdd2VoltageUV:
return input >= 0;
case HocClkConfigValue_UncappedClocks:
case HocClkConfigValue_OverwriteBoostMode:
@@ -200,6 +209,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case HocClkConfigValue_DockedGovernor:
case HocClkConfigValue_HandheldGovernor:
case HocClkConfigValue_HandheldTDP:
+ case HocClkConfigValue_EnforceBoardLimit:
return (input & 0x1) == input;
default:
return false;
diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp
index 4b997b07..cd01d3ca 100644
--- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp
+++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp
@@ -207,12 +207,13 @@ void MiscGui::listUI()
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental"));
addConfigToggle(HocClkConfigValue_ThermalThrottle, nullptr);
addConfigToggle(HocClkConfigValue_HandheldTDP, nullptr);
+ addConfigToggle(HocClkConfigValue_EnforceBoardLimit, nullptr);
ValueThresholds tdpThresholds(8600, 9500);
addConfigButton(
HocClkConfigValue_HandheldTDPLimit,
"TDP Threshold",
- ValueRange(5000, 10000, 100, "mW", 1),
+ ValueRange(5000, 10000, 200, "mW", 1),
"Power",
&tdpThresholds
);
@@ -221,7 +222,7 @@ void MiscGui::listUI()
addConfigButton(
HocClkConfigValue_LiteTDPLimit,
"Lite TDP Threshold",
- ValueRange(4000, 8000, 100, "mW", 1),
+ ValueRange(4000, 8000, 200, "mW", 1),
"Power",
&tdpThresholdsLite
);
@@ -230,7 +231,7 @@ void MiscGui::listUI()
addConfigButton(
HocClkConfigValue_ThermalThrottleThreshold,
"Thermal Throttle Limit",
- ValueRange(50, 85, 1, "°C", 1),
+ ValueRange(50, 85, 5, "°C", 1),
"Temp",
&throttleThresholds
);
@@ -244,6 +245,16 @@ void MiscGui::listUI()
addFreqButton(HocClkConfigValue_EristaMaxGpuClock, nullptr, SysClkModule_GPU);
addFreqButton(HocClkConfigValue_EristaMaxMemClock, nullptr, SysClkModule_MEM);
}
+
+ ValueThresholds emcUvThresholds(1212500, 1250000);
+ addConfigButton(
+ HocClkConfigValue_EMCVdd2VoltageUV,
+ "EMC VDD2 Voltage",
+ ValueRange(1100000, 1350000, 12500, "mV", 1000, 1),
+ "EMC VDD2 Voltage",
+ &emcUvThresholds
+ );
+
tsl::elm::ListItem* applyBtn = new tsl::elm::ListItem("Apply EMC Regs");
applyBtn->setClickListener([](u64 keys) {
if (keys & HidNpadButton_A) {
diff --git a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp
index ed5108df..7856d150 100644
--- a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp
+++ b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp
@@ -1,145 +1,118 @@
-/*
- * Copyright (c) Souldbminer and Horizon OC Contributors
- *
- * 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 .
- *
- */
-
-/* --------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * , ,
- * wrote this file. As long as you retain this notice you can do whatever you
- * want with this stuff. If you meet any of us some day, and you think this
- * stuff is worth it, you can buy us a beer in return. - The sys-clk authors
- * --------------------------------------------------------------------------
- */
+#include "value_choice_gui.h"
+#include "../format.h"
+#include "fatal_gui.h"
+#include
+#include
+ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue,
+ const ValueRange& range,
+ const std::string& categoryName,
+ ValueChoiceListener listener,
+ const ValueThresholds& thresholds,
+ bool enableThresholds)
+ : selectedValue(selectedValue),
+ range(range),
+ categoryName(categoryName),
+ listener(listener),
+ thresholds(thresholds),
+ enableThresholds(enableThresholds)
+{
+}
- #include "value_choice_gui.h"
- #include "../format.h"
- #include "fatal_gui.h"
- #include
- #include
+ValueChoiceGui::~ValueChoiceGui()
+{
+}
- ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue,
- const ValueRange& range,
- const std::string& categoryName,
- ValueChoiceListener listener,
- const ValueThresholds& thresholds,
- bool enableThresholds)
- : selectedValue(selectedValue),
- range(range),
- categoryName(categoryName),
- listener(listener),
- thresholds(thresholds),
- enableThresholds(enableThresholds)
- {
- }
+std::string ValueChoiceGui::formatValue(std::uint32_t value)
+{
+ std::ostringstream oss;
- ValueChoiceGui::~ValueChoiceGui()
- {
- }
+ if (value == 0) {
+ return VALUE_DEFAULT_TEXT;
+ }
- std::string ValueChoiceGui::formatValue(std::uint32_t value)
- {
- std::ostringstream oss;
+ // Convert to floating point for division
+ double displayValue = static_cast(value) / static_cast(range.divisor);
- if (value == 0) {
+ // Set precision and formatting
+ oss << std::fixed << std::setprecision(range.decimalPlaces) << displayValue;
+
+ if (!range.suffix.empty()) {
+ oss << " " << range.suffix;
+ }
+ return oss.str();
+}
- return VALUE_DEFAULT_TEXT;
- }
+int ValueChoiceGui::getSafetyLevel(std::uint32_t value)
+{
+ // if (!enableThresholds) {
+ // return 0;
+ // }
- std::uint32_t displayValue = value / range.divisor;
+ std::uint32_t scaledValue = value / range.divisor;
- oss << displayValue;
- if (!range.suffix.empty()) {
- oss << " " << range.suffix;
- }
- return oss.str();
- }
+ if (value > thresholds.danger) {
+ return 2;
+ }
+ if (value > thresholds.warning) {
+ return 1;
+ }
+ return 0;
+}
- int ValueChoiceGui::getSafetyLevel(std::uint32_t value)
- {
- if (!enableThresholds) {
- return 0;
- }
+tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, bool selected, int safety)
+{
+ std::string text = formatValue(value);
+ if (selected) {
+ text += " \uE14B";
+ }
- std::uint32_t scaledValue = value / range.divisor;
+ tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, "", false);
- if (scaledValue > thresholds.danger) {
- return 2;
- }
- if (scaledValue > thresholds.warning) {
- return 1;
- }
- return 0;
- }
+ switch (safety)
+ {
+ case 0:
+ listItem->setTextColor(tsl::Color(255, 255, 255, 255));
+ listItem->setValueColor(tsl::Color(255, 255, 255, 255));
+ break;
+ case 1:
+ listItem->setTextColor(tsl::Color(255, 165, 0, 255));
+ listItem->setValueColor(tsl::Color(255, 165, 0, 255));
+ break;
+ case 2:
+ listItem->setTextColor(tsl::Color(255, 0, 0, 255));
+ listItem->setValueColor(tsl::Color(255, 0, 0, 255));
+ break;
+ }
- tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, bool selected, int safety)
- {
- std::string text = formatValue(value);
- if (selected) {
- text += " \uE14B";
- }
+ listItem->setClickListener([this, value](u64 keys)
+ {
+ if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) {
+ if (this->listener(value)) {
+ tsl::goBack();
+ }
+ return true;
+ }
+ return false;
+ });
- tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, "", false);
+ return listItem;
+}
- switch (safety)
- {
- case 0:
- listItem->setTextColor(tsl::Color(255, 255, 255, 255));
- listItem->setValueColor(tsl::Color(255, 255, 255, 255));
- break;
- case 1:
- listItem->setTextColor(tsl::Color(255, 165, 0, 255));
- listItem->setValueColor(tsl::Color(255, 165, 0, 255));
- break;
- case 2:
- listItem->setTextColor(tsl::Color(255, 0, 0, 255));
- listItem->setValueColor(tsl::Color(255, 0, 0, 255));
- break;
- }
+void ValueChoiceGui::listUI()
+{
+ if (!categoryName.empty()) {
+ this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName));
+ }
- listItem->setClickListener([this, value](u64 keys)
- {
- if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) {
+ this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
- if (this->listener(value)) {
- tsl::goBack();
- }
- return true;
- }
- return false;
- });
+ for (std::uint32_t value = range.min; value <= range.max; value += range.step)
+ {
+ int safety = getSafetyLevel(value);
+ bool selected = (value == this->selectedValue);
+ this->listElement->addItem(this->createValueListItem(value, selected, safety));
+ }
- return listItem;
- }
-
- void ValueChoiceGui::listUI()
- {
-
- if (!categoryName.empty()) {
- this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName));
- }
-
- this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
-
- for (std::uint32_t value = range.min; value <= range.max; value += range.step)
- {
- int safety = getSafetyLevel(value);
- bool selected = (value == this->selectedValue);
- this->listElement->addItem(this->createValueListItem(value, selected, safety));
- }
-
- this->listElement->jumpToItem("", "\uE14B");
- }
\ No newline at end of file
+ this->listElement->jumpToItem("", "\uE14B");
+}
\ No newline at end of file
diff --git a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h
index 160de655..2c9b122e 100644
--- a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h
+++ b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h
@@ -37,20 +37,20 @@
#define VALUE_DEFAULT_TEXT "Default"
struct ValueRange {
- std::uint32_t min;
- std::uint32_t max;
- std::uint32_t step;
- std::string suffix;
- std::uint32_t divisor; // Divide input values by this for display
-
- // Default constructor
- ValueRange() : min(0), max(0), step(1), suffix(""), divisor(1) {}
-
- ValueRange(std::uint32_t min, std::uint32_t max, std::uint32_t step,
- const std::string& suffix = "", std::uint32_t divisor = 1)
- : min(min), max(max), step(step), suffix(suffix), divisor(divisor) {}
- };
-
+ std::uint32_t min;
+ std::uint32_t max;
+ std::uint32_t step;
+ std::string suffix;
+ std::uint32_t divisor; // Divide input values by this for display
+ int decimalPlaces; // Number of decimal places to display (0-6)
+
+ ValueRange() : min(0), max(0), step(1), suffix(""), divisor(1), decimalPlaces(0) {}
+
+ ValueRange(std::uint32_t min, std::uint32_t max, std::uint32_t step,
+ const std::string& suffix = "", std::uint32_t divisor = 1, int decimalPlaces = 0)
+ : min(min), max(max), step(step), suffix(suffix), divisor(divisor), decimalPlaces(decimalPlaces) {}
+};
+
struct ValueThresholds {
std::uint32_t warning; // Values >= this show orange
std::uint32_t danger; // Values >= this show red
diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp
index b82dd89d..9cebf807 100644
--- a/Source/sys-clk/sysmodule/src/clock_manager.cpp
+++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp
@@ -235,23 +235,32 @@ void ClockManager::Tick()
std::uint32_t maxHz = 0;
std::uint32_t nearestHz = 0;
std::uint32_t mode = 0;
-
+
+ if(this->config->GetConfigValue(HocClkConfigValue_EMCVdd2VoltageUV) < 1400000) { // Safety Check
+ set_sd1_voltage((u32)this->config->GetConfigValue(HocClkConfigValue_EMCVdd2VoltageUV));
+ }
+
AppletOperationMode opMode = appletGetOperationMode();
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
ASSERT_RESULT_OK(rc, "apmExtGetCurrentPerformanceConfiguration");
if(this->config->GetConfigValue(HocClkConfigValue_HandheldTDP) && opMode == AppletOperationMode_Handheld) {
if(Board::GetSocType() == SysClkSocType_MarikoLite) {
- if(Board::GetPowerMw(SysClkPowerSensor_Now) < -(int)this->config->GetConfigValue(HocClkConfigValue_LiteTDPLimit)) {
+ if(Board::GetPowerMw(SysClkPowerSensor_Avg) < -(int)this->config->GetConfigValue(HocClkConfigValue_LiteTDPLimit)) {
ResetToStockClocks();
return;
}
} else {
- if(Board::GetPowerMw(SysClkPowerSensor_Now) < -(int)this->config->GetConfigValue(HocClkConfigValue_HandheldTDPLimit)) {
+ if(Board::GetPowerMw(SysClkPowerSensor_Avg) < -(int)this->config->GetConfigValue(HocClkConfigValue_HandheldTDPLimit)) {
ResetToStockClocks();
return;
}
}
+ } else if(opMode == AppletOperationMode_Console && this->config->GetConfigValue(HocClkConfigValue_EnforceBoardLimit)) {
+ if(Board::GetPowerMw(SysClkPowerSensor_Avg) < 0) {
+ ResetToStockClocks();
+ return;
+ }
}
if(apmExtIsBoostMode(mode) && !this->config->GetConfigValue(HocClkConfigValue_OverwriteBoostMode)) {
@@ -442,4 +451,52 @@ bool ClockManager::RefreshContext()
void ClockManager::SetRNXRTMode(ReverseNXMode mode)
{
this->rnxSync->SetRTMode(mode);
+}
+
+void ClockManager::set_sd1_voltage(uint32_t voltage_uv)
+{
+ // SD1 parameters
+ const u32 uv_step = 12500;
+ const u32 uv_min = 600000;
+ const u32 uv_max = 1237500;
+ const u8 volt_addr = 0x17; // MAX77620_REG_SD1
+ const u8 volt_mask = 0x7F; // MAX77620_SD1_VOLT_MASK
+
+ // Validate input voltage
+ if (voltage_uv < uv_min || voltage_uv > uv_max)
+ return;
+
+ // Calculate voltage multiplier
+ u32 mult = (voltage_uv + uv_step - 1 - uv_min) / uv_step;
+ mult = mult & volt_mask;
+
+ // Open I2C session to MAX77620 PMIC
+ I2cSession session;
+ Result res = i2cOpenSession(&session, I2cDevice_Max77620Pmic);
+ if (R_FAILED(res)) {
+ return;
+ }
+
+ // Read current register value
+ u8 current_val = 0;
+ res = i2csessionSendAuto(&session, &volt_addr, 1, I2cTransactionOption_Start);
+ if (R_FAILED(res)) {
+ i2csessionClose(&session);
+ return;
+ }
+
+ res = i2csessionReceiveAuto(&session, ¤t_val, 1, I2cTransactionOption_Stop);
+ if (R_FAILED(res)) {
+ i2csessionClose(&session);
+ return;
+ }
+
+ // Mask in the new voltage bits, preserving other bits
+ u8 new_val = (current_val & ~volt_mask) | mult;
+
+ // Write back register with START and STOP conditions
+ u8 write_buf[2] = {volt_addr, new_val};
+ res = i2csessionSendAuto(&session, write_buf, sizeof(write_buf), I2cTransactionOption_All);
+
+ i2csessionClose(&session);
}
\ No newline at end of file
diff --git a/Source/sys-clk/sysmodule/src/clock_manager.h b/Source/sys-clk/sysmodule/src/clock_manager.h
index c29681d8..9fd92c00 100644
--- a/Source/sys-clk/sysmodule/src/clock_manager.h
+++ b/Source/sys-clk/sysmodule/src/clock_manager.h
@@ -70,6 +70,7 @@ class ClockManager
bool ConfigIntervalTimeout(SysClkConfigValue intervalMsConfigValue, std::uint64_t ns, std::uint64_t* lastLogNs);
void RefreshFreqTableRow(SysClkModule module);
bool RefreshContext();
+ void set_sd1_voltage(uint32_t voltage_uv);
static ClockManager *instance;
diff --git a/Source/sys-clk/sysmodule/src/emc_patcher.cpp b/Source/sys-clk/sysmodule/src/emc_patcher.cpp
index 6b5c7135..9e34bdac 100644
--- a/Source/sys-clk/sysmodule/src/emc_patcher.cpp
+++ b/Source/sys-clk/sysmodule/src/emc_patcher.cpp
@@ -66,26 +66,26 @@ void EMCpatcher::Run()
void EMCpatcher::ApplyEMCPatch()
{
- if(HOSSVC_HAS_MM) { // only for 10.0.0+, older versions need rewrites
- u64 mc_virt_addr = 0;
- u64 mc_out_size = 0;
- u64 emc_virt_addr = 0;
- u64 emc_out_size = 0;
- Result rc;
+ // if(HOSSVC_HAS_MM) { // only for 10.0.0+, older versions need rewrites
+ // u64 mc_virt_addr = 0;
+ // u64 mc_out_size = 0;
+ // u64 emc_virt_addr = 0;
+ // u64 emc_out_size = 0;
+ // Result rc;
- // rc = svcQueryMemoryMapping(&mc_virt_addr, &mc_out_size, MC_BASE, MC_EMC_BASE_SIZE); // map mc
- // ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping");
+ // // rc = svcQueryMemoryMapping(&mc_virt_addr, &mc_out_size, MC_BASE, MC_EMC_BASE_SIZE); // map mc
+ // // ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping");
- // rc = svcQueryMemoryMapping(&emc_virt_addr, &emc_out_size, EMC_BASE, MC_EMC_BASE_SIZE); // map emc
- // ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping");
+ // // rc = svcQueryMemoryMapping(&emc_virt_addr, &emc_out_size, EMC_BASE, MC_EMC_BASE_SIZE); // map emc
+ // // ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping");
- write_reg64(EMC_BASE, EMC_RAS_0, 1);
+ // write_reg64(EMC_BASE, EMC_RAS_0, 1);
- write_reg64(EMC_BASE, EMC_TIMING_CONTROL_0, 0x1); // apply shadow regs
+ // write_reg64(EMC_BASE, EMC_TIMING_CONTROL_0, 0x1); // apply shadow regs
- // svcUnmapMemory((void *)mc_virt_addr, (void *)MC_BASE, MC_EMC_BASE_SIZE); // clean up
- // svcUnmapMemory((void *)emc_virt_addr, (void *)EMC_BASE, MC_EMC_BASE_SIZE);
+ // // svcUnmapMemory((void *)mc_virt_addr, (void *)MC_BASE, MC_EMC_BASE_SIZE); // clean up
+ // // svcUnmapMemory((void *)emc_virt_addr, (void *)EMC_BASE, MC_EMC_BASE_SIZE);
- }
+ // }
}
diff --git a/Source/sys-clk/sysmodule/src/maxXXXXX.h b/Source/sys-clk/sysmodule/src/maxXXXXX.h
new file mode 100644
index 00000000..2da06670
--- /dev/null
+++ b/Source/sys-clk/sysmodule/src/maxXXXXX.h
@@ -0,0 +1,691 @@
+/*
+ * Copyright (c) Souldbminer and Horizon OC Contributors
+ *
+ * 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 .
+ *
+ */
+
+
+/*
+ * Defining registers address and its bit definitions of MAX77620 and MAX20024
+ *
+ * Copyright (c) 2019-2020 CTCaer
+ *
+ * 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.
+ */
+
+#include
+
+#ifndef MAX77XXX_H
+#define MAX77XXX_H
+
+
+#define MAX17050_BOARD_CGAIN 2 /* Actual: 1.99993 */
+#define MAX17050_BOARD_SNS_RESISTOR_UOHM 5000 /* 0.005 Ohm */
+
+#define MAX17050_STATUS_BattAbsent BIT(3)
+
+/* Consider RepCap which is less then 10 units below FullCAP full */
+#define MAX17050_FULL_THRESHOLD 10
+
+#define MAX17050_CHARACTERIZATION_DATA_SIZE 48
+
+#define MAXIM17050_I2C_ADDR 0x36
+
+enum MAX17050_reg {
+ MAX17050_STATUS = 0x00,
+ MAX17050_VALRT_Th = 0x01,
+ MAX17050_TALRT_Th = 0x02,
+ MAX17050_SALRT_Th = 0x03,
+ MAX17050_AtRate = 0x04,
+ MAX17050_RepCap = 0x05,
+ MAX17050_RepSOC = 0x06,
+ MAX17050_Age = 0x07,
+ MAX17050_TEMP = 0x08,
+ MAX17050_VCELL = 0x09,
+ MAX17050_Current = 0x0A,
+ MAX17050_AvgCurrent = 0x0B,
+
+ MAX17050_SOC = 0x0D,
+ MAX17050_AvSOC = 0x0E,
+ MAX17050_RemCap = 0x0F,
+ MAX17050_FullCAP = 0x10,
+ MAX17050_TTE = 0x11,
+ MAX17050_QRTbl00 = 0x12,
+ MAX17050_FullSOCThr = 0x13,
+ MAX17050_RSLOW = 0x14,
+
+ MAX17050_AvgTA = 0x16,
+ MAX17050_Cycles = 0x17,
+ MAX17050_DesignCap = 0x18,
+ MAX17050_AvgVCELL = 0x19,
+ MAX17050_MinMaxTemp = 0x1A,
+ MAX17050_MinMaxVolt = 0x1B,
+ MAX17050_MinMaxCurr = 0x1C,
+ MAX17050_CONFIG = 0x1D,
+ MAX17050_ICHGTerm = 0x1E,
+ MAX17050_AvCap = 0x1F,
+ MAX17050_ManName = 0x20,
+ MAX17050_DevName = 0x21,
+ MAX17050_QRTbl10 = 0x22,
+ MAX17050_FullCAPNom = 0x23,
+ MAX17050_TempNom = 0x24,
+ MAX17050_TempLim = 0x25,
+ MAX17050_TempHot = 0x26,
+ MAX17050_AIN = 0x27,
+ MAX17050_LearnCFG = 0x28,
+ MAX17050_FilterCFG = 0x29,
+ MAX17050_RelaxCFG = 0x2A,
+ MAX17050_MiscCFG = 0x2B,
+ MAX17050_TGAIN = 0x2C,
+ MAX17050_TOFF = 0x2D,
+ MAX17050_CGAIN = 0x2E,
+ MAX17050_COFF = 0x2F,
+
+ MAX17050_QRTbl20 = 0x32,
+ MAX17050_SOC_empty = 0x33,
+ MAX17050_T_empty = 0x34,
+ MAX17050_FullCAP0 = 0x35,
+ MAX17050_LAvg_empty = 0x36,
+ MAX17050_FCTC = 0x37,
+ MAX17050_RCOMP0 = 0x38,
+ MAX17050_TempCo = 0x39,
+ MAX17050_V_empty = 0x3A,
+ MAX17050_K_empty0 = 0x3B,
+ MAX17050_TaskPeriod = 0x3C,
+ MAX17050_FSTAT = 0x3D,
+ MAX17050_TIMER = 0x3E,
+ MAX17050_SHDNTIMER = 0x3F,
+
+ MAX17050_QRTbl30 = 0x42,
+
+ MAX17050_dQacc = 0x45,
+ MAX17050_dPacc = 0x46,
+
+ MAX17050_VFSOC0 = 0x48,
+
+ Max17050_QH0 = 0x4C,
+ MAX17050_QH = 0x4D,
+ MAX17050_QL = 0x4E,
+
+ MAX17050_MinVolt = 0x50, // Custom ID. Not to be sent to i2c.
+ MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c.
+
+ MAX17050_VFSOC0Enable = 0x60,
+ MAX17050_MODELEnable1 = 0x62,
+ MAX17050_MODELEnable2 = 0x63,
+
+ MAX17050_MODELChrTbl = 0x80,
+
+ MAX17050_OCV = 0xEE,
+
+ MAX17050_OCVInternal = 0xFB,
+
+ MAX17050_VFSOC = 0xFF,
+};
+
+#define MAX77620_I2C_ADDR 0x3C
+
+/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
+#define MAX77620_REG_CNFGGLBL1 0x00
+#define MAX77620_CNFGGLBL1_LBRSTEN BIT(0)
+#define MAX77620_CNFGGLBL1_LBDAC_MASK 0x0E
+#define MAX77620_CNFGGLBL1_LBDAC_2700 (0 << 1)
+#define MAX77620_CNFGGLBL1_LBDAC_2800 (1 << 1)
+#define MAX77620_CNFGGLBL1_LBDAC_2900 (2 << 1)
+#define MAX77620_CNFGGLBL1_LBDAC_3000 (3 << 1)
+#define MAX77620_CNFGGLBL1_LBDAC_3100 (4 << 1)
+#define MAX77620_CNFGGLBL1_LBDAC_3200 (5 << 1)
+#define MAX77620_CNFGGLBL1_LBDAC_3300 (6 << 1)
+#define MAX77620_CNFGGLBL1_LBDAC_3400 (7 << 1)
+#define MAX77620_CNFGGLBL1_LBHYST_100 (0 << 4)
+#define MAX77620_CNFGGLBL1_LBHYST_200 (1 << 4)
+#define MAX77620_CNFGGLBL1_LBHYST_300 (2 << 4)
+#define MAX77620_CNFGGLBL1_LBHYST_400 (3 << 4)
+#define MAX77620_CNFGGLBL1_MPPLD BIT(6)
+#define MAX77620_CNFGGLBL1_LBDAC_EN BIT(7)
+
+#define MAX77620_REG_CNFGGLBL2 0x01
+#define MAX77620_TWD_MASK 0x3
+#define MAX77620_TWD_2s 0x0
+#define MAX77620_TWD_16s 0x1
+#define MAX77620_TWD_64s 0x2
+#define MAX77620_TWD_128s 0x3
+#define MAX77620_WDTEN BIT(2)
+#define MAX77620_WDTSLPC BIT(3)
+#define MAX77620_WDTOFFC BIT(4)
+#define MAX77620_GLBL_LPM BIT(5)
+#define MAX77620_I2CTWD_MASK 0xC0
+#define MAX77620_I2CTWD_DISABLED 0x00
+#define MAX77620_I2CTWD_1_33ms 0x40
+#define MAX77620_I2CTWD_35_7ms 0x80
+#define MAX77620_I2CTWD_41_7ms 0xC0
+
+#define MAX77620_REG_CNFGGLBL3 0x02
+#define MAX77620_WDTC_MASK 0x3
+
+#define MAX77620_REG_CNFG1_32K 0x03
+#define MAX77620_CNFG1_PWR_MD_32K_MASK 0x3
+#define MAX77620_CNFG1_32K_OUT0_EN BIT(2)
+#define MAX77620_CNFG1_32KLOAD_MASK 0x30
+#define MAX77620_CNFG1_32K_OK BIT(7)
+
+#define MAX77620_REG_CNFGBBC 0x04
+#define MAX77620_CNFGBBC_ENABLE BIT(0)
+#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
+#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
+#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
+#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
+#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE BIT(5)
+#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
+#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
+#define MAX77620_CNFGBBC_RESISTOR_100 (0 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
+#define MAX77620_CNFGBBC_RESISTOR_1K (1 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
+#define MAX77620_CNFGBBC_RESISTOR_3K (2 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
+#define MAX77620_CNFGBBC_RESISTOR_6K (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
+
+#define MAX77620_REG_IRQTOP 0x05
+#define MAX77620_REG_IRQTOPM 0x0D
+#define MAX77620_IRQ_TOP_ONOFF_MASK BIT(1)
+#define MAX77620_IRQ_TOP_32K_MASK BIT(2)
+#define MAX77620_IRQ_TOP_RTC_MASK BIT(3)
+#define MAX77620_IRQ_TOP_GPIO_MASK BIT(4)
+#define MAX77620_IRQ_TOP_LDO_MASK BIT(5)
+#define MAX77620_IRQ_TOP_SD_MASK BIT(6)
+#define MAX77620_IRQ_TOP_GLBL_MASK BIT(7)
+
+#define MAX77620_REG_INTLBT 0x06
+#define MAX77620_REG_INTENLBT 0x0E
+#define MAX77620_IRQ_GLBLM_MASK BIT(0)
+#define MAX77620_IRQ_TJALRM2_MASK BIT(1)
+#define MAX77620_IRQ_TJALRM1_MASK BIT(2)
+#define MAX77620_IRQ_LBM_MASK BIT(3)
+
+#define MAX77620_REG_IRQSD 0x07
+#define MAX77620_REG_IRQMASKSD 0x0F
+#define MAX77620_IRQSD_PFI_SD3 BIT(4)
+#define MAX77620_IRQSD_PFI_SD2 BIT(5)
+#define MAX77620_IRQSD_PFI_SD1 BIT(6)
+#define MAX77620_IRQSD_PFI_SD0 BIT(7)
+
+#define MAX77620_REG_IRQ_LVL2_L0_7 0x08 // LDO number that irq occurred.
+#define MAX77620_REG_IRQ_MSK_L0_7 0x10
+#define MAX77620_REG_IRQ_LVL2_L8 \
+ 0x09 // LDO number that irq occurred. Only bit0: LDO8 is valid.
+#define MAX77620_REG_IRQ_MSK_L8 0x11
+#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A // Edge detection interrupt.
+
+#define MAX77620_REG_ONOFFIRQ 0x0B
+#define MAX77620_REG_ONOFFIRQM 0x12
+#define MAX77620_ONOFFIRQ_MRWRN BIT(0)
+#define MAX77620_ONOFFIRQ_EN0_1SEC BIT(1)
+#define MAX77620_ONOFFIRQ_EN0_F BIT(2)
+#define MAX77620_ONOFFIRQ_EN0_R BIT(3)
+#define MAX77620_ONOFFIRQ_LID_F BIT(4)
+#define MAX77620_ONOFFIRQ_LID_R BIT(5)
+#define MAX77620_ONOFFIRQ_ACOK_F BIT(6)
+#define MAX77620_ONOFFIRQ_ACOK_R BIT(7)
+
+#define MAX77620_REG_NVERC 0x0C // Shutdown reason (non-volatile).
+#define MAX77620_NVERC_SHDN BIT(0)
+#define MAX77620_NVERC_WTCHDG BIT(1)
+#define MAX77620_NVERC_HDRST BIT(2)
+#define MAX77620_NVERC_TOVLD BIT(3)
+#define MAX77620_NVERC_MBLSD BIT(4)
+#define MAX77620_NVERC_MBO BIT(5)
+#define MAX77620_NVERC_MBU BIT(6)
+#define MAX77620_NVERC_RSTIN BIT(7)
+
+#define MAX77620_REG_STATLBT 0x13
+#define MAX77620_REG_STATSD 0x14
+
+#define MAX77620_REG_ONOFFSTAT 0x15
+#define MAX77620_ONOFFSTAT_LID BIT(0)
+#define MAX77620_ONOFFSTAT_ACOK BIT(1)
+#define MAX77620_ONOFFSTAT_EN0 BIT(2)
+
+/* SD and LDO Registers */
+#define MAX77620_REG_SD0 0x16
+#define MAX77620_REG_SD1 0x17
+#define MAX77620_REG_SD2 0x18
+#define MAX77620_REG_SD3 0x19
+#define MAX77620_REG_SD4 0x1A
+#define MAX77620_REG_DVSSD0 0x1B
+#define MAX77620_REG_DVSSD1 0x1C
+#define MAX77620_SDX_VOLT_MASK 0xFF
+#define MAX77620_SD0_VOLT_MASK 0x7F // Max is 0x40.
+#define MAX77620_SD1_VOLT_MASK 0x7F // Max is 0x4C.
+#define MAX77620_LDO_VOLT_MASK 0x3F
+
+#define MAX77620_REG_SD0_CFG 0x1D
+#define MAX77620_REG_SD1_CFG 0x1E
+#define MAX77620_REG_SD2_CFG 0x1F
+#define MAX77620_REG_SD3_CFG 0x20
+#define MAX77620_REG_SD4_CFG 0x21
+#define MAX77620_SD_SR_MASK 0xC0
+#define MAX77620_SD_SR_SHIFT 6
+#define MAX77620_SD_POWER_MODE_MASK 0x30
+#define MAX77620_SD_POWER_MODE_SHIFT 4
+#define MAX77620_SD_CFG1_ADE_MASK BIT(3)
+#define MAX77620_SD_CFG1_ADE_DISABLE 0
+#define MAX77620_SD_CFG1_ADE_ENABLE BIT(3)
+#define MAX77620_SD_FPWM_MASK 0x04
+#define MAX77620_SD_FPWM_SHIFT 2
+#define MAX77620_SD_FSRADE_MASK 0x01
+#define MAX77620_SD_FSRADE_SHIFT 0
+#define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2)
+#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
+#define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2)
+#define MAX77620_SD_CFG1_MPOK_MASK BIT(1)
+#define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0)
+#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
+#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0)
+
+#define MAX77620_REG_SD_CFG2 0x22
+#define MAX77620_SD_CNF2_RSVD BIT(0)
+#define MAX77620_SD_CNF2_ROVS_EN_SD1 BIT(1)
+#define MAX77620_SD_CNF2_ROVS_EN_SD0 BIT(2)
+
+#define MAX77620_REG_LDO0_CFG 0x23
+#define MAX77620_REG_LDO0_CFG2 0x24
+#define MAX77620_REG_LDO1_CFG 0x25
+#define MAX77620_REG_LDO1_CFG2 0x26
+#define MAX77620_REG_LDO2_CFG 0x27
+#define MAX77620_REG_LDO2_CFG2 0x28
+#define MAX77620_REG_LDO3_CFG 0x29
+#define MAX77620_REG_LDO3_CFG2 0x2A
+#define MAX77620_REG_LDO4_CFG 0x2B
+#define MAX77620_REG_LDO4_CFG2 0x2C
+#define MAX77620_REG_LDO5_CFG 0x2D
+#define MAX77620_REG_LDO5_CFG2 0x2E
+#define MAX77620_REG_LDO6_CFG 0x2F
+#define MAX77620_REG_LDO6_CFG2 0x30
+#define MAX77620_REG_LDO7_CFG 0x31
+#define MAX77620_REG_LDO7_CFG2 0x32
+#define MAX77620_REG_LDO8_CFG 0x33
+#define MAX77620_REG_LDO8_CFG2 0x34
+/*! LDO CFG */
+#define MAX77620_LDO_POWER_MODE_SHIFT 6
+#define MAX77620_LDO_POWER_MODE_MASK (3 << MAX77620_LDO_POWER_MODE_SHIFT)
+#define MAX77620_POWER_MODE_NORMAL 3
+#define MAX77620_POWER_MODE_LPM 2
+#define MAX77620_POWER_MODE_GLPM 1
+#define MAX77620_POWER_MODE_DISABLE 0
+/*! LDO CFG2 */
+#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
+#define MAX77620_LDO_CFG2_SS_FAST (0 << 0)
+#define MAX77620_LDO_CFG2_SS_SLOW (1 << 0)
+#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
+#define MAX77620_LDO_CFG2_ADE_DISABLE (0 << 1)
+#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
+#define MAX77620_LDO_CFG2_MPOK_MASK BIT(2)
+#define MAX77620_LDO_CFG2_POK_MASK BIT(3)
+#define MAX77620_LDO_CFG2_COMP_SHIFT 4
+#define MAX77620_LDO_CFG2_COMP_MASK (3 << MAX77620_LDO_COMP_SHIFT)
+#define MAX77620_LDO_CFG2_COMP_SLOW 3
+#define MAX77620_LDO_CFG2_COMP_MID_SLOW 2
+#define MAX77620_LDO_CFG2_COMP_MID_FAST 1
+#define MAX77620_LDO_CFG2_COMP_FAST 0
+#define MAX77620_LDO_CFG2_ALPM_EN_MASK BIT(6)
+#define MAX77620_LDO_CFG2_OVCLMP_MASK BIT(7)
+
+#define MAX77620_REG_LDO_CFG3 0x35
+#define MAX77620_LDO_BIAS_EN BIT(0)
+#define MAX77620_TRACK4_SHIFT 5
+#define MAX77620_TRACK4_MASK (1 << MAX77620_TRACK4_SHIFT)
+
+#define MAX77620_REG_GPIO0 0x36
+#define MAX77620_REG_GPIO1 0x37
+#define MAX77620_REG_GPIO2 0x38
+#define MAX77620_REG_GPIO3 0x39
+#define MAX77620_REG_GPIO4 0x3A
+#define MAX77620_REG_GPIO5 0x3B
+#define MAX77620_REG_GPIO6 0x3C
+#define MAX77620_REG_GPIO7 0x3D
+#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
+#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
+#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN (0 << 0)
+#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
+#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
+#define MAX77620_CNFG_GPIO_DIR_OUTPUT (0 << 1)
+#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW (0 << 3)
+#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
+#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
+#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
+#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
+#define MAX77620_GPIO_OUTPUT_DISABLE 0
+#define MAX77620_GPIO_OUTPUT_ENABLE 1
+
+#define MAX77620_REG_PUE_GPIO 0x3E // Gpio Pullup resistor enable.
+#define MAX77620_REG_PDE_GPIO 0x3F // Gpio Pulldown resistor enable.
+
+#define MAX77620_REG_AME_GPIO \
+ 0x40 // Gpio pinmuxing. Clear bits are Standard GPIO.
+
+#define MAX77620_REG_ONOFFCNFG1 0x41
+#define MAX20024_ONOFFCNFG1_CLRSE 0x18
+#define MAX77620_ONOFFCNFG1_PWR_OFF BIT(1)
+#define MAX77620_ONOFFCNFG1_SLPEN BIT(2)
+#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
+#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
+#define MAX77620_ONOFFCNFG1_RSVD BIT(6)
+#define MAX77620_ONOFFCNFG1_SFT_RST BIT(7)
+
+#define MAX77620_REG_ONOFFCNFG2 0x42
+#define MAX77620_ONOFFCNFG2_WK_EN0 BIT(0)
+#define MAX77620_ONOFFCNFG2_WK_ALARM2 BIT(1)
+#define MAX77620_ONOFFCNFG2_WK_ALARM1 BIT(2)
+#define MAX77620_ONOFFCNFG2_WK_MBATT \
+ BIT(3) // MBATT event generates a wakeup signal. use it in android/l4t?
+#define MAX77620_ONOFFCNFG2_WK_ACOK BIT(4)
+#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK BIT(5)
+#define MAX77620_ONOFFCNFG2_WD_RST_WK BIT(6)
+#define MAX77620_ONOFFCNFG2_SFT_RST_WK BIT(7)
+
+/* FPS Registers */
+#define MAX77620_REG_FPS_CFG0 0x43 // FPS0.
+#define MAX77620_REG_FPS_CFG1 0x44 // FPS1.
+#define MAX77620_REG_FPS_CFG2 0x45 // FPS2.
+#define MAX77620_FPS_ENFPS_SW_MASK 0x01
+#define MAX77620_FPS_ENFPS_SW 0x01
+#define MAX77620_FPS_EN_SRC_SHIFT 1
+#define MAX77620_FPS_EN_SRC_MASK 0x06
+#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
+#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
+
+#define MAX77620_REG_FPS_LDO0 0x46
+#define MAX77620_REG_FPS_LDO1 0x47
+#define MAX77620_REG_FPS_LDO2 0x48
+#define MAX77620_REG_FPS_LDO3 0x49
+#define MAX77620_REG_FPS_LDO4 0x4A
+#define MAX77620_REG_FPS_LDO5 0x4B
+#define MAX77620_REG_FPS_LDO6 0x4C
+#define MAX77620_REG_FPS_LDO7 0x4D
+#define MAX77620_REG_FPS_LDO8 0x4E
+#define MAX77620_REG_FPS_SD0 0x4F
+#define MAX77620_REG_FPS_SD1 0x50
+#define MAX77620_REG_FPS_SD2 0x51
+#define MAX77620_REG_FPS_SD3 0x52
+#define MAX77620_REG_FPS_SD4 0x53
+#define MAX77620_REG_FPS_GPIO1 0x54
+#define MAX77620_REG_FPS_GPIO2 0x55
+#define MAX77620_REG_FPS_GPIO3 0x56
+#define MAX77620_REG_FPS_RSO 0x57
+#define MAX77620_FPS_PD_PERIOD_SHIFT 0
+#define MAX77620_FPS_PD_PERIOD_MASK 0x07
+#define MAX77620_FPS_PU_PERIOD_SHIFT 3
+#define MAX77620_FPS_PU_PERIOD_MASK 0x38
+#define MAX77620_FPS_SRC_SHIFT 6
+#define MAX77620_FPS_SRC_MASK 0xC0
+
+#define MAX77620_FPS_COUNT 3
+#define MAX77620_FPS_PERIOD_MIN_US 40
+#define MAX77620_FPS_PERIOD_MAX_US 2560
+
+#define MAX77620_REG_CID0 0x58
+#define MAX77620_REG_CID1 0x59
+#define MAX77620_REG_CID2 0x5A
+#define MAX77620_REG_CID3 0x5B
+#define MAX77620_REG_CID4 0x5C // OTP version.
+#define MAX77620_REG_CID5 0x5D // ES version.
+#define MAX77620_CID_DIDO_MASK 0xF
+#define MAX77620_CID_DIDO_SHIFT 0
+#define MAX77620_CID_DIDM_MASK 0xF0
+#define MAX77620_CID_DIDM_SHIFT 4
+
+/* Device Identification Metal */
+#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
+/* Device Indentification OTP */
+#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
+
+#define MAX77620_REG_DVSSD4 0x5E
+#define MAX20024_REG_MAX_ADD 0x70
+
+#define MAX77620_IRQ_LVL2_GPIO_EDGE0 BIT(0)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE1 BIT(1)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE2 BIT(2)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE3 BIT(3)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE4 BIT(4)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE5 BIT(5)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE6 BIT(6)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE7 BIT(7)
+
+/* Interrupts */
+enum {
+ MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
+ MAX77620_IRQ_TOP_SD, /* SD power fail */
+ MAX77620_IRQ_TOP_LDO, /* LDO power fail */
+ MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
+ MAX77620_IRQ_TOP_RTC, /* RTC */
+ MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
+ MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
+ MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
+ MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
+ MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
+};
+
+/* GPIOs */
+enum {
+ MAX77620_GPIO0,
+ MAX77620_GPIO1,
+ MAX77620_GPIO2,
+ MAX77620_GPIO3,
+ MAX77620_GPIO4,
+ MAX77620_GPIO5,
+ MAX77620_GPIO6,
+ MAX77620_GPIO7,
+ MAX77620_GPIO_NR,
+};
+
+/* FPS Source */
+enum max77620_fps_src {
+ MAX77620_FPS_SRC_0,
+ MAX77620_FPS_SRC_1,
+ MAX77620_FPS_SRC_2,
+ MAX77620_FPS_SRC_NONE,
+ MAX77620_FPS_SRC_DEF,
+};
+
+#define MAX77812_PHASE31_CPU_I2C_ADDR \
+ 0x31 // High power GPU. 2 Outputs: 3-phase M1 + 1-phase M4.
+#define MAX77812_PHASE211_CPU_I2C_ADDR \
+ 0x33 // Low power GPU. 3 Outputs: 2-phase M1 + 1-phase M3 + 1-phase M4.
+
+#define MAX77812_REG_RSET 0x00
+#define MAX77812_REG_INT_SRC 0x01
+#define MAX77812_REG_INT_SRC_M 0x02
+#define MAX77812_REG_TOPSYS_INT 0x03
+#define MAX77812_REG_TOPSYS_INT_M 0x04
+#define MAX77812_REG_TOPSYS_STAT 0x05
+#define MAX77812_REG_EN_CTRL 0x06
+#define MAX77812_EN_CTRL_ENABLE 1
+#define MAX77812_EN_CTRL_EN_M1_SHIFT 0
+#define MAX77812_EN_CTRL_EN_M1_MASK (1 << MAX77812_EN_CTRL_EN_M1_SHIFT)
+#define MAX77812_EN_CTRL_EN_M2_SHIFT 2
+#define MAX77812_EN_CTRL_EN_M2_MASK (1 << MAX77812_EN_CTRL_EN_M2_SHIFT)
+#define MAX77812_EN_CTRL_EN_M3_SHIFT 4
+#define MAX77812_EN_CTRL_EN_M3_MASK (1 << MAX77812_EN_CTRL_EN_M3_SHIFT)
+#define MAX77812_EN_CTRL_EN_M4_SHIFT 6
+#define MAX77812_EN_CTRL_EN_M4_MASK (1 << MAX77812_EN_CTRL_EN_M4_SHIFT)
+#define MAX77812_REG_STUP_DLY2 0x07
+#define MAX77812_REG_STUP_DLY3 0x08
+#define MAX77812_REG_STUP_DLY4 0x09
+#define MAX77812_REG_SHDN_DLY1 0x0A
+#define MAX77812_REG_SHDN_DLY2 0x0B
+#define MAX77812_REG_SHDN_DLY3 0x0C
+#define MAX77812_REG_SHDN_DLY4 0x0D
+#define MAX77812_REG_WDTRSTB_DEB 0x0E
+#define MAX77812_REG_GPI_FUNC 0x0F
+#define MAX77812_REG_GPI_DEB1 0x10
+#define MAX77812_REG_GPI_DEB2 0x11
+#define MAX77812_REG_GPI_PD_CTRL 0x12
+#define MAX77812_REG_PROT_CFG 0x13
+#define MAX77812_REG_VERSION 0x14
+#define MAX77812_REG_I2C_CFG 0x15
+#define MAX77812_REG_BUCK_INT 0x20
+#define MAX77812_REG_BUCK_INT_M 0x21
+#define MAX77812_REG_BUCK_STAT 0x22
+#define MAX77812_REG_M1_VOUT 0x23 // GPU.
+#define MAX77812_REG_M2_VOUT 0x24
+#define MAX77812_REG_M3_VOUT 0x25 // DRAM on PHASE211.
+#define MAX77812_REG_M4_VOUT 0x26 // CPU.
+#define MAX77812_REG_M1_VOUT_D 0x27
+#define MAX77812_REG_M2_VOUT_D 0x28
+#define MAX77812_REG_M3_VOUT_D 0x29
+#define MAX77812_REG_M4_VOUT_D 0x2A
+#define MAX77812_REG_M1_VOUT_S 0x2B
+#define MAX77812_REG_M2_VOUT_S 0x2C
+#define MAX77812_REG_M3_VOUT_S 0x2D
+#define MAX77812_REG_M4_VOUT_S 0x2E
+#define MAX77812_REG_M1_CFG 0x2F // HOS: M1_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_M2_CFG 0x30 // HOS: M2_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_M3_CFG 0x31 // HOS: M3_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_M4_CFG 0x32 // HOS: M4_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_GLB_CFG1 0x33 // HOS: B_SD_SR/B_SS_SR - 5mV/us.
+#define MAX77812_REG_GLB_CFG2 0x34 // HOS: B_RD_SR/B_RU_SR - 5mV/us
+#define MAX77812_REG_GLB_CFG3 0x35
+
+/*! Protected area and settings only for MAX77812_ES2_VERSION */
+#define MAX77812_REG_GLB_CFG4 0x36 // QS: 0xBB.
+#define MAX77812_REG_GLB_CFG5 0x37 // QS: 0x39. ES2: Set to 0x3E.
+#define MAX77812_REG_GLB_CFG6 0x38 // QS: 0x88. ES2: Set to 0x90.
+#define MAX77812_REG_GLB_CFG7 0x39 // QS: 0x04.
+#define MAX77812_REG_GLB_CFG8 0x3A // QS: 0x3A. ES2: Set to 0x3A.
+
+#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
+#define MAX77812_REG_UNKNOWN 0xFE
+
+#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
+#define MAX77812_START_SLEW_RATE_MASK 0x07
+#define MAX77812_SHDN_SLEW_RATE_MASK 0x70
+#define MAX77812_RAMPUP_SLEW_RATE_MASK 0x07
+#define MAX77812_RAMPDOWN_SLEW_RATE_MASK 0x70
+#define MAX77812_SLEW_RATE_SHIFT 4
+
+#define MAX77812_OP_ACTIVE_DISCHARGE_MASK BIT(7)
+#define MAX77812_PEAK_CURRENT_LMT_MASK 0x70
+#define MAX77812_SWITCH_FREQ_MASK 0x0C
+#define MAX77812_FORCED_PWM_MASK BIT(1)
+#define MAX77812_SLEW_RATE_CNTRL_MASK BIT(0)
+#define MAX77812_START_SHD_DELAY_MASK 0x1F
+#define MAX77812_VERSION_MASK 0x07
+#define MAX77812_ES2_VERSION 0x04
+#define MAX77812_QS_VERSION 0x05
+
+#define MAX77812_BUCK_VOLT_MASK 0xFF
+
+#define BQ24193_I2C_ADDR 0x6B
+
+// REG 0 masks.
+#define BQ24193_INCONFIG_INLIMIT_MASK (7 << 0)
+#define BQ24193_INCONFIG_VINDPM_MASK 0x78
+#define BQ24193_INCONFIG_HIZ_EN_MASK (1 << 7)
+
+// REG 1 masks.
+#define BQ24193_PORCONFIG_BOOST_MASK (1 << 0)
+#define BQ24193_PORCONFIG_SYSMIN_MASK (7 << 1) // 3000uV HOS default.
+#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3 << 4)
+#define BQ24193_PORCONFIG_CHGCONFIG_CHARGER_EN (1 << 4)
+#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1 << 6)
+#define BQ24193_PORCONFIG_RESET_MASK (1 << 7)
+
+// REG 2 masks.
+#define BQ24193_CHRGCURR_20PCT_MASK (1 << 0)
+#define BQ24193_CHRGCURR_ICHG_MASK 0xFC
+
+// REG 3 masks.
+#define BQ24193_PRECHRG_ITERM 0x0F
+#define BQ24193_PRECHRG_IPRECHG 0xF0
+
+// REG 4 masks.
+#define BQ24193_CHRGVOLT_VTHRES (1 << 0)
+#define BQ24193_CHRGVOLT_BATTLOW (1 << 1)
+#define BQ24193_CHRGVOLT_VREG 0xFC
+
+// REG 5 masks.
+#define BQ24193_CHRGTERM_ISET_MASK (1 << 0)
+#define BQ24193_CHRGTERM_CHGTIMER_MASK (3 << 1)
+#define BQ24193_CHRGTERM_ENTIMER_MASK (1 << 3)
+#define BQ24193_CHRGTERM_WATCHDOG_MASK (3 << 4)
+#define BQ24193_CHRGTERM_TERM_ST_MASK (1 << 6)
+#define BQ24193_CHRGTERM_TERM_EN_MASK (1 << 7)
+
+// REG 6 masks.
+#define BQ24193_IRTHERMAL_THERM_MASK (3 << 0)
+#define BQ24193_IRTHERMAL_VCLAMP_MASK (7 << 2)
+#define BQ24193_IRTHERMAL_BATTCOMP_MASK (7 << 5)
+
+// REG 7 masks.
+#define BQ24193_MISC_INT_MASK (3 << 0)
+#define BQ24193_MISC_VSET_MASK (1 << 4)
+#define BQ24193_MISC_BATFET_DI_MASK (1 << 5)
+#define BQ24193_MISC_TMR2X_EN_MASK (1 << 6)
+#define BQ24193_MISC_DPDM_EN_MASK (1 << 7)
+
+// REG 8 masks.
+#define BQ24193_STATUS_VSYS_MASK (1 << 0)
+#define BQ24193_STATUS_THERM_MASK (1 << 1)
+#define BQ24193_STATUS_PG_MASK (1 << 2)
+#define BQ24193_STATUS_DPM_MASK (1 << 3)
+#define BQ24193_STATUS_CHRG_MASK (3 << 4)
+#define BQ24193_STATUS_VBUS_MASK (3 << 6)
+
+// REG 9 masks.
+#define BQ24193_FAULT_THERM_MASK (7 << 0)
+#define BQ24193_FAULT_BATT_OVP_MASK (1 << 3)
+#define BQ24193_FAULT_CHARGE_MASK (3 << 4)
+#define BQ24193_FAULT_BOOST_MASK (1 << 6)
+#define BQ24193_FAULT_WATCHDOG_MASK (1 << 7)
+
+// REG A masks.
+#define BQ24193_VENDORPART_DEV_MASK (3 << 0)
+#define BQ24193_VENDORPART_PN_MASK (7 << 3)
+
+enum BQ24193_reg {
+ BQ24193_InputSource = 0x00,
+ BQ24193_PORConfig = 0x01,
+ BQ24193_ChrgCurr = 0x02,
+ BQ24193_PreChrgTerm = 0x03,
+ BQ24193_ChrgVolt = 0x04,
+ BQ24193_ChrgTermTimer = 0x05,
+ BQ24193_IRCompThermal = 0x06,
+ BQ24193_Misc = 0x07,
+ BQ24193_Status = 0x08,
+ BQ24193_FaultReg = 0x09,
+ BQ24193_VendorPart = 0x0A,
+};
+
+enum BQ24193_reg_prop {
+ BQ24193_InputVoltageLimit, // REG 0.
+ BQ24193_InputCurrentLimit, // REG 0.
+ BQ24193_SystemMinimumVoltage, // REG 1.
+ BQ24193_FastChargeCurrentLimit, // REG 2.
+ BQ24193_ChargeVoltageLimit, // REG 4.
+ BQ24193_RechargeThreshold, // REG 4.
+ BQ24193_ThermalRegulation, // REG 6.
+ BQ24193_ChargeStatus, // REG 8.
+ BQ24193_TempStatus, // REG 9.
+ BQ24193_DevID, // REG A.
+ BQ24193_ProductNumber, // REG A.
+};
+
+#endif /* MAX77XXX_H */