From e16b87c8432223a14b158cee9dc30c3ae0895ce9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 29 Jun 2020 04:40:59 -0700 Subject: [PATCH] exo: implement mariko fuse driver --- .../libexosphere/source/fuse/fuse_api.cpp | 86 ++++- .../source/fuse/fuse_registers.hpp | 354 ++++++++++++++++-- 2 files changed, 395 insertions(+), 45 deletions(-) diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index 7265e42d9..17e4b2564 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -20,6 +20,10 @@ namespace ams::fuse { namespace { + static constexpr SocType SocType_CommonInternal = static_cast(-1); + static_assert(SocType_CommonInternal != SocType_Erista); + static_assert(SocType_CommonInternal != SocType_Mariko); + struct BypassEntry { u32 offset; u32 value; @@ -42,6 +46,11 @@ namespace ams::fuse { using HardwareType3 = util::BitPack32::Field; }; + struct OdmWord28 { + using Regulator = util::BitPack32::Field<0, 1, int>; + using Reserved = util::BitPack32::Field<1, 31, int>; + }; + constexpr ALWAYS_INLINE int GetHardwareStateValue(const util::BitPack32 odm_word4) { constexpr auto HardwareState1Shift = 0; constexpr auto HardwareState2Shift = OdmWord4::HardwareState1::Count + HardwareState1Shift; @@ -73,8 +82,16 @@ namespace ams::fuse { return GetRegisterRegion()->fuse; } - ALWAYS_INLINE volatile FuseChipRegisters &GetChipRegisters() { - return GetRegisterRegion()->chip; + ALWAYS_INLINE volatile FuseChipRegistersCommon &GetChipRegistersCommon() { + return GetRegisterRegion()->chip_common; + } + + ALWAYS_INLINE volatile FuseChipRegistersErista &GetChipRegistersErista() { + return GetRegisterRegion()->chip_erista; + } + + ALWAYS_INLINE volatile FuseChipRegistersMariko &GetChipRegistersMariko() { + return GetRegisterRegion()->chip_mariko; } bool IsIdle() { @@ -85,6 +102,31 @@ namespace ams::fuse { while (!IsIdle()) { /* ... */ } } + u32 GetOdmWordImpl(int index, fuse::SocType soc_type) { + if (index < 8) { + volatile auto &chip = GetChipRegistersCommon(); + return chip.FUSE_RESERVED_ODM_0[index - 0]; + } else if (soc_type == SocType_Mariko) { + volatile auto &chip = GetChipRegistersMariko(); + if (index < 22) { + return chip.FUSE_RESERVED_ODM_8[index - 8]; + } else if (index < 25) { + return chip.FUSE_RESERVED_ODM_22[index - 22]; + } else if (index < 26) { + return chip.FUSE_RESERVED_ODM_25[index - 25]; + } else if (index < 29) { + return chip.FUSE_RESERVED_ODM_26[index - 26]; + } else if (index < 30) { + return chip.FUSE_RESERVED_ODM_29[index - 29]; + } + } + AMS_ABORT("Invalid ODM fuse read"); + } + + u32 GetCommonOdmWord(int index) { + return GetOdmWordImpl(index, SocType_CommonInternal); + } + bool IsNewFuseFormat() { /* On mariko, this should always be true. */ if (GetSocType() != SocType_Erista) { @@ -92,7 +134,7 @@ namespace ams::fuse { } /* Require that the format version be non-zero in odm4. */ - if (util::BitPack32{GetOdmWord(4)}.Get() == 0) { + if (util::BitPack32{GetCommonOdmWord(4)}.Get() == 0) { return false; } @@ -100,8 +142,8 @@ namespace ams::fuse { constexpr u32 NewFuseFormatMagic0 = 0x8E61ECAE; constexpr u32 NewFuseFormatMagic1 = 0xF2BA3BB2; - const u32 w0 = GetOdmWord(0); - const u32 w1 = GetOdmWord(1); + const u32 w0 = GetCommonOdmWord(0); + const u32 w1 = GetCommonOdmWord(1); return w0 == NewFuseFormatMagic0 && w1 == NewFuseFormatMagic1; } @@ -206,12 +248,12 @@ namespace ams::fuse { } u32 GetOdmWord(int index) { - return GetChipRegisters().FUSE_RESERVED_ODM[index]; + return GetOdmWordImpl(index, GetSocType()); } void GetEcid(br::BootEcid *out) { /* Get the registers. */ - volatile auto &chip = GetChipRegisters(); + volatile auto &chip = GetChipRegistersCommon(); /* Read the ecid components. */ const u32 vendor = reg::Read(chip.FUSE_OPT_VENDOR_CODE) & ((1u << 4) - 1); @@ -235,7 +277,7 @@ namespace ams::fuse { u64 GetDeviceId() { /* Get the registers. */ - volatile auto &chip = GetChipRegisters(); + volatile auto &chip = GetChipRegistersCommon(); /* Read the device id components. */ /* NOTE: Device ID is "basically" just an alternate encoding of Ecid. */ @@ -258,12 +300,12 @@ namespace ams::fuse { } DramId GetDramId() { - return static_cast(util::BitPack32{GetOdmWord(4)}.Get()); + return static_cast(util::BitPack32{GetCommonOdmWord(4)}.Get()); } HardwareType GetHardwareType() { /* Read the odm word. */ - const util::BitPack32 odm_word4 = { GetOdmWord(4) }; + const util::BitPack32 odm_word4 = { GetCommonOdmWord(4) }; /* Get the value. */ const auto value = GetHardwareTypeValue(odm_word4); @@ -280,7 +322,7 @@ namespace ams::fuse { HardwareState GetHardwareState() { /* Read the odm word. */ - const util::BitPack32 odm_word4 = { GetOdmWord(4) }; + const util::BitPack32 odm_word4 = { GetCommonOdmWord(4) }; /* Get the value. */ const auto value = GetHardwareStateValue(odm_word4); @@ -293,22 +335,28 @@ namespace ams::fuse { } PatchVersion GetPatchVersion() { - const auto patch_version = reg::Read(GetChipRegisters().FUSE_SOC_SPEEDO_1_CALIB); + const auto patch_version = reg::Read(GetChipRegistersCommon().FUSE_SOC_SPEEDO_1_CALIB); return static_cast(static_cast(GetSocType() << 12) | patch_version); } QuestState GetQuestState() { - return static_cast(util::BitPack32{GetOdmWord(4)}.Get()); + return static_cast(util::BitPack32{GetCommonOdmWord(4)}.Get()); } pmic::Regulator GetRegulator() { - /* TODO: How should mariko be handled? This reads from ODM word 28 in fuses (not present in erista...). */ - return pmic::Regulator_Erista_Max77621; + if (GetSocType() == SocType_Mariko) { + /* Read the odm word. */ + const util::BitPack32 odm_word28 = { GetOdmWordImpl(28, SocType_Mariko) }; + + return static_cast(odm_word28.Get() + 1); + } else /* if (GetSocType() == SocType_Erista) */ { + return pmic::Regulator_Erista_Max77621; + } } int GetDeviceUniqueKeyGeneration() { if (IsNewFuseFormat()) { - return util::BitPack32{GetOdmWord(2)}.Get(); + return util::BitPack32{GetCommonOdmWord(2)}.Get(); } else { return 0; } @@ -344,13 +392,13 @@ namespace ams::fuse { } /* Some patched units use XUSB in RCM. */ - if (reg::Read(GetChipRegisters().FUSE_RESERVED_SW) & 0x80) { + if (reg::Read(GetChipRegistersCommon().FUSE_RESERVED_SW) & 0x80) { g_has_rcm_bug_patch = true; break; } /* Other units have a proper ipatch instead. */ - u32 word_count = reg::Read(GetChipRegisters().FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F; + u32 word_count = reg::Read(GetChipRegistersCommon().FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F; u32 word_addr = 191; while (word_count && !g_has_rcm_bug_patch) { @@ -379,7 +427,7 @@ namespace ams::fuse { } bool IsOdmProductionMode() { - return reg::HasValue(GetChipRegisters().FUSE_SECURITY_MODE, FUSE_REG_BITS_ENUM(SECURITY_MODE_SECURITY_MODE, ENABLED)); + return reg::HasValue(GetChipRegistersCommon().FUSE_SECURITY_MODE, FUSE_REG_BITS_ENUM(SECURITY_MODE_SECURITY_MODE, ENABLED)); } void ConfigureFuseBypass() { diff --git a/libraries/libexosphere/source/fuse/fuse_registers.hpp b/libraries/libexosphere/source/fuse/fuse_registers.hpp index 3d729c9b6..19542b0b0 100644 --- a/libraries/libexosphere/source/fuse/fuse_registers.hpp +++ b/libraries/libexosphere/source/fuse/fuse_registers.hpp @@ -42,12 +42,162 @@ namespace ams::fuse { u32 FUSE_PRIVATE_KEY2_NONZERO; u32 FUSE_PRIVATE_KEY3_NONZERO; u32 FUSE_PRIVATE_KEY4_NONZERO; - u32 _0x94[0x1B]; + u32 _0x94; }; static_assert(util::is_pod::value); - static_assert(sizeof(FuseRegisters) == 0x100); + static_assert(sizeof(FuseRegisters) == 0x98); - struct FuseChipRegisters { + struct FuseChipRegistersCommon { + u32 _0x98[0x1A]; + u32 FUSE_PRODUCTION_MODE; + u32 FUSE_JTAG_SECUREID_VALID; + u32 FUSE_ODM_LOCK; + u32 FUSE_OPT_OPENGL_EN; + u32 FUSE_SKU_INFO; + u32 FUSE_CPU_SPEEDO_0_CALIB; + u32 FUSE_CPU_IDDQ_CALIB; + u32 _0x11C; + u32 _0x120; + u32 _0x124; + u32 FUSE_OPT_FT_REV; + u32 FUSE_CPU_SPEEDO_1_CALIB; + u32 FUSE_CPU_SPEEDO_2_CALIB; + u32 FUSE_SOC_SPEEDO_0_CALIB; + u32 FUSE_SOC_SPEEDO_1_CALIB; + u32 FUSE_SOC_SPEEDO_2_CALIB; + u32 FUSE_SOC_IDDQ_CALIB; + u32 _0x144; + u32 FUSE_FA; + u32 FUSE_RESERVED_PRODUCTION; + u32 FUSE_HDMI_LANE0_CALIB; + u32 FUSE_HDMI_LANE1_CALIB; + u32 FUSE_HDMI_LANE2_CALIB; + u32 FUSE_HDMI_LANE3_CALIB; + u32 FUSE_ENCRYPTION_RATE; + u32 FUSE_PUBLIC_KEY[0x8]; + u32 FUSE_TSENSOR1_CALIB; + u32 FUSE_TSENSOR2_CALIB; + u32 _0x18C; + u32 FUSE_OPT_CP_REV; + u32 FUSE_OPT_PFG; + u32 FUSE_TSENSOR0_CALIB; + u32 FUSE_FIRST_BOOTROM_PATCH_SIZE; + u32 FUSE_SECURITY_MODE; + u32 FUSE_PRIVATE_KEY[0x5]; + u32 FUSE_ARM_JTAG_DIS; + u32 FUSE_BOOT_DEVICE_INFO; + u32 FUSE_RESERVED_SW; + u32 FUSE_OPT_VP9_DISABLE; + u32 FUSE_RESERVED_ODM_0[8 - 0]; + u32 FUSE_OBS_DIS; + u32 _0x1EC; + u32 FUSE_USB_CALIB; + u32 FUSE_SKU_DIRECT_CONFIG; + u32 FUSE_KFUSE_PRIVKEY_CTRL; + u32 FUSE_PACKAGE_INFO; + u32 FUSE_OPT_VENDOR_CODE; + u32 FUSE_OPT_FAB_CODE; + u32 FUSE_OPT_LOT_CODE_0; + u32 FUSE_OPT_LOT_CODE_1; + u32 FUSE_OPT_WAFER_ID; + u32 FUSE_OPT_X_COORDINATE; + u32 FUSE_OPT_Y_COORDINATE; + u32 FUSE_OPT_SEC_DEBUG_EN; + u32 FUSE_OPT_OPS_RESERVED; + u32 _0x224; + u32 FUSE_GPU_IDDQ_CALIB; + u32 FUSE_TSENSOR3_CALIB; + u32 _0x234; + u32 _0x238; + u32 _0x23C; + u32 _0x240; + u32 _0x244; + u32 FUSE_OPT_SAMPLE_TYPE; + u32 FUSE_OPT_SUBREVISION; + u32 FUSE_OPT_SW_RESERVED_0; + u32 FUSE_OPT_SW_RESERVED_1; + u32 FUSE_TSENSOR4_CALIB; + u32 FUSE_TSENSOR5_CALIB; + u32 FUSE_TSENSOR6_CALIB; + u32 FUSE_TSENSOR7_CALIB; + u32 FUSE_OPT_PRIV_SEC_EN; + u32 _0x268; + u32 _0x26C; + u32 _0x270; + u32 _0x274; + u32 _0x278; + u32 FUSE_FUSE2TSEC_DEBUG_DISABLE; + u32 FUSE_TSENSOR_COMMON; + u32 FUSE_OPT_CP_BIN; + u32 FUSE_OPT_GPU_DISABLE; + u32 FUSE_OPT_FT_BIN; + u32 FUSE_OPT_DONE_MAP; + u32 _0x294; + u32 FUSE_APB2JTAG_DISABLE; + u32 FUSE_ODM_INFO; + u32 _0x2A0; + u32 _0x2A4; + u32 FUSE_ARM_CRYPT_DE_FEATURE; + u32 _0x2AC; + u32 _0x2B0; + u32 _0x2B4; + u32 _0x2B8; + u32 _0x2BC; + u32 FUSE_WOA_SKU_FLAG; + u32 FUSE_ECO_RESERVE_1; + u32 FUSE_GCPLEX_CONFIG_FUSE; + u32 FUSE_PRODUCTION_MONTH; + u32 FUSE_RAM_REPAIR_INDICATOR; + u32 FUSE_TSENSOR9_CALIB; + u32 _0x2D8; + u32 FUSE_VMIN_CALIBRATION; + u32 FUSE_AGING_SENSOR_CALIBRATION; + u32 FUSE_DEBUG_AUTHENTICATION; + u32 FUSE_SECURE_PROVISION_INDEX; + u32 FUSE_SECURE_PROVISION_INFO; + u32 FUSE_OPT_GPU_DISABLE_CP1; + u32 FUSE_SPARE_ENDIS; + u32 FUSE_ECO_RESERVE_0; + u32 _0x2FC; + u32 _0x300; + u32 FUSE_RESERVED_CALIB0; + u32 FUSE_RESERVED_CALIB1; + u32 FUSE_OPT_GPU_TPC0_DISABLE; + u32 FUSE_OPT_GPU_TPC0_DISABLE_CP1; + u32 FUSE_OPT_CPU_DISABLE; + u32 FUSE_OPT_CPU_DISABLE_CP1; + u32 FUSE_TSENSOR10_CALIB; + u32 FUSE_TSENSOR10_CALIB_AUX; + u32 _0x324; + u32 _0x328; + u32 _0x32C; + u32 _0x330; + u32 _0x334; + u32 FUSE_OPT_GPU_TPC0_DISABLE_CP2; + u32 FUSE_OPT_GPU_TPC1_DISABLE; + u32 FUSE_OPT_GPU_TPC1_DISABLE_CP1; + u32 FUSE_OPT_GPU_TPC1_DISABLE_CP2; + u32 FUSE_OPT_CPU_DISABLE_CP2; + u32 FUSE_OPT_GPU_DISABLE_CP2; + u32 FUSE_USB_CALIB_EXT; + u32 FUSE_RESERVED_FIELD; + u32 _0x358; + u32 _0x35C; + u32 _0x360; + u32 _0x364; + u32 _0x368; + u32 _0x36C; + u32 _0x370; + u32 _0x374; + u32 _0x378; + u32 FUSE_SPARE_REALIGNMENT_REG; + u32 FUSE_SPARE_BIT[0x20]; + }; + static_assert(util::is_pod::value); + static_assert(sizeof(FuseChipRegistersCommon) == 0x400 - 0x98); + + struct FuseChipRegistersErista { + u32 _0x98[0x1A]; u32 FUSE_PRODUCTION_MODE; u32 FUSE_JTAG_SECUREID_VALID; u32 FUSE_ODM_LOCK; @@ -87,7 +237,7 @@ namespace ams::fuse { u32 FUSE_BOOT_DEVICE_INFO; u32 FUSE_RESERVED_SW; u32 FUSE_OPT_VP9_DISABLE; - u32 FUSE_RESERVED_ODM[0x8]; + u32 FUSE_RESERVED_ODM_0[8 - 0]; u32 FUSE_OBS_DIS; u32 FUSE_NOR_INFO; u32 FUSE_USB_CALIB; @@ -121,34 +271,34 @@ namespace ams::fuse { u32 FUSE_TSENSOR7_CALIB; u32 FUSE_OPT_PRIV_SEC_EN; u32 FUSE_PKC_DISABLE; - u32 _0x16C; - u32 _0x170; - u32 _0x174; - u32 _0x178; + u32 _0x26C; + u32 _0x270; + u32 _0x274; + u32 _0x278; u32 FUSE_FUSE2TSEC_DEBUG_DISABLE; u32 FUSE_TSENSOR_COMMON; u32 FUSE_OPT_CP_BIN; u32 FUSE_OPT_GPU_DISABLE; u32 FUSE_OPT_FT_BIN; u32 FUSE_OPT_DONE_MAP; - u32 _0x194; + u32 _0x294; u32 FUSE_APB2JTAG_DISABLE; u32 FUSE_ODM_INFO; - u32 _0x1A0; - u32 _0x1A4; + u32 _0x2A0; + u32 _0x2A4; u32 FUSE_ARM_CRYPT_DE_FEATURE; - u32 _0x1AC; - u32 _0x1B0; - u32 _0x1B4; - u32 _0x1B8; - u32 _0x1BC; + u32 _0x2AC; + u32 _0x2B0; + u32 _0x2B4; + u32 _0x2B8; + u32 _0x2BC; u32 FUSE_WOA_SKU_FLAG; u32 FUSE_ECO_RESERVE_1; u32 FUSE_GCPLEX_CONFIG_FUSE; u32 FUSE_PRODUCTION_MONTH; u32 FUSE_RAM_REPAIR_INDICATOR; u32 FUSE_TSENSOR9_CALIB; - u32 _0x1D8; + u32 _0x2D8; u32 FUSE_VMIN_CALIBRATION; u32 FUSE_AGING_SENSOR_CALIBRATION; u32 FUSE_DEBUG_AUTHENTICATION; @@ -157,8 +307,8 @@ namespace ams::fuse { u32 FUSE_OPT_GPU_DISABLE_CP1; u32 FUSE_SPARE_ENDIS; u32 FUSE_ECO_RESERVE_0; - u32 _0x1FC; - u32 _0x200; + u32 _0x2FC; + u32 _0x300; u32 FUSE_RESERVED_CALIB0; u32 FUSE_RESERVED_CALIB1; u32 FUSE_OPT_GPU_TPC0_DISABLE; @@ -181,23 +331,175 @@ namespace ams::fuse { u32 FUSE_USB_CALIB_EXT; u32 FUSE_RESERVED_FIELD; u32 FUSE_OPT_ECC_EN; - u32 _0x25C; - u32 _0x260; - u32 _0x264; - u32 _0x268; + u32 _0x35C; + u32 _0x360; + u32 _0x364; + u32 _0x368; + u32 _0x36C; + u32 _0x370; + u32 _0x374; + u32 _0x378; + u32 FUSE_SPARE_REALIGNMENT_REG; + u32 FUSE_SPARE_BIT[0x20]; + }; + static_assert(util::is_pod::value); + static_assert(sizeof(FuseChipRegistersErista) == 0x400 - 0x98); + + struct FuseChipRegistersMariko { + u32 FUSE_RESERVED_ODM_8[22 - 8]; + u32 FUSE_KEK[4]; + u32 FUSE_BEK[4]; + u32 _0xF0[4]; + u32 FUSE_PRODUCTION_MODE; + u32 FUSE_JTAG_SECUREID_VALID; + u32 FUSE_ODM_LOCK; + u32 FUSE_OPT_OPENGL_EN; + u32 FUSE_SKU_INFO; + u32 FUSE_CPU_SPEEDO_0_CALIB; + u32 FUSE_CPU_IDDQ_CALIB; + u32 FUSE_RESERVED_ODM_22[25 - 22]; + u32 FUSE_OPT_FT_REV; + u32 FUSE_CPU_SPEEDO_1_CALIB; + u32 FUSE_CPU_SPEEDO_2_CALIB; + u32 FUSE_SOC_SPEEDO_0_CALIB; + u32 FUSE_SOC_SPEEDO_1_CALIB; + u32 FUSE_SOC_SPEEDO_2_CALIB; + u32 FUSE_SOC_IDDQ_CALIB; + u32 FUSE_RESERVED_ODM_25[26 - 25]; + u32 FUSE_FA; + u32 FUSE_RESERVED_PRODUCTION; + u32 FUSE_HDMI_LANE0_CALIB; + u32 FUSE_HDMI_LANE1_CALIB; + u32 FUSE_HDMI_LANE2_CALIB; + u32 FUSE_HDMI_LANE3_CALIB; + u32 FUSE_ENCRYPTION_RATE; + u32 FUSE_PUBLIC_KEY[0x8]; + u32 FUSE_TSENSOR1_CALIB; + u32 FUSE_TSENSOR2_CALIB; + u32 FUSE_OPT_SECURE_SCC_DIS; + u32 FUSE_OPT_CP_REV; + u32 FUSE_OPT_PFG; + u32 FUSE_TSENSOR0_CALIB; + u32 FUSE_FIRST_BOOTROM_PATCH_SIZE; + u32 FUSE_SECURITY_MODE; + u32 FUSE_PRIVATE_KEY[0x5]; + u32 FUSE_ARM_JTAG_DIS; + u32 FUSE_BOOT_DEVICE_INFO; + u32 FUSE_RESERVED_SW; + u32 FUSE_OPT_VP9_DISABLE; + u32 FUSE_RESERVED_ODM_0[8 - 0]; + u32 FUSE_OBS_DIS; + u32 _0x1EC; + u32 FUSE_USB_CALIB; + u32 FUSE_SKU_DIRECT_CONFIG; + u32 FUSE_KFUSE_PRIVKEY_CTRL; + u32 FUSE_PACKAGE_INFO; + u32 FUSE_OPT_VENDOR_CODE; + u32 FUSE_OPT_FAB_CODE; + u32 FUSE_OPT_LOT_CODE_0; + u32 FUSE_OPT_LOT_CODE_1; + u32 FUSE_OPT_WAFER_ID; + u32 FUSE_OPT_X_COORDINATE; + u32 FUSE_OPT_Y_COORDINATE; + u32 FUSE_OPT_SEC_DEBUG_EN; + u32 FUSE_OPT_OPS_RESERVED; + u32 _0x224; + u32 FUSE_GPU_IDDQ_CALIB; + u32 FUSE_TSENSOR3_CALIB; + u32 FUSE_CLOCK_BONDOUT0; + u32 FUSE_CLOCK_BONDOUT1; + u32 FUSE_RESERVED_ODM_26[29 - 26]; + u32 FUSE_OPT_SAMPLE_TYPE; + u32 FUSE_OPT_SUBREVISION; + u32 FUSE_OPT_SW_RESERVED_0; + u32 FUSE_OPT_SW_RESERVED_1; + u32 FUSE_TSENSOR4_CALIB; + u32 FUSE_TSENSOR5_CALIB; + u32 FUSE_TSENSOR6_CALIB; + u32 FUSE_TSENSOR7_CALIB; + u32 FUSE_OPT_PRIV_SEC_EN; + u32 FUSE_BOOT_SECURITY_INFO; u32 _0x26C; u32 _0x270; u32 _0x274; u32 _0x278; + u32 FUSE_FUSE2TSEC_DEBUG_DISABLE; + u32 FUSE_TSENSOR_COMMON; + u32 FUSE_OPT_CP_BIN; + u32 FUSE_OPT_GPU_DISABLE; + u32 FUSE_OPT_FT_BIN; + u32 FUSE_OPT_DONE_MAP; + u32 FUSE_RESERVED_ODM_29[30 - 29]; + u32 FUSE_APB2JTAG_DISABLE; + u32 FUSE_ODM_INFO; + u32 _0x2A0; + u32 _0x2A4; + u32 FUSE_ARM_CRYPT_DE_FEATURE; + u32 _0x2AC; + u32 _0x2B0; + u32 _0x2B4; + u32 _0x2B8; + u32 _0x2BC; + u32 FUSE_WOA_SKU_FLAG; + u32 FUSE_ECO_RESERVE_1; + u32 FUSE_GCPLEX_CONFIG_FUSE; + u32 FUSE_PRODUCTION_MONTH; + u32 FUSE_RAM_REPAIR_INDICATOR; + u32 FUSE_TSENSOR9_CALIB; + u32 _0x2D8; + u32 FUSE_VMIN_CALIBRATION; + u32 FUSE_AGING_SENSOR_CALIBRATION; + u32 FUSE_DEBUG_AUTHENTICATION; + u32 FUSE_SECURE_PROVISION_INDEX; + u32 FUSE_SECURE_PROVISION_INFO; + u32 FUSE_OPT_GPU_DISABLE_CP1; + u32 FUSE_SPARE_ENDIS; + u32 FUSE_ECO_RESERVE_0; + u32 _0x2FC; + u32 _0x300; + u32 FUSE_RESERVED_CALIB0; + u32 FUSE_RESERVED_CALIB1; + u32 FUSE_OPT_GPU_TPC0_DISABLE; + u32 FUSE_OPT_GPU_TPC0_DISABLE_CP1; + u32 FUSE_OPT_CPU_DISABLE; + u32 FUSE_OPT_CPU_DISABLE_CP1; + u32 FUSE_TSENSOR10_CALIB; + u32 FUSE_TSENSOR10_CALIB_AUX; + u32 _0x324; + u32 _0x328; + u32 _0x32C; + u32 _0x330; + u32 _0x334; + u32 FUSE_OPT_GPU_TPC0_DISABLE_CP2; + u32 FUSE_OPT_GPU_TPC1_DISABLE; + u32 FUSE_OPT_GPU_TPC1_DISABLE_CP1; + u32 FUSE_OPT_GPU_TPC1_DISABLE_CP2; + u32 FUSE_OPT_CPU_DISABLE_CP2; + u32 FUSE_OPT_GPU_DISABLE_CP2; + u32 FUSE_USB_CALIB_EXT; + u32 FUSE_RESERVED_FIELD; + u32 _0x358; + u32 _0x35C; + u32 _0x360; + u32 _0x364; + u32 _0x368; + u32 _0x36C; + u32 _0x370; + u32 _0x374; + u32 _0x378; u32 FUSE_SPARE_REALIGNMENT_REG; u32 FUSE_SPARE_BIT[0x20]; }; - static_assert(util::is_pod::value); - static_assert(sizeof(FuseChipRegisters) == 0x300); + static_assert(util::is_pod::value); + static_assert(sizeof(FuseChipRegistersMariko) == 0x400 - 0x98); struct FuseRegisterRegion { FuseRegisters fuse; - FuseChipRegisters chip; + union { + FuseChipRegistersCommon chip_common; + FuseChipRegistersErista chip_erista; + FuseChipRegistersMariko chip_mariko; + }; }; static_assert(util::is_pod::value); static_assert(sizeof(FuseRegisterRegion) == secmon::MemoryRegionPhysicalDeviceFuses.GetSize());