Cleanup FUSE, TSEC and SE code and add KFUSE state check during TSEC initialization (thanks @CTCaer).
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user