From b89f0e45ec886910d9792988cc32f2552261ae10 Mon Sep 17 00:00:00 2001 From: hexkyz Date: Tue, 31 Dec 2019 17:59:15 +0000 Subject: [PATCH] Cleanup FUSE, TSEC and SE code and add KFUSE state check during TSEC initialization (thanks @CTCaer). --- exosphere/lp0fw/src/car.c | 4 + exosphere/lp0fw/src/car.h | 3 +- exosphere/lp0fw/src/fuse.c | 22 +- exosphere/lp0fw/src/fuse.h | 253 ++++---- exosphere/lp0fw/src/misc.c | 20 +- exosphere/lp0fw/src/misc.h | 3 - exosphere/lp0fw/src/pmc.h | 72 +-- exosphere/lp0fw/src/se.c | 62 +- exosphere/lp0fw/src/se.h | 112 ++-- exosphere/lp0fw/src/secmon.c | 2 +- exosphere/src/car.c | 5 +- exosphere/src/car.h | 3 +- exosphere/src/configitem.c | 2 +- exosphere/src/fuse.c | 328 +++++----- exosphere/src/fuse.h | 275 ++++----- exosphere/src/package2.c | 12 +- exosphere/src/pmc.h | 11 +- exosphere/src/se.c | 276 ++++----- exosphere/src/se.h | 112 ++-- exosphere/src/timers.h | 60 +- fusee/fusee-mtc/src/fuse.c | 232 ++++---- fusee/fusee-mtc/src/fuse.h | 262 ++++---- fusee/fusee-mtc/src/pmc.h | 626 ++++++++++++++++++++ fusee/fusee-primary/src/fuse.c | 232 ++++---- fusee/fusee-primary/src/fuse.h | 262 ++++---- fusee/fusee-primary/src/hwinit.c | 6 +- fusee/fusee-primary/src/se.c | 166 +++--- fusee/fusee-primary/src/se.h | 112 ++-- fusee/fusee-secondary/src/fuse.c | 232 ++++---- fusee/fusee-secondary/src/fuse.h | 262 ++++---- fusee/fusee-secondary/src/nxboot_iram.c | 8 +- fusee/fusee-secondary/src/se.c | 166 +++--- fusee/fusee-secondary/src/se.h | 112 ++-- fusee/fusee-secondary/src/smmu.c | 3 +- fusee/fusee-secondary/src/tsec.c | 113 ++-- fusee/fusee-secondary/src/tsec.h | 339 ++++++++--- sept/sept-primary/src/fuse.c | 226 +++---- sept/sept-primary/src/fuse.h | 262 ++++---- sept/sept-primary/src/main.c | 71 ++- sept/sept-primary/src/se.c | 166 +++--- sept/sept-primary/src/se.h | 112 ++-- sept/sept-primary/src/timers.h | 23 + sept/sept-primary/src/tsec.h | 346 ++++++++--- sept/sept-secondary/key_derivation/src/se.c | 246 ++++---- sept/sept-secondary/key_derivation/src/se.h | 112 ++-- sept/sept-secondary/src/fuse.c | 232 ++++---- sept/sept-secondary/src/fuse.h | 262 ++++---- sept/sept-secondary/src/hwinit.c | 6 +- sept/sept-secondary/src/se.c | 238 ++++---- sept/sept-secondary/src/se.h | 112 ++-- 50 files changed, 4167 insertions(+), 3017 deletions(-) create mode 100644 fusee/fusee-mtc/src/pmc.h diff --git a/exosphere/lp0fw/src/car.c b/exosphere/lp0fw/src/car.c index 332959e6e..4335aeca7 100644 --- a/exosphere/lp0fw/src/car.c +++ b/exosphere/lp0fw/src/car.c @@ -132,3 +132,7 @@ void clkrst_reboot(CarDevice dev) { clkrst_disable(dev); clkrst_enable(dev); } + +void clkrst_enable_fuse_regs(bool enable) { + MAKE_CAR_REG(CLK_RST_CONTROLLER_MISC_CLK_ENB_0) = ((MAKE_CAR_REG(CLK_RST_CONTROLLER_MISC_CLK_ENB_0) & 0xEFFFFFFF) | ((enable & 1) << 28)); +} \ No newline at end of file diff --git a/exosphere/lp0fw/src/car.h b/exosphere/lp0fw/src/car.h index 12d66f3e9..66f2f30ed 100644 --- a/exosphere/lp0fw/src/car.h +++ b/exosphere/lp0fw/src/car.h @@ -103,7 +103,8 @@ void rst_disable(CarDevice dev); void clkrst_enable(CarDevice dev); void clkrst_disable(CarDevice dev); - void clkrst_reboot(CarDevice dev); +void clkrst_enable_fuse_regs(bool enable); + #endif diff --git a/exosphere/lp0fw/src/fuse.c b/exosphere/lp0fw/src/fuse.c index 467d545ed..2a7d94313 100644 --- a/exosphere/lp0fw/src/fuse.c +++ b/exosphere/lp0fw/src/fuse.c @@ -29,7 +29,7 @@ bool fuse_check_downgrade_status(void) { } void fuse_disable_programming(void) { - FUSE_REGS->FUSE_DIS_PGM = 1; + FUSE_REGS->FUSE_DISABLEREGPROGRAM = 1; } static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = { @@ -37,13 +37,14 @@ static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = { }; void fuse_configure_fuse_bypass(void) { - /* Enable fuses in CAR? This seems to affect fuse data visibility. */ - CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= 0x10000000; + /* Make all fuse registers visible. */ + clkrst_enable_fuse_regs(true); - /* Configure bypass/override, only if programming is allowed. */ - if (!(FUSE_REGS->FUSE_DIS_PGM & 1)) { - /* Enable write access. */ - FUSE_REGS->FUSE_WRITE_ACCESS = (FUSE_REGS->FUSE_WRITE_ACCESS & ~0x1) | 0x10000; + /* Configure bypass/override, only if programming is allowed. */ + if (!(FUSE_REGS->FUSE_DISABLEREGPROGRAM & 1)) { + /* Enable write access and flush status. */ + FUSE_REGS->FUSE_WRITE_ACCESS_SW = (FUSE_REGS->FUSE_WRITE_ACCESS_SW & ~0x1) | 0x10000; + /* Enable fuse bypass config. */ FUSE_REGS->FUSE_FUSEBYPASS = 1; @@ -53,7 +54,7 @@ void fuse_configure_fuse_bypass(void) { } /* Disable fuse write access. */ - FUSE_REGS->FUSE_WRITE_ACCESS |= 1; + FUSE_REGS->FUSE_WRITE_ACCESS_SW |= 1; /* Enable fuse bypass config. */ /* I think this is a bug, and Nintendo meant to write 0 here? */ @@ -63,7 +64,7 @@ void fuse_configure_fuse_bypass(void) { /* I have no idea why this happens. What? */ /* This is probably also either a bug or does nothing. */ /* Is this bit even clearable? */ - FUSE_REGS->FUSE_DIS_PGM &= 0xFFFFFFFE; + FUSE_REGS->FUSE_DISABLEREGPROGRAM &= 0xFFFFFFFE; /* Restore saved private key disable bit. */ FUSE_REGS->FUSE_PRIVATEKEYDISABLE |= (APBDEV_PMC_SECURE_SCRATCH21_0 & 0x10); @@ -71,5 +72,4 @@ void fuse_configure_fuse_bypass(void) { /* Lock private key disable secure scratch. */ APBDEV_PMC_SEC_DISABLE2_0 |= 0x4000000; } - -} +} \ No newline at end of file diff --git a/exosphere/lp0fw/src/fuse.h b/exosphere/lp0fw/src/fuse.h index b63751457..618e17f08 100644 --- a/exosphere/lp0fw/src/fuse.h +++ b/exosphere/lp0fw/src/fuse.h @@ -23,154 +23,167 @@ #include "utils.h" typedef struct { - uint32_t FUSE_CTRL; - uint32_t FUSE_REG_ADDR; - uint32_t FUSE_REG_READ; - uint32_t FUSE_REG_WRITE; - uint32_t FUSE_TIME_RD1; - uint32_t FUSE_TIME_RD2; - uint32_t FUSE_TIME_PGM1; - uint32_t FUSE_TIME_PGM2; - uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSECTRL; + uint32_t FUSE_FUSEADDR; + uint32_t FUSE_FUSERDATA; + uint32_t FUSE_FUSEWDATA; + uint32_t FUSE_FUSETIME_RD1; + uint32_t FUSE_FUSETIME_RD2; + uint32_t FUSE_FUSETIME_PGM1; + uint32_t FUSE_FUSETIME_PGM2; + uint32_t FUSE_PRIV2INTFC_START; uint32_t FUSE_FUSEBYPASS; uint32_t FUSE_PRIVATEKEYDISABLE; - uint32_t FUSE_DIS_PGM; - uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_DISABLEREGPROGRAM; + uint32_t FUSE_WRITE_ACCESS_SW; uint32_t FUSE_PWR_GOOD_SW; - uint32_t _0x38[0x32]; -} fuse_registers_t; + uint32_t _0x38; + uint32_t FUSE_PRIV2RESHIFT; + uint32_t _0x40[0x3]; + uint32_t FUSE_FUSETIME_RD3; + uint32_t _0x50[0xC]; + uint32_t FUSE_PRIVATE_KEY0_NONZERO; + uint32_t FUSE_PRIVATE_KEY1_NONZERO; + uint32_t FUSE_PRIVATE_KEY2_NONZERO; + uint32_t FUSE_PRIVATE_KEY3_NONZERO; + uint32_t FUSE_PRIVATE_KEY4_NONZERO; + uint32_t _0x90[0x1C]; +} tegra_fuse_t; typedef struct { uint32_t FUSE_PRODUCTION_MODE; - uint32_t _0x4; - uint32_t _0x8; - uint32_t _0xC; + uint32_t FUSE_JTAG_SECUREID_VALID; + uint32_t FUSE_ODM_LOCK; + uint32_t FUSE_OPT_OPENGL_EN; uint32_t FUSE_SKU_INFO; - uint32_t FUSE_CPU_SPEEDO_0; - uint32_t FUSE_CPU_IDDQ; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t _0x24; - uint32_t FUSE_FT_REV; - uint32_t FUSE_CPU_SPEEDO_1; - uint32_t FUSE_CPU_SPEEDO_2; - uint32_t FUSE_SOC_SPEEDO_0; - uint32_t FUSE_SOC_SPEEDO_1; - uint32_t FUSE_SOC_SPEEDO_2; - uint32_t FUSE_SOC_IDDQ; - uint32_t _0x44; + uint32_t FUSE_CPU_SPEEDO_0_CALIB; + uint32_t FUSE_CPU_IDDQ_CALIB; + uint32_t FUSE_DAC_CRT_CALIB; + uint32_t FUSE_DAC_HDTV_CALIB; + uint32_t FUSE_DAC_SDTV_CALIB; + uint32_t FUSE_OPT_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1_CALIB; + uint32_t FUSE_CPU_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_SPEEDO_0_CALIB; + uint32_t FUSE_SOC_SPEEDO_1_CALIB; + uint32_t FUSE_SOC_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_IDDQ_CALIB; + uint32_t FUSE_RESERVED_PRODUCTION_WP; uint32_t FUSE_FA; - uint32_t _0x4C; - uint32_t _0x50; - uint32_t _0x54; - uint32_t _0x58; - uint32_t _0x5C; - uint32_t _0x60; + uint32_t FUSE_RESERVED_PRODUCTION; + uint32_t FUSE_HDMI_LANE0_CALIB; + uint32_t FUSE_HDMI_LANE1_CALIB; + uint32_t FUSE_HDMI_LANE2_CALIB; + uint32_t FUSE_HDMI_LANE3_CALIB; + uint32_t FUSE_ENCRYPTION_RATE; uint32_t FUSE_PUBLIC_KEY[0x8]; - uint32_t FUSE_TSENSOR_1; - uint32_t FUSE_TSENSOR_2; - uint32_t _0x8C; - uint32_t FUSE_CP_REV; - uint32_t _0x94; - uint32_t FUSE_TSENSOR_0; - uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_TSENSOR1_CALIB; + uint32_t FUSE_TSENSOR2_CALIB; + uint32_t FUSE_VSENSOR_CALIB; + uint32_t FUSE_OPT_CP_REV; + uint32_t FUSE_OPT_PFG; + uint32_t FUSE_TSENSOR0_CALIB; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; - uint32_t FUSE_PRIVATE_KEY[0x4]; - uint32_t FUSE_DEVICE_KEY; - uint32_t _0xB8; - uint32_t _0xBC; + uint32_t FUSE_PRIVATE_KEY[0x5]; + uint32_t FUSE_ARM_JTAG_DIS; + uint32_t FUSE_BOOT_DEVICE_INFO; uint32_t FUSE_RESERVED_SW; - uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_OPT_VP9_DISABLE; uint32_t FUSE_RESERVED_ODM[0x8]; - uint32_t _0xE8; - uint32_t _0xEC; - uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_OBS_DIS; + uint32_t FUSE_NOR_INFO; + uint32_t FUSE_USB_CALIB; uint32_t FUSE_SKU_DIRECT_CONFIG; - uint32_t _0xF8; - uint32_t _0xFC; - uint32_t FUSE_VENDOR_CODE; - uint32_t FUSE_FAB_CODE; - uint32_t FUSE_LOT_CODE_0; - uint32_t FUSE_LOT_CODE_1; - uint32_t FUSE_WAFER_ID; - uint32_t FUSE_X_COORDINATE; - uint32_t FUSE_Y_COORDINATE; - uint32_t _0x11C; - uint32_t _0x120; + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; + uint32_t FUSE_PACKAGE_INFO; + uint32_t FUSE_OPT_VENDOR_CODE; + uint32_t FUSE_OPT_FAB_CODE; + uint32_t FUSE_OPT_LOT_CODE_0; + uint32_t FUSE_OPT_LOT_CODE_1; + uint32_t FUSE_OPT_WAFER_ID; + uint32_t FUSE_OPT_X_COORDINATE; + uint32_t FUSE_OPT_Y_COORDINATE; + uint32_t FUSE_OPT_SEC_DEBUG_EN; + uint32_t FUSE_OPT_OPS_RESERVED; uint32_t FUSE_SATA_CALIB; - uint32_t FUSE_GPU_IDDQ; - uint32_t FUSE_TSENSOR_3; - uint32_t _0x130; - uint32_t _0x134; - uint32_t _0x138; - uint32_t _0x13C; - uint32_t _0x140; - uint32_t _0x144; + uint32_t FUSE_GPU_IDDQ_CALIB; + uint32_t FUSE_TSENSOR3_CALIB; + uint32_t FUSE_SKU_BOND_OUT_L; + uint32_t FUSE_SKU_BOND_OUT_H; + uint32_t FUSE_SKU_BOND_OUT_U; + uint32_t FUSE_SKU_BOND_OUT_V; + uint32_t FUSE_SKU_BOND_OUT_W; + uint32_t FUSE_OPT_SAMPLE_TYPE; uint32_t FUSE_OPT_SUBREVISION; - uint32_t _0x14C; - uint32_t _0x150; - uint32_t FUSE_TSENSOR_4; - uint32_t FUSE_TSENSOR_5; - uint32_t FUSE_TSENSOR_6; - uint32_t FUSE_TSENSOR_7; - uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_OPT_SW_RESERVED_0; + uint32_t FUSE_OPT_SW_RESERVED_1; + uint32_t FUSE_TSENSOR4_CALIB; + uint32_t FUSE_TSENSOR5_CALIB; + uint32_t FUSE_TSENSOR6_CALIB; + uint32_t FUSE_TSENSOR7_CALIB; + uint32_t FUSE_OPT_PRIV_SEC_EN; uint32_t FUSE_PKC_DISABLE; uint32_t _0x16C; uint32_t _0x170; uint32_t _0x174; uint32_t _0x178; - uint32_t _0x17C; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; uint32_t FUSE_TSENSOR_COMMON; - uint32_t _0x184; - uint32_t _0x188; - uint32_t _0x18C; - uint32_t _0x190; + uint32_t FUSE_OPT_CP_BIN; + uint32_t FUSE_OPT_GPU_DISABLE; + uint32_t FUSE_OPT_FT_BIN; + uint32_t FUSE_OPT_DONE_MAP; uint32_t _0x194; - uint32_t _0x198; - uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t FUSE_APB2JTAG_DISABLE; + uint32_t FUSE_ODM_INFO; uint32_t _0x1A0; uint32_t _0x1A4; - uint32_t _0x1A8; + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; uint32_t _0x1AC; uint32_t _0x1B0; uint32_t _0x1B4; uint32_t _0x1B8; uint32_t _0x1BC; - uint32_t _0x1D0; - uint32_t FUSE_TSENSOR_8; + uint32_t FUSE_WOA_SKU_FLAG; + uint32_t FUSE_ECO_RESERVE_1; + uint32_t FUSE_GCPLEX_CONFIG_FUSE; + uint32_t FUSE_PRODUCTION_MONTH; + uint32_t FUSE_RAM_REPAIR_INDICATOR; + uint32_t FUSE_TSENSOR9_CALIB; uint32_t _0x1D8; - uint32_t _0x1DC; - uint32_t _0x1E0; - uint32_t _0x1E4; - uint32_t _0x1E8; - uint32_t _0x1EC; - uint32_t _0x1F0; - uint32_t _0x1F4; - uint32_t _0x1F8; + uint32_t FUSE_VMIN_CALIBRATION; + uint32_t FUSE_AGING_SENSOR_CALIBRATION; + uint32_t FUSE_DEBUG_AUTHENTICATION; + uint32_t FUSE_SECURE_PROVISION_INDEX; + uint32_t FUSE_SECURE_PROVISION_INFO; + uint32_t FUSE_OPT_GPU_DISABLE_CP1; + uint32_t FUSE_SPARE_ENDIS; + uint32_t FUSE_ECO_RESERVE_0; uint32_t _0x1FC; uint32_t _0x200; - uint32_t FUSE_RESERVED_CALIB; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t _0x214; - uint32_t _0x218; - uint32_t FUSE_TSENSOR_9; - uint32_t _0x220; - uint32_t _0x224; - uint32_t _0x228; - uint32_t _0x22C; - uint32_t _0x230; - uint32_t _0x234; - uint32_t _0x238; - uint32_t _0x23C; - uint32_t _0x240; - uint32_t _0x244; - uint32_t _0x248; - uint32_t _0x24C; + uint32_t FUSE_RESERVED_CALIB0; + uint32_t FUSE_RESERVED_CALIB1; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1; + uint32_t FUSE_OPT_CPU_DISABLE; + uint32_t FUSE_OPT_CPU_DISABLE_CP1; + uint32_t FUSE_TSENSOR10_CALIB; + uint32_t FUSE_TSENSOR10_CALIB_AUX; + uint32_t FUSE_OPT_RAM_SVOP_DP; + uint32_t FUSE_OPT_RAM_SVOP_PDP; + uint32_t FUSE_OPT_RAM_SVOP_REG; + uint32_t FUSE_OPT_RAM_SVOP_SP; + uint32_t FUSE_OPT_RAM_SVOP_SMPDP; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2; + uint32_t FUSE_OPT_CPU_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_DISABLE_CP2; uint32_t FUSE_USB_CALIB_EXT; - uint32_t _0x254; - uint32_t _0x258; + uint32_t FUSE_RESERVED_FIELD; + uint32_t FUSE_OPT_ECC_EN; uint32_t _0x25C; uint32_t _0x260; uint32_t _0x264; @@ -179,12 +192,12 @@ typedef struct { uint32_t _0x270; uint32_t _0x274; uint32_t _0x278; - uint32_t _0x27C; + uint32_t FUSE_SPARE_REALIGNMENT_REG; uint32_t FUSE_SPARE_BIT[0x20]; -} fuse_chip_registers_t; +} tegra_fuse_chip_t; -#define FUSE_REGS ((volatile fuse_registers_t *)(0x7000F800)) -#define FUSE_CHIP_REGS ((volatile fuse_chip_registers_t *)(0x7000F900)) +#define FUSE_REGS ((volatile tegra_fuse_t *)(0x7000F800)) +#define FUSE_CHIP_REGS ((volatile tegra_fuse_chip_t *)(0x7000F900)) #define MAKE_FUSE_REG(n) MAKE_REG32(0x7000F800 + n) @@ -194,9 +207,7 @@ typedef struct { } fuse_bypass_data_t; bool fuse_check_downgrade_status(void); - void fuse_configure_fuse_bypass(void); - void fuse_disable_programming(void); #endif diff --git a/exosphere/lp0fw/src/misc.c b/exosphere/lp0fw/src/misc.c index 14db3b67d..33355b621 100644 --- a/exosphere/lp0fw/src/misc.c +++ b/exosphere/lp0fw/src/misc.c @@ -23,26 +23,26 @@ #include "pmc.h" void misc_configure_device_dbg_settings(void) { - /* Enable RTCK daisychaining by setting TBE bit. */ + /* Set APB_MISC_PP_CONFIG_CTL_TBE (enables RTCK daisy-chaining). */ APB_MISC_PP_CONFIG_CTL_0 = 0x80; - /* Literally none of this is documented in the TRM, lol. */ + /* Configure JTAG and debug bits. */ if (FUSE_CHIP_REGS->FUSE_SECURITY_MODE == 1) { - uint32_t secure_boot_val = 0b0100; /* Sets NIDEN for aarch64. */ - uint32_t misc_val = 0x40; + uint32_t secure_boot_val = 0b0100; /* Set NIDEN for aarch64. */ + uint32_t pp_config_ctl_val = 0x40; /* Set APB_MISC_PP_CONFIG_CTL_JTAG. */ if (APBDEV_PMC_STICKY_BITS_0 & 0x40) { - misc_val = 0x0; + pp_config_ctl_val = 0x0; } else { - secure_boot_val = 0b1101; /* Sets SPNIDEN, NIDEN, DBGEN for aarch64. */ + secure_boot_val = 0b1101; /* Set SPNIDEN, NIDEN, DBGEN for aarch64. */ } - SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configures debug bits. */ - APB_MISC_PP_CONFIG_CTL_0 |= misc_val; /* Undocumented, seems to control invasive debugging/JTAG. */ + SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configure debug bits. */ + APB_MISC_PP_CONFIG_CTL_0 |= pp_config_ctl_val; /* Configure JTAG. */ } - /* Set sticky bits based SECURITY_MODE. */ + /* Set HDA_LPBK_DIS if FUSE_SECURITY_MODE is set (disables HDA codec loopback). */ APBDEV_PMC_STICKY_BITS_0 |= FUSE_CHIP_REGS->FUSE_SECURITY_MODE; - /* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 */ + /* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 (needed by the XUSB and SATA controllers). */ PINMUX_AUX_GPIO_PA6_0 |= 0x40; } diff --git a/exosphere/lp0fw/src/misc.h b/exosphere/lp0fw/src/misc.h index 44fc03d04..5468e9c73 100644 --- a/exosphere/lp0fw/src/misc.h +++ b/exosphere/lp0fw/src/misc.h @@ -26,17 +26,14 @@ #define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n) #define APB_MISC_PP_CONFIG_CTL_0 MAKE_MISC_REG(0x024) - #define APB_MISC_GP_ASDBGREG_0 MAKE_MISC_REG(0x810) #define PINMUX_AUX_PWR_I2C_SCL_0 MAKE_MISC_REG(0x30DC) #define PINMUX_AUX_PWR_I2C_SDA_0 MAKE_MISC_REG(0x30E0) #define PINMUX_AUX_DVFS_PWM_0 MAKE_MISC_REG(0x3184) - #define PINMUX_AUX_GPIO_PA6_0 MAKE_MISC_REG(0x3244) void misc_configure_device_dbg_settings(void); - void misc_restore_ram_svop(void); #endif diff --git a/exosphere/lp0fw/src/pmc.h b/exosphere/lp0fw/src/pmc.h index e43055768..9fda5590a 100644 --- a/exosphere/lp0fw/src/pmc.h +++ b/exosphere/lp0fw/src/pmc.h @@ -23,47 +23,35 @@ #define MAKE_PMC_REG(ofs) (MAKE_REG32(PMC_BASE + ofs)) -#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000) - -#define APBDEV_PMC_DPD_SAMPLE_0 MAKE_PMC_REG(0x020) - -#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x024) - -#define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C) - -#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030) -#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034) -#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038) - -#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080) -#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084) -#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098) -#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818) - -#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4) - -#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0) -#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4) -#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8) - -#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334) -#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360) -#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368) -#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C) - -#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18) -#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C) -#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_PMC_REG(0xB20) -#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_PMC_REG(0xB24) - -#define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C) -#define APBDEV_PMC_IO_DPD3_STATUS_0 MAKE_PMC_REG(0x460) - -#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464) -#define APBDEV_PMC_IO_DPD4_STATUS_0 MAKE_PMC_REG(0x468) - -#define APBDEV_PMC_SET_SW_CLAMP_0 MAKE_PMC_REG(0x47C) - -#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4) +#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000) +#define APBDEV_PMC_DPD_SAMPLE_0 MAKE_PMC_REG(0x020) +#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x024) +#define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C) +#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030) +#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034) +#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038) +#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080) +#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084) +#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098) +#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818) +#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4) +#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0) +#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4) +#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8) +#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334) +#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360) +#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368) +#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C) +#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18) +#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C) +#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_PMC_REG(0xB20) +#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_PMC_REG(0xB24) +#define APBDEV_PMC_FUSE_CTRL MAKE_PMC_REG(0x450) +#define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C) +#define APBDEV_PMC_IO_DPD3_STATUS_0 MAKE_PMC_REG(0x460) +#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464) +#define APBDEV_PMC_IO_DPD4_STATUS_0 MAKE_PMC_REG(0x468) +#define APBDEV_PMC_SET_SW_CLAMP_0 MAKE_PMC_REG(0x47C) +#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4) #endif diff --git a/exosphere/lp0fw/src/se.c b/exosphere/lp0fw/src/se.c index b787f8c52..48ad8293c 100644 --- a/exosphere/lp0fw/src/se.c +++ b/exosphere/lp0fw/src/se.c @@ -36,20 +36,20 @@ static void __attribute__((__noinline__)) ll_init(volatile se_ll_t *ll, void *bu } void se_check_error_status_reg(void) { - if (se_get_regs()->ERR_STATUS_REG) { + if (se_get_regs()->SE_ERR_STATUS) { reboot(); } } void se_check_for_error(void) { volatile tegra_se_t *se = se_get_regs(); - if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) { + if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) { reboot(); } } void se_verify_flags_cleared(void) { - if (se_get_regs()->FLAGS_REG & 3) { + if (se_get_regs()->SE_STATUS & 3) { reboot(); } } @@ -63,8 +63,8 @@ void clear_aes_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -78,13 +78,13 @@ void clear_rsa_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + se->SE_RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = 0; } } @@ -96,8 +96,8 @@ void clear_aes_keyslot_iv(unsigned int keyslot) { } for (size_t i = 0; i < (0x10 >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -111,15 +111,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v ll_init(&out_ll, dst, dst_size); /* Set the LLs. */ - se->IN_LL_ADDR_REG = (uint32_t)(&in_ll); - se->OUT_LL_ADDR_REG = (uint32_t) (&out_ll); + se->SE_IN_LL_ADDR = (uint32_t)(&in_ll); + se->SE_OUT_LL_ADDR = (uint32_t) (&out_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = op; + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = op; - while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -137,7 +137,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } /* Trigger AES operation. */ - se_get_regs()->BLOCK_COUNT_REG = 0; + se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -154,8 +154,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - se->CRYPTO_REG = keyslot << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -166,8 +166,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, reboot(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot << 24; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -198,16 +198,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - se->CRYPTO_REG = (keyslot << 24) | (0x145); + se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - se->BLOCK_COUNT_REG = num_blocks - 2; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2; trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); - se->CRYPTO_REG |= 0x80; + se->SE_CRYPTO_CONFIG |= 0x80; } /* Create final block. */ @@ -224,12 +224,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con } /* Perform last operation. */ - se->BLOCK_COUNT_REG = 0; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->HASH_RESULT_REG)[i]; + ((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->SE_HASH_RESULT)[i]; } } @@ -244,9 +244,9 @@ void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, co reboot(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x66; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x66; clear_aes_keyslot_iv(keyslot); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } \ No newline at end of file diff --git a/exosphere/lp0fw/src/se.h b/exosphere/lp0fw/src/se.h index 6ffdbc6f1..59601e39e 100644 --- a/exosphere/lp0fw/src/se.h +++ b/exosphere/lp0fw/src/se.h @@ -92,71 +92,59 @@ #define RSA_2048_BYTES 0x100 typedef struct { - uint32_t _0x0; - uint32_t _0x4; - uint32_t OPERATION_REG; - uint32_t INT_ENABLE_REG; - uint32_t INT_STATUS_REG; - uint32_t CONFIG_REG; - uint32_t IN_LL_ADDR_REG; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t OUT_LL_ADDR_REG; - uint32_t _0x28; - uint32_t _0x2C; - uint8_t HASH_RESULT_REG[0x20]; - uint8_t _0x50[0x20]; - uint32_t CONTEXT_SAVE_CONFIG_REG; - uint8_t _0x74[0x18C]; - uint32_t SHA_CONFIG_REG; - uint32_t SHA_MSG_LENGTH_REG; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t SHA_MSG_LEFT_REG; - uint32_t _0x218; - uint32_t _0x21C; - uint32_t _0x220; - uint32_t _0x224; - uint8_t _0x228[0x58]; - uint32_t AES_KEY_READ_DISABLE_REG; - uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C4[0x3C]; - uint32_t _0x300; - uint32_t CRYPTO_REG; - uint32_t CRYPTO_CTR_REG[4]; - uint32_t BLOCK_COUNT_REG; - uint32_t AES_KEYTABLE_ADDR; - uint32_t AES_KEYTABLE_DATA; - uint32_t _0x324; - uint32_t _0x328; - uint32_t _0x32C; - uint32_t CRYPTO_KEYTABLE_DST_REG; - uint8_t _0x334[0xC]; - uint32_t RNG_CONFIG_REG; - uint32_t RNG_SRC_CONFIG_REG; - uint32_t RNG_RESEED_INTERVAL_REG; - uint8_t _0x34C[0xB4]; - uint32_t RSA_CONFIG; - uint32_t RSA_KEY_SIZE_REG; - uint32_t RSA_EXP_SIZE_REG; - uint32_t RSA_KEY_READ_DISABLE_REG; - uint32_t RSA_KEYSLOT_FLAGS[2]; - uint32_t _0x418; - uint32_t _0x41C; - uint32_t RSA_KEYTABLE_ADDR; - uint32_t RSA_KEYTABLE_DATA; - uint8_t RSA_OUTPUT[0x100]; - uint8_t _0x528[0x2D8]; - uint32_t FLAGS_REG; - uint32_t ERR_STATUS_REG; - uint32_t _0x808; - uint32_t SPARE_0; - uint32_t _0x810; + uint32_t SE_SE_SECURITY; + uint32_t SE_TZRAM_SECURITY; + uint32_t SE_OPERATION; + uint32_t SE_INT_ENABLE; + uint32_t SE_INT_STATUS; + uint32_t SE_CONFIG; + uint32_t SE_IN_LL_ADDR; + uint32_t SE_IN_CUR_BYTE_ADDR; + uint32_t SE_IN_CUR_LL_ID; + uint32_t SE_OUT_LL_ADDR; + uint32_t SE_OUT_CUR_BYTE_ADDR; + uint32_t SE_OUT_CUR_LL_ID; + uint32_t SE_HASH_RESULT[0x10]; + uint32_t SE_CTX_SAVE_CONFIG; + uint32_t _0x74[0x63]; + uint32_t SE_SHA_CONFIG; + uint32_t SE_SHA_MSG_LENGTH[0x4]; + uint32_t SE_SHA_MSG_LEFT[0x4]; + uint32_t _0x224[0x17]; + uint32_t SE_CRYPTO_SECURITY_PERKEY; + uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10]; + uint32_t _0x2C4[0x10]; + uint32_t SE_CRYPTO_CONFIG; + uint32_t SE_CRYPTO_LINEAR_CTR[0x4]; + uint32_t SE_CRYPTO_LAST_BLOCK; + uint32_t SE_CRYPTO_KEYTABLE_ADDR; + uint32_t SE_CRYPTO_KEYTABLE_DATA; + uint32_t _0x324[0x3]; + uint32_t SE_CRYPTO_KEYTABLE_DST; + uint32_t _0x334[0x3]; + uint32_t SE_RNG_CONFIG; + uint32_t SE_RNG_SRC_CONFIG; + uint32_t SE_RNG_RESEED_INTERVAL; + uint32_t _0x34C[0x2D]; + uint32_t SE_RSA_CONFIG; + uint32_t SE_RSA_KEY_SIZE; + uint32_t SE_RSA_EXP_SIZE; + uint32_t SE_RSA_SECURITY_PERKEY; + uint32_t SE_RSA_KEYTABLE_ACCESS[0x2]; + uint32_t _0x418[0x2]; + uint32_t SE_RSA_KEYTABLE_ADDR; + uint32_t SE_RSA_KEYTABLE_DATA; + uint32_t SE_RSA_OUTPUT[0x40]; + uint32_t _0x528[0xB6]; + uint32_t SE_STATUS; + uint32_t SE_ERR_STATUS; + uint32_t SE_MISC; + uint32_t SE_SPARE; + uint32_t SE_ENTROPY_DEBUG_COUNTER; uint32_t _0x814; uint32_t _0x818; uint32_t _0x81C; - uint8_t _0x820[0x17E0]; + uint32_t _0x820[0x5F8]; } tegra_se_t; typedef struct { diff --git a/exosphere/lp0fw/src/secmon.c b/exosphere/lp0fw/src/secmon.c index 9fb5101a0..b1d4ec4bf 100644 --- a/exosphere/lp0fw/src/secmon.c +++ b/exosphere/lp0fw/src/secmon.c @@ -46,7 +46,7 @@ void secmon_restore_to_tzram(const uint32_t target_firmware) { } /* Make security engine require secure busmaster. */ - se_get_regs()->_0x4 = 0; + se_get_regs()->SE_TZRAM_SECURITY = 0; /* TODO: se_verify_keys_unreadable(); */ diff --git a/exosphere/src/car.c b/exosphere/src/car.c index 5f1c5f089..e2be219cc 100644 --- a/exosphere/src/car.c +++ b/exosphere/src/car.c @@ -67,7 +67,6 @@ void rst_disable(CarDevice dev) { MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F)); } - void clkrst_enable(CarDevice dev) { clk_enable(dev); rst_disable(dev); @@ -82,3 +81,7 @@ void clkrst_reboot(CarDevice dev) { clkrst_disable(dev); clkrst_enable(dev); } + +void clkrst_enable_fuse_regs(bool enable) { + MAKE_CAR_REG(CLK_RST_CONTROLLER_MISC_CLK_ENB_0) = ((MAKE_CAR_REG(CLK_RST_CONTROLLER_MISC_CLK_ENB_0) & 0xEFFFFFFF) | ((enable & 1) << 28)); +} \ No newline at end of file diff --git a/exosphere/src/car.h b/exosphere/src/car.h index 80fac5bc0..b37a9cd5a 100644 --- a/exosphere/src/car.h +++ b/exosphere/src/car.h @@ -51,7 +51,8 @@ void rst_disable(CarDevice dev); void clkrst_enable(CarDevice dev); void clkrst_disable(CarDevice dev); - void clkrst_reboot(CarDevice dev); +void clkrst_enable_fuse_regs(bool enable); + #endif diff --git a/exosphere/src/configitem.c b/exosphere/src/configitem.c index 7cdf3ff13..de33c4e98 100644 --- a/exosphere/src/configitem.c +++ b/exosphere/src/configitem.c @@ -191,7 +191,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) *p_outvalue = PACKAGE2_MAXVER_400_410 - 1; break; case CONFIGITEM_HARDWARETYPE: - *p_outvalue = fuse_get_hardware_type(); + *p_outvalue = fuse_get_hardware_type(mkey_get_revision()); break; case CONFIGITEM_ISRETAIL: *p_outvalue = fuse_get_retail_type(); diff --git a/exosphere/src/fuse.c b/exosphere/src/fuse.c index 415b2042a..3fe86e24e 100644 --- a/exosphere/src/fuse.c +++ b/exosphere/src/fuse.c @@ -18,225 +18,207 @@ #include "car.h" #include "fuse.h" -#include "utils.h" -#include "timers.h" -#include "exocfg.h" - #include "masterkey.h" +#include "pmc.h" +#include "timers.h" static bool g_has_checked_for_rcm_bug_patch = false; static bool g_has_rcm_bug_patch = false; /* Prototypes for internal commands. */ -void fuse_make_regs_visible(void); - void fuse_enable_power(void); void fuse_disable_power(void); void fuse_wait_idle(void); -/* Initialize the FUSE driver */ -void fuse_init(void) -{ - fuse_make_regs_visible(); - fuse_secondary_private_key_disable(); +/* Initialize the fuse driver */ +void fuse_init(void) { + /* Make all fuse registers visible, disable the private key and disable programming. */ + clkrst_enable_fuse_regs(true); + fuse_disable_private_key(); fuse_disable_programming(); /* TODO: Should we allow this to be done later? */ if (!g_has_checked_for_rcm_bug_patch) { (void)(fuse_has_rcm_bug_patch()); } - - /* TODO: Overrides (iROM patches) and various reads happen here */ } -/* Make all fuse registers visible */ -void fuse_make_regs_visible(void) -{ - CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= BIT(28); -} - -/* Enable power to the fuse hardware array */ -void fuse_enable_power(void) -{ - FUSE_REGS->FUSE_PWR_GOOD_SW = 1; - wait(1); -} - -/* Disable power to the fuse hardware array */ -void fuse_disable_power(void) -{ - FUSE_REGS->FUSE_PWR_GOOD_SW = 0; - wait(1); -} - -/* Wait for the fuse driver to go idle */ -void fuse_wait_idle(void) -{ - uint32_t ctrl_val = 0; - - /* Wait for STATE_IDLE */ - while ((ctrl_val & (0xF0000)) != 0x40000) - { - wait(1); - ctrl_val = FUSE_REGS->FUSE_CTRL; - } -} - -/* Read a fuse from the hardware array */ -uint32_t fuse_hw_read(uint32_t addr) -{ - fuse_wait_idle(); - - /* Program the target address */ - FUSE_REGS->FUSE_REG_ADDR = addr; - - /* Enable read operation in control register */ - uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL; - ctrl_val &= ~0x3; - ctrl_val |= 0x1; /* Set FUSE_READ command */ - FUSE_REGS->FUSE_CTRL = ctrl_val; - - fuse_wait_idle(); - - return FUSE_REGS->FUSE_REG_READ; -} - -/* Write a fuse in the hardware array */ -void fuse_hw_write(uint32_t value, uint32_t addr) -{ - fuse_wait_idle(); - - /* Program the target address and value */ - FUSE_REGS->FUSE_REG_ADDR = addr; - FUSE_REGS->FUSE_REG_WRITE = value; - - /* Enable write operation in control register */ - uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL; - ctrl_val &= ~0x3; - ctrl_val |= 0x2; /* Set FUSE_WRITE command */ - FUSE_REGS->FUSE_CTRL = ctrl_val; - - fuse_wait_idle(); -} - -/* Sense the fuse hardware array into the shadow cache */ -void fuse_hw_sense(void) -{ - fuse_wait_idle(); - - /* Enable sense operation in control register */ - uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL; - ctrl_val &= ~0x3; - ctrl_val |= 0x3; /* Set FUSE_SENSE command */ - FUSE_REGS->FUSE_CTRL = ctrl_val; - - fuse_wait_idle(); +/* Disable access to the private key and set the TZ sticky bit. */ +void fuse_disable_private_key(void) { + FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10; } /* Disables all fuse programming. */ void fuse_disable_programming(void) { - FUSE_REGS->FUSE_DIS_PGM = 1; + FUSE_REGS->FUSE_DISABLEREGPROGRAM = 1; } -/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */ -void fuse_secondary_private_key_disable(void) { - FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10; +/* Enable power to the fuse hardware array. */ +void fuse_enable_power(void) { + APBDEV_PMC_FUSE_CTRL &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */ + mdelay(1); + APBDEV_PMC_FUSE_CTRL |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */ + mdelay(1); } +/* Disable power to the fuse hardware array. */ +void fuse_disable_power(void) { + APBDEV_PMC_FUSE_CTRL &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */ + mdelay(1); + APBDEV_PMC_FUSE_CTRL |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */ + mdelay(1); +} -/* Read the SKU info register from the shadow cache */ -uint32_t fuse_get_sku_info(void) -{ +/* Wait for the fuse driver to go idle. */ +void fuse_wait_idle(void) { + uint32_t ctrl_val = 0; + + /* Wait for STATE_IDLE */ + while ((ctrl_val & (0xF0000)) != 0x40000) + ctrl_val = FUSE_REGS->FUSE_FUSECTRL; +} + +/* Read a fuse from the hardware array. */ +uint32_t fuse_hw_read(uint32_t addr) { + /* Wait for idle state. */ + fuse_wait_idle(); + + /* Program the target address. */ + FUSE_REGS->FUSE_FUSEADDR = addr; + + /* Enable read operation in control register. */ + uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL; + ctrl_val &= ~0x3; + ctrl_val |= 0x1; /* Set READ command. */ + FUSE_REGS->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ + fuse_wait_idle(); + + return FUSE_REGS->FUSE_FUSERDATA; +} + +/* Write a fuse in the hardware array. */ +void fuse_hw_write(uint32_t value, uint32_t addr) { + /* Wait for idle state. */ + fuse_wait_idle(); + + /* Program the target address and value. */ + FUSE_REGS->FUSE_FUSEADDR = addr; + FUSE_REGS->FUSE_FUSEWDATA = value; + + /* Enable write operation in control register. */ + uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL; + ctrl_val &= ~0x3; + ctrl_val |= 0x2; /* Set WRITE command. */ + FUSE_REGS->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ + fuse_wait_idle(); +} + +/* Sense the fuse hardware array into the shadow cache. */ +void fuse_hw_sense(void) { + /* Wait for idle state. */ + fuse_wait_idle(); + + /* Enable sense operation in control register */ + uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL; + ctrl_val &= ~0x3; + ctrl_val |= 0x3; /* Set SENSE_CTRL command */ + FUSE_REGS->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ + fuse_wait_idle(); +} + +/* Read the SKU info register from the shadow cache. */ +uint32_t fuse_get_sku_info(void) { return FUSE_CHIP_REGS->FUSE_SKU_INFO; } -/* Read the bootrom patch version from a register in the shadow cache */ -uint32_t fuse_get_bootrom_patch_version(void) -{ - return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1; +/* Read the bootrom patch version from a register in the shadow cache. */ +uint32_t fuse_get_bootrom_patch_version(void) { + return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1_CALIB; } /* Read a spare bit register from the shadow cache */ -uint32_t fuse_get_spare_bit(uint32_t idx) -{ - if (idx >= 32) { - return 0; - } - - return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx]; -} - -/* Read a reserved ODM register from the shadow cache */ -uint32_t fuse_get_reserved_odm(uint32_t idx) -{ - if (idx >= 8) { - return 0; - } - - return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx]; -} - -uint32_t fuse_get_5x_key_generation(void) { - if ((fuse_get_reserved_odm(4) & 0x800) && fuse_get_reserved_odm(0) == 0x8E61ECAE && fuse_get_reserved_odm(1) == 0xF2BA3BB2) { - return fuse_get_reserved_odm(2) & 0x1F; +uint32_t fuse_get_spare_bit(uint32_t idx) { + if (idx < 32) { + return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx]; } else { return 0; } } -/* Derive the Device ID using values in the shadow cache */ +/* Read a reserved ODM register from the shadow cache. */ +uint32_t fuse_get_reserved_odm(uint32_t idx) { + if (idx < 8) { + return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx]; + } else { + return 0; + } +} + +/* Get the DRAM ID using values in the shadow cache. */ +uint32_t fuse_get_dram_id(void) { + return ((fuse_get_reserved_odm(4) >> 3) & 0x7); +} + +/* Derive the Device ID using values in the shadow cache. */ uint64_t fuse_get_device_id(void) { uint64_t device_id = 0; - uint64_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF; - uint64_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF; - uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code = FUSE_CHIP_REGS->FUSE_LOT_CODE_0; - uint64_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F; + uint64_t y_coord = FUSE_CHIP_REGS->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint64_t x_coord = FUSE_CHIP_REGS->FUSE_OPT_X_COORDINATE & 0x1FF; + uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0; + uint64_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F; + uint64_t derived_lot_code = 0; for (unsigned int i = 0; i < 5; i++) { derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F); } derived_lot_code &= 0x03FFFFFF; - + device_id |= y_coord << 0; device_id |= x_coord << 9; device_id |= wafer_id << 18; device_id |= derived_lot_code << 24; device_id |= fab_code << 50; + return device_id; } -/* Get the DRAM ID using values in the shadow cache */ -uint32_t fuse_get_dram_id(void) { - return (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 3) & 0x7; -} - -/* Derive the Hardware Type using values in the shadow cache */ -uint32_t fuse_get_hardware_type(void) { - /* This function is very different between 4.x and < 4.x */ - uint32_t hardware_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 2) & 1); +/* Derive the Hardware Type using values in the shadow cache. */ +uint32_t fuse_get_hardware_type(uint32_t mkey_rev) { + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1)); - if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) { - static const uint32_t types[] = {0,1,4,3}; - - hardware_type |= (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 14) & 0x3C; - hardware_type--; - return hardware_type > 3 ? 4 : types[hardware_type]; - } else { + /* Firmware from versions 1.0.0 to 3.0.2. */ + if (mkey_rev < 0x03) { if (hardware_type >= 1) { - return hardware_type > 2 ? 3 : hardware_type - 1; + return (hardware_type > 2) ? 3 : hardware_type - 1; } else if ((FUSE_CHIP_REGS->FUSE_SPARE_BIT[9] & 1) == 0) { return 0; } else { return 3; } + } else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */ + static const uint32_t types[] = {0,1,4,3}; + hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C); + hardware_type--; + return (hardware_type > 3) ? 4 : types[hardware_type]; + } else { /* Firmware versions from 7.0.0 onwards. */ + /* Always return 0 in retail. */ + return 0; } } -/* Derive the Retail Type using values in the shadow cache */ +/* Derive the Retail Type using values in the shadow cache. */ uint32_t fuse_get_retail_type(void) { - /* Retail type = IS_RETAIL | UNIT_TYPE */ - uint32_t retail_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 4) | (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] & 3); + /* Retail Type = IS_RETAIL | UNIT_TYPE. */ + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3)); if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */ return 1; } else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */ @@ -249,17 +231,17 @@ uint32_t fuse_get_retail_type(void) { void fuse_get_hardware_info(void *dst) { uint32_t hw_info[0x4]; - uint32_t unk_hw_fuse = FUSE_CHIP_REGS->_0x120 & 0x3F; - uint32_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF; - uint32_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF; - uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_LOT_CODE_0; - uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF; - uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F; - uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF; + uint32_t ops_reserved = FUSE_CHIP_REGS->FUSE_OPT_OPS_RESERVED & 0x3F; + uint32_t y_coord = FUSE_CHIP_REGS->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint32_t x_coord = FUSE_CHIP_REGS->FUSE_OPT_X_COORDINATE & 0x1FF; + uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0; + uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF; + uint32_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F; + uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_OPT_VENDOR_CODE & 0xF; - /* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ - hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse)); + /* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ + hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved)); hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2)); hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6)); hw_info[3] = (uint32_t)(vendor_code); @@ -267,15 +249,25 @@ void fuse_get_hardware_info(void *dst) { memcpy(dst, hw_info, 0x10); } +/* Get the Key Generation value. */ +uint32_t fuse_get_5x_key_generation(void) { + if ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2)) { + return (fuse_get_reserved_odm(2) & 0x1F); + } else { + return 0; + } +} + +/* Check for RCM bug patches. */ bool fuse_has_rcm_bug_patch(void) { /* Only check for RCM bug patch once, and cache our result. */ if (!g_has_checked_for_rcm_bug_patch) { - /* Patched units have this bit set in reserved_sw, according to reports. */ + /* Some patched units use XUSB in RCM. */ if (FUSE_CHIP_REGS->FUSE_RESERVED_SW & 0x80) { g_has_rcm_bug_patch = true; } - /* Also check for an ipatch. */ + /* Other units have a proper ipatch instead. */ { uint32_t word_count = FUSE_CHIP_REGS->FUSE_FIRST_BOOTROM_PATCH_SIZE & 0x7f; uint32_t word_addr = 191; @@ -301,4 +293,4 @@ bool fuse_has_rcm_bug_patch(void) { g_has_checked_for_rcm_bug_patch = true; return g_has_rcm_bug_patch; -} +} \ No newline at end of file diff --git a/exosphere/src/fuse.h b/exosphere/src/fuse.h index 04ac2eafc..7f5353bb7 100644 --- a/exosphere/src/fuse.h +++ b/exosphere/src/fuse.h @@ -24,154 +24,167 @@ /* Exosphere driver for the Tegra X1 FUSE registers. */ typedef struct { - uint32_t FUSE_CTRL; - uint32_t FUSE_REG_ADDR; - uint32_t FUSE_REG_READ; - uint32_t FUSE_REG_WRITE; - uint32_t FUSE_TIME_RD1; - uint32_t FUSE_TIME_RD2; - uint32_t FUSE_TIME_PGM1; - uint32_t FUSE_TIME_PGM2; - uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSECTRL; + uint32_t FUSE_FUSEADDR; + uint32_t FUSE_FUSERDATA; + uint32_t FUSE_FUSEWDATA; + uint32_t FUSE_FUSETIME_RD1; + uint32_t FUSE_FUSETIME_RD2; + uint32_t FUSE_FUSETIME_PGM1; + uint32_t FUSE_FUSETIME_PGM2; + uint32_t FUSE_PRIV2INTFC_START; uint32_t FUSE_FUSEBYPASS; uint32_t FUSE_PRIVATEKEYDISABLE; - uint32_t FUSE_DIS_PGM; - uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_DISABLEREGPROGRAM; + uint32_t FUSE_WRITE_ACCESS_SW; uint32_t FUSE_PWR_GOOD_SW; - uint32_t _0x38[0x32]; -} fuse_registers_t; + uint32_t _0x38; + uint32_t FUSE_PRIV2RESHIFT; + uint32_t _0x40[0x3]; + uint32_t FUSE_FUSETIME_RD3; + uint32_t _0x50[0xC]; + uint32_t FUSE_PRIVATE_KEY0_NONZERO; + uint32_t FUSE_PRIVATE_KEY1_NONZERO; + uint32_t FUSE_PRIVATE_KEY2_NONZERO; + uint32_t FUSE_PRIVATE_KEY3_NONZERO; + uint32_t FUSE_PRIVATE_KEY4_NONZERO; + uint32_t _0x90[0x1C]; +} tegra_fuse_t; typedef struct { uint32_t FUSE_PRODUCTION_MODE; - uint32_t _0x4; - uint32_t _0x8; - uint32_t _0xC; + uint32_t FUSE_JTAG_SECUREID_VALID; + uint32_t FUSE_ODM_LOCK; + uint32_t FUSE_OPT_OPENGL_EN; uint32_t FUSE_SKU_INFO; - uint32_t FUSE_CPU_SPEEDO_0; - uint32_t FUSE_CPU_IDDQ; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t _0x24; - uint32_t FUSE_FT_REV; - uint32_t FUSE_CPU_SPEEDO_1; - uint32_t FUSE_CPU_SPEEDO_2; - uint32_t FUSE_SOC_SPEEDO_0; - uint32_t FUSE_SOC_SPEEDO_1; - uint32_t FUSE_SOC_SPEEDO_2; - uint32_t FUSE_SOC_IDDQ; - uint32_t _0x44; + uint32_t FUSE_CPU_SPEEDO_0_CALIB; + uint32_t FUSE_CPU_IDDQ_CALIB; + uint32_t FUSE_DAC_CRT_CALIB; + uint32_t FUSE_DAC_HDTV_CALIB; + uint32_t FUSE_DAC_SDTV_CALIB; + uint32_t FUSE_OPT_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1_CALIB; + uint32_t FUSE_CPU_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_SPEEDO_0_CALIB; + uint32_t FUSE_SOC_SPEEDO_1_CALIB; + uint32_t FUSE_SOC_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_IDDQ_CALIB; + uint32_t FUSE_RESERVED_PRODUCTION_WP; uint32_t FUSE_FA; - uint32_t _0x4C; - uint32_t _0x50; - uint32_t _0x54; - uint32_t _0x58; - uint32_t _0x5C; - uint32_t _0x60; + uint32_t FUSE_RESERVED_PRODUCTION; + uint32_t FUSE_HDMI_LANE0_CALIB; + uint32_t FUSE_HDMI_LANE1_CALIB; + uint32_t FUSE_HDMI_LANE2_CALIB; + uint32_t FUSE_HDMI_LANE3_CALIB; + uint32_t FUSE_ENCRYPTION_RATE; uint32_t FUSE_PUBLIC_KEY[0x8]; - uint32_t FUSE_TSENSOR_1; - uint32_t FUSE_TSENSOR_2; - uint32_t _0x8C; - uint32_t FUSE_CP_REV; - uint32_t _0x94; - uint32_t FUSE_TSENSOR_0; + uint32_t FUSE_TSENSOR1_CALIB; + uint32_t FUSE_TSENSOR2_CALIB; + uint32_t FUSE_VSENSOR_CALIB; + uint32_t FUSE_OPT_CP_REV; + uint32_t FUSE_OPT_PFG; + uint32_t FUSE_TSENSOR0_CALIB; uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; - uint32_t FUSE_PRIVATE_KEY[0x4]; - uint32_t FUSE_DEVICE_KEY; - uint32_t _0xB8; - uint32_t _0xBC; + uint32_t FUSE_PRIVATE_KEY[0x5]; + uint32_t FUSE_ARM_JTAG_DIS; + uint32_t FUSE_BOOT_DEVICE_INFO; uint32_t FUSE_RESERVED_SW; - uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_OPT_VP9_DISABLE; uint32_t FUSE_RESERVED_ODM[0x8]; - uint32_t _0xE8; - uint32_t _0xEC; - uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_OBS_DIS; + uint32_t FUSE_NOR_INFO; + uint32_t FUSE_USB_CALIB; uint32_t FUSE_SKU_DIRECT_CONFIG; - uint32_t _0xF8; - uint32_t _0xFC; - uint32_t FUSE_VENDOR_CODE; - uint32_t FUSE_FAB_CODE; - uint32_t FUSE_LOT_CODE_0; - uint32_t FUSE_LOT_CODE_1; - uint32_t FUSE_WAFER_ID; - uint32_t FUSE_X_COORDINATE; - uint32_t FUSE_Y_COORDINATE; - uint32_t _0x11C; - uint32_t _0x120; + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; + uint32_t FUSE_PACKAGE_INFO; + uint32_t FUSE_OPT_VENDOR_CODE; + uint32_t FUSE_OPT_FAB_CODE; + uint32_t FUSE_OPT_LOT_CODE_0; + uint32_t FUSE_OPT_LOT_CODE_1; + uint32_t FUSE_OPT_WAFER_ID; + uint32_t FUSE_OPT_X_COORDINATE; + uint32_t FUSE_OPT_Y_COORDINATE; + uint32_t FUSE_OPT_SEC_DEBUG_EN; + uint32_t FUSE_OPT_OPS_RESERVED; uint32_t FUSE_SATA_CALIB; - uint32_t FUSE_GPU_IDDQ; - uint32_t FUSE_TSENSOR_3; - uint32_t _0x130; - uint32_t _0x134; - uint32_t _0x138; - uint32_t _0x13C; - uint32_t _0x140; - uint32_t _0x144; + uint32_t FUSE_GPU_IDDQ_CALIB; + uint32_t FUSE_TSENSOR3_CALIB; + uint32_t FUSE_SKU_BOND_OUT_L; + uint32_t FUSE_SKU_BOND_OUT_H; + uint32_t FUSE_SKU_BOND_OUT_U; + uint32_t FUSE_SKU_BOND_OUT_V; + uint32_t FUSE_SKU_BOND_OUT_W; + uint32_t FUSE_OPT_SAMPLE_TYPE; uint32_t FUSE_OPT_SUBREVISION; - uint32_t _0x14C; - uint32_t _0x150; - uint32_t FUSE_TSENSOR_4; - uint32_t FUSE_TSENSOR_5; - uint32_t FUSE_TSENSOR_6; - uint32_t FUSE_TSENSOR_7; - uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_OPT_SW_RESERVED_0; + uint32_t FUSE_OPT_SW_RESERVED_1; + uint32_t FUSE_TSENSOR4_CALIB; + uint32_t FUSE_TSENSOR5_CALIB; + uint32_t FUSE_TSENSOR6_CALIB; + uint32_t FUSE_TSENSOR7_CALIB; + uint32_t FUSE_OPT_PRIV_SEC_EN; uint32_t FUSE_PKC_DISABLE; uint32_t _0x16C; uint32_t _0x170; uint32_t _0x174; uint32_t _0x178; - uint32_t _0x17C; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; uint32_t FUSE_TSENSOR_COMMON; - uint32_t _0x184; - uint32_t _0x188; - uint32_t _0x18C; - uint32_t _0x190; + uint32_t FUSE_OPT_CP_BIN; + uint32_t FUSE_OPT_GPU_DISABLE; + uint32_t FUSE_OPT_FT_BIN; + uint32_t FUSE_OPT_DONE_MAP; uint32_t _0x194; - uint32_t _0x198; - uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t FUSE_APB2JTAG_DISABLE; + uint32_t FUSE_ODM_INFO; uint32_t _0x1A0; uint32_t _0x1A4; - uint32_t _0x1A8; + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; uint32_t _0x1AC; uint32_t _0x1B0; uint32_t _0x1B4; uint32_t _0x1B8; uint32_t _0x1BC; - uint32_t _0x1D0; - uint32_t FUSE_TSENSOR_8; + uint32_t FUSE_WOA_SKU_FLAG; + uint32_t FUSE_ECO_RESERVE_1; + uint32_t FUSE_GCPLEX_CONFIG_FUSE; + uint32_t FUSE_PRODUCTION_MONTH; + uint32_t FUSE_RAM_REPAIR_INDICATOR; + uint32_t FUSE_TSENSOR9_CALIB; uint32_t _0x1D8; - uint32_t _0x1DC; - uint32_t _0x1E0; - uint32_t _0x1E4; - uint32_t _0x1E8; - uint32_t _0x1EC; - uint32_t _0x1F0; - uint32_t _0x1F4; - uint32_t _0x1F8; + uint32_t FUSE_VMIN_CALIBRATION; + uint32_t FUSE_AGING_SENSOR_CALIBRATION; + uint32_t FUSE_DEBUG_AUTHENTICATION; + uint32_t FUSE_SECURE_PROVISION_INDEX; + uint32_t FUSE_SECURE_PROVISION_INFO; + uint32_t FUSE_OPT_GPU_DISABLE_CP1; + uint32_t FUSE_SPARE_ENDIS; + uint32_t FUSE_ECO_RESERVE_0; uint32_t _0x1FC; uint32_t _0x200; - uint32_t FUSE_RESERVED_CALIB; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t _0x214; - uint32_t _0x218; - uint32_t FUSE_TSENSOR_9; - uint32_t _0x220; - uint32_t _0x224; - uint32_t _0x228; - uint32_t _0x22C; - uint32_t _0x230; - uint32_t _0x234; - uint32_t _0x238; - uint32_t _0x23C; - uint32_t _0x240; - uint32_t _0x244; - uint32_t _0x248; - uint32_t _0x24C; + uint32_t FUSE_RESERVED_CALIB0; + uint32_t FUSE_RESERVED_CALIB1; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1; + uint32_t FUSE_OPT_CPU_DISABLE; + uint32_t FUSE_OPT_CPU_DISABLE_CP1; + uint32_t FUSE_TSENSOR10_CALIB; + uint32_t FUSE_TSENSOR10_CALIB_AUX; + uint32_t FUSE_OPT_RAM_SVOP_DP; + uint32_t FUSE_OPT_RAM_SVOP_PDP; + uint32_t FUSE_OPT_RAM_SVOP_REG; + uint32_t FUSE_OPT_RAM_SVOP_SP; + uint32_t FUSE_OPT_RAM_SVOP_SMPDP; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2; + uint32_t FUSE_OPT_CPU_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_DISABLE_CP2; uint32_t FUSE_USB_CALIB_EXT; - uint32_t _0x254; - uint32_t _0x258; + uint32_t FUSE_RESERVED_FIELD; + uint32_t FUSE_OPT_ECC_EN; uint32_t _0x25C; uint32_t _0x260; uint32_t _0x264; @@ -180,41 +193,39 @@ typedef struct { uint32_t _0x270; uint32_t _0x274; uint32_t _0x278; - uint32_t _0x27C; + uint32_t FUSE_SPARE_REALIGNMENT_REG; uint32_t FUSE_SPARE_BIT[0x20]; -} fuse_chip_registers_t; +} tegra_fuse_chip_t; -static inline volatile fuse_registers_t *get_fuse_regs(void) { - return (volatile fuse_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x800); +static inline volatile tegra_fuse_t *fuse_get_regs(void) { + return (volatile tegra_fuse_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x800); } -static inline volatile fuse_chip_registers_t *get_fuse_chip_regs(void) { - return (volatile fuse_chip_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x900); +static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) { + return (volatile tegra_fuse_chip_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x900); } -#define FUSE_REGS (get_fuse_regs()) -#define FUSE_CHIP_REGS (get_fuse_chip_regs()) + +#define FUSE_REGS (fuse_get_regs()) +#define FUSE_CHIP_REGS (fuse_chip_get_regs()) void fuse_init(void); - -uint32_t fuse_hw_read(uint32_t addr); -void fuse_hw_write(uint32_t value, uint32_t addr); -void fuse_hw_sense(void); void fuse_disable_programming(void); -void fuse_secondary_private_key_disable(void); +void fuse_disable_private_key(void); uint32_t fuse_get_sku_info(void); uint32_t fuse_get_spare_bit(uint32_t idx); uint32_t fuse_get_reserved_odm(uint32_t idx); - -uint32_t fuse_get_5x_key_generation(void); - uint32_t fuse_get_bootrom_patch_version(void); uint64_t fuse_get_device_id(void); uint32_t fuse_get_dram_id(void); -uint32_t fuse_get_hardware_type(void); +uint32_t fuse_get_hardware_type(uint32_t mkey_rev); uint32_t fuse_get_retail_type(void); void fuse_get_hardware_info(void *dst); - +uint32_t fuse_get_5x_key_generation(void); bool fuse_has_rcm_bug_patch(void); +uint32_t fuse_hw_read(uint32_t addr); +void fuse_hw_write(uint32_t value, uint32_t addr); +void fuse_hw_sense(void); + #endif diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index 4fe2b6623..e46cacbf0 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -106,15 +106,15 @@ static void setup_se(void) { /* Perform some sanity initialization. */ volatile tegra_se_t *se = se_get_regs(); - se->_0x0 &= 0xFFFEFFFF; /* Clear bit 16. */ - (void)(se->FLAGS_REG); + se->SE_SE_SECURITY &= 0xFFFEFFFF; /* Clear bit 16. */ + (void)(se->SE_STATUS); __dsb_sy(); /* NOTE: On 8.1.0+, Nintendo does not make keyslots 0-5 unreadable. */ - se->_0x4 = 0; - se->AES_KEY_READ_DISABLE_REG = 0; - se->RSA_KEY_READ_DISABLE_REG = 0; - se->_0x0 &= 0xFFFFFFFB; + se->SE_TZRAM_SECURITY = 0; + se->SE_CRYPTO_SECURITY_PERKEY = 0; + se->SE_RSA_SECURITY_PERKEY = 0; + se->SE_SE_SECURITY &= 0xFFFFFFFB; /* Currently unknown what each flag does. */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { diff --git a/exosphere/src/pmc.h b/exosphere/src/pmc.h index f4808cd12..429571f1e 100644 --- a/exosphere/src/pmc.h +++ b/exosphere/src/pmc.h @@ -29,32 +29,24 @@ static inline uintptr_t get_pmc_base(void) { #define PMC_BASE (get_pmc_base()) #define APBDEV_PMC_DPD_ENABLE_0 MAKE_REG32(PMC_BASE + 0x24) - #define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_REG32(PMC_BASE + 0x30) #define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_REG32(PMC_BASE + 0x38) - #define APBDEV_PMC_SCRATCH0_0 MAKE_REG32(PMC_BASE + 0x50) - #define APBDEV_PMC_CRYPTO_OP_0 MAKE_REG32(PMC_BASE + 0xF4) - #define APBDEV_PM_0 MAKE_REG32(PMC_BASE + 0x14) #define APBDEV_PMC_WAKE2_STATUS_0 MAKE_REG32(PMC_BASE + 0x168) #define APBDEV_PMC_CNTRL2_0 MAKE_REG32(PMC_BASE + 0x440) - +#define APBDEV_PMC_FUSE_CTRL MAKE_REG32(PMC_BASE + 0x450) #define APBDEV_PMC_SCRATCH43_0 MAKE_REG32(PMC_BASE + 0x22C) #define APBDEV_PMC_SEC_DISABLE8_0 MAKE_REG32(PMC_BASE + 0x5C0) #define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_REG32(PMC_BASE + 0xB18) #define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_REG32(PMC_BASE + 0xB1C) #define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_REG32(PMC_BASE + 0xB20) #define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_REG32(PMC_BASE + 0xB24) - #define APBDEV_PMC_SCRATCH200_0 MAKE_REG32(PMC_BASE + 0x840) - - #define APBDEV_PMC_SEC_DISABLE3_0 MAKE_REG32(PMC_BASE + 0x2D8) #define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_REG32(PMC_BASE + 0x368) #define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_REG32(PMC_BASE + 0x36C) - #define APBDEV_PMC_SECURE_SCRATCH16_0 MAKE_REG32(PMC_BASE + 0x320) #define APBDEV_PMC_SECURE_SCRATCH51_0 MAKE_REG32(PMC_BASE + 0x3AC) #define APBDEV_PMC_SECURE_SCRATCH55_0 MAKE_REG32(PMC_BASE + 0x3BC) @@ -70,5 +62,4 @@ static inline uintptr_t get_pmc_base(void) { #define APBDEV_PMC_SECURE_SCRATCH103_0 MAKE_REG32(PMC_BASE + 0xAF4) #define APBDEV_PMC_SECURE_SCRATCH39_0 MAKE_REG32(PMC_BASE + 0x37C) - #endif diff --git a/exosphere/src/se.c b/exosphere/src/se.c index 2a42157d6..c35340d4a 100644 --- a/exosphere/src/se.c +++ b/exosphere/src/se.c @@ -61,7 +61,7 @@ void set_security_engine_callback(unsigned int (*callback)(void)) { /* Fires on Security Engine operation completion. */ void se_operation_completed(void) { - se_get_regs()->INT_ENABLE_REG = 0; + se_get_regs()->SE_INT_ENABLE = 0; if (g_se_callback != NULL) { g_se_callback(); g_se_callback = NULL; @@ -69,14 +69,14 @@ void se_operation_completed(void) { } void se_check_error_status_reg(void) { - if (se_get_regs()->ERR_STATUS_REG) { + if (se_get_regs()->SE_ERR_STATUS) { generic_panic(); } } void se_check_for_error(void) { volatile tegra_se_t *se = se_get_regs(); - if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) { + if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) { generic_panic(); } } @@ -86,7 +86,7 @@ void se_trigger_interrupt(void) { } void se_verify_flags_cleared(void) { - if (se_get_regs()->FLAGS_REG & 3) { + if (se_get_regs()->SE_STATUS & 3) { generic_panic(); } } @@ -129,12 +129,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { - se->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -149,12 +149,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { /* TODO: Why are flags assigned this way? */ - se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -167,8 +167,8 @@ void clear_aes_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -182,13 +182,13 @@ void clear_rsa_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + se->SE_RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = 0; } } @@ -200,8 +200,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { } for (size_t i = 0; i < (key_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = read32le(key, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i); } } @@ -213,13 +213,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_ } for (size_t i = 0; i < (modulus_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; - se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); } for (size_t i = 0; i < (exp_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); } g_se_modulus_sizes[keyslot] = modulus_size; @@ -234,8 +234,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { } for (size_t i = 0; i < (iv_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i); } } @@ -247,14 +247,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) { } for (size_t i = 0; i < (0x10 >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } void set_se_ctr(const void *ctr) { for (unsigned int i = 0; i < 4; i++) { - se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4); } } @@ -265,10 +265,10 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); - se->CRYPTO_REG = keyslot_src << 24; - se->BLOCK_COUNT_REG = 0; - se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; + se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = keyslot_src << 24; + se->SE_CRYPTO_LAST_BLOCK = 0; + se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8; flush_dcache_range(wrapped_key, (const uint8_t *)wrapped_key + wrapped_key_size); trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); @@ -287,35 +287,35 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, /* Setup Config register. */ if (encrypt) { - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); } else { - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); } /* Setup Crypto register. */ - se->CRYPTO_REG = crypt_config | (keyslot << 24) | (encrypt << 8); + se->SE_CRYPTO_CONFIG = crypt_config | (keyslot << 24) | (encrypt << 8); /* Mark this encryption as insecure -- this makes the SE not a secure busmaster. */ - se->CRYPTO_REG |= 0x80000000; + se->SE_CRYPTO_CONFIG |= 0x80000000; /* Appropriate number of blocks. */ - se->BLOCK_COUNT_REG = (size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1; /* Set the callback, for after the async operation. */ set_security_engine_callback(callback); /* Enable SE Interrupt firing for async op. */ - se->INT_ENABLE_REG = 0x10; + se->SE_INT_ENABLE = 0x10; /* Setup Input/Output lists */ - se->IN_LL_ADDR_REG = in_ll_paddr; - se->OUT_LL_ADDR_REG = out_ll_paddr; + se->SE_IN_LL_ADDR = in_ll_paddr; + se->SE_OUT_LL_ADDR = out_ll_paddr; /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = 1; - (void)(se->OPERATION_REG); + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = 1; + (void)(se->SE_OPERATION); /* Ensure writes go through. */ __dsb_ish(); @@ -323,7 +323,7 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void)) { /* Unknown what this write does, but official code writes it for CTR mode. */ - se_get_regs()->SPARE_0 = 1; + se_get_regs()->SE_SPARE = 1; set_se_ctr(ctr); se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, true, callback); } @@ -351,20 +351,20 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal stack_buf[i] = *((uint8_t *)buf + size - i - 1); } - se->CONFIG_REG = (ALG_RSA | DST_RSAREG); - se->RSA_CONFIG = keyslot << 24; - se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + se->SE_CONFIG = (ALG_RSA | DST_RSAREG); + se->SE_RSA_CONFIG = keyslot << 24; + se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1; + se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2; set_security_engine_callback(callback); - /* Enable SE Interrupt firing for async op. */ - se->INT_ENABLE_REG = 0x10; + /* Enable SE interrupt firing for async op. */ + se->SE_INT_ENABLE = 0x10; flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX); trigger_se_rsa_op(stack_buf, size); - while (!(se->INT_STATUS_REG & 2)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 2)) { /* Wait a while */ } } void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { @@ -380,10 +380,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co stack_buf[i] = *((uint8_t *)src + src_size - i - 1); } - se->CONFIG_REG = (ALG_RSA | DST_RSAREG); - se->RSA_CONFIG = keyslot << 24; - se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + se->SE_CONFIG = (ALG_RSA | DST_RSAREG); + se->SE_RSA_CONFIG = keyslot << 24; + se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1; + se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2; flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX); trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size); @@ -401,7 +401,7 @@ void se_get_exp_mod_output(void *buf, size_t size) { /* Copy endian swapped output. */ while (num_dwords) { - *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset); + *p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset); offset += 4; p_out--; num_dwords--; @@ -472,13 +472,13 @@ void trigger_se_rsa_op(void *buf, size_t size) { ll_init(&in_ll, (void *)buf, size); /* Set the input LL. */ - se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); + se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = 1; - (void)(se->OPERATION_REG); + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = 1; + (void)(se->SE_OPERATION); /* Ensure writes go through. */ __dsb_ish(); @@ -495,18 +495,18 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v __dsb_sy(); /* Set the LLs. */ - se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); - se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll); + se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); + se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = op; - (void)(se->OPERATION_REG); + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = op; + (void)(se->SE_OPERATION); __dsb_ish(); - while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -526,7 +526,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, flush_dcache_range(block, block + sizeof(block)); /* Trigger AES operation. */ - se_get_regs()->BLOCK_COUNT_REG = 0; + se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -553,15 +553,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo unsigned int num_blocks = src_size >> 4; /* Unknown what this write does, but official code writes it for CTR mode. */ - se->SPARE_0 = 1; - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x91E; + se->SE_SPARE = 1; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E; set_se_ctr(ctr); /* Handle any aligned blocks. */ size_t aligned_size = (size_t)num_blocks << 4; if (aligned_size) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size); } @@ -587,8 +587,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - se->CRYPTO_REG = keyslot << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100; flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10); se_perform_aes_block_operation(dst, 0x10, src, 0x10); flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10); @@ -611,8 +611,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot << 24; flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10); se_perform_aes_block_operation(dst, 0x10, src, 0x10); flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10); @@ -649,16 +649,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - se->CRYPTO_REG = (keyslot << 24) | (0x145); + se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - se->BLOCK_COUNT_REG = num_blocks - 2; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2; trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); - se->CRYPTO_REG |= 0x80; + se->SE_CRYPTO_CONFIG |= 0x80; } /* Create final block. */ @@ -675,13 +675,13 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con } /* Perform last operation. */ - se->BLOCK_COUNT_REG = 0; + se->SE_CRYPTO_LAST_BLOCK = 0; flush_dcache_range(last_block, last_block + sizeof(last_block)); trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2); } } @@ -699,10 +699,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x144; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144; set_aes_keyslot_iv(keyslot, iv, 0x10); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -711,23 +711,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { volatile tegra_se_t *se = se_get_regs(); /* Setup config for SHA256, size = BITS(src_size) */ - se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); - se->SHA_CONFIG_REG = 1; - se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3); - se->_0x208 = 0; - se->_0x20C = 0; - se->_0x210 = 0; - se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3); - se->_0x218 = 0; - se->_0x21C = 0; - se->_0x220 = 0; + se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + se->SE_SHA_CONFIG = 1; + se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LENGTH[1] = 0; + se->SE_SHA_MSG_LENGTH[2] = 0; + se->SE_SHA_MSG_LENGTH[3] = 0; + se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LEFT[1] = 0; + se->SE_SHA_MSG_LEFT[2] = 0; + se->SE_SHA_MSG_LEFT[3] = 0; /* Trigger the operation. */ trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); /* Copy output hash. */ for (unsigned int i = 0; i < (0x20 >> 2); i++) { - ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2); } } @@ -743,12 +743,12 @@ void se_initialize_rng(unsigned int keyslot) { /* This will be discarded, when done. */ uint8_t output_buf[0x10]; - se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ - se->RNG_RESEED_INTERVAL_REG = 70001; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 5; - se->BLOCK_COUNT_REG = 0; + se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */ + se->SE_RNG_RESEED_INTERVAL = 70001; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 5; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0); } @@ -761,12 +761,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) { uint32_t num_blocks = size >> 4; size_t aligned_size = num_blocks << 4; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; if (num_blocks >= 1) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0); } if (size > aligned_size) { @@ -778,15 +778,15 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) { void se_set_in_context_save_mode(bool is_context_save_mode) { volatile tegra_se_t *se = se_get_regs(); - uint32_t val = se->_0x0; + uint32_t val = se->SE_SE_SECURITY; if (is_context_save_mode) { val |= 0x10000; } else { val &= 0xFFFEFFFF; } - se->_0x0 = val; + se->SE_SE_SECURITY = val; /* Perform a useless read from flags reg. */ - (void)(se->FLAGS_REG); + (void)(se->SE_STATUS); } void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) { @@ -797,26 +797,26 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) } /* Setup Config. */ - se->CONFIG_REG = (ALG_RNG | DST_KEYTAB); - se->CRYPTO_REG = (rng_keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_RNG | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = (rng_keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; + se->SE_CRYPTO_LAST_BLOCK = 0; /* Generate low part of key. */ - se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8); + se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8); trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); /* Generate high part of key. */ - se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8) | 1; + se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8) | 1; trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); } void se_generate_srk(unsigned int srkgen_keyslot) { volatile tegra_se_t *se = se_get_regs(); - se->CONFIG_REG = (ALG_RNG | DST_SRK); - se->CRYPTO_REG = (srkgen_keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 6; - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_RNG | DST_SRK); + se->SE_CRYPTO_CONFIG = (srkgen_keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 6; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); } @@ -853,39 +853,39 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void flush_dcache_range(work_buf, work_buf + 0x10); /* Save random initial block. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst, 0x10, work_buf, 0x10); /* Save Sticky Bits. */ for (unsigned int i = 0; i < 0x2; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0); } /* Save AES Key Table. */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x30 + (i * 0x20), 0x10, NULL, 0); - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0); } /* Save AES Original IVs. */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0); } /* Save AES Updated IVs */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0); } @@ -894,8 +894,8 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) { for (unsigned int mod_exp = 0; mod_exp < 2; mod_exp++) { for (unsigned int sub_block = 0; sub_block < 0x10; sub_block++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(rsa_ctx_out, 0x10, NULL, 0); rsa_ctx_out += 0x10; } @@ -904,14 +904,14 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void /* Save "Known Pattern. " */ static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10); /* Save SRK into PMC registers. */ - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(work_buf, 0, NULL, 0); - se->CONFIG_REG = 0; + se->SE_CONFIG = 0; se_encrypt_with_srk(work_buf, 0, NULL, 0); } diff --git a/exosphere/src/se.h b/exosphere/src/se.h index dfb6cef09..d49928ad8 100644 --- a/exosphere/src/se.h +++ b/exosphere/src/se.h @@ -103,71 +103,59 @@ #define RSA_2048_BYTES 0x100 typedef struct { - uint32_t _0x0; - uint32_t _0x4; - uint32_t OPERATION_REG; - uint32_t INT_ENABLE_REG; - uint32_t INT_STATUS_REG; - uint32_t CONFIG_REG; - uint32_t IN_LL_ADDR_REG; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t OUT_LL_ADDR_REG; - uint32_t _0x28; - uint32_t _0x2C; - uint8_t HASH_RESULT_REG[0x20]; - uint8_t _0x50[0x20]; - uint32_t CONTEXT_SAVE_CONFIG_REG; - uint8_t _0x74[0x18C]; - uint32_t SHA_CONFIG_REG; - uint32_t SHA_MSG_LENGTH_REG; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t SHA_MSG_LEFT_REG; - uint32_t _0x218; - uint32_t _0x21C; - uint32_t _0x220; - uint32_t _0x224; - uint8_t _0x228[0x58]; - uint32_t AES_KEY_READ_DISABLE_REG; - uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C4[0x3C]; - uint32_t _0x300; - uint32_t CRYPTO_REG; - uint32_t CRYPTO_CTR_REG[4]; - uint32_t BLOCK_COUNT_REG; - uint32_t AES_KEYTABLE_ADDR; - uint32_t AES_KEYTABLE_DATA; - uint32_t _0x324; - uint32_t _0x328; - uint32_t _0x32C; - uint32_t CRYPTO_KEYTABLE_DST_REG; - uint8_t _0x334[0xC]; - uint32_t RNG_CONFIG_REG; - uint32_t RNG_SRC_CONFIG_REG; - uint32_t RNG_RESEED_INTERVAL_REG; - uint8_t _0x34C[0xB4]; - uint32_t RSA_CONFIG; - uint32_t RSA_KEY_SIZE_REG; - uint32_t RSA_EXP_SIZE_REG; - uint32_t RSA_KEY_READ_DISABLE_REG; - uint32_t RSA_KEYSLOT_FLAGS[2]; - uint32_t _0x418; - uint32_t _0x41C; - uint32_t RSA_KEYTABLE_ADDR; - uint32_t RSA_KEYTABLE_DATA; - uint8_t RSA_OUTPUT[0x100]; - uint8_t _0x528[0x2D8]; - uint32_t FLAGS_REG; - uint32_t ERR_STATUS_REG; - uint32_t _0x808; - uint32_t SPARE_0; - uint32_t _0x810; + uint32_t SE_SE_SECURITY; + uint32_t SE_TZRAM_SECURITY; + uint32_t SE_OPERATION; + uint32_t SE_INT_ENABLE; + uint32_t SE_INT_STATUS; + uint32_t SE_CONFIG; + uint32_t SE_IN_LL_ADDR; + uint32_t SE_IN_CUR_BYTE_ADDR; + uint32_t SE_IN_CUR_LL_ID; + uint32_t SE_OUT_LL_ADDR; + uint32_t SE_OUT_CUR_BYTE_ADDR; + uint32_t SE_OUT_CUR_LL_ID; + uint32_t SE_HASH_RESULT[0x10]; + uint32_t SE_CTX_SAVE_CONFIG; + uint32_t _0x74[0x63]; + uint32_t SE_SHA_CONFIG; + uint32_t SE_SHA_MSG_LENGTH[0x4]; + uint32_t SE_SHA_MSG_LEFT[0x4]; + uint32_t _0x224[0x17]; + uint32_t SE_CRYPTO_SECURITY_PERKEY; + uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10]; + uint32_t _0x2C4[0x10]; + uint32_t SE_CRYPTO_CONFIG; + uint32_t SE_CRYPTO_LINEAR_CTR[0x4]; + uint32_t SE_CRYPTO_LAST_BLOCK; + uint32_t SE_CRYPTO_KEYTABLE_ADDR; + uint32_t SE_CRYPTO_KEYTABLE_DATA; + uint32_t _0x324[0x3]; + uint32_t SE_CRYPTO_KEYTABLE_DST; + uint32_t _0x334[0x3]; + uint32_t SE_RNG_CONFIG; + uint32_t SE_RNG_SRC_CONFIG; + uint32_t SE_RNG_RESEED_INTERVAL; + uint32_t _0x34C[0x2D]; + uint32_t SE_RSA_CONFIG; + uint32_t SE_RSA_KEY_SIZE; + uint32_t SE_RSA_EXP_SIZE; + uint32_t SE_RSA_SECURITY_PERKEY; + uint32_t SE_RSA_KEYTABLE_ACCESS[0x2]; + uint32_t _0x418[0x2]; + uint32_t SE_RSA_KEYTABLE_ADDR; + uint32_t SE_RSA_KEYTABLE_DATA; + uint32_t SE_RSA_OUTPUT[0x40]; + uint32_t _0x528[0xB6]; + uint32_t SE_STATUS; + uint32_t SE_ERR_STATUS; + uint32_t SE_MISC; + uint32_t SE_SPARE; + uint32_t SE_ENTROPY_DEBUG_COUNTER; uint32_t _0x814; uint32_t _0x818; uint32_t _0x81C; - uint8_t _0x820[0x17E0]; + uint32_t _0x820[0x5F8]; } tegra_se_t; typedef struct { diff --git a/exosphere/src/timers.h b/exosphere/src/timers.h index 473c79ab4..d3ca4e1fb 100644 --- a/exosphere/src/timers.h +++ b/exosphere/src/timers.h @@ -26,13 +26,25 @@ static inline uintptr_t get_timers_base(void) { return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_TMRs_WDTs); } +static inline uintptr_t get_rtc_base(void) { + return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC); +} + #define TIMERS_BASE (get_timers_base()) #define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n) #define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10) +#define TIMERUS_USEC_CFG_0 MAKE_TIMERS_REG(0x14) #define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0) #define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4) +#define RTC_BASE (get_rtc_base()) +#define MAKE_RTC_REG(n) MAKE_REG32(RTC_BASE + n) + +#define RTC_SECONDS MAKE_RTC_REG(0x08) +#define RTC_SHADOW_SECONDS MAKE_RTC_REG(0x0C) +#define RTC_MILLI_SECONDS MAKE_RTC_REG(0x10) + typedef struct { uint32_t CONFIG; uint32_t STATUS; @@ -46,10 +58,54 @@ typedef struct { void wait(uint32_t microseconds); -static inline uint32_t get_time(void) { +static inline uint32_t get_time_s(void) { + return RTC_SECONDS; +} + +static inline uint32_t get_time_ms(void) { + return (RTC_MILLI_SECONDS | (RTC_SHADOW_SECONDS << 10)); +} + +static inline uint32_t get_time_us(void) { return TIMERUS_CNTR_1US_0; } -__attribute__ ((noreturn)) void watchdog_reboot(void); +/** + * Returns the time in microseconds. + */ +static inline uint32_t get_time(void) { + return get_time_us(); +} +/** + * Returns the number of microseconds that have passed since a given get_time(). + */ +static inline uint32_t get_time_since(uint32_t base) { + return get_time_us() - base; +} + +/** + * Delays for a given number of microseconds. + */ +static inline void udelay(uint32_t usecs) { + uint32_t start = get_time_us(); + while (get_time_us() - start < usecs); +} + +/** + * Delays until a number of usecs have passed since an absolute start time. + */ +static inline void udelay_absolute(uint32_t start, uint32_t usecs) { + while (get_time_us() - start < usecs); +} + +/** + * Delays for a given number of milliseconds. + */ +static inline void mdelay(uint32_t msecs) { + uint32_t start = get_time_ms(); + while (get_time_ms() - start < msecs); +} + +__attribute__ ((noreturn)) void watchdog_reboot(void); #endif diff --git a/fusee/fusee-mtc/src/fuse.c b/fusee/fusee-mtc/src/fuse.c index 1bfe3334c..4d4c948fb 100644 --- a/fusee/fusee-mtc/src/fuse.c +++ b/fusee/fusee-mtc/src/fuse.c @@ -20,214 +20,216 @@ #include "car.h" #include "fuse.h" +#include "pmc.h" #include "timers.h" /* Prototypes for internal commands. */ -void fuse_make_regs_visible(void); - void fuse_enable_power(void); void fuse_disable_power(void); void fuse_wait_idle(void); /* Initialize the fuse driver */ void fuse_init(void) { - fuse_make_regs_visible(); - fuse_secondary_private_key_disable(); - fuse_disable_programming(); - - /* TODO: Overrides (iROM patches) and various reads happen here */ -} - -/* Make all fuse registers visible */ -void fuse_make_regs_visible(void) { + /* Make all fuse registers visible, disable the private key and disable programming. */ clkrst_enable_fuse_regs(true); + fuse_disable_private_key(); + fuse_disable_programming(); } -/* Enable power to the fuse hardware array */ +/* Disable access to the private key and set the TZ sticky bit. */ +void fuse_disable_private_key(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_PRIVATEKEYDISABLE = 0x10; +} + +/* Disables all fuse programming. */ +void fuse_disable_programming(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_DISABLEREGPROGRAM = 1; +} + +/* Enable power to the fuse hardware array. */ void fuse_enable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 1; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x200); // Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. + mdelay(1); + pmc->fuse_control |= 0x100; // Set PMC_FUSE_CTRL_PS18_LATCH_SET. + mdelay(1); } -/* Disable power to the fuse hardware array */ +/* Disable power to the fuse hardware array. */ void fuse_disable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 0; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x100); // Clear PMC_FUSE_CTRL_PS18_LATCH_SET. + mdelay(1); + pmc->fuse_control |= 0x200; // Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. + mdelay(1); } -/* Wait for the fuse driver to go idle */ +/* Wait for the fuse driver to go idle. */ void fuse_wait_idle(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); uint32_t ctrl_val = 0; /* Wait for STATE_IDLE */ while ((ctrl_val & (0xF0000)) != 0x40000) - { - udelay(1); - ctrl_val = fuse->FUSE_CTRL; - } + ctrl_val = fuse->FUSE_FUSECTRL; } -/* Read a fuse from the hardware array */ +/* Read a fuse from the hardware array. */ uint32_t fuse_hw_read(uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address */ - fuse->FUSE_REG_ADDR = addr; + /* Program the target address. */ + fuse->FUSE_FUSEADDR = addr; - /* Enable read operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable read operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x1; /* Set FUSE_READ command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x1; /* Set READ command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); - return fuse->FUSE_REG_READ; + return fuse->FUSE_FUSERDATA; } -/* Write a fuse in the hardware array */ +/* Write a fuse in the hardware array. */ void fuse_hw_write(uint32_t value, uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address and value */ - fuse->FUSE_REG_ADDR = addr; - fuse->FUSE_REG_WRITE = value; + /* Program the target address and value. */ + fuse->FUSE_FUSEADDR = addr; + fuse->FUSE_FUSEWDATA = value; - /* Enable write operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable write operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x2; /* Set FUSE_WRITE command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x2; /* Set WRITE command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); } -/* Sense the fuse hardware array into the shadow cache */ +/* Sense the fuse hardware array into the shadow cache. */ void fuse_hw_sense(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); /* Enable sense operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x3; /* Set FUSE_SENSE command */ - fuse->FUSE_CTRL = ctrl_val; - + ctrl_val |= 0x3; /* Set SENSE_CTRL command */ + fuse->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ fuse_wait_idle(); } -/* Disables all fuse programming. */ -void fuse_disable_programming(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_DIS_PGM = 1; -} - -/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */ -void fuse_secondary_private_key_disable(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PRIVATEKEYDISABLE = 0x10; -} - - -/* Read the SKU info register from the shadow cache */ +/* Read the SKU info register from the shadow cache. */ uint32_t fuse_get_sku_info(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); return fuse_chip->FUSE_SKU_INFO; } -/* Read the bootrom patch version from a register in the shadow cache */ +/* Read the bootrom patch version from a register in the shadow cache. */ uint32_t fuse_get_bootrom_patch_version(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return fuse_chip->FUSE_SOC_SPEEDO_1; + return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB; } /* Read a spare bit register from the shadow cache */ uint32_t fuse_get_spare_bit(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 32) { + if (idx < 32) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_SPARE_BIT[idx]; + } else { return 0; } - - return fuse_chip->FUSE_SPARE_BIT[idx]; } -/* Read a reserved ODM register from the shadow cache */ +/* Read a reserved ODM register from the shadow cache. */ uint32_t fuse_get_reserved_odm(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 8) { + if (idx < 8) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_RESERVED_ODM[idx]; + } else { return 0; } - - return fuse_chip->FUSE_RESERVED_ODM[idx]; } -/* Derive the Device ID using values in the shadow cache */ +/* Get the DRAM ID using values in the shadow cache. */ +uint32_t fuse_get_dram_id(void) { + return ((fuse_get_reserved_odm(4) >> 3) & 0x7); +} + +/* Derive the Device ID using values in the shadow cache. */ uint64_t fuse_get_device_id(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint64_t device_id = 0; - uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0; - uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; + uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint64_t derived_lot_code = 0; for (unsigned int i = 0; i < 5; i++) { derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F); } derived_lot_code &= 0x03FFFFFF; - + device_id |= y_coord << 0; device_id |= x_coord << 9; device_id |= wafer_id << 18; device_id |= derived_lot_code << 24; device_id |= fab_code << 50; + return device_id; } -/* Get the DRAM ID using values in the shadow cache */ -uint32_t fuse_get_dram_id(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7; -} - -/* Derive the Hardware Type using values in the shadow cache */ -uint32_t fuse_get_hardware_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); +/* Derive the Hardware Type using values in the shadow cache. */ +uint32_t fuse_get_hardware_type(uint32_t mkey_rev) { + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1)); - /* This function is very different between 4.x and < 4.x */ - uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1); - - /* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) { - static const uint32_t types[] = {0,1,4,3}; - - hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C; - hardware_type--; - return hardware_type > 3 ? 4 : types[hardware_type]; - } else {*/ + /* Firmware from versions 1.0.0 to 3.0.2. */ + if (mkey_rev < 0x03) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); if (hardware_type >= 1) { - return hardware_type > 2 ? 3 : hardware_type - 1; + return (hardware_type > 2) ? 3 : hardware_type - 1; } else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) { return 0; } else { return 3; } -// } + } else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */ + static const uint32_t types[] = {0,1,4,3}; + hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C); + hardware_type--; + return (hardware_type > 3) ? 4 : types[hardware_type]; + } else { /* Firmware versions from 7.0.0 onwards. */ + /* Always return 0 in retail. */ + return 0; + } } -/* Derive the Retail Type using values in the shadow cache */ +/* Derive the Retail Type using values in the shadow cache. */ uint32_t fuse_get_retail_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - /* Retail type = IS_RETAIL | UNIT_TYPE */ - uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3); + /* Retail Type = IS_RETAIL | UNIT_TYPE. */ + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3)); if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */ return 1; } else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */ @@ -241,17 +243,17 @@ void fuse_get_hardware_info(void *dst) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint32_t hw_info[0x4]; - uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F; - uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0; - uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF; - uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; - uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF; + uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F; + uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF; + uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF; - /* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ - hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse)); + /* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ + hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved)); hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2)); hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6)); hw_info[3] = (uint32_t)(vendor_code); diff --git a/fusee/fusee-mtc/src/fuse.h b/fusee/fusee-mtc/src/fuse.h index 9d92503e2..d118b53dc 100644 --- a/fusee/fusee-mtc/src/fuse.h +++ b/fusee/fusee-mtc/src/fuse.h @@ -23,154 +23,167 @@ #define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n) typedef struct { - uint32_t FUSE_CTRL; - uint32_t FUSE_REG_ADDR; - uint32_t FUSE_REG_READ; - uint32_t FUSE_REG_WRITE; - uint32_t FUSE_TIME_RD1; - uint32_t FUSE_TIME_RD2; - uint32_t FUSE_TIME_PGM1; - uint32_t FUSE_TIME_PGM2; - uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSECTRL; + uint32_t FUSE_FUSEADDR; + uint32_t FUSE_FUSERDATA; + uint32_t FUSE_FUSEWDATA; + uint32_t FUSE_FUSETIME_RD1; + uint32_t FUSE_FUSETIME_RD2; + uint32_t FUSE_FUSETIME_PGM1; + uint32_t FUSE_FUSETIME_PGM2; + uint32_t FUSE_PRIV2INTFC_START; uint32_t FUSE_FUSEBYPASS; uint32_t FUSE_PRIVATEKEYDISABLE; - uint32_t FUSE_DIS_PGM; - uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_DISABLEREGPROGRAM; + uint32_t FUSE_WRITE_ACCESS_SW; uint32_t FUSE_PWR_GOOD_SW; - uint32_t _0x38[0x32]; + uint32_t _0x38; + uint32_t FUSE_PRIV2RESHIFT; + uint32_t _0x40[0x3]; + uint32_t FUSE_FUSETIME_RD3; + uint32_t _0x50[0xC]; + uint32_t FUSE_PRIVATE_KEY0_NONZERO; + uint32_t FUSE_PRIVATE_KEY1_NONZERO; + uint32_t FUSE_PRIVATE_KEY2_NONZERO; + uint32_t FUSE_PRIVATE_KEY3_NONZERO; + uint32_t FUSE_PRIVATE_KEY4_NONZERO; + uint32_t _0x90[0x1C]; } tegra_fuse_t; typedef struct { uint32_t FUSE_PRODUCTION_MODE; - uint32_t _0x4; - uint32_t _0x8; - uint32_t _0xC; + uint32_t FUSE_JTAG_SECUREID_VALID; + uint32_t FUSE_ODM_LOCK; + uint32_t FUSE_OPT_OPENGL_EN; uint32_t FUSE_SKU_INFO; - uint32_t FUSE_CPU_SPEEDO_0; - uint32_t FUSE_CPU_IDDQ; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t _0x24; - uint32_t FUSE_FT_REV; - uint32_t FUSE_CPU_SPEEDO_1; - uint32_t FUSE_CPU_SPEEDO_2; - uint32_t FUSE_SOC_SPEEDO_0; - uint32_t FUSE_SOC_SPEEDO_1; - uint32_t FUSE_SOC_SPEEDO_2; - uint32_t FUSE_SOC_IDDQ; - uint32_t _0x44; + uint32_t FUSE_CPU_SPEEDO_0_CALIB; + uint32_t FUSE_CPU_IDDQ_CALIB; + uint32_t FUSE_DAC_CRT_CALIB; + uint32_t FUSE_DAC_HDTV_CALIB; + uint32_t FUSE_DAC_SDTV_CALIB; + uint32_t FUSE_OPT_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1_CALIB; + uint32_t FUSE_CPU_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_SPEEDO_0_CALIB; + uint32_t FUSE_SOC_SPEEDO_1_CALIB; + uint32_t FUSE_SOC_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_IDDQ_CALIB; + uint32_t FUSE_RESERVED_PRODUCTION_WP; uint32_t FUSE_FA; - uint32_t _0x4C; - uint32_t _0x50; - uint32_t _0x54; - uint32_t _0x58; - uint32_t _0x5C; - uint32_t _0x60; + uint32_t FUSE_RESERVED_PRODUCTION; + uint32_t FUSE_HDMI_LANE0_CALIB; + uint32_t FUSE_HDMI_LANE1_CALIB; + uint32_t FUSE_HDMI_LANE2_CALIB; + uint32_t FUSE_HDMI_LANE3_CALIB; + uint32_t FUSE_ENCRYPTION_RATE; uint32_t FUSE_PUBLIC_KEY[0x8]; - uint32_t FUSE_TSENSOR_1; - uint32_t FUSE_TSENSOR_2; - uint32_t _0x8C; - uint32_t FUSE_CP_REV; - uint32_t _0x94; - uint32_t FUSE_TSENSOR_0; - uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_TSENSOR1_CALIB; + uint32_t FUSE_TSENSOR2_CALIB; + uint32_t FUSE_VSENSOR_CALIB; + uint32_t FUSE_OPT_CP_REV; + uint32_t FUSE_OPT_PFG; + uint32_t FUSE_TSENSOR0_CALIB; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; - uint32_t FUSE_PRIVATE_KEY[0x4]; - uint32_t FUSE_DEVICE_KEY; - uint32_t _0xB8; - uint32_t _0xBC; + uint32_t FUSE_PRIVATE_KEY[0x5]; + uint32_t FUSE_ARM_JTAG_DIS; + uint32_t FUSE_BOOT_DEVICE_INFO; uint32_t FUSE_RESERVED_SW; - uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_OPT_VP9_DISABLE; uint32_t FUSE_RESERVED_ODM[0x8]; - uint32_t _0xE8; - uint32_t _0xEC; - uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_OBS_DIS; + uint32_t FUSE_NOR_INFO; + uint32_t FUSE_USB_CALIB; uint32_t FUSE_SKU_DIRECT_CONFIG; - uint32_t _0xF8; - uint32_t _0xFC; - uint32_t FUSE_VENDOR_CODE; - uint32_t FUSE_FAB_CODE; - uint32_t FUSE_LOT_CODE_0; - uint32_t FUSE_LOT_CODE_1; - uint32_t FUSE_WAFER_ID; - uint32_t FUSE_X_COORDINATE; - uint32_t FUSE_Y_COORDINATE; - uint32_t _0x11C; - uint32_t _0x120; + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; + uint32_t FUSE_PACKAGE_INFO; + uint32_t FUSE_OPT_VENDOR_CODE; + uint32_t FUSE_OPT_FAB_CODE; + uint32_t FUSE_OPT_LOT_CODE_0; + uint32_t FUSE_OPT_LOT_CODE_1; + uint32_t FUSE_OPT_WAFER_ID; + uint32_t FUSE_OPT_X_COORDINATE; + uint32_t FUSE_OPT_Y_COORDINATE; + uint32_t FUSE_OPT_SEC_DEBUG_EN; + uint32_t FUSE_OPT_OPS_RESERVED; uint32_t FUSE_SATA_CALIB; - uint32_t FUSE_GPU_IDDQ; - uint32_t FUSE_TSENSOR_3; - uint32_t _0x130; - uint32_t _0x134; - uint32_t _0x138; - uint32_t _0x13C; - uint32_t _0x140; - uint32_t _0x144; + uint32_t FUSE_GPU_IDDQ_CALIB; + uint32_t FUSE_TSENSOR3_CALIB; + uint32_t FUSE_SKU_BOND_OUT_L; + uint32_t FUSE_SKU_BOND_OUT_H; + uint32_t FUSE_SKU_BOND_OUT_U; + uint32_t FUSE_SKU_BOND_OUT_V; + uint32_t FUSE_SKU_BOND_OUT_W; + uint32_t FUSE_OPT_SAMPLE_TYPE; uint32_t FUSE_OPT_SUBREVISION; - uint32_t _0x14C; - uint32_t _0x150; - uint32_t FUSE_TSENSOR_4; - uint32_t FUSE_TSENSOR_5; - uint32_t FUSE_TSENSOR_6; - uint32_t FUSE_TSENSOR_7; - uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_OPT_SW_RESERVED_0; + uint32_t FUSE_OPT_SW_RESERVED_1; + uint32_t FUSE_TSENSOR4_CALIB; + uint32_t FUSE_TSENSOR5_CALIB; + uint32_t FUSE_TSENSOR6_CALIB; + uint32_t FUSE_TSENSOR7_CALIB; + uint32_t FUSE_OPT_PRIV_SEC_EN; uint32_t FUSE_PKC_DISABLE; uint32_t _0x16C; uint32_t _0x170; uint32_t _0x174; uint32_t _0x178; - uint32_t _0x17C; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; uint32_t FUSE_TSENSOR_COMMON; - uint32_t _0x184; - uint32_t _0x188; - uint32_t _0x18C; - uint32_t _0x190; + uint32_t FUSE_OPT_CP_BIN; + uint32_t FUSE_OPT_GPU_DISABLE; + uint32_t FUSE_OPT_FT_BIN; + uint32_t FUSE_OPT_DONE_MAP; uint32_t _0x194; - uint32_t _0x198; - uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t FUSE_APB2JTAG_DISABLE; + uint32_t FUSE_ODM_INFO; uint32_t _0x1A0; uint32_t _0x1A4; - uint32_t _0x1A8; + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; uint32_t _0x1AC; uint32_t _0x1B0; uint32_t _0x1B4; uint32_t _0x1B8; uint32_t _0x1BC; - uint32_t _0x1D0; - uint32_t FUSE_TSENSOR_8; + uint32_t FUSE_WOA_SKU_FLAG; + uint32_t FUSE_ECO_RESERVE_1; + uint32_t FUSE_GCPLEX_CONFIG_FUSE; + uint32_t FUSE_PRODUCTION_MONTH; + uint32_t FUSE_RAM_REPAIR_INDICATOR; + uint32_t FUSE_TSENSOR9_CALIB; uint32_t _0x1D8; - uint32_t _0x1DC; - uint32_t _0x1E0; - uint32_t _0x1E4; - uint32_t _0x1E8; - uint32_t _0x1EC; - uint32_t _0x1F0; - uint32_t _0x1F4; - uint32_t _0x1F8; + uint32_t FUSE_VMIN_CALIBRATION; + uint32_t FUSE_AGING_SENSOR_CALIBRATION; + uint32_t FUSE_DEBUG_AUTHENTICATION; + uint32_t FUSE_SECURE_PROVISION_INDEX; + uint32_t FUSE_SECURE_PROVISION_INFO; + uint32_t FUSE_OPT_GPU_DISABLE_CP1; + uint32_t FUSE_SPARE_ENDIS; + uint32_t FUSE_ECO_RESERVE_0; uint32_t _0x1FC; uint32_t _0x200; - uint32_t FUSE_RESERVED_CALIB; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t _0x214; - uint32_t _0x218; - uint32_t FUSE_TSENSOR_9; - uint32_t _0x220; - uint32_t _0x224; - uint32_t _0x228; - uint32_t _0x22C; - uint32_t _0x230; - uint32_t _0x234; - uint32_t _0x238; - uint32_t _0x23C; - uint32_t _0x240; - uint32_t _0x244; - uint32_t _0x248; - uint32_t _0x24C; + uint32_t FUSE_RESERVED_CALIB0; + uint32_t FUSE_RESERVED_CALIB1; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1; + uint32_t FUSE_OPT_CPU_DISABLE; + uint32_t FUSE_OPT_CPU_DISABLE_CP1; + uint32_t FUSE_TSENSOR10_CALIB; + uint32_t FUSE_TSENSOR10_CALIB_AUX; + uint32_t FUSE_OPT_RAM_SVOP_DP; + uint32_t FUSE_OPT_RAM_SVOP_PDP; + uint32_t FUSE_OPT_RAM_SVOP_REG; + uint32_t FUSE_OPT_RAM_SVOP_SP; + uint32_t FUSE_OPT_RAM_SVOP_SMPDP; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2; + uint32_t FUSE_OPT_CPU_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_DISABLE_CP2; uint32_t FUSE_USB_CALIB_EXT; - uint32_t _0x254; - uint32_t _0x258; + uint32_t FUSE_RESERVED_FIELD; + uint32_t FUSE_OPT_ECC_EN; uint32_t _0x25C; uint32_t _0x260; uint32_t _0x264; @@ -179,35 +192,36 @@ typedef struct { uint32_t _0x270; uint32_t _0x274; uint32_t _0x278; - uint32_t _0x27C; + uint32_t FUSE_SPARE_REALIGNMENT_REG; uint32_t FUSE_SPARE_BIT[0x20]; } tegra_fuse_chip_t; -static inline volatile tegra_fuse_t *fuse_get_regs(void) { +static inline volatile tegra_fuse_t *fuse_get_regs(void) +{ return (volatile tegra_fuse_t *)FUSE_BASE; } -static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) { +static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) +{ return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE; } void fuse_init(void); - -uint32_t fuse_hw_read(uint32_t addr); -void fuse_hw_write(uint32_t value, uint32_t addr); -void fuse_hw_sense(void); void fuse_disable_programming(void); -void fuse_secondary_private_key_disable(void); +void fuse_disable_private_key(void); uint32_t fuse_get_sku_info(void); uint32_t fuse_get_spare_bit(uint32_t idx); uint32_t fuse_get_reserved_odm(uint32_t idx); - uint32_t fuse_get_bootrom_patch_version(void); uint64_t fuse_get_device_id(void); uint32_t fuse_get_dram_id(void); -uint32_t fuse_get_hardware_type(void); +uint32_t fuse_get_hardware_type(uint32_t mkey_rev); uint32_t fuse_get_retail_type(void); void fuse_get_hardware_info(void *dst); +uint32_t fuse_hw_read(uint32_t addr); +void fuse_hw_write(uint32_t value, uint32_t addr); +void fuse_hw_sense(void); + #endif diff --git a/fusee/fusee-mtc/src/pmc.h b/fusee/fusee-mtc/src/pmc.h new file mode 100644 index 000000000..f3a4f9379 --- /dev/null +++ b/fusee/fusee-mtc/src/pmc.h @@ -0,0 +1,626 @@ +/* + * Copyright (c) 2018-2019 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 . + */ + +#ifndef FUSEE_PMC_H +#define FUSEE_PMC_H + +#include + +#define PMC_BASE 0x7000E400 +#define MAKE_PMC_REG(n) MAKE_REG32(PMC_BASE + n) + +#define PMC_CONTROL_SDMMC1 (1 << 12) +#define PMC_CONTROL_SDMMC3 (1 << 13) +#define PMC_CONTROL_SDMMC4 (1 << 14) + +#define APBDEV_PMC_CONTROL MAKE_PMC_REG(0x00) +#define APBDEV_PM_0 MAKE_PMC_REG(0x14) +#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x24) +#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x30) +#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x38) +#define APBDEV_PMC_NO_IOPOWER_0 MAKE_PMC_REG(0x44) +#define APBDEV_PMC_SCRATCH0_0 MAKE_PMC_REG(0x50) +#define APBDEV_PMC_SCRATCH1_0 MAKE_PMC_REG(0x54) +#define APBDEV_PMC_SCRATCH20_0 MAKE_PMC_REG(0xA0) +#define APBDEV_PMC_PWR_DET_VAL_0 MAKE_PMC_REG(0xE4) +#define APBDEV_PMC_DDR_PWR_0 MAKE_PMC_REG(0xE8) +#define APBDEV_PMC_CRYPTO_OP_0 MAKE_PMC_REG(0xF4) +#define APBDEV_PMC_WAKE2_STATUS_0 MAKE_PMC_REG(0x168) +#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4) +#define APBDEV_PMC_RST_STATUS_0 MAKE_PMC_REG(0x1B4) +#define APBDEV_PMC_IO_DPD_REQ_0 MAKE_PMC_REG(0x1B8) +#define APBDEV_PMC_IO_DPD2_REQ_0 MAKE_PMC_REG(0x1C0) +#define APBDEV_PMC_VDDP_SEL_0 MAKE_PMC_REG(0x1CC) +#define APBDEV_PMC_SCRATCH49_0 MAKE_PMC_REG(0x244) +#define APBDEV_PMC_TSC_MULT_0 MAKE_PMC_REG(0x2B4) +#define APBDEV_PMC_REG_SHORT_0 MAKE_PMC_REG(0x2CC) +#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8) +#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334) +#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360) +#define APBDEV_PMC_SECURE_SCRATCH49_0 MAKE_PMC_REG(0x3A4) +#define APBDEV_PMC_CNTRL2_0 MAKE_PMC_REG(0x440) +#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464) +#define APBDEV_PMC_UTMIP_PAD_CFG1_0 MAKE_PMC_REG(0x4C4) +#define APBDEV_PMC_UTMIP_PAD_CFG3_0 MAKE_PMC_REG(0x4CC) +#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4) +#define APBDEV_PMC_SCRATCH43_0 MAKE_PMC_REG(0x22C) +#define APBDEV_PMC_SCRATCH188_0 MAKE_PMC_REG(0x810) +#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818) +#define APBDEV_PMC_SCRATCH200_0 MAKE_PMC_REG(0x840) + +#define APBDEV_PMC_SCRATCH45_0 MAKE_PMC_REG(0x234) +#define APBDEV_PMC_SCRATCH46_0 MAKE_PMC_REG(0x238) +#define APBDEV_PMC_SCRATCH33_0 MAKE_PMC_REG(0x120) +#define APBDEV_PMC_SCRATCH40_0 MAKE_PMC_REG(0x13C) + +typedef struct { + uint32_t cntrl; + uint32_t sec_disable; + uint32_t pmc_swrst; + uint32_t wake_mask; + uint32_t wake_lvl; + uint32_t wake_status; + uint32_t sw_wake_status; + uint32_t dpd_pads_oride; + uint32_t dpd_sample; + uint32_t dpd_enable; + uint32_t pwrgate_timer_off; + uint32_t clamp_status; + uint32_t pwrgate_toggle; + uint32_t remove_clamping; + uint32_t pwrgate_status; + uint32_t pwrgood_timer; + uint32_t blink_timer; + uint32_t no_iopower; + uint32_t pwr_det; + uint32_t pwr_det_latch; + uint32_t scratch0; + uint32_t scratch1; + uint32_t scratch2; + uint32_t scratch3; + uint32_t scratch4; + uint32_t scratch5; + uint32_t scratch6; + uint32_t scratch7; + uint32_t scratch8; + uint32_t scratch9; + uint32_t scratch10; + uint32_t scratch11; + uint32_t scratch12; + uint32_t scratch13; + uint32_t scratch14; + uint32_t scratch15; + uint32_t scratch16; + uint32_t scratch17; + uint32_t scratch18; + uint32_t scratch19; + uint32_t scratch20; + uint32_t scratch21; + uint32_t scratch22; + uint32_t scratch23; + uint32_t secure_scratch0; + uint32_t secure_scratch1; + uint32_t secure_scratch2; + uint32_t secure_scratch3; + uint32_t secure_scratch4; + uint32_t secure_scratch5; + uint32_t cpupwrgood_timer; + uint32_t cpupwroff_timer; + uint32_t pg_mask; + uint32_t pg_mask_1; + uint32_t auto_wake_lvl; + uint32_t auto_wake_lvl_mask; + uint32_t wake_delay; + uint32_t pwr_det_val; + uint32_t ddr_pwr; + uint32_t usb_debounce_del; + uint32_t usb_ao; + uint32_t crypto_op; + uint32_t pllp_wb0_override; + uint32_t scratch24; + uint32_t scratch25; + uint32_t scratch26; + uint32_t scratch27; + uint32_t scratch28; + uint32_t scratch29; + uint32_t scratch30; + uint32_t scratch31; + uint32_t scratch32; + uint32_t scratch33; + uint32_t scratch34; + uint32_t scratch35; + uint32_t scratch36; + uint32_t scratch37; + uint32_t scratch38; + uint32_t scratch39; + uint32_t scratch40; + uint32_t scratch41; + uint32_t scratch42; + uint32_t bo_mirror0; + uint32_t bo_mirror1; + uint32_t bo_mirror2; + uint32_t sys_33v_en; + uint32_t bo_mirror_access; + uint32_t gate; + uint32_t wake2_mask; + uint32_t wake2_lvl; + uint32_t wake2_stat; + uint32_t sw_wake2_stat; + uint32_t auto_wake2_lvl_mask; + uint32_t pg_mask2; + uint32_t pg_mask_ce1; + uint32_t pg_mask_ce2; + uint32_t pg_mask_ce3; + uint32_t pwrgate_timer_ce0; + uint32_t pwrgate_timer_ce1; + uint32_t pwrgate_timer_ce2; + uint32_t pwrgate_timer_ce3; + uint32_t pwrgate_timer_ce4; + uint32_t pwrgate_timer_ce5; + uint32_t pwrgate_timer_ce6; + uint32_t pcx_edpd_cntrl; + uint32_t osc_edpd_over; + uint32_t clk_out_cntrl; + uint32_t sata_pwrgate; + uint32_t sensor_ctrl; + uint32_t reset_status; + uint32_t io_dpd_req; + uint32_t io_dpd_stat; + uint32_t io_dpd2_req; + uint32_t io_dpd2_stat; + uint32_t sel_dpd_tim; + uint32_t vddp_sel; + uint32_t ddr_cfg; + uint32_t e_no_vttgen; + uint32_t _reserved0; + uint32_t pllm_wb0_ovrride_frq; + uint32_t test_pwrgate; + uint32_t pwrgate_timer_mult; + uint32_t dsi_sel_dpd; + uint32_t utmip_uhsic_triggers; + uint32_t utmip_uhsic_saved_st; + uint32_t utmip_pad_cfg; + uint32_t utmip_term_pad_cfg; + uint32_t utmip_uhsic_sleep_cfg; + uint32_t utmip_uhsic_sleepwalk_cfg; + uint32_t utmip_sleepwalk_p[3]; + uint32_t uhsic_sleepwalk_p0; + uint32_t utmip_uhsic_status; + uint32_t utmip_uhsic_fake; + uint32_t bo_mirror3[2]; + uint32_t secure_scratch6; + uint32_t secure_scratch7; + uint32_t scratch43; + uint32_t scratch44; + uint32_t scratch45; + uint32_t scratch46; + uint32_t scratch47; + uint32_t scratch48; + uint32_t scratch49; + uint32_t scratch50; + uint32_t scratch51; + uint32_t scratch52; + uint32_t scratch53; + uint32_t scratch54; + uint32_t scratch55; + uint32_t scratch0_eco; + uint32_t por_dpd_ctrl; + uint32_t scratch2_eco; + uint32_t utmip_uhsic_line_wakeup; + uint32_t utmip_bias_master_cntrl; + uint32_t utmip_master_config; + uint32_t td_pwrgate_inter_part_timer; + uint32_t utmip_uhsic2_triggers; + uint32_t utmip_uhsic2_saved_state; + uint32_t utmip_uhsic2_sleep_cfg; + uint32_t utmip_uhsic2_sleepwalk_cfg; + uint32_t uhsic2_sleepwalk_p1; + uint32_t utmip_uhsic2_status; + uint32_t utmip_uhsic2_fake; + uint32_t utmip_uhsic2_line_wakeup; + uint32_t utmip_master2_config; + uint32_t utmip_uhsic_rpd_cfg; + uint32_t pg_mask_ce0; + uint32_t pg_mask3[2]; + uint32_t pllm_wb0_override2; + uint32_t tsc_mult; + uint32_t cpu_vsense_override; + uint32_t glb_amap_cfg; + uint32_t sticky_bits; + uint32_t sec_disable2; + uint32_t weak_bias; + uint32_t reg_short; + uint32_t pg_mask_andor; + uint32_t _reserved1[11]; + uint32_t secure_scratch8; + uint32_t secure_scratch9; + uint32_t secure_scratch10; + uint32_t secure_scratch11; + uint32_t secure_scratch12; + uint32_t secure_scratch13; + uint32_t secure_scratch14; + uint32_t secure_scratch15; + uint32_t secure_scratch16; + uint32_t secure_scratch17; + uint32_t secure_scratch18; + uint32_t secure_scratch19; + uint32_t secure_scratch20; + uint32_t secure_scratch21; + uint32_t secure_scratch22; + uint32_t secure_scratch23; + uint32_t secure_scratch24; + uint32_t secure_scratch25; + uint32_t secure_scratch26; + uint32_t secure_scratch27; + uint32_t secure_scratch28; + uint32_t secure_scratch29; + uint32_t secure_scratch30; + uint32_t secure_scratch31; + uint32_t secure_scratch32; + uint32_t secure_scratch33; + uint32_t secure_scratch34; + uint32_t secure_scratch35; + uint32_t secure_scratch36; + uint32_t secure_scratch37; + uint32_t secure_scratch38; + uint32_t secure_scratch39; + uint32_t secure_scratch40; + uint32_t secure_scratch41; + uint32_t secure_scratch42; + uint32_t secure_scratch43; + uint32_t secure_scratch44; + uint32_t secure_scratch45; + uint32_t secure_scratch46; + uint32_t secure_scratch47; + uint32_t secure_scratch48; + uint32_t secure_scratch49; + uint32_t secure_scratch50; + uint32_t secure_scratch51; + uint32_t secure_scratch52; + uint32_t secure_scratch53; + uint32_t secure_scratch54; + uint32_t secure_scratch55; + uint32_t secure_scratch56; + uint32_t secure_scratch57; + uint32_t secure_scratch58; + uint32_t secure_scratch59; + uint32_t secure_scratch60; + uint32_t secure_scratch61; + uint32_t secure_scratch62; + uint32_t secure_scratch63; + uint32_t secure_scratch64; + uint32_t secure_scratch65; + uint32_t secure_scratch66; + uint32_t secure_scratch67; + uint32_t secure_scratch68; + uint32_t secure_scratch69; + uint32_t secure_scratch70; + uint32_t secure_scratch71; + uint32_t secure_scratch72; + uint32_t secure_scratch73; + uint32_t secure_scratch74; + uint32_t secure_scratch75; + uint32_t secure_scratch76; + uint32_t secure_scratch77; + uint32_t secure_scratch78; + uint32_t secure_scratch79; + uint32_t _reserved2[8]; + uint32_t cntrl2; + uint32_t _reserved3[2]; + uint32_t event_counter; + uint32_t fuse_control; + uint32_t scratch1_eco; + uint32_t _reserved4; + uint32_t io_dpd3_req; + uint32_t io_dpd3_status; + uint32_t io_dpd4_req; + uint32_t io_dpd4_status; + uint32_t _reserved5[30]; + uint32_t ddr_cntrl; + uint32_t _reserved6[70]; + uint32_t scratch56; + uint32_t scratch57; + uint32_t scratch58; + uint32_t scratch59; + uint32_t scratch60; + uint32_t scratch61; + uint32_t scratch62; + uint32_t scratch63; + uint32_t scratch64; + uint32_t scratch65; + uint32_t scratch66; + uint32_t scratch67; + uint32_t scratch68; + uint32_t scratch69; + uint32_t scratch70; + uint32_t scratch71; + uint32_t scratch72; + uint32_t scratch73; + uint32_t scratch74; + uint32_t scratch75; + uint32_t scratch76; + uint32_t scratch77; + uint32_t scratch78; + uint32_t scratch79; + uint32_t scratch80; + uint32_t scratch81; + uint32_t scratch82; + uint32_t scratch83; + uint32_t scratch84; + uint32_t scratch85; + uint32_t scratch86; + uint32_t scratch87; + uint32_t scratch88; + uint32_t scratch89; + uint32_t scratch90; + uint32_t scratch91; + uint32_t scratch92; + uint32_t scratch93; + uint32_t scratch94; + uint32_t scratch95; + uint32_t scratch96; + uint32_t scratch97; + uint32_t scratch98; + uint32_t scratch99; + uint32_t scratch100; + uint32_t scratch101; + uint32_t scratch102; + uint32_t scratch103; + uint32_t scratch104; + uint32_t scratch105; + uint32_t scratch106; + uint32_t scratch107; + uint32_t scratch108; + uint32_t scratch109; + uint32_t scratch110; + uint32_t scratch111; + uint32_t scratch112; + uint32_t scratch113; + uint32_t scratch114; + uint32_t scratch115; + uint32_t scratch116; + uint32_t scratch117; + uint32_t scratch118; + uint32_t scratch119; + uint32_t scratch120; + uint32_t scratch121; + uint32_t scratch122; + uint32_t scratch123; + uint32_t scratch124; + uint32_t scratch125; + uint32_t scratch126; + uint32_t scratch127; + uint32_t scratch128; + uint32_t scratch129; + uint32_t scratch130; + uint32_t scratch131; + uint32_t scratch132; + uint32_t scratch133; + uint32_t scratch134; + uint32_t scratch135; + uint32_t scratch136; + uint32_t scratch137; + uint32_t scratch138; + uint32_t scratch139; + uint32_t scratch140; + uint32_t scratch141; + uint32_t scratch142; + uint32_t scratch143; + uint32_t scratch144; + uint32_t scratch145; + uint32_t scratch146; + uint32_t scratch147; + uint32_t scratch148; + uint32_t scratch149; + uint32_t scratch150; + uint32_t scratch151; + uint32_t scratch152; + uint32_t scratch153; + uint32_t scratch154; + uint32_t scratch155; + uint32_t scratch156; + uint32_t scratch157; + uint32_t scratch158; + uint32_t scratch159; + uint32_t scratch160; + uint32_t scratch161; + uint32_t scratch162; + uint32_t scratch163; + uint32_t scratch164; + uint32_t scratch165; + uint32_t scratch166; + uint32_t scratch167; + uint32_t scratch168; + uint32_t scratch169; + uint32_t scratch170; + uint32_t scratch171; + uint32_t scratch172; + uint32_t scratch173; + uint32_t scratch174; + uint32_t scratch175; + uint32_t scratch176; + uint32_t scratch177; + uint32_t scratch178; + uint32_t scratch179; + uint32_t scratch180; + uint32_t scratch181; + uint32_t scratch182; + uint32_t scratch183; + uint32_t scratch184; + uint32_t scratch185; + uint32_t scratch186; + uint32_t scratch187; + uint32_t scratch188; + uint32_t scratch189; + uint32_t scratch190; + uint32_t scratch191; + uint32_t scratch192; + uint32_t scratch193; + uint32_t scratch194; + uint32_t scratch195; + uint32_t scratch196; + uint32_t scratch197; + uint32_t scratch198; + uint32_t scratch199; + uint32_t scratch200; + uint32_t scratch201; + uint32_t scratch202; + uint32_t scratch203; + uint32_t scratch204; + uint32_t scratch205; + uint32_t scratch206; + uint32_t scratch207; + uint32_t scratch208; + uint32_t scratch209; + uint32_t scratch210; + uint32_t scratch211; + uint32_t scratch212; + uint32_t scratch213; + uint32_t scratch214; + uint32_t scratch215; + uint32_t scratch216; + uint32_t scratch217; + uint32_t scratch218; + uint32_t scratch219; + uint32_t scratch220; + uint32_t scratch221; + uint32_t scratch222; + uint32_t scratch223; + uint32_t scratch224; + uint32_t scratch225; + uint32_t scratch226; + uint32_t scratch227; + uint32_t scratch228; + uint32_t scratch229; + uint32_t scratch230; + uint32_t scratch231; + uint32_t scratch232; + uint32_t scratch233; + uint32_t scratch234; + uint32_t scratch235; + uint32_t scratch236; + uint32_t scratch237; + uint32_t scratch238; + uint32_t scratch239; + uint32_t scratch240; + uint32_t scratch241; + uint32_t scratch242; + uint32_t scratch243; + uint32_t scratch244; + uint32_t scratch245; + uint32_t scratch246; + uint32_t scratch247; + uint32_t scratch248; + uint32_t scratch249; + uint32_t scratch250; + uint32_t scratch251; + uint32_t scratch252; + uint32_t scratch253; + uint32_t scratch254; + uint32_t scratch255; + uint32_t scratch256; + uint32_t scratch257; + uint32_t scratch258; + uint32_t scratch259; + uint32_t scratch260; + uint32_t scratch261; + uint32_t scratch262; + uint32_t scratch263; + uint32_t scratch264; + uint32_t scratch265; + uint32_t scratch266; + uint32_t scratch267; + uint32_t scratch268; + uint32_t scratch269; + uint32_t scratch270; + uint32_t scratch271; + uint32_t scratch272; + uint32_t scratch273; + uint32_t scratch274; + uint32_t scratch275; + uint32_t scratch276; + uint32_t scratch277; + uint32_t scratch278; + uint32_t scratch279; + uint32_t scratch280; + uint32_t scratch281; + uint32_t scratch282; + uint32_t scratch283; + uint32_t scratch284; + uint32_t scratch285; + uint32_t scratch286; + uint32_t scratch287; + uint32_t scratch288; + uint32_t scratch289; + uint32_t scratch290; + uint32_t scratch291; + uint32_t scratch292; + uint32_t scratch293; + uint32_t scratch294; + uint32_t scratch295; + uint32_t scratch296; + uint32_t scratch297; + uint32_t scratch298; + uint32_t scratch299; + uint32_t _reserved7[50]; + uint32_t secure_scratch80; + uint32_t secure_scratch81; + uint32_t secure_scratch82; + uint32_t secure_scratch83; + uint32_t secure_scratch84; + uint32_t secure_scratch85; + uint32_t secure_scratch86; + uint32_t secure_scratch87; + uint32_t secure_scratch88; + uint32_t secure_scratch89; + uint32_t secure_scratch90; + uint32_t secure_scratch91; + uint32_t secure_scratch92; + uint32_t secure_scratch93; + uint32_t secure_scratch94; + uint32_t secure_scratch95; + uint32_t secure_scratch96; + uint32_t secure_scratch97; + uint32_t secure_scratch98; + uint32_t secure_scratch99; + uint32_t secure_scratch100; + uint32_t secure_scratch101; + uint32_t secure_scratch102; + uint32_t secure_scratch103; + uint32_t secure_scratch104; + uint32_t secure_scratch105; + uint32_t secure_scratch106; + uint32_t secure_scratch107; + uint32_t secure_scratch108; + uint32_t secure_scratch109; + uint32_t secure_scratch110; + uint32_t secure_scratch111; + uint32_t secure_scratch112; + uint32_t secure_scratch113; + uint32_t secure_scratch114; + uint32_t secure_scratch115; + uint32_t secure_scratch116; + uint32_t secure_scratch117; + uint32_t secure_scratch118; + uint32_t secure_scratch119; +} tegra_pmc_t; + +static inline volatile tegra_pmc_t *pmc_get_regs(void) +{ + return (volatile tegra_pmc_t *)PMC_BASE; +} + +#endif diff --git a/fusee/fusee-primary/src/fuse.c b/fusee/fusee-primary/src/fuse.c index 1bfe3334c..dc0d2b41f 100644 --- a/fusee/fusee-primary/src/fuse.c +++ b/fusee/fusee-primary/src/fuse.c @@ -20,214 +20,216 @@ #include "car.h" #include "fuse.h" +#include "pmc.h" #include "timers.h" /* Prototypes for internal commands. */ -void fuse_make_regs_visible(void); - void fuse_enable_power(void); void fuse_disable_power(void); void fuse_wait_idle(void); /* Initialize the fuse driver */ void fuse_init(void) { - fuse_make_regs_visible(); - fuse_secondary_private_key_disable(); - fuse_disable_programming(); - - /* TODO: Overrides (iROM patches) and various reads happen here */ -} - -/* Make all fuse registers visible */ -void fuse_make_regs_visible(void) { + /* Make all fuse registers visible, disable the private key and disable programming. */ clkrst_enable_fuse_regs(true); + fuse_disable_private_key(); + fuse_disable_programming(); } -/* Enable power to the fuse hardware array */ +/* Disable access to the private key and set the TZ sticky bit. */ +void fuse_disable_private_key(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_PRIVATEKEYDISABLE = 0x10; +} + +/* Disables all fuse programming. */ +void fuse_disable_programming(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_DISABLEREGPROGRAM = 1; +} + +/* Enable power to the fuse hardware array. */ void fuse_enable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 1; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */ + mdelay(1); + pmc->fuse_control |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */ + mdelay(1); } -/* Disable power to the fuse hardware array */ +/* Disable power to the fuse hardware array. */ void fuse_disable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 0; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */ + mdelay(1); + pmc->fuse_control |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */ + mdelay(1); } -/* Wait for the fuse driver to go idle */ +/* Wait for the fuse driver to go idle. */ void fuse_wait_idle(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); uint32_t ctrl_val = 0; /* Wait for STATE_IDLE */ while ((ctrl_val & (0xF0000)) != 0x40000) - { - udelay(1); - ctrl_val = fuse->FUSE_CTRL; - } + ctrl_val = fuse->FUSE_FUSECTRL; } -/* Read a fuse from the hardware array */ +/* Read a fuse from the hardware array. */ uint32_t fuse_hw_read(uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address */ - fuse->FUSE_REG_ADDR = addr; + /* Program the target address. */ + fuse->FUSE_FUSEADDR = addr; - /* Enable read operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable read operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x1; /* Set FUSE_READ command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x1; /* Set READ command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); - return fuse->FUSE_REG_READ; + return fuse->FUSE_FUSERDATA; } -/* Write a fuse in the hardware array */ +/* Write a fuse in the hardware array. */ void fuse_hw_write(uint32_t value, uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address and value */ - fuse->FUSE_REG_ADDR = addr; - fuse->FUSE_REG_WRITE = value; + /* Program the target address and value. */ + fuse->FUSE_FUSEADDR = addr; + fuse->FUSE_FUSEWDATA = value; - /* Enable write operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable write operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x2; /* Set FUSE_WRITE command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x2; /* Set WRITE command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); } -/* Sense the fuse hardware array into the shadow cache */ +/* Sense the fuse hardware array into the shadow cache. */ void fuse_hw_sense(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); /* Enable sense operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x3; /* Set FUSE_SENSE command */ - fuse->FUSE_CTRL = ctrl_val; - + ctrl_val |= 0x3; /* Set SENSE_CTRL command */ + fuse->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ fuse_wait_idle(); } -/* Disables all fuse programming. */ -void fuse_disable_programming(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_DIS_PGM = 1; -} - -/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */ -void fuse_secondary_private_key_disable(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PRIVATEKEYDISABLE = 0x10; -} - - -/* Read the SKU info register from the shadow cache */ +/* Read the SKU info register from the shadow cache. */ uint32_t fuse_get_sku_info(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); return fuse_chip->FUSE_SKU_INFO; } -/* Read the bootrom patch version from a register in the shadow cache */ +/* Read the bootrom patch version from a register in the shadow cache. */ uint32_t fuse_get_bootrom_patch_version(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return fuse_chip->FUSE_SOC_SPEEDO_1; + return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB; } /* Read a spare bit register from the shadow cache */ uint32_t fuse_get_spare_bit(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 32) { + if (idx < 32) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_SPARE_BIT[idx]; + } else { return 0; } - - return fuse_chip->FUSE_SPARE_BIT[idx]; } -/* Read a reserved ODM register from the shadow cache */ +/* Read a reserved ODM register from the shadow cache. */ uint32_t fuse_get_reserved_odm(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 8) { + if (idx < 8) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_RESERVED_ODM[idx]; + } else { return 0; } - - return fuse_chip->FUSE_RESERVED_ODM[idx]; } -/* Derive the Device ID using values in the shadow cache */ +/* Get the DRAM ID using values in the shadow cache. */ +uint32_t fuse_get_dram_id(void) { + return ((fuse_get_reserved_odm(4) >> 3) & 0x7); +} + +/* Derive the Device ID using values in the shadow cache. */ uint64_t fuse_get_device_id(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint64_t device_id = 0; - uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0; - uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; + uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint64_t derived_lot_code = 0; for (unsigned int i = 0; i < 5; i++) { derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F); } derived_lot_code &= 0x03FFFFFF; - + device_id |= y_coord << 0; device_id |= x_coord << 9; device_id |= wafer_id << 18; device_id |= derived_lot_code << 24; device_id |= fab_code << 50; + return device_id; } -/* Get the DRAM ID using values in the shadow cache */ -uint32_t fuse_get_dram_id(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7; -} - -/* Derive the Hardware Type using values in the shadow cache */ -uint32_t fuse_get_hardware_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); +/* Derive the Hardware Type using values in the shadow cache. */ +uint32_t fuse_get_hardware_type(uint32_t mkey_rev) { + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1)); - /* This function is very different between 4.x and < 4.x */ - uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1); - - /* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) { - static const uint32_t types[] = {0,1,4,3}; - - hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C; - hardware_type--; - return hardware_type > 3 ? 4 : types[hardware_type]; - } else {*/ + /* Firmware from versions 1.0.0 to 3.0.2. */ + if (mkey_rev < 0x03) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); if (hardware_type >= 1) { - return hardware_type > 2 ? 3 : hardware_type - 1; + return (hardware_type > 2) ? 3 : hardware_type - 1; } else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) { return 0; } else { return 3; } -// } + } else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */ + static const uint32_t types[] = {0,1,4,3}; + hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C); + hardware_type--; + return (hardware_type > 3) ? 4 : types[hardware_type]; + } else { /* Firmware versions from 7.0.0 onwards. */ + /* Always return 0 in retail. */ + return 0; + } } -/* Derive the Retail Type using values in the shadow cache */ +/* Derive the Retail Type using values in the shadow cache. */ uint32_t fuse_get_retail_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - /* Retail type = IS_RETAIL | UNIT_TYPE */ - uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3); + /* Retail Type = IS_RETAIL | UNIT_TYPE. */ + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3)); if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */ return 1; } else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */ @@ -241,17 +243,17 @@ void fuse_get_hardware_info(void *dst) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint32_t hw_info[0x4]; - uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F; - uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0; - uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF; - uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; - uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF; + uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F; + uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF; + uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF; - /* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ - hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse)); + /* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ + hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved)); hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2)); hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6)); hw_info[3] = (uint32_t)(vendor_code); diff --git a/fusee/fusee-primary/src/fuse.h b/fusee/fusee-primary/src/fuse.h index 9d92503e2..d118b53dc 100644 --- a/fusee/fusee-primary/src/fuse.h +++ b/fusee/fusee-primary/src/fuse.h @@ -23,154 +23,167 @@ #define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n) typedef struct { - uint32_t FUSE_CTRL; - uint32_t FUSE_REG_ADDR; - uint32_t FUSE_REG_READ; - uint32_t FUSE_REG_WRITE; - uint32_t FUSE_TIME_RD1; - uint32_t FUSE_TIME_RD2; - uint32_t FUSE_TIME_PGM1; - uint32_t FUSE_TIME_PGM2; - uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSECTRL; + uint32_t FUSE_FUSEADDR; + uint32_t FUSE_FUSERDATA; + uint32_t FUSE_FUSEWDATA; + uint32_t FUSE_FUSETIME_RD1; + uint32_t FUSE_FUSETIME_RD2; + uint32_t FUSE_FUSETIME_PGM1; + uint32_t FUSE_FUSETIME_PGM2; + uint32_t FUSE_PRIV2INTFC_START; uint32_t FUSE_FUSEBYPASS; uint32_t FUSE_PRIVATEKEYDISABLE; - uint32_t FUSE_DIS_PGM; - uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_DISABLEREGPROGRAM; + uint32_t FUSE_WRITE_ACCESS_SW; uint32_t FUSE_PWR_GOOD_SW; - uint32_t _0x38[0x32]; + uint32_t _0x38; + uint32_t FUSE_PRIV2RESHIFT; + uint32_t _0x40[0x3]; + uint32_t FUSE_FUSETIME_RD3; + uint32_t _0x50[0xC]; + uint32_t FUSE_PRIVATE_KEY0_NONZERO; + uint32_t FUSE_PRIVATE_KEY1_NONZERO; + uint32_t FUSE_PRIVATE_KEY2_NONZERO; + uint32_t FUSE_PRIVATE_KEY3_NONZERO; + uint32_t FUSE_PRIVATE_KEY4_NONZERO; + uint32_t _0x90[0x1C]; } tegra_fuse_t; typedef struct { uint32_t FUSE_PRODUCTION_MODE; - uint32_t _0x4; - uint32_t _0x8; - uint32_t _0xC; + uint32_t FUSE_JTAG_SECUREID_VALID; + uint32_t FUSE_ODM_LOCK; + uint32_t FUSE_OPT_OPENGL_EN; uint32_t FUSE_SKU_INFO; - uint32_t FUSE_CPU_SPEEDO_0; - uint32_t FUSE_CPU_IDDQ; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t _0x24; - uint32_t FUSE_FT_REV; - uint32_t FUSE_CPU_SPEEDO_1; - uint32_t FUSE_CPU_SPEEDO_2; - uint32_t FUSE_SOC_SPEEDO_0; - uint32_t FUSE_SOC_SPEEDO_1; - uint32_t FUSE_SOC_SPEEDO_2; - uint32_t FUSE_SOC_IDDQ; - uint32_t _0x44; + uint32_t FUSE_CPU_SPEEDO_0_CALIB; + uint32_t FUSE_CPU_IDDQ_CALIB; + uint32_t FUSE_DAC_CRT_CALIB; + uint32_t FUSE_DAC_HDTV_CALIB; + uint32_t FUSE_DAC_SDTV_CALIB; + uint32_t FUSE_OPT_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1_CALIB; + uint32_t FUSE_CPU_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_SPEEDO_0_CALIB; + uint32_t FUSE_SOC_SPEEDO_1_CALIB; + uint32_t FUSE_SOC_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_IDDQ_CALIB; + uint32_t FUSE_RESERVED_PRODUCTION_WP; uint32_t FUSE_FA; - uint32_t _0x4C; - uint32_t _0x50; - uint32_t _0x54; - uint32_t _0x58; - uint32_t _0x5C; - uint32_t _0x60; + uint32_t FUSE_RESERVED_PRODUCTION; + uint32_t FUSE_HDMI_LANE0_CALIB; + uint32_t FUSE_HDMI_LANE1_CALIB; + uint32_t FUSE_HDMI_LANE2_CALIB; + uint32_t FUSE_HDMI_LANE3_CALIB; + uint32_t FUSE_ENCRYPTION_RATE; uint32_t FUSE_PUBLIC_KEY[0x8]; - uint32_t FUSE_TSENSOR_1; - uint32_t FUSE_TSENSOR_2; - uint32_t _0x8C; - uint32_t FUSE_CP_REV; - uint32_t _0x94; - uint32_t FUSE_TSENSOR_0; - uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_TSENSOR1_CALIB; + uint32_t FUSE_TSENSOR2_CALIB; + uint32_t FUSE_VSENSOR_CALIB; + uint32_t FUSE_OPT_CP_REV; + uint32_t FUSE_OPT_PFG; + uint32_t FUSE_TSENSOR0_CALIB; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; - uint32_t FUSE_PRIVATE_KEY[0x4]; - uint32_t FUSE_DEVICE_KEY; - uint32_t _0xB8; - uint32_t _0xBC; + uint32_t FUSE_PRIVATE_KEY[0x5]; + uint32_t FUSE_ARM_JTAG_DIS; + uint32_t FUSE_BOOT_DEVICE_INFO; uint32_t FUSE_RESERVED_SW; - uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_OPT_VP9_DISABLE; uint32_t FUSE_RESERVED_ODM[0x8]; - uint32_t _0xE8; - uint32_t _0xEC; - uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_OBS_DIS; + uint32_t FUSE_NOR_INFO; + uint32_t FUSE_USB_CALIB; uint32_t FUSE_SKU_DIRECT_CONFIG; - uint32_t _0xF8; - uint32_t _0xFC; - uint32_t FUSE_VENDOR_CODE; - uint32_t FUSE_FAB_CODE; - uint32_t FUSE_LOT_CODE_0; - uint32_t FUSE_LOT_CODE_1; - uint32_t FUSE_WAFER_ID; - uint32_t FUSE_X_COORDINATE; - uint32_t FUSE_Y_COORDINATE; - uint32_t _0x11C; - uint32_t _0x120; + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; + uint32_t FUSE_PACKAGE_INFO; + uint32_t FUSE_OPT_VENDOR_CODE; + uint32_t FUSE_OPT_FAB_CODE; + uint32_t FUSE_OPT_LOT_CODE_0; + uint32_t FUSE_OPT_LOT_CODE_1; + uint32_t FUSE_OPT_WAFER_ID; + uint32_t FUSE_OPT_X_COORDINATE; + uint32_t FUSE_OPT_Y_COORDINATE; + uint32_t FUSE_OPT_SEC_DEBUG_EN; + uint32_t FUSE_OPT_OPS_RESERVED; uint32_t FUSE_SATA_CALIB; - uint32_t FUSE_GPU_IDDQ; - uint32_t FUSE_TSENSOR_3; - uint32_t _0x130; - uint32_t _0x134; - uint32_t _0x138; - uint32_t _0x13C; - uint32_t _0x140; - uint32_t _0x144; + uint32_t FUSE_GPU_IDDQ_CALIB; + uint32_t FUSE_TSENSOR3_CALIB; + uint32_t FUSE_SKU_BOND_OUT_L; + uint32_t FUSE_SKU_BOND_OUT_H; + uint32_t FUSE_SKU_BOND_OUT_U; + uint32_t FUSE_SKU_BOND_OUT_V; + uint32_t FUSE_SKU_BOND_OUT_W; + uint32_t FUSE_OPT_SAMPLE_TYPE; uint32_t FUSE_OPT_SUBREVISION; - uint32_t _0x14C; - uint32_t _0x150; - uint32_t FUSE_TSENSOR_4; - uint32_t FUSE_TSENSOR_5; - uint32_t FUSE_TSENSOR_6; - uint32_t FUSE_TSENSOR_7; - uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_OPT_SW_RESERVED_0; + uint32_t FUSE_OPT_SW_RESERVED_1; + uint32_t FUSE_TSENSOR4_CALIB; + uint32_t FUSE_TSENSOR5_CALIB; + uint32_t FUSE_TSENSOR6_CALIB; + uint32_t FUSE_TSENSOR7_CALIB; + uint32_t FUSE_OPT_PRIV_SEC_EN; uint32_t FUSE_PKC_DISABLE; uint32_t _0x16C; uint32_t _0x170; uint32_t _0x174; uint32_t _0x178; - uint32_t _0x17C; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; uint32_t FUSE_TSENSOR_COMMON; - uint32_t _0x184; - uint32_t _0x188; - uint32_t _0x18C; - uint32_t _0x190; + uint32_t FUSE_OPT_CP_BIN; + uint32_t FUSE_OPT_GPU_DISABLE; + uint32_t FUSE_OPT_FT_BIN; + uint32_t FUSE_OPT_DONE_MAP; uint32_t _0x194; - uint32_t _0x198; - uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t FUSE_APB2JTAG_DISABLE; + uint32_t FUSE_ODM_INFO; uint32_t _0x1A0; uint32_t _0x1A4; - uint32_t _0x1A8; + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; uint32_t _0x1AC; uint32_t _0x1B0; uint32_t _0x1B4; uint32_t _0x1B8; uint32_t _0x1BC; - uint32_t _0x1D0; - uint32_t FUSE_TSENSOR_8; + uint32_t FUSE_WOA_SKU_FLAG; + uint32_t FUSE_ECO_RESERVE_1; + uint32_t FUSE_GCPLEX_CONFIG_FUSE; + uint32_t FUSE_PRODUCTION_MONTH; + uint32_t FUSE_RAM_REPAIR_INDICATOR; + uint32_t FUSE_TSENSOR9_CALIB; uint32_t _0x1D8; - uint32_t _0x1DC; - uint32_t _0x1E0; - uint32_t _0x1E4; - uint32_t _0x1E8; - uint32_t _0x1EC; - uint32_t _0x1F0; - uint32_t _0x1F4; - uint32_t _0x1F8; + uint32_t FUSE_VMIN_CALIBRATION; + uint32_t FUSE_AGING_SENSOR_CALIBRATION; + uint32_t FUSE_DEBUG_AUTHENTICATION; + uint32_t FUSE_SECURE_PROVISION_INDEX; + uint32_t FUSE_SECURE_PROVISION_INFO; + uint32_t FUSE_OPT_GPU_DISABLE_CP1; + uint32_t FUSE_SPARE_ENDIS; + uint32_t FUSE_ECO_RESERVE_0; uint32_t _0x1FC; uint32_t _0x200; - uint32_t FUSE_RESERVED_CALIB; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t _0x214; - uint32_t _0x218; - uint32_t FUSE_TSENSOR_9; - uint32_t _0x220; - uint32_t _0x224; - uint32_t _0x228; - uint32_t _0x22C; - uint32_t _0x230; - uint32_t _0x234; - uint32_t _0x238; - uint32_t _0x23C; - uint32_t _0x240; - uint32_t _0x244; - uint32_t _0x248; - uint32_t _0x24C; + uint32_t FUSE_RESERVED_CALIB0; + uint32_t FUSE_RESERVED_CALIB1; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1; + uint32_t FUSE_OPT_CPU_DISABLE; + uint32_t FUSE_OPT_CPU_DISABLE_CP1; + uint32_t FUSE_TSENSOR10_CALIB; + uint32_t FUSE_TSENSOR10_CALIB_AUX; + uint32_t FUSE_OPT_RAM_SVOP_DP; + uint32_t FUSE_OPT_RAM_SVOP_PDP; + uint32_t FUSE_OPT_RAM_SVOP_REG; + uint32_t FUSE_OPT_RAM_SVOP_SP; + uint32_t FUSE_OPT_RAM_SVOP_SMPDP; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2; + uint32_t FUSE_OPT_CPU_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_DISABLE_CP2; uint32_t FUSE_USB_CALIB_EXT; - uint32_t _0x254; - uint32_t _0x258; + uint32_t FUSE_RESERVED_FIELD; + uint32_t FUSE_OPT_ECC_EN; uint32_t _0x25C; uint32_t _0x260; uint32_t _0x264; @@ -179,35 +192,36 @@ typedef struct { uint32_t _0x270; uint32_t _0x274; uint32_t _0x278; - uint32_t _0x27C; + uint32_t FUSE_SPARE_REALIGNMENT_REG; uint32_t FUSE_SPARE_BIT[0x20]; } tegra_fuse_chip_t; -static inline volatile tegra_fuse_t *fuse_get_regs(void) { +static inline volatile tegra_fuse_t *fuse_get_regs(void) +{ return (volatile tegra_fuse_t *)FUSE_BASE; } -static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) { +static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) +{ return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE; } void fuse_init(void); - -uint32_t fuse_hw_read(uint32_t addr); -void fuse_hw_write(uint32_t value, uint32_t addr); -void fuse_hw_sense(void); void fuse_disable_programming(void); -void fuse_secondary_private_key_disable(void); +void fuse_disable_private_key(void); uint32_t fuse_get_sku_info(void); uint32_t fuse_get_spare_bit(uint32_t idx); uint32_t fuse_get_reserved_odm(uint32_t idx); - uint32_t fuse_get_bootrom_patch_version(void); uint64_t fuse_get_device_id(void); uint32_t fuse_get_dram_id(void); -uint32_t fuse_get_hardware_type(void); +uint32_t fuse_get_hardware_type(uint32_t mkey_rev); uint32_t fuse_get_retail_type(void); void fuse_get_hardware_info(void *dst); +uint32_t fuse_hw_read(uint32_t addr); +void fuse_hw_write(uint32_t value, uint32_t addr); +void fuse_hw_sense(void); + #endif diff --git a/fusee/fusee-primary/src/hwinit.c b/fusee/fusee-primary/src/hwinit.c index 8e61afbf3..e26f9c54e 100644 --- a/fusee/fusee-primary/src/hwinit.c +++ b/fusee/fusee-primary/src/hwinit.c @@ -162,16 +162,16 @@ void config_se_brom() set_aes_keyslot(0xE, sbk, 0x10); /* Lock SBK from being read. */ - se->AES_KEYSLOT_FLAGS[0xE] = 0x7E; + se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E; /* This memset needs to happen here, else TZRAM will behave weirdly later on. */ memset((void *)0x7C010000, 0, 0x10000); pmc->crypto_op = 0; - se->INT_STATUS_REG = 0x1F; + se->SE_INT_STATUS = 0x1F; /* Lock SSK (although it's not set and unused anyways). */ - se->AES_KEYSLOT_FLAGS[0xF] = 0x7E; + se->SE_CRYPTO_KEYTABLE_ACCESS[0xF] = 0x7E; /* Clear the boot reason to avoid problems later */ pmc->scratch200 = 0; diff --git a/fusee/fusee-primary/src/se.c b/fusee/fusee-primary/src/se.c index 0a22229b0..188176aa7 100644 --- a/fusee/fusee-primary/src/se.c +++ b/fusee/fusee-primary/src/se.c @@ -39,20 +39,20 @@ void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) { } void se_check_error_status_reg(void) { - if (se_get_regs()->ERR_STATUS_REG) { + if (se_get_regs()->SE_ERR_STATUS) { generic_panic(); } } void se_check_for_error(void) { volatile tegra_se_t *se = se_get_regs(); - if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) { + if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) { generic_panic(); } } void se_verify_flags_cleared(void) { - if (se_get_regs()->FLAGS_REG & 3) { + if (se_get_regs()->SE_STATUS & 3) { generic_panic(); } } @@ -67,12 +67,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { - se->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -87,12 +87,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { /* TODO: Why are flags assigned this way? */ - se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -105,8 +105,8 @@ void clear_aes_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -120,13 +120,13 @@ void clear_rsa_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + se->SE_RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = 0; } } @@ -138,8 +138,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { } for (size_t i = 0; i < (key_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = read32le(key, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i); } } @@ -151,13 +151,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_ } for (size_t i = 0; i < (modulus_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; - se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); } for (size_t i = 0; i < (exp_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); } g_se_modulus_sizes[keyslot] = modulus_size; @@ -172,8 +172,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { } for (size_t i = 0; i < (iv_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i); } } @@ -185,14 +185,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) { } for (size_t i = 0; i < (0x10 >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } void set_se_ctr(const void *ctr) { for (unsigned int i = 0; i < 4; i++) { - se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4); } } @@ -203,10 +203,10 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); - se->CRYPTO_REG = keyslot_src << 24; - se->BLOCK_COUNT_REG = 0; - se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; + se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = keyslot_src << 24; + se->SE_CRYPTO_LAST_BLOCK = 0; + se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8; trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); } @@ -224,10 +224,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co stack_buf[i] = *((uint8_t *)src + src_size - i - 1); } - se->CONFIG_REG = (ALG_RSA | DST_RSAREG); - se->RSA_CONFIG = keyslot << 24; - se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + se->SE_CONFIG = (ALG_RSA | DST_RSAREG); + se->SE_RSA_CONFIG = keyslot << 24; + se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1; + se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2; trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size); se_get_exp_mod_output(dst, dst_size); @@ -245,7 +245,7 @@ void se_get_exp_mod_output(void *buf, size_t size) { /* Copy endian swapped output. */ while (num_dwords) { - *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset); + *p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset); offset += 4; p_out--; num_dwords--; @@ -314,15 +314,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v ll_init(&out_ll, dst, dst_size); /* Set the LLs. */ - se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); - se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll); + se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); + se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = op; + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = op; - while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -340,7 +340,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } /* Trigger AES operation. */ - se_get_regs()->BLOCK_COUNT_REG = 0; + se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -358,15 +358,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo unsigned int num_blocks = src_size >> 4; /* Unknown what this write does, but official code writes it for CTR mode. */ - se->SPARE_0 = 1; - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x91E; + se->SE_SPARE = 1; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E; set_se_ctr(ctr); /* Handle any aligned blocks. */ size_t aligned_size = (size_t)num_blocks << 4; if (aligned_size) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size); } @@ -388,8 +388,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - se->CRYPTO_REG = keyslot << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -408,8 +408,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot << 24; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -472,13 +472,13 @@ void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keys /* Encrypt/Decrypt. */ if (encrypt) { - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24 | 0x100; } else { - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24; } - se->BLOCK_COUNT_REG = (size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, size, src, size); /* XOR. */ @@ -524,16 +524,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - se->CRYPTO_REG = (keyslot << 24) | (0x145); + se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - se->BLOCK_COUNT_REG = num_blocks - 2; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2; trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); - se->CRYPTO_REG |= 0x80; + se->SE_CRYPTO_CONFIG |= 0x80; } /* Create final block. */ @@ -550,12 +550,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con } /* Perform last operation. */ - se->BLOCK_COUNT_REG = 0; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2); } } @@ -573,10 +573,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x144; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144; set_aes_keyslot_iv(keyslot, iv, 0x10); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -585,23 +585,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { volatile tegra_se_t *se = se_get_regs(); /* Setup config for SHA256, size = BITS(src_size) */ - se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); - se->SHA_CONFIG_REG = 1; - se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3); - se->_0x208 = 0; - se->_0x20C = 0; - se->_0x210 = 0; - se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3); - se->_0x218 = 0; - se->_0x21C = 0; - se->_0x220 = 0; + se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + se->SE_SHA_CONFIG = 1; + se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LENGTH[1] = 0; + se->SE_SHA_MSG_LENGTH[2] = 0; + se->SE_SHA_MSG_LENGTH[3] = 0; + se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LEFT[1] = 0; + se->SE_SHA_MSG_LEFT[2] = 0; + se->SE_SHA_MSG_LEFT[3] = 0; /* Trigger the operation. */ trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); /* Copy output hash. */ for (unsigned int i = 0; i < (0x20 >> 2); i++) { - ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2); } } @@ -617,12 +617,12 @@ void se_initialize_rng(unsigned int keyslot) { /* This will be discarded, when done. */ uint8_t ALIGN(16) output_buf[0x10]; - se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ - se->RNG_RESEED_INTERVAL_REG = 70001; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 5; - se->BLOCK_COUNT_REG = 0; + se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */ + se->SE_RNG_RESEED_INTERVAL = 70001; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 5; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0); } @@ -635,12 +635,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) { uint32_t num_blocks = size >> 4; size_t aligned_size = num_blocks << 4; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; if (num_blocks >= 1) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0); } if (size > aligned_size) { diff --git a/fusee/fusee-primary/src/se.h b/fusee/fusee-primary/src/se.h index b6ad69866..5e8e46900 100644 --- a/fusee/fusee-primary/src/se.h +++ b/fusee/fusee-primary/src/se.h @@ -92,71 +92,59 @@ #define RSA_2048_BYTES 0x100 typedef struct { - uint32_t _0x0; - uint32_t _0x4; - uint32_t OPERATION_REG; - uint32_t INT_ENABLE_REG; - uint32_t INT_STATUS_REG; - uint32_t CONFIG_REG; - uint32_t IN_LL_ADDR_REG; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t OUT_LL_ADDR_REG; - uint32_t _0x28; - uint32_t _0x2C; - uint8_t HASH_RESULT_REG[0x20]; - uint8_t _0x50[0x20]; - uint32_t CONTEXT_SAVE_CONFIG_REG; - uint8_t _0x74[0x18C]; - uint32_t SHA_CONFIG_REG; - uint32_t SHA_MSG_LENGTH_REG; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t SHA_MSG_LEFT_REG; - uint32_t _0x218; - uint32_t _0x21C; - uint32_t _0x220; - uint32_t _0x224; - uint8_t _0x228[0x58]; - uint32_t AES_KEY_READ_DISABLE_REG; - uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C4[0x3C]; - uint32_t _0x300; - uint32_t CRYPTO_REG; - uint32_t CRYPTO_CTR_REG[4]; - uint32_t BLOCK_COUNT_REG; - uint32_t AES_KEYTABLE_ADDR; - uint32_t AES_KEYTABLE_DATA; - uint32_t _0x324; - uint32_t _0x328; - uint32_t _0x32C; - uint32_t CRYPTO_KEYTABLE_DST_REG; - uint8_t _0x334[0xC]; - uint32_t RNG_CONFIG_REG; - uint32_t RNG_SRC_CONFIG_REG; - uint32_t RNG_RESEED_INTERVAL_REG; - uint8_t _0x34C[0xB4]; - uint32_t RSA_CONFIG; - uint32_t RSA_KEY_SIZE_REG; - uint32_t RSA_EXP_SIZE_REG; - uint32_t RSA_KEY_READ_DISABLE_REG; - uint32_t RSA_KEYSLOT_FLAGS[2]; - uint32_t _0x418; - uint32_t _0x41C; - uint32_t RSA_KEYTABLE_ADDR; - uint32_t RSA_KEYTABLE_DATA; - uint8_t RSA_OUTPUT[0x100]; - uint8_t _0x528[0x2D8]; - uint32_t FLAGS_REG; - uint32_t ERR_STATUS_REG; - uint32_t _0x808; - uint32_t SPARE_0; - uint32_t _0x810; + uint32_t SE_SE_SECURITY; + uint32_t SE_TZRAM_SECURITY; + uint32_t SE_OPERATION; + uint32_t SE_INT_ENABLE; + uint32_t SE_INT_STATUS; + uint32_t SE_CONFIG; + uint32_t SE_IN_LL_ADDR; + uint32_t SE_IN_CUR_BYTE_ADDR; + uint32_t SE_IN_CUR_LL_ID; + uint32_t SE_OUT_LL_ADDR; + uint32_t SE_OUT_CUR_BYTE_ADDR; + uint32_t SE_OUT_CUR_LL_ID; + uint32_t SE_HASH_RESULT[0x10]; + uint32_t SE_CTX_SAVE_CONFIG; + uint32_t _0x74[0x63]; + uint32_t SE_SHA_CONFIG; + uint32_t SE_SHA_MSG_LENGTH[0x4]; + uint32_t SE_SHA_MSG_LEFT[0x4]; + uint32_t _0x224[0x17]; + uint32_t SE_CRYPTO_SECURITY_PERKEY; + uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10]; + uint32_t _0x2C4[0x10]; + uint32_t SE_CRYPTO_CONFIG; + uint32_t SE_CRYPTO_LINEAR_CTR[0x4]; + uint32_t SE_CRYPTO_LAST_BLOCK; + uint32_t SE_CRYPTO_KEYTABLE_ADDR; + uint32_t SE_CRYPTO_KEYTABLE_DATA; + uint32_t _0x324[0x3]; + uint32_t SE_CRYPTO_KEYTABLE_DST; + uint32_t _0x334[0x3]; + uint32_t SE_RNG_CONFIG; + uint32_t SE_RNG_SRC_CONFIG; + uint32_t SE_RNG_RESEED_INTERVAL; + uint32_t _0x34C[0x2D]; + uint32_t SE_RSA_CONFIG; + uint32_t SE_RSA_KEY_SIZE; + uint32_t SE_RSA_EXP_SIZE; + uint32_t SE_RSA_SECURITY_PERKEY; + uint32_t SE_RSA_KEYTABLE_ACCESS[0x2]; + uint32_t _0x418[0x2]; + uint32_t SE_RSA_KEYTABLE_ADDR; + uint32_t SE_RSA_KEYTABLE_DATA; + uint32_t SE_RSA_OUTPUT[0x40]; + uint32_t _0x528[0xB6]; + uint32_t SE_STATUS; + uint32_t SE_ERR_STATUS; + uint32_t SE_MISC; + uint32_t SE_SPARE; + uint32_t SE_ENTROPY_DEBUG_COUNTER; uint32_t _0x814; uint32_t _0x818; uint32_t _0x81C; - uint8_t _0x820[0x17E0]; + uint32_t _0x820[0x5F8]; } tegra_se_t; typedef struct { diff --git a/fusee/fusee-secondary/src/fuse.c b/fusee/fusee-secondary/src/fuse.c index 1bfe3334c..4d4c948fb 100644 --- a/fusee/fusee-secondary/src/fuse.c +++ b/fusee/fusee-secondary/src/fuse.c @@ -20,214 +20,216 @@ #include "car.h" #include "fuse.h" +#include "pmc.h" #include "timers.h" /* Prototypes for internal commands. */ -void fuse_make_regs_visible(void); - void fuse_enable_power(void); void fuse_disable_power(void); void fuse_wait_idle(void); /* Initialize the fuse driver */ void fuse_init(void) { - fuse_make_regs_visible(); - fuse_secondary_private_key_disable(); - fuse_disable_programming(); - - /* TODO: Overrides (iROM patches) and various reads happen here */ -} - -/* Make all fuse registers visible */ -void fuse_make_regs_visible(void) { + /* Make all fuse registers visible, disable the private key and disable programming. */ clkrst_enable_fuse_regs(true); + fuse_disable_private_key(); + fuse_disable_programming(); } -/* Enable power to the fuse hardware array */ +/* Disable access to the private key and set the TZ sticky bit. */ +void fuse_disable_private_key(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_PRIVATEKEYDISABLE = 0x10; +} + +/* Disables all fuse programming. */ +void fuse_disable_programming(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_DISABLEREGPROGRAM = 1; +} + +/* Enable power to the fuse hardware array. */ void fuse_enable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 1; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x200); // Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. + mdelay(1); + pmc->fuse_control |= 0x100; // Set PMC_FUSE_CTRL_PS18_LATCH_SET. + mdelay(1); } -/* Disable power to the fuse hardware array */ +/* Disable power to the fuse hardware array. */ void fuse_disable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 0; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x100); // Clear PMC_FUSE_CTRL_PS18_LATCH_SET. + mdelay(1); + pmc->fuse_control |= 0x200; // Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. + mdelay(1); } -/* Wait for the fuse driver to go idle */ +/* Wait for the fuse driver to go idle. */ void fuse_wait_idle(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); uint32_t ctrl_val = 0; /* Wait for STATE_IDLE */ while ((ctrl_val & (0xF0000)) != 0x40000) - { - udelay(1); - ctrl_val = fuse->FUSE_CTRL; - } + ctrl_val = fuse->FUSE_FUSECTRL; } -/* Read a fuse from the hardware array */ +/* Read a fuse from the hardware array. */ uint32_t fuse_hw_read(uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address */ - fuse->FUSE_REG_ADDR = addr; + /* Program the target address. */ + fuse->FUSE_FUSEADDR = addr; - /* Enable read operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable read operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x1; /* Set FUSE_READ command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x1; /* Set READ command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); - return fuse->FUSE_REG_READ; + return fuse->FUSE_FUSERDATA; } -/* Write a fuse in the hardware array */ +/* Write a fuse in the hardware array. */ void fuse_hw_write(uint32_t value, uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address and value */ - fuse->FUSE_REG_ADDR = addr; - fuse->FUSE_REG_WRITE = value; + /* Program the target address and value. */ + fuse->FUSE_FUSEADDR = addr; + fuse->FUSE_FUSEWDATA = value; - /* Enable write operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable write operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x2; /* Set FUSE_WRITE command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x2; /* Set WRITE command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); } -/* Sense the fuse hardware array into the shadow cache */ +/* Sense the fuse hardware array into the shadow cache. */ void fuse_hw_sense(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); /* Enable sense operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x3; /* Set FUSE_SENSE command */ - fuse->FUSE_CTRL = ctrl_val; - + ctrl_val |= 0x3; /* Set SENSE_CTRL command */ + fuse->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ fuse_wait_idle(); } -/* Disables all fuse programming. */ -void fuse_disable_programming(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_DIS_PGM = 1; -} - -/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */ -void fuse_secondary_private_key_disable(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PRIVATEKEYDISABLE = 0x10; -} - - -/* Read the SKU info register from the shadow cache */ +/* Read the SKU info register from the shadow cache. */ uint32_t fuse_get_sku_info(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); return fuse_chip->FUSE_SKU_INFO; } -/* Read the bootrom patch version from a register in the shadow cache */ +/* Read the bootrom patch version from a register in the shadow cache. */ uint32_t fuse_get_bootrom_patch_version(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return fuse_chip->FUSE_SOC_SPEEDO_1; + return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB; } /* Read a spare bit register from the shadow cache */ uint32_t fuse_get_spare_bit(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 32) { + if (idx < 32) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_SPARE_BIT[idx]; + } else { return 0; } - - return fuse_chip->FUSE_SPARE_BIT[idx]; } -/* Read a reserved ODM register from the shadow cache */ +/* Read a reserved ODM register from the shadow cache. */ uint32_t fuse_get_reserved_odm(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 8) { + if (idx < 8) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_RESERVED_ODM[idx]; + } else { return 0; } - - return fuse_chip->FUSE_RESERVED_ODM[idx]; } -/* Derive the Device ID using values in the shadow cache */ +/* Get the DRAM ID using values in the shadow cache. */ +uint32_t fuse_get_dram_id(void) { + return ((fuse_get_reserved_odm(4) >> 3) & 0x7); +} + +/* Derive the Device ID using values in the shadow cache. */ uint64_t fuse_get_device_id(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint64_t device_id = 0; - uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0; - uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; + uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint64_t derived_lot_code = 0; for (unsigned int i = 0; i < 5; i++) { derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F); } derived_lot_code &= 0x03FFFFFF; - + device_id |= y_coord << 0; device_id |= x_coord << 9; device_id |= wafer_id << 18; device_id |= derived_lot_code << 24; device_id |= fab_code << 50; + return device_id; } -/* Get the DRAM ID using values in the shadow cache */ -uint32_t fuse_get_dram_id(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7; -} - -/* Derive the Hardware Type using values in the shadow cache */ -uint32_t fuse_get_hardware_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); +/* Derive the Hardware Type using values in the shadow cache. */ +uint32_t fuse_get_hardware_type(uint32_t mkey_rev) { + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1)); - /* This function is very different between 4.x and < 4.x */ - uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1); - - /* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) { - static const uint32_t types[] = {0,1,4,3}; - - hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C; - hardware_type--; - return hardware_type > 3 ? 4 : types[hardware_type]; - } else {*/ + /* Firmware from versions 1.0.0 to 3.0.2. */ + if (mkey_rev < 0x03) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); if (hardware_type >= 1) { - return hardware_type > 2 ? 3 : hardware_type - 1; + return (hardware_type > 2) ? 3 : hardware_type - 1; } else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) { return 0; } else { return 3; } -// } + } else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */ + static const uint32_t types[] = {0,1,4,3}; + hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C); + hardware_type--; + return (hardware_type > 3) ? 4 : types[hardware_type]; + } else { /* Firmware versions from 7.0.0 onwards. */ + /* Always return 0 in retail. */ + return 0; + } } -/* Derive the Retail Type using values in the shadow cache */ +/* Derive the Retail Type using values in the shadow cache. */ uint32_t fuse_get_retail_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - /* Retail type = IS_RETAIL | UNIT_TYPE */ - uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3); + /* Retail Type = IS_RETAIL | UNIT_TYPE. */ + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3)); if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */ return 1; } else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */ @@ -241,17 +243,17 @@ void fuse_get_hardware_info(void *dst) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint32_t hw_info[0x4]; - uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F; - uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0; - uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF; - uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; - uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF; + uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F; + uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF; + uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF; - /* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ - hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse)); + /* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ + hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved)); hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2)); hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6)); hw_info[3] = (uint32_t)(vendor_code); diff --git a/fusee/fusee-secondary/src/fuse.h b/fusee/fusee-secondary/src/fuse.h index 9d92503e2..d118b53dc 100644 --- a/fusee/fusee-secondary/src/fuse.h +++ b/fusee/fusee-secondary/src/fuse.h @@ -23,154 +23,167 @@ #define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n) typedef struct { - uint32_t FUSE_CTRL; - uint32_t FUSE_REG_ADDR; - uint32_t FUSE_REG_READ; - uint32_t FUSE_REG_WRITE; - uint32_t FUSE_TIME_RD1; - uint32_t FUSE_TIME_RD2; - uint32_t FUSE_TIME_PGM1; - uint32_t FUSE_TIME_PGM2; - uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSECTRL; + uint32_t FUSE_FUSEADDR; + uint32_t FUSE_FUSERDATA; + uint32_t FUSE_FUSEWDATA; + uint32_t FUSE_FUSETIME_RD1; + uint32_t FUSE_FUSETIME_RD2; + uint32_t FUSE_FUSETIME_PGM1; + uint32_t FUSE_FUSETIME_PGM2; + uint32_t FUSE_PRIV2INTFC_START; uint32_t FUSE_FUSEBYPASS; uint32_t FUSE_PRIVATEKEYDISABLE; - uint32_t FUSE_DIS_PGM; - uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_DISABLEREGPROGRAM; + uint32_t FUSE_WRITE_ACCESS_SW; uint32_t FUSE_PWR_GOOD_SW; - uint32_t _0x38[0x32]; + uint32_t _0x38; + uint32_t FUSE_PRIV2RESHIFT; + uint32_t _0x40[0x3]; + uint32_t FUSE_FUSETIME_RD3; + uint32_t _0x50[0xC]; + uint32_t FUSE_PRIVATE_KEY0_NONZERO; + uint32_t FUSE_PRIVATE_KEY1_NONZERO; + uint32_t FUSE_PRIVATE_KEY2_NONZERO; + uint32_t FUSE_PRIVATE_KEY3_NONZERO; + uint32_t FUSE_PRIVATE_KEY4_NONZERO; + uint32_t _0x90[0x1C]; } tegra_fuse_t; typedef struct { uint32_t FUSE_PRODUCTION_MODE; - uint32_t _0x4; - uint32_t _0x8; - uint32_t _0xC; + uint32_t FUSE_JTAG_SECUREID_VALID; + uint32_t FUSE_ODM_LOCK; + uint32_t FUSE_OPT_OPENGL_EN; uint32_t FUSE_SKU_INFO; - uint32_t FUSE_CPU_SPEEDO_0; - uint32_t FUSE_CPU_IDDQ; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t _0x24; - uint32_t FUSE_FT_REV; - uint32_t FUSE_CPU_SPEEDO_1; - uint32_t FUSE_CPU_SPEEDO_2; - uint32_t FUSE_SOC_SPEEDO_0; - uint32_t FUSE_SOC_SPEEDO_1; - uint32_t FUSE_SOC_SPEEDO_2; - uint32_t FUSE_SOC_IDDQ; - uint32_t _0x44; + uint32_t FUSE_CPU_SPEEDO_0_CALIB; + uint32_t FUSE_CPU_IDDQ_CALIB; + uint32_t FUSE_DAC_CRT_CALIB; + uint32_t FUSE_DAC_HDTV_CALIB; + uint32_t FUSE_DAC_SDTV_CALIB; + uint32_t FUSE_OPT_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1_CALIB; + uint32_t FUSE_CPU_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_SPEEDO_0_CALIB; + uint32_t FUSE_SOC_SPEEDO_1_CALIB; + uint32_t FUSE_SOC_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_IDDQ_CALIB; + uint32_t FUSE_RESERVED_PRODUCTION_WP; uint32_t FUSE_FA; - uint32_t _0x4C; - uint32_t _0x50; - uint32_t _0x54; - uint32_t _0x58; - uint32_t _0x5C; - uint32_t _0x60; + uint32_t FUSE_RESERVED_PRODUCTION; + uint32_t FUSE_HDMI_LANE0_CALIB; + uint32_t FUSE_HDMI_LANE1_CALIB; + uint32_t FUSE_HDMI_LANE2_CALIB; + uint32_t FUSE_HDMI_LANE3_CALIB; + uint32_t FUSE_ENCRYPTION_RATE; uint32_t FUSE_PUBLIC_KEY[0x8]; - uint32_t FUSE_TSENSOR_1; - uint32_t FUSE_TSENSOR_2; - uint32_t _0x8C; - uint32_t FUSE_CP_REV; - uint32_t _0x94; - uint32_t FUSE_TSENSOR_0; - uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_TSENSOR1_CALIB; + uint32_t FUSE_TSENSOR2_CALIB; + uint32_t FUSE_VSENSOR_CALIB; + uint32_t FUSE_OPT_CP_REV; + uint32_t FUSE_OPT_PFG; + uint32_t FUSE_TSENSOR0_CALIB; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; - uint32_t FUSE_PRIVATE_KEY[0x4]; - uint32_t FUSE_DEVICE_KEY; - uint32_t _0xB8; - uint32_t _0xBC; + uint32_t FUSE_PRIVATE_KEY[0x5]; + uint32_t FUSE_ARM_JTAG_DIS; + uint32_t FUSE_BOOT_DEVICE_INFO; uint32_t FUSE_RESERVED_SW; - uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_OPT_VP9_DISABLE; uint32_t FUSE_RESERVED_ODM[0x8]; - uint32_t _0xE8; - uint32_t _0xEC; - uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_OBS_DIS; + uint32_t FUSE_NOR_INFO; + uint32_t FUSE_USB_CALIB; uint32_t FUSE_SKU_DIRECT_CONFIG; - uint32_t _0xF8; - uint32_t _0xFC; - uint32_t FUSE_VENDOR_CODE; - uint32_t FUSE_FAB_CODE; - uint32_t FUSE_LOT_CODE_0; - uint32_t FUSE_LOT_CODE_1; - uint32_t FUSE_WAFER_ID; - uint32_t FUSE_X_COORDINATE; - uint32_t FUSE_Y_COORDINATE; - uint32_t _0x11C; - uint32_t _0x120; + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; + uint32_t FUSE_PACKAGE_INFO; + uint32_t FUSE_OPT_VENDOR_CODE; + uint32_t FUSE_OPT_FAB_CODE; + uint32_t FUSE_OPT_LOT_CODE_0; + uint32_t FUSE_OPT_LOT_CODE_1; + uint32_t FUSE_OPT_WAFER_ID; + uint32_t FUSE_OPT_X_COORDINATE; + uint32_t FUSE_OPT_Y_COORDINATE; + uint32_t FUSE_OPT_SEC_DEBUG_EN; + uint32_t FUSE_OPT_OPS_RESERVED; uint32_t FUSE_SATA_CALIB; - uint32_t FUSE_GPU_IDDQ; - uint32_t FUSE_TSENSOR_3; - uint32_t _0x130; - uint32_t _0x134; - uint32_t _0x138; - uint32_t _0x13C; - uint32_t _0x140; - uint32_t _0x144; + uint32_t FUSE_GPU_IDDQ_CALIB; + uint32_t FUSE_TSENSOR3_CALIB; + uint32_t FUSE_SKU_BOND_OUT_L; + uint32_t FUSE_SKU_BOND_OUT_H; + uint32_t FUSE_SKU_BOND_OUT_U; + uint32_t FUSE_SKU_BOND_OUT_V; + uint32_t FUSE_SKU_BOND_OUT_W; + uint32_t FUSE_OPT_SAMPLE_TYPE; uint32_t FUSE_OPT_SUBREVISION; - uint32_t _0x14C; - uint32_t _0x150; - uint32_t FUSE_TSENSOR_4; - uint32_t FUSE_TSENSOR_5; - uint32_t FUSE_TSENSOR_6; - uint32_t FUSE_TSENSOR_7; - uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_OPT_SW_RESERVED_0; + uint32_t FUSE_OPT_SW_RESERVED_1; + uint32_t FUSE_TSENSOR4_CALIB; + uint32_t FUSE_TSENSOR5_CALIB; + uint32_t FUSE_TSENSOR6_CALIB; + uint32_t FUSE_TSENSOR7_CALIB; + uint32_t FUSE_OPT_PRIV_SEC_EN; uint32_t FUSE_PKC_DISABLE; uint32_t _0x16C; uint32_t _0x170; uint32_t _0x174; uint32_t _0x178; - uint32_t _0x17C; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; uint32_t FUSE_TSENSOR_COMMON; - uint32_t _0x184; - uint32_t _0x188; - uint32_t _0x18C; - uint32_t _0x190; + uint32_t FUSE_OPT_CP_BIN; + uint32_t FUSE_OPT_GPU_DISABLE; + uint32_t FUSE_OPT_FT_BIN; + uint32_t FUSE_OPT_DONE_MAP; uint32_t _0x194; - uint32_t _0x198; - uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t FUSE_APB2JTAG_DISABLE; + uint32_t FUSE_ODM_INFO; uint32_t _0x1A0; uint32_t _0x1A4; - uint32_t _0x1A8; + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; uint32_t _0x1AC; uint32_t _0x1B0; uint32_t _0x1B4; uint32_t _0x1B8; uint32_t _0x1BC; - uint32_t _0x1D0; - uint32_t FUSE_TSENSOR_8; + uint32_t FUSE_WOA_SKU_FLAG; + uint32_t FUSE_ECO_RESERVE_1; + uint32_t FUSE_GCPLEX_CONFIG_FUSE; + uint32_t FUSE_PRODUCTION_MONTH; + uint32_t FUSE_RAM_REPAIR_INDICATOR; + uint32_t FUSE_TSENSOR9_CALIB; uint32_t _0x1D8; - uint32_t _0x1DC; - uint32_t _0x1E0; - uint32_t _0x1E4; - uint32_t _0x1E8; - uint32_t _0x1EC; - uint32_t _0x1F0; - uint32_t _0x1F4; - uint32_t _0x1F8; + uint32_t FUSE_VMIN_CALIBRATION; + uint32_t FUSE_AGING_SENSOR_CALIBRATION; + uint32_t FUSE_DEBUG_AUTHENTICATION; + uint32_t FUSE_SECURE_PROVISION_INDEX; + uint32_t FUSE_SECURE_PROVISION_INFO; + uint32_t FUSE_OPT_GPU_DISABLE_CP1; + uint32_t FUSE_SPARE_ENDIS; + uint32_t FUSE_ECO_RESERVE_0; uint32_t _0x1FC; uint32_t _0x200; - uint32_t FUSE_RESERVED_CALIB; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t _0x214; - uint32_t _0x218; - uint32_t FUSE_TSENSOR_9; - uint32_t _0x220; - uint32_t _0x224; - uint32_t _0x228; - uint32_t _0x22C; - uint32_t _0x230; - uint32_t _0x234; - uint32_t _0x238; - uint32_t _0x23C; - uint32_t _0x240; - uint32_t _0x244; - uint32_t _0x248; - uint32_t _0x24C; + uint32_t FUSE_RESERVED_CALIB0; + uint32_t FUSE_RESERVED_CALIB1; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1; + uint32_t FUSE_OPT_CPU_DISABLE; + uint32_t FUSE_OPT_CPU_DISABLE_CP1; + uint32_t FUSE_TSENSOR10_CALIB; + uint32_t FUSE_TSENSOR10_CALIB_AUX; + uint32_t FUSE_OPT_RAM_SVOP_DP; + uint32_t FUSE_OPT_RAM_SVOP_PDP; + uint32_t FUSE_OPT_RAM_SVOP_REG; + uint32_t FUSE_OPT_RAM_SVOP_SP; + uint32_t FUSE_OPT_RAM_SVOP_SMPDP; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2; + uint32_t FUSE_OPT_CPU_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_DISABLE_CP2; uint32_t FUSE_USB_CALIB_EXT; - uint32_t _0x254; - uint32_t _0x258; + uint32_t FUSE_RESERVED_FIELD; + uint32_t FUSE_OPT_ECC_EN; uint32_t _0x25C; uint32_t _0x260; uint32_t _0x264; @@ -179,35 +192,36 @@ typedef struct { uint32_t _0x270; uint32_t _0x274; uint32_t _0x278; - uint32_t _0x27C; + uint32_t FUSE_SPARE_REALIGNMENT_REG; uint32_t FUSE_SPARE_BIT[0x20]; } tegra_fuse_chip_t; -static inline volatile tegra_fuse_t *fuse_get_regs(void) { +static inline volatile tegra_fuse_t *fuse_get_regs(void) +{ return (volatile tegra_fuse_t *)FUSE_BASE; } -static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) { +static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) +{ return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE; } void fuse_init(void); - -uint32_t fuse_hw_read(uint32_t addr); -void fuse_hw_write(uint32_t value, uint32_t addr); -void fuse_hw_sense(void); void fuse_disable_programming(void); -void fuse_secondary_private_key_disable(void); +void fuse_disable_private_key(void); uint32_t fuse_get_sku_info(void); uint32_t fuse_get_spare_bit(uint32_t idx); uint32_t fuse_get_reserved_odm(uint32_t idx); - uint32_t fuse_get_bootrom_patch_version(void); uint64_t fuse_get_device_id(void); uint32_t fuse_get_dram_id(void); -uint32_t fuse_get_hardware_type(void); +uint32_t fuse_get_hardware_type(uint32_t mkey_rev); uint32_t fuse_get_retail_type(void); void fuse_get_hardware_info(void *dst); +uint32_t fuse_hw_read(uint32_t addr); +void fuse_hw_write(uint32_t value, uint32_t addr); +void fuse_hw_sense(void); + #endif diff --git a/fusee/fusee-secondary/src/nxboot_iram.c b/fusee/fusee-secondary/src/nxboot_iram.c index 44438c2ae..b8934f9c3 100644 --- a/fusee/fusee-secondary/src/nxboot_iram.c +++ b/fusee/fusee-secondary/src/nxboot_iram.c @@ -56,10 +56,10 @@ void nxboot_finish(uint32_t boot_memaddr) { set_rsa_keyslot_flags(i, 1); /* Lock the Security Engine. */ - se->_0x4 = 0; - se->AES_KEY_READ_DISABLE_REG = 0; - se->RSA_KEY_READ_DISABLE_REG = 0; - se->_0x0 &= 0xFFFFFFFB; + se->SE_TZRAM_SECURITY = 0; + se->SE_CRYPTO_SECURITY_PERKEY = 0; + se->SE_RSA_SECURITY_PERKEY = 0; + se->SE_SE_SECURITY &= 0xFFFFFFFB; /* Boot up Exosphère. */ MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE(target_firmware) = 0; diff --git a/fusee/fusee-secondary/src/se.c b/fusee/fusee-secondary/src/se.c index 0a22229b0..188176aa7 100644 --- a/fusee/fusee-secondary/src/se.c +++ b/fusee/fusee-secondary/src/se.c @@ -39,20 +39,20 @@ void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) { } void se_check_error_status_reg(void) { - if (se_get_regs()->ERR_STATUS_REG) { + if (se_get_regs()->SE_ERR_STATUS) { generic_panic(); } } void se_check_for_error(void) { volatile tegra_se_t *se = se_get_regs(); - if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) { + if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) { generic_panic(); } } void se_verify_flags_cleared(void) { - if (se_get_regs()->FLAGS_REG & 3) { + if (se_get_regs()->SE_STATUS & 3) { generic_panic(); } } @@ -67,12 +67,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { - se->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -87,12 +87,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { /* TODO: Why are flags assigned this way? */ - se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -105,8 +105,8 @@ void clear_aes_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -120,13 +120,13 @@ void clear_rsa_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + se->SE_RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = 0; } } @@ -138,8 +138,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { } for (size_t i = 0; i < (key_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = read32le(key, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i); } } @@ -151,13 +151,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_ } for (size_t i = 0; i < (modulus_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; - se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); } for (size_t i = 0; i < (exp_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); } g_se_modulus_sizes[keyslot] = modulus_size; @@ -172,8 +172,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { } for (size_t i = 0; i < (iv_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i); } } @@ -185,14 +185,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) { } for (size_t i = 0; i < (0x10 >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } void set_se_ctr(const void *ctr) { for (unsigned int i = 0; i < 4; i++) { - se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4); } } @@ -203,10 +203,10 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); - se->CRYPTO_REG = keyslot_src << 24; - se->BLOCK_COUNT_REG = 0; - se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; + se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = keyslot_src << 24; + se->SE_CRYPTO_LAST_BLOCK = 0; + se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8; trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); } @@ -224,10 +224,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co stack_buf[i] = *((uint8_t *)src + src_size - i - 1); } - se->CONFIG_REG = (ALG_RSA | DST_RSAREG); - se->RSA_CONFIG = keyslot << 24; - se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + se->SE_CONFIG = (ALG_RSA | DST_RSAREG); + se->SE_RSA_CONFIG = keyslot << 24; + se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1; + se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2; trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size); se_get_exp_mod_output(dst, dst_size); @@ -245,7 +245,7 @@ void se_get_exp_mod_output(void *buf, size_t size) { /* Copy endian swapped output. */ while (num_dwords) { - *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset); + *p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset); offset += 4; p_out--; num_dwords--; @@ -314,15 +314,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v ll_init(&out_ll, dst, dst_size); /* Set the LLs. */ - se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); - se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll); + se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); + se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = op; + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = op; - while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -340,7 +340,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } /* Trigger AES operation. */ - se_get_regs()->BLOCK_COUNT_REG = 0; + se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -358,15 +358,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo unsigned int num_blocks = src_size >> 4; /* Unknown what this write does, but official code writes it for CTR mode. */ - se->SPARE_0 = 1; - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x91E; + se->SE_SPARE = 1; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E; set_se_ctr(ctr); /* Handle any aligned blocks. */ size_t aligned_size = (size_t)num_blocks << 4; if (aligned_size) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size); } @@ -388,8 +388,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - se->CRYPTO_REG = keyslot << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -408,8 +408,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot << 24; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -472,13 +472,13 @@ void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keys /* Encrypt/Decrypt. */ if (encrypt) { - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24 | 0x100; } else { - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24; } - se->BLOCK_COUNT_REG = (size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, size, src, size); /* XOR. */ @@ -524,16 +524,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - se->CRYPTO_REG = (keyslot << 24) | (0x145); + se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - se->BLOCK_COUNT_REG = num_blocks - 2; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2; trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); - se->CRYPTO_REG |= 0x80; + se->SE_CRYPTO_CONFIG |= 0x80; } /* Create final block. */ @@ -550,12 +550,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con } /* Perform last operation. */ - se->BLOCK_COUNT_REG = 0; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2); } } @@ -573,10 +573,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x144; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144; set_aes_keyslot_iv(keyslot, iv, 0x10); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -585,23 +585,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { volatile tegra_se_t *se = se_get_regs(); /* Setup config for SHA256, size = BITS(src_size) */ - se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); - se->SHA_CONFIG_REG = 1; - se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3); - se->_0x208 = 0; - se->_0x20C = 0; - se->_0x210 = 0; - se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3); - se->_0x218 = 0; - se->_0x21C = 0; - se->_0x220 = 0; + se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + se->SE_SHA_CONFIG = 1; + se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LENGTH[1] = 0; + se->SE_SHA_MSG_LENGTH[2] = 0; + se->SE_SHA_MSG_LENGTH[3] = 0; + se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LEFT[1] = 0; + se->SE_SHA_MSG_LEFT[2] = 0; + se->SE_SHA_MSG_LEFT[3] = 0; /* Trigger the operation. */ trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); /* Copy output hash. */ for (unsigned int i = 0; i < (0x20 >> 2); i++) { - ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2); } } @@ -617,12 +617,12 @@ void se_initialize_rng(unsigned int keyslot) { /* This will be discarded, when done. */ uint8_t ALIGN(16) output_buf[0x10]; - se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ - se->RNG_RESEED_INTERVAL_REG = 70001; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 5; - se->BLOCK_COUNT_REG = 0; + se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */ + se->SE_RNG_RESEED_INTERVAL = 70001; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 5; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0); } @@ -635,12 +635,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) { uint32_t num_blocks = size >> 4; size_t aligned_size = num_blocks << 4; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; if (num_blocks >= 1) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0); } if (size > aligned_size) { diff --git a/fusee/fusee-secondary/src/se.h b/fusee/fusee-secondary/src/se.h index b6ad69866..5e8e46900 100644 --- a/fusee/fusee-secondary/src/se.h +++ b/fusee/fusee-secondary/src/se.h @@ -92,71 +92,59 @@ #define RSA_2048_BYTES 0x100 typedef struct { - uint32_t _0x0; - uint32_t _0x4; - uint32_t OPERATION_REG; - uint32_t INT_ENABLE_REG; - uint32_t INT_STATUS_REG; - uint32_t CONFIG_REG; - uint32_t IN_LL_ADDR_REG; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t OUT_LL_ADDR_REG; - uint32_t _0x28; - uint32_t _0x2C; - uint8_t HASH_RESULT_REG[0x20]; - uint8_t _0x50[0x20]; - uint32_t CONTEXT_SAVE_CONFIG_REG; - uint8_t _0x74[0x18C]; - uint32_t SHA_CONFIG_REG; - uint32_t SHA_MSG_LENGTH_REG; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t SHA_MSG_LEFT_REG; - uint32_t _0x218; - uint32_t _0x21C; - uint32_t _0x220; - uint32_t _0x224; - uint8_t _0x228[0x58]; - uint32_t AES_KEY_READ_DISABLE_REG; - uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C4[0x3C]; - uint32_t _0x300; - uint32_t CRYPTO_REG; - uint32_t CRYPTO_CTR_REG[4]; - uint32_t BLOCK_COUNT_REG; - uint32_t AES_KEYTABLE_ADDR; - uint32_t AES_KEYTABLE_DATA; - uint32_t _0x324; - uint32_t _0x328; - uint32_t _0x32C; - uint32_t CRYPTO_KEYTABLE_DST_REG; - uint8_t _0x334[0xC]; - uint32_t RNG_CONFIG_REG; - uint32_t RNG_SRC_CONFIG_REG; - uint32_t RNG_RESEED_INTERVAL_REG; - uint8_t _0x34C[0xB4]; - uint32_t RSA_CONFIG; - uint32_t RSA_KEY_SIZE_REG; - uint32_t RSA_EXP_SIZE_REG; - uint32_t RSA_KEY_READ_DISABLE_REG; - uint32_t RSA_KEYSLOT_FLAGS[2]; - uint32_t _0x418; - uint32_t _0x41C; - uint32_t RSA_KEYTABLE_ADDR; - uint32_t RSA_KEYTABLE_DATA; - uint8_t RSA_OUTPUT[0x100]; - uint8_t _0x528[0x2D8]; - uint32_t FLAGS_REG; - uint32_t ERR_STATUS_REG; - uint32_t _0x808; - uint32_t SPARE_0; - uint32_t _0x810; + uint32_t SE_SE_SECURITY; + uint32_t SE_TZRAM_SECURITY; + uint32_t SE_OPERATION; + uint32_t SE_INT_ENABLE; + uint32_t SE_INT_STATUS; + uint32_t SE_CONFIG; + uint32_t SE_IN_LL_ADDR; + uint32_t SE_IN_CUR_BYTE_ADDR; + uint32_t SE_IN_CUR_LL_ID; + uint32_t SE_OUT_LL_ADDR; + uint32_t SE_OUT_CUR_BYTE_ADDR; + uint32_t SE_OUT_CUR_LL_ID; + uint32_t SE_HASH_RESULT[0x10]; + uint32_t SE_CTX_SAVE_CONFIG; + uint32_t _0x74[0x63]; + uint32_t SE_SHA_CONFIG; + uint32_t SE_SHA_MSG_LENGTH[0x4]; + uint32_t SE_SHA_MSG_LEFT[0x4]; + uint32_t _0x224[0x17]; + uint32_t SE_CRYPTO_SECURITY_PERKEY; + uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10]; + uint32_t _0x2C4[0x10]; + uint32_t SE_CRYPTO_CONFIG; + uint32_t SE_CRYPTO_LINEAR_CTR[0x4]; + uint32_t SE_CRYPTO_LAST_BLOCK; + uint32_t SE_CRYPTO_KEYTABLE_ADDR; + uint32_t SE_CRYPTO_KEYTABLE_DATA; + uint32_t _0x324[0x3]; + uint32_t SE_CRYPTO_KEYTABLE_DST; + uint32_t _0x334[0x3]; + uint32_t SE_RNG_CONFIG; + uint32_t SE_RNG_SRC_CONFIG; + uint32_t SE_RNG_RESEED_INTERVAL; + uint32_t _0x34C[0x2D]; + uint32_t SE_RSA_CONFIG; + uint32_t SE_RSA_KEY_SIZE; + uint32_t SE_RSA_EXP_SIZE; + uint32_t SE_RSA_SECURITY_PERKEY; + uint32_t SE_RSA_KEYTABLE_ACCESS[0x2]; + uint32_t _0x418[0x2]; + uint32_t SE_RSA_KEYTABLE_ADDR; + uint32_t SE_RSA_KEYTABLE_DATA; + uint32_t SE_RSA_OUTPUT[0x40]; + uint32_t _0x528[0xB6]; + uint32_t SE_STATUS; + uint32_t SE_ERR_STATUS; + uint32_t SE_MISC; + uint32_t SE_SPARE; + uint32_t SE_ENTROPY_DEBUG_COUNTER; uint32_t _0x814; uint32_t _0x818; uint32_t _0x81C; - uint8_t _0x820[0x17E0]; + uint32_t _0x820[0x5F8]; } tegra_se_t; typedef struct { diff --git a/fusee/fusee-secondary/src/smmu.c b/fusee/fusee-secondary/src/smmu.c index d542f6b29..81c97bf1c 100644 --- a/fusee/fusee-secondary/src/smmu.c +++ b/fusee/fusee-secondary/src/smmu.c @@ -237,7 +237,6 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si mc_page[0x65C/4] = 0; mc_page[0x660/4] = 0x80000000; - /* Run the TSEC firmware. */ tsec_run_fw(); @@ -245,7 +244,7 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si volatile uint32_t *key_data = (volatile uint32_t *)((void *)se_page + 0x320); uint32_t old_key_data = *key_data; uint32_t buf_counter = 0; - while (!(tsec->FALCON_CPUCTL & 0x10)) { + while (!(tsec->TSEC_FALCON_CPUCTL & 0x10)) { const uint32_t new_key_data = *key_data; if (new_key_data != old_key_data) { old_key_data = new_key_data; diff --git a/fusee/fusee-secondary/src/tsec.c b/fusee/fusee-secondary/src/tsec.c index 18b17da00..73a831e77 100644 --- a/fusee/fusee-secondary/src/tsec.c +++ b/fusee/fusee-secondary/src/tsec.c @@ -25,7 +25,7 @@ static int tsec_dma_wait_idle() volatile tegra_tsec_t *tsec = tsec_get_regs(); uint32_t timeout = (get_time_ms() + 10000); - while (!(tsec->FALCON_DMATRFCMD & 2)) + while (!(tsec->TSEC_FALCON_DMATRFCMD & 2)) if (get_time_ms() > timeout) return 0; @@ -42,13 +42,29 @@ static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t ph else cmd = 0x10; - tsec->FALCON_DMATRFMOFFS = flcn_offset; - tsec->FALCON_DMATRFFBOFFS = phys_offset; - tsec->FALCON_DMATRFCMD = cmd; + tsec->TSEC_FALCON_DMATRFMOFFS = flcn_offset; + tsec->TSEC_FALCON_DMATRFFBOFFS = phys_offset; + tsec->TSEC_FALCON_DMATRFCMD = cmd; return tsec_dma_wait_idle(); } +static int tsec_kfuse_wait_ready() +{ + uint32_t timeout = (get_time_ms() + 10000); + + /* Wait for STATE_DONE. */ + while (!(KFUSE_STATE & 0x10000)) + if (get_time_ms() > timeout) + return 0; + + /* Check for STATE_CRCPASS. */ + if (!(KFUSE_STATE & 0x20000)) + return 0; + + return 1; +} + void tsec_enable_clkrst() { /* Enable all devices used by TSEC. */ @@ -77,23 +93,33 @@ int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw /* Enable clocks. */ tsec_enable_clkrst(); - - /* Configure Falcon. */ - tsec->FALCON_DMACTL = 0; - tsec->FALCON_IRQMSET = 0xFFF2; - tsec->FALCON_IRQDEST = 0xFFF0; - tsec->FALCON_ITFEN = 3; - if (!tsec_dma_wait_idle()) + /* Make sure KFUSE is ready. */ + if (!tsec_kfuse_wait_ready()) { /* Disable clocks. */ tsec_disable_clkrst(); return -1; } + + /* Configure Falcon. */ + tsec->TSEC_FALCON_DMACTL = 0; + tsec->TSEC_FALCON_IRQMSET = 0xFFF2; + tsec->TSEC_FALCON_IRQDEST = 0xFFF0; + tsec->TSEC_FALCON_ITFEN = 3; + + /* Make sure the DMA block is idle. */ + if (!tsec_dma_wait_idle()) + { + /* Disable clocks. */ + tsec_disable_clkrst(); + + return -2; + } /* Load firmware. */ - tsec->FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8; + tsec->TSEC_FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8; for (uint32_t addr = 0; addr < tsec_fw_size; addr += 0x100) { if (!tsec_dma_phys_to_flcn(true, addr, addr)) @@ -101,48 +127,49 @@ int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw /* Disable clocks. */ tsec_disable_clkrst(); - return -2; + return -3; } } - /* Unknown host1x write. */ + /* Write magic value to HOST1X scratch register. */ MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA; /* Execute firmware. */ - tsec->FALCON_SCRATCH1 = 0; - tsec->FALCON_SCRATCH0 = rev; - tsec->FALCON_BOOTVEC = 0; - tsec->FALCON_CPUCTL = 2; + tsec->TSEC_FALCON_MAILBOX1 = 0; + tsec->TSEC_FALCON_MAILBOX0 = rev; + tsec->TSEC_FALCON_BOOTVEC = 0; + tsec->TSEC_FALCON_CPUCTL = 2; + /* Make sure the DMA block is idle. */ if (!tsec_dma_wait_idle()) { /* Disable clocks. */ tsec_disable_clkrst(); - return -3; + return -4; } uint32_t timeout = (get_time_ms() + 2000); - while (!tsec->FALCON_SCRATCH1) + while (!tsec->TSEC_FALCON_MAILBOX1) { if (get_time_ms() > timeout) { /* Disable clocks. */ tsec_disable_clkrst(); - return -4; + return -5; } } - if (tsec->FALCON_SCRATCH1 != 0xB0B0B0B0) + if (tsec->TSEC_FALCON_MAILBOX1 != 0xB0B0B0B0) { /* Disable clocks. */ tsec_disable_clkrst(); - return -5; + return -6; } - /* Unknown host1x write. */ + /* Clear magic value from HOST1X scratch register. */ MAKE_HOST1X_REG(0x3300) = 0; /* Fetch result from SOR1. */ @@ -170,23 +197,33 @@ int tsec_load_fw(const void *tsec_fw, size_t tsec_fw_size) /* Enable clocks. */ tsec_enable_clkrst(); - - /* Configure Falcon. */ - tsec->FALCON_DMACTL = 0; - tsec->FALCON_IRQMSET = 0xFFF2; - tsec->FALCON_IRQDEST = 0xFFF0; - tsec->FALCON_ITFEN = 3; - if (!tsec_dma_wait_idle()) + /* Make sure KFUSE is ready. */ + if (!tsec_kfuse_wait_ready()) { /* Disable clocks. */ tsec_disable_clkrst(); return -1; } + + /* Configure Falcon. */ + tsec->TSEC_FALCON_DMACTL = 0; + tsec->TSEC_FALCON_IRQMSET = 0xFFF2; + tsec->TSEC_FALCON_IRQDEST = 0xFFF0; + tsec->TSEC_FALCON_ITFEN = 3; + + /* Make sure the DMA block is idle. */ + if (!tsec_dma_wait_idle()) + { + /* Disable clocks. */ + tsec_disable_clkrst(); + + return -2; + } /* Load firmware. */ - tsec->FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8; + tsec->TSEC_FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8; for (uint32_t addr = 0; addr < tsec_fw_size; addr += 0x100) { if (!tsec_dma_phys_to_flcn(true, addr, addr)) @@ -194,7 +231,7 @@ int tsec_load_fw(const void *tsec_fw, size_t tsec_fw_size) /* Disable clocks. */ tsec_disable_clkrst(); - return -2; + return -3; } } @@ -205,12 +242,12 @@ void tsec_run_fw() { volatile tegra_tsec_t *tsec = tsec_get_regs(); - /* Unknown host1x write. */ + /* Write magic value to HOST1X scratch register. */ MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA; /* Execute firmware. */ - tsec->FALCON_SCRATCH1 = 0; - tsec->FALCON_SCRATCH0 = 1; - tsec->FALCON_BOOTVEC = 0; - tsec->FALCON_CPUCTL = 2; + tsec->TSEC_FALCON_MAILBOX1 = 0; + tsec->TSEC_FALCON_MAILBOX0 = 1; + tsec->TSEC_FALCON_BOOTVEC = 0; + tsec->TSEC_FALCON_CPUCTL = 2; } \ No newline at end of file diff --git a/fusee/fusee-secondary/src/tsec.h b/fusee/fusee-secondary/src/tsec.h index 8fa648864..d2efcee9b 100644 --- a/fusee/fusee-secondary/src/tsec.h +++ b/fusee/fusee-secondary/src/tsec.h @@ -23,85 +23,280 @@ #define TSEC_BASE 0x54500000 #define SOR1_BASE 0x54580000 +#define KFUSE_BASE 0x7000FC00 #define SOR1_DP_HDCP_BKSV_LSB MAKE_REG32(SOR1_BASE + 0x1E8) #define SOR1_TMDS_HDCP_BKSV_LSB MAKE_REG32(SOR1_BASE + 0x21C) #define SOR1_TMDS_HDCP_CN_MSB MAKE_REG32(SOR1_BASE + 0x208) #define SOR1_TMDS_HDCP_CN_LSB MAKE_REG32(SOR1_BASE + 0x20C) +#define KFUSE_FUSECTRL MAKE_REG32(KFUSE_BASE + 0x00) +#define KFUSE_FUSEADDR MAKE_REG32(KFUSE_BASE + 0x04) +#define KFUSE_FUSEDATA0 MAKE_REG32(KFUSE_BASE + 0x08) +#define KFUSE_FUSEWRDATA0 MAKE_REG32(KFUSE_BASE + 0x0C) +#define KFUSE_FUSETIME_RD1 MAKE_REG32(KFUSE_BASE + 0x10) +#define KFUSE_FUSETIME_RD2 MAKE_REG32(KFUSE_BASE + 0x14) +#define KFUSE_FUSETIME_PGM1 MAKE_REG32(KFUSE_BASE + 0x18) +#define KFUSE_FUSETIME_PGM2 MAKE_REG32(KFUSE_BASE + 0x1C) +#define KFUSE_REGULATOR MAKE_REG32(KFUSE_BASE + 0x20) +#define KFUSE_PD MAKE_REG32(KFUSE_BASE + 0x24) +#define KFUSE_FUSETIME_RD3 MAKE_REG32(KFUSE_BASE + 0x28) +#define KFUSE_STATE MAKE_REG32(KFUSE_BASE + 0x80) +#define KFUSE_ERRCOUNT MAKE_REG32(KFUSE_BASE + 0x84) +#define KFUSE_KEYADDR MAKE_REG32(KFUSE_BASE + 0x88) +#define KFUSE_KEYS MAKE_REG32(KFUSE_BASE + 0x8C) + typedef struct { - uint8_t _0x0[0x1000]; /* Ignore non Falcon registers. */ - uint32_t FALCON_IRQSSET; - uint32_t FALCON_IRQSCLR; - uint32_t FALCON_IRQSTAT; - uint32_t FALCON_IRQMODE; - uint32_t FALCON_IRQMSET; - uint32_t FALCON_IRQMCLR; - uint32_t FALCON_IRQMASK; - uint32_t FALCON_IRQDEST; - uint8_t _0x1020[0x20]; - uint32_t FALCON_SCRATCH0; - uint32_t FALCON_SCRATCH1; - uint32_t FALCON_ITFEN; - uint32_t FALCON_IDLESTATE; - uint32_t FALCON_CURCTX; - uint32_t FALCON_NXTCTX; - uint8_t _0x1058[0x28]; - uint32_t FALCON_SCRATCH2; - uint32_t FALCON_SCRATCH3; - uint8_t _0x1088[0x18]; - uint32_t FALCON_CGCTL; - uint32_t FALCON_ENGCTL; - uint8_t _0x10A8[0x58]; - uint32_t FALCON_CPUCTL; - uint32_t FALCON_BOOTVEC; - uint32_t FALCON_HWCFG; - uint32_t FALCON_DMACTL; - uint32_t FALCON_DMATRFBASE; - uint32_t FALCON_DMATRFMOFFS; - uint32_t FALCON_DMATRFCMD; - uint32_t FALCON_DMATRFFBOFFS; - uint8_t _0x1120[0x10]; - uint32_t FALCON_CPUCTL_ALIAS; - uint8_t _0x1134[0x20]; - uint32_t FALCON_IMFILLRNG1; - uint32_t FALCON_IMFILLCTL; - uint32_t _0x115C; - uint32_t _0x1160; - uint32_t _0x1164; - uint32_t FALCON_EXTERRADDR; - uint32_t FALCON_EXTERRSTAT; - uint32_t _0x1170; - uint32_t _0x1174; - uint32_t _0x1178; - uint32_t FALCON_CG2; - uint32_t FALCON_CODE_INDEX; - uint32_t FALCON_CODE; - uint32_t FALCON_CODE_VIRT_ADDR; - uint8_t _0x118C[0x34]; - uint32_t FALCON_DATA_INDEX0; - uint32_t FALCON_DATA0; - uint32_t FALCON_DATA_INDEX1; - uint32_t FALCON_DATA1; - uint32_t FALCON_DATA_INDEX2; - uint32_t FALCON_DATA2; - uint32_t FALCON_DATA_INDEX3; - uint32_t FALCON_DATA3; - uint32_t FALCON_DATA_INDEX4; - uint32_t FALCON_DATA4; - uint32_t FALCON_DATA_INDEX5; - uint32_t FALCON_DATA5; - uint32_t FALCON_DATA_INDEX6; - uint32_t FALCON_DATA6; - uint32_t FALCON_DATA_INDEX7; - uint32_t FALCON_DATA7; - uint32_t FALCON_ICD_CMD; - uint32_t FALCON_ICD_ADDR; - uint32_t FALCON_ICD_WDATA; - uint32_t FALCON_ICD_RDATA; - uint8_t _0x1210[0x30]; - uint32_t FALCON_SCTL; - uint8_t _0x1244[0x5F8]; /* Ignore non Falcon registers. */ + uint32_t TSEC_THI_INCR_SYNCPT; /* Tegra Host Interface registers. */ + uint32_t TSEC_THI_INCR_SYNCPT_CTRL; + uint32_t TSEC_THI_INCR_SYNCPT_ERR; + uint32_t TSEC_THI_CTXSW_INCR_SYNCPT; + uint32_t _0x10[0x4]; + uint32_t TSEC_THI_CTXSW; + uint32_t TSEC_THI_CTXSW_NEXT; + uint32_t TSEC_THI_CONT_SYNCPT_EOF; + uint32_t TSEC_THI_CONT_SYNCPT_L1; + uint32_t TSEC_THI_STREAMID0; + uint32_t TSEC_THI_STREAMID1; + uint32_t TSEC_THI_THI_SEC; + uint32_t _0x3C; + uint32_t TSEC_THI_METHOD0; + uint32_t TSEC_THI_METHOD1; + uint32_t _0x48[0x6]; + uint32_t TSEC_THI_CONTEXT_SWITCH; + uint32_t _0x64[0x5]; + uint32_t TSEC_THI_INT_STATUS; + uint32_t TSEC_THI_INT_MASK; + uint32_t TSEC_THI_CONFIG0; + uint32_t TSEC_THI_DBG_MISC; + uint32_t TSEC_THI_SLCG_OVERRIDE_HIGH_A; + uint32_t TSEC_THI_SLCG_OVERRIDE_LOW_A; + uint32_t _0x90[0x35C]; + uint32_t TSEC_THI_CLK_OVERRIDE; + uint32_t _0xE04[0x7F]; + uint32_t TSEC_FALCON_IRQSSET; /* Falcon microcontroller registers. */ + uint32_t TSEC_FALCON_IRQSCLR; + uint32_t TSEC_FALCON_IRQSTAT; + uint32_t TSEC_FALCON_IRQMODE; + uint32_t TSEC_FALCON_IRQMSET; + uint32_t TSEC_FALCON_IRQMCLR; + uint32_t TSEC_FALCON_IRQMASK; + uint32_t TSEC_FALCON_IRQDEST; + uint32_t TSEC_FALCON_GPTMRINT; + uint32_t TSEC_FALCON_GPTMRVAL; + uint32_t TSEC_FALCON_GPTMRCTL; + uint32_t TSEC_FALCON_PTIMER0; + uint32_t TSEC_FALCON_PTIMER1; + uint32_t TSEC_FALCON_WDTMRVAL; + uint32_t TSEC_FALCON_WDTMRCTL; + uint32_t TSEC_FALCON_IRQDEST2; + uint32_t TSEC_FALCON_MAILBOX0; + uint32_t TSEC_FALCON_MAILBOX1; + uint32_t TSEC_FALCON_ITFEN; + uint32_t TSEC_FALCON_IDLESTATE; + uint32_t TSEC_FALCON_CURCTX; + uint32_t TSEC_FALCON_NXTCTX; + uint32_t TSEC_FALCON_CTXACK; + uint32_t TSEC_FALCON_FHSTATE; + uint32_t TSEC_FALCON_PRIVSTATE; + uint32_t TSEC_FALCON_MTHDDATA; + uint32_t TSEC_FALCON_MTHDID; + uint32_t TSEC_FALCON_MTHDWDAT; + uint32_t TSEC_FALCON_MTHDCOUNT; + uint32_t TSEC_FALCON_MTHDPOP; + uint32_t TSEC_FALCON_MTHDRAMSZ; + uint32_t TSEC_FALCON_SFTRESET; + uint32_t TSEC_FALCON_OS; + uint32_t TSEC_FALCON_RM; + uint32_t TSEC_FALCON_SOFT_PM; + uint32_t TSEC_FALCON_SOFT_MODE; + uint32_t TSEC_FALCON_DEBUG1; + uint32_t TSEC_FALCON_DEBUGINFO; + uint32_t TSEC_FALCON_IBRKPT1; + uint32_t TSEC_FALCON_IBRKPT2; + uint32_t TSEC_FALCON_CGCTL; + uint32_t TSEC_FALCON_ENGCTL; + uint32_t TSEC_FALCON_PMM; + uint32_t TSEC_FALCON_ADDR; + uint32_t TSEC_FALCON_IBRKPT3; + uint32_t TSEC_FALCON_IBRKPT4; + uint32_t TSEC_FALCON_IBRKPT5; + uint32_t _0x10BC[0x5]; + uint32_t TSEC_FALCON_EXCI; + uint32_t TSEC_FALCON_SVEC_SPR; + uint32_t TSEC_FALCON_RSTAT0; + uint32_t TSEC_FALCON_RSTAT3; + uint32_t _0x10E0[0x8]; + uint32_t TSEC_FALCON_CPUCTL; + uint32_t TSEC_FALCON_BOOTVEC; + uint32_t TSEC_FALCON_HWCFG; + uint32_t TSEC_FALCON_DMACTL; + uint32_t TSEC_FALCON_DMATRFBASE; + uint32_t TSEC_FALCON_DMATRFMOFFS; + uint32_t TSEC_FALCON_DMATRFCMD; + uint32_t TSEC_FALCON_DMATRFFBOFFS; + uint32_t TSEC_FALCON_DMAPOLL_FB; + uint32_t TSEC_FALCON_DMAPOLL_CP; + uint32_t TSEC_FALCON_DBG_STATE; + uint32_t TSEC_FALCON_HWCFG1; + uint32_t TSEC_FALCON_CPUCTL_ALIAS; + uint32_t _0x1134; + uint32_t TSEC_FALCON_STACKCFG; + uint32_t _0x113C; + uint32_t TSEC_FALCON_IMCTL; + uint32_t TSEC_FALCON_IMSTAT; + uint32_t TSEC_FALCON_TRACEIDX; + uint32_t TSEC_FALCON_TRACEPC; + uint32_t TSEC_FALCON_IMFILLRNG0; + uint32_t TSEC_FALCON_IMFILLRNG1; + uint32_t TSEC_FALCON_IMFILLCTL; + uint32_t TSEC_FALCON_IMCTL_DEBUG; + uint32_t TSEC_FALCON_CMEMBASE; + uint32_t TSEC_FALCON_DMEMAPERT; + uint32_t TSEC_FALCON_EXTERRADDR; + uint32_t TSEC_FALCON_EXTERRSTAT; + uint32_t _0x1170[0x3]; + uint32_t TSEC_FALCON_CG2; + uint32_t TSEC_FALCON_IMEMC0; + uint32_t TSEC_FALCON_IMEMD0; + uint32_t TSEC_FALCON_IMEMT0; + uint32_t _0x118C; + uint32_t TSEC_FALCON_IMEMC1; + uint32_t TSEC_FALCON_IMEMD1; + uint32_t TSEC_FALCON_IMEMT1; + uint32_t _0x119C; + uint32_t TSEC_FALCON_IMEMC2; + uint32_t TSEC_FALCON_IMEMD2; + uint32_t TSEC_FALCON_IMEMT2; + uint32_t _0x11AC; + uint32_t TSEC_FALCON_IMEMC3; + uint32_t TSEC_FALCON_IMEMD3; + uint32_t TSEC_FALCON_IMEMT3; + uint32_t _0x11BC; + uint32_t TSEC_FALCON_DMEMC0; + uint32_t TSEC_FALCON_DMEMD0; + uint32_t TSEC_FALCON_DMEMC1; + uint32_t TSEC_FALCON_DMEMD1; + uint32_t TSEC_FALCON_DMEMC2; + uint32_t TSEC_FALCON_DMEMD2; + uint32_t TSEC_FALCON_DMEMC3; + uint32_t TSEC_FALCON_DMEMD3; + uint32_t TSEC_FALCON_DMEMC4; + uint32_t TSEC_FALCON_DMEMD4; + uint32_t TSEC_FALCON_DMEMC5; + uint32_t TSEC_FALCON_DMEMD5; + uint32_t TSEC_FALCON_DMEMC6; + uint32_t TSEC_FALCON_DMEMD6; + uint32_t TSEC_FALCON_DMEMC7; + uint32_t TSEC_FALCON_DMEMD7; + uint32_t TSEC_FALCON_ICD_CMD; + uint32_t TSEC_FALCON_ICD_ADDR; + uint32_t TSEC_FALCON_ICD_WDATA; + uint32_t TSEC_FALCON_ICD_RDATA; + uint32_t _0x1210[0xC]; + uint32_t TSEC_FALCON_SCTL; + uint32_t TSEC_FALCON_SSTAT; + uint32_t _0x1248[0xE]; + uint32_t TSEC_FALCON_SPROT_IMEM; + uint32_t TSEC_FALCON_SPROT_DMEM; + uint32_t TSEC_FALCON_SPROT_CPUCTL; + uint32_t TSEC_FALCON_SPROT_MISC; + uint32_t TSEC_FALCON_SPROT_IRQ; + uint32_t TSEC_FALCON_SPROT_MTHD; + uint32_t TSEC_FALCON_SPROT_SCTL; + uint32_t TSEC_FALCON_SPROT_WDTMR; + uint32_t _0x12A0[0x8]; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBRD_LOW; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBRD_HIGH; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBWR_LOW; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBWR_HIGH; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBRD_LOW; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBRD_HIGH; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBWR_LOW; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBWR_HIGH; + uint32_t TSEC_FALCON_DMAINFO_CTL; + uint32_t _0x12E4[0x47]; + uint32_t TSEC_SCP_CTL0; /* Secure Co-processor registers. */ + uint32_t TSEC_SCP_CTL1; + uint32_t TSEC_SCP_CTL_STAT; + uint32_t TSEC_SCP_CTL_LOCK; + uint32_t TSEC_SCP_CFG; + uint32_t TSEC_SCP_CTL_SCP; + uint32_t TSEC_SCP_CTL_PKEY; + uint32_t TSEC_SCP_CTL_DBG; + uint32_t TSEC_SCP_DBG0; + uint32_t TSEC_SCP_DBG1; + uint32_t TSEC_SCP_DBG2; + uint32_t _0x142C; + uint32_t TSEC_SCP_CMD; + uint32_t _0x1434[0x7]; + uint32_t TSEC_SCP_STAT0; + uint32_t TSEC_SCP_STAT1; + uint32_t TSEC_SCP_STAT2; + uint32_t _0x145C[0x5]; + uint32_t TSEC_SCP_RND_STAT0; + uint32_t TSEC_SCP_RND_STAT1; + uint32_t _0x1478[0x2]; + uint32_t TSEC_SCP_IRQSTAT; + uint32_t TSEC_SCP_IRQMASK; + uint32_t _0x1488[0x2]; + uint32_t TSEC_SCP_ACL_ERR; + uint32_t TSEC_SCP_SEC_ERR; + uint32_t TSEC_SCP_CMD_ERR; + uint32_t _0x149C[0x19]; + uint32_t TSEC_RND_CTL0; /* Random Number Generator registers. */ + uint32_t TSEC_RND_CTL1; + uint32_t TSEC_RND_CTL2; + uint32_t TSEC_RND_CTL3; + uint32_t TSEC_RND_CTL4; + uint32_t TSEC_RND_CTL5; + uint32_t TSEC_RND_CTL6; + uint32_t TSEC_RND_CTL7; + uint32_t TSEC_RND_CTL8; + uint32_t TSEC_RND_CTL9; + uint32_t TSEC_RND_CTL10; + uint32_t TSEC_RND_CTL11; + uint32_t _0x1530[0x34]; + uint32_t TSEC_TFBIF_CTL; /* Tegra Framebuffer Interface registers. */ + uint32_t TSEC_TFBIF_MCCIF_FIFOCTRL; + uint32_t TSEC_TFBIF_THROTTLE; + uint32_t TSEC_TFBIF_DBG_STAT0; + uint32_t TSEC_TFBIF_DBG_STAT1; + uint32_t TSEC_TFBIF_DBG_RDCOUNT_LO; + uint32_t TSEC_TFBIF_DBG_RDCOUNT_HI; + uint32_t TSEC_TFBIF_DBG_WRCOUNT_LO; + uint32_t TSEC_TFBIF_DBG_WRCOUNT_HI; + uint32_t TSEC_TFBIF_DBG_R32COUNT; + uint32_t TSEC_TFBIF_DBG_R64COUNT; + uint32_t TSEC_TFBIF_DBG_R128COUNT; + uint32_t _0x1630; + uint32_t TSEC_TFBIF_MCCIF_FIFOCTRL1; + uint32_t TSEC_TFBIF_WRR_RDP; + uint32_t _0x163C; + uint32_t TSEC_TFBIF_SPROT_EMEM; + uint32_t TSEC_TFBIF_TRANSCFG; + uint32_t TSEC_TFBIF_REGIONCFG; + uint32_t TSEC_TFBIF_ACTMON_ACTIVE_MASK; + uint32_t TSEC_TFBIF_ACTMON_ACTIVE_BORPS; + uint32_t TSEC_TFBIF_ACTMON_ACTIVE_WEIGHT; + uint32_t _0x1658[0x2]; + uint32_t TSEC_TFBIF_ACTMON_MCB_MASK; + uint32_t TSEC_TFBIF_ACTMON_MCB_BORPS; + uint32_t TSEC_TFBIF_ACTMON_MCB_WEIGHT; + uint32_t _0x166C; + uint32_t TSEC_TFBIF_THI_TRANSPROP; + uint32_t _0x1674[0x17]; + uint32_t TSEC_CG; /* Clock Gate registers. */ + uint32_t _0x16D4[0xB]; + uint32_t TSEC_BAR0_CTL; /* HOST1X device DMA registers. */ + uint32_t TSEC_BAR0_ADDR; + uint32_t TSEC_BAR0_DATA; + uint32_t TSEC_BAR0_TIMEOUT; + uint32_t _0x1710[0x3C]; + uint32_t TSEC_TEGRA_FALCON_IP_VER; /* Miscellaneous registers. */ + uint32_t _0x1804[0xD]; + uint32_t TSEC_TEGRA_CTL; + uint32_t _0x183C[0x31]; } tegra_tsec_t; static inline volatile tegra_tsec_t *tsec_get_regs(void) diff --git a/sept/sept-primary/src/fuse.c b/sept/sept-primary/src/fuse.c index 9026e39b0..57120207a 100644 --- a/sept/sept-primary/src/fuse.c +++ b/sept/sept-primary/src/fuse.c @@ -20,210 +20,214 @@ #include "car.h" #include "fuse.h" +#include "pmc.h" #include "timers.h" /* Prototypes for internal commands. */ -void fuse_make_regs_visible(void); - void fuse_enable_power(void); void fuse_disable_power(void); void fuse_wait_idle(void); /* Initialize the fuse driver */ void fuse_init(void) { - fuse_make_regs_visible(); -} - -/* Make all fuse registers visible */ -void fuse_make_regs_visible(void) { + /* Make all fuse registers visible. */ clkrst_enable_fuse_regs(true); } -/* Enable power to the fuse hardware array */ +/* Disable access to the private key and set the TZ sticky bit. */ +void fuse_disable_private_key(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_PRIVATEKEYDISABLE = 0x10; +} + +/* Disables all fuse programming. */ +void fuse_disable_programming(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_DISABLEREGPROGRAM = 1; +} + +/* Enable power to the fuse hardware array. */ void fuse_enable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 1; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */ + mdelay(1); + pmc->fuse_control |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */ + mdelay(1); } -/* Disable power to the fuse hardware array */ +/* Disable power to the fuse hardware array. */ void fuse_disable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 0; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */ + mdelay(1); + pmc->fuse_control |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */ + mdelay(1); } -/* Wait for the fuse driver to go idle */ +/* Wait for the fuse driver to go idle. */ void fuse_wait_idle(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); uint32_t ctrl_val = 0; /* Wait for STATE_IDLE */ while ((ctrl_val & (0xF0000)) != 0x40000) - { - udelay(1); - ctrl_val = fuse->FUSE_CTRL; - } + ctrl_val = fuse->FUSE_FUSECTRL; } -/* Read a fuse from the hardware array */ +/* Read a fuse from the hardware array. */ uint32_t fuse_hw_read(uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address */ - fuse->FUSE_REG_ADDR = addr; + /* Program the target address. */ + fuse->FUSE_FUSEADDR = addr; - /* Enable read operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable read operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x1; /* Set FUSE_READ command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x1; /* Set READ command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); - return fuse->FUSE_REG_READ; + return fuse->FUSE_FUSERDATA; } -/* Write a fuse in the hardware array */ +/* Write a fuse in the hardware array. */ void fuse_hw_write(uint32_t value, uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address and value */ - fuse->FUSE_REG_ADDR = addr; - fuse->FUSE_REG_WRITE = value; + /* Program the target address and value. */ + fuse->FUSE_FUSEADDR = addr; + fuse->FUSE_FUSEWDATA = value; - /* Enable write operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable write operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x2; /* Set FUSE_WRITE command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x2; /* Set WRITE command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); } -/* Sense the fuse hardware array into the shadow cache */ +/* Sense the fuse hardware array into the shadow cache. */ void fuse_hw_sense(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); /* Enable sense operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x3; /* Set FUSE_SENSE command */ - fuse->FUSE_CTRL = ctrl_val; - + ctrl_val |= 0x3; /* Set SENSE_CTRL command */ + fuse->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ fuse_wait_idle(); } -/* Disables all fuse programming. */ -void fuse_disable_programming(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_DIS_PGM = 1; -} - -/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */ -void fuse_secondary_private_key_disable(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PRIVATEKEYDISABLE = 0x10; -} - - -/* Read the SKU info register from the shadow cache */ +/* Read the SKU info register from the shadow cache. */ uint32_t fuse_get_sku_info(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); return fuse_chip->FUSE_SKU_INFO; } -/* Read the bootrom patch version from a register in the shadow cache */ +/* Read the bootrom patch version from a register in the shadow cache. */ uint32_t fuse_get_bootrom_patch_version(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return fuse_chip->FUSE_SOC_SPEEDO_1; + return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB; } /* Read a spare bit register from the shadow cache */ uint32_t fuse_get_spare_bit(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 32) { + if (idx < 32) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_SPARE_BIT[idx]; + } else { return 0; } - - return fuse_chip->FUSE_SPARE_BIT[idx]; } -/* Read a reserved ODM register from the shadow cache */ +/* Read a reserved ODM register from the shadow cache. */ uint32_t fuse_get_reserved_odm(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 8) { + if (idx < 8) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_RESERVED_ODM[idx]; + } else { return 0; } - - return fuse_chip->FUSE_RESERVED_ODM[idx]; } -/* Derive the Device ID using values in the shadow cache */ +/* Get the DRAM ID using values in the shadow cache. */ +uint32_t fuse_get_dram_id(void) { + return ((fuse_get_reserved_odm(4) >> 3) & 0x7); +} + +/* Derive the Device ID using values in the shadow cache. */ uint64_t fuse_get_device_id(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint64_t device_id = 0; - uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0; - uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; + uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint64_t derived_lot_code = 0; for (unsigned int i = 0; i < 5; i++) { derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F); } derived_lot_code &= 0x03FFFFFF; - + device_id |= y_coord << 0; device_id |= x_coord << 9; device_id |= wafer_id << 18; device_id |= derived_lot_code << 24; device_id |= fab_code << 50; + return device_id; } -/* Get the DRAM ID using values in the shadow cache */ -uint32_t fuse_get_dram_id(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7; -} - -/* Derive the Hardware Type using values in the shadow cache */ -uint32_t fuse_get_hardware_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); +/* Derive the Hardware Type using values in the shadow cache. */ +uint32_t fuse_get_hardware_type(uint32_t mkey_rev) { + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1)); - /* This function is very different between 4.x and < 4.x */ - uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1); - - /* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) { - static const uint32_t types[] = {0,1,4,3}; - - hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C; - hardware_type--; - return hardware_type > 3 ? 4 : types[hardware_type]; - } else {*/ + /* Firmware from versions 1.0.0 to 3.0.2. */ + if (mkey_rev < 0x03) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); if (hardware_type >= 1) { - return hardware_type > 2 ? 3 : hardware_type - 1; + return (hardware_type > 2) ? 3 : hardware_type - 1; } else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) { return 0; } else { return 3; } -// } + } else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */ + static const uint32_t types[] = {0,1,4,3}; + hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C); + hardware_type--; + return (hardware_type > 3) ? 4 : types[hardware_type]; + } else { /* Firmware versions from 7.0.0 onwards. */ + /* Always return 0 in retail. */ + return 0; + } } -/* Derive the Retail Type using values in the shadow cache */ +/* Derive the Retail Type using values in the shadow cache. */ uint32_t fuse_get_retail_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - /* Retail type = IS_RETAIL | UNIT_TYPE */ - uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3); + /* Retail Type = IS_RETAIL | UNIT_TYPE. */ + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3)); if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */ return 1; } else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */ @@ -237,17 +241,17 @@ void fuse_get_hardware_info(void *dst) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint32_t hw_info[0x4]; - uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F; - uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0; - uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF; - uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; - uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF; + uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F; + uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF; + uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF; - /* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ - hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse)); + /* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ + hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved)); hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2)); hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6)); hw_info[3] = (uint32_t)(vendor_code); diff --git a/sept/sept-primary/src/fuse.h b/sept/sept-primary/src/fuse.h index 9d92503e2..d118b53dc 100644 --- a/sept/sept-primary/src/fuse.h +++ b/sept/sept-primary/src/fuse.h @@ -23,154 +23,167 @@ #define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n) typedef struct { - uint32_t FUSE_CTRL; - uint32_t FUSE_REG_ADDR; - uint32_t FUSE_REG_READ; - uint32_t FUSE_REG_WRITE; - uint32_t FUSE_TIME_RD1; - uint32_t FUSE_TIME_RD2; - uint32_t FUSE_TIME_PGM1; - uint32_t FUSE_TIME_PGM2; - uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSECTRL; + uint32_t FUSE_FUSEADDR; + uint32_t FUSE_FUSERDATA; + uint32_t FUSE_FUSEWDATA; + uint32_t FUSE_FUSETIME_RD1; + uint32_t FUSE_FUSETIME_RD2; + uint32_t FUSE_FUSETIME_PGM1; + uint32_t FUSE_FUSETIME_PGM2; + uint32_t FUSE_PRIV2INTFC_START; uint32_t FUSE_FUSEBYPASS; uint32_t FUSE_PRIVATEKEYDISABLE; - uint32_t FUSE_DIS_PGM; - uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_DISABLEREGPROGRAM; + uint32_t FUSE_WRITE_ACCESS_SW; uint32_t FUSE_PWR_GOOD_SW; - uint32_t _0x38[0x32]; + uint32_t _0x38; + uint32_t FUSE_PRIV2RESHIFT; + uint32_t _0x40[0x3]; + uint32_t FUSE_FUSETIME_RD3; + uint32_t _0x50[0xC]; + uint32_t FUSE_PRIVATE_KEY0_NONZERO; + uint32_t FUSE_PRIVATE_KEY1_NONZERO; + uint32_t FUSE_PRIVATE_KEY2_NONZERO; + uint32_t FUSE_PRIVATE_KEY3_NONZERO; + uint32_t FUSE_PRIVATE_KEY4_NONZERO; + uint32_t _0x90[0x1C]; } tegra_fuse_t; typedef struct { uint32_t FUSE_PRODUCTION_MODE; - uint32_t _0x4; - uint32_t _0x8; - uint32_t _0xC; + uint32_t FUSE_JTAG_SECUREID_VALID; + uint32_t FUSE_ODM_LOCK; + uint32_t FUSE_OPT_OPENGL_EN; uint32_t FUSE_SKU_INFO; - uint32_t FUSE_CPU_SPEEDO_0; - uint32_t FUSE_CPU_IDDQ; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t _0x24; - uint32_t FUSE_FT_REV; - uint32_t FUSE_CPU_SPEEDO_1; - uint32_t FUSE_CPU_SPEEDO_2; - uint32_t FUSE_SOC_SPEEDO_0; - uint32_t FUSE_SOC_SPEEDO_1; - uint32_t FUSE_SOC_SPEEDO_2; - uint32_t FUSE_SOC_IDDQ; - uint32_t _0x44; + uint32_t FUSE_CPU_SPEEDO_0_CALIB; + uint32_t FUSE_CPU_IDDQ_CALIB; + uint32_t FUSE_DAC_CRT_CALIB; + uint32_t FUSE_DAC_HDTV_CALIB; + uint32_t FUSE_DAC_SDTV_CALIB; + uint32_t FUSE_OPT_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1_CALIB; + uint32_t FUSE_CPU_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_SPEEDO_0_CALIB; + uint32_t FUSE_SOC_SPEEDO_1_CALIB; + uint32_t FUSE_SOC_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_IDDQ_CALIB; + uint32_t FUSE_RESERVED_PRODUCTION_WP; uint32_t FUSE_FA; - uint32_t _0x4C; - uint32_t _0x50; - uint32_t _0x54; - uint32_t _0x58; - uint32_t _0x5C; - uint32_t _0x60; + uint32_t FUSE_RESERVED_PRODUCTION; + uint32_t FUSE_HDMI_LANE0_CALIB; + uint32_t FUSE_HDMI_LANE1_CALIB; + uint32_t FUSE_HDMI_LANE2_CALIB; + uint32_t FUSE_HDMI_LANE3_CALIB; + uint32_t FUSE_ENCRYPTION_RATE; uint32_t FUSE_PUBLIC_KEY[0x8]; - uint32_t FUSE_TSENSOR_1; - uint32_t FUSE_TSENSOR_2; - uint32_t _0x8C; - uint32_t FUSE_CP_REV; - uint32_t _0x94; - uint32_t FUSE_TSENSOR_0; - uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_TSENSOR1_CALIB; + uint32_t FUSE_TSENSOR2_CALIB; + uint32_t FUSE_VSENSOR_CALIB; + uint32_t FUSE_OPT_CP_REV; + uint32_t FUSE_OPT_PFG; + uint32_t FUSE_TSENSOR0_CALIB; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; - uint32_t FUSE_PRIVATE_KEY[0x4]; - uint32_t FUSE_DEVICE_KEY; - uint32_t _0xB8; - uint32_t _0xBC; + uint32_t FUSE_PRIVATE_KEY[0x5]; + uint32_t FUSE_ARM_JTAG_DIS; + uint32_t FUSE_BOOT_DEVICE_INFO; uint32_t FUSE_RESERVED_SW; - uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_OPT_VP9_DISABLE; uint32_t FUSE_RESERVED_ODM[0x8]; - uint32_t _0xE8; - uint32_t _0xEC; - uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_OBS_DIS; + uint32_t FUSE_NOR_INFO; + uint32_t FUSE_USB_CALIB; uint32_t FUSE_SKU_DIRECT_CONFIG; - uint32_t _0xF8; - uint32_t _0xFC; - uint32_t FUSE_VENDOR_CODE; - uint32_t FUSE_FAB_CODE; - uint32_t FUSE_LOT_CODE_0; - uint32_t FUSE_LOT_CODE_1; - uint32_t FUSE_WAFER_ID; - uint32_t FUSE_X_COORDINATE; - uint32_t FUSE_Y_COORDINATE; - uint32_t _0x11C; - uint32_t _0x120; + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; + uint32_t FUSE_PACKAGE_INFO; + uint32_t FUSE_OPT_VENDOR_CODE; + uint32_t FUSE_OPT_FAB_CODE; + uint32_t FUSE_OPT_LOT_CODE_0; + uint32_t FUSE_OPT_LOT_CODE_1; + uint32_t FUSE_OPT_WAFER_ID; + uint32_t FUSE_OPT_X_COORDINATE; + uint32_t FUSE_OPT_Y_COORDINATE; + uint32_t FUSE_OPT_SEC_DEBUG_EN; + uint32_t FUSE_OPT_OPS_RESERVED; uint32_t FUSE_SATA_CALIB; - uint32_t FUSE_GPU_IDDQ; - uint32_t FUSE_TSENSOR_3; - uint32_t _0x130; - uint32_t _0x134; - uint32_t _0x138; - uint32_t _0x13C; - uint32_t _0x140; - uint32_t _0x144; + uint32_t FUSE_GPU_IDDQ_CALIB; + uint32_t FUSE_TSENSOR3_CALIB; + uint32_t FUSE_SKU_BOND_OUT_L; + uint32_t FUSE_SKU_BOND_OUT_H; + uint32_t FUSE_SKU_BOND_OUT_U; + uint32_t FUSE_SKU_BOND_OUT_V; + uint32_t FUSE_SKU_BOND_OUT_W; + uint32_t FUSE_OPT_SAMPLE_TYPE; uint32_t FUSE_OPT_SUBREVISION; - uint32_t _0x14C; - uint32_t _0x150; - uint32_t FUSE_TSENSOR_4; - uint32_t FUSE_TSENSOR_5; - uint32_t FUSE_TSENSOR_6; - uint32_t FUSE_TSENSOR_7; - uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_OPT_SW_RESERVED_0; + uint32_t FUSE_OPT_SW_RESERVED_1; + uint32_t FUSE_TSENSOR4_CALIB; + uint32_t FUSE_TSENSOR5_CALIB; + uint32_t FUSE_TSENSOR6_CALIB; + uint32_t FUSE_TSENSOR7_CALIB; + uint32_t FUSE_OPT_PRIV_SEC_EN; uint32_t FUSE_PKC_DISABLE; uint32_t _0x16C; uint32_t _0x170; uint32_t _0x174; uint32_t _0x178; - uint32_t _0x17C; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; uint32_t FUSE_TSENSOR_COMMON; - uint32_t _0x184; - uint32_t _0x188; - uint32_t _0x18C; - uint32_t _0x190; + uint32_t FUSE_OPT_CP_BIN; + uint32_t FUSE_OPT_GPU_DISABLE; + uint32_t FUSE_OPT_FT_BIN; + uint32_t FUSE_OPT_DONE_MAP; uint32_t _0x194; - uint32_t _0x198; - uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t FUSE_APB2JTAG_DISABLE; + uint32_t FUSE_ODM_INFO; uint32_t _0x1A0; uint32_t _0x1A4; - uint32_t _0x1A8; + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; uint32_t _0x1AC; uint32_t _0x1B0; uint32_t _0x1B4; uint32_t _0x1B8; uint32_t _0x1BC; - uint32_t _0x1D0; - uint32_t FUSE_TSENSOR_8; + uint32_t FUSE_WOA_SKU_FLAG; + uint32_t FUSE_ECO_RESERVE_1; + uint32_t FUSE_GCPLEX_CONFIG_FUSE; + uint32_t FUSE_PRODUCTION_MONTH; + uint32_t FUSE_RAM_REPAIR_INDICATOR; + uint32_t FUSE_TSENSOR9_CALIB; uint32_t _0x1D8; - uint32_t _0x1DC; - uint32_t _0x1E0; - uint32_t _0x1E4; - uint32_t _0x1E8; - uint32_t _0x1EC; - uint32_t _0x1F0; - uint32_t _0x1F4; - uint32_t _0x1F8; + uint32_t FUSE_VMIN_CALIBRATION; + uint32_t FUSE_AGING_SENSOR_CALIBRATION; + uint32_t FUSE_DEBUG_AUTHENTICATION; + uint32_t FUSE_SECURE_PROVISION_INDEX; + uint32_t FUSE_SECURE_PROVISION_INFO; + uint32_t FUSE_OPT_GPU_DISABLE_CP1; + uint32_t FUSE_SPARE_ENDIS; + uint32_t FUSE_ECO_RESERVE_0; uint32_t _0x1FC; uint32_t _0x200; - uint32_t FUSE_RESERVED_CALIB; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t _0x214; - uint32_t _0x218; - uint32_t FUSE_TSENSOR_9; - uint32_t _0x220; - uint32_t _0x224; - uint32_t _0x228; - uint32_t _0x22C; - uint32_t _0x230; - uint32_t _0x234; - uint32_t _0x238; - uint32_t _0x23C; - uint32_t _0x240; - uint32_t _0x244; - uint32_t _0x248; - uint32_t _0x24C; + uint32_t FUSE_RESERVED_CALIB0; + uint32_t FUSE_RESERVED_CALIB1; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1; + uint32_t FUSE_OPT_CPU_DISABLE; + uint32_t FUSE_OPT_CPU_DISABLE_CP1; + uint32_t FUSE_TSENSOR10_CALIB; + uint32_t FUSE_TSENSOR10_CALIB_AUX; + uint32_t FUSE_OPT_RAM_SVOP_DP; + uint32_t FUSE_OPT_RAM_SVOP_PDP; + uint32_t FUSE_OPT_RAM_SVOP_REG; + uint32_t FUSE_OPT_RAM_SVOP_SP; + uint32_t FUSE_OPT_RAM_SVOP_SMPDP; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2; + uint32_t FUSE_OPT_CPU_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_DISABLE_CP2; uint32_t FUSE_USB_CALIB_EXT; - uint32_t _0x254; - uint32_t _0x258; + uint32_t FUSE_RESERVED_FIELD; + uint32_t FUSE_OPT_ECC_EN; uint32_t _0x25C; uint32_t _0x260; uint32_t _0x264; @@ -179,35 +192,36 @@ typedef struct { uint32_t _0x270; uint32_t _0x274; uint32_t _0x278; - uint32_t _0x27C; + uint32_t FUSE_SPARE_REALIGNMENT_REG; uint32_t FUSE_SPARE_BIT[0x20]; } tegra_fuse_chip_t; -static inline volatile tegra_fuse_t *fuse_get_regs(void) { +static inline volatile tegra_fuse_t *fuse_get_regs(void) +{ return (volatile tegra_fuse_t *)FUSE_BASE; } -static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) { +static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) +{ return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE; } void fuse_init(void); - -uint32_t fuse_hw_read(uint32_t addr); -void fuse_hw_write(uint32_t value, uint32_t addr); -void fuse_hw_sense(void); void fuse_disable_programming(void); -void fuse_secondary_private_key_disable(void); +void fuse_disable_private_key(void); uint32_t fuse_get_sku_info(void); uint32_t fuse_get_spare_bit(uint32_t idx); uint32_t fuse_get_reserved_odm(uint32_t idx); - uint32_t fuse_get_bootrom_patch_version(void); uint64_t fuse_get_device_id(void); uint32_t fuse_get_dram_id(void); -uint32_t fuse_get_hardware_type(void); +uint32_t fuse_get_hardware_type(uint32_t mkey_rev); uint32_t fuse_get_retail_type(void); void fuse_get_hardware_info(void *dst); +uint32_t fuse_hw_read(uint32_t addr); +void fuse_hw_write(uint32_t value, uint32_t addr); +void fuse_hw_sense(void); + #endif diff --git a/sept/sept-primary/src/main.c b/sept/sept-primary/src/main.c index 62a5c15d6..5b939c996 100644 --- a/sept/sept-primary/src/main.c +++ b/sept/sept-primary/src/main.c @@ -94,10 +94,10 @@ static void mbist_workaround(void) static int tsec_dma_wait_idle() { volatile tegra_tsec_t *tsec = tsec_get_regs(); - uint32_t timeout = (get_time_us() + 10000000); + uint32_t timeout = (get_time_ms() + 10000); - while (!(tsec->FALCON_DMATRFCMD & 2)) - if (get_time_us() > timeout) + while (!(tsec->TSEC_FALCON_DMATRFCMD & 2)) + if (get_time_ms() > timeout) return 0; return 1; @@ -113,13 +113,29 @@ static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t ph else cmd = 0x10; - tsec->FALCON_DMATRFMOFFS = flcn_offset; - tsec->FALCON_DMATRFFBOFFS = phys_offset; - tsec->FALCON_DMATRFCMD = cmd; + tsec->TSEC_FALCON_DMATRFMOFFS = flcn_offset; + tsec->TSEC_FALCON_DMATRFFBOFFS = phys_offset; + tsec->TSEC_FALCON_DMATRFCMD = cmd; return tsec_dma_wait_idle(); } +static int tsec_kfuse_wait_ready() +{ + uint32_t timeout = (get_time_ms() + 10000); + + /* Wait for STATE_DONE. */ + while (!(KFUSE_STATE & 0x10000)) + if (get_time_ms() > timeout) + return 0; + + /* Check for STATE_CRCPASS. */ + if (!(KFUSE_STATE & 0x20000)) + return 0; + + return 1; +} + int load_tsec_fw(void) { volatile uint32_t* tsec_fw = (volatile uint32_t*)0x40010F00; const uint32_t tsec_fw_length = MAKE_REG32(0x40010EFC); @@ -134,12 +150,27 @@ int load_tsec_fw(void) { clkrst_reboot(CARDEVICE_SOR1); clkrst_reboot(CARDEVICE_KFUSE); + /* Make sure KFUSE is ready. */ + if (!tsec_kfuse_wait_ready()) + { + /* Disable clocks. */ + clkrst_disable(CARDEVICE_KFUSE); + clkrst_disable(CARDEVICE_SOR1); + clkrst_disable(CARDEVICE_SOR0); + clkrst_disable(CARDEVICE_SOR_SAFE); + clkrst_disable(CARDEVICE_TSEC); + clkrst_disable(CARDEVICE_HOST1X); + + return -1; + } + /* Configure Falcon. */ - tsec->FALCON_DMACTL = 0; - tsec->FALCON_IRQMSET = 0xFFF2; - tsec->FALCON_IRQDEST = 0xFFF0; - tsec->FALCON_ITFEN = 3; - + tsec->TSEC_FALCON_DMACTL = 0; + tsec->TSEC_FALCON_IRQMSET = 0xFFF2; + tsec->TSEC_FALCON_IRQDEST = 0xFFF0; + tsec->TSEC_FALCON_ITFEN = 3; + + /* Make sure the DMA block is idle. */ if (!tsec_dma_wait_idle()) { /* Disable clocks. */ @@ -150,11 +181,11 @@ int load_tsec_fw(void) { clkrst_disable(CARDEVICE_TSEC); clkrst_disable(CARDEVICE_HOST1X); - return -1; + return -2; } /* Load firmware. */ - tsec->FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8; + tsec->TSEC_FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8; for (uint32_t addr = 0; addr < tsec_fw_length; addr += 0x100) { if (!tsec_dma_phys_to_flcn(true, addr, addr)) @@ -167,26 +198,24 @@ int load_tsec_fw(void) { clkrst_disable(CARDEVICE_TSEC); clkrst_disable(CARDEVICE_HOST1X); - return -2; + return -3; } } - /* Unknown host1x write. */ + /* Write magic value to HOST1X scratch register. */ MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA; - /* Execute firmware. */ - tsec->FALCON_SCRATCH1 = 0; - tsec->FALCON_SCRATCH0 = 1; - tsec->FALCON_BOOTVEC = 0; - tsec->FALCON_CPUCTL = 2; + tsec->TSEC_FALCON_MAILBOX1 = 0; + tsec->TSEC_FALCON_MAILBOX0 = 1; + tsec->TSEC_FALCON_BOOTVEC = 0; + tsec->TSEC_FALCON_CPUCTL = 2; while (true) { /* Yield to Nintendo's TSEC firmware. */ } } - int main(void) { /* Setup vectors */ setup_exception_vectors(); diff --git a/sept/sept-primary/src/se.c b/sept/sept-primary/src/se.c index 0a22229b0..188176aa7 100644 --- a/sept/sept-primary/src/se.c +++ b/sept/sept-primary/src/se.c @@ -39,20 +39,20 @@ void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) { } void se_check_error_status_reg(void) { - if (se_get_regs()->ERR_STATUS_REG) { + if (se_get_regs()->SE_ERR_STATUS) { generic_panic(); } } void se_check_for_error(void) { volatile tegra_se_t *se = se_get_regs(); - if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) { + if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) { generic_panic(); } } void se_verify_flags_cleared(void) { - if (se_get_regs()->FLAGS_REG & 3) { + if (se_get_regs()->SE_STATUS & 3) { generic_panic(); } } @@ -67,12 +67,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { - se->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -87,12 +87,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { /* TODO: Why are flags assigned this way? */ - se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -105,8 +105,8 @@ void clear_aes_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -120,13 +120,13 @@ void clear_rsa_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + se->SE_RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = 0; } } @@ -138,8 +138,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { } for (size_t i = 0; i < (key_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = read32le(key, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i); } } @@ -151,13 +151,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_ } for (size_t i = 0; i < (modulus_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; - se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); } for (size_t i = 0; i < (exp_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); } g_se_modulus_sizes[keyslot] = modulus_size; @@ -172,8 +172,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { } for (size_t i = 0; i < (iv_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i); } } @@ -185,14 +185,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) { } for (size_t i = 0; i < (0x10 >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } void set_se_ctr(const void *ctr) { for (unsigned int i = 0; i < 4; i++) { - se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4); } } @@ -203,10 +203,10 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); - se->CRYPTO_REG = keyslot_src << 24; - se->BLOCK_COUNT_REG = 0; - se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; + se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = keyslot_src << 24; + se->SE_CRYPTO_LAST_BLOCK = 0; + se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8; trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); } @@ -224,10 +224,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co stack_buf[i] = *((uint8_t *)src + src_size - i - 1); } - se->CONFIG_REG = (ALG_RSA | DST_RSAREG); - se->RSA_CONFIG = keyslot << 24; - se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + se->SE_CONFIG = (ALG_RSA | DST_RSAREG); + se->SE_RSA_CONFIG = keyslot << 24; + se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1; + se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2; trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size); se_get_exp_mod_output(dst, dst_size); @@ -245,7 +245,7 @@ void se_get_exp_mod_output(void *buf, size_t size) { /* Copy endian swapped output. */ while (num_dwords) { - *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset); + *p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset); offset += 4; p_out--; num_dwords--; @@ -314,15 +314,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v ll_init(&out_ll, dst, dst_size); /* Set the LLs. */ - se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); - se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll); + se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); + se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = op; + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = op; - while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -340,7 +340,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } /* Trigger AES operation. */ - se_get_regs()->BLOCK_COUNT_REG = 0; + se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -358,15 +358,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo unsigned int num_blocks = src_size >> 4; /* Unknown what this write does, but official code writes it for CTR mode. */ - se->SPARE_0 = 1; - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x91E; + se->SE_SPARE = 1; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E; set_se_ctr(ctr); /* Handle any aligned blocks. */ size_t aligned_size = (size_t)num_blocks << 4; if (aligned_size) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size); } @@ -388,8 +388,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - se->CRYPTO_REG = keyslot << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -408,8 +408,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot << 24; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -472,13 +472,13 @@ void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keys /* Encrypt/Decrypt. */ if (encrypt) { - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24 | 0x100; } else { - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24; } - se->BLOCK_COUNT_REG = (size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, size, src, size); /* XOR. */ @@ -524,16 +524,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - se->CRYPTO_REG = (keyslot << 24) | (0x145); + se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - se->BLOCK_COUNT_REG = num_blocks - 2; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2; trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); - se->CRYPTO_REG |= 0x80; + se->SE_CRYPTO_CONFIG |= 0x80; } /* Create final block. */ @@ -550,12 +550,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con } /* Perform last operation. */ - se->BLOCK_COUNT_REG = 0; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2); } } @@ -573,10 +573,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x144; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144; set_aes_keyslot_iv(keyslot, iv, 0x10); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -585,23 +585,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { volatile tegra_se_t *se = se_get_regs(); /* Setup config for SHA256, size = BITS(src_size) */ - se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); - se->SHA_CONFIG_REG = 1; - se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3); - se->_0x208 = 0; - se->_0x20C = 0; - se->_0x210 = 0; - se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3); - se->_0x218 = 0; - se->_0x21C = 0; - se->_0x220 = 0; + se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + se->SE_SHA_CONFIG = 1; + se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LENGTH[1] = 0; + se->SE_SHA_MSG_LENGTH[2] = 0; + se->SE_SHA_MSG_LENGTH[3] = 0; + se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LEFT[1] = 0; + se->SE_SHA_MSG_LEFT[2] = 0; + se->SE_SHA_MSG_LEFT[3] = 0; /* Trigger the operation. */ trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); /* Copy output hash. */ for (unsigned int i = 0; i < (0x20 >> 2); i++) { - ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2); } } @@ -617,12 +617,12 @@ void se_initialize_rng(unsigned int keyslot) { /* This will be discarded, when done. */ uint8_t ALIGN(16) output_buf[0x10]; - se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ - se->RNG_RESEED_INTERVAL_REG = 70001; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 5; - se->BLOCK_COUNT_REG = 0; + se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */ + se->SE_RNG_RESEED_INTERVAL = 70001; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 5; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0); } @@ -635,12 +635,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) { uint32_t num_blocks = size >> 4; size_t aligned_size = num_blocks << 4; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; if (num_blocks >= 1) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0); } if (size > aligned_size) { diff --git a/sept/sept-primary/src/se.h b/sept/sept-primary/src/se.h index b6ad69866..5e8e46900 100644 --- a/sept/sept-primary/src/se.h +++ b/sept/sept-primary/src/se.h @@ -92,71 +92,59 @@ #define RSA_2048_BYTES 0x100 typedef struct { - uint32_t _0x0; - uint32_t _0x4; - uint32_t OPERATION_REG; - uint32_t INT_ENABLE_REG; - uint32_t INT_STATUS_REG; - uint32_t CONFIG_REG; - uint32_t IN_LL_ADDR_REG; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t OUT_LL_ADDR_REG; - uint32_t _0x28; - uint32_t _0x2C; - uint8_t HASH_RESULT_REG[0x20]; - uint8_t _0x50[0x20]; - uint32_t CONTEXT_SAVE_CONFIG_REG; - uint8_t _0x74[0x18C]; - uint32_t SHA_CONFIG_REG; - uint32_t SHA_MSG_LENGTH_REG; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t SHA_MSG_LEFT_REG; - uint32_t _0x218; - uint32_t _0x21C; - uint32_t _0x220; - uint32_t _0x224; - uint8_t _0x228[0x58]; - uint32_t AES_KEY_READ_DISABLE_REG; - uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C4[0x3C]; - uint32_t _0x300; - uint32_t CRYPTO_REG; - uint32_t CRYPTO_CTR_REG[4]; - uint32_t BLOCK_COUNT_REG; - uint32_t AES_KEYTABLE_ADDR; - uint32_t AES_KEYTABLE_DATA; - uint32_t _0x324; - uint32_t _0x328; - uint32_t _0x32C; - uint32_t CRYPTO_KEYTABLE_DST_REG; - uint8_t _0x334[0xC]; - uint32_t RNG_CONFIG_REG; - uint32_t RNG_SRC_CONFIG_REG; - uint32_t RNG_RESEED_INTERVAL_REG; - uint8_t _0x34C[0xB4]; - uint32_t RSA_CONFIG; - uint32_t RSA_KEY_SIZE_REG; - uint32_t RSA_EXP_SIZE_REG; - uint32_t RSA_KEY_READ_DISABLE_REG; - uint32_t RSA_KEYSLOT_FLAGS[2]; - uint32_t _0x418; - uint32_t _0x41C; - uint32_t RSA_KEYTABLE_ADDR; - uint32_t RSA_KEYTABLE_DATA; - uint8_t RSA_OUTPUT[0x100]; - uint8_t _0x528[0x2D8]; - uint32_t FLAGS_REG; - uint32_t ERR_STATUS_REG; - uint32_t _0x808; - uint32_t SPARE_0; - uint32_t _0x810; + uint32_t SE_SE_SECURITY; + uint32_t SE_TZRAM_SECURITY; + uint32_t SE_OPERATION; + uint32_t SE_INT_ENABLE; + uint32_t SE_INT_STATUS; + uint32_t SE_CONFIG; + uint32_t SE_IN_LL_ADDR; + uint32_t SE_IN_CUR_BYTE_ADDR; + uint32_t SE_IN_CUR_LL_ID; + uint32_t SE_OUT_LL_ADDR; + uint32_t SE_OUT_CUR_BYTE_ADDR; + uint32_t SE_OUT_CUR_LL_ID; + uint32_t SE_HASH_RESULT[0x10]; + uint32_t SE_CTX_SAVE_CONFIG; + uint32_t _0x74[0x63]; + uint32_t SE_SHA_CONFIG; + uint32_t SE_SHA_MSG_LENGTH[0x4]; + uint32_t SE_SHA_MSG_LEFT[0x4]; + uint32_t _0x224[0x17]; + uint32_t SE_CRYPTO_SECURITY_PERKEY; + uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10]; + uint32_t _0x2C4[0x10]; + uint32_t SE_CRYPTO_CONFIG; + uint32_t SE_CRYPTO_LINEAR_CTR[0x4]; + uint32_t SE_CRYPTO_LAST_BLOCK; + uint32_t SE_CRYPTO_KEYTABLE_ADDR; + uint32_t SE_CRYPTO_KEYTABLE_DATA; + uint32_t _0x324[0x3]; + uint32_t SE_CRYPTO_KEYTABLE_DST; + uint32_t _0x334[0x3]; + uint32_t SE_RNG_CONFIG; + uint32_t SE_RNG_SRC_CONFIG; + uint32_t SE_RNG_RESEED_INTERVAL; + uint32_t _0x34C[0x2D]; + uint32_t SE_RSA_CONFIG; + uint32_t SE_RSA_KEY_SIZE; + uint32_t SE_RSA_EXP_SIZE; + uint32_t SE_RSA_SECURITY_PERKEY; + uint32_t SE_RSA_KEYTABLE_ACCESS[0x2]; + uint32_t _0x418[0x2]; + uint32_t SE_RSA_KEYTABLE_ADDR; + uint32_t SE_RSA_KEYTABLE_DATA; + uint32_t SE_RSA_OUTPUT[0x40]; + uint32_t _0x528[0xB6]; + uint32_t SE_STATUS; + uint32_t SE_ERR_STATUS; + uint32_t SE_MISC; + uint32_t SE_SPARE; + uint32_t SE_ENTROPY_DEBUG_COUNTER; uint32_t _0x814; uint32_t _0x818; uint32_t _0x81C; - uint8_t _0x820[0x17E0]; + uint32_t _0x820[0x5F8]; } tegra_se_t; typedef struct { diff --git a/sept/sept-primary/src/timers.h b/sept/sept-primary/src/timers.h index 114768fe4..88776a3a5 100644 --- a/sept/sept-primary/src/timers.h +++ b/sept/sept-primary/src/timers.h @@ -47,6 +47,14 @@ typedef struct { void wait(uint32_t microseconds); +static inline uint32_t get_time_s(void) { + return RTC_SECONDS; +} + +static inline uint32_t get_time_ms(void) { + return (RTC_MILLI_SECONDS | (RTC_SHADOW_SECONDS << 10)); +} + static inline uint32_t get_time_us(void) { return TIMERUS_CNTR_1US_0; } @@ -73,6 +81,21 @@ static inline void udelay(uint32_t usecs) { while (get_time_us() - start < usecs); } +/** + * Delays until a number of usecs have passed since an absolute start time. + */ +static inline void udelay_absolute(uint32_t start, uint32_t usecs) { + while (get_time_us() - start < usecs); +} + +/** + * Delays for a given number of milliseconds. + */ +static inline void mdelay(uint32_t msecs) { + uint32_t start = get_time_ms(); + while (get_time_ms() - start < msecs); +} + __attribute__ ((noreturn)) void watchdog_reboot(void); #endif diff --git a/sept/sept-primary/src/tsec.h b/sept/sept-primary/src/tsec.h index ab04895d5..d580a5e71 100644 --- a/sept/sept-primary/src/tsec.h +++ b/sept/sept-primary/src/tsec.h @@ -23,92 +23,280 @@ #define TSEC_BASE 0x54500000 #define SOR1_BASE 0x54580000 +#define KFUSE_BASE 0x7000FC00 #define SOR1_DP_HDCP_BKSV_LSB MAKE_REG32(SOR1_BASE + 0x1E8) #define SOR1_TMDS_HDCP_BKSV_LSB MAKE_REG32(SOR1_BASE + 0x21C) #define SOR1_TMDS_HDCP_CN_MSB MAKE_REG32(SOR1_BASE + 0x208) #define SOR1_TMDS_HDCP_CN_LSB MAKE_REG32(SOR1_BASE + 0x20C) +#define KFUSE_FUSECTRL MAKE_REG32(KFUSE_BASE + 0x00) +#define KFUSE_FUSEADDR MAKE_REG32(KFUSE_BASE + 0x04) +#define KFUSE_FUSEDATA0 MAKE_REG32(KFUSE_BASE + 0x08) +#define KFUSE_FUSEWRDATA0 MAKE_REG32(KFUSE_BASE + 0x0C) +#define KFUSE_FUSETIME_RD1 MAKE_REG32(KFUSE_BASE + 0x10) +#define KFUSE_FUSETIME_RD2 MAKE_REG32(KFUSE_BASE + 0x14) +#define KFUSE_FUSETIME_PGM1 MAKE_REG32(KFUSE_BASE + 0x18) +#define KFUSE_FUSETIME_PGM2 MAKE_REG32(KFUSE_BASE + 0x1C) +#define KFUSE_REGULATOR MAKE_REG32(KFUSE_BASE + 0x20) +#define KFUSE_PD MAKE_REG32(KFUSE_BASE + 0x24) +#define KFUSE_FUSETIME_RD3 MAKE_REG32(KFUSE_BASE + 0x28) +#define KFUSE_STATE MAKE_REG32(KFUSE_BASE + 0x80) +#define KFUSE_ERRCOUNT MAKE_REG32(KFUSE_BASE + 0x84) +#define KFUSE_KEYADDR MAKE_REG32(KFUSE_BASE + 0x88) +#define KFUSE_KEYS MAKE_REG32(KFUSE_BASE + 0x8C) + typedef struct { - uint8_t _0x0[0x1000]; /* Ignore non Falcon registers. */ - uint32_t FALCON_IRQSSET; - uint32_t FALCON_IRQSCLR; - uint32_t FALCON_IRQSTAT; - uint32_t FALCON_IRQMODE; - uint32_t FALCON_IRQMSET; - uint32_t FALCON_IRQMCLR; - uint32_t FALCON_IRQMASK; - uint32_t FALCON_IRQDEST; - uint8_t _0x1020[0x20]; - uint32_t FALCON_SCRATCH0; - uint32_t FALCON_SCRATCH1; - uint32_t FALCON_ITFEN; - uint32_t FALCON_IDLESTATE; - uint32_t FALCON_CURCTX; - uint32_t FALCON_NXTCTX; - uint8_t _0x1058[0x28]; - uint32_t FALCON_SCRATCH2; - uint32_t FALCON_SCRATCH3; - uint32_t FALCON_PM_SIGNAL; - uint32_t FALCON_PM_MODE; - uint32_t FALCON_DEBUG1; - uint32_t FALCON_DEBUGINFO; - uint32_t FALCON_BREAKPOINT0; - uint32_t FALCON_BREAKPOINT1; - uint32_t FALCON_CGCTL; - uint32_t FALCON_ENGCTL; - uint8_t _0x10A8[0x58]; - uint32_t FALCON_CPUCTL; - uint32_t FALCON_BOOTVEC; - uint32_t FALCON_HWCFG; - uint32_t FALCON_DMACTL; - uint32_t FALCON_DMATRFBASE; - uint32_t FALCON_DMATRFMOFFS; - uint32_t FALCON_DMATRFCMD; - uint32_t FALCON_DMATRFFBOFFS; - uint8_t _0x1120[0x10]; - uint32_t FALCON_CPUCTL_ALIAS; - uint8_t _0x1134[0x20]; - uint32_t FALCON_IMFILLRNG1; - uint32_t FALCON_IMFILLCTL; - uint32_t _0x115C; - uint32_t _0x1160; - uint32_t _0x1164; - uint32_t FALCON_EXTERRADDR; - uint32_t FALCON_EXTERRSTAT; - uint32_t _0x1170; - uint32_t _0x1174; - uint32_t _0x1178; - uint32_t FALCON_CG2; - uint32_t FALCON_CODE_INDEX; - uint32_t FALCON_CODE; - uint32_t FALCON_CODE_VIRT_ADDR; - uint8_t _0x118C[0x34]; - uint32_t FALCON_DATA_INDEX0; - uint32_t FALCON_DATA0; - uint32_t FALCON_DATA_INDEX1; - uint32_t FALCON_DATA1; - uint32_t FALCON_DATA_INDEX2; - uint32_t FALCON_DATA2; - uint32_t FALCON_DATA_INDEX3; - uint32_t FALCON_DATA3; - uint32_t FALCON_DATA_INDEX4; - uint32_t FALCON_DATA4; - uint32_t FALCON_DATA_INDEX5; - uint32_t FALCON_DATA5; - uint32_t FALCON_DATA_INDEX6; - uint32_t FALCON_DATA6; - uint32_t FALCON_DATA_INDEX7; - uint32_t FALCON_DATA7; - uint32_t FALCON_ICD_CMD; - uint32_t FALCON_ICD_ADDR; - uint32_t FALCON_ICD_WDATA; - uint32_t FALCON_ICD_RDATA; - uint8_t _0x1210[0x30]; - uint32_t FALCON_SCTL; - uint8_t _0x1244[0x1430-0x1244]; /* Ignore non Falcon registers. */ - uint32_t TSEC_SCP_INSN_STAT; - uint8_t _0x1434[0x1244+0x5F8-0x1434]; /* Ignore non Falcon registers. */ + uint32_t TSEC_THI_INCR_SYNCPT; /* Tegra Host Interface registers. */ + uint32_t TSEC_THI_INCR_SYNCPT_CTRL; + uint32_t TSEC_THI_INCR_SYNCPT_ERR; + uint32_t TSEC_THI_CTXSW_INCR_SYNCPT; + uint32_t _0x10[0x4]; + uint32_t TSEC_THI_CTXSW; + uint32_t TSEC_THI_CTXSW_NEXT; + uint32_t TSEC_THI_CONT_SYNCPT_EOF; + uint32_t TSEC_THI_CONT_SYNCPT_L1; + uint32_t TSEC_THI_STREAMID0; + uint32_t TSEC_THI_STREAMID1; + uint32_t TSEC_THI_THI_SEC; + uint32_t _0x3C; + uint32_t TSEC_THI_METHOD0; + uint32_t TSEC_THI_METHOD1; + uint32_t _0x48[0x6]; + uint32_t TSEC_THI_CONTEXT_SWITCH; + uint32_t _0x64[0x5]; + uint32_t TSEC_THI_INT_STATUS; + uint32_t TSEC_THI_INT_MASK; + uint32_t TSEC_THI_CONFIG0; + uint32_t TSEC_THI_DBG_MISC; + uint32_t TSEC_THI_SLCG_OVERRIDE_HIGH_A; + uint32_t TSEC_THI_SLCG_OVERRIDE_LOW_A; + uint32_t _0x90[0x35C]; + uint32_t TSEC_THI_CLK_OVERRIDE; + uint32_t _0xE04[0x7F]; + uint32_t TSEC_FALCON_IRQSSET; /* Falcon microcontroller registers. */ + uint32_t TSEC_FALCON_IRQSCLR; + uint32_t TSEC_FALCON_IRQSTAT; + uint32_t TSEC_FALCON_IRQMODE; + uint32_t TSEC_FALCON_IRQMSET; + uint32_t TSEC_FALCON_IRQMCLR; + uint32_t TSEC_FALCON_IRQMASK; + uint32_t TSEC_FALCON_IRQDEST; + uint32_t TSEC_FALCON_GPTMRINT; + uint32_t TSEC_FALCON_GPTMRVAL; + uint32_t TSEC_FALCON_GPTMRCTL; + uint32_t TSEC_FALCON_PTIMER0; + uint32_t TSEC_FALCON_PTIMER1; + uint32_t TSEC_FALCON_WDTMRVAL; + uint32_t TSEC_FALCON_WDTMRCTL; + uint32_t TSEC_FALCON_IRQDEST2; + uint32_t TSEC_FALCON_MAILBOX0; + uint32_t TSEC_FALCON_MAILBOX1; + uint32_t TSEC_FALCON_ITFEN; + uint32_t TSEC_FALCON_IDLESTATE; + uint32_t TSEC_FALCON_CURCTX; + uint32_t TSEC_FALCON_NXTCTX; + uint32_t TSEC_FALCON_CTXACK; + uint32_t TSEC_FALCON_FHSTATE; + uint32_t TSEC_FALCON_PRIVSTATE; + uint32_t TSEC_FALCON_MTHDDATA; + uint32_t TSEC_FALCON_MTHDID; + uint32_t TSEC_FALCON_MTHDWDAT; + uint32_t TSEC_FALCON_MTHDCOUNT; + uint32_t TSEC_FALCON_MTHDPOP; + uint32_t TSEC_FALCON_MTHDRAMSZ; + uint32_t TSEC_FALCON_SFTRESET; + uint32_t TSEC_FALCON_OS; + uint32_t TSEC_FALCON_RM; + uint32_t TSEC_FALCON_SOFT_PM; + uint32_t TSEC_FALCON_SOFT_MODE; + uint32_t TSEC_FALCON_DEBUG1; + uint32_t TSEC_FALCON_DEBUGINFO; + uint32_t TSEC_FALCON_IBRKPT1; + uint32_t TSEC_FALCON_IBRKPT2; + uint32_t TSEC_FALCON_CGCTL; + uint32_t TSEC_FALCON_ENGCTL; + uint32_t TSEC_FALCON_PMM; + uint32_t TSEC_FALCON_ADDR; + uint32_t TSEC_FALCON_IBRKPT3; + uint32_t TSEC_FALCON_IBRKPT4; + uint32_t TSEC_FALCON_IBRKPT5; + uint32_t _0x10BC[0x5]; + uint32_t TSEC_FALCON_EXCI; + uint32_t TSEC_FALCON_SVEC_SPR; + uint32_t TSEC_FALCON_RSTAT0; + uint32_t TSEC_FALCON_RSTAT3; + uint32_t _0x10E0[0x8]; + uint32_t TSEC_FALCON_CPUCTL; + uint32_t TSEC_FALCON_BOOTVEC; + uint32_t TSEC_FALCON_HWCFG; + uint32_t TSEC_FALCON_DMACTL; + uint32_t TSEC_FALCON_DMATRFBASE; + uint32_t TSEC_FALCON_DMATRFMOFFS; + uint32_t TSEC_FALCON_DMATRFCMD; + uint32_t TSEC_FALCON_DMATRFFBOFFS; + uint32_t TSEC_FALCON_DMAPOLL_FB; + uint32_t TSEC_FALCON_DMAPOLL_CP; + uint32_t TSEC_FALCON_DBG_STATE; + uint32_t TSEC_FALCON_HWCFG1; + uint32_t TSEC_FALCON_CPUCTL_ALIAS; + uint32_t _0x1134; + uint32_t TSEC_FALCON_STACKCFG; + uint32_t _0x113C; + uint32_t TSEC_FALCON_IMCTL; + uint32_t TSEC_FALCON_IMSTAT; + uint32_t TSEC_FALCON_TRACEIDX; + uint32_t TSEC_FALCON_TRACEPC; + uint32_t TSEC_FALCON_IMFILLRNG0; + uint32_t TSEC_FALCON_IMFILLRNG1; + uint32_t TSEC_FALCON_IMFILLCTL; + uint32_t TSEC_FALCON_IMCTL_DEBUG; + uint32_t TSEC_FALCON_CMEMBASE; + uint32_t TSEC_FALCON_DMEMAPERT; + uint32_t TSEC_FALCON_EXTERRADDR; + uint32_t TSEC_FALCON_EXTERRSTAT; + uint32_t _0x1170[0x3]; + uint32_t TSEC_FALCON_CG2; + uint32_t TSEC_FALCON_IMEMC0; + uint32_t TSEC_FALCON_IMEMD0; + uint32_t TSEC_FALCON_IMEMT0; + uint32_t _0x118C; + uint32_t TSEC_FALCON_IMEMC1; + uint32_t TSEC_FALCON_IMEMD1; + uint32_t TSEC_FALCON_IMEMT1; + uint32_t _0x119C; + uint32_t TSEC_FALCON_IMEMC2; + uint32_t TSEC_FALCON_IMEMD2; + uint32_t TSEC_FALCON_IMEMT2; + uint32_t _0x11AC; + uint32_t TSEC_FALCON_IMEMC3; + uint32_t TSEC_FALCON_IMEMD3; + uint32_t TSEC_FALCON_IMEMT3; + uint32_t _0x11BC; + uint32_t TSEC_FALCON_DMEMC0; + uint32_t TSEC_FALCON_DMEMD0; + uint32_t TSEC_FALCON_DMEMC1; + uint32_t TSEC_FALCON_DMEMD1; + uint32_t TSEC_FALCON_DMEMC2; + uint32_t TSEC_FALCON_DMEMD2; + uint32_t TSEC_FALCON_DMEMC3; + uint32_t TSEC_FALCON_DMEMD3; + uint32_t TSEC_FALCON_DMEMC4; + uint32_t TSEC_FALCON_DMEMD4; + uint32_t TSEC_FALCON_DMEMC5; + uint32_t TSEC_FALCON_DMEMD5; + uint32_t TSEC_FALCON_DMEMC6; + uint32_t TSEC_FALCON_DMEMD6; + uint32_t TSEC_FALCON_DMEMC7; + uint32_t TSEC_FALCON_DMEMD7; + uint32_t TSEC_FALCON_ICD_CMD; + uint32_t TSEC_FALCON_ICD_ADDR; + uint32_t TSEC_FALCON_ICD_WDATA; + uint32_t TSEC_FALCON_ICD_RDATA; + uint32_t _0x1210[0xC]; + uint32_t TSEC_FALCON_SCTL; + uint32_t TSEC_FALCON_SSTAT; + uint32_t _0x1248[0xE]; + uint32_t TSEC_FALCON_SPROT_IMEM; + uint32_t TSEC_FALCON_SPROT_DMEM; + uint32_t TSEC_FALCON_SPROT_CPUCTL; + uint32_t TSEC_FALCON_SPROT_MISC; + uint32_t TSEC_FALCON_SPROT_IRQ; + uint32_t TSEC_FALCON_SPROT_MTHD; + uint32_t TSEC_FALCON_SPROT_SCTL; + uint32_t TSEC_FALCON_SPROT_WDTMR; + uint32_t _0x12A0[0x8]; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBRD_LOW; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBRD_HIGH; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBWR_LOW; + uint32_t TSEC_FALCON_DMAINFO_FINISHED_FBWR_HIGH; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBRD_LOW; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBRD_HIGH; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBWR_LOW; + uint32_t TSEC_FALCON_DMAINFO_CURRENT_FBWR_HIGH; + uint32_t TSEC_FALCON_DMAINFO_CTL; + uint32_t _0x12E4[0x47]; + uint32_t TSEC_SCP_CTL0; /* Secure Co-processor registers. */ + uint32_t TSEC_SCP_CTL1; + uint32_t TSEC_SCP_CTL_STAT; + uint32_t TSEC_SCP_CTL_LOCK; + uint32_t TSEC_SCP_CFG; + uint32_t TSEC_SCP_CTL_SCP; + uint32_t TSEC_SCP_CTL_PKEY; + uint32_t TSEC_SCP_CTL_DBG; + uint32_t TSEC_SCP_DBG0; + uint32_t TSEC_SCP_DBG1; + uint32_t TSEC_SCP_DBG2; + uint32_t _0x142C; + uint32_t TSEC_SCP_CMD; + uint32_t _0x1434[0x7]; + uint32_t TSEC_SCP_STAT0; + uint32_t TSEC_SCP_STAT1; + uint32_t TSEC_SCP_STAT2; + uint32_t _0x145C[0x5]; + uint32_t TSEC_SCP_RND_STAT0; + uint32_t TSEC_SCP_RND_STAT1; + uint32_t _0x1478[0x2]; + uint32_t TSEC_SCP_IRQSTAT; + uint32_t TSEC_SCP_IRQMASK; + uint32_t _0x1488[0x2]; + uint32_t TSEC_SCP_ACL_ERR; + uint32_t TSEC_SCP_SEC_ERR; + uint32_t TSEC_SCP_CMD_ERR; + uint32_t _0x149C[0x19]; + uint32_t TSEC_RND_CTL0; /* Random Number Generator registers. */ + uint32_t TSEC_RND_CTL1; + uint32_t TSEC_RND_CTL2; + uint32_t TSEC_RND_CTL3; + uint32_t TSEC_RND_CTL4; + uint32_t TSEC_RND_CTL5; + uint32_t TSEC_RND_CTL6; + uint32_t TSEC_RND_CTL7; + uint32_t TSEC_RND_CTL8; + uint32_t TSEC_RND_CTL9; + uint32_t TSEC_RND_CTL10; + uint32_t TSEC_RND_CTL11; + uint32_t _0x1530[0x34]; + uint32_t TSEC_TFBIF_CTL; /* Tegra Framebuffer Interface registers. */ + uint32_t TSEC_TFBIF_MCCIF_FIFOCTRL; + uint32_t TSEC_TFBIF_THROTTLE; + uint32_t TSEC_TFBIF_DBG_STAT0; + uint32_t TSEC_TFBIF_DBG_STAT1; + uint32_t TSEC_TFBIF_DBG_RDCOUNT_LO; + uint32_t TSEC_TFBIF_DBG_RDCOUNT_HI; + uint32_t TSEC_TFBIF_DBG_WRCOUNT_LO; + uint32_t TSEC_TFBIF_DBG_WRCOUNT_HI; + uint32_t TSEC_TFBIF_DBG_R32COUNT; + uint32_t TSEC_TFBIF_DBG_R64COUNT; + uint32_t TSEC_TFBIF_DBG_R128COUNT; + uint32_t _0x1630; + uint32_t TSEC_TFBIF_MCCIF_FIFOCTRL1; + uint32_t TSEC_TFBIF_WRR_RDP; + uint32_t _0x163C; + uint32_t TSEC_TFBIF_SPROT_EMEM; + uint32_t TSEC_TFBIF_TRANSCFG; + uint32_t TSEC_TFBIF_REGIONCFG; + uint32_t TSEC_TFBIF_ACTMON_ACTIVE_MASK; + uint32_t TSEC_TFBIF_ACTMON_ACTIVE_BORPS; + uint32_t TSEC_TFBIF_ACTMON_ACTIVE_WEIGHT; + uint32_t _0x1658[0x2]; + uint32_t TSEC_TFBIF_ACTMON_MCB_MASK; + uint32_t TSEC_TFBIF_ACTMON_MCB_BORPS; + uint32_t TSEC_TFBIF_ACTMON_MCB_WEIGHT; + uint32_t _0x166C; + uint32_t TSEC_TFBIF_THI_TRANSPROP; + uint32_t _0x1674[0x17]; + uint32_t TSEC_CG; /* Clock Gate registers. */ + uint32_t _0x16D4[0xB]; + uint32_t TSEC_BAR0_CTL; /* HOST1X device DMA registers. */ + uint32_t TSEC_BAR0_ADDR; + uint32_t TSEC_BAR0_DATA; + uint32_t TSEC_BAR0_TIMEOUT; + uint32_t _0x1710[0x3C]; + uint32_t TSEC_TEGRA_FALCON_IP_VER; /* Miscellaneous registers. */ + uint32_t _0x1804[0xD]; + uint32_t TSEC_TEGRA_CTL; + uint32_t _0x183C[0x31]; } tegra_tsec_t; static inline volatile tegra_tsec_t *tsec_get_regs(void) diff --git a/sept/sept-secondary/key_derivation/src/se.c b/sept/sept-secondary/key_derivation/src/se.c index b32595c99..5439340d4 100644 --- a/sept/sept-secondary/key_derivation/src/se.c +++ b/sept/sept-secondary/key_derivation/src/se.c @@ -39,20 +39,20 @@ void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) { } void se_check_error_status_reg(void) { - if (se_get_regs()->ERR_STATUS_REG) { + if (se_get_regs()->SE_ERR_STATUS) { generic_panic(); } } void se_check_for_error(void) { volatile tegra_se_t *se = se_get_regs(); - if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) { + if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) { generic_panic(); } } void se_verify_flags_cleared(void) { - if (se_get_regs()->FLAGS_REG & 3) { + if (se_get_regs()->SE_STATUS & 3) { generic_panic(); } } @@ -67,12 +67,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { - se->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -87,12 +87,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { /* TODO: Why are flags assigned this way? */ - se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -105,8 +105,8 @@ void clear_aes_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -120,13 +120,13 @@ void clear_rsa_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + se->SE_RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = 0; } } @@ -138,8 +138,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { } for (size_t i = 0; i < (key_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = read32le(key, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i); } } @@ -151,13 +151,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_ } for (size_t i = 0; i < (modulus_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; - se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); } for (size_t i = 0; i < (exp_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); } g_se_modulus_sizes[keyslot] = modulus_size; @@ -172,8 +172,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { } for (size_t i = 0; i < (iv_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i); } } @@ -185,14 +185,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) { } for (size_t i = 0; i < (0x10 >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } void set_se_ctr(const void *ctr) { for (unsigned int i = 0; i < 4; i++) { - se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4); } } @@ -204,34 +204,34 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr } /* Write config, validate. */ - se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); - if (se->CONFIG_REG != (ALG_AES_DEC | DST_KEYTAB)) { + se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB); + if (se->SE_CONFIG != (ALG_AES_DEC | DST_KEYTAB)) { generic_panic(); } - se->CRYPTO_REG = keyslot_src << 24; - if (se->CRYPTO_REG != (keyslot_src << 24)) { + se->SE_CRYPTO_CONFIG = keyslot_src << 24; + if (se->SE_CRYPTO_CONFIG != (keyslot_src << 24)) { generic_panic(); } - se->BLOCK_COUNT_REG = 0; - if (se->BLOCK_COUNT_REG != 0) { + se->SE_CRYPTO_LAST_BLOCK = 0; + if (se->SE_CRYPTO_LAST_BLOCK != 0) { generic_panic(); } - se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; - if (se->CRYPTO_KEYTABLE_DST_REG != (keyslot_dst << 8)) { + se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8; + if (se->SE_CRYPTO_KEYTABLE_DST != (keyslot_dst << 8)) { generic_panic(); } /* Clear address context. */ - se->IN_LL_ADDR_REG = 0; - se->OUT_LL_ADDR_REG = 0; - if (se->IN_LL_ADDR_REG != 0 || se->OUT_LL_ADDR_REG != 0) { + se->SE_IN_LL_ADDR = 0; + se->SE_OUT_LL_ADDR = 0; + if (se->SE_IN_LL_ADDR != 0 || se->SE_OUT_LL_ADDR != 0) { generic_panic(); } trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); /* Validate address context. */ - if (se->IN_LL_ADDR_REG == 0 || se->OUT_LL_ADDR_REG == 0) { + if (se->SE_IN_LL_ADDR == 0 || se->SE_OUT_LL_ADDR == 0) { generic_panic(); } } @@ -249,10 +249,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co stack_buf[i] = *((uint8_t *)src + src_size - i - 1); } - se->CONFIG_REG = (ALG_RSA | DST_RSAREG); - se->RSA_CONFIG = keyslot << 24; - se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + se->SE_CONFIG = (ALG_RSA | DST_RSAREG); + se->SE_RSA_CONFIG = keyslot << 24; + se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1; + se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2; trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size); se_get_exp_mod_output(dst, dst_size); @@ -270,7 +270,7 @@ void se_get_exp_mod_output(void *buf, size_t size) { /* Copy endian swapped output. */ while (num_dwords) { - *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset); + *p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset); offset += 4; p_out--; num_dwords--; @@ -339,20 +339,20 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v ll_init(&out_ll, dst, dst_size); /* Set the LLs. */ - se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); - se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll); + se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); + se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; - if (se->IN_LL_ADDR_REG != (uint32_t) get_physical_address(&in_ll) || se->OUT_LL_ADDR_REG != (uint32_t) get_physical_address(&out_ll) || (se->INT_STATUS_REG & 0x10) || (se->FLAGS_REG & 0x3)) { + if (se->SE_IN_LL_ADDR != (uint32_t) get_physical_address(&in_ll) || se->SE_OUT_LL_ADDR != (uint32_t) get_physical_address(&out_ll) || (se->SE_INT_STATUS & 0x10) || (se->SE_STATUS & 0x3)) { generic_panic(); } - se->OPERATION_REG = op; + se->SE_OPERATION = op; - while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -370,7 +370,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } /* Trigger AES operation. */ - se_get_regs()->BLOCK_COUNT_REG = 0; + se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -388,15 +388,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo unsigned int num_blocks = src_size >> 4; /* Unknown what this write does, but official code writes it for CTR mode. */ - se->SPARE_0 = 1; - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x91E; + se->SE_SPARE = 1; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E; set_se_ctr(ctr); /* Handle any aligned blocks. */ size_t aligned_size = (size_t)num_blocks << 4; if (aligned_size) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size); } @@ -418,8 +418,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - se->CRYPTO_REG = keyslot << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -438,8 +438,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot << 24; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -482,16 +482,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - se->CRYPTO_REG = (keyslot << 24) | (0x145); + se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - se->BLOCK_COUNT_REG = num_blocks - 2; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2; trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); - se->CRYPTO_REG |= 0x80; + se->SE_CRYPTO_CONFIG |= 0x80; } /* Create final block. */ @@ -508,12 +508,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con } /* Perform last operation. */ - se->BLOCK_COUNT_REG = 0; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2); } } @@ -531,10 +531,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x144; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144; set_aes_keyslot_iv(keyslot, iv, 0x10); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -545,10 +545,10 @@ void se_aes_128_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY) | (0x000 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x66; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY) | (0x000 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x66; clear_aes_keyslot_iv(keyslot); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -557,23 +557,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { volatile tegra_se_t *se = se_get_regs(); /* Setup config for SHA256, size = BITS(src_size) */ - se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); - se->SHA_CONFIG_REG = 1; - se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3); - se->_0x208 = 0; - se->_0x20C = 0; - se->_0x210 = 0; - se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3); - se->_0x218 = 0; - se->_0x21C = 0; - se->_0x220 = 0; + se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + se->SE_SHA_CONFIG = 1; + se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LENGTH[1] = 0; + se->SE_SHA_MSG_LENGTH[2] = 0; + se->SE_SHA_MSG_LENGTH[3] = 0; + se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LEFT[1] = 0; + se->SE_SHA_MSG_LEFT[2] = 0; + se->SE_SHA_MSG_LEFT[3] = 0; /* Trigger the operation. */ trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); /* Copy output hash. */ for (unsigned int i = 0; i < (0x20 >> 2); i++) { - ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2); } } @@ -589,12 +589,12 @@ void se_initialize_rng(unsigned int keyslot) { /* This will be discarded, when done. */ uint8_t ALIGN(16) output_buf[0x10]; - se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ - se->RNG_RESEED_INTERVAL_REG = 70001; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 5; - se->BLOCK_COUNT_REG = 0; + se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */ + se->SE_RNG_RESEED_INTERVAL = 70001; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 5; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0); } @@ -607,12 +607,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) { uint32_t num_blocks = size >> 4; size_t aligned_size = num_blocks << 4; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; if (num_blocks >= 1) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0); } if (size > aligned_size) { @@ -628,16 +628,16 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) } /* Setup Config. */ - se->CONFIG_REG = (ALG_RNG | DST_KEYTAB); - se->CRYPTO_REG = (rng_keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_RNG | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = (rng_keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; + se->SE_CRYPTO_LAST_BLOCK = 0; /* Generate low part of key. */ - se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8); + se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8); trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); /* Generate high part of key. */ - se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8) | 1; + se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8) | 1; trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); } @@ -645,24 +645,24 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) void se_set_in_context_save_mode(bool is_context_save_mode) { volatile tegra_se_t *se = se_get_regs(); - uint32_t val = se->_0x0; + uint32_t val = se->SE_SE_SECURITY; if (is_context_save_mode) { val |= 0x10000; } else { val &= 0xFFFEFFFF; } - se->_0x0 = val; + se->SE_SE_SECURITY = val; /* Perform a useless read from flags reg. */ - (void)(se->FLAGS_REG); + (void)(se->SE_STATUS); } void se_generate_srk(unsigned int srkgen_keyslot) { volatile tegra_se_t *se = se_get_regs(); - se->CONFIG_REG = (ALG_RNG | DST_SRK); - se->CRYPTO_REG = (srkgen_keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 6; - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_RNG | DST_SRK); + se->SE_CRYPTO_CONFIG = (srkgen_keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 6; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); } @@ -693,39 +693,39 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void se_generate_random(rng_keyslot, work_buf, 0x10); /* Save random initial block. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst, 0x10, work_buf, 0x10); /* Save Sticky Bits. */ for (unsigned int i = 0; i < 0x2; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0); } /* Save AES Key Table. */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x30 + (i * 0x20), 0x10, NULL, 0); - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0); } /* Save AES Original IVs. */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0); } /* Save AES Updated IVs */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0); } @@ -734,8 +734,8 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) { for (unsigned int mod_exp = 0; mod_exp < 2; mod_exp++) { for (unsigned int sub_block = 0; sub_block < 0x10; sub_block++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(rsa_ctx_out, 0x10, NULL, 0); rsa_ctx_out += 0x10; } @@ -744,14 +744,14 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void /* Save "Known Pattern. " */ static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10); /* Save SRK into PMC registers. */ - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(work_buf, 0, NULL, 0); - se->CONFIG_REG = 0; + se->SE_CONFIG = 0; se_encrypt_with_srk(work_buf, 0, NULL, 0); } diff --git a/sept/sept-secondary/key_derivation/src/se.h b/sept/sept-secondary/key_derivation/src/se.h index 98a6a170f..f3bb43542 100644 --- a/sept/sept-secondary/key_derivation/src/se.h +++ b/sept/sept-secondary/key_derivation/src/se.h @@ -93,71 +93,59 @@ #define RSA_2048_BYTES 0x100 typedef struct { - uint32_t _0x0; - uint32_t _0x4; - uint32_t OPERATION_REG; - uint32_t INT_ENABLE_REG; - uint32_t INT_STATUS_REG; - uint32_t CONFIG_REG; - uint32_t IN_LL_ADDR_REG; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t OUT_LL_ADDR_REG; - uint32_t _0x28; - uint32_t _0x2C; - uint8_t HASH_RESULT_REG[0x20]; - uint8_t _0x50[0x20]; - uint32_t CONTEXT_SAVE_CONFIG_REG; - uint8_t _0x74[0x18C]; - uint32_t SHA_CONFIG_REG; - uint32_t SHA_MSG_LENGTH_REG; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t SHA_MSG_LEFT_REG; - uint32_t _0x218; - uint32_t _0x21C; - uint32_t _0x220; - uint32_t _0x224; - uint8_t _0x228[0x58]; - uint32_t AES_KEY_READ_DISABLE_REG; - uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C4[0x3C]; - uint32_t _0x300; - uint32_t CRYPTO_REG; - uint32_t CRYPTO_CTR_REG[4]; - uint32_t BLOCK_COUNT_REG; - uint32_t AES_KEYTABLE_ADDR; - uint32_t AES_KEYTABLE_DATA; - uint32_t _0x324; - uint32_t _0x328; - uint32_t _0x32C; - uint32_t CRYPTO_KEYTABLE_DST_REG; - uint8_t _0x334[0xC]; - uint32_t RNG_CONFIG_REG; - uint32_t RNG_SRC_CONFIG_REG; - uint32_t RNG_RESEED_INTERVAL_REG; - uint8_t _0x34C[0xB4]; - uint32_t RSA_CONFIG; - uint32_t RSA_KEY_SIZE_REG; - uint32_t RSA_EXP_SIZE_REG; - uint32_t RSA_KEY_READ_DISABLE_REG; - uint32_t RSA_KEYSLOT_FLAGS[2]; - uint32_t _0x418; - uint32_t _0x41C; - uint32_t RSA_KEYTABLE_ADDR; - uint32_t RSA_KEYTABLE_DATA; - uint8_t RSA_OUTPUT[0x100]; - uint8_t _0x528[0x2D8]; - uint32_t FLAGS_REG; - uint32_t ERR_STATUS_REG; - uint32_t _0x808; - uint32_t SPARE_0; - uint32_t _0x810; + uint32_t SE_SE_SECURITY; + uint32_t SE_TZRAM_SECURITY; + uint32_t SE_OPERATION; + uint32_t SE_INT_ENABLE; + uint32_t SE_INT_STATUS; + uint32_t SE_CONFIG; + uint32_t SE_IN_LL_ADDR; + uint32_t SE_IN_CUR_BYTE_ADDR; + uint32_t SE_IN_CUR_LL_ID; + uint32_t SE_OUT_LL_ADDR; + uint32_t SE_OUT_CUR_BYTE_ADDR; + uint32_t SE_OUT_CUR_LL_ID; + uint32_t SE_HASH_RESULT[0x10]; + uint32_t SE_CTX_SAVE_CONFIG; + uint32_t _0x74[0x63]; + uint32_t SE_SHA_CONFIG; + uint32_t SE_SHA_MSG_LENGTH[0x4]; + uint32_t SE_SHA_MSG_LEFT[0x4]; + uint32_t _0x224[0x17]; + uint32_t SE_CRYPTO_SECURITY_PERKEY; + uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10]; + uint32_t _0x2C4[0x10]; + uint32_t SE_CRYPTO_CONFIG; + uint32_t SE_CRYPTO_LINEAR_CTR[0x4]; + uint32_t SE_CRYPTO_LAST_BLOCK; + uint32_t SE_CRYPTO_KEYTABLE_ADDR; + uint32_t SE_CRYPTO_KEYTABLE_DATA; + uint32_t _0x324[0x3]; + uint32_t SE_CRYPTO_KEYTABLE_DST; + uint32_t _0x334[0x3]; + uint32_t SE_RNG_CONFIG; + uint32_t SE_RNG_SRC_CONFIG; + uint32_t SE_RNG_RESEED_INTERVAL; + uint32_t _0x34C[0x2D]; + uint32_t SE_RSA_CONFIG; + uint32_t SE_RSA_KEY_SIZE; + uint32_t SE_RSA_EXP_SIZE; + uint32_t SE_RSA_SECURITY_PERKEY; + uint32_t SE_RSA_KEYTABLE_ACCESS[0x2]; + uint32_t _0x418[0x2]; + uint32_t SE_RSA_KEYTABLE_ADDR; + uint32_t SE_RSA_KEYTABLE_DATA; + uint32_t SE_RSA_OUTPUT[0x40]; + uint32_t _0x528[0xB6]; + uint32_t SE_STATUS; + uint32_t SE_ERR_STATUS; + uint32_t SE_MISC; + uint32_t SE_SPARE; + uint32_t SE_ENTROPY_DEBUG_COUNTER; uint32_t _0x814; uint32_t _0x818; uint32_t _0x81C; - uint8_t _0x820[0x17E0]; + uint32_t _0x820[0x5F8]; } tegra_se_t; typedef struct { diff --git a/sept/sept-secondary/src/fuse.c b/sept/sept-secondary/src/fuse.c index 1bfe3334c..4d4c948fb 100644 --- a/sept/sept-secondary/src/fuse.c +++ b/sept/sept-secondary/src/fuse.c @@ -20,214 +20,216 @@ #include "car.h" #include "fuse.h" +#include "pmc.h" #include "timers.h" /* Prototypes for internal commands. */ -void fuse_make_regs_visible(void); - void fuse_enable_power(void); void fuse_disable_power(void); void fuse_wait_idle(void); /* Initialize the fuse driver */ void fuse_init(void) { - fuse_make_regs_visible(); - fuse_secondary_private_key_disable(); - fuse_disable_programming(); - - /* TODO: Overrides (iROM patches) and various reads happen here */ -} - -/* Make all fuse registers visible */ -void fuse_make_regs_visible(void) { + /* Make all fuse registers visible, disable the private key and disable programming. */ clkrst_enable_fuse_regs(true); + fuse_disable_private_key(); + fuse_disable_programming(); } -/* Enable power to the fuse hardware array */ +/* Disable access to the private key and set the TZ sticky bit. */ +void fuse_disable_private_key(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_PRIVATEKEYDISABLE = 0x10; +} + +/* Disables all fuse programming. */ +void fuse_disable_programming(void) { + volatile tegra_fuse_t *fuse = fuse_get_regs(); + fuse->FUSE_DISABLEREGPROGRAM = 1; +} + +/* Enable power to the fuse hardware array. */ void fuse_enable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 1; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x200); // Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. + mdelay(1); + pmc->fuse_control |= 0x100; // Set PMC_FUSE_CTRL_PS18_LATCH_SET. + mdelay(1); } -/* Disable power to the fuse hardware array */ +/* Disable power to the fuse hardware array. */ void fuse_disable_power(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PWR_GOOD_SW = 0; - udelay(1); + volatile tegra_pmc_t *pmc = pmc_get_regs(); + pmc->fuse_control &= ~(0x100); // Clear PMC_FUSE_CTRL_PS18_LATCH_SET. + mdelay(1); + pmc->fuse_control |= 0x200; // Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. + mdelay(1); } -/* Wait for the fuse driver to go idle */ +/* Wait for the fuse driver to go idle. */ void fuse_wait_idle(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); uint32_t ctrl_val = 0; /* Wait for STATE_IDLE */ while ((ctrl_val & (0xF0000)) != 0x40000) - { - udelay(1); - ctrl_val = fuse->FUSE_CTRL; - } + ctrl_val = fuse->FUSE_FUSECTRL; } -/* Read a fuse from the hardware array */ +/* Read a fuse from the hardware array. */ uint32_t fuse_hw_read(uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address */ - fuse->FUSE_REG_ADDR = addr; + /* Program the target address. */ + fuse->FUSE_FUSEADDR = addr; - /* Enable read operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable read operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x1; /* Set FUSE_READ command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x1; /* Set READ command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); - return fuse->FUSE_REG_READ; + return fuse->FUSE_FUSERDATA; } -/* Write a fuse in the hardware array */ +/* Write a fuse in the hardware array. */ void fuse_hw_write(uint32_t value, uint32_t addr) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); - /* Program the target address and value */ - fuse->FUSE_REG_ADDR = addr; - fuse->FUSE_REG_WRITE = value; + /* Program the target address and value. */ + fuse->FUSE_FUSEADDR = addr; + fuse->FUSE_FUSEWDATA = value; - /* Enable write operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + /* Enable write operation in control register. */ + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x2; /* Set FUSE_WRITE command */ - fuse->FUSE_CTRL = ctrl_val; + ctrl_val |= 0x2; /* Set WRITE command. */ + fuse->FUSE_FUSECTRL = ctrl_val; + /* Wait for idle state. */ fuse_wait_idle(); } -/* Sense the fuse hardware array into the shadow cache */ +/* Sense the fuse hardware array into the shadow cache. */ void fuse_hw_sense(void) { volatile tegra_fuse_t *fuse = fuse_get_regs(); + + /* Wait for idle state. */ fuse_wait_idle(); /* Enable sense operation in control register */ - uint32_t ctrl_val = fuse->FUSE_CTRL; + uint32_t ctrl_val = fuse->FUSE_FUSECTRL; ctrl_val &= ~0x3; - ctrl_val |= 0x3; /* Set FUSE_SENSE command */ - fuse->FUSE_CTRL = ctrl_val; - + ctrl_val |= 0x3; /* Set SENSE_CTRL command */ + fuse->FUSE_FUSECTRL = ctrl_val; + + /* Wait for idle state. */ fuse_wait_idle(); } -/* Disables all fuse programming. */ -void fuse_disable_programming(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_DIS_PGM = 1; -} - -/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */ -void fuse_secondary_private_key_disable(void) { - volatile tegra_fuse_t *fuse = fuse_get_regs(); - fuse->FUSE_PRIVATEKEYDISABLE = 0x10; -} - - -/* Read the SKU info register from the shadow cache */ +/* Read the SKU info register from the shadow cache. */ uint32_t fuse_get_sku_info(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); return fuse_chip->FUSE_SKU_INFO; } -/* Read the bootrom patch version from a register in the shadow cache */ +/* Read the bootrom patch version from a register in the shadow cache. */ uint32_t fuse_get_bootrom_patch_version(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return fuse_chip->FUSE_SOC_SPEEDO_1; + return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB; } /* Read a spare bit register from the shadow cache */ uint32_t fuse_get_spare_bit(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 32) { + if (idx < 32) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_SPARE_BIT[idx]; + } else { return 0; } - - return fuse_chip->FUSE_SPARE_BIT[idx]; } -/* Read a reserved ODM register from the shadow cache */ +/* Read a reserved ODM register from the shadow cache. */ uint32_t fuse_get_reserved_odm(uint32_t idx) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - if (idx >= 8) { + if (idx < 8) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); + return fuse_chip->FUSE_RESERVED_ODM[idx]; + } else { return 0; } - - return fuse_chip->FUSE_RESERVED_ODM[idx]; } -/* Derive the Device ID using values in the shadow cache */ +/* Get the DRAM ID using values in the shadow cache. */ +uint32_t fuse_get_dram_id(void) { + return ((fuse_get_reserved_odm(4) >> 3) & 0x7); +} + +/* Derive the Device ID using values in the shadow cache. */ uint64_t fuse_get_device_id(void) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint64_t device_id = 0; - uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0; - uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; + uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint64_t derived_lot_code = 0; for (unsigned int i = 0; i < 5; i++) { derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F); } derived_lot_code &= 0x03FFFFFF; - + device_id |= y_coord << 0; device_id |= x_coord << 9; device_id |= wafer_id << 18; device_id |= derived_lot_code << 24; device_id |= fab_code << 50; + return device_id; } -/* Get the DRAM ID using values in the shadow cache */ -uint32_t fuse_get_dram_id(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7; -} - -/* Derive the Hardware Type using values in the shadow cache */ -uint32_t fuse_get_hardware_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); +/* Derive the Hardware Type using values in the shadow cache. */ +uint32_t fuse_get_hardware_type(uint32_t mkey_rev) { + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1)); - /* This function is very different between 4.x and < 4.x */ - uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1); - - /* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) { - static const uint32_t types[] = {0,1,4,3}; - - hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C; - hardware_type--; - return hardware_type > 3 ? 4 : types[hardware_type]; - } else {*/ + /* Firmware from versions 1.0.0 to 3.0.2. */ + if (mkey_rev < 0x03) { + volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); if (hardware_type >= 1) { - return hardware_type > 2 ? 3 : hardware_type - 1; + return (hardware_type > 2) ? 3 : hardware_type - 1; } else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) { return 0; } else { return 3; } -// } + } else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */ + static const uint32_t types[] = {0,1,4,3}; + hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C); + hardware_type--; + return (hardware_type > 3) ? 4 : types[hardware_type]; + } else { /* Firmware versions from 7.0.0 onwards. */ + /* Always return 0 in retail. */ + return 0; + } } -/* Derive the Retail Type using values in the shadow cache */ +/* Derive the Retail Type using values in the shadow cache. */ uint32_t fuse_get_retail_type(void) { - volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); - - /* Retail type = IS_RETAIL | UNIT_TYPE */ - uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3); + /* Retail Type = IS_RETAIL | UNIT_TYPE. */ + uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4); + uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3)); if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */ return 1; } else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */ @@ -241,17 +243,17 @@ void fuse_get_hardware_info(void *dst) { volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs(); uint32_t hw_info[0x4]; - uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F; - uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF; - uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF; - uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F; - uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0; - uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF; - uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F; - uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF; + uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F; + uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF; + uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF; + uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F; + uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0; + uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF; + uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F; + uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF; - /* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ - hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse)); + /* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ + hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved)); hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2)); hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6)); hw_info[3] = (uint32_t)(vendor_code); diff --git a/sept/sept-secondary/src/fuse.h b/sept/sept-secondary/src/fuse.h index 9d92503e2..d118b53dc 100644 --- a/sept/sept-secondary/src/fuse.h +++ b/sept/sept-secondary/src/fuse.h @@ -23,154 +23,167 @@ #define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n) typedef struct { - uint32_t FUSE_CTRL; - uint32_t FUSE_REG_ADDR; - uint32_t FUSE_REG_READ; - uint32_t FUSE_REG_WRITE; - uint32_t FUSE_TIME_RD1; - uint32_t FUSE_TIME_RD2; - uint32_t FUSE_TIME_PGM1; - uint32_t FUSE_TIME_PGM2; - uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSECTRL; + uint32_t FUSE_FUSEADDR; + uint32_t FUSE_FUSERDATA; + uint32_t FUSE_FUSEWDATA; + uint32_t FUSE_FUSETIME_RD1; + uint32_t FUSE_FUSETIME_RD2; + uint32_t FUSE_FUSETIME_PGM1; + uint32_t FUSE_FUSETIME_PGM2; + uint32_t FUSE_PRIV2INTFC_START; uint32_t FUSE_FUSEBYPASS; uint32_t FUSE_PRIVATEKEYDISABLE; - uint32_t FUSE_DIS_PGM; - uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_DISABLEREGPROGRAM; + uint32_t FUSE_WRITE_ACCESS_SW; uint32_t FUSE_PWR_GOOD_SW; - uint32_t _0x38[0x32]; + uint32_t _0x38; + uint32_t FUSE_PRIV2RESHIFT; + uint32_t _0x40[0x3]; + uint32_t FUSE_FUSETIME_RD3; + uint32_t _0x50[0xC]; + uint32_t FUSE_PRIVATE_KEY0_NONZERO; + uint32_t FUSE_PRIVATE_KEY1_NONZERO; + uint32_t FUSE_PRIVATE_KEY2_NONZERO; + uint32_t FUSE_PRIVATE_KEY3_NONZERO; + uint32_t FUSE_PRIVATE_KEY4_NONZERO; + uint32_t _0x90[0x1C]; } tegra_fuse_t; typedef struct { uint32_t FUSE_PRODUCTION_MODE; - uint32_t _0x4; - uint32_t _0x8; - uint32_t _0xC; + uint32_t FUSE_JTAG_SECUREID_VALID; + uint32_t FUSE_ODM_LOCK; + uint32_t FUSE_OPT_OPENGL_EN; uint32_t FUSE_SKU_INFO; - uint32_t FUSE_CPU_SPEEDO_0; - uint32_t FUSE_CPU_IDDQ; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t _0x24; - uint32_t FUSE_FT_REV; - uint32_t FUSE_CPU_SPEEDO_1; - uint32_t FUSE_CPU_SPEEDO_2; - uint32_t FUSE_SOC_SPEEDO_0; - uint32_t FUSE_SOC_SPEEDO_1; - uint32_t FUSE_SOC_SPEEDO_2; - uint32_t FUSE_SOC_IDDQ; - uint32_t _0x44; + uint32_t FUSE_CPU_SPEEDO_0_CALIB; + uint32_t FUSE_CPU_IDDQ_CALIB; + uint32_t FUSE_DAC_CRT_CALIB; + uint32_t FUSE_DAC_HDTV_CALIB; + uint32_t FUSE_DAC_SDTV_CALIB; + uint32_t FUSE_OPT_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1_CALIB; + uint32_t FUSE_CPU_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_SPEEDO_0_CALIB; + uint32_t FUSE_SOC_SPEEDO_1_CALIB; + uint32_t FUSE_SOC_SPEEDO_2_CALIB; + uint32_t FUSE_SOC_IDDQ_CALIB; + uint32_t FUSE_RESERVED_PRODUCTION_WP; uint32_t FUSE_FA; - uint32_t _0x4C; - uint32_t _0x50; - uint32_t _0x54; - uint32_t _0x58; - uint32_t _0x5C; - uint32_t _0x60; + uint32_t FUSE_RESERVED_PRODUCTION; + uint32_t FUSE_HDMI_LANE0_CALIB; + uint32_t FUSE_HDMI_LANE1_CALIB; + uint32_t FUSE_HDMI_LANE2_CALIB; + uint32_t FUSE_HDMI_LANE3_CALIB; + uint32_t FUSE_ENCRYPTION_RATE; uint32_t FUSE_PUBLIC_KEY[0x8]; - uint32_t FUSE_TSENSOR_1; - uint32_t FUSE_TSENSOR_2; - uint32_t _0x8C; - uint32_t FUSE_CP_REV; - uint32_t _0x94; - uint32_t FUSE_TSENSOR_0; - uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_TSENSOR1_CALIB; + uint32_t FUSE_TSENSOR2_CALIB; + uint32_t FUSE_VSENSOR_CALIB; + uint32_t FUSE_OPT_CP_REV; + uint32_t FUSE_OPT_PFG; + uint32_t FUSE_TSENSOR0_CALIB; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; - uint32_t FUSE_PRIVATE_KEY[0x4]; - uint32_t FUSE_DEVICE_KEY; - uint32_t _0xB8; - uint32_t _0xBC; + uint32_t FUSE_PRIVATE_KEY[0x5]; + uint32_t FUSE_ARM_JTAG_DIS; + uint32_t FUSE_BOOT_DEVICE_INFO; uint32_t FUSE_RESERVED_SW; - uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_OPT_VP9_DISABLE; uint32_t FUSE_RESERVED_ODM[0x8]; - uint32_t _0xE8; - uint32_t _0xEC; - uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_OBS_DIS; + uint32_t FUSE_NOR_INFO; + uint32_t FUSE_USB_CALIB; uint32_t FUSE_SKU_DIRECT_CONFIG; - uint32_t _0xF8; - uint32_t _0xFC; - uint32_t FUSE_VENDOR_CODE; - uint32_t FUSE_FAB_CODE; - uint32_t FUSE_LOT_CODE_0; - uint32_t FUSE_LOT_CODE_1; - uint32_t FUSE_WAFER_ID; - uint32_t FUSE_X_COORDINATE; - uint32_t FUSE_Y_COORDINATE; - uint32_t _0x11C; - uint32_t _0x120; + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; + uint32_t FUSE_PACKAGE_INFO; + uint32_t FUSE_OPT_VENDOR_CODE; + uint32_t FUSE_OPT_FAB_CODE; + uint32_t FUSE_OPT_LOT_CODE_0; + uint32_t FUSE_OPT_LOT_CODE_1; + uint32_t FUSE_OPT_WAFER_ID; + uint32_t FUSE_OPT_X_COORDINATE; + uint32_t FUSE_OPT_Y_COORDINATE; + uint32_t FUSE_OPT_SEC_DEBUG_EN; + uint32_t FUSE_OPT_OPS_RESERVED; uint32_t FUSE_SATA_CALIB; - uint32_t FUSE_GPU_IDDQ; - uint32_t FUSE_TSENSOR_3; - uint32_t _0x130; - uint32_t _0x134; - uint32_t _0x138; - uint32_t _0x13C; - uint32_t _0x140; - uint32_t _0x144; + uint32_t FUSE_GPU_IDDQ_CALIB; + uint32_t FUSE_TSENSOR3_CALIB; + uint32_t FUSE_SKU_BOND_OUT_L; + uint32_t FUSE_SKU_BOND_OUT_H; + uint32_t FUSE_SKU_BOND_OUT_U; + uint32_t FUSE_SKU_BOND_OUT_V; + uint32_t FUSE_SKU_BOND_OUT_W; + uint32_t FUSE_OPT_SAMPLE_TYPE; uint32_t FUSE_OPT_SUBREVISION; - uint32_t _0x14C; - uint32_t _0x150; - uint32_t FUSE_TSENSOR_4; - uint32_t FUSE_TSENSOR_5; - uint32_t FUSE_TSENSOR_6; - uint32_t FUSE_TSENSOR_7; - uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_OPT_SW_RESERVED_0; + uint32_t FUSE_OPT_SW_RESERVED_1; + uint32_t FUSE_TSENSOR4_CALIB; + uint32_t FUSE_TSENSOR5_CALIB; + uint32_t FUSE_TSENSOR6_CALIB; + uint32_t FUSE_TSENSOR7_CALIB; + uint32_t FUSE_OPT_PRIV_SEC_EN; uint32_t FUSE_PKC_DISABLE; uint32_t _0x16C; uint32_t _0x170; uint32_t _0x174; uint32_t _0x178; - uint32_t _0x17C; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; uint32_t FUSE_TSENSOR_COMMON; - uint32_t _0x184; - uint32_t _0x188; - uint32_t _0x18C; - uint32_t _0x190; + uint32_t FUSE_OPT_CP_BIN; + uint32_t FUSE_OPT_GPU_DISABLE; + uint32_t FUSE_OPT_FT_BIN; + uint32_t FUSE_OPT_DONE_MAP; uint32_t _0x194; - uint32_t _0x198; - uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t FUSE_APB2JTAG_DISABLE; + uint32_t FUSE_ODM_INFO; uint32_t _0x1A0; uint32_t _0x1A4; - uint32_t _0x1A8; + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; uint32_t _0x1AC; uint32_t _0x1B0; uint32_t _0x1B4; uint32_t _0x1B8; uint32_t _0x1BC; - uint32_t _0x1D0; - uint32_t FUSE_TSENSOR_8; + uint32_t FUSE_WOA_SKU_FLAG; + uint32_t FUSE_ECO_RESERVE_1; + uint32_t FUSE_GCPLEX_CONFIG_FUSE; + uint32_t FUSE_PRODUCTION_MONTH; + uint32_t FUSE_RAM_REPAIR_INDICATOR; + uint32_t FUSE_TSENSOR9_CALIB; uint32_t _0x1D8; - uint32_t _0x1DC; - uint32_t _0x1E0; - uint32_t _0x1E4; - uint32_t _0x1E8; - uint32_t _0x1EC; - uint32_t _0x1F0; - uint32_t _0x1F4; - uint32_t _0x1F8; + uint32_t FUSE_VMIN_CALIBRATION; + uint32_t FUSE_AGING_SENSOR_CALIBRATION; + uint32_t FUSE_DEBUG_AUTHENTICATION; + uint32_t FUSE_SECURE_PROVISION_INDEX; + uint32_t FUSE_SECURE_PROVISION_INFO; + uint32_t FUSE_OPT_GPU_DISABLE_CP1; + uint32_t FUSE_SPARE_ENDIS; + uint32_t FUSE_ECO_RESERVE_0; uint32_t _0x1FC; uint32_t _0x200; - uint32_t FUSE_RESERVED_CALIB; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t _0x214; - uint32_t _0x218; - uint32_t FUSE_TSENSOR_9; - uint32_t _0x220; - uint32_t _0x224; - uint32_t _0x228; - uint32_t _0x22C; - uint32_t _0x230; - uint32_t _0x234; - uint32_t _0x238; - uint32_t _0x23C; - uint32_t _0x240; - uint32_t _0x244; - uint32_t _0x248; - uint32_t _0x24C; + uint32_t FUSE_RESERVED_CALIB0; + uint32_t FUSE_RESERVED_CALIB1; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1; + uint32_t FUSE_OPT_CPU_DISABLE; + uint32_t FUSE_OPT_CPU_DISABLE_CP1; + uint32_t FUSE_TSENSOR10_CALIB; + uint32_t FUSE_TSENSOR10_CALIB_AUX; + uint32_t FUSE_OPT_RAM_SVOP_DP; + uint32_t FUSE_OPT_RAM_SVOP_PDP; + uint32_t FUSE_OPT_RAM_SVOP_REG; + uint32_t FUSE_OPT_RAM_SVOP_SP; + uint32_t FUSE_OPT_RAM_SVOP_SMPDP; + uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1; + uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2; + uint32_t FUSE_OPT_CPU_DISABLE_CP2; + uint32_t FUSE_OPT_GPU_DISABLE_CP2; uint32_t FUSE_USB_CALIB_EXT; - uint32_t _0x254; - uint32_t _0x258; + uint32_t FUSE_RESERVED_FIELD; + uint32_t FUSE_OPT_ECC_EN; uint32_t _0x25C; uint32_t _0x260; uint32_t _0x264; @@ -179,35 +192,36 @@ typedef struct { uint32_t _0x270; uint32_t _0x274; uint32_t _0x278; - uint32_t _0x27C; + uint32_t FUSE_SPARE_REALIGNMENT_REG; uint32_t FUSE_SPARE_BIT[0x20]; } tegra_fuse_chip_t; -static inline volatile tegra_fuse_t *fuse_get_regs(void) { +static inline volatile tegra_fuse_t *fuse_get_regs(void) +{ return (volatile tegra_fuse_t *)FUSE_BASE; } -static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) { +static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) +{ return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE; } void fuse_init(void); - -uint32_t fuse_hw_read(uint32_t addr); -void fuse_hw_write(uint32_t value, uint32_t addr); -void fuse_hw_sense(void); void fuse_disable_programming(void); -void fuse_secondary_private_key_disable(void); +void fuse_disable_private_key(void); uint32_t fuse_get_sku_info(void); uint32_t fuse_get_spare_bit(uint32_t idx); uint32_t fuse_get_reserved_odm(uint32_t idx); - uint32_t fuse_get_bootrom_patch_version(void); uint64_t fuse_get_device_id(void); uint32_t fuse_get_dram_id(void); -uint32_t fuse_get_hardware_type(void); +uint32_t fuse_get_hardware_type(uint32_t mkey_rev); uint32_t fuse_get_retail_type(void); void fuse_get_hardware_info(void *dst); +uint32_t fuse_hw_read(uint32_t addr); +void fuse_hw_write(uint32_t value, uint32_t addr); +void fuse_hw_sense(void); + #endif diff --git a/sept/sept-secondary/src/hwinit.c b/sept/sept-secondary/src/hwinit.c index 8e61afbf3..e26f9c54e 100644 --- a/sept/sept-secondary/src/hwinit.c +++ b/sept/sept-secondary/src/hwinit.c @@ -162,16 +162,16 @@ void config_se_brom() set_aes_keyslot(0xE, sbk, 0x10); /* Lock SBK from being read. */ - se->AES_KEYSLOT_FLAGS[0xE] = 0x7E; + se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E; /* This memset needs to happen here, else TZRAM will behave weirdly later on. */ memset((void *)0x7C010000, 0, 0x10000); pmc->crypto_op = 0; - se->INT_STATUS_REG = 0x1F; + se->SE_INT_STATUS = 0x1F; /* Lock SSK (although it's not set and unused anyways). */ - se->AES_KEYSLOT_FLAGS[0xF] = 0x7E; + se->SE_CRYPTO_KEYTABLE_ACCESS[0xF] = 0x7E; /* Clear the boot reason to avoid problems later */ pmc->scratch200 = 0; diff --git a/sept/sept-secondary/src/se.c b/sept/sept-secondary/src/se.c index 488ad68eb..32a8f8eb7 100644 --- a/sept/sept-secondary/src/se.c +++ b/sept/sept-secondary/src/se.c @@ -39,20 +39,20 @@ void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) { } void se_check_error_status_reg(void) { - if (se_get_regs()->ERR_STATUS_REG) { + if (se_get_regs()->SE_ERR_STATUS) { generic_panic(); } } void se_check_for_error(void) { volatile tegra_se_t *se = se_get_regs(); - if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) { + if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) { generic_panic(); } } void se_verify_flags_cleared(void) { - if (se_get_regs()->FLAGS_REG & 3) { + if (se_get_regs()->SE_STATUS & 3) { generic_panic(); } } @@ -67,12 +67,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { - se->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -87,12 +87,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { /* Misc flags. */ if (flags & ~0x80) { /* TODO: Why are flags assigned this way? */ - se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; } /* Disable keyslot reads. */ if (flags & 0x80) { - se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot); } } @@ -105,8 +105,8 @@ void clear_aes_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } @@ -120,13 +120,13 @@ void clear_rsa_keyslot(unsigned int keyslot) { /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + se->SE_RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = 0; + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = 0; } } @@ -138,8 +138,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { } for (size_t i = 0; i < (key_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - se->AES_KEYTABLE_DATA = read32le(key, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i); } } @@ -151,13 +151,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_ } for (size_t i = 0; i < (modulus_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; - se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); } for (size_t i = 0; i < (exp_size >> 2); i++) { - se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); + se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); } g_se_modulus_sizes[keyslot] = modulus_size; @@ -172,8 +172,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { } for (size_t i = 0; i < (iv_size >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i); } } @@ -185,14 +185,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) { } for (size_t i = 0; i < (0x10 >> 2); i++) { - se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - se->AES_KEYTABLE_DATA = 0; + se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + se->SE_CRYPTO_KEYTABLE_DATA = 0; } } void set_se_ctr(const void *ctr) { for (unsigned int i = 0; i < 4; i++) { - se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4); } } @@ -203,10 +203,10 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); - se->CRYPTO_REG = keyslot_src << 24; - se->BLOCK_COUNT_REG = 0; - se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; + se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = keyslot_src << 24; + se->SE_CRYPTO_LAST_BLOCK = 0; + se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8; trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); } @@ -224,10 +224,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co stack_buf[i] = *((uint8_t *)src + src_size - i - 1); } - se->CONFIG_REG = (ALG_RSA | DST_RSAREG); - se->RSA_CONFIG = keyslot << 24; - se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + se->SE_CONFIG = (ALG_RSA | DST_RSAREG); + se->SE_RSA_CONFIG = keyslot << 24; + se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1; + se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2; trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size); se_get_exp_mod_output(dst, dst_size); @@ -245,7 +245,7 @@ void se_get_exp_mod_output(void *buf, size_t size) { /* Copy endian swapped output. */ while (num_dwords) { - *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset); + *p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset); offset += 4; p_out--; num_dwords--; @@ -314,15 +314,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v ll_init(&out_ll, dst, dst_size); /* Set the LLs. */ - se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); - se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll); + se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll); + se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll); /* Set registers for operation. */ - se->ERR_STATUS_REG = se->ERR_STATUS_REG; - se->INT_STATUS_REG = se->INT_STATUS_REG; - se->OPERATION_REG = op; + se->SE_ERR_STATUS = se->SE_ERR_STATUS; + se->SE_INT_STATUS = se->SE_INT_STATUS; + se->SE_OPERATION = op; - while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -340,7 +340,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } /* Trigger AES operation. */ - se_get_regs()->BLOCK_COUNT_REG = 0; + se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -358,15 +358,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo unsigned int num_blocks = src_size >> 4; /* Unknown what this write does, but official code writes it for CTR mode. */ - se->SPARE_0 = 1; - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x91E; + se->SE_SPARE = 1; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E; set_se_ctr(ctr); /* Handle any aligned blocks. */ size_t aligned_size = (size_t)num_blocks << 4; if (aligned_size) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size); } @@ -388,8 +388,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - se->CRYPTO_REG = keyslot << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -408,8 +408,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot << 24; se_perform_aes_block_operation(dst, 0x10, src, 0x10); } @@ -472,13 +472,13 @@ void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keys /* Encrypt/Decrypt. */ if (encrypt) { - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24 | 0x100; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24 | 0x100; } else { - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - se->CRYPTO_REG = keyslot_1 << 24; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY); + se->SE_CRYPTO_CONFIG = keyslot_1 << 24; } - se->BLOCK_COUNT_REG = (size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, size, src, size); /* XOR. */ @@ -524,16 +524,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - se->CRYPTO_REG = (keyslot << 24) | (0x145); + se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - se->BLOCK_COUNT_REG = num_blocks - 2; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2; trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); - se->CRYPTO_REG |= 0x80; + se->SE_CRYPTO_CONFIG |= 0x80; } /* Create final block. */ @@ -550,12 +550,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con } /* Perform last operation. */ - se->BLOCK_COUNT_REG = 0; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2); } } @@ -573,10 +573,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x144; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144; set_aes_keyslot_iv(keyslot, iv, 0x10); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -587,10 +587,10 @@ void se_aes_128_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, co generic_panic(); } - se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY) | (0x000 << 16); - se->CRYPTO_REG = (keyslot << 24) | 0x66; + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY) | (0x000 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x66; clear_aes_keyslot_iv(keyslot); - se->BLOCK_COUNT_REG = (src_size >> 4) - 1; + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } @@ -599,23 +599,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { volatile tegra_se_t *se = se_get_regs(); /* Setup config for SHA256, size = BITS(src_size) */ - se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); - se->SHA_CONFIG_REG = 1; - se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3); - se->_0x208 = 0; - se->_0x20C = 0; - se->_0x210 = 0; - se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3); - se->_0x218 = 0; - se->_0x21C = 0; - se->_0x220 = 0; + se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + se->SE_SHA_CONFIG = 1; + se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LENGTH[1] = 0; + se->SE_SHA_MSG_LENGTH[2] = 0; + se->SE_SHA_MSG_LENGTH[3] = 0; + se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3); + se->SE_SHA_MSG_LEFT[1] = 0; + se->SE_SHA_MSG_LEFT[2] = 0; + se->SE_SHA_MSG_LEFT[3] = 0; /* Trigger the operation. */ trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); /* Copy output hash. */ for (unsigned int i = 0; i < (0x20 >> 2); i++) { - ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2); + ((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2); } } @@ -631,12 +631,12 @@ void se_initialize_rng(unsigned int keyslot) { /* This will be discarded, when done. */ uint8_t ALIGN(16) output_buf[0x10]; - se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ - se->RNG_RESEED_INTERVAL_REG = 70001; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 5; - se->BLOCK_COUNT_REG = 0; + se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */ + se->SE_RNG_RESEED_INTERVAL = 70001; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 5; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0); } @@ -649,12 +649,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) { uint32_t num_blocks = size >> 4; size_t aligned_size = num_blocks << 4; - se->CONFIG_REG = (ALG_RNG | DST_MEMORY); - se->CRYPTO_REG = (keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; + se->SE_CONFIG = (ALG_RNG | DST_MEMORY); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; if (num_blocks >= 1) { - se->BLOCK_COUNT_REG = num_blocks - 1; + se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1; trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0); } if (size > aligned_size) { @@ -670,16 +670,16 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) } /* Setup Config. */ - se->CONFIG_REG = (ALG_RNG | DST_KEYTAB); - se->CRYPTO_REG = (rng_keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 4; - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_RNG | DST_KEYTAB); + se->SE_CRYPTO_CONFIG = (rng_keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 4; + se->SE_CRYPTO_LAST_BLOCK = 0; /* Generate low part of key. */ - se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8); + se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8); trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); /* Generate high part of key. */ - se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8) | 1; + se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8) | 1; trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); } @@ -687,24 +687,24 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) void se_set_in_context_save_mode(bool is_context_save_mode) { volatile tegra_se_t *se = se_get_regs(); - uint32_t val = se->_0x0; + uint32_t val = se->SE_SE_SECURITY; if (is_context_save_mode) { val |= 0x10000; } else { val &= 0xFFFEFFFF; } - se->_0x0 = val; + se->SE_SE_SECURITY = val; /* Perform a useless read from flags reg. */ - (void)(se->FLAGS_REG); + (void)(se->SE_STATUS); } void se_generate_srk(unsigned int srkgen_keyslot) { volatile tegra_se_t *se = se_get_regs(); - se->CONFIG_REG = (ALG_RNG | DST_SRK); - se->CRYPTO_REG = (srkgen_keyslot << 24) | 0x108; - se->RNG_CONFIG_REG = 6; - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_RNG | DST_SRK); + se->SE_CRYPTO_CONFIG = (srkgen_keyslot << 24) | 0x108; + se->SE_RNG_CONFIG = 6; + se->SE_CRYPTO_LAST_BLOCK = 0; trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); } @@ -735,39 +735,39 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void se_generate_random(rng_keyslot, work_buf, 0x10); /* Save random initial block. */ - se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); - se->BLOCK_COUNT_REG = 0; + se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY); + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst, 0x10, work_buf, 0x10); /* Save Sticky Bits. */ for (unsigned int i = 0; i < 0x2; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0); } /* Save AES Key Table. */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x30 + (i * 0x20), 0x10, NULL, 0); - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0); } /* Save AES Original IVs. */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0); } /* Save AES Updated IVs */ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0); } @@ -776,8 +776,8 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) { for (unsigned int mod_exp = 0; mod_exp < 2; mod_exp++) { for (unsigned int sub_block = 0; sub_block < 0x10; sub_block++) { - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(rsa_ctx_out, 0x10, NULL, 0); rsa_ctx_out += 0x10; } @@ -786,15 +786,15 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void /* Save "Known Pattern. " */ static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10); /* Save SRK into PMC registers. */ - se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK); - se->BLOCK_COUNT_REG = 0; + se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK); + se->SE_CRYPTO_LAST_BLOCK = 0; se_encrypt_with_srk(work_buf, 0, NULL, 0); - se->CONFIG_REG = 0; + se->SE_CONFIG = 0; se_encrypt_with_srk(work_buf, 0, NULL, 0); } diff --git a/sept/sept-secondary/src/se.h b/sept/sept-secondary/src/se.h index db1b86ba1..61733a39f 100644 --- a/sept/sept-secondary/src/se.h +++ b/sept/sept-secondary/src/se.h @@ -92,71 +92,59 @@ #define RSA_2048_BYTES 0x100 typedef struct { - uint32_t _0x0; - uint32_t _0x4; - uint32_t OPERATION_REG; - uint32_t INT_ENABLE_REG; - uint32_t INT_STATUS_REG; - uint32_t CONFIG_REG; - uint32_t IN_LL_ADDR_REG; - uint32_t _0x1C; - uint32_t _0x20; - uint32_t OUT_LL_ADDR_REG; - uint32_t _0x28; - uint32_t _0x2C; - uint8_t HASH_RESULT_REG[0x20]; - uint8_t _0x50[0x20]; - uint32_t CONTEXT_SAVE_CONFIG_REG; - uint8_t _0x74[0x18C]; - uint32_t SHA_CONFIG_REG; - uint32_t SHA_MSG_LENGTH_REG; - uint32_t _0x208; - uint32_t _0x20C; - uint32_t _0x210; - uint32_t SHA_MSG_LEFT_REG; - uint32_t _0x218; - uint32_t _0x21C; - uint32_t _0x220; - uint32_t _0x224; - uint8_t _0x228[0x58]; - uint32_t AES_KEY_READ_DISABLE_REG; - uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C4[0x3C]; - uint32_t _0x300; - uint32_t CRYPTO_REG; - uint32_t CRYPTO_CTR_REG[4]; - uint32_t BLOCK_COUNT_REG; - uint32_t AES_KEYTABLE_ADDR; - uint32_t AES_KEYTABLE_DATA; - uint32_t _0x324; - uint32_t _0x328; - uint32_t _0x32C; - uint32_t CRYPTO_KEYTABLE_DST_REG; - uint8_t _0x334[0xC]; - uint32_t RNG_CONFIG_REG; - uint32_t RNG_SRC_CONFIG_REG; - uint32_t RNG_RESEED_INTERVAL_REG; - uint8_t _0x34C[0xB4]; - uint32_t RSA_CONFIG; - uint32_t RSA_KEY_SIZE_REG; - uint32_t RSA_EXP_SIZE_REG; - uint32_t RSA_KEY_READ_DISABLE_REG; - uint32_t RSA_KEYSLOT_FLAGS[2]; - uint32_t _0x418; - uint32_t _0x41C; - uint32_t RSA_KEYTABLE_ADDR; - uint32_t RSA_KEYTABLE_DATA; - uint8_t RSA_OUTPUT[0x100]; - uint8_t _0x528[0x2D8]; - uint32_t FLAGS_REG; - uint32_t ERR_STATUS_REG; - uint32_t _0x808; - uint32_t SPARE_0; - uint32_t _0x810; + uint32_t SE_SE_SECURITY; + uint32_t SE_TZRAM_SECURITY; + uint32_t SE_OPERATION; + uint32_t SE_INT_ENABLE; + uint32_t SE_INT_STATUS; + uint32_t SE_CONFIG; + uint32_t SE_IN_LL_ADDR; + uint32_t SE_IN_CUR_BYTE_ADDR; + uint32_t SE_IN_CUR_LL_ID; + uint32_t SE_OUT_LL_ADDR; + uint32_t SE_OUT_CUR_BYTE_ADDR; + uint32_t SE_OUT_CUR_LL_ID; + uint32_t SE_HASH_RESULT[0x10]; + uint32_t SE_CTX_SAVE_CONFIG; + uint32_t _0x74[0x63]; + uint32_t SE_SHA_CONFIG; + uint32_t SE_SHA_MSG_LENGTH[0x4]; + uint32_t SE_SHA_MSG_LEFT[0x4]; + uint32_t _0x224[0x17]; + uint32_t SE_CRYPTO_SECURITY_PERKEY; + uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10]; + uint32_t _0x2C4[0x10]; + uint32_t SE_CRYPTO_CONFIG; + uint32_t SE_CRYPTO_LINEAR_CTR[0x4]; + uint32_t SE_CRYPTO_LAST_BLOCK; + uint32_t SE_CRYPTO_KEYTABLE_ADDR; + uint32_t SE_CRYPTO_KEYTABLE_DATA; + uint32_t _0x324[0x3]; + uint32_t SE_CRYPTO_KEYTABLE_DST; + uint32_t _0x334[0x3]; + uint32_t SE_RNG_CONFIG; + uint32_t SE_RNG_SRC_CONFIG; + uint32_t SE_RNG_RESEED_INTERVAL; + uint32_t _0x34C[0x2D]; + uint32_t SE_RSA_CONFIG; + uint32_t SE_RSA_KEY_SIZE; + uint32_t SE_RSA_EXP_SIZE; + uint32_t SE_RSA_SECURITY_PERKEY; + uint32_t SE_RSA_KEYTABLE_ACCESS[0x2]; + uint32_t _0x418[0x2]; + uint32_t SE_RSA_KEYTABLE_ADDR; + uint32_t SE_RSA_KEYTABLE_DATA; + uint32_t SE_RSA_OUTPUT[0x40]; + uint32_t _0x528[0xB6]; + uint32_t SE_STATUS; + uint32_t SE_ERR_STATUS; + uint32_t SE_MISC; + uint32_t SE_SPARE; + uint32_t SE_ENTROPY_DEBUG_COUNTER; uint32_t _0x814; uint32_t _0x818; uint32_t _0x81C; - uint8_t _0x820[0x17E0]; + uint32_t _0x820[0x5F8]; } tegra_se_t; typedef struct {