mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
ams: replace sept with tsec firmware (#1594)
* ams: replace sept with tsec firmware This replaces sept with a custom tsec key derivation firmware. NOTE: This does not use any TSEC exploits whatsoever; it is a well-signed TSEC binary assembled with envyas and signed with the real cauth key. For more details, contact SciresM#0524. * fusee: only set SBK if it's readable
This commit is contained in:
parent
f175802136
commit
17ca463c3f
137 changed files with 149 additions and 28364 deletions
17
Makefile
17
Makefile
|
@ -32,10 +32,7 @@ mesosphere: exosphere libraries
|
||||||
troposphere: stratosphere
|
troposphere: stratosphere
|
||||||
$(MAKE) -C troposphere all
|
$(MAKE) -C troposphere all
|
||||||
|
|
||||||
sept: exosphere
|
fusee: exosphere mesosphere stratosphere
|
||||||
$(MAKE) -C sept all
|
|
||||||
|
|
||||||
fusee: exosphere mesosphere stratosphere sept
|
|
||||||
$(MAKE) -C $@ all
|
$(MAKE) -C $@ all
|
||||||
|
|
||||||
libraries:
|
libraries:
|
||||||
|
@ -61,7 +58,6 @@ dist-no-debug: all
|
||||||
rm -rf out
|
rm -rf out
|
||||||
mkdir atmosphere-$(AMSVER)
|
mkdir atmosphere-$(AMSVER)
|
||||||
mkdir atmosphere-$(AMSVER)/atmosphere
|
mkdir atmosphere-$(AMSVER)/atmosphere
|
||||||
mkdir atmosphere-$(AMSVER)/sept
|
|
||||||
mkdir atmosphere-$(AMSVER)/switch
|
mkdir atmosphere-$(AMSVER)/switch
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
|
||||||
|
@ -71,13 +67,6 @@ dist-no-debug: all
|
||||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||||
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
|
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
|
||||||
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/sept/payload.bin
|
|
||||||
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
|
|
||||||
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
|
|
||||||
cp sept/sept-secondary/sept-secondary_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
|
|
||||||
cp sept/sept-secondary/sept-secondary_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_01.enc
|
|
||||||
cp sept/sept-secondary/sept-secondary_dev_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_00.enc
|
|
||||||
cp sept/sept-secondary/sept-secondary_dev_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_01.enc
|
|
||||||
cp config_templates/BCT.ini atmosphere-$(AMSVER)/atmosphere/config_templates/BCT.ini
|
cp config_templates/BCT.ini atmosphere-$(AMSVER)/atmosphere/config_templates/BCT.ini
|
||||||
cp config_templates/override_config.ini atmosphere-$(AMSVER)/atmosphere/config_templates/override_config.ini
|
cp config_templates/override_config.ini atmosphere-$(AMSVER)/atmosphere/config_templates/override_config.ini
|
||||||
cp config_templates/system_settings.ini atmosphere-$(AMSVER)/atmosphere/config_templates/system_settings.ini
|
cp config_templates/system_settings.ini atmosphere-$(AMSVER)/atmosphere/config_templates/system_settings.ini
|
||||||
|
@ -109,7 +98,6 @@ dist-no-debug: all
|
||||||
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
|
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
|
||||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
|
|
||||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER)-WITHOUT_MESOSPHERE.zip ./*; cd ../;
|
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER)-WITHOUT_MESOSPHERE.zip ./*; cd ../;
|
||||||
rm -r atmosphere-$(AMSVER)
|
rm -r atmosphere-$(AMSVER)
|
||||||
mkdir out
|
mkdir out
|
||||||
|
@ -133,9 +121,6 @@ dist: dist-no-debug
|
||||||
cp fusee/fusee-primary/fusee-primary.elf atmosphere-$(AMSVER)-debug/fusee-primary.elf
|
cp fusee/fusee-primary/fusee-primary.elf atmosphere-$(AMSVER)-debug/fusee-primary.elf
|
||||||
cp fusee/fusee-mtc/fusee-mtc.elf atmosphere-$(AMSVER)-debug/fusee-mtc.elf
|
cp fusee/fusee-mtc/fusee-mtc.elf atmosphere-$(AMSVER)-debug/fusee-mtc.elf
|
||||||
cp fusee/fusee-secondary/fusee-secondary-experimental.elf atmosphere-$(AMSVER)-debug/fusee-secondary.elf
|
cp fusee/fusee-secondary/fusee-secondary-experimental.elf atmosphere-$(AMSVER)-debug/fusee-secondary.elf
|
||||||
cp sept/sept-primary/sept-primary.elf atmosphere-$(AMSVER)-debug/sept-primary.elf
|
|
||||||
cp sept/sept-secondary/sept-secondary.elf atmosphere-$(AMSVER)-debug/sept-secondary.elf
|
|
||||||
cp sept/sept-secondary/key_derivation/key_derivation.elf atmosphere-$(AMSVER)-debug/sept-secondary-key-derivation.elf
|
|
||||||
cp exosphere/loader_stub/loader_stub.elf atmosphere-$(AMSVER)-debug/exosphere-loader-stub.elf
|
cp exosphere/loader_stub/loader_stub.elf atmosphere-$(AMSVER)-debug/exosphere-loader-stub.elf
|
||||||
cp exosphere/program/program.elf atmosphere-$(AMSVER)-debug/exosphere-program.elf
|
cp exosphere/program/program.elf atmosphere-$(AMSVER)-debug/exosphere-program.elf
|
||||||
cp exosphere/warmboot/warmboot.elf atmosphere-$(AMSVER)-debug/exosphere-warmboot.elf
|
cp exosphere/warmboot/warmboot.elf atmosphere-$(AMSVER)-debug/exosphere-warmboot.elf
|
||||||
|
|
|
@ -20,13 +20,13 @@
|
||||||
|
|
||||||
namespace ams::secmon::loader {
|
namespace ams::secmon::loader {
|
||||||
|
|
||||||
NORETURN void UncompressAndExecute() {
|
NORETURN void UncompressAndExecute(const void *program, const void *boot_code) {
|
||||||
/* Uncompress the program image. */
|
/* Uncompress the program image. */
|
||||||
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program_lz4, program_lz4_size);
|
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program, program_lz4_size);
|
||||||
|
|
||||||
/* Copy the boot image to the end of IRAM */
|
/* Copy the boot image to the end of IRAM */
|
||||||
u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - boot_code_lz4_size;
|
u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - boot_code_lz4_size;
|
||||||
std::memcpy(relocated_boot_code, boot_code_lz4, boot_code_lz4_size);
|
std::memcpy(relocated_boot_code, boot_code, boot_code_lz4_size);
|
||||||
|
|
||||||
/* Uncompress the boot image. */
|
/* Uncompress the boot image. */
|
||||||
Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size);
|
Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size);
|
||||||
|
|
|
@ -98,8 +98,8 @@ _start:
|
||||||
ldr x20, =0x7C020000
|
ldr x20, =0x7C020000
|
||||||
mov sp, x20
|
mov sp, x20
|
||||||
|
|
||||||
/* Call our init array functions. */
|
adr x0, program_lz4
|
||||||
bl __libc_init_array
|
adr x1, boot_code_lz4
|
||||||
|
|
||||||
/* Uncompress the program and iram boot code images. */
|
/* Uncompress the program and iram boot code images. */
|
||||||
b _ZN3ams6secmon6loader20UncompressAndExecuteEv
|
b _ZN3ams6secmon6loader20UncompressAndExecuteEPKvS3_
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
#include "../../../fusee/fusee-primary/fusee-primary-main/src/fs_utils.h"
|
#include "../../../fusee/fusee-primary/fusee-primary-main/src/fs_utils.h"
|
||||||
#elif defined(FUSEE_STAGE2_SRC)
|
#elif defined(FUSEE_STAGE2_SRC)
|
||||||
#include "../../../fusee/fusee-secondary/src/device_partition.h"
|
#include "../../../fusee/fusee-secondary/src/device_partition.h"
|
||||||
#elif defined(SEPT_STAGE2_SRC)
|
|
||||||
#include "../../../sept/sept-secondary/src/fs_utils.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FUSEE_STAGE2_SRC
|
#ifdef FUSEE_STAGE2_SRC
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
#include "../../../fusee/fusee-primary/fusee-primary-main/src/timers.h"
|
#include "../../../fusee/fusee-primary/fusee-primary-main/src/timers.h"
|
||||||
#elif defined(FUSEE_STAGE2_SRC)
|
#elif defined(FUSEE_STAGE2_SRC)
|
||||||
#include "../../../fusee/fusee-secondary/src/timers.h"
|
#include "../../../fusee/fusee-secondary/src/timers.h"
|
||||||
#elif defined(SEPT_STAGE2_SRC)
|
|
||||||
#include "../../../sept/sept-secondary/src/timers.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNSTUFF_BITS(resp,start,size) \
|
#define UNSTUFF_BITS(resp,start,size) \
|
||||||
|
@ -102,7 +100,7 @@ static int sdmmc_device_send_r1_cmd(sdmmc_device_t *device, uint32_t opcode, uin
|
||||||
if (resp_mask) {
|
if (resp_mask) {
|
||||||
resp &= ~(resp_mask);
|
resp &= ~(resp_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We got an error state. */
|
/* We got an error state. */
|
||||||
if (is_sdmmc_device_r1_error(resp)) {
|
if (is_sdmmc_device_r1_error(resp)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -355,7 +353,7 @@ static int sdmmc_sd_decode_scr(sdmmc_device_t *device, uint8_t *scr) {
|
||||||
if (device->scr.sda_spec3) {
|
if (device->scr.sda_spec3) {
|
||||||
device->scr.cmds = UNSTUFF_BITS(resp, 32, 2);
|
device->scr.cmds = UNSTUFF_BITS(resp, 32, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unknown SCR structure version. */
|
/* Unknown SCR structure version. */
|
||||||
if (UNSTUFF_BITS(resp, 60, 4)) {
|
if (UNSTUFF_BITS(resp, 60, 4)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -465,7 +463,7 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
|
||||||
if (is_uhs_en) {
|
if (is_uhs_en) {
|
||||||
arg |= SD_OCR_S18R;
|
arg |= SD_OCR_S18R;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.opcode = SD_APP_OP_COND;
|
cmd.opcode = SD_APP_OP_COND;
|
||||||
cmd.arg = arg;
|
cmd.arg = arg;
|
||||||
cmd.flags = SDMMC_RSP_R3;
|
cmd.flags = SDMMC_RSP_R3;
|
||||||
|
@ -916,7 +914,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
|
||||||
if (!sdmmc_sd_decode_csd(device, csd)) {
|
if (!sdmmc_sd_decode_csd(device, csd)) {
|
||||||
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
|
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we never switched to 1.8V, change the bus speed mode. */
|
/* If we never switched to 1.8V, change the bus speed mode. */
|
||||||
if (!device->is_180v) {
|
if (!device->is_180v) {
|
||||||
/* Reconfigure the internal clock. */
|
/* Reconfigure the internal clock. */
|
||||||
|
@ -1155,7 +1153,7 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo
|
||||||
if (resp & SD_OCR_CCS) {
|
if (resp & SD_OCR_CCS) {
|
||||||
device->is_block_sdhc = true;
|
device->is_block_sdhc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1439,7 +1437,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
|
||||||
if (!sdmmc_mmc_decode_csd(device, csd)) {
|
if (!sdmmc_mmc_decode_csd(device, csd)) {
|
||||||
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
|
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reconfigure the internal clock. */
|
/* Reconfigure the internal clock. */
|
||||||
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_LEGACY)) {
|
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_LEGACY)) {
|
||||||
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
|
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
|
||||||
|
@ -1498,7 +1496,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
|
||||||
} else {
|
} else {
|
||||||
sdmmc_info(sdmmc, "BKOPS is disabled!");
|
sdmmc_info(sdmmc, "BKOPS is disabled!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch to high speed mode. */
|
/* Switch to high speed mode. */
|
||||||
if (!sdmmc_mmc_select_timing(device, bus_speed)) {
|
if (!sdmmc_mmc_select_timing(device, bus_speed)) {
|
||||||
sdmmc_error(sdmmc, "Failed to switch to high speed mode!");
|
sdmmc_error(sdmmc, "Failed to switch to high speed mode!");
|
||||||
|
|
|
@ -41,15 +41,6 @@
|
||||||
#include "../../../fusee/fusee-secondary/src/gpio.h"
|
#include "../../../fusee/fusee-secondary/src/gpio.h"
|
||||||
#include "../../../fusee/fusee-secondary/src/pmc.h"
|
#include "../../../fusee/fusee-secondary/src/pmc.h"
|
||||||
#include "../../../fusee/fusee-secondary/src/max7762x.h"
|
#include "../../../fusee/fusee-secondary/src/max7762x.h"
|
||||||
#elif defined(SEPT_STAGE2_SRC)
|
|
||||||
#include "../../../sept/sept-secondary/src/car.h"
|
|
||||||
#include "../../../sept/sept-secondary/src/fuse.h"
|
|
||||||
#include "../../../sept/sept-secondary/src/pinmux.h"
|
|
||||||
#include "../../../sept/sept-secondary/src/timers.h"
|
|
||||||
#include "../../../sept/sept-secondary/src/apb_misc.h"
|
|
||||||
#include "../../../sept/sept-secondary/src/gpio.h"
|
|
||||||
#include "../../../sept/sept-secondary/src/pmc.h"
|
|
||||||
#include "../../../sept/sept-secondary/src/max7762x.h"
|
|
||||||
#endif
|
#endif
|
||||||
#include "../log.h"
|
#include "../log.h"
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,12 @@ static void config_se_brom(void) {
|
||||||
|
|
||||||
/* Bootrom part we skipped. */
|
/* Bootrom part we skipped. */
|
||||||
uint32_t sbk[4] = {fuse_chip->FUSE_PRIVATE_KEY[0], fuse_chip->FUSE_PRIVATE_KEY[1], fuse_chip->FUSE_PRIVATE_KEY[2], fuse_chip->FUSE_PRIVATE_KEY[3]};
|
uint32_t sbk[4] = {fuse_chip->FUSE_PRIVATE_KEY[0], fuse_chip->FUSE_PRIVATE_KEY[1], fuse_chip->FUSE_PRIVATE_KEY[2], fuse_chip->FUSE_PRIVATE_KEY[3]};
|
||||||
set_aes_keyslot(0xE, sbk, 0x10);
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
if (sbk[i] != 0xFFFFFFFF) {
|
||||||
|
set_aes_keyslot(0xE, sbk, 0x10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Lock SBK from being read. */
|
/* Lock SBK from being read. */
|
||||||
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
|
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
|
||||||
|
@ -247,7 +252,7 @@ void nx_hwinit(bool enable_log) {
|
||||||
} else {
|
} else {
|
||||||
uint8_t val = 0x40;
|
uint8_t val = 0x40;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
|
||||||
val = 0x60;
|
val = 0x58;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
|
||||||
val = 0x38;
|
val = 0x38;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
|
||||||
|
|
|
@ -92,8 +92,8 @@ export KIPDIRS := $(AMS)/stratosphere/loader $(AMS)/stratosphere/ncm $(AMS)/stra
|
||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||||
$(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \
|
$(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \
|
||||||
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \
|
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/emummc $(AMS)/mesosphere \
|
||||||
$(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere $(AMS)/mesosphere/kernel_ldr $(KIPDIRS)
|
$(KIPDIRS)
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
@ -103,9 +103,7 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
KIPFILES := loader.kip ncm.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
|
KIPFILES := loader.kip ncm.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
|
||||||
exosphere.bin warmboot.bin rebootstub.bin thermosphere.bin splash_screen.bin \
|
exosphere.bin warmboot.bin rebootstub.bin thermosphere.bin splash_screen.bin \
|
||||||
sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
|
emummc.kip mesosphere.bin mariko_fatal.bin $(KIPFILES)
|
||||||
sept-secondary_dev_00.enc sept-secondary_dev_01.enc mesosphere.bin kernel_ldr.bin \
|
|
||||||
mariko_fatal.bin $(KIPFILES)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# use CXX for linking C++ projects, CC for standard C
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
@ -133,7 +131,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||||
|
|
||||||
.PHONY: $(BUILD) clean all
|
.PHONY: $(BUILD) clean all
|
||||||
.PHONY: check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_stratosphere check_libraries
|
.PHONY: check_fusee_primary check_exosphere check_emummc check_thermosphere check_stratosphere check_libraries
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
all: $(BUILD)
|
all: $(BUILD)
|
||||||
|
@ -144,9 +142,6 @@ check_fusee_primary:
|
||||||
check_exosphere:
|
check_exosphere:
|
||||||
@$(MAKE) -C $(AMS)/exosphere all
|
@$(MAKE) -C $(AMS)/exosphere all
|
||||||
|
|
||||||
check_sept:
|
|
||||||
@$(MAKE) -C $(AMS)/sept all
|
|
||||||
|
|
||||||
check_emummc:
|
check_emummc:
|
||||||
@$(MAKE) -C $(AMS)/emummc EMUMMCDIR=$(AMS)/emummc all
|
@$(MAKE) -C $(AMS)/emummc EMUMMCDIR=$(AMS)/emummc all
|
||||||
|
|
||||||
|
@ -163,7 +158,7 @@ check_libraries:
|
||||||
@$(MAKE) -C $(AMS)/libraries all
|
@$(MAKE) -C $(AMS)/libraries all
|
||||||
|
|
||||||
|
|
||||||
$(BUILD): check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere
|
$(BUILD): check_fusee_primary check_exosphere check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
@ -176,7 +171,6 @@ clean:
|
||||||
@$(MAKE) -C $(AMS)/libraries clean
|
@$(MAKE) -C $(AMS)/libraries clean
|
||||||
@$(MAKE) -C $(AMS)/mesosphere clean
|
@$(MAKE) -C $(AMS)/mesosphere clean
|
||||||
@$(MAKE) -C $(AMS)/stratosphere clean
|
@$(MAKE) -C $(AMS)/stratosphere clean
|
||||||
@$(MAKE) -C $(AMS)/sept clean
|
|
||||||
@$(MAKE) -C $(AMS)/emummc clean
|
@$(MAKE) -C $(AMS)/emummc clean
|
||||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
||||||
|
|
||||||
|
@ -216,31 +210,6 @@ fusee_primary.bin.o fusee_primary_bin.h: fusee-primary.bin
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(_bin2o)
|
@$(_bin2o)
|
||||||
|
|
||||||
sept_primary.bin.o sept_primary_bin.h: sept-primary.bin
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(_bin2o)
|
|
||||||
|
|
||||||
sept_secondary_00.enc.o sept_secondary_00_enc.h: sept-secondary_00.enc
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(_bin2o)
|
|
||||||
|
|
||||||
sept_secondary_01.enc.o sept_secondary_01_enc.h: sept-secondary_01.enc
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(_bin2o)
|
|
||||||
|
|
||||||
sept_secondary_dev_00.enc.o sept_secondary_dev_00_enc.h: sept-secondary_dev_00.enc
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(_bin2o)
|
|
||||||
|
|
||||||
sept_secondary_dev_01.enc.o sept_secondary_dev_01_enc.h: sept-secondary_dev_01.enc
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(_bin2o)
|
|
||||||
|
|
||||||
%.bin.o %_bin.h: %.bin
|
%.bin.o %_bin.h: %.bin
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
|
|
BIN
fusee/fusee-secondary/data/tsec_keygen.bin
Normal file
BIN
fusee/fusee-secondary/data/tsec_keygen.bin
Normal file
Binary file not shown.
|
@ -244,12 +244,6 @@ SECTIONS
|
||||||
PROVIDE(__pm_kip_size__ = pm_kip_end - pm_kip);
|
PROVIDE(__pm_kip_size__ = pm_kip_end - pm_kip);
|
||||||
PROVIDE(__rebootstub_bin_start__ = rebootstub_bin - __start__);
|
PROVIDE(__rebootstub_bin_start__ = rebootstub_bin - __start__);
|
||||||
PROVIDE(__rebootstub_bin_size__ = rebootstub_bin_end - rebootstub_bin);
|
PROVIDE(__rebootstub_bin_size__ = rebootstub_bin_end - rebootstub_bin);
|
||||||
PROVIDE(__sept_primary_bin_start__ = sept_primary_bin - __start__);
|
|
||||||
PROVIDE(__sept_primary_bin_size__ = sept_primary_bin_end - sept_primary_bin);
|
|
||||||
PROVIDE(__sept_secondary_00_enc_start__ = sept_secondary_00_enc - __start__);
|
|
||||||
PROVIDE(__sept_secondary_00_enc_size__ = sept_secondary_00_enc_end - sept_secondary_00_enc);
|
|
||||||
PROVIDE(__sept_secondary_01_enc_start__ = sept_secondary_01_enc - __start__);
|
|
||||||
PROVIDE(__sept_secondary_01_enc_size__ = sept_secondary_01_enc_end - sept_secondary_01_enc);
|
|
||||||
PROVIDE(__sm_kip_start__ = sm_kip - __start__);
|
PROVIDE(__sm_kip_start__ = sm_kip - __start__);
|
||||||
PROVIDE(__sm_kip_size__ = sm_kip_end - sm_kip);
|
PROVIDE(__sm_kip_size__ = sm_kip_end - sm_kip);
|
||||||
PROVIDE(__spl_kip_start__ = spl_kip - __start__);
|
PROVIDE(__spl_kip_start__ = spl_kip - __start__);
|
||||||
|
@ -266,4 +260,6 @@ SECTIONS
|
||||||
PROVIDE(__mesosphere_bin_size__ = mesosphere_bin_end - mesosphere_bin);
|
PROVIDE(__mesosphere_bin_size__ = mesosphere_bin_end - mesosphere_bin);
|
||||||
PROVIDE(__mariko_fatal_bin_start__ = mariko_fatal_bin - __start__);
|
PROVIDE(__mariko_fatal_bin_start__ = mariko_fatal_bin - __start__);
|
||||||
PROVIDE(__mariko_fatal_bin_size__ = mariko_fatal_bin_end - mariko_fatal_bin);
|
PROVIDE(__mariko_fatal_bin_size__ = mariko_fatal_bin_end - mariko_fatal_bin);
|
||||||
|
PROVIDE(__tsec_keygen_bin_start__ = tsec_keygen_bin - __start__);
|
||||||
|
PROVIDE(__tsec_keygen_bin_size__ = tsec_keygen_bin_end - tsec_keygen_bin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_CAR_H
|
#ifndef FUSEE_CAR_H
|
||||||
#define FUSEE_CAR_H
|
#define FUSEE_CAR_H
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ typedef enum {
|
||||||
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
|
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
|
||||||
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
||||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||||
CARDEVICE_MSELECT = ((3 << 5) | 0x8),
|
CARDEVICE_MSELECT = ((3 << 5) | 0x3),
|
||||||
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
||||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
||||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
||||||
|
@ -489,7 +489,7 @@ typedef struct {
|
||||||
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
|
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
|
||||||
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
|
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
|
||||||
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
|
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
|
||||||
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
|
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
|
||||||
} tegra_car_t;
|
} tegra_car_t;
|
||||||
|
|
||||||
static inline volatile tegra_car_t *car_get_regs(void) {
|
static inline volatile tegra_car_t *car_get_regs(void) {
|
||||||
|
|
|
@ -21,12 +21,6 @@
|
||||||
#include "kernel_patches.h"
|
#include "kernel_patches.h"
|
||||||
#include "ips.h"
|
#include "ips.h"
|
||||||
|
|
||||||
#define u8 uint8_t
|
|
||||||
#define u32 uint32_t
|
|
||||||
#include "kernel_ldr_bin.h"
|
|
||||||
#undef u8
|
|
||||||
#undef u32
|
|
||||||
|
|
||||||
#define MAKE_BRANCH(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
#define MAKE_BRANCH(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||||
#define MAKE_NOP 0xD503201F
|
#define MAKE_NOP 0xD503201F
|
||||||
|
|
||||||
|
|
|
@ -26,19 +26,6 @@
|
||||||
|
|
||||||
#define AL16 ALIGN(16)
|
#define AL16 ALIGN(16)
|
||||||
|
|
||||||
static const uint8_t AL16 keyblob_seeds[MASTERKEY_REVISION_MAX][0x10] = {
|
|
||||||
{0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, /* Keyblob seed 00. */
|
|
||||||
{0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC}, /* Keyblob seed 01. */
|
|
||||||
{0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B}, /* Keyblob seed 02. */
|
|
||||||
{0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE}, /* Keyblob seed 03. */
|
|
||||||
{0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80}, /* Keyblob seed 04. */
|
|
||||||
{0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0} /* Keyblob seed 05. */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 keyblob_mac_seed[0x10] = {
|
|
||||||
0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 masterkey_seed[0x10] = {
|
static const uint8_t AL16 masterkey_seed[0x10] = {
|
||||||
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
||||||
};
|
};
|
||||||
|
@ -55,164 +42,51 @@ static const uint8_t AL16 masterkey_4x_seed[0x10] = {
|
||||||
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: Bother adding 8.1.0 here? We'll never call into here... */
|
static const uint8_t AL16 keyblob_seed_00[0x10] = {
|
||||||
static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MASTERKEY_REVISION_600_610][0x10] = {
|
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
|
||||||
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* MasterKek seed 06. */
|
};
|
||||||
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* MasterKek seed 07. */
|
|
||||||
|
static const uint8_t AL16 master_kek_seed_erista[0x10] = { /* TODO: Update on next change of keys. */
|
||||||
|
0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A /* Erista MasterKek seed 0B. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t AL16 master_devkey_seed_erista[0x10] = {
|
||||||
|
0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
|
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
|
||||||
0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1, /* Mariko MasterKek seed 0B. */
|
0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1, /* Mariko MasterKek seed 0B. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static nx_dec_keyblob_t AL16 g_dec_keyblobs[32];
|
|
||||||
|
|
||||||
static int get_keyblob(nx_keyblob_t *dst, uint32_t revision, const nx_keyblob_t *keyblobs, uint32_t available_revision) {
|
|
||||||
if (revision >= 0x20) {
|
|
||||||
return -1;
|
|
||||||
/* TODO: what should we do? */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyblobs != NULL) {
|
|
||||||
*dst = keyblobs[revision];
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
/* TODO: what should we do? */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool safe_memcmp(uint8_t *a, uint8_t *b, size_t sz) {
|
|
||||||
uint8_t different = 0;
|
|
||||||
for (unsigned int i = 0; i < sz; i++) {
|
|
||||||
different |= a[i] ^ b[i];
|
|
||||||
}
|
|
||||||
return different != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int decrypt_keyblob(const nx_keyblob_t *keyblobs, uint32_t revision, uint32_t available_revision) {
|
|
||||||
nx_keyblob_t AL16 keyblob;
|
|
||||||
uint8_t AL16 work_buffer[0x10];
|
|
||||||
unsigned int keyslot = revision == MASTERKEY_REVISION_100_230 ? 0xF : KEYSLOT_SWITCH_TEMPKEY;
|
|
||||||
|
|
||||||
if (get_keyblob(&keyblob, revision, keyblobs, available_revision) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, keyblob_seeds[revision], 0x10);
|
|
||||||
decrypt_data_into_keyslot(keyslot, 0xE, work_buffer, 0x10);
|
|
||||||
decrypt_data_into_keyslot(0xB, keyslot, keyblob_mac_seed, 0x10);
|
|
||||||
|
|
||||||
/* Validate keyblob. */
|
|
||||||
se_compute_aes_128_cmac(0xB, work_buffer, 0x10, keyblob.mac + sizeof(keyblob.mac), sizeof(keyblob) - sizeof(keyblob.mac));
|
|
||||||
if (safe_memcmp(keyblob.mac, work_buffer, 0x10)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrypt keyblob. */
|
|
||||||
se_aes_ctr_crypt(keyslot, &g_dec_keyblobs[revision], sizeof(g_dec_keyblobs[revision]), keyblob.data, sizeof(keyblob.data), keyblob.ctr, sizeof(keyblob.ctr));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int load_package1_key(uint32_t revision) {
|
|
||||||
if (revision > MASTERKEY_REVISION_600_610) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_aes_keyslot(0xB, g_dec_keyblobs[revision].package1_key, 0x10);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive all Switch keys. */
|
/* Derive all Switch keys. */
|
||||||
int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_keys, unsigned int *out_keygen_type) {
|
int derive_nx_keydata_erista(uint32_t target_firmware) {
|
||||||
uint8_t AL16 work_buffer[0x10];
|
uint8_t AL16 work_buffer[0x10];
|
||||||
uint8_t AL16 zeroes[0x10] = {0};
|
|
||||||
|
|
||||||
/* Initialize keygen type. */
|
/* Get whether we're using dev keys. */
|
||||||
*out_keygen_type = 0;
|
const bool is_retail = fuse_get_hardware_state() != 0;
|
||||||
|
|
||||||
/* TODO: Set keyslot flags properly in preparation of derivation. */
|
/* Derive Keyblob Key 00. */
|
||||||
set_aes_keyslot_flags(0xE, 0x15);
|
se_aes_ecb_decrypt_block(0xC, work_buffer, 0x10, keyblob_seed_00, 0x10);
|
||||||
set_aes_keyslot_flags(0xD, 0x15);
|
decrypt_data_into_keyslot(0xF, 0xE, work_buffer, 0x10);
|
||||||
|
|
||||||
/* Set the TSEC key. */
|
/* Derive master kek. */
|
||||||
set_aes_keyslot(0xD, tsec_key, 0x10);
|
decrypt_data_into_keyslot(0xE, is_retail ? 0xD : 0xB, master_kek_seed_erista, 0x10);
|
||||||
|
|
||||||
/* Decrypt all keyblobs, setting keyslot 0xF correctly. */
|
/* Derive master key, device master key. */
|
||||||
for (unsigned int rev = 0; rev <= MASTERKEY_REVISION_600_610; rev++) {
|
decrypt_data_into_keyslot(0xD, 0xE, masterkey_seed, 0x10);
|
||||||
int ret = decrypt_keyblob(keyblobs, rev, available_revision);
|
decrypt_data_into_keyslot(0xE, 0xE, masterkey_4x_seed, 0x10);
|
||||||
if (ret) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do 6.2.0+ keygen. */
|
/* Derive device keys. */
|
||||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
|
|
||||||
uint32_t desired_keyblob;
|
|
||||||
|
|
||||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
|
|
||||||
/* NOTE: We load in the current key for all >= 8.1.0 firmwares to reduce sept binaries. */
|
|
||||||
desired_keyblob = MASTERKEY_REVISION_C10_CURRENT;
|
|
||||||
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
|
|
||||||
desired_keyblob = MASTERKEY_REVISION_700_800;
|
|
||||||
} else {
|
|
||||||
desired_keyblob = MASTERKEY_REVISION_620;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try emulation result. */
|
|
||||||
for (unsigned int rev = MASTERKEY_REVISION_620; rev < MASTERKEY_REVISION_MAX; rev++) {
|
|
||||||
void *tsec_root_key = (void *)((uintptr_t)tsec_root_keys + 0x10 * (rev - MASTERKEY_REVISION_620));
|
|
||||||
if (memcmp(tsec_root_key, zeroes, 0x10) != 0) {
|
|
||||||
/* We got a valid key from emulation. */
|
|
||||||
set_aes_keyslot(0xD, tsec_root_key, 0x10);
|
|
||||||
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, new_master_kek_seeds[rev - MASTERKEY_REVISION_620], 0x10);
|
|
||||||
memcpy(g_dec_keyblobs[rev].master_kek, work_buffer, 0x10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(g_dec_keyblobs[desired_keyblob].master_kek, zeroes, 0x10) == 0) {
|
|
||||||
/* Try reading the keys from a file. */
|
|
||||||
const char *keyfile = fuse_get_hardware_state() != 0 ? "atmosphere/prod.keys" : "atmosphere/dev.keys";
|
|
||||||
FILE *extkey_file = fopen(keyfile, "r");
|
|
||||||
AL16 fusee_extkeys_t extkeys = {0};
|
|
||||||
if (extkey_file == NULL) {
|
|
||||||
fatal_error("Error: failed to read %s, needed for 6.2.0+ key derivation!", keyfile);
|
|
||||||
}
|
|
||||||
extkeys_initialize_keyset(&extkeys, extkey_file);
|
|
||||||
fclose(extkey_file);
|
|
||||||
for (unsigned int rev = MASTERKEY_REVISION_620; rev < MASTERKEY_REVISION_MAX; rev++) {
|
|
||||||
if (memcmp(extkeys.tsec_root_keys[rev - MASTERKEY_REVISION_620], zeroes, 0x10) != 0) {
|
|
||||||
set_aes_keyslot(0xD, extkeys.tsec_root_keys[rev - MASTERKEY_REVISION_620], 0x10);
|
|
||||||
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, new_master_kek_seeds[rev - MASTERKEY_REVISION_620], 0x10);
|
|
||||||
memcpy(g_dec_keyblobs[rev].master_kek, work_buffer, 0x10);
|
|
||||||
} else {
|
|
||||||
memcpy(g_dec_keyblobs[rev].master_kek, extkeys.master_keks[rev], 0x10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(g_dec_keyblobs[available_revision].master_kek, zeroes, 0x10) == 0) {
|
|
||||||
fatal_error("Error: failed to derive master_kek_%02x!", available_revision);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear the SBK. */
|
|
||||||
clear_aes_keyslot(0xE);
|
|
||||||
|
|
||||||
/* Get needed data. */
|
|
||||||
set_aes_keyslot(0xD, g_dec_keyblobs[available_revision].master_kek, 0x10);
|
|
||||||
|
|
||||||
/* Also set the Package1 key for the revision that is stored on the eMMC boot0 partition. */
|
|
||||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
|
|
||||||
load_package1_key(available_revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive keys for Exosphere, lock critical keyslots. */
|
|
||||||
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
|
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
|
||||||
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
|
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
|
||||||
decrypt_data_into_keyslot(0xC, 0xD, masterkey_4x_seed, 0x10);
|
|
||||||
decrypt_data_into_keyslot(0xD, 0xD, masterkey_seed, 0x10);
|
/* Derive firmware specific device key. */
|
||||||
|
se_aes_ecb_decrypt_block(0xA, work_buffer, 0x10, master_devkey_seed_erista, 0x10);
|
||||||
|
decrypt_data_into_keyslot(0xC, 0xE, work_buffer, 0x10);
|
||||||
|
|
||||||
|
/* Clear keyslots 0xB/0xE. */
|
||||||
|
clear_aes_keyslot(0xB);
|
||||||
|
clear_aes_keyslot(0xE);
|
||||||
|
|
||||||
/* Setup master key revision, derive older master keys for use. */
|
/* Setup master key revision, derive older master keys for use. */
|
||||||
return mkey_detect_revision(fuse_get_hardware_state() != 0);
|
return mkey_detect_revision(fuse_get_hardware_state() != 0);
|
||||||
|
|
|
@ -27,29 +27,8 @@ typedef enum BisPartition {
|
||||||
BisPartition_UserSystem = 2,
|
BisPartition_UserSystem = 2,
|
||||||
} BisPartition;
|
} BisPartition;
|
||||||
|
|
||||||
typedef struct {
|
int derive_nx_keydata_erista(uint32_t target_firmware);
|
||||||
union {
|
|
||||||
uint8_t keys[9][0x10];
|
|
||||||
struct {
|
|
||||||
uint8_t master_kek[0x10];
|
|
||||||
uint8_t _keys[7][0x10];
|
|
||||||
uint8_t package1_key[0x10];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} nx_dec_keyblob_t;
|
|
||||||
|
|
||||||
typedef struct nx_keyblob_t {
|
|
||||||
uint8_t mac[0x10];
|
|
||||||
uint8_t ctr[0x10];
|
|
||||||
union {
|
|
||||||
uint8_t data[0x90];
|
|
||||||
nx_dec_keyblob_t dec_blob;
|
|
||||||
};
|
|
||||||
} nx_keyblob_t;
|
|
||||||
|
|
||||||
int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_key, unsigned int *out_keygen_type);
|
|
||||||
int derive_nx_keydata_mariko(uint32_t target_firmware);
|
int derive_nx_keydata_mariko(uint32_t target_firmware);
|
||||||
int load_package1_key(uint32_t revision);
|
|
||||||
void derive_bis_key(void *dst, BisPartition partition_id, uint32_t target_firmware);
|
void derive_bis_key(void *dst, BisPartition partition_id, uint32_t target_firmware);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -185,8 +185,8 @@ void derive_new_device_keys(bool is_retail, unsigned int keygen_keyslot, unsigne
|
||||||
if (relative_revision > mkey_get_revision()) {
|
if (relative_revision > mkey_get_revision()) {
|
||||||
break;
|
break;
|
||||||
} else if (relative_revision == mkey_get_revision()) {
|
} else if (relative_revision == mkey_get_revision()) {
|
||||||
/* On 7.0.0 erista, sept will have derived this key for us already. */
|
/* On Erista, this will already be derived. */
|
||||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0 || is_mariko) {
|
if (is_mariko) {
|
||||||
decrypt_data_into_keyslot(is_mariko ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
|
decrypt_data_into_keyslot(is_mariko ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
#include "masterkey.h"
|
#include "masterkey.h"
|
||||||
#include "package1.h"
|
#include "package1.h"
|
||||||
#include "package2.h"
|
#include "package2.h"
|
||||||
#include "smmu.h"
|
|
||||||
#include "tsec.h"
|
#include "tsec.h"
|
||||||
#include "lp0.h"
|
#include "lp0.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
@ -59,11 +58,8 @@
|
||||||
#include "exosphere_bin.h"
|
#include "exosphere_bin.h"
|
||||||
#include "mariko_fatal_bin.h"
|
#include "mariko_fatal_bin.h"
|
||||||
#include "mesosphere_bin.h"
|
#include "mesosphere_bin.h"
|
||||||
#include "sept_secondary_00_enc.h"
|
|
||||||
#include "sept_secondary_01_enc.h"
|
|
||||||
#include "sept_secondary_dev_00_enc.h"
|
|
||||||
#include "sept_secondary_dev_01_enc.h"
|
|
||||||
#include "warmboot_bin.h"
|
#include "warmboot_bin.h"
|
||||||
|
#include "tsec_keygen_bin.h"
|
||||||
#include "emummc_kip.h"
|
#include "emummc_kip.h"
|
||||||
#undef u8
|
#undef u8
|
||||||
#undef u32
|
#undef u32
|
||||||
|
@ -724,18 +720,11 @@ static void nxboot_move_bootconfig() {
|
||||||
free(bootconfig);
|
free(bootconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_and_clear_has_run_sept(void) {
|
|
||||||
bool has_run_sept = (MAKE_EMC_REG(EMC_SCRATCH0) & 0x80000000) != 0;
|
|
||||||
MAKE_EMC_REG(EMC_SCRATCH0) &= ~0x80000000;
|
|
||||||
return has_run_sept;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_mariko_warmboot_path(char *dst, size_t dst_size, uint32_t version) {
|
static void get_mariko_warmboot_path(char *dst, size_t dst_size, uint32_t version) {
|
||||||
snprintf(dst, dst_size, "warmboot_mariko/wb_%02" PRIx32 ".bin", version);
|
snprintf(dst, dst_size, "warmboot_mariko/wb_%02" PRIx32 ".bin", version);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the main function responsible for booting Horizon. */
|
/* This is the main function responsible for booting Horizon. */
|
||||||
static nx_keyblob_t __attribute__((aligned(16))) g_keyblobs[32];
|
|
||||||
uint32_t nxboot_main(void) {
|
uint32_t nxboot_main(void) {
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
loader_ctx_t *loader_ctx = get_loader_ctx();
|
loader_ctx_t *loader_ctx = get_loader_ctx();
|
||||||
|
@ -745,8 +734,6 @@ uint32_t nxboot_main(void) {
|
||||||
size_t package2_size;
|
size_t package2_size;
|
||||||
void *tsec_fw;
|
void *tsec_fw;
|
||||||
size_t tsec_fw_size;
|
size_t tsec_fw_size;
|
||||||
const void *sept_secondary_enc = NULL;
|
|
||||||
size_t sept_secondary_enc_size = 0;
|
|
||||||
void *warmboot_fw;
|
void *warmboot_fw;
|
||||||
size_t warmboot_fw_size;
|
size_t warmboot_fw_size;
|
||||||
void *warmboot_memaddr;
|
void *warmboot_memaddr;
|
||||||
|
@ -756,7 +743,6 @@ uint32_t nxboot_main(void) {
|
||||||
size_t mesosphere_size;
|
size_t mesosphere_size;
|
||||||
void *emummc;
|
void *emummc;
|
||||||
size_t emummc_size;
|
size_t emummc_size;
|
||||||
uint32_t available_revision;
|
|
||||||
FILE *boot0, *pk2file;
|
FILE *boot0, *pk2file;
|
||||||
void *exosphere_memaddr;
|
void *exosphere_memaddr;
|
||||||
exo_emummc_config_t exo_emummc_cfg;
|
exo_emummc_config_t exo_emummc_cfg;
|
||||||
|
@ -844,7 +830,7 @@ uint32_t nxboot_main(void) {
|
||||||
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (package1_read_and_parse_boot0_erista(&package1loader, &package1loader_size, g_keyblobs, &available_revision, boot0) == -1) {
|
if (package1_read_and_parse_boot0_erista(&package1loader, &package1loader_size, boot0) == -1) {
|
||||||
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -860,103 +846,26 @@ uint32_t nxboot_main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle TSEC and Sept (Erista only). */
|
/* Handle TSEC and Sept (Erista only). */
|
||||||
uint8_t tsec_key[0x10] = {0};
|
|
||||||
uint8_t tsec_root_keys[0x20][0x10] = {0};
|
|
||||||
if (!is_mariko) {
|
if (!is_mariko) {
|
||||||
/* Read the TSEC firmware from a file, otherwise from PK1L. */
|
/* Use Atmosphere's tsec_keygen implementation. */
|
||||||
if (loader_ctx->tsecfw_path[0] != '\0') {
|
tsec_fw_size = tsec_keygen_bin_size;
|
||||||
tsec_fw_size = get_file_size(loader_ctx->tsecfw_path);
|
tsec_fw = memalign(0x100, tsec_fw_size);
|
||||||
if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000 && tsec_fw_size != 0x3300)) {
|
|
||||||
fatal_error("[NXBOOT] TSEC firmware from %s has a wrong size!\n", loader_ctx->tsecfw_path);
|
|
||||||
} else if (tsec_fw_size == 0) {
|
|
||||||
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for the TSEC firmware. */
|
if (tsec_fw == NULL) {
|
||||||
tsec_fw = memalign(0x100, tsec_fw_size);
|
fatal_error("[NXBOOT] Out of memory!\n");
|
||||||
|
|
||||||
if (tsec_fw == NULL) {
|
|
||||||
fatal_error("[NXBOOT] Out of memory!\n");
|
|
||||||
}
|
|
||||||
if (read_from_file(tsec_fw, tsec_fw_size, loader_ctx->tsecfw_path) != tsec_fw_size) {
|
|
||||||
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tsec_fw_size == 0x3000) {
|
|
||||||
if (fuse_get_hardware_state() != 0) {
|
|
||||||
sept_secondary_enc = sept_secondary_00_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_00_enc_size;
|
|
||||||
} else {
|
|
||||||
sept_secondary_enc = sept_secondary_dev_00_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_dev_00_enc_size;
|
|
||||||
}
|
|
||||||
} else if (tsec_fw_size == 0x3300) {
|
|
||||||
if (fuse_get_hardware_state() != 0) {
|
|
||||||
sept_secondary_enc = sept_secondary_01_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_01_enc_size;
|
|
||||||
} else {
|
|
||||||
sept_secondary_enc = sept_secondary_dev_01_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_dev_01_enc_size;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fatal_error("[NXBOOT] Unable to identify sept revision to run.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!package1_get_tsec_fw(&tsec_fw, package1loader, package1loader_size)) {
|
|
||||||
fatal_error("[NXBOOT] Failed to read the TSEC firmware from Package1loader!\n");
|
|
||||||
}
|
|
||||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
|
|
||||||
if (fuse_get_hardware_state() != 0) {
|
|
||||||
sept_secondary_enc = sept_secondary_01_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_01_enc_size;
|
|
||||||
} else {
|
|
||||||
sept_secondary_enc = sept_secondary_dev_01_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_dev_01_enc_size;
|
|
||||||
}
|
|
||||||
tsec_fw_size = 0x3300;
|
|
||||||
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
|
|
||||||
if (fuse_get_hardware_state() != 0) {
|
|
||||||
sept_secondary_enc = sept_secondary_00_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_00_enc_size;
|
|
||||||
} else {
|
|
||||||
sept_secondary_enc = sept_secondary_dev_00_enc;
|
|
||||||
sept_secondary_enc_size = sept_secondary_dev_00_enc_size;
|
|
||||||
}
|
|
||||||
tsec_fw_size = 0x3000;
|
|
||||||
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
|
|
||||||
tsec_fw_size = 0x2900;
|
|
||||||
} else {
|
|
||||||
tsec_fw_size = 0xF00;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Loaded firmware from eMMC...\n");
|
memcpy(tsec_fw, tsec_keygen_bin, tsec_fw_size);
|
||||||
|
|
||||||
/* Get the TSEC keys. */
|
if (tsec_fw_size == 0) {
|
||||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
|
fatal_error("[NXBOOT] Could not read the warmboot firmware from Package1!\n");
|
||||||
/* Detect whether we need to run sept-secondary in order to derive keys. */
|
}
|
||||||
if (!get_and_clear_has_run_sept()) {
|
|
||||||
reboot_to_sept(tsec_fw, tsec_fw_size, sept_secondary_enc, sept_secondary_enc_size);
|
|
||||||
} else {
|
|
||||||
if (mkey_detect_revision(fuse_get_hardware_state() != 0) != 0) {
|
|
||||||
fatal_error("[NXBOOT] Sept derived incorrect keys!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
get_and_clear_has_run_sept();
|
|
||||||
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
|
|
||||||
uint8_t tsec_keys[0x20] = {0};
|
|
||||||
|
|
||||||
/* Emulate the TSEC payload on 6.2.0+. */
|
/* Get the TSEC keys into the security engine. */
|
||||||
smmu_emulate_tsec((void *)tsec_keys, package1loader, package1loader_size, package1loader);
|
int tsec_res = tsec_run_fw(tsec_fw, tsec_fw_size);
|
||||||
|
if (tsec_res != 0) {
|
||||||
/* Copy back the keys. */
|
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
||||||
memcpy((void *)tsec_key, (void *)tsec_keys, 0x10);
|
fatal_error("[NXBOOT] Failed to run TSEC firmware %d %08x %08x!\n", tsec_res, tsec->TSEC_FALCON_MAILBOX0, tsec->TSEC_FALCON_MAILBOX1);
|
||||||
memcpy((void *)tsec_root_keys, (void *)tsec_keys + 0x10, 0x10);
|
|
||||||
} else {
|
|
||||||
/* Run the TSEC payload and get the key. */
|
|
||||||
if (tsec_get_key(tsec_key, 1, tsec_fw, tsec_fw_size) != 0) {
|
|
||||||
fatal_error("[NXBOOT] Failed to get TSEC key!\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,8 +878,8 @@ uint32_t nxboot_main(void) {
|
||||||
if (derive_nx_keydata_mariko(target_firmware) != 0) {
|
if (derive_nx_keydata_mariko(target_firmware) != 0) {
|
||||||
fatal_error("[NXBOOT] Mariko key derivation failed!\n");
|
fatal_error("[NXBOOT] Mariko key derivation failed!\n");
|
||||||
}
|
}
|
||||||
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { /* If on 7.0.0+, sept has already derived keys for us (Erista only). */
|
} else {
|
||||||
if (derive_nx_keydata_erista(target_firmware, g_keyblobs, available_revision, tsec_key, tsec_root_keys, &keygen_type) != 0) {
|
if (derive_nx_keydata_erista(target_firmware) != 0) {
|
||||||
fatal_error("[NXBOOT] Erista key derivation failed!\n");
|
fatal_error("[NXBOOT] Erista key derivation failed!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1230,9 +1139,6 @@ uint32_t nxboot_main(void) {
|
||||||
|
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
free(package1loader);
|
free(package1loader);
|
||||||
if (loader_ctx->tsecfw_path[0] != '\0') {
|
|
||||||
free(tsec_fw);
|
|
||||||
}
|
|
||||||
if (loader_ctx->warmboot_path[0] != '\0') {
|
if (loader_ctx->warmboot_path[0] != '\0') {
|
||||||
free(warmboot_fw);
|
free(warmboot_fw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,18 +24,10 @@
|
||||||
#include "mc.h"
|
#include "mc.h"
|
||||||
#include "nxboot.h"
|
#include "nxboot.h"
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
#include "smmu.h"
|
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "sysreg.h"
|
#include "sysreg.h"
|
||||||
|
|
||||||
/* Determine the current SoC for Mariko specific code. */
|
|
||||||
static bool is_soc_mariko() {
|
|
||||||
return (fuse_get_soc_type() == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nxboot_finish(uint32_t boot_memaddr) {
|
void nxboot_finish(uint32_t boot_memaddr) {
|
||||||
bool is_mariko = is_soc_mariko();
|
|
||||||
|
|
||||||
/* Boot up Exosphère. */
|
/* Boot up Exosphère. */
|
||||||
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0;
|
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0;
|
||||||
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X;
|
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X;
|
||||||
|
@ -43,26 +35,8 @@ void nxboot_finish(uint32_t boot_memaddr) {
|
||||||
/* Terminate the display. */
|
/* Terminate the display. */
|
||||||
display_end();
|
display_end();
|
||||||
|
|
||||||
if (is_mariko) {
|
/* Boot CPU0. */
|
||||||
/* Boot CPU0. */
|
cluster_boot_cpu0(boot_memaddr);
|
||||||
cluster_boot_cpu0(boot_memaddr);
|
|
||||||
} else {
|
|
||||||
/* Check if SMMU emulation has been used. */
|
|
||||||
uint32_t smmu_magic = *(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xFC);
|
|
||||||
if (smmu_magic == 0xDEADC0DE) {
|
|
||||||
/* Clear the magic. */
|
|
||||||
*(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xFC) = 0;
|
|
||||||
|
|
||||||
/* Pass the boot address to the already running payload. */
|
|
||||||
*(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xF0) = boot_memaddr;
|
|
||||||
|
|
||||||
/* Wait a while. */
|
|
||||||
mdelay(500);
|
|
||||||
} else {
|
|
||||||
/* Boot CPU0. */
|
|
||||||
cluster_boot_cpu0(boot_memaddr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for Exosphère to wake up. */
|
/* Wait for Exosphère to wake up. */
|
||||||
while (MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE == 0) {
|
while (MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE == 0) {
|
||||||
|
|
|
@ -58,16 +58,12 @@ bool package1_is_custom_public_key(const void *bct, bool mariko) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0) {
|
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, FILE *boot0) {
|
||||||
nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */
|
nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */
|
||||||
nv_bootloader_info *pk1l_info; /* TODO: check? */
|
nv_bootloader_info *pk1l_info; /* TODO: check? */
|
||||||
size_t fpos, pk1l_offset;
|
size_t fpos, pk1l_offset;
|
||||||
union {
|
|
||||||
nx_keyblob_t keyblob;
|
|
||||||
uint8_t sector[0x200];
|
|
||||||
} d;
|
|
||||||
|
|
||||||
if (package1loader == NULL || package1loader_size == NULL || keyblobs == NULL || revision == NULL || boot0 == NULL) {
|
if (package1loader == NULL || package1loader_size == NULL || boot0 == NULL) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +101,6 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*revision = pk1l_info->version - 1;
|
|
||||||
*package1loader_size = pk1l_info->length;
|
*package1loader_size = pk1l_info->length;
|
||||||
|
|
||||||
pk1l_offset = 0x4000 * pk1l_info->start_blk + 0x200 * pk1l_info->start_page;
|
pk1l_offset = 0x4000 * pk1l_info->start_blk + 0x200 * pk1l_info->start_page;
|
||||||
|
@ -128,14 +123,6 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the full keyblob area.*/
|
|
||||||
for (size_t i = 0; i < 32; i++) {
|
|
||||||
if (!fread(d.sector, 0x200, 1, boot0)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
keyblobs[i] = d.keyblob;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,24 +198,6 @@ bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t pac
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t package1_get_encrypted_package1(package1_header_t **package1, uint8_t *ctr, const void *package1loader, size_t package1loader_size) {
|
|
||||||
const uint8_t *crypt_hdr = (const uint8_t *)package1loader + 0x4000 - 0x20;
|
|
||||||
if (package1loader_size < 0x4000) {
|
|
||||||
return 0; /* Shouldn't happen, ever. */
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(ctr, crypt_hdr + 0x10, 0x10);
|
|
||||||
(*package1) = (package1_header_t *)(crypt_hdr + 0x20);
|
|
||||||
return *(uint32_t *)crypt_hdr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool package1_decrypt(package1_header_t *package1, size_t package1_size, const uint8_t *ctr) {
|
|
||||||
uint8_t __attribute__((aligned(16))) ctrbuf[16];
|
|
||||||
memcpy(ctrbuf, ctr, 16);
|
|
||||||
se_aes_ctr_crypt(0xB, package1, package1_size, package1, package1_size, ctrbuf, 16);
|
|
||||||
return memcmp(package1->magic, "PK11", 4) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *package1_get_warmboot_fw(const package1_header_t *package1) {
|
void *package1_get_warmboot_fw(const package1_header_t *package1) {
|
||||||
/*
|
/*
|
||||||
The layout of pk1 changes between versions.
|
The layout of pk1 changes between versions.
|
||||||
|
|
|
@ -59,14 +59,10 @@ typedef struct {
|
||||||
|
|
||||||
bool package1_is_custom_public_key(const void *bct, bool mariko);
|
bool package1_is_custom_public_key(const void *bct, bool mariko);
|
||||||
|
|
||||||
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0);
|
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, FILE *boot0);
|
||||||
int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, FILE *boot0);
|
int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, FILE *boot0);
|
||||||
|
|
||||||
bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t package1loader_size);
|
|
||||||
size_t package1_get_encrypted_package1(package1_header_t **package1, uint8_t *ctr, const void *package1loader, size_t package1loader_size);
|
|
||||||
|
|
||||||
/* Must be aligned to 16 bytes. */
|
/* Must be aligned to 16 bytes. */
|
||||||
bool package1_decrypt(package1_header_t *package1, size_t package1_size, const uint8_t *ctr);
|
|
||||||
void *package1_get_warmboot_fw(const package1_header_t *package1);
|
void *package1_get_warmboot_fw(const package1_header_t *package1);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,284 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "smmu.h"
|
|
||||||
#include "cluster.h"
|
|
||||||
#include "mc.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "tsec.h"
|
|
||||||
|
|
||||||
#define TSEC_KEYGEN_MAX_RETRIES 25
|
|
||||||
|
|
||||||
void *smmu_heap = (void *)SMMU_HEAP_BASE_ADDR;
|
|
||||||
|
|
||||||
static void safe_memcpy(void *dst, void *src, uint32_t sz) {
|
|
||||||
/* Aligned memcpy to read MMIO correctly. */
|
|
||||||
for (size_t i = 0; i < (sz/4); i++) {
|
|
||||||
((volatile uint32_t *)dst)[i] = ((volatile uint32_t *)src)[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smmu_flush_ppsb() {
|
|
||||||
/* Read-back barrier for interactions between the PPSB and the APB/AHB. */
|
|
||||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smmu_flush_regs() {
|
|
||||||
/* Flush all TLB and PTC entries. */
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTC_FLUSH) = 0;
|
|
||||||
smmu_flush_ppsb();
|
|
||||||
MAKE_MC_REG(MC_SMMU_TLB_FLUSH) = 0;
|
|
||||||
smmu_flush_ppsb();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *smmu_alloc_page(uint32_t page_count) {
|
|
||||||
void *cur_page = smmu_heap;
|
|
||||||
smmu_heap += (page_count * SMMU_PAGE_SIZE);
|
|
||||||
memset(cur_page, 0, (page_count * SMMU_PAGE_SIZE));
|
|
||||||
return cur_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t *smmu_alloc_pdir() {
|
|
||||||
uint32_t *pdir = (uint32_t *)smmu_alloc_page(1);
|
|
||||||
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++) {
|
|
||||||
pdir[pdn] = _PDE_VACANT(pdn);
|
|
||||||
}
|
|
||||||
return pdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t *smmu_locate_pte(uint32_t *pdir_page, uint32_t iova) {
|
|
||||||
uint32_t ptn = SMMU_ADDR_TO_PFN(iova);
|
|
||||||
uint32_t pdn = SMMU_ADDR_TO_PDN(iova);
|
|
||||||
uint32_t *pdir = pdir_page;
|
|
||||||
uint32_t *ptbl;
|
|
||||||
|
|
||||||
if (pdir[pdn] != _PDE_VACANT(pdn)) {
|
|
||||||
/* Mapped entry table already exists. */
|
|
||||||
ptbl = (uint32_t *)SMMU_EX_PTBL_PAGE(pdir[pdn]);
|
|
||||||
} else {
|
|
||||||
/* Allocate page table. */
|
|
||||||
ptbl = (uint32_t *)smmu_alloc_page(1);
|
|
||||||
uint32_t addr = SMMU_PDN_TO_ADDR(pdn);
|
|
||||||
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE) {
|
|
||||||
ptbl[pn] = _PTE_VACANT(addr);
|
|
||||||
}
|
|
||||||
pdir[pdn] = SMMU_MK_PDE((uint32_t)ptbl, _PDE_ATTR | _PDE_NEXT);
|
|
||||||
smmu_flush_regs();
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ptbl[ptn % SMMU_PTBL_COUNT];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smmu_map(uint32_t *pdir, uint32_t addr, uint32_t ptpage, int pcount, uint32_t pte_attr) {
|
|
||||||
for (int i = 0; i < pcount; i++) {
|
|
||||||
uint32_t *pte = smmu_locate_pte(pdir, addr);
|
|
||||||
*pte = SMMU_PFN_TO_PTE(SMMU_ADDR_TO_PFN(ptpage), pte_attr);
|
|
||||||
addr += SMMU_PAGE_SIZE;
|
|
||||||
ptpage += SMMU_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
smmu_flush_regs();
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t *smmu_setup_tsec_as(uint32_t asid) {
|
|
||||||
/* Allocate the page directory. */
|
|
||||||
uint32_t *pdir_page = smmu_alloc_pdir();
|
|
||||||
|
|
||||||
/* Set the PTB ASID and point it to the PDIR. */
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTB_ASID) = asid;
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((uint32_t)pdir_page, _PDIR_ATTR);
|
|
||||||
smmu_flush_ppsb();
|
|
||||||
|
|
||||||
/* Assign the ASID to TSEC. */
|
|
||||||
MAKE_MC_REG(MC_SMMU_TSEC_ASID) = SMMU_ASID_ENABLE((asid << 24) | (asid << 16) | (asid << 8) | asid);
|
|
||||||
smmu_flush_ppsb();
|
|
||||||
|
|
||||||
return pdir_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smmu_clear_tsec_as(uint32_t asid) {
|
|
||||||
/* Set the PTB ASID and clear it's data. */
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTB_ASID) = asid;
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0;
|
|
||||||
|
|
||||||
/* Clear the ASID from TSEC. */
|
|
||||||
MAKE_MC_REG(MC_SMMU_TSEC_ASID) = SMMU_ASID_DISABLE;
|
|
||||||
smmu_flush_ppsb();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smmu_enable() {
|
|
||||||
/* AARCH64 payload for enabling the SMMU. */
|
|
||||||
/* Write 1 to MC_SMMU_CONFIG, read back and write the result to 0x40003F80. */
|
|
||||||
/* This will leave the CPU waiting until 0x40003FF0 is set to Exosphère's address. */
|
|
||||||
static const uint32_t aarch64_payload[20] = {
|
|
||||||
0x52800020, 0x58000162, 0x58000183, 0xB9000040,
|
|
||||||
0xB9400041, 0xB9000061, 0x58000142, 0xF9400040,
|
|
||||||
0xF100001F, 0x54FFFFA0, 0xD61F0000, 0x00000000,
|
|
||||||
0x70019010, 0x00000000, 0x40003F80, 0x00000000,
|
|
||||||
0x40003FF0, 0x00000000, 0x00000000, 0x00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Reset Translation Enable Registers. */
|
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_0) = 0xFFFFFFFF;
|
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_1) = 0xFFFFFFFF;
|
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_2) = 0xFFFFFFFF;
|
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_3) = 0xFFFFFFFF;
|
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_4) = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
/* Setup initial TLB and PTC configuration. */
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0;
|
|
||||||
MAKE_MC_REG(MC_SMMU_TLB_CONFIG) = 0x30000030;
|
|
||||||
MAKE_MC_REG(MC_SMMU_PTC_CONFIG) = 0x2800003F;
|
|
||||||
smmu_flush_regs();
|
|
||||||
|
|
||||||
/* Power on the CCPLEX to enable the SMMU globally (requires a secure write). */
|
|
||||||
volatile uint32_t *aarch64_payload_res = (volatile uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0x80);
|
|
||||||
memset((void *)SMMU_AARCH64_PAYLOAD_ADDR, 0, 0x100);
|
|
||||||
memcpy((void *)SMMU_AARCH64_PAYLOAD_ADDR, aarch64_payload, 20 * 4);
|
|
||||||
cluster_boot_cpu0(SMMU_AARCH64_PAYLOAD_ADDR);
|
|
||||||
mdelay(500);
|
|
||||||
if (*aarch64_payload_res != 1) {
|
|
||||||
fatal_error("[SMMU]: Failed to enable SMMU!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write magic for nxboot. */
|
|
||||||
*(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xFC) = 0xDEADC0DE;
|
|
||||||
|
|
||||||
/* Flush TLB and PTC entries. */
|
|
||||||
smmu_flush_regs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_size, void *package1_dec) {
|
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
|
||||||
|
|
||||||
/* Backup IRAM to DRAM. */
|
|
||||||
memcpy((void *)SMMU_IRAM_BACKUP_ADDR, (void *)0x40010000, 0x30000);
|
|
||||||
|
|
||||||
/* Copy package1 into IRAM. */
|
|
||||||
memcpy((void *)0x40010000, package1, package1_size);
|
|
||||||
|
|
||||||
/* Setup TSEC's address space. */
|
|
||||||
uint32_t *pdir = smmu_setup_tsec_as(1);
|
|
||||||
|
|
||||||
/* Allocate pages for MMIO and IRAM. */
|
|
||||||
volatile uint32_t *car_page = smmu_alloc_page(1);
|
|
||||||
volatile uint32_t *fuse_page = smmu_alloc_page(1);
|
|
||||||
volatile uint32_t *pmc_page = smmu_alloc_page(1);
|
|
||||||
volatile uint32_t *flow_page = smmu_alloc_page(1);
|
|
||||||
volatile uint32_t *se_page = smmu_alloc_page(1);
|
|
||||||
volatile uint32_t *mc_page = smmu_alloc_page(1);
|
|
||||||
volatile uint32_t *iram_pages = smmu_alloc_page(48);
|
|
||||||
volatile uint32_t *expv_page = smmu_alloc_page(1);
|
|
||||||
|
|
||||||
/* Map all necessary pages. */
|
|
||||||
smmu_map(pdir, 0x60006000, (uint32_t)car_page, 1, _READABLE | _WRITABLE | _NONSECURE);
|
|
||||||
smmu_map(pdir, 0x7000F000, (uint32_t)fuse_page, 1, _READABLE | _NONSECURE);
|
|
||||||
smmu_map(pdir, 0x7000E000, (uint32_t)pmc_page, 1, _READABLE | _NONSECURE);
|
|
||||||
smmu_map(pdir, 0x60007000, (uint32_t)flow_page, 1, _WRITABLE | _NONSECURE);
|
|
||||||
smmu_map(pdir, 0x70012000, (uint32_t)se_page, 1, _READABLE | _WRITABLE | _NONSECURE);
|
|
||||||
smmu_map(pdir, 0x70019000, (uint32_t)mc_page, 1, _READABLE | _NONSECURE);
|
|
||||||
smmu_map(pdir, 0x40010000, (uint32_t)iram_pages, 48, _READABLE | _WRITABLE | _NONSECURE);
|
|
||||||
smmu_map(pdir, 0x6000F000, (uint32_t)expv_page, 1, _READABLE | _WRITABLE | _NONSECURE);
|
|
||||||
|
|
||||||
/* Enable the SMMU. */
|
|
||||||
smmu_enable();
|
|
||||||
|
|
||||||
/* Loop retrying TSEC firmware execution, in case we lose the SE keydata race. */
|
|
||||||
uint32_t key_buf[0x20/4] = {0};
|
|
||||||
unsigned int retries = 0;
|
|
||||||
while (true) {
|
|
||||||
if (retries++ > TSEC_KEYGEN_MAX_RETRIES) {
|
|
||||||
fatal_error("[SMMU] TSEC key generation race was lost too many times!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load the TSEC firmware from IRAM. */
|
|
||||||
if (tsec_load_fw((void *)(0x40010000 + 0xE00), 0x2900) < 0) {
|
|
||||||
fatal_error("[SMMU]: Failed to load TSEC firmware!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable the aperture since it has precedence over the SMMU. */
|
|
||||||
mc_disable_ahb_redirect();
|
|
||||||
|
|
||||||
/* Clear all pages. */
|
|
||||||
memset((void *)car_page, 0, SMMU_PAGE_SIZE);
|
|
||||||
memset((void *)fuse_page, 0, SMMU_PAGE_SIZE);
|
|
||||||
memset((void *)pmc_page, 0, SMMU_PAGE_SIZE);
|
|
||||||
memset((void *)flow_page, 0, SMMU_PAGE_SIZE);
|
|
||||||
memset((void *)se_page, 0, SMMU_PAGE_SIZE);
|
|
||||||
memset((void *)mc_page, 0, SMMU_PAGE_SIZE);
|
|
||||||
memset((void *)iram_pages, 0, 48 * SMMU_PAGE_SIZE);
|
|
||||||
memset((void *)expv_page, 0, SMMU_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Copy CAR, MC and FUSE. */
|
|
||||||
safe_memcpy((void *)car_page, (void *)0x60006000, 0x1000);
|
|
||||||
safe_memcpy((void *)mc_page, (void *)0x70019000, 0x1000);
|
|
||||||
safe_memcpy((void *)&fuse_page[0x800/4], (void *)0x7000F800, 0x400);
|
|
||||||
|
|
||||||
/* Copy IRAM. */
|
|
||||||
memcpy((void *)iram_pages, (void *)0x40010000, 0x30000);
|
|
||||||
|
|
||||||
/* TSEC wants CLK_RST_CONTROLLER_CLK_SOURCE_TSEC_0 to be equal to 2. */
|
|
||||||
car_page[0x1F4/4] = 2;
|
|
||||||
|
|
||||||
/* TSEC wants the aperture fully open. */
|
|
||||||
mc_page[0x65C/4] = 0;
|
|
||||||
mc_page[0x660/4] = 0x80000000;
|
|
||||||
|
|
||||||
/* Run the TSEC firmware. */
|
|
||||||
tsec_run_fw();
|
|
||||||
|
|
||||||
/* Extract the keys from SE. */
|
|
||||||
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->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;
|
|
||||||
key_buf[buf_counter] = new_key_data;
|
|
||||||
buf_counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable back the aperture. */
|
|
||||||
mc_enable_ahb_redirect();
|
|
||||||
|
|
||||||
if (buf_counter == 8) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the TSEC firmware wrote over the exception vectors. */
|
|
||||||
volatile uint32_t *tsec_done_check = (volatile uint32_t *)((void *)expv_page + 0x200);
|
|
||||||
if (!(*tsec_done_check)) {
|
|
||||||
fatal_error("[SMMU]: Failed to emulate the TSEC firmware!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy back the extracted keys. */
|
|
||||||
memcpy((void *)tsec_keys, (void *)key_buf, 0x20);
|
|
||||||
|
|
||||||
/* Manually disable TSEC clocks. */
|
|
||||||
tsec_disable_clkrst();
|
|
||||||
|
|
||||||
/* Clear TSEC's address space. */
|
|
||||||
smmu_clear_tsec_as(1);
|
|
||||||
|
|
||||||
/* Return the decrypted package1 from emulated IRAM. */
|
|
||||||
memcpy(package1_dec, (void *)iram_pages, package1_size);
|
|
||||||
|
|
||||||
/* Restore IRAM from DRAM. */
|
|
||||||
memcpy((void *)0x40010000, (void *)SMMU_IRAM_BACKUP_ADDR, 0x30000);
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_SMMU_H_
|
|
||||||
#define FUSEE_SMMU_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define SMMU_HEAP_BASE_ADDR 0x81000000
|
|
||||||
#define SMMU_IRAM_BACKUP_ADDR 0x82000000
|
|
||||||
#define SMMU_AARCH64_PAYLOAD_ADDR 0x40003F00
|
|
||||||
|
|
||||||
#define SMMU_PAGE_SHIFT 12
|
|
||||||
#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
|
|
||||||
#define SMMU_PDIR_COUNT 1024
|
|
||||||
#define SMMU_PDIR_SIZE (sizeof(uint32_t) * SMMU_PDIR_COUNT)
|
|
||||||
#define SMMU_PTBL_COUNT 1024
|
|
||||||
#define SMMU_PTBL_SIZE (sizeof(uint32_t) * SMMU_PTBL_COUNT)
|
|
||||||
#define SMMU_PDIR_SHIFT 12
|
|
||||||
#define SMMU_PDE_SHIFT 12
|
|
||||||
#define SMMU_PTE_SHIFT 12
|
|
||||||
#define SMMU_PFN_MASK 0x000fffff
|
|
||||||
#define SMMU_PDE_NEXT_SHIFT 28
|
|
||||||
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
|
|
||||||
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
|
|
||||||
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << 22)
|
|
||||||
#define _READABLE (1 << 31)
|
|
||||||
#define _WRITABLE (1 << 30)
|
|
||||||
#define _NONSECURE (1 << 29)
|
|
||||||
#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
|
|
||||||
#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PDE_ATTR_N (_PDE_ATTR | _PDE_NEXT)
|
|
||||||
#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
|
|
||||||
#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
|
||||||
#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
|
|
||||||
#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
|
|
||||||
#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
|
|
||||||
#define SMMU_EX_PTBL_PAGE(pde) (((pde) & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT)
|
|
||||||
#define SMMU_PFN_TO_PTE(pfn, attr) ((pfn) | (attr))
|
|
||||||
#define SMMU_ASID_ENABLE(asid) ((asid) | (1 << 31))
|
|
||||||
#define SMMU_ASID_DISABLE 0
|
|
||||||
#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0))
|
|
||||||
|
|
||||||
void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_size, void *package1_dec);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -108,6 +108,7 @@ _metadata:
|
||||||
#define CONTENT_TYPE_KLD 9
|
#define CONTENT_TYPE_KLD 9
|
||||||
#define CONTENT_TYPE_KRN 10
|
#define CONTENT_TYPE_KRN 10
|
||||||
#define CONTENT_TYPE_EXF 11
|
#define CONTENT_TYPE_EXF 11
|
||||||
|
#define CONTENT_TYPE_TKG 12
|
||||||
|
|
||||||
#define CONTENT_FLAG_NONE (0 << 0)
|
#define CONTENT_FLAG_NONE (0 << 0)
|
||||||
|
|
||||||
|
@ -213,39 +214,6 @@ _content_headers:
|
||||||
.asciz "rebootstub"
|
.asciz "rebootstub"
|
||||||
.align 5
|
.align 5
|
||||||
|
|
||||||
/* sept_primary content header */
|
|
||||||
.word __sept_primary_bin_start__
|
|
||||||
.word __sept_primary_bin_size__
|
|
||||||
.byte CONTENT_TYPE_SP1
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.word 0xCCCCCCCC
|
|
||||||
.asciz "sept_primary"
|
|
||||||
.align 5
|
|
||||||
|
|
||||||
/* sept_secondary 00 content header */
|
|
||||||
.word __sept_secondary_00_enc_start__
|
|
||||||
.word __sept_secondary_00_enc_size__
|
|
||||||
.byte CONTENT_TYPE_SP2
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.word 0xCCCCCCCC
|
|
||||||
.asciz "septsecondary00"
|
|
||||||
.align 5
|
|
||||||
|
|
||||||
/* sept_secondary 01 content header */
|
|
||||||
.word __sept_secondary_01_enc_start__
|
|
||||||
.word __sept_secondary_01_enc_size__
|
|
||||||
.byte CONTENT_TYPE_SP2
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.byte CONTENT_FLAG_NONE
|
|
||||||
.word 0xCCCCCCCC
|
|
||||||
.asciz "septsecondary01"
|
|
||||||
.align 5
|
|
||||||
|
|
||||||
/* sm content header */
|
/* sm content header */
|
||||||
.word __sm_kip_start__
|
.word __sm_kip_start__
|
||||||
.word __sm_kip_size__
|
.word __sm_kip_size__
|
||||||
|
@ -301,6 +269,17 @@ _content_headers:
|
||||||
.asciz "exosphere_fatal"
|
.asciz "exosphere_fatal"
|
||||||
.align 5
|
.align 5
|
||||||
|
|
||||||
|
/* tsec_keygen content header */
|
||||||
|
.word __tsec_keygen_bin_start__
|
||||||
|
.word __tsec_keygen_bin_size__
|
||||||
|
.byte CONTENT_TYPE_TKG
|
||||||
|
.byte CONTENT_FLAG_NONE
|
||||||
|
.byte CONTENT_FLAG_NONE
|
||||||
|
.byte CONTENT_FLAG_NONE
|
||||||
|
.word 0xCCCCCCCC
|
||||||
|
.asciz "tsec_keygen"
|
||||||
|
.align 5
|
||||||
|
|
||||||
_content_headers_end:
|
_content_headers_end:
|
||||||
|
|
||||||
/* No need to include this in normal programs: */
|
/* No need to include this in normal programs: */
|
||||||
|
|
|
@ -14,15 +14,16 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tsec.h"
|
#include "tsec.h"
|
||||||
#include "di.h"
|
#include "di.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
|
#include "mc.h"
|
||||||
|
|
||||||
static int tsec_dma_wait_idle()
|
static int tsec_dma_wait_idle()
|
||||||
{
|
{
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
||||||
uint32_t timeout = (get_time_ms() + 10000);
|
uint32_t timeout = (get_time_ms() + 10000);
|
||||||
|
|
||||||
while (!(tsec->TSEC_FALCON_DMATRFCMD & 2))
|
while (!(tsec->TSEC_FALCON_DMATRFCMD & 2))
|
||||||
|
@ -30,13 +31,13 @@ static int tsec_dma_wait_idle()
|
||||||
if (get_time_ms() > timeout)
|
if (get_time_ms() > timeout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t phys_offset)
|
static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t phys_offset)
|
||||||
{
|
{
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
||||||
uint32_t cmd = 0;
|
uint32_t cmd = 0;
|
||||||
|
|
||||||
if (!is_imem)
|
if (!is_imem)
|
||||||
|
@ -52,16 +53,16 @@ static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t ph
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsec_kfuse_wait_ready()
|
static int tsec_kfuse_wait_ready()
|
||||||
{
|
{
|
||||||
uint32_t timeout = (get_time_ms() + 10000);
|
uint32_t timeout = (get_time_ms() + 10000);
|
||||||
|
|
||||||
/* Wait for STATE_DONE. */
|
/* Wait for STATE_DONE. */
|
||||||
while (!(KFUSE_STATE & 0x10000))
|
while (!(KFUSE_STATE & 0x10000))
|
||||||
{
|
{
|
||||||
if (get_time_ms() > timeout)
|
if (get_time_ms() > timeout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for STATE_CRCPASS. */
|
/* Check for STATE_CRCPASS. */
|
||||||
if (!(KFUSE_STATE & 0x20000))
|
if (!(KFUSE_STATE & 0x20000))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -91,19 +92,19 @@ void tsec_disable_clkrst()
|
||||||
clkrst_disable(CARDEVICE_HOST1X);
|
clkrst_disable(CARDEVICE_HOST1X);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw_size)
|
static int tsec_run_fw_impl(const void *tsec_fw, size_t tsec_fw_size)
|
||||||
{
|
{
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
||||||
|
|
||||||
/* Enable clocks. */
|
/* Enable clocks. */
|
||||||
tsec_enable_clkrst();
|
tsec_enable_clkrst();
|
||||||
|
|
||||||
/* Make sure KFUSE is ready. */
|
/* Make sure KFUSE is ready. */
|
||||||
if (!tsec_kfuse_wait_ready())
|
if (!tsec_kfuse_wait_ready())
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,16 +113,16 @@ int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw
|
||||||
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
|
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
|
||||||
tsec->TSEC_FALCON_IRQDEST = 0xFFF0;
|
tsec->TSEC_FALCON_IRQDEST = 0xFFF0;
|
||||||
tsec->TSEC_FALCON_ITFEN = 3;
|
tsec->TSEC_FALCON_ITFEN = 3;
|
||||||
|
|
||||||
/* Make sure the DMA block is idle. */
|
/* Make sure the DMA block is idle. */
|
||||||
if (!tsec_dma_wait_idle())
|
if (!tsec_dma_wait_idle())
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load firmware. */
|
/* Load firmware. */
|
||||||
tsec->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)
|
for (uint32_t addr = 0; addr < tsec_fw_size; addr += 0x100)
|
||||||
|
@ -130,128 +131,71 @@ int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write magic value to HOST1X scratch register. */
|
/* Write magic value to HOST1X scratch register. */
|
||||||
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
|
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
|
||||||
|
|
||||||
/* Execute firmware. */
|
/* Execute firmware. */
|
||||||
tsec->TSEC_FALCON_MAILBOX1 = 0;
|
tsec->TSEC_FALCON_MAILBOX1 = 0;
|
||||||
tsec->TSEC_FALCON_MAILBOX0 = rev;
|
tsec->TSEC_FALCON_MAILBOX0 = 1;
|
||||||
tsec->TSEC_FALCON_BOOTVEC = 0;
|
tsec->TSEC_FALCON_BOOTVEC = 0;
|
||||||
tsec->TSEC_FALCON_CPUCTL = 2;
|
tsec->TSEC_FALCON_CPUCTL = 2;
|
||||||
|
|
||||||
/* Make sure the DMA block is idle. */
|
/* Make sure the DMA block is idle. */
|
||||||
if (!tsec_dma_wait_idle())
|
if (!tsec_dma_wait_idle())
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t timeout = (get_time_ms() + 2000);
|
uint32_t timeout = (get_time_ms() + 4000);
|
||||||
while (!tsec->TSEC_FALCON_MAILBOX1)
|
while (!(tsec->TSEC_FALCON_CPUCTL & 0x10)) {
|
||||||
{
|
if (get_time_ms() > timeout) {
|
||||||
if (get_time_ms() > timeout)
|
|
||||||
{
|
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsec->TSEC_FALCON_MAILBOX1 != 0xB0B0B0B0)
|
if (tsec->TSEC_FALCON_MAILBOX1 != 0xB0B0B0B0)
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear magic value from HOST1X scratch register. */
|
/* Clear magic value from HOST1X scratch register. */
|
||||||
MAKE_HOST1X_REG(0x3300) = 0;
|
MAKE_HOST1X_REG(0x3300) = 0;
|
||||||
|
|
||||||
/* Fetch result from SOR1. */
|
|
||||||
uint32_t tmp[0x4] = {0};
|
|
||||||
tmp[0] = SOR1_DP_HDCP_BKSV_LSB;
|
|
||||||
tmp[1] = SOR1_TMDS_HDCP_BKSV_LSB;
|
|
||||||
tmp[2] = SOR1_TMDS_HDCP_CN_MSB;
|
|
||||||
tmp[3] = SOR1_TMDS_HDCP_CN_LSB;
|
|
||||||
|
|
||||||
/* Clear SOR1 registers. */
|
|
||||||
SOR1_DP_HDCP_BKSV_LSB = 0;
|
|
||||||
SOR1_TMDS_HDCP_BKSV_LSB = 0;
|
|
||||||
SOR1_TMDS_HDCP_CN_MSB = 0;
|
|
||||||
SOR1_TMDS_HDCP_CN_LSB = 0;
|
|
||||||
|
|
||||||
/* Copy back the key. */
|
|
||||||
memcpy(key, &tmp, 0x10);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsec_load_fw(const void *tsec_fw, size_t tsec_fw_size)
|
int tsec_run_fw(const void *tsec_fw, size_t tsec_fw_size) {
|
||||||
{
|
/* Ensure that the ahb redirect is enabled. */
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
mc_enable_ahb_redirect();
|
||||||
|
|
||||||
/* Enable clocks. */
|
/* Get bom/tom */
|
||||||
tsec_enable_clkrst();
|
uint32_t bom = MAKE_MC_REG(MC_IRAM_BOM);
|
||||||
|
uint32_t tom = MAKE_MC_REG(MC_IRAM_TOM);
|
||||||
/* Make sure KFUSE is ready. */
|
|
||||||
if (!tsec_kfuse_wait_ready())
|
|
||||||
{
|
|
||||||
/* Disable clocks. */
|
|
||||||
tsec_disable_clkrst();
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure Falcon. */
|
/* Override the ahb redirect extents. */
|
||||||
tsec->TSEC_FALCON_DMACTL = 0;
|
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
|
||||||
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
|
MAKE_MC_REG(MC_IRAM_TOM) = 0x80000000;
|
||||||
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->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))
|
|
||||||
{
|
|
||||||
/* Disable clocks. */
|
|
||||||
tsec_disable_clkrst();
|
|
||||||
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
/* Run the fw. */
|
||||||
}
|
int res = tsec_run_fw_impl(tsec_fw, tsec_fw_size);
|
||||||
|
|
||||||
void tsec_run_fw()
|
/* Reset the ahb redirect extents. */
|
||||||
{
|
MAKE_MC_REG(MC_IRAM_BOM) = bom;
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
MAKE_MC_REG(MC_IRAM_TOM) = tom;
|
||||||
|
|
||||||
/* Write magic value to HOST1X scratch register. */
|
return res;
|
||||||
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
|
|
||||||
|
|
||||||
/* Execute firmware. */
|
|
||||||
tsec->TSEC_FALCON_MAILBOX1 = 0;
|
|
||||||
tsec->TSEC_FALCON_MAILBOX0 = 1;
|
|
||||||
tsec->TSEC_FALCON_BOOTVEC = 0;
|
|
||||||
tsec->TSEC_FALCON_CPUCTL = 2;
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_TSEC_H_
|
#ifndef FUSEE_TSEC_H_
|
||||||
#define FUSEE_TSEC_H_
|
#define FUSEE_TSEC_H_
|
||||||
|
|
||||||
|
@ -306,8 +306,7 @@ static inline volatile tegra_tsec_t *tsec_get_regs(void)
|
||||||
|
|
||||||
void tsec_enable_clkrst();
|
void tsec_enable_clkrst();
|
||||||
void tsec_disable_clkrst();
|
void tsec_disable_clkrst();
|
||||||
int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw_size);
|
|
||||||
int tsec_load_fw(const void *tsec_fw, size_t tsec_fw_size);
|
int tsec_run_fw(const void *tsec_fw, size_t tsec_fw_size);
|
||||||
void tsec_run_fw();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -34,7 +34,6 @@
|
||||||
#define u8 uint8_t
|
#define u8 uint8_t
|
||||||
#define u32 uint32_t
|
#define u32 uint32_t
|
||||||
#include "fusee_primary_bin.h"
|
#include "fusee_primary_bin.h"
|
||||||
#include "sept_primary_bin.h"
|
|
||||||
#include "rebootstub_bin.h"
|
#include "rebootstub_bin.h"
|
||||||
#undef u8
|
#undef u8
|
||||||
#undef u32
|
#undef u32
|
||||||
|
@ -131,42 +130,8 @@ __attribute__((noreturn)) void reboot_to_fusee_primary(void) {
|
||||||
reboot_to_payload();
|
reboot_to_payload();
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn)) void reboot_to_sept(const void *tsec_fw, size_t tsec_fw_length, const void *stage2, size_t stage2_size) {
|
|
||||||
if (is_soc_mariko()) {
|
|
||||||
/* Reboot to sept isn't possible on mariko, so just do normal reboot. */
|
|
||||||
shutdown_system(true);
|
|
||||||
} else {
|
|
||||||
/* Copy tsec firmware. */
|
|
||||||
for (size_t i = 0; i < tsec_fw_length; i += sizeof(uint32_t)) {
|
|
||||||
write32le((void *)0x40010F00, i, read32le(tsec_fw, i));
|
|
||||||
}
|
|
||||||
MAKE_REG32(0x40010EFC) = tsec_fw_length;
|
|
||||||
|
|
||||||
/* Copy stage 2. */
|
|
||||||
for (size_t i = 0; i < stage2_size; i += sizeof(uint32_t)) {
|
|
||||||
write32le((void *)0x40016FE0, i, read32le(stage2, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy sept into IRAM low. */
|
|
||||||
for (size_t i = 0; i < sept_primary_bin_size; i += sizeof(uint32_t)) {
|
|
||||||
write32le((void *)0x4003F000, i, read32le(sept_primary_bin, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Patch SDRAM init to perform an SVC immediately after second write */
|
|
||||||
APBDEV_PMC_SCRATCH45_0 = 0x2E38DFFF;
|
|
||||||
APBDEV_PMC_SCRATCH46_0 = 0x6001DC28;
|
|
||||||
/* Set SVC handler to jump to reboot stub in IRAM. */
|
|
||||||
APBDEV_PMC_SCRATCH33_0 = 0x4003F000;
|
|
||||||
APBDEV_PMC_SCRATCH40_0 = 0x6000F208;
|
|
||||||
|
|
||||||
/* Trigger warm reboot. */
|
|
||||||
pmc_reboot(1 << 0);
|
|
||||||
while (true) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void reboot_to_iram_payload(void *payload, size_t payload_size) {
|
__attribute__((noreturn)) void reboot_to_iram_payload(void *payload, size_t payload_size) {
|
||||||
/* Copy sept into IRAM low. */
|
/* Copy payload into IRAM low. */
|
||||||
for (size_t i = 0; i < payload_size; i += sizeof(uint32_t)) {
|
for (size_t i = 0; i < payload_size; i += sizeof(uint32_t)) {
|
||||||
write32le((void *)0x40010000, i, read32le(payload, i));
|
write32le((void *)0x40010000, i, read32le(payload, i));
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_UTILS_H
|
#ifndef FUSEE_UTILS_H
|
||||||
#define FUSEE_UTILS_H
|
#define FUSEE_UTILS_H
|
||||||
|
|
||||||
|
@ -121,7 +121,6 @@ static inline bool check_32bit_address_range_in_program(uintptr_t addr, size_t s
|
||||||
__attribute__((noreturn)) void watchdog_reboot(void);
|
__attribute__((noreturn)) void watchdog_reboot(void);
|
||||||
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
|
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
|
||||||
__attribute__((noreturn)) void reboot_to_fusee_primary(void);
|
__attribute__((noreturn)) void reboot_to_fusee_primary(void);
|
||||||
__attribute__((noreturn)) void reboot_to_sept(const void *tsec_fw, size_t tsec_fw_length, const void *stage2, size_t stage2_size);
|
|
||||||
__attribute__((noreturn)) void reboot_to_iram_payload(void *payload, size_t payload_size);
|
__attribute__((noreturn)) void reboot_to_iram_payload(void *payload, size_t payload_size);
|
||||||
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
|
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
|
||||||
void wait_for_button(void);
|
void wait_for_button(void);
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
SUBFOLDERS := sept-primary sept-secondary
|
|
||||||
|
|
||||||
TOPTARGETS := all clean
|
|
||||||
|
|
||||||
$(TOPTARGETS): $(SUBFOLDERS)
|
|
||||||
|
|
||||||
$(SUBFOLDERS):
|
|
||||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
|
||||||
|
|
||||||
.PHONY: $(TOPTARGETS) $(SUBFOLDERS)
|
|
|
@ -1,168 +0,0 @@
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
.SUFFIXES:
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEVKITARM)),)
|
|
||||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
|
||||||
endif
|
|
||||||
|
|
||||||
TOPDIR ?= $(CURDIR)
|
|
||||||
|
|
||||||
AMS := $(TOPDIR)/../../
|
|
||||||
include $(DEVKITARM)/base_rules
|
|
||||||
|
|
||||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
|
||||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
|
||||||
AMSREV := $(AMSREV)-dirty
|
|
||||||
endif
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# TARGET is the name of the output
|
|
||||||
# BUILD is the directory where object files & intermediate files will be placed
|
|
||||||
# SOURCES is a list of directories containing source code
|
|
||||||
# DATA is a list of directories containing data files
|
|
||||||
# INCLUDES is a list of directories containing header files
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
TARGET := $(notdir $(CURDIR))
|
|
||||||
BUILD := build
|
|
||||||
SOURCES := src
|
|
||||||
DATA := data
|
|
||||||
INCLUDES := include ../../libraries/libvapours/include
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# options for code generation
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
|
||||||
DEFINES := -D__BPMP__ -DSEPT_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
|
||||||
|
|
||||||
CFLAGS := \
|
|
||||||
-g \
|
|
||||||
-gdwarf-4 \
|
|
||||||
-Os \
|
|
||||||
-fomit-frame-pointer \
|
|
||||||
-ffunction-sections \
|
|
||||||
-fdata-sections \
|
|
||||||
-std=gnu11 \
|
|
||||||
-Werror \
|
|
||||||
-Wall \
|
|
||||||
-Wno-array-bounds \
|
|
||||||
-Wno-stringop-overflow \
|
|
||||||
-Wno-stringop-overread \
|
|
||||||
-fstrict-volatile-bitfields \
|
|
||||||
$(ARCH) $(DEFINES)
|
|
||||||
|
|
||||||
CFLAGS += $(INCLUDE)
|
|
||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
|
||||||
|
|
||||||
ASFLAGS := -g -gdwarf-4 $(ARCH)
|
|
||||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
|
|
||||||
|
|
||||||
LIBS :=
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# list of directories containing libraries, this must be the top level containing
|
|
||||||
# include and lib
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
LIBDIRS :=
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# no real need to edit anything past this point unless you need to add additional
|
|
||||||
# rules for different file extensions
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
|
||||||
export TOPDIR := $(CURDIR)
|
|
||||||
|
|
||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
|
||||||
|
|
||||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
|
||||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# use CXX for linking C++ projects, CC for standard C
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ifeq ($(strip $(CPPFILES)),)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export LD := $(CC)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
else
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export LD := $(CXX)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
|
||||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
|
||||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
|
||||||
|
|
||||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|
||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
|
||||||
-I$(CURDIR)/$(BUILD)
|
|
||||||
|
|
||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
|
||||||
|
|
||||||
.PHONY: $(BUILD) clean all
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
all: $(BUILD)
|
|
||||||
|
|
||||||
$(BUILD):
|
|
||||||
@[ -d $@ ] || mkdir -p $@
|
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
clean:
|
|
||||||
@echo clean ...
|
|
||||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
else
|
|
||||||
.PHONY: all
|
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# main targets
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
all : $(OUTPUT).bin
|
|
||||||
|
|
||||||
$(OUTPUT).bin : $(OUTPUT).elf
|
|
||||||
$(OBJCOPY) -S -O binary $< $@
|
|
||||||
@echo built ... $(notdir $@)
|
|
||||||
|
|
||||||
$(OUTPUT).elf : $(OFILES)
|
|
||||||
|
|
||||||
%.elf: $(OFILES)
|
|
||||||
@echo linking $(notdir $@)
|
|
||||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
|
||||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
|
||||||
|
|
||||||
$(OFILES_SRC) : $(HFILES_BIN)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# you need a rule like this for each extension you use as binary data
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.bin.o %_bin.h: %.bin
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(bin2o)
|
|
||||||
|
|
||||||
-include $(DEPENDS)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
|
@ -1,168 +0,0 @@
|
||||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
|
||||||
OUTPUT_ARCH(arm)
|
|
||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
PHDRS
|
|
||||||
{
|
|
||||||
crt0 PT_LOAD;
|
|
||||||
main PT_LOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mostly copied from https://github.com/devkitPro/buildscripts/blob/master/dkarm-eabi/crtls/3dsx.ld */
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
NULL : ORIGIN = 0x00000000, LENGTH = 0x1000
|
|
||||||
main : ORIGIN = 0x40010000, LENGTH = 0x1000
|
|
||||||
high_iram : ORIGIN = 0x4003F000, LENGTH = 0x1000
|
|
||||||
low_iram : ORIGIN = 0x40003000, LENGTH = 0x8000
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
PROVIDE(__crt0_start__ = 0x4003F000);
|
|
||||||
PROVIDE(__main_start__ = 0x40010000);
|
|
||||||
PROVIDE(__stack_top__ = 0x40010000);
|
|
||||||
PROVIDE(__stack_bottom__ = 0x4000C000);
|
|
||||||
PROVIDE(__heap_start__ = 0);
|
|
||||||
PROVIDE(__heap_end__ = 0);
|
|
||||||
|
|
||||||
. = __crt0_start__;
|
|
||||||
|
|
||||||
.crt0 :
|
|
||||||
{
|
|
||||||
KEEP( *(.text.start) )
|
|
||||||
KEEP( *(.text.ipatch_word) )
|
|
||||||
KEEP( *(.init) )
|
|
||||||
. = ALIGN(32);
|
|
||||||
} >high_iram AT>high_iram :crt0
|
|
||||||
|
|
||||||
__main_phys_start__ = ABSOLUTE(.) ;
|
|
||||||
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
/* .text */
|
|
||||||
KEEP( *(.text.jump_to_main) )
|
|
||||||
*(.text)
|
|
||||||
*(.text.*)
|
|
||||||
*(.glue_7)
|
|
||||||
*(.glue_7t)
|
|
||||||
*(.stub)
|
|
||||||
*(.gnu.warning)
|
|
||||||
*(.gnu.linkonce.t*)
|
|
||||||
|
|
||||||
/* .fini */
|
|
||||||
KEEP( *(.fini) )
|
|
||||||
. = ALIGN(8);
|
|
||||||
} >main AT>high_iram :main
|
|
||||||
|
|
||||||
.rodata :
|
|
||||||
{
|
|
||||||
*(.rodata)
|
|
||||||
*(.roda)
|
|
||||||
*(.rodata.*)
|
|
||||||
*all.rodata*(*)
|
|
||||||
*(.gnu.linkonce.r*)
|
|
||||||
SORT(CONSTRUCTORS)
|
|
||||||
. = ALIGN(8);
|
|
||||||
} >main AT>high_iram
|
|
||||||
|
|
||||||
.preinit_array :
|
|
||||||
{
|
|
||||||
PROVIDE (__preinit_array_start = .);
|
|
||||||
KEEP (*(.preinit_array))
|
|
||||||
PROVIDE (__preinit_array_end = .);
|
|
||||||
} >main AT>high_iram
|
|
||||||
|
|
||||||
.init_array ALIGN(4) :
|
|
||||||
{
|
|
||||||
PROVIDE (__init_array_start = .);
|
|
||||||
KEEP (*(SORT(.init_array.*)))
|
|
||||||
KEEP (*(.init_array))
|
|
||||||
PROVIDE (__init_array_end = .);
|
|
||||||
} >main AT>high_iram
|
|
||||||
|
|
||||||
.fini_array ALIGN(4) :
|
|
||||||
{
|
|
||||||
PROVIDE (__fini_array_start = .);
|
|
||||||
KEEP (*(.fini_array))
|
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
|
||||||
PROVIDE (__fini_array_end = .);
|
|
||||||
} >main AT>high_iram
|
|
||||||
|
|
||||||
.ctors ALIGN(4) :
|
|
||||||
{
|
|
||||||
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
|
||||||
KEEP (*(.ctors))
|
|
||||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
|
||||||
} >main AT>high_iram
|
|
||||||
|
|
||||||
.dtors ALIGN(4) :
|
|
||||||
{
|
|
||||||
KEEP (*crtbegin.o(.dtors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
|
||||||
KEEP (*(.dtors))
|
|
||||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
|
||||||
} >main AT>high_iram
|
|
||||||
|
|
||||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) __exidx_start = ABSOLUTE(.);} >main AT>high_iram
|
|
||||||
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = ABSOLUTE(.);} >main AT>high_iram
|
|
||||||
|
|
||||||
.bss (NOLOAD) :
|
|
||||||
{
|
|
||||||
. = ALIGN(32);
|
|
||||||
PROVIDE (__bss_start__ = ABSOLUTE(.));
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.bss.*)
|
|
||||||
*(.gnu.linkonce.b*)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN(32);
|
|
||||||
PROVIDE (__bss_end__ = ABSOLUTE(.));
|
|
||||||
} >main AT>high_iram :NONE
|
|
||||||
__main_end__ = ABSOLUTE(.) ;
|
|
||||||
|
|
||||||
PROVIDE(__main_size__ = (__main_end__ - __main_start__));
|
|
||||||
|
|
||||||
/* ==================
|
|
||||||
==== Metadata ====
|
|
||||||
================== */
|
|
||||||
|
|
||||||
/* Discard sections that difficult post-processing */
|
|
||||||
/DISCARD/ : { *(.group .comment .note) }
|
|
||||||
|
|
||||||
/* Stabs debugging sections. */
|
|
||||||
.stab 0 : { *(.stab) }
|
|
||||||
.stabstr 0 : { *(.stabstr) }
|
|
||||||
.stab.excl 0 : { *(.stab.excl) }
|
|
||||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
|
||||||
.stab.index 0 : { *(.stab.index) }
|
|
||||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
|
||||||
|
|
||||||
/* DWARF debug sections.
|
|
||||||
Symbols in the DWARF debugging sections are relative to the beginning
|
|
||||||
of the section so we begin them at 0. */
|
|
||||||
|
|
||||||
/* DWARF 1 */
|
|
||||||
.debug 0 : { *(.debug) }
|
|
||||||
.line 0 : { *(.line) }
|
|
||||||
|
|
||||||
/* GNU DWARF 1 extensions */
|
|
||||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
|
||||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
|
||||||
|
|
||||||
/* DWARF 1.1 and DWARF 2 */
|
|
||||||
.debug_aranges 0 : { *(.debug_aranges) }
|
|
||||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
||||||
|
|
||||||
/* DWARF 2 */
|
|
||||||
.debug_info 0 : { *(.debug_info) }
|
|
||||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
||||||
.debug_line 0 : { *(.debug_line) }
|
|
||||||
.debug_frame 0 : { *(.debug_frame) }
|
|
||||||
.debug_str 0 : { *(.debug_str) }
|
|
||||||
.debug_loc 0 : { *(.debug_loc) }
|
|
||||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
%rename link old_link
|
|
||||||
|
|
||||||
*link:
|
|
||||||
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
|
|
||||||
|
|
||||||
*startfile:
|
|
||||||
crti%O%s crtbegin%O%s
|
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_APB_MISC_H
|
|
||||||
#define FUSEE_APB_MISC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define APB_MISC_BASE 0x70000000
|
|
||||||
#define APB_PADCTL_BASE 0x70000810
|
|
||||||
#define MAKE_APB_MISC_REG(n) MAKE_REG32(APB_MISC_BASE + n)
|
|
||||||
#define MAKE_APB_PADCTL_REG(n) MAKE_REG32(APB_PADCTL_BASE + n)
|
|
||||||
|
|
||||||
#define APB_MISC_PP_PINMUX_GLOBAL_0 MAKE_APB_MISC_REG(0x40)
|
|
||||||
#define APB_MISC_GP_DSI_PAD_CONTROL_0 MAKE_APB_MISC_REG(0xAC0)
|
|
||||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB64)
|
|
||||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB68)
|
|
||||||
|
|
||||||
#define SDMMC1_PAD_CAL_DRVUP_SHIFT (20)
|
|
||||||
#define SDMMC1_PAD_CAL_DRVDN_SHIFT (12)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_SHIFT (28)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_SHIFT (30)
|
|
||||||
#define SDMMC1_PAD_CAL_DRVUP_MASK (0x7Fu << SDMMC1_PAD_CAL_DRVUP_SHIFT)
|
|
||||||
#define SDMMC1_PAD_CAL_DRVDN_MASK (0x7Fu << SDMMC1_PAD_CAL_DRVDN_SHIFT)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_MASK (0x03u << SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_SHIFT)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_MASK (0x03u << SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_SHIFT)
|
|
||||||
|
|
||||||
#define EMMC2_PAD_DRVUP_COMP_SHIFT (8)
|
|
||||||
#define EMMC2_PAD_DRVDN_COMP_SHIFT (2)
|
|
||||||
#define EMMC2_PAD_DRVUP_COMP_MASK (0x3Fu << EMMC2_PAD_DRVUP_COMP_SHIFT)
|
|
||||||
#define EMMC2_PAD_DRVDN_COMP_MASK (0x3Fu << EMMC2_PAD_DRVDN_COMP_SHIFT)
|
|
||||||
|
|
||||||
#define SDMMC2_PAD_CAL_DRVUP_SHIFT (20)
|
|
||||||
#define SDMMC2_PAD_CAL_DRVDN_SHIFT (12)
|
|
||||||
#define SDMMC2_PAD_CAL_DRVUP_MASK (0x7Fu << SDMMC2_PAD_CAL_DRVUP_SHIFT)
|
|
||||||
#define SDMMC2_PAD_CAL_DRVDN_MASK (0x7Fu << SDMMC2_PAD_CAL_DRVDN_SHIFT)
|
|
||||||
|
|
||||||
#define EMMC4_PAD_DRVUP_COMP_SHIFT (8)
|
|
||||||
#define EMMC4_PAD_DRVDN_COMP_SHIFT (2)
|
|
||||||
#define EMMC4_PAD_DRVUP_COMP_MASK (0x3Fu << EMMC4_PAD_DRVUP_COMP_SHIFT)
|
|
||||||
#define EMMC4_PAD_DRVDN_COMP_MASK (0x3Fu << EMMC4_PAD_DRVDN_COMP_SHIFT)
|
|
||||||
|
|
||||||
#define PADCTL_SDMMC1_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC3_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC2_ENABLE_DATA_IN (0xFF << 8)
|
|
||||||
#define PADCTL_SDMMC2_ENABLE_CLK_IN (0x3 << 4)
|
|
||||||
#define PADCTL_SDMMC2_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC4_ENABLE_DATA_IN (0xFF << 8)
|
|
||||||
#define PADCTL_SDMMC4_ENABLE_CLK_IN (0x3 << 4)
|
|
||||||
#define PADCTL_SDMMC4_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC1_CD_SOURCE (1 << 0)
|
|
||||||
#define PADCTL_SDMMC1_WP_SOURCE (1 << 1)
|
|
||||||
#define PADCTL_SDMMC3_CD_SOURCE (1 << 2)
|
|
||||||
#define PADCTL_SDMMC3_WP_SOURCE (1 << 3)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t asdbgreg; /* 0x810 */
|
|
||||||
uint32_t _0x814[0x31];
|
|
||||||
uint32_t sdmmc1_clk_lpbk_control; /* 0x8D4 */
|
|
||||||
uint32_t sdmmc3_clk_lpbk_control; /* 0x8D8 */
|
|
||||||
uint32_t emmc2_pad_cfg_control; /* 0x8DC */
|
|
||||||
uint32_t emmc4_pad_cfg_control; /* 0x8E0 */
|
|
||||||
uint32_t _0x8E4[0x6E];
|
|
||||||
uint32_t sdmmc1_pad_cfgpadctrl; /* 0xA98 */
|
|
||||||
uint32_t emmc2_pad_cfgpadctrl; /* 0xA9C */
|
|
||||||
uint32_t emmc2_pad_drv_type_cfgpadctrl; /* 0xAA0 */
|
|
||||||
uint32_t emmc2_pad_pupd_cfgpadctrl; /* 0xAA4 */
|
|
||||||
uint32_t _0xAA8[0x03];
|
|
||||||
uint32_t sdmmc3_pad_cfgpadctrl; /* 0xAB0 */
|
|
||||||
uint32_t emmc4_pad_cfgpadctrl; /* 0xAB4 */
|
|
||||||
uint32_t emmc4_pad_drv_type_cfgpadctrl; /* 0xAB8 */
|
|
||||||
uint32_t emmc4_pad_pupd_cfgpadctrl; /* 0xABC */
|
|
||||||
uint32_t _0xAC0[0x2E];
|
|
||||||
uint32_t vgpio_gpio_mux_sel; /* 0xB74 */
|
|
||||||
uint32_t qspi_sck_lpbk_control; /* 0xB78 */
|
|
||||||
} tegra_padctl_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_padctl_t *padctl_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_padctl_t *)APB_PADCTL_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "btn.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "timers.h"
|
|
||||||
|
|
||||||
uint32_t btn_read()
|
|
||||||
{
|
|
||||||
uint32_t res = 0;
|
|
||||||
|
|
||||||
if (!gpio_read(GPIO_BUTTON_VOL_DOWN))
|
|
||||||
res |= BTN_VOL_DOWN;
|
|
||||||
|
|
||||||
if (!gpio_read(GPIO_BUTTON_VOL_UP))
|
|
||||||
res |= BTN_VOL_UP;
|
|
||||||
|
|
||||||
uint32_t val = 0;
|
|
||||||
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x15, &val, 1))
|
|
||||||
{
|
|
||||||
if (val & 0x4)
|
|
||||||
res |= BTN_POWER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t btn_wait()
|
|
||||||
{
|
|
||||||
uint32_t res = 0, btn = btn_read();
|
|
||||||
int pwr = 0;
|
|
||||||
|
|
||||||
if (btn & BTN_POWER)
|
|
||||||
{
|
|
||||||
pwr = 1;
|
|
||||||
btn &= ~BTN_POWER;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
res = btn_read();
|
|
||||||
|
|
||||||
if (!(res & BTN_POWER) && pwr)
|
|
||||||
pwr = 0;
|
|
||||||
else if (pwr)
|
|
||||||
res &= ~BTN_POWER;
|
|
||||||
} while (btn == res);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask)
|
|
||||||
{
|
|
||||||
uint32_t timeout = get_time_us() + time_ms * 1000;
|
|
||||||
uint32_t res = btn_read() & mask;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!(res & mask))
|
|
||||||
res = btn_read() & mask;
|
|
||||||
} while (get_time_us() < timeout);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_BTN_H_
|
|
||||||
#define FUSEE_BTN_H_
|
|
||||||
|
|
||||||
#define BTN_POWER 0x1
|
|
||||||
#define BTN_VOL_DOWN 0x2
|
|
||||||
#define BTN_VOL_UP 0x4
|
|
||||||
|
|
||||||
uint32_t btn_read();
|
|
||||||
uint32_t btn_wait();
|
|
||||||
uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "car.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
|
||||||
switch (dev) {
|
|
||||||
case CARDEVICE_UARTA: return 0x178;
|
|
||||||
case CARDEVICE_UARTB: return 0x17C;
|
|
||||||
case CARDEVICE_UARTC: return 0x1A0;
|
|
||||||
case CARDEVICE_I2C1: return 0x124;
|
|
||||||
case CARDEVICE_I2C5: return 0x128;
|
|
||||||
case CARDEVICE_TZRAM: return 0;
|
|
||||||
case CARDEVICE_SE: return 0x42C;
|
|
||||||
case CARDEVICE_HOST1X: return 0x180;
|
|
||||||
case CARDEVICE_TSEC: return 0x1F4;
|
|
||||||
case CARDEVICE_SOR_SAFE: return 0;
|
|
||||||
case CARDEVICE_SOR0: return 0;
|
|
||||||
case CARDEVICE_SOR1: return 0x410;
|
|
||||||
case CARDEVICE_KFUSE: return 0;
|
|
||||||
case CARDEVICE_CL_DVFS: return 0;
|
|
||||||
case CARDEVICE_CORESIGHT: return 0x1D4;
|
|
||||||
case CARDEVICE_MSELECT: return 0x3B4;
|
|
||||||
case CARDEVICE_ACTMON: return 0x3E8;
|
|
||||||
case CARDEVICE_BPMP: return 0;
|
|
||||||
default: generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_val(CarDevice dev) {
|
|
||||||
switch (dev) {
|
|
||||||
case CARDEVICE_UARTA: return 0;
|
|
||||||
case CARDEVICE_UARTB: return 0;
|
|
||||||
case CARDEVICE_UARTC: return 0;
|
|
||||||
case CARDEVICE_I2C1: return 6;
|
|
||||||
case CARDEVICE_I2C5: return 6;
|
|
||||||
case CARDEVICE_TZRAM: return 0;
|
|
||||||
case CARDEVICE_SE: return 0;
|
|
||||||
case CARDEVICE_HOST1X: return 4;
|
|
||||||
case CARDEVICE_TSEC: return 0;
|
|
||||||
case CARDEVICE_SOR_SAFE: return 0;
|
|
||||||
case CARDEVICE_SOR0: return 0;
|
|
||||||
case CARDEVICE_SOR1: return 0;
|
|
||||||
case CARDEVICE_KFUSE: return 0;
|
|
||||||
case CARDEVICE_CL_DVFS: return 0;
|
|
||||||
case CARDEVICE_CORESIGHT: return 0;
|
|
||||||
case CARDEVICE_MSELECT: return 0;
|
|
||||||
case CARDEVICE_ACTMON: return 6;
|
|
||||||
case CARDEVICE_BPMP: return 0;
|
|
||||||
default: generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_div(CarDevice dev) {
|
|
||||||
switch (dev) {
|
|
||||||
case CARDEVICE_UARTA: return 0;
|
|
||||||
case CARDEVICE_UARTB: return 0;
|
|
||||||
case CARDEVICE_UARTC: return 0;
|
|
||||||
case CARDEVICE_I2C1: return 0;
|
|
||||||
case CARDEVICE_I2C5: return 0;
|
|
||||||
case CARDEVICE_TZRAM: return 0;
|
|
||||||
case CARDEVICE_SE: return 0;
|
|
||||||
case CARDEVICE_HOST1X: return 3;
|
|
||||||
case CARDEVICE_TSEC: return 2;
|
|
||||||
case CARDEVICE_SOR_SAFE: return 0;
|
|
||||||
case CARDEVICE_SOR0: return 0;
|
|
||||||
case CARDEVICE_SOR1: return 2;
|
|
||||||
case CARDEVICE_KFUSE: return 0;
|
|
||||||
case CARDEVICE_CL_DVFS: return 0;
|
|
||||||
case CARDEVICE_CORESIGHT: return 4;
|
|
||||||
case CARDEVICE_MSELECT: return 6;
|
|
||||||
case CARDEVICE_ACTMON: return 0;
|
|
||||||
case CARDEVICE_BPMP: return 0;
|
|
||||||
default: generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
|
|
||||||
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
|
|
||||||
|
|
||||||
void clk_enable(CarDevice dev) {
|
|
||||||
uint32_t clk_source_reg;
|
|
||||||
if ((clk_source_reg = get_clk_source_reg(dev))) {
|
|
||||||
MAKE_CAR_REG(clk_source_reg) = (get_clk_source_val(dev) << 29) | get_clk_source_div(dev);
|
|
||||||
}
|
|
||||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clk_disable(CarDevice dev) {
|
|
||||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
void rst_enable(CarDevice dev) {
|
|
||||||
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clkrst_disable(CarDevice dev) {
|
|
||||||
rst_enable(dev);
|
|
||||||
clk_disable(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clkrst_reboot(CarDevice dev) {
|
|
||||||
clkrst_disable(dev);
|
|
||||||
if (dev == CARDEVICE_KFUSE) {
|
|
||||||
/* Workaround for KFUSE clock. */
|
|
||||||
clk_enable(dev);
|
|
||||||
udelay(100);
|
|
||||||
rst_disable(dev);
|
|
||||||
udelay(200);
|
|
||||||
} else {
|
|
||||||
clkrst_enable(dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clkrst_enable_fuse_regs(bool enable) {
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
car->misc_clk_enb = ((car->misc_clk_enb & 0xEFFFFFFF) | ((enable & 1) << 28));
|
|
||||||
}
|
|
|
@ -1,510 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_CAR_H
|
|
||||||
#define FUSEE_CAR_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define CAR_BASE 0x60006000
|
|
||||||
#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
|
|
||||||
|
|
||||||
#define CLK_L_SDMMC1 (1 << 14)
|
|
||||||
#define CLK_L_SDMMC2 (1 << 9)
|
|
||||||
#define CLK_U_SDMMC3 (1 << 5)
|
|
||||||
#define CLK_L_SDMMC4 (1 << 15)
|
|
||||||
|
|
||||||
#define CLK_SOURCE_MASK (0b111 << 29)
|
|
||||||
#define CLK_SOURCE_FIRST (0b000 << 29)
|
|
||||||
#define CLK_DIVIDER_MASK (0xff << 0)
|
|
||||||
#define CLK_DIVIDER_UNITY (0x00 << 0)
|
|
||||||
|
|
||||||
#define NUM_CAR_BANKS 7
|
|
||||||
|
|
||||||
/* Clock and reset devices. */
|
|
||||||
typedef enum {
|
|
||||||
CARDEVICE_BPMP = ((0 << 5) | 0x1),
|
|
||||||
CARDEVICE_UARTA = ((0 << 5) | 0x6),
|
|
||||||
CARDEVICE_UARTB = ((0 << 5) | 0x7),
|
|
||||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
|
||||||
CARDEVICE_USBD = ((0 << 5) | 0x16),
|
|
||||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
|
||||||
CARDEVICE_AHBDMA = ((1 << 5) | 0x1),
|
|
||||||
CARDEVICE_APBDMA = ((1 << 5) | 0x2),
|
|
||||||
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
|
|
||||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
|
||||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
|
||||||
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
|
|
||||||
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
|
||||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
|
||||||
CARDEVICE_MSELECT = ((3 << 5) | 0x8),
|
|
||||||
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
|
||||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
|
||||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
|
||||||
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
|
|
||||||
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
|
|
||||||
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
|
|
||||||
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
|
|
||||||
} CarDevice;
|
|
||||||
|
|
||||||
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t rst_src; /* _RST_SOURCE_0, 0x00 */
|
|
||||||
|
|
||||||
/* _RST_DEVICES_L/H/U_0 0x4-0xc */
|
|
||||||
uint32_t rst_dev_l;
|
|
||||||
uint32_t rst_dev_h;
|
|
||||||
uint32_t rst_dev_u;
|
|
||||||
|
|
||||||
/* _CLK_OUT_ENB_L/H/U_0 0x10-0x18 */
|
|
||||||
uint32_t clk_out_enb_l;
|
|
||||||
uint32_t clk_out_enb_h;
|
|
||||||
uint32_t clk_out_enb_u;
|
|
||||||
|
|
||||||
uint32_t _0x1C;
|
|
||||||
uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
|
|
||||||
uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0, 0x24 */
|
|
||||||
uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
|
|
||||||
uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0, 0x2c */
|
|
||||||
uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
|
|
||||||
uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
|
|
||||||
uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0, 0x38 */
|
|
||||||
uint32_t _0x3C;
|
|
||||||
uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0, 0x40 */
|
|
||||||
uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
|
|
||||||
uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
|
|
||||||
uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4c */
|
|
||||||
uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
|
|
||||||
uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
|
|
||||||
uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
|
|
||||||
uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0, 0x5c */
|
|
||||||
uint32_t _0x60[2];
|
|
||||||
uint32_t plle_ss_cntl; /* _PLLE_SS_CNTL_0, 0x68 */
|
|
||||||
uint32_t plle_misc1; /* _PLLE_MISC1_0, 0x6c */
|
|
||||||
uint32_t _0x70[4];
|
|
||||||
|
|
||||||
/* PLLC 0x80-0x8c */
|
|
||||||
uint32_t pllc_base;
|
|
||||||
uint32_t pllc_out;
|
|
||||||
uint32_t pllc_misc0;
|
|
||||||
uint32_t pllc_misc1;
|
|
||||||
|
|
||||||
/* PLLM 0x90-0x9c */
|
|
||||||
uint32_t pllm_base;
|
|
||||||
uint32_t pllm_out;
|
|
||||||
uint32_t pllm_misc1;
|
|
||||||
uint32_t pllm_misc2;
|
|
||||||
|
|
||||||
/* PLLP 0xa0-0xac */
|
|
||||||
uint32_t pllp_base;
|
|
||||||
uint32_t pllp_outa;
|
|
||||||
uint32_t pllp_outb;
|
|
||||||
uint32_t pllp_misc;
|
|
||||||
|
|
||||||
/* PLLA 0xb0-0xbc */
|
|
||||||
uint32_t plla_base;
|
|
||||||
uint32_t plla_out;
|
|
||||||
uint32_t plla_misc0;
|
|
||||||
uint32_t plla_misc1;
|
|
||||||
|
|
||||||
/* PLLU 0xc0-0xcc */
|
|
||||||
uint32_t pllu_base;
|
|
||||||
uint32_t pllu_out;
|
|
||||||
uint32_t pllu_misc1;
|
|
||||||
uint32_t pllu_misc2;
|
|
||||||
|
|
||||||
/* PLLD 0xd0-0xdc */
|
|
||||||
uint32_t plld_base;
|
|
||||||
uint32_t plld_out;
|
|
||||||
uint32_t plld_misc1;
|
|
||||||
uint32_t plld_misc2;
|
|
||||||
|
|
||||||
/* PLLX 0xe0-0xe4 */
|
|
||||||
uint32_t pllx_base;
|
|
||||||
uint32_t pllx_misc;
|
|
||||||
|
|
||||||
/* PLLE 0xe8-0xf4 */
|
|
||||||
uint32_t plle_base;
|
|
||||||
uint32_t plle_misc;
|
|
||||||
uint32_t plle_ss_cntl1;
|
|
||||||
uint32_t plle_ss_cntl2;
|
|
||||||
|
|
||||||
uint32_t lvl2_clk_gate_ovra; /* _LVL2_CLK_GATE_OVRA_0, 0xf8 */
|
|
||||||
uint32_t lvl2_clk_gate_ovrb; /* _LVL2_CLK_GATE_OVRB_0, 0xfc */
|
|
||||||
|
|
||||||
uint32_t clk_source_i2s2; /* _CLK_SOURCE_I2S2_0, 0x100 */
|
|
||||||
uint32_t clk_source_i2s3; /* _CLK_SOURCE_I2S3_0, 0x104 */
|
|
||||||
uint32_t clk_source_spdif_out; /* _CLK_SOURCE_SPDIF_OUT_0, 0x108 */
|
|
||||||
uint32_t clk_source_spdif_in; /* _CLK_SOURCE_SPDIF_IN_0, 0x10c */
|
|
||||||
uint32_t clk_source_pwm; /* _CLK_SOURCE_PWM_0, 0x110 */
|
|
||||||
uint32_t _0x114;
|
|
||||||
uint32_t clk_source_spi2; /* _CLK_SOURCE_SPI2_0, 0x118 */
|
|
||||||
uint32_t clk_source_spi3; /* _CLK_SOURCE_SPI3_0, 0x11c */
|
|
||||||
uint32_t _0x120;
|
|
||||||
uint32_t clk_source_i2c1; /* _CLK_SOURCE_I2C1_0, 0x124 */
|
|
||||||
uint32_t clk_source_i2c5; /* _CLK_SOURCE_I2C5_0, 0x128 */
|
|
||||||
uint32_t _0x12c[2];
|
|
||||||
uint32_t clk_source_spi1; /* _CLK_SOURCE_SPI1_0, 0x134 */
|
|
||||||
uint32_t clk_source_disp1; /* _CLK_SOURCE_DISP1_0, 0x138 */
|
|
||||||
uint32_t clk_source_disp2; /* _CLK_SOURCE_DISP2_0, 0x13c */
|
|
||||||
uint32_t _0x140;
|
|
||||||
uint32_t clk_source_isp; /* _CLK_SOURCE_ISP_0, 0x144 */
|
|
||||||
uint32_t clk_source_vi; /* _CLK_SOURCE_VI_0, 0x148 */
|
|
||||||
uint32_t _0x14c;
|
|
||||||
uint32_t clk_source_sdmmc1; /* _CLK_SOURCE_SDMMC1_0, 0x150 */
|
|
||||||
uint32_t clk_source_sdmmc2; /* _CLK_SOURCE_SDMMC2_0, 0x154 */
|
|
||||||
uint32_t _0x158[3];
|
|
||||||
uint32_t clk_source_sdmmc4; /* _CLK_SOURCE_SDMMC4_0, 0x164 */
|
|
||||||
uint32_t _0x168[4];
|
|
||||||
uint32_t clk_source_uarta; /* _CLK_SOURCE_UARTA_0, 0x178 */
|
|
||||||
uint32_t clk_source_uartb; /* _CLK_SOURCE_UARTB_0, 0x17c */
|
|
||||||
uint32_t clk_source_host1x; /* _CLK_SOURCE_HOST1X_0, 0x180 */
|
|
||||||
uint32_t _0x184[5];
|
|
||||||
uint32_t clk_source_i2c2; /* _CLK_SOURCE_I2C2_0, 0x198 */
|
|
||||||
uint32_t clk_source_emc; /* _CLK_SOURCE_EMC_0, 0x19c */
|
|
||||||
uint32_t clk_source_uartc; /* _CLK_SOURCE_UARTC_0, 0x1a0 */
|
|
||||||
uint32_t _0x1a4;
|
|
||||||
uint32_t clk_source_vi_sensor; /* _CLK_SOURCE_VI_SENSOR_0, 0x1a8 */
|
|
||||||
uint32_t _0x1ac[2];
|
|
||||||
uint32_t clk_source_spi4; /* _CLK_SOURCE_SPI4_0, 0x1b4 */
|
|
||||||
uint32_t clk_source_i2c3; /* _CLK_SOURCE_I2C3_0, 0x1b8 */
|
|
||||||
uint32_t clk_source_sdmmc3; /* _CLK_SOURCE_SDMMC3_0, 0x1bc */
|
|
||||||
uint32_t clk_source_uartd; /* _CLK_SOURCE_UARTD_0, 0x1c0 */
|
|
||||||
uint32_t _0x1c4[2];
|
|
||||||
uint32_t clk_source_owr; /* _CLK_SOURCE_OWR_0, 0x1cc */
|
|
||||||
uint32_t _0x1d0;
|
|
||||||
uint32_t clk_source_csite; /* _CLK_SOURCE_CSITE_0, 0x1d4 */
|
|
||||||
uint32_t clk_source_i2s1; /* _CLK_SOURCE_I2S1_0, 0x1d8 */
|
|
||||||
uint32_t clk_source_dtv; /* _CLK_SOURCE_DTV_0, 0x1dc */
|
|
||||||
uint32_t _0x1e0[5];
|
|
||||||
uint32_t clk_source_tsec; /* _CLK_SOURCE_TSEC_0, 0x1f4 */
|
|
||||||
uint32_t _0x1f8;
|
|
||||||
|
|
||||||
uint32_t clk_spare2; /* _CLK_SPARE2_0, 0x1fc */
|
|
||||||
uint32_t _0x200[32];
|
|
||||||
|
|
||||||
uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
|
|
||||||
uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
|
|
||||||
uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
|
|
||||||
|
|
||||||
uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
|
|
||||||
uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
|
|
||||||
uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
|
|
||||||
|
|
||||||
uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
|
|
||||||
uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
|
|
||||||
uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
|
|
||||||
|
|
||||||
uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
|
|
||||||
uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
|
|
||||||
uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
|
|
||||||
|
|
||||||
uint32_t _0x2b0[17];
|
|
||||||
uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
|
|
||||||
uint32_t _0x2f8[2];
|
|
||||||
|
|
||||||
/* _RST_DEV_L/H/U_SET_0 0x300-0x314 */
|
|
||||||
uint32_t rst_dev_l_set;
|
|
||||||
uint32_t rst_dev_l_clr;
|
|
||||||
uint32_t rst_dev_h_set;
|
|
||||||
uint32_t rst_dev_h_clr;
|
|
||||||
uint32_t rst_dev_u_set;
|
|
||||||
uint32_t rst_dev_u_clr;
|
|
||||||
|
|
||||||
uint32_t _0x318[2];
|
|
||||||
|
|
||||||
/* _CLK_ENB_L/H/U_CLR_0 0x320-0x334 */
|
|
||||||
uint32_t clk_enb_l_set;
|
|
||||||
uint32_t clk_enb_l_clr;
|
|
||||||
uint32_t clk_enb_h_set;
|
|
||||||
uint32_t clk_enb_h_clr;
|
|
||||||
uint32_t clk_enb_u_set;
|
|
||||||
uint32_t clk_enb_u_clr;
|
|
||||||
|
|
||||||
uint32_t _0x338;
|
|
||||||
uint32_t ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD_0, 0x33c */
|
|
||||||
uint32_t rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
|
|
||||||
uint32_t rst_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
|
|
||||||
|
|
||||||
/* Additional (T30) registers */
|
|
||||||
uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
|
|
||||||
uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
|
|
||||||
|
|
||||||
uint32_t _0x350[2];
|
|
||||||
uint32_t rst_dev_v; /* _RST_DEVICES_V_0, 0x358 */
|
|
||||||
uint32_t rst_dev_w; /* _RST_DEVICES_W_0, 0x35c */
|
|
||||||
uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V_0, 0x360 */
|
|
||||||
uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_W_0, 0x364 */
|
|
||||||
uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
|
|
||||||
uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36c */
|
|
||||||
uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
|
|
||||||
uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
|
|
||||||
uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
|
|
||||||
uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37c */
|
|
||||||
uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
|
|
||||||
uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
|
|
||||||
uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
|
|
||||||
uint32_t _0x38c[5];
|
|
||||||
uint32_t lvl2_clk_gate_ovrc; /* _LVL2_CLK_GATE_OVRC, 0x3a0 */
|
|
||||||
uint32_t lvl2_clk_gate_ovrd; /* _LVL2_CLK_GATE_OVRD, 0x3a4 */
|
|
||||||
uint32_t _0x3a8[2];
|
|
||||||
|
|
||||||
uint32_t _0x3b0;
|
|
||||||
uint32_t clk_source_mselect; /* _CLK_SOURCE_MSELECT_0, 0x3b4 */
|
|
||||||
uint32_t clk_source_tsensor; /* _CLK_SOURCE_TSENSOR_0, 0x3b8 */
|
|
||||||
uint32_t clk_source_i2s4; /* _CLK_SOURCE_I2S4_0, 0x3bc */
|
|
||||||
uint32_t clk_source_i2s5; /* _CLK_SOURCE_I2S5_0, 0x3c0 */
|
|
||||||
uint32_t clk_source_i2c4; /* _CLK_SOURCE_I2C4_0, 0x3c4 */
|
|
||||||
uint32_t _0x3c8[2];
|
|
||||||
uint32_t clk_source_ahub; /* _CLK_SOURCE_AHUB_0, 0x3d0 */
|
|
||||||
uint32_t _0x3d4[4];
|
|
||||||
uint32_t clk_source_hda2codec_2x; /* _CLK_SOURCE_HDA2CODEC_2X_0, 0x3e4 */
|
|
||||||
uint32_t clk_source_actmon; /* _CLK_SOURCE_ACTMON_0, 0x3e8 */
|
|
||||||
uint32_t clk_source_extperiph1; /* _CLK_SOURCE_EXTPERIPH1_0, 0x3ec */
|
|
||||||
uint32_t clk_source_extperiph2; /* _CLK_SOURCE_EXTPERIPH2_0, 0x3f0 */
|
|
||||||
uint32_t clk_source_extperiph3; /* _CLK_SOURCE_EXTPERIPH3_0, 0x3f4 */
|
|
||||||
uint32_t _0x3f8;
|
|
||||||
uint32_t clk_source_i2c_slow; /* _CLK_SOURCE_I2C_SLOW_0, 0x3fc */
|
|
||||||
uint32_t clk_source_sys; /* _CLK_SOURCE_SYS_0, 0x400 */
|
|
||||||
uint32_t clk_source_ispb; /* _CLK_SOURCE_ISPB_0, 0x404 */
|
|
||||||
uint32_t _0x408[2];
|
|
||||||
uint32_t clk_source_sor1; /* _CLK_SOURCE_SOR1_0, 0x410 */
|
|
||||||
uint32_t clk_source_sor0; /* _CLK_SOURCE_SOR0_0, 0x414 */
|
|
||||||
uint32_t _0x418[2];
|
|
||||||
uint32_t clk_source_sata_oob; /* _CLK_SOURCE_SATA_OOB_0, 0x420 */
|
|
||||||
uint32_t clk_source_sata; /* _CLK_SOURCE_SATA_0, 0x424 */
|
|
||||||
uint32_t clk_source_hda; /* _CLK_SOURCE_HDA_0, 0x428 */
|
|
||||||
uint32_t clk_source_se; /* _CLK_SOURCE_SE_0, 0x42c */
|
|
||||||
|
|
||||||
/* _RST_DEV_V/W_SET_0 0x430-0x43c */
|
|
||||||
uint32_t rst_dev_v_set;
|
|
||||||
uint32_t rst_dev_v_clr;
|
|
||||||
uint32_t rst_dev_w_set;
|
|
||||||
uint32_t rst_dev_w_clr;
|
|
||||||
|
|
||||||
/* _CLK_ENB_V/W_CLR_0 0x440-0x44c */
|
|
||||||
uint32_t clk_enb_v_set;
|
|
||||||
uint32_t clk_enb_v_clr;
|
|
||||||
uint32_t clk_enb_w_set;
|
|
||||||
uint32_t clk_enb_w_clr;
|
|
||||||
|
|
||||||
/* Additional (T114+) registers */
|
|
||||||
uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
|
|
||||||
uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
|
|
||||||
uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
|
|
||||||
uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45c */
|
|
||||||
uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
|
|
||||||
uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
|
|
||||||
uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
|
|
||||||
uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46c */
|
|
||||||
uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
|
|
||||||
uint32_t _0x474;
|
|
||||||
uint32_t intstatus; /* _INTSTATUS_0, 0x478 */
|
|
||||||
uint32_t intmask; /* _INTMASK_0, 0x47c */
|
|
||||||
uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
|
|
||||||
uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
|
|
||||||
uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
|
|
||||||
|
|
||||||
uint32_t plle_aux; /* _PLLE_AUX_0, 0x48c */
|
|
||||||
uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
|
|
||||||
uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
|
|
||||||
uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
|
|
||||||
|
|
||||||
uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49c */
|
|
||||||
uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4a0 */
|
|
||||||
uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4a4 */
|
|
||||||
uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4a8 */
|
|
||||||
uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4ac */
|
|
||||||
uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4b0 */
|
|
||||||
uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4b4 */
|
|
||||||
|
|
||||||
uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4b8 */
|
|
||||||
uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4bc */
|
|
||||||
uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4c0 */
|
|
||||||
uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4c4 */
|
|
||||||
uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4c8 */
|
|
||||||
uint32_t pllrefe_out; /* _PLLREFE_OUT_0, 0x4cc */
|
|
||||||
uint32_t cpu_finetrim_byp; /* _CPU_FINETRIM_BYP_0, 0x4d0 */
|
|
||||||
uint32_t cpu_finetrim_select; /* _CPU_FINETRIM_SELECT_0, 0x4d4 */
|
|
||||||
uint32_t cpu_finetrim_dr; /* _CPU_FINETRIM_DR_0, 0x4d8 */
|
|
||||||
uint32_t cpu_finetrim_df; /* _CPU_FINETRIM_DF_0, 0x4dc */
|
|
||||||
uint32_t cpu_finetrim_f; /* _CPU_FINETRIM_F_0, 0x4e0 */
|
|
||||||
uint32_t cpu_finetrim_r; /* _CPU_FINETRIM_R_0, 0x4e4 */
|
|
||||||
uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4e8 */
|
|
||||||
uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4ec */
|
|
||||||
uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4f0 */
|
|
||||||
uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4f4 */
|
|
||||||
uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4f8 */
|
|
||||||
uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4fc */
|
|
||||||
uint32_t pllc3_misc0; /* _PLLC3_MISC_0_0, 0x500 */
|
|
||||||
uint32_t pllc3_misc1; /* _PLLC3_MISC_1_0, 0x504 */
|
|
||||||
uint32_t pllc3_misc2; /* _PLLC3_MISC_2_0, 0x508 */
|
|
||||||
uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50c */
|
|
||||||
uint32_t pllx_misc1; /* _PLLX_MISC_1_0, 0x510 */
|
|
||||||
uint32_t pllx_misc2; /* _PLLX_MISC_2_0, 0x514 */
|
|
||||||
uint32_t pllx_misc3; /* _PLLX_MISC_3_0, 0x518 */
|
|
||||||
uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51c */
|
|
||||||
uint32_t xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG0_1, 0x520 */
|
|
||||||
uint32_t plle_aux1; /* _PLLE_AUX1_0, 0x524 */
|
|
||||||
uint32_t pllp_reshift; /* _PLLP_RESHIFT_0, 0x528 */
|
|
||||||
uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52c */
|
|
||||||
uint32_t pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0_0, 0x530 */
|
|
||||||
uint32_t xusb_pll_cfg0; /* _XUSB_PLL_CFG0_0, 0x534 */
|
|
||||||
uint32_t _0x538;
|
|
||||||
uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53c */
|
|
||||||
uint32_t clk_cpug_misc; /* _CLK_CPUG_MISC_0, 0x540 */
|
|
||||||
uint32_t clk_cpulp_misc; /* _CLK_CPULP_MISC_0, 0x544 */
|
|
||||||
uint32_t pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG_0, 0x548 */
|
|
||||||
uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54c */
|
|
||||||
uint32_t pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS_0, 0x550 */
|
|
||||||
uint32_t lvl2_clk_gate_ovre; /* _LVL2_CLK_GATE_OVRE, 0x554 */
|
|
||||||
uint32_t super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER_0, 0x558 */
|
|
||||||
uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55c */
|
|
||||||
uint32_t audio_sync_clk_dmic1; /* _AUDIO_SYNC_CLK_DMIC1_0, 0x560 */
|
|
||||||
uint32_t audio_sync_clk_dmic2; /* _AUDIO_SYNC_CLK_DMIC2_0, 0x564 */
|
|
||||||
|
|
||||||
uint32_t _0x568[2];
|
|
||||||
uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG, 0x570 */
|
|
||||||
uint32_t plld2_ss_ctrl1; /* _PLLD2_SS_CTRL1_0, 0x574 */
|
|
||||||
uint32_t plld2_ss_ctrl2; /* _PLLD2_SS_CTRL2_0, 0x578 */
|
|
||||||
uint32_t _0x57c[5];
|
|
||||||
|
|
||||||
uint32_t plldp_base; /* _PLLDP_BASE, 0x590*/
|
|
||||||
uint32_t plldp_misc; /* _PLLDP_MISC, 0x594 */
|
|
||||||
uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
|
|
||||||
uint32_t plldp_ss_ctrl1; /* _PLLDP_SS_CTRL1_0, 0x59c */
|
|
||||||
uint32_t plldp_ss_ctrl2; /* _PLLDP_SS_CTRL2_0, 0x5a0 */
|
|
||||||
uint32_t pllc4_base; /* _PLLC4_BASE_0, 0x5a4 */
|
|
||||||
uint32_t pllc4_misc; /* _PLLC4_MISC_0, 0x5a8 */
|
|
||||||
uint32_t _0x5ac[6];
|
|
||||||
uint32_t clk_spare0; /* _CLK_SPARE0_0, 0x5c4 */
|
|
||||||
uint32_t clk_spare1; /* _CLK_SPARE1_0, 0x5c8 */
|
|
||||||
uint32_t gpu_isob_ctrl; /* _GPU_ISOB_CTRL_0, 0x5cc */
|
|
||||||
uint32_t pllc_misc2; /* _PLLC_MISC_2_0, 0x5d0 */
|
|
||||||
uint32_t pllc_misc3; /* _PLLC_MISC_3_0, 0x5d4 */
|
|
||||||
uint32_t plla_misc2; /* _PLLA_MISC2_0, 0x5d8 */
|
|
||||||
uint32_t _0x5dc[2];
|
|
||||||
uint32_t pllc4_out; /* _PLLC4_OUT_0, 0x5e4 */
|
|
||||||
uint32_t pllmb_base; /* _PLLMB_BASE_0, 0x5e8 */
|
|
||||||
uint32_t pllmb_misc1; /* _PLLMB_MISC1_0, 0x5ec */
|
|
||||||
uint32_t pllx_misc4; /* _PLLX_MISC_4_0, 0x5f0 */
|
|
||||||
uint32_t pllx_misc5; /* _PLLX_MISC_5_0, 0x5f4 */
|
|
||||||
uint32_t _0x5f8[2];
|
|
||||||
|
|
||||||
uint32_t clk_source_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST_0, 0x600 */
|
|
||||||
uint32_t clk_source_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON_0, 0x604 */
|
|
||||||
uint32_t clk_source_xusb_fs; /* _CLK_SOURCE_XUSB_FS_0, 0x608 */
|
|
||||||
uint32_t clk_source_xusb_core_dev; /* _CLK_SOURCE_XUSB_CORE_DEV_0, 0x60c */
|
|
||||||
uint32_t clk_source_xusb_ss; /* _CLK_SOURCE_XUSB_SS_0, 0x610 */
|
|
||||||
uint32_t clk_source_cilab; /* _CLK_SOURCE_CILAB_0, 0x614 */
|
|
||||||
uint32_t clk_source_cilcd; /* _CLK_SOURCE_CILCD_0, 0x618 */
|
|
||||||
uint32_t clk_source_cilef; /* _CLK_SOURCE_CILEF_0, 0x61c */
|
|
||||||
uint32_t clk_source_dsia_lp; /* _CLK_SOURCE_DSIA_LP_0, 0x620 */
|
|
||||||
uint32_t clk_source_dsib_lp; /* _CLK_SOURCE_DSIB_LP_0, 0x624 */
|
|
||||||
uint32_t clk_source_entropy; /* _CLK_SOURCE_ENTROPY_0, 0x628 */
|
|
||||||
uint32_t clk_source_dvfs_ref; /* _CLK_SOURCE_DVFS_REF_0, 0x62c */
|
|
||||||
uint32_t clk_source_dvfs_soc; /* _CLK_SOURCE_DVFS_SOC_0, 0x630 */
|
|
||||||
uint32_t _0x634[3];
|
|
||||||
uint32_t clk_source_emc_latency; /* _CLK_SOURCE_EMC_LATENCY_0, 0x640 */
|
|
||||||
uint32_t clk_source_soc_therm; /* _CLK_SOURCE_SOC_THERM_0, 0x644 */
|
|
||||||
uint32_t _0x648;
|
|
||||||
uint32_t clk_source_dmic1; /* _CLK_SOURCE_DMIC1_0, 0x64c */
|
|
||||||
uint32_t clk_source_dmic2; /* _CLK_SOURCE_DMIC2_0, 0x650 */
|
|
||||||
uint32_t _0x654;
|
|
||||||
uint32_t clk_source_vi_sensor2; /* _CLK_SOURCE_VI_SENSOR2_0, 0x658 */
|
|
||||||
uint32_t clk_source_i2c6; /* _CLK_SOURCE_I2C6_0, 0x65c */
|
|
||||||
uint32_t clk_source_mipibif; /* _CLK_SOURCE_MIPIBIF_0, 0x660 */
|
|
||||||
uint32_t clk_source_emc_dll; /* _CLK_SOURCE_EMC_DLL_0, 0x664 */
|
|
||||||
uint32_t _0x668;
|
|
||||||
uint32_t clk_source_uart_fst_mipi_cal; /* _CLK_SOURCE_UART_FST_MIPI_CAL_0, 0x66c */
|
|
||||||
uint32_t _0x670[2];
|
|
||||||
uint32_t clk_source_vic; /* _CLK_SOURCE_VIC_0, 0x678 */
|
|
||||||
|
|
||||||
uint32_t pllp_outc; /* _PLLP_OUTC_0, 0x67c */
|
|
||||||
uint32_t pllp_misc1; /* _PLLP_MISC1_0, 0x680 */
|
|
||||||
uint32_t _0x684[2];
|
|
||||||
uint32_t emc_div_clk_shaper_ctrl; /* _EMC_DIV_CLK_SHAPER_CTRL_0, 0x68c */
|
|
||||||
uint32_t emc_pllc_shaper_ctrl; /* _EMC_PLLC_SHAPER_CTRL_0, 0x690 */
|
|
||||||
|
|
||||||
uint32_t clk_source_sdmmc_legacy_tm; /* _CLK_SOURCE_SDMMC_LEGACY_TM_0, 0x694 */
|
|
||||||
uint32_t clk_source_nvdec; /* _CLK_SOURCE_NVDEC_0, 0x698 */
|
|
||||||
uint32_t clk_source_nvjpg; /* _CLK_SOURCE_NVJPG_0, 0x69c */
|
|
||||||
uint32_t clk_source_nvenc; /* _CLK_SOURCE_NVENC_0, 0x6a0 */
|
|
||||||
|
|
||||||
uint32_t plla1_base; /* _PLLA1_BASE_0, 0x6a4 */
|
|
||||||
uint32_t plla1_misc0; /* _PLLA1_MISC_0_0, 0x6a8 */
|
|
||||||
uint32_t plla1_misc1; /* _PLLA1_MISC_1_0, 0x6ac */
|
|
||||||
uint32_t plla1_misc2; /* _PLLA1_MISC_2_0, 0x6b0 */
|
|
||||||
uint32_t plla1_misc3; /* _PLLA1_MISC_3_0, 0x6b4 */
|
|
||||||
uint32_t audio_sync_clk_dmic3; /* _AUDIO_SYNC_CLK_DMIC3_0, 0x6b8 */
|
|
||||||
|
|
||||||
uint32_t clk_source_dmic3; /* _CLK_SOURCE_DMIC3_0, 0x6bc */
|
|
||||||
uint32_t clk_source_ape; /* _CLK_SOURCE_APE_0, 0x6c0 */
|
|
||||||
uint32_t clk_source_qspi; /* _CLK_SOURCE_QSPI_0, 0x6c4 */
|
|
||||||
uint32_t clk_source_vi_i2c; /* _CLK_SOURCE_VI_I2C_0, 0x6c8 */
|
|
||||||
uint32_t clk_source_usb2_hsic_trk; /* _CLK_SOURCE_USB2_HSIC_TRK_0, 0x6cc */
|
|
||||||
uint32_t clk_source_pex_sata_usb_rx_byp; /* _CLK_SOURCE_PEX_SATA_USB_RX_BYP_0, 0x6d0 */
|
|
||||||
uint32_t clk_source_maud; /* _CLK_SOURCE_MAUD_0, 0x6d4 */
|
|
||||||
uint32_t clk_source_tsecb; /* _CLK_SOURCE_TSECB_0, 0x6d8 */
|
|
||||||
|
|
||||||
uint32_t clk_cpug_misc1; /* _CLK_CPUG_MISC1_0, 0x6dc */
|
|
||||||
uint32_t aclk_burst_policy; /* _ACLK_BURST_POLICY_0, 0x6e0 */
|
|
||||||
uint32_t super_aclk_divider; /* _SUPER_ACLK_DIVIDER_0, 0x6e4 */
|
|
||||||
|
|
||||||
uint32_t nvenc_super_clk_divider; /* _NVENC_SUPER_CLK_DIVIDER_0, 0x6e8 */
|
|
||||||
uint32_t vi_super_clk_divider; /* _VI_SUPER_CLK_DIVIDER_0, 0x6ec */
|
|
||||||
uint32_t vic_super_clk_divider; /* _VIC_SUPER_CLK_DIVIDER_0, 0x6f0 */
|
|
||||||
uint32_t nvdec_super_clk_divider; /* _NVDEC_SUPER_CLK_DIVIDER_0, 0x6f4 */
|
|
||||||
uint32_t isp_super_clk_divider; /* _ISP_SUPER_CLK_DIVIDER_0, 0x6f8 */
|
|
||||||
uint32_t ispb_super_clk_divider; /* _ISPB_SUPER_CLK_DIVIDER_0, 0x6fc */
|
|
||||||
uint32_t nvjpg_super_clk_divider; /* _NVJPG_SUPER_CLK_DIVIDER_0, 0x700 */
|
|
||||||
uint32_t se_super_clk_divider; /* _SE_SUPER_CLK_DIVIDER_0, 0x704 */
|
|
||||||
uint32_t tsec_super_clk_divider; /* _TSEC_SUPER_CLK_DIVIDER_0, 0x708 */
|
|
||||||
uint32_t tsecb_super_clk_divider; /* _TSECB_SUPER_CLK_DIVIDER_0, 0x70c */
|
|
||||||
|
|
||||||
uint32_t clk_source_uartape; /* _CLK_SOURCE_UARTAPE_0, 0x710 */
|
|
||||||
uint32_t clk_cpug_misc2; /* _CLK_CPUG_MISC2_0, 0x714 */
|
|
||||||
uint32_t clk_source_dbgapb; /* _CLK_SOURCE_DBGAPB_0, 0x718 */
|
|
||||||
uint32_t clk_ccplex_cc4_ret_clk_enb; /* _CLK_CCPLEX_CC4_RET_CLK_ENB_0, 0x71c */
|
|
||||||
uint32_t actmon_cpu_clk; /* _ACTMON_CPU_CLK_0, 0x720 */
|
|
||||||
uint32_t clk_source_emc_safe; /* _CLK_SOURCE_EMC_SAFE_0, 0x724 */
|
|
||||||
uint32_t sdmmc2_pllc4_out0_shaper_ctrl; /* _SDMMC2_PLLC4_OUT0_SHAPER_CTRL_0, 0x728 */
|
|
||||||
uint32_t sdmmc2_pllc4_out1_shaper_ctrl; /* _SDMMC2_PLLC4_OUT1_SHAPER_CTRL_0, 0x72c */
|
|
||||||
uint32_t sdmmc2_pllc4_out2_shaper_ctrl; /* _SDMMC2_PLLC4_OUT2_SHAPER_CTRL_0, 0x730 */
|
|
||||||
uint32_t sdmmc2_div_clk_shaper_ctrl; /* _SDMMC2_DIV_CLK_SHAPER_CTRL_0, 0x734 */
|
|
||||||
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
|
|
||||||
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
|
|
||||||
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
|
|
||||||
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
|
|
||||||
} tegra_car_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_car_t *car_get_regs(void) {
|
|
||||||
return (volatile tegra_car_t *)CAR_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clk_enable(CarDevice dev);
|
|
||||||
void clk_disable(CarDevice dev);
|
|
||||||
void rst_enable(CarDevice dev);
|
|
||||||
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
|
|
|
@ -1,350 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_DI_H_
|
|
||||||
#define FUSEE_DI_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define HOST1X_BASE 0x50000000
|
|
||||||
#define DI_BASE 0x54200000
|
|
||||||
#define DSI_BASE 0x54300000
|
|
||||||
#define VIC_BASE 0x54340000
|
|
||||||
#define MIPI_CAL_BASE 0x700E3000
|
|
||||||
#define MAKE_HOST1X_REG(n) MAKE_REG32(HOST1X_BASE + n)
|
|
||||||
#define MAKE_DI_REG(n) MAKE_REG32(DI_BASE + n * 4)
|
|
||||||
#define MAKE_DSI_REG(n) MAKE_REG32(DSI_BASE + n * 4)
|
|
||||||
#define MAKE_MIPI_CAL_REG(n) MAKE_REG32(MIPI_CAL_BASE + n)
|
|
||||||
#define MAKE_VIC_REG(n) MAKE_REG32(VIC_BASE + n)
|
|
||||||
|
|
||||||
/* Display registers. */
|
|
||||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
|
||||||
|
|
||||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
|
||||||
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
|
|
||||||
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
|
|
||||||
|
|
||||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
|
||||||
#define SYNCPT_VSYNC_ENABLE (1 << 8)
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_COMMAND 0x32
|
|
||||||
#define DISP_CTRL_MODE_STOP (0 << 5)
|
|
||||||
#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
|
|
||||||
#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
|
|
||||||
#define DISP_CTRL_MODE_MASK (3 << 5)
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
|
|
||||||
#define PW0_ENABLE (1 << 0)
|
|
||||||
#define PW1_ENABLE (1 << 2)
|
|
||||||
#define PW2_ENABLE (1 << 4)
|
|
||||||
#define PW3_ENABLE (1 << 6)
|
|
||||||
#define PW4_ENABLE (1 << 8)
|
|
||||||
#define PM0_ENABLE (1 << 16)
|
|
||||||
#define PM1_ENABLE (1 << 18)
|
|
||||||
|
|
||||||
#define DC_CMD_INT_MASK 0x38
|
|
||||||
#define DC_CMD_INT_ENABLE 0x39
|
|
||||||
|
|
||||||
#define DC_CMD_STATE_ACCESS 0x40
|
|
||||||
#define READ_MUX (1 << 0)
|
|
||||||
#define WRITE_MUX (1 << 2)
|
|
||||||
|
|
||||||
#define DC_CMD_STATE_CONTROL 0x41
|
|
||||||
#define GENERAL_ACT_REQ (1 << 0)
|
|
||||||
#define WIN_A_ACT_REQ (1 << 1)
|
|
||||||
#define WIN_B_ACT_REQ (1 << 2)
|
|
||||||
#define WIN_C_ACT_REQ (1 << 3)
|
|
||||||
#define CURSOR_ACT_REQ (1 << 7)
|
|
||||||
#define GENERAL_UPDATE (1 << 8)
|
|
||||||
#define WIN_A_UPDATE (1 << 9)
|
|
||||||
#define WIN_B_UPDATE (1 << 10)
|
|
||||||
#define WIN_C_UPDATE (1 << 11)
|
|
||||||
#define CURSOR_UPDATE (1 << 15)
|
|
||||||
#define NC_HOST_TRIG (1 << 24)
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
|
||||||
#define WINDOW_A_SELECT (1 << 4)
|
|
||||||
#define WINDOW_B_SELECT (1 << 5)
|
|
||||||
#define WINDOW_C_SELECT (1 << 6)
|
|
||||||
|
|
||||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
|
||||||
|
|
||||||
#define DC_COM_CRC_CONTROL 0x300
|
|
||||||
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
|
|
||||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
|
||||||
|
|
||||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_WIN_OPTIONS 0x402
|
|
||||||
#define HDMI_ENABLE (1 << 30)
|
|
||||||
#define DSI_ENABLE (1 << 29)
|
|
||||||
#define SOR1_TIMING_CYA (1 << 27)
|
|
||||||
#define SOR1_ENABLE (1 << 26)
|
|
||||||
#define SOR_ENABLE (1 << 25)
|
|
||||||
#define CURSOR_ENABLE (1 << 16)
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
|
||||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
|
||||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
|
||||||
#define DC_DISP_REF_TO_SYNC 0x406
|
|
||||||
#define DC_DISP_SYNC_WIDTH 0x407
|
|
||||||
#define DC_DISP_BACK_PORCH 0x408
|
|
||||||
#define DC_DISP_ACTIVE 0x409
|
|
||||||
#define DC_DISP_FRONT_PORCH 0x40A
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
|
|
||||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
|
|
||||||
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF2S (4 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF3S (5 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DFSPI (6 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
|
|
||||||
#define DISP_ALIGNMENT_MSB (0 << 8)
|
|
||||||
#define DISP_ALIGNMENT_LSB (1 << 8)
|
|
||||||
#define DISP_ORDER_RED_BLUE (0 << 9)
|
|
||||||
#define DISP_ORDER_BLUE_RED (1 << 9)
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
|
||||||
#define DITHER_CONTROL_MASK (3 << 8)
|
|
||||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
|
||||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
|
||||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
|
||||||
#define BASE_COLOR_SIZE_MASK (0xf << 0)
|
|
||||||
#define BASE_COLOR_SIZE_666 (0 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_111 (1 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_222 (2 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_333 (3 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_444 (4 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_555 (5 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_565 (6 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_332 (7 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
|
||||||
|
|
||||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
|
||||||
#define SC1_H_QUALIFIER_NONE (1 << 16)
|
|
||||||
#define SC0_H_QUALIFIER_NONE (1 << 0)
|
|
||||||
|
|
||||||
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
|
|
||||||
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
|
|
||||||
#define DE_SELECT_ACTIVE (1 << 0)
|
|
||||||
#define DE_SELECT_ACTIVE_IS (2 << 0)
|
|
||||||
#define DE_CONTROL_ONECLK (0 << 2)
|
|
||||||
#define DE_CONTROL_NORMAL (1 << 2)
|
|
||||||
#define DE_CONTROL_EARLY_EXT (2 << 2)
|
|
||||||
#define DE_CONTROL_EARLY (3 << 2)
|
|
||||||
#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
|
|
||||||
|
|
||||||
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
|
|
||||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
|
||||||
|
|
||||||
#define DC_WIN_CSC_YOF 0x611
|
|
||||||
#define DC_WIN_CSC_KYRGB 0x612
|
|
||||||
#define DC_WIN_CSC_KUR 0x613
|
|
||||||
#define DC_WIN_CSC_KVR 0x614
|
|
||||||
#define DC_WIN_CSC_KUG 0x615
|
|
||||||
#define DC_WIN_CSC_KVG 0x616
|
|
||||||
#define DC_WIN_CSC_KUB 0x617
|
|
||||||
#define DC_WIN_CSC_KVB 0x618
|
|
||||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
|
||||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
|
||||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
|
||||||
|
|
||||||
/* The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER). */
|
|
||||||
#define DC_WIN_WIN_OPTIONS 0x700
|
|
||||||
#define H_DIRECTION (1 << 0)
|
|
||||||
#define V_DIRECTION (1 << 2)
|
|
||||||
#define COLOR_EXPAND (1 << 6)
|
|
||||||
#define CSC_ENABLE (1 << 18)
|
|
||||||
#define WIN_ENABLE (1 << 30)
|
|
||||||
|
|
||||||
#define DC_WIN_COLOR_DEPTH 0x703
|
|
||||||
#define WIN_COLOR_DEPTH_P1 0x0
|
|
||||||
#define WIN_COLOR_DEPTH_P2 0x1
|
|
||||||
#define WIN_COLOR_DEPTH_P4 0x2
|
|
||||||
#define WIN_COLOR_DEPTH_P8 0x3
|
|
||||||
#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
|
|
||||||
#define WIN_COLOR_DEPTH_B5G5R5A 0x5
|
|
||||||
#define WIN_COLOR_DEPTH_B5G6R5 0x6
|
|
||||||
#define WIN_COLOR_DEPTH_AB5G5R5 0x7
|
|
||||||
#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
|
|
||||||
#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
|
|
||||||
#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
|
|
||||||
#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422 0x10
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422 0x11
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr420P 0x12
|
|
||||||
#define WIN_COLOR_DEPTH_YUV420P 0x13
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422P 0x14
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422P 0x15
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422R 0x16
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
|
||||||
|
|
||||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
|
||||||
#define DC_WIN_POSITION 0x704
|
|
||||||
|
|
||||||
#define DC_WIN_SIZE 0x705
|
|
||||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
|
||||||
#define V_SIZE(x) (((x) & 0x1fff) << 16)
|
|
||||||
|
|
||||||
#define DC_WIN_PRESCALED_SIZE 0x706
|
|
||||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
|
|
||||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
|
|
||||||
|
|
||||||
#define DC_WIN_H_INITIAL_DDA 0x707
|
|
||||||
#define DC_WIN_V_INITIAL_DDA 0x708
|
|
||||||
|
|
||||||
#define DC_WIN_DDA_INC 0x709
|
|
||||||
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
|
|
||||||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
|
||||||
|
|
||||||
#define DC_WIN_LINE_STRIDE 0x70A
|
|
||||||
#define DC_WIN_DV_CONTROL 0x70E
|
|
||||||
|
|
||||||
/* The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
|
|
||||||
#define DC_WINBUF_START_ADDR 0x800
|
|
||||||
#define DC_WINBUF_ADDR_H_OFFSET 0x806
|
|
||||||
#define DC_WINBUF_ADDR_V_OFFSET 0x808
|
|
||||||
#define DC_WINBUF_SURFACE_KIND 0x80B
|
|
||||||
|
|
||||||
/* Display serial interface registers. */
|
|
||||||
#define DSI_RD_DATA 0x9
|
|
||||||
#define DSI_WR_DATA 0xA
|
|
||||||
|
|
||||||
#define DSI_POWER_CONTROL 0xB
|
|
||||||
#define DSI_POWER_CONTROL_ENABLE 1
|
|
||||||
|
|
||||||
#define DSI_INT_ENABLE 0xC
|
|
||||||
#define DSI_INT_STATUS 0xD
|
|
||||||
#define DSI_INT_MASK 0xE
|
|
||||||
|
|
||||||
#define DSI_HOST_CONTROL 0xF
|
|
||||||
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
|
|
||||||
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
|
|
||||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
|
||||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
|
||||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
|
||||||
#define DSI_HOST_CONTROL_RAW (1 << 6)
|
|
||||||
#define DSI_HOST_CONTROL_HS (1 << 5)
|
|
||||||
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
|
|
||||||
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
|
|
||||||
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
|
|
||||||
#define DSI_HOST_CONTROL_CS (1 << 1)
|
|
||||||
#define DSI_HOST_CONTROL_ECC (1 << 0)
|
|
||||||
|
|
||||||
#define DSI_CONTROL 0x10
|
|
||||||
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
|
|
||||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
|
||||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
|
||||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
|
||||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
|
||||||
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
|
|
||||||
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
|
|
||||||
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
|
|
||||||
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
|
|
||||||
|
|
||||||
#define DSI_SOL_DELAY 0x11
|
|
||||||
#define DSI_MAX_THRESHOLD 0x12
|
|
||||||
|
|
||||||
#define DSI_TRIGGER 0x13
|
|
||||||
#define DSI_TRIGGER_HOST (1 << 1)
|
|
||||||
#define DSI_TRIGGER_VIDEO (1 << 0)
|
|
||||||
|
|
||||||
#define DSI_TX_CRC 0x14
|
|
||||||
#define DSI_STATUS 0x15
|
|
||||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
|
||||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
|
||||||
#define DSI_INIT_SEQ_DATA_1 0x1C
|
|
||||||
#define DSI_INIT_SEQ_DATA_2 0x1D
|
|
||||||
#define DSI_INIT_SEQ_DATA_3 0x1E
|
|
||||||
#define DSI_PKT_SEQ_0_LO 0x23
|
|
||||||
#define DSI_PKT_SEQ_0_HI 0x24
|
|
||||||
#define DSI_PKT_SEQ_1_LO 0x25
|
|
||||||
#define DSI_PKT_SEQ_1_HI 0x26
|
|
||||||
#define DSI_PKT_SEQ_2_LO 0x27
|
|
||||||
#define DSI_PKT_SEQ_2_HI 0x28
|
|
||||||
#define DSI_PKT_SEQ_3_LO 0x29
|
|
||||||
#define DSI_PKT_SEQ_3_HI 0x2A
|
|
||||||
#define DSI_PKT_SEQ_4_LO 0x2B
|
|
||||||
#define DSI_PKT_SEQ_4_HI 0x2C
|
|
||||||
#define DSI_PKT_SEQ_5_LO 0x2D
|
|
||||||
#define DSI_PKT_SEQ_5_HI 0x2E
|
|
||||||
#define DSI_DCS_CMDS 0x33
|
|
||||||
#define DSI_PKT_LEN_0_1 0x34
|
|
||||||
#define DSI_PKT_LEN_2_3 0x35
|
|
||||||
#define DSI_PKT_LEN_4_5 0x36
|
|
||||||
#define DSI_PKT_LEN_6_7 0x37
|
|
||||||
#define DSI_PHY_TIMING_0 0x3C
|
|
||||||
#define DSI_PHY_TIMING_1 0x3D
|
|
||||||
#define DSI_PHY_TIMING_2 0x3E
|
|
||||||
#define DSI_BTA_TIMING 0x3F
|
|
||||||
|
|
||||||
#define DSI_TIMEOUT_0 0x44
|
|
||||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
|
||||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
|
||||||
|
|
||||||
#define DSI_TIMEOUT_1 0x45
|
|
||||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
|
||||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
|
||||||
|
|
||||||
#define DSI_TO_TALLY 0x46
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_0 0x4B
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_CD 0x4c
|
|
||||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_1 0x4F
|
|
||||||
#define DSI_PAD_CONTROL_2 0x50
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_3 0x51
|
|
||||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
|
||||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
|
||||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
|
||||||
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_4 0x52
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,346 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <vapours/ams_version.h>
|
|
||||||
|
|
||||||
#include "car.h"
|
|
||||||
#include "fuse.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "timers.h"
|
|
||||||
|
|
||||||
/* 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(); */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable 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_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. */
|
|
||||||
void fuse_disable_power(void) {
|
|
||||||
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. */
|
|
||||||
static 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) {
|
|
||||||
ctrl_val = fuse->FUSE_FUSECTRL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_FUSEADDR = addr;
|
|
||||||
|
|
||||||
/* Enable read operation in control register. */
|
|
||||||
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
ctrl_val |= 0x1; /* Set READ command. */
|
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
|
||||||
|
|
||||||
/* Wait for idle state. */
|
|
||||||
fuse_wait_idle();
|
|
||||||
|
|
||||||
return fuse->FUSE_FUSERDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_FUSEADDR = addr;
|
|
||||||
fuse->FUSE_FUSEWDATA = value;
|
|
||||||
|
|
||||||
/* Enable write operation in control register. */
|
|
||||||
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
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 fuse 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_FUSECTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
|
||||||
|
|
||||||
/* Wait for idle state. */
|
|
||||||
fuse_wait_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the SKU info register. */
|
|
||||||
uint32_t fuse_get_sku_info(void) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
return fuse_chip->FUSE_SKU_INFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the bootrom patch version. */
|
|
||||||
uint32_t fuse_get_bootrom_patch_version(void) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a spare bit register. */
|
|
||||||
uint32_t fuse_get_spare_bit(uint32_t index) {
|
|
||||||
uint32_t soc_type = fuse_get_soc_type();
|
|
||||||
if (soc_type == 0) {
|
|
||||||
if (index < 32) {
|
|
||||||
volatile tegra_fuse_chip_erista_t *fuse_chip = fuse_chip_erista_get_regs();
|
|
||||||
return fuse_chip->FUSE_SPARE_BIT[index];
|
|
||||||
}
|
|
||||||
} else if (soc_type == 1) {
|
|
||||||
if (index < 30) {
|
|
||||||
volatile tegra_fuse_chip_mariko_t *fuse_chip = fuse_chip_mariko_get_regs();
|
|
||||||
return fuse_chip->FUSE_SPARE_BIT[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a reserved ODM register. */
|
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t index) {
|
|
||||||
if (index < 8) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM0[index];
|
|
||||||
} else {
|
|
||||||
uint32_t soc_type = fuse_get_soc_type();
|
|
||||||
if (soc_type == 1) {
|
|
||||||
volatile tegra_fuse_chip_mariko_t *fuse_chip = fuse_chip_mariko_get_regs();
|
|
||||||
if (index < 22) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM8[index - 8];
|
|
||||||
} else if (index < 25) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM22[index - 22];
|
|
||||||
} else if (index < 26) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM25;
|
|
||||||
} else if (index < 29) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM26[index - 26];
|
|
||||||
} else if (index < 30) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM29;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the DramId. */
|
|
||||||
uint32_t fuse_get_dram_id(void) {
|
|
||||||
return ((fuse_get_reserved_odm(4) >> 3) & 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the DeviceId. */
|
|
||||||
uint64_t fuse_get_device_id(void) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the HardwareType with firmware specific checks. */
|
|
||||||
uint32_t fuse_get_hardware_type_with_firmware_check(uint32_t target_firmware) {
|
|
||||||
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 (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
uint32_t fuse_spare_bit9 = (fuse_chip->FUSE_SPARE_BIT[9] & 1);
|
|
||||||
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x00: return (fuse_spare_bit9 == 0) ? 0 : 3;
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 1; /* HardwareType_Copper */
|
|
||||||
default: return 3; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
|
||||||
|
|
||||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 1; /* HardwareType_Copper */
|
|
||||||
case 0x04: return 3; /* HardwareType_Iowa */
|
|
||||||
default: return 4; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 4; /* HardwareType_Calcio */
|
|
||||||
case 0x04: return 3; /* HardwareType_Iowa */
|
|
||||||
case 0x08: return 2; /* HardwareType_Hoag */
|
|
||||||
default: return 0xF; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 4; /* HardwareType_Calcio */
|
|
||||||
case 0x04: return 3; /* HardwareType_Iowa */
|
|
||||||
case 0x08: return 2; /* HardwareType_Hoag */
|
|
||||||
case 0x10: return 5; /* HardwareType_Five */
|
|
||||||
default: return 0xF; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the HardwareType. */
|
|
||||||
uint32_t fuse_get_hardware_type(void) {
|
|
||||||
return fuse_get_hardware_type_with_firmware_check(ATMOSPHERE_TARGET_FIRMWARE_CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the HardwareState. */
|
|
||||||
uint32_t fuse_get_hardware_state(void) {
|
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
|
||||||
uint32_t hardware_state = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
|
|
||||||
|
|
||||||
switch (hardware_state) {
|
|
||||||
case 0x03: return 0; /* HardwareState_Development */
|
|
||||||
case 0x04: return 1; /* HardwareState_Production */
|
|
||||||
default: return 2; /* HardwareState_Undefined */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the 16-byte HardwareInfo and copy to output buffer. */
|
|
||||||
void fuse_get_hardware_info(void *dst) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
uint32_t hw_info[0x4];
|
|
||||||
|
|
||||||
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 = 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);
|
|
||||||
|
|
||||||
memcpy(dst, hw_info, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if have a new ODM fuse format. */
|
|
||||||
bool fuse_is_new_format(void) {
|
|
||||||
return ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the DeviceUniqueKeyGeneration. */
|
|
||||||
uint32_t fuse_get_device_unique_key_generation(void) {
|
|
||||||
if (fuse_is_new_format()) {
|
|
||||||
return (fuse_get_reserved_odm(2) & 0x1F);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the SocType from the HardwareType. */
|
|
||||||
uint32_t fuse_get_soc_type(void) {
|
|
||||||
switch (fuse_get_hardware_type()) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
return 0; /* SocType_Erista */
|
|
||||||
case 3:
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
return 1; /* SocType_Mariko */
|
|
||||||
default:
|
|
||||||
return 0xF; /* SocType_Undefined */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the Regulator type. */
|
|
||||||
uint32_t fuse_get_regulator(void) {
|
|
||||||
if (fuse_get_soc_type() == 1) {
|
|
||||||
return ((fuse_get_reserved_odm(28) & 1) + 1); /* Regulator_Mariko_Max77812_A or Regulator_Mariko_Max77812_B */
|
|
||||||
} else {
|
|
||||||
return 0; /* Regulator_Erista_Max77621 */
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,484 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
|
||||||
#define FUSEE_FUSE_H
|
|
||||||
|
|
||||||
#define FUSE_BASE 0x7000F800
|
|
||||||
#define FUSE_CHIP_BASE (FUSE_BASE + 0x98)
|
|
||||||
#define MAKE_FUSE_REG(n) MAKE_REG32(FUSE_BASE + n)
|
|
||||||
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
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_DISABLEREGPROGRAM;
|
|
||||||
uint32_t FUSE_WRITE_ACCESS_SW;
|
|
||||||
uint32_t FUSE_PWR_GOOD_SW;
|
|
||||||
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 _0x94;
|
|
||||||
} tegra_fuse_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t _0x98[0x1A];
|
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
|
||||||
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_CALIB;
|
|
||||||
uint32_t FUSE_CPU_IDDQ_CALIB;
|
|
||||||
uint32_t _0x11C[0x3];
|
|
||||||
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 _0x144;
|
|
||||||
uint32_t FUSE_FA;
|
|
||||||
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_TSENSOR1_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR2_CALIB;
|
|
||||||
uint32_t _0x18C;
|
|
||||||
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[0x5];
|
|
||||||
uint32_t FUSE_ARM_JTAG_DIS;
|
|
||||||
uint32_t FUSE_BOOT_DEVICE_INFO;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
|
||||||
uint32_t FUSE_OPT_VP9_DISABLE;
|
|
||||||
uint32_t FUSE_RESERVED_ODM0[0x8];
|
|
||||||
uint32_t FUSE_OBS_DIS;
|
|
||||||
uint32_t _0x1EC;
|
|
||||||
uint32_t FUSE_USB_CALIB;
|
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
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 _0x224;
|
|
||||||
uint32_t FUSE_GPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR3_CALIB;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT0;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT1;
|
|
||||||
uint32_t _0x238[0x3];
|
|
||||||
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
|
||||||
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 _0x268[0x5];
|
|
||||||
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
|
||||||
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 _0x294;
|
|
||||||
uint32_t FUSE_APB2JTAG_DISABLE;
|
|
||||||
uint32_t FUSE_ODM_INFO;
|
|
||||||
uint32_t _0x2A0[0x2];
|
|
||||||
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
uint32_t _0x2AC[0x5];
|
|
||||||
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 _0x2D8;
|
|
||||||
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 _0x2FC[0x2];
|
|
||||||
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 _0x324[0x5];
|
|
||||||
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 FUSE_RESERVED_FIELD;
|
|
||||||
uint32_t _0x358[0x9];
|
|
||||||
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
|
||||||
} tegra_fuse_chip_common_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t _0x98[0x1A];
|
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
|
||||||
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_CALIB;
|
|
||||||
uint32_t FUSE_CPU_IDDQ_CALIB;
|
|
||||||
uint32_t _0x11C[0x3];
|
|
||||||
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 _0x144;
|
|
||||||
uint32_t FUSE_FA;
|
|
||||||
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_TSENSOR1_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR2_CALIB;
|
|
||||||
uint32_t _0x18C;
|
|
||||||
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[0x5];
|
|
||||||
uint32_t FUSE_ARM_JTAG_DIS;
|
|
||||||
uint32_t FUSE_BOOT_DEVICE_INFO;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
|
||||||
uint32_t FUSE_OPT_VP9_DISABLE;
|
|
||||||
uint32_t FUSE_RESERVED_ODM0[0x8];
|
|
||||||
uint32_t FUSE_OBS_DIS;
|
|
||||||
uint32_t _0x1EC;
|
|
||||||
uint32_t FUSE_USB_CALIB;
|
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
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; /* Erista only. */
|
|
||||||
uint32_t FUSE_GPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR3_CALIB;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT0;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT1;
|
|
||||||
uint32_t _0x238[0x3];
|
|
||||||
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
|
||||||
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; /* Erista only. */
|
|
||||||
uint32_t _0x26C[0x4];
|
|
||||||
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
|
||||||
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 _0x294;
|
|
||||||
uint32_t FUSE_APB2JTAG_DISABLE;
|
|
||||||
uint32_t FUSE_ODM_INFO;
|
|
||||||
uint32_t _0x2A0[0x2];
|
|
||||||
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
uint32_t _0x2AC[0x5];
|
|
||||||
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 _0x2D8;
|
|
||||||
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 _0x2FC[0x2];
|
|
||||||
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; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_PDP; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_REG; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_SP; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_SMPDP; /* Erista only. */
|
|
||||||
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 FUSE_RESERVED_FIELD;
|
|
||||||
uint32_t _0x358[0x9];
|
|
||||||
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
|
||||||
} tegra_fuse_chip_erista_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t FUSE_RESERVED_ODM8[0xE]; /* Mariko only. */
|
|
||||||
uint32_t FUSE_KEK[0x4]; /* Mariko only. */
|
|
||||||
uint32_t FUSE_BEK[0x4]; /* Mariko only. */
|
|
||||||
uint32_t _0xF0; /* Mariko only. */
|
|
||||||
uint32_t _0xF4; /* Mariko only. */
|
|
||||||
uint32_t _0xF8; /* Mariko only. */
|
|
||||||
uint32_t _0xFC; /* Mariko only. */
|
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
|
||||||
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_CALIB;
|
|
||||||
uint32_t FUSE_CPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_RESERVED_ODM22[0x3]; /* Mariko only. */
|
|
||||||
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_ODM25; /* Mariko only. */
|
|
||||||
uint32_t FUSE_FA;
|
|
||||||
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_TSENSOR1_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR2_CALIB;
|
|
||||||
uint32_t FUSE_OPT_SECURE_SCC_DIS; /* Mariko only. */
|
|
||||||
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[0x5];
|
|
||||||
uint32_t FUSE_ARM_JTAG_DIS;
|
|
||||||
uint32_t FUSE_BOOT_DEVICE_INFO;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
|
||||||
uint32_t FUSE_OPT_VP9_DISABLE;
|
|
||||||
uint32_t FUSE_RESERVED_ODM0[0x8];
|
|
||||||
uint32_t FUSE_OBS_DIS;
|
|
||||||
uint32_t _0x1EC; /* Mariko only. */
|
|
||||||
uint32_t FUSE_USB_CALIB;
|
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
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 _0x224; /* Mariko only. */
|
|
||||||
uint32_t FUSE_GPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR3_CALIB;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT0;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT1;
|
|
||||||
uint32_t FUSE_RESERVED_ODM26[0x3]; /* Mariko only. */
|
|
||||||
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
|
||||||
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_BOOT_SECURITY_INFO; /* Mariko only. */
|
|
||||||
uint32_t _0x26C; /* Mariko only. */
|
|
||||||
uint32_t _0x270; /* Mariko only. */
|
|
||||||
uint32_t _0x274; /* Mariko only. */
|
|
||||||
uint32_t _0x278; /* Mariko only. */
|
|
||||||
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
|
||||||
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 FUSE_RESERVED_ODM29; /* Mariko only. */
|
|
||||||
uint32_t FUSE_APB2JTAG_DISABLE;
|
|
||||||
uint32_t FUSE_ODM_INFO;
|
|
||||||
uint32_t _0x2A0[0x2];
|
|
||||||
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
uint32_t _0x2AC;
|
|
||||||
uint32_t _0x2B0; /* Mariko only. */
|
|
||||||
uint32_t _0x2B4; /* Mariko only. */
|
|
||||||
uint32_t _0x2B8; /* Mariko only. */
|
|
||||||
uint32_t _0x2BC; /* Mariko only. */
|
|
||||||
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 _0x2D8;
|
|
||||||
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 _0x2FC[0x2];
|
|
||||||
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 _0x324; /* Mariko only. */
|
|
||||||
uint32_t _0x328; /* Mariko only. */
|
|
||||||
uint32_t _0x32C; /* Mariko only. */
|
|
||||||
uint32_t _0x330; /* Mariko only. */
|
|
||||||
uint32_t _0x334; /* Mariko only. */
|
|
||||||
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 FUSE_RESERVED_FIELD;
|
|
||||||
uint32_t _0x358[0x9];
|
|
||||||
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
uint32_t FUSE_SPARE_BIT[0x1E];
|
|
||||||
} tegra_fuse_chip_mariko_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_t *fuse_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_t *)FUSE_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_common_t *fuse_chip_common_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_chip_common_t *)FUSE_CHIP_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_erista_t *fuse_chip_erista_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_chip_erista_t *)FUSE_CHIP_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_mariko_t *fuse_chip_mariko_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_chip_mariko_t *)FUSE_CHIP_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_init(void);
|
|
||||||
void fuse_disable_programming(void);
|
|
||||||
void fuse_disable_private_key(void);
|
|
||||||
void fuse_enable_power(void);
|
|
||||||
void fuse_disable_power(void);
|
|
||||||
|
|
||||||
uint32_t fuse_get_sku_info(void);
|
|
||||||
uint32_t fuse_get_spare_bit(uint32_t index);
|
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t index);
|
|
||||||
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_with_firmware_check(uint32_t target_firmware);
|
|
||||||
uint32_t fuse_get_hardware_type(void);
|
|
||||||
uint32_t fuse_get_retail_type(void);
|
|
||||||
void fuse_get_hardware_info(void *dst);
|
|
||||||
bool fuse_is_new_format(void);
|
|
||||||
uint32_t fuse_get_device_unique_key_generation(void);
|
|
||||||
uint32_t fuse_get_soc_type(void);
|
|
||||||
uint32_t fuse_get_regulator(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
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
/* Set GPIO's value. */
|
|
||||||
static void gpio_register_set(uint32_t pin, bool do_set, uint32_t offset) {
|
|
||||||
volatile tegra_gpio_t *gpio = gpio_get_regs();
|
|
||||||
|
|
||||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
|
||||||
volatile uint32_t *cluster = (uint32_t *)((uintptr_t)&gpio->bank[(pin >> GPIO_BANK_SHIFT)] + offset);
|
|
||||||
|
|
||||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
|
||||||
uint32_t port = ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
|
|
||||||
uint32_t mask = (1 << (pin & GPIO_PIN_MASK));
|
|
||||||
|
|
||||||
/* Set or clear the bit, as appropriate. */
|
|
||||||
if (do_set)
|
|
||||||
cluster[port] |= mask;
|
|
||||||
else
|
|
||||||
cluster[port] &= ~mask;
|
|
||||||
|
|
||||||
/* Dummy read. */
|
|
||||||
cluster[port];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get GPIO's value. */
|
|
||||||
static bool gpio_register_get(uint32_t pin, uint32_t offset) {
|
|
||||||
volatile tegra_gpio_t *gpio = gpio_get_regs();
|
|
||||||
|
|
||||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
|
||||||
volatile uint32_t *cluster = (uint32_t *)((uintptr_t)&gpio->bank[(pin >> GPIO_BANK_SHIFT)] + offset);
|
|
||||||
|
|
||||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
|
||||||
uint32_t port = ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
|
|
||||||
uint32_t mask = (1 << (pin & GPIO_PIN_MASK));
|
|
||||||
|
|
||||||
/* Convert the given value to a boolean. */
|
|
||||||
return !!(cluster[port] & mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure GPIO's mode. */
|
|
||||||
void gpio_configure_mode(uint32_t pin, uint32_t mode) {
|
|
||||||
gpio_register_set(pin, mode == GPIO_MODE_GPIO, offsetof(tegra_gpio_bank_t, config));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure GPIO's direction. */
|
|
||||||
void gpio_configure_direction(uint32_t pin, uint32_t dir) {
|
|
||||||
gpio_register_set(pin, dir == GPIO_DIRECTION_OUTPUT, offsetof(tegra_gpio_bank_t, direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write to GPIO. */
|
|
||||||
void gpio_write(uint32_t pin, uint32_t value) {
|
|
||||||
gpio_register_set(pin, value == GPIO_LEVEL_HIGH, offsetof(tegra_gpio_bank_t, out));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read from GPIO. */
|
|
||||||
uint32_t gpio_read(uint32_t pin) {
|
|
||||||
return gpio_register_get(pin, offsetof(tegra_gpio_bank_t, in));
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_GPIO_H
|
|
||||||
#define FUSEE_GPIO_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define GPIO_BASE 0x6000D000
|
|
||||||
#define MAKE_GPIO_REG(n) MAKE_REG32(GPIO_BASE + n)
|
|
||||||
|
|
||||||
#define TEGRA_GPIO_PORTS 4
|
|
||||||
#define TEGRA_GPIO_BANKS 8
|
|
||||||
#define GPIO_BANK_SHIFT 5
|
|
||||||
#define GPIO_PORT_SHIFT 3
|
|
||||||
#define GPIO_PORT_MASK 0x03
|
|
||||||
#define GPIO_PIN_MASK 0x07
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
TEGRA_GPIO_PORT_A = 0,
|
|
||||||
TEGRA_GPIO_PORT_B = 1,
|
|
||||||
TEGRA_GPIO_PORT_C = 2,
|
|
||||||
TEGRA_GPIO_PORT_D = 3,
|
|
||||||
TEGRA_GPIO_PORT_E = 4,
|
|
||||||
TEGRA_GPIO_PORT_F = 5,
|
|
||||||
TEGRA_GPIO_PORT_G = 6,
|
|
||||||
TEGRA_GPIO_PORT_H = 7,
|
|
||||||
TEGRA_GPIO_PORT_I = 8,
|
|
||||||
TEGRA_GPIO_PORT_J = 9,
|
|
||||||
TEGRA_GPIO_PORT_K = 10,
|
|
||||||
TEGRA_GPIO_PORT_L = 11,
|
|
||||||
TEGRA_GPIO_PORT_M = 12,
|
|
||||||
TEGRA_GPIO_PORT_N = 13,
|
|
||||||
TEGRA_GPIO_PORT_O = 14,
|
|
||||||
TEGRA_GPIO_PORT_P = 15,
|
|
||||||
TEGRA_GPIO_PORT_Q = 16,
|
|
||||||
TEGRA_GPIO_PORT_R = 17,
|
|
||||||
TEGRA_GPIO_PORT_S = 18,
|
|
||||||
TEGRA_GPIO_PORT_T = 19,
|
|
||||||
TEGRA_GPIO_PORT_U = 20,
|
|
||||||
TEGRA_GPIO_PORT_V = 21,
|
|
||||||
TEGRA_GPIO_PORT_W = 22,
|
|
||||||
TEGRA_GPIO_PORT_X = 23,
|
|
||||||
TEGRA_GPIO_PORT_Y = 24,
|
|
||||||
TEGRA_GPIO_PORT_Z = 25,
|
|
||||||
TEGRA_GPIO_PORT_AA = 26,
|
|
||||||
TEGRA_GPIO_PORT_BB = 27,
|
|
||||||
TEGRA_GPIO_PORT_CC = 28,
|
|
||||||
TEGRA_GPIO_PORT_DD = 29,
|
|
||||||
TEGRA_GPIO_PORT_EE = 30,
|
|
||||||
TEGRA_GPIO_PORT_FF = 31,
|
|
||||||
} tegra_gpio_port;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t config[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t direction[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t out[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t in[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_status[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_enable[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_level[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_clear[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_config[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_dir_out[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_out[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_in[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_status[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_enable[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_level[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_clear[TEGRA_GPIO_PORTS];
|
|
||||||
} tegra_gpio_bank_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
tegra_gpio_bank_t bank[TEGRA_GPIO_BANKS];
|
|
||||||
} tegra_gpio_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_gpio_t *gpio_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_gpio_t *)GPIO_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TEGRA_GPIO(port, offset) \
|
|
||||||
((TEGRA_GPIO_PORT_##port * 8) + offset)
|
|
||||||
|
|
||||||
/* Mode select */
|
|
||||||
#define GPIO_MODE_SFIO 0
|
|
||||||
#define GPIO_MODE_GPIO 1
|
|
||||||
|
|
||||||
/* Direction */
|
|
||||||
#define GPIO_DIRECTION_INPUT 0
|
|
||||||
#define GPIO_DIRECTION_OUTPUT 1
|
|
||||||
|
|
||||||
/* Level */
|
|
||||||
#define GPIO_LEVEL_LOW 0
|
|
||||||
#define GPIO_LEVEL_HIGH 1
|
|
||||||
|
|
||||||
/* Named GPIOs */
|
|
||||||
#define GPIO_BUTTON_VOL_DOWN TEGRA_GPIO(X, 7)
|
|
||||||
#define GPIO_BUTTON_VOL_UP TEGRA_GPIO(X, 6)
|
|
||||||
#define GPIO_MICROSD_CARD_DETECT TEGRA_GPIO(Z, 1)
|
|
||||||
#define GPIO_MICROSD_WRITE_PROTECT TEGRA_GPIO(Z, 4)
|
|
||||||
#define GPIO_MICROSD_SUPPLY_ENABLE TEGRA_GPIO(E, 4)
|
|
||||||
#define GPIO_LCD_BL_P5V TEGRA_GPIO(I, 0)
|
|
||||||
#define GPIO_LCD_BL_N5V TEGRA_GPIO(I, 1)
|
|
||||||
#define GPIO_LCD_BL_PWM TEGRA_GPIO(V, 0)
|
|
||||||
#define GPIO_LCD_BL_EN TEGRA_GPIO(V, 1)
|
|
||||||
#define GPIO_LCD_BL_RST TEGRA_GPIO(V, 2)
|
|
||||||
|
|
||||||
void gpio_configure_mode(uint32_t pin, uint32_t mode);
|
|
||||||
void gpio_configure_direction(uint32_t pin, uint32_t dir);
|
|
||||||
void gpio_write(uint32_t pin, uint32_t value);
|
|
||||||
uint32_t gpio_read(uint32_t pin);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,252 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "pinmux.h"
|
|
||||||
|
|
||||||
/* Prototypes for internal commands. */
|
|
||||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
|
|
||||||
void i2c_load_config(volatile tegra_i2c_t *regs);
|
|
||||||
|
|
||||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
|
||||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
|
||||||
|
|
||||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
|
|
||||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
|
|
||||||
|
|
||||||
/* Configure I2C pinmux. */
|
|
||||||
void i2c_config(I2CDevice id) {
|
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
|
||||||
|
|
||||||
switch (id) {
|
|
||||||
case I2C_1:
|
|
||||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->gen1_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_2:
|
|
||||||
pinmux->gen2_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->gen2_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_3:
|
|
||||||
pinmux->gen3_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->gen3_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_4:
|
|
||||||
pinmux->cam_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->cam_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_5:
|
|
||||||
pinmux->pwr_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->pwr_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_6:
|
|
||||||
/* Unused. */
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize I2C based on registers. */
|
|
||||||
void i2c_init(I2CDevice id) {
|
|
||||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
|
||||||
|
|
||||||
/* Setup divisor, and clear the bus. */
|
|
||||||
regs->I2C_I2C_CLK_DIVISOR_REGISTER_0 = 0x50001;
|
|
||||||
regs->I2C_I2C_BUS_CLEAR_CONFIG_0 = 0x90003;
|
|
||||||
|
|
||||||
/* Load hardware configuration. */
|
|
||||||
i2c_load_config(regs);
|
|
||||||
|
|
||||||
/* Wait a while until BUS_CLEAR_DONE is set. */
|
|
||||||
for (unsigned int i = 0; i < 10; i++) {
|
|
||||||
udelay(20000);
|
|
||||||
if (regs->I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the BUS_CLEAR_STATUS. Result doesn't matter. */
|
|
||||||
regs->I2C_I2C_BUS_CLEAR_STATUS_0;
|
|
||||||
|
|
||||||
/* Read and set the Interrupt Status. */
|
|
||||||
uint32_t int_status = regs->I2C_INTERRUPT_STATUS_REGISTER_0;
|
|
||||||
regs->I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
|
|
||||||
void i2c_send_pmic_cpu_shutdown_cmd(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* PMIC == Device 4:3C. */
|
|
||||||
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
|
|
||||||
val |= 4;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Queries the value of TI charger bit over I2C. */
|
|
||||||
bool i2c_query_ti_charger_bit_7(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* TI Charger = Device 0:6B. */
|
|
||||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
return (val & 0x80) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clears TI charger bit over I2C. */
|
|
||||||
void i2c_clear_ti_charger_bit_7(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* TI Charger = Device 0:6B. */
|
|
||||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
val &= 0x7F;
|
|
||||||
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets TI charger bit over I2C. */
|
|
||||||
void i2c_set_ti_charger_bit_7(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* TI Charger = Device 0:6B. */
|
|
||||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
val |= 0x80;
|
|
||||||
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get registers pointer based on I2C ID. */
|
|
||||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
|
|
||||||
switch (id) {
|
|
||||||
case I2C_1:
|
|
||||||
return I2C1_REGS;
|
|
||||||
case I2C_2:
|
|
||||||
return I2C2_REGS;
|
|
||||||
case I2C_3:
|
|
||||||
return I2C3_REGS;
|
|
||||||
case I2C_4:
|
|
||||||
return I2C4_REGS;
|
|
||||||
case I2C_5:
|
|
||||||
return I2C5_REGS;
|
|
||||||
case I2C_6:
|
|
||||||
return I2C6_REGS;
|
|
||||||
default:
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load hardware config for I2C4. */
|
|
||||||
void i2c_load_config(volatile tegra_i2c_t *regs) {
|
|
||||||
/* Set MSTR_CONFIG_LOAD, TIMEOUT_CONFIG_LOAD, undocumented bit. */
|
|
||||||
regs->I2C_I2C_CONFIG_LOAD_0 = 0x25;
|
|
||||||
|
|
||||||
/* Wait a bit for master config to be loaded. */
|
|
||||||
for (unsigned int i = 0; i < 20; i++) {
|
|
||||||
udelay(1);
|
|
||||||
if (!(regs->I2C_I2C_CONFIG_LOAD_0 & 1)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reads a register from a device over I2C, writes result to output. */
|
|
||||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
|
||||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
|
||||||
uint32_t val = r;
|
|
||||||
|
|
||||||
/* Write single byte register ID to device. */
|
|
||||||
if (!i2c_write(regs, device, &val, 1)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* Limit output size to 32-bits. */
|
|
||||||
if (dst_size > 4) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i2c_read(regs, device, dst, dst_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Writes a value to a register over I2C. */
|
|
||||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
|
||||||
uint32_t val = r;
|
|
||||||
if (src_size == 0) {
|
|
||||||
return true;
|
|
||||||
} else if (src_size <= 3) {
|
|
||||||
memcpy(((uint8_t *)&val) + 1, src, src_size);
|
|
||||||
return i2c_write(i2c_get_registers_from_id(id), device, &val, src_size + 1);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Writes bytes to device over I2C. */
|
|
||||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size) {
|
|
||||||
if (src_size > 4) {
|
|
||||||
return false;
|
|
||||||
} else if (src_size == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set device for 7-bit write mode. */
|
|
||||||
regs->I2C_I2C_CMD_ADDR0_0 = device << 1;
|
|
||||||
|
|
||||||
/* Load in data to write. */
|
|
||||||
regs->I2C_I2C_CMD_DATA1_0 = read32le(src, 0);
|
|
||||||
|
|
||||||
/* Set config with LENGTH = src_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((src_size << 1) - 2) | 0x2800;
|
|
||||||
|
|
||||||
i2c_load_config(regs);
|
|
||||||
|
|
||||||
/* Config |= SEND; */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
|
|
||||||
|
|
||||||
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
|
||||||
/* Wait until not busy. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return CMD1_STAT == SL1_XFER_SUCCESSFUL. */
|
|
||||||
return (regs->I2C_I2C_STATUS_0 & 0xF) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reads bytes from device over I2C. */
|
|
||||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size) {
|
|
||||||
if (dst_size > 4) {
|
|
||||||
return false;
|
|
||||||
} else if (dst_size == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set device for 7-bit read mode. */
|
|
||||||
regs->I2C_I2C_CMD_ADDR0_0 = (device << 1) | 1;
|
|
||||||
|
|
||||||
/* Set config with LENGTH = dst_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((dst_size << 1) - 2) | 0x2840;
|
|
||||||
|
|
||||||
i2c_load_config(regs);
|
|
||||||
|
|
||||||
/* Config |= SEND; */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
|
|
||||||
|
|
||||||
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
|
||||||
/* Wait until not busy. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure success. */
|
|
||||||
if ((regs->I2C_I2C_STATUS_0 & 0xF) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t val = regs->I2C_I2C_CMD_DATA1_0;
|
|
||||||
memcpy(dst, &val, dst_size);
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_I2C_H
|
|
||||||
#define FUSEE_I2C_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define I2C1234_BASE 0x7000C000
|
|
||||||
#define I2C56_BASE 0x7000D000
|
|
||||||
|
|
||||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
|
||||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
|
||||||
#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31
|
|
||||||
#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33
|
|
||||||
#define MAX17050_I2C_ADDR 0x36
|
|
||||||
#define MAX77620_PWR_I2C_ADDR 0x3C
|
|
||||||
#define MAX77620_RTC_I2C_ADDR 0x68
|
|
||||||
#define BQ24193_I2C_ADDR 0x6B
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
I2C_1 = 0,
|
|
||||||
I2C_2 = 1,
|
|
||||||
I2C_3 = 2,
|
|
||||||
I2C_4 = 3,
|
|
||||||
I2C_5 = 4,
|
|
||||||
I2C_6 = 5,
|
|
||||||
} I2CDevice;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t I2C_I2C_CNFG_0;
|
|
||||||
uint32_t I2C_I2C_CMD_ADDR0_0;
|
|
||||||
uint32_t I2C_I2C_CMD_ADDR1_0;
|
|
||||||
uint32_t I2C_I2C_CMD_DATA1_0;
|
|
||||||
uint32_t I2C_I2C_CMD_DATA2_0;
|
|
||||||
uint32_t _0x14;
|
|
||||||
uint32_t _0x18;
|
|
||||||
uint32_t I2C_I2C_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_SL_CNFG_0;
|
|
||||||
uint32_t I2C_I2C_SL_RCVD_0;
|
|
||||||
uint32_t I2C_I2C_SL_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_SL_ADDR1_0;
|
|
||||||
uint32_t I2C_I2C_SL_ADDR2_0;
|
|
||||||
uint32_t I2C_I2C_TLOW_SEXT_0;
|
|
||||||
uint32_t _0x38;
|
|
||||||
uint32_t I2C_I2C_SL_DELAY_COUNT_0;
|
|
||||||
uint32_t I2C_I2C_SL_INT_MASK_0;
|
|
||||||
uint32_t I2C_I2C_SL_INT_SOURCE_0;
|
|
||||||
uint32_t I2C_I2C_SL_INT_SET_0;
|
|
||||||
uint32_t _0x4C;
|
|
||||||
uint32_t I2C_I2C_TX_PACKET_FIFO_0;
|
|
||||||
uint32_t I2C_I2C_RX_FIFO_0;
|
|
||||||
uint32_t I2C_PACKET_TRANSFER_STATUS_0;
|
|
||||||
uint32_t I2C_FIFO_CONTROL_0;
|
|
||||||
uint32_t I2C_FIFO_STATUS_0;
|
|
||||||
uint32_t I2C_INTERRUPT_MASK_REGISTER_0;
|
|
||||||
uint32_t I2C_INTERRUPT_STATUS_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_CLK_DIVISOR_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_INTERRUPT_SOURCE_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_INTERRUPT_SET_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_SLV_TX_PACKET_FIFO_0;
|
|
||||||
uint32_t I2C_I2C_SLV_RX_FIFO_0;
|
|
||||||
uint32_t I2C_I2C_SLV_PACKET_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_BUS_CLEAR_CONFIG_0;
|
|
||||||
uint32_t I2C_I2C_BUS_CLEAR_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_CONFIG_LOAD_0;
|
|
||||||
uint32_t _0x90;
|
|
||||||
uint32_t I2C_I2C_INTERFACE_TIMING_0_0;
|
|
||||||
uint32_t I2C_I2C_INTERFACE_TIMING_1_0;
|
|
||||||
uint32_t I2C_I2C_HS_INTERFACE_TIMING_0_0;
|
|
||||||
uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0;
|
|
||||||
} tegra_i2c_t;
|
|
||||||
|
|
||||||
#define I2C1_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x000))
|
|
||||||
#define I2C2_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x400))
|
|
||||||
#define I2C3_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x500))
|
|
||||||
#define I2C4_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x700))
|
|
||||||
#define I2C5_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x000))
|
|
||||||
#define I2C6_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x100))
|
|
||||||
|
|
||||||
void i2c_config(I2CDevice id);
|
|
||||||
|
|
||||||
void i2c_init(I2CDevice id);
|
|
||||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
|
||||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
|
||||||
|
|
||||||
void i2c_send_pmic_cpu_shutdown_cmd(void);
|
|
||||||
bool i2c_query_ti_charger_bit_7(void);
|
|
||||||
void i2c_clear_ti_charger_bit_7(void);
|
|
||||||
void i2c_set_ti_charger_bit_7(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,257 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "utils.h"
|
|
||||||
#include "car.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "di.h"
|
|
||||||
#include "se.h"
|
|
||||||
#include "fuse.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "mc.h"
|
|
||||||
#include "sysreg.h"
|
|
||||||
#include "tsec.h"
|
|
||||||
|
|
||||||
#define I2S_BASE 0x702D1000
|
|
||||||
#define MAKE_I2S_REG(n) MAKE_REG32(I2S_BASE + n)
|
|
||||||
|
|
||||||
static void setup_exception_vectors(void) {
|
|
||||||
for (unsigned int i = 0; i < 0x20; i += 4) {
|
|
||||||
MAKE_REG32(0x6000F200u + i) = (uint32_t)generic_panic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbist_workaround(void)
|
|
||||||
{
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
|
|
||||||
car->clk_source_sor1 = ((car->clk_source_sor1 | 0x8000) & 0xFFFFBFFF);
|
|
||||||
car->plld_base |= 0x40800000u;
|
|
||||||
car->rst_dev_y_clr = 0x40;
|
|
||||||
car->rst_dev_x_clr = 0x40000;
|
|
||||||
car->rst_dev_l_clr = 0x18000000;
|
|
||||||
udelay(3);
|
|
||||||
|
|
||||||
/* Setup I2S. */
|
|
||||||
MAKE_I2S_REG(0x0A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x088) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x1A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x188) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x2A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x288) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x3A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x388) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x4A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x488) &= 0xFFFFFFFE;
|
|
||||||
|
|
||||||
MAKE_DI_REG(DC_COM_DSC_TOP_CTL) |= 4;
|
|
||||||
MAKE_VIC_REG(0x8C) = 0xFFFFFFFF;
|
|
||||||
udelay(3);
|
|
||||||
|
|
||||||
/* Set devices in reset. */
|
|
||||||
car->rst_dev_y_set = 0x40;
|
|
||||||
car->rst_dev_l_set = 0x18000000;
|
|
||||||
car->rst_dev_x_set = 0x40000;
|
|
||||||
|
|
||||||
/* Clock out enables. */
|
|
||||||
car->clk_out_enb_h = 0xC0;
|
|
||||||
car->clk_out_enb_l = 0x80000130;
|
|
||||||
car->clk_out_enb_u = 0x1F00200;
|
|
||||||
car->clk_out_enb_v = 0x80400808;
|
|
||||||
car->clk_out_enb_w = 0x402000FC;
|
|
||||||
car->clk_out_enb_x = 0x23000780;
|
|
||||||
car->clk_out_enb_y = 0x300;
|
|
||||||
|
|
||||||
/* LVL2 clock gate overrides. */
|
|
||||||
car->lvl2_clk_gate_ovra = 0;
|
|
||||||
car->lvl2_clk_gate_ovrb = 0;
|
|
||||||
car->lvl2_clk_gate_ovrc = 0;
|
|
||||||
car->lvl2_clk_gate_ovrd = 0;
|
|
||||||
car->lvl2_clk_gate_ovre = 0;
|
|
||||||
|
|
||||||
/* Configure clock sources. */
|
|
||||||
car->plld_base &= 0x1F7FFFFF;
|
|
||||||
car->clk_source_sor1 &= 0xFFFF3FFF;
|
|
||||||
car->clk_source_vi = ((car->clk_source_vi & 0x1FFFFFFF) | 0x80000000);
|
|
||||||
car->clk_source_host1x = ((car->clk_source_host1x & 0x1FFFFFFF) | 0x80000000);
|
|
||||||
car->clk_source_nvenc = ((car->clk_source_nvenc & 0x1FFFFFFF) | 0x80000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tsec_dma_wait_idle()
|
|
||||||
{
|
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
|
||||||
uint32_t timeout = (get_time_ms() + 10000);
|
|
||||||
|
|
||||||
while (!(tsec->TSEC_FALCON_DMATRFCMD & 2))
|
|
||||||
{
|
|
||||||
if (get_time_ms() > timeout)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t phys_offset)
|
|
||||||
{
|
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
|
||||||
uint32_t cmd = 0;
|
|
||||||
|
|
||||||
if (!is_imem)
|
|
||||||
cmd = 0x600;
|
|
||||||
else
|
|
||||||
cmd = 0x10;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
|
||||||
|
|
||||||
/* Enable clocks. */
|
|
||||||
clkrst_reboot(CARDEVICE_HOST1X);
|
|
||||||
clkrst_reboot(CARDEVICE_TSEC);
|
|
||||||
clkrst_reboot(CARDEVICE_SOR_SAFE);
|
|
||||||
clkrst_reboot(CARDEVICE_SOR0);
|
|
||||||
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->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. */
|
|
||||||
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 -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load firmware. */
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
/* 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 -3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write magic value to HOST1X scratch register. */
|
|
||||||
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
|
|
||||||
|
|
||||||
/* Execute firmware. */
|
|
||||||
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();
|
|
||||||
|
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
|
|
||||||
/* Clear the boot reason to avoid problems later */
|
|
||||||
pmc->scratch200 = 0;
|
|
||||||
pmc->rst_status = 0;
|
|
||||||
|
|
||||||
//AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F;
|
|
||||||
//pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD);
|
|
||||||
|
|
||||||
/* Apply the memory built-in self test workaround. */
|
|
||||||
mbist_workaround();
|
|
||||||
|
|
||||||
/* Reboot SE. */
|
|
||||||
clkrst_reboot(CARDEVICE_SE);
|
|
||||||
|
|
||||||
/* Initialize the fuse driver. */
|
|
||||||
fuse_init();
|
|
||||||
|
|
||||||
/* Don't bother checking SKU, fuses, or bootloader version. */
|
|
||||||
mc_enable_for_tsec();
|
|
||||||
|
|
||||||
/* 7.0.0 package1ldr holds I2C5 in reset, clears SYS clock. */
|
|
||||||
car->clk_source_sys = 0;
|
|
||||||
rst_enable(CARDEVICE_I2C5);
|
|
||||||
|
|
||||||
load_tsec_fw();
|
|
||||||
|
|
||||||
while (true) { }
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mc.h"
|
|
||||||
#include "car.h"
|
|
||||||
#include "timers.h"
|
|
||||||
|
|
||||||
void mc_enable_for_tsec()
|
|
||||||
{
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
|
|
||||||
/* Set EMC clock source. */
|
|
||||||
car->clk_source_emc = ((car->clk_source_emc & 0x1FFFFFFF) | 0x40000000);
|
|
||||||
|
|
||||||
/* Enable MIPI CAL clock. */
|
|
||||||
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFDFFFFFF) | 0x2000000);
|
|
||||||
|
|
||||||
/* Enable MC clock. */
|
|
||||||
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFFFFFFFE) | 1);
|
|
||||||
|
|
||||||
/* Enable EMC DLL clock. */
|
|
||||||
car->clk_enb_x_set = ((car->clk_enb_x_set & 0xFFFFBFFF) | 0x4000);
|
|
||||||
|
|
||||||
/* Clear EMC and MC reset. */
|
|
||||||
/* NOTE: [4.0.0+] This was changed to use the right register. */
|
|
||||||
/* car->rst_dev_h_set = 0x2000001; */
|
|
||||||
car->rst_dev_h_clr = 0x2000001;
|
|
||||||
udelay(5);
|
|
||||||
|
|
||||||
/* Enable AHB redirect, weird boundaries for new TSEC firmware. */
|
|
||||||
car->lvl2_clk_gate_ovrd = ((car->lvl2_clk_gate_ovrd & 0xFFF7FFFF) | 0x80000);
|
|
||||||
|
|
||||||
MAKE_MC_REG(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
|
|
||||||
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
|
|
||||||
MAKE_MC_REG(MC_IRAM_TOM) = 0x80000000;
|
|
||||||
}
|
|
|
@ -1,601 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_MC_H_
|
|
||||||
#define FUSEE_MC_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define MC_BASE 0x70019000
|
|
||||||
#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
|
|
||||||
|
|
||||||
#define MC_INTSTATUS 0x0
|
|
||||||
#define MC_INTMASK 0x4
|
|
||||||
#define MC_ERR_STATUS 0x8
|
|
||||||
#define MC_ERR_ADR 0xc
|
|
||||||
#define MC_SMMU_CONFIG 0x10
|
|
||||||
#define MC_SMMU_TLB_CONFIG 0x14
|
|
||||||
#define MC_SMMU_PTC_CONFIG 0x18
|
|
||||||
#define MC_SMMU_PTB_ASID 0x1c
|
|
||||||
#define MC_SMMU_PTB_DATA 0x20
|
|
||||||
#define MC_SMMU_TLB_FLUSH 0x30
|
|
||||||
#define MC_SMMU_PTC_FLUSH 0x34
|
|
||||||
#define MC_SMMU_ASID_SECURITY 0x38
|
|
||||||
#define MC_SMMU_ASID_SECURITY_1 0x3c
|
|
||||||
#define MC_SMMU_ASID_SECURITY_2 0x9e0
|
|
||||||
#define MC_SMMU_ASID_SECURITY_3 0x9e4
|
|
||||||
#define MC_SMMU_ASID_SECURITY_4 0x9e8
|
|
||||||
#define MC_SMMU_ASID_SECURITY_5 0x9ec
|
|
||||||
#define MC_SMMU_ASID_SECURITY_6 0x9f0
|
|
||||||
#define MC_SMMU_ASID_SECURITY_7 0x9f4
|
|
||||||
#define MC_SMMU_AFI_ASID 0x238
|
|
||||||
#define MC_SMMU_AVPC_ASID 0x23c
|
|
||||||
#define MC_SMMU_TSEC_ASID 0x294
|
|
||||||
#define MC_SMMU_PPCS1_ASID 0x298
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
|
||||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
|
|
||||||
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
|
|
||||||
#define MC_EMEM_CFG 0x50
|
|
||||||
#define MC_EMEM_ADR_CFG 0x54
|
|
||||||
#define MC_EMEM_ADR_CFG_DEV0 0x58
|
|
||||||
#define MC_EMEM_ADR_CFG_DEV1 0x5c
|
|
||||||
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
|
|
||||||
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
|
|
||||||
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
|
|
||||||
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
|
|
||||||
#define MC_SECURITY_CFG0 0x70
|
|
||||||
#define MC_SECURITY_CFG1 0x74
|
|
||||||
#define MC_SECURITY_CFG3 0x9bc
|
|
||||||
#define MC_SECURITY_RSV 0x7c
|
|
||||||
#define MC_EMEM_ARB_CFG 0x90
|
|
||||||
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
|
|
||||||
#define MC_EMEM_ARB_TIMING_RCD 0x98
|
|
||||||
#define MC_EMEM_ARB_TIMING_RP 0x9c
|
|
||||||
#define MC_EMEM_ARB_TIMING_RC 0xa0
|
|
||||||
#define MC_EMEM_ARB_TIMING_RAS 0xa4
|
|
||||||
#define MC_EMEM_ARB_TIMING_FAW 0xa8
|
|
||||||
#define MC_EMEM_ARB_TIMING_RRD 0xac
|
|
||||||
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
|
|
||||||
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
|
|
||||||
#define MC_EMEM_ARB_TIMING_R2R 0xb8
|
|
||||||
#define MC_EMEM_ARB_TIMING_W2W 0xbc
|
|
||||||
#define MC_EMEM_ARB_TIMING_R2W 0xc0
|
|
||||||
#define MC_EMEM_ARB_TIMING_W2R 0xc4
|
|
||||||
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
|
|
||||||
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
|
|
||||||
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
|
|
||||||
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
|
|
||||||
#define MC_EMEM_ARB_DA_TURNS 0xd0
|
|
||||||
#define MC_EMEM_ARB_DA_COVERS 0xd4
|
|
||||||
#define MC_EMEM_ARB_MISC0 0xd8
|
|
||||||
#define MC_EMEM_ARB_MISC1 0xdc
|
|
||||||
#define MC_EMEM_ARB_MISC2 0xc8
|
|
||||||
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
|
|
||||||
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
|
|
||||||
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
|
|
||||||
#define MC_EMEM_ARB_OVERRIDE 0xe8
|
|
||||||
#define MC_EMEM_ARB_RSV 0xec
|
|
||||||
#define MC_CLKEN_OVERRIDE 0xf4
|
|
||||||
#define MC_TIMING_CONTROL_DBG 0xf8
|
|
||||||
#define MC_TIMING_CONTROL 0xfc
|
|
||||||
#define MC_STAT_CONTROL 0x100
|
|
||||||
#define MC_STAT_STATUS 0x104
|
|
||||||
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
|
|
||||||
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
|
|
||||||
#define MC_STAT_EMC_CLOCKS 0x110
|
|
||||||
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
|
|
||||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
|
|
||||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
|
|
||||||
#define MC_STAT_EMC_SET0_COUNT 0x138
|
|
||||||
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
|
|
||||||
#define MC_STAT_EMC_SET1_COUNT 0x178
|
|
||||||
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
|
|
||||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
|
|
||||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
|
|
||||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
|
|
||||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
|
|
||||||
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
|
|
||||||
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
|
|
||||||
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
|
|
||||||
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
|
|
||||||
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
|
|
||||||
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
|
|
||||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
|
|
||||||
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
|
|
||||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
|
|
||||||
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
|
|
||||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
|
|
||||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
|
|
||||||
#define MC_CLIENT_HOTRESET_CTRL 0x200
|
|
||||||
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
|
|
||||||
#define MC_CLIENT_HOTRESET_STATUS 0x204
|
|
||||||
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
|
|
||||||
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
|
|
||||||
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
|
|
||||||
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
|
|
||||||
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
|
|
||||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
|
|
||||||
#define MC_RESERVED_RSV 0x3fc
|
|
||||||
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
|
|
||||||
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
|
|
||||||
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
|
|
||||||
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
|
|
||||||
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
|
|
||||||
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
|
|
||||||
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
|
|
||||||
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
|
|
||||||
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
|
|
||||||
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
|
|
||||||
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
|
|
||||||
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
|
|
||||||
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
|
|
||||||
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
|
|
||||||
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
|
|
||||||
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
|
|
||||||
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
|
|
||||||
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
|
|
||||||
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
|
|
||||||
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
|
|
||||||
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
|
|
||||||
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
|
|
||||||
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
|
|
||||||
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
|
|
||||||
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
|
|
||||||
#define MC_VIDEO_PROTECT_BOM 0x648
|
|
||||||
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
|
|
||||||
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
|
|
||||||
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
|
|
||||||
#define MC_ERR_VPR_STATUS 0x654
|
|
||||||
#define MC_ERR_VPR_ADR 0x658
|
|
||||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
|
|
||||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
|
|
||||||
#define MC_IRAM_BOM 0x65c
|
|
||||||
#define MC_IRAM_TOM 0x660
|
|
||||||
#define MC_IRAM_ADR_HI 0x980
|
|
||||||
#define MC_IRAM_REG_CTRL 0x964
|
|
||||||
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
|
|
||||||
#define MC_TZ_SECURITY_CTRL 0x668
|
|
||||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
|
|
||||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
|
|
||||||
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
|
|
||||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
|
|
||||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
|
|
||||||
#define MC_SEC_CARVEOUT_BOM 0x670
|
|
||||||
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
|
|
||||||
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
|
|
||||||
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
|
|
||||||
#define MC_ERR_SEC_STATUS 0x67c
|
|
||||||
#define MC_ERR_SEC_ADR 0x680
|
|
||||||
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
|
|
||||||
#define MC_STUTTER_CONTROL 0x688
|
|
||||||
#define MC_RESERVED_RSV_1 0x958
|
|
||||||
#define MC_DVFS_PIPE_SELECT 0x95c
|
|
||||||
#define MC_AHB_PTSA_MIN 0x4e0
|
|
||||||
#define MC_AUD_PTSA_MIN 0x54c
|
|
||||||
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
|
|
||||||
#define MC_RING2_PTSA_RATE 0x440
|
|
||||||
#define MC_USBD_PTSA_RATE 0x530
|
|
||||||
#define MC_USBX_PTSA_MIN 0x528
|
|
||||||
#define MC_USBD_PTSA_MIN 0x534
|
|
||||||
#define MC_APB_PTSA_MAX 0x4f0
|
|
||||||
#define MC_JPG_PTSA_RATE 0x584
|
|
||||||
#define MC_DIS_PTSA_MIN 0x420
|
|
||||||
#define MC_AVP_PTSA_MAX 0x4fc
|
|
||||||
#define MC_AVP_PTSA_RATE 0x4f4
|
|
||||||
#define MC_RING1_PTSA_MIN 0x480
|
|
||||||
#define MC_DIS_PTSA_MAX 0x424
|
|
||||||
#define MC_SD_PTSA_MAX 0x4d8
|
|
||||||
#define MC_MSE_PTSA_RATE 0x4c4
|
|
||||||
#define MC_VICPC_PTSA_MIN 0x558
|
|
||||||
#define MC_PCX_PTSA_MAX 0x4b4
|
|
||||||
#define MC_ISP_PTSA_RATE 0x4a0
|
|
||||||
#define MC_A9AVPPC_PTSA_MIN 0x48c
|
|
||||||
#define MC_RING2_PTSA_MAX 0x448
|
|
||||||
#define MC_AUD_PTSA_RATE 0x548
|
|
||||||
#define MC_HOST_PTSA_MIN 0x51c
|
|
||||||
#define MC_MLL_MPCORER_PTSA_MAX 0x454
|
|
||||||
#define MC_SD_PTSA_MIN 0x4d4
|
|
||||||
#define MC_RING1_PTSA_RATE 0x47c
|
|
||||||
#define MC_JPG_PTSA_MIN 0x588
|
|
||||||
#define MC_HDAPC_PTSA_MIN 0x62c
|
|
||||||
#define MC_AVP_PTSA_MIN 0x4f8
|
|
||||||
#define MC_JPG_PTSA_MAX 0x58c
|
|
||||||
#define MC_VE_PTSA_MAX 0x43c
|
|
||||||
#define MC_DFD_PTSA_MAX 0x63c
|
|
||||||
#define MC_VICPC_PTSA_RATE 0x554
|
|
||||||
#define MC_GK_PTSA_MAX 0x544
|
|
||||||
#define MC_VICPC_PTSA_MAX 0x55c
|
|
||||||
#define MC_SDM_PTSA_MAX 0x624
|
|
||||||
#define MC_SAX_PTSA_RATE 0x4b8
|
|
||||||
#define MC_PCX_PTSA_MIN 0x4b0
|
|
||||||
#define MC_APB_PTSA_MIN 0x4ec
|
|
||||||
#define MC_GK2_PTSA_MIN 0x614
|
|
||||||
#define MC_PCX_PTSA_RATE 0x4ac
|
|
||||||
#define MC_RING1_PTSA_MAX 0x484
|
|
||||||
#define MC_HDAPC_PTSA_RATE 0x628
|
|
||||||
#define MC_MLL_MPCORER_PTSA_MIN 0x450
|
|
||||||
#define MC_GK2_PTSA_MAX 0x618
|
|
||||||
#define MC_AUD_PTSA_MAX 0x550
|
|
||||||
#define MC_GK2_PTSA_RATE 0x610
|
|
||||||
#define MC_ISP_PTSA_MAX 0x4a8
|
|
||||||
#define MC_DISB_PTSA_RATE 0x428
|
|
||||||
#define MC_VE2_PTSA_MAX 0x49c
|
|
||||||
#define MC_DFD_PTSA_MIN 0x638
|
|
||||||
#define MC_FTOP_PTSA_RATE 0x50c
|
|
||||||
#define MC_A9AVPPC_PTSA_RATE 0x488
|
|
||||||
#define MC_VE2_PTSA_MIN 0x498
|
|
||||||
#define MC_USBX_PTSA_MAX 0x52c
|
|
||||||
#define MC_DIS_PTSA_RATE 0x41c
|
|
||||||
#define MC_USBD_PTSA_MAX 0x538
|
|
||||||
#define MC_A9AVPPC_PTSA_MAX 0x490
|
|
||||||
#define MC_USBX_PTSA_RATE 0x524
|
|
||||||
#define MC_FTOP_PTSA_MAX 0x514
|
|
||||||
#define MC_HDAPC_PTSA_MAX 0x630
|
|
||||||
#define MC_SD_PTSA_RATE 0x4d0
|
|
||||||
#define MC_DFD_PTSA_RATE 0x634
|
|
||||||
#define MC_FTOP_PTSA_MIN 0x510
|
|
||||||
#define MC_SDM_PTSA_RATE 0x61c
|
|
||||||
#define MC_AHB_PTSA_RATE 0x4dc
|
|
||||||
#define MC_SMMU_SMMU_PTSA_MAX 0x460
|
|
||||||
#define MC_RING2_PTSA_MIN 0x444
|
|
||||||
#define MC_SDM_PTSA_MIN 0x620
|
|
||||||
#define MC_APB_PTSA_RATE 0x4e8
|
|
||||||
#define MC_MSE_PTSA_MIN 0x4c8
|
|
||||||
#define MC_HOST_PTSA_RATE 0x518
|
|
||||||
#define MC_VE_PTSA_RATE 0x434
|
|
||||||
#define MC_AHB_PTSA_MAX 0x4e4
|
|
||||||
#define MC_SAX_PTSA_MIN 0x4bc
|
|
||||||
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
|
|
||||||
#define MC_ISP_PTSA_MIN 0x4a4
|
|
||||||
#define MC_HOST_PTSA_MAX 0x520
|
|
||||||
#define MC_SAX_PTSA_MAX 0x4c0
|
|
||||||
#define MC_VE_PTSA_MIN 0x438
|
|
||||||
#define MC_GK_PTSA_MIN 0x540
|
|
||||||
#define MC_MSE_PTSA_MAX 0x4cc
|
|
||||||
#define MC_DISB_PTSA_MAX 0x430
|
|
||||||
#define MC_DISB_PTSA_MIN 0x42c
|
|
||||||
#define MC_SMMU_SMMU_PTSA_RATE 0x458
|
|
||||||
#define MC_VE2_PTSA_RATE 0x494
|
|
||||||
#define MC_GK_PTSA_RATE 0x53c
|
|
||||||
#define MC_PTSA_GRANT_DECREMENT 0x960
|
|
||||||
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
|
|
||||||
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
|
|
||||||
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
|
|
||||||
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
|
|
||||||
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
|
|
||||||
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
|
|
||||||
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
|
|
||||||
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
|
|
||||||
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
|
|
||||||
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
|
|
||||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
|
|
||||||
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
|
|
||||||
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
|
|
||||||
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
|
|
||||||
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
|
|
||||||
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
|
|
||||||
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
|
|
||||||
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
|
|
||||||
#define MC_MIN_LENGTH_APE_0 0xb34
|
|
||||||
#define MC_MIN_LENGTH_DCB_2 0x8a8
|
|
||||||
#define MC_MIN_LENGTH_A9AVP_0 0x950
|
|
||||||
#define MC_MIN_LENGTH_TSEC_0 0x93c
|
|
||||||
#define MC_MIN_LENGTH_DC_1 0x898
|
|
||||||
#define MC_MIN_LENGTH_AXIAP_0 0x94c
|
|
||||||
#define MC_MIN_LENGTH_ISP2B_0 0x930
|
|
||||||
#define MC_MIN_LENGTH_VI2_0 0x944
|
|
||||||
#define MC_MIN_LENGTH_DCB_0 0x8a0
|
|
||||||
#define MC_MIN_LENGTH_DCB_1 0x8a4
|
|
||||||
#define MC_MIN_LENGTH_PPCS_1 0x8f4
|
|
||||||
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
|
|
||||||
#define MC_MIN_LENGTH_HDA_0 0x8c4
|
|
||||||
#define MC_MIN_LENGTH_NVENC_0 0x8d4
|
|
||||||
#define MC_MIN_LENGTH_SDMMC_0 0xb18
|
|
||||||
#define MC_MIN_LENGTH_ISP2B_1 0x934
|
|
||||||
#define MC_MIN_LENGTH_HC_1 0x8c0
|
|
||||||
#define MC_MIN_LENGTH_DC_3 0xb20
|
|
||||||
#define MC_MIN_LENGTH_AVPC_0 0x890
|
|
||||||
#define MC_MIN_LENGTH_VIC_0 0x940
|
|
||||||
#define MC_MIN_LENGTH_ISP2_0 0x91c
|
|
||||||
#define MC_MIN_LENGTH_HC_0 0x8bc
|
|
||||||
#define MC_MIN_LENGTH_SE_0 0xb38
|
|
||||||
#define MC_MIN_LENGTH_NVDEC_0 0xb30
|
|
||||||
#define MC_MIN_LENGTH_SATA_0 0x8fc
|
|
||||||
#define MC_MIN_LENGTH_DC_0 0x894
|
|
||||||
#define MC_MIN_LENGTH_XUSB_1 0x92c
|
|
||||||
#define MC_MIN_LENGTH_DC_2 0x89c
|
|
||||||
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
|
|
||||||
#define MC_MIN_LENGTH_GPU_0 0xb04
|
|
||||||
#define MC_MIN_LENGTH_ETR_0 0xb44
|
|
||||||
#define MC_MIN_LENGTH_AFI_0 0x88c
|
|
||||||
#define MC_MIN_LENGTH_PPCS_0 0x8f0
|
|
||||||
#define MC_MIN_LENGTH_ISP2_1 0x920
|
|
||||||
#define MC_MIN_LENGTH_XUSB_0 0x928
|
|
||||||
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
|
|
||||||
#define MC_MIN_LENGTH_TSECB_0 0xb48
|
|
||||||
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
|
|
||||||
#define MC_MIN_LENGTH_GPU2_0 0xb40
|
|
||||||
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
|
|
||||||
#define MC_MIN_LENGTH_PTC_0 0x8f8
|
|
||||||
#define MC_EMEM_ARB_OVERRIDE_1 0x968
|
|
||||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
|
|
||||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
|
|
||||||
#define MC_EMEM_ARB_STATS_0 0x990
|
|
||||||
#define MC_EMEM_ARB_STATS_1 0x994
|
|
||||||
#define MC_MTS_CARVEOUT_BOM 0x9a0
|
|
||||||
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
|
|
||||||
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
|
|
||||||
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
|
|
||||||
#define MC_ERR_MTS_STATUS 0x9b0
|
|
||||||
#define MC_ERR_MTS_ADR 0x9b4
|
|
||||||
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
|
|
||||||
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
|
|
||||||
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
|
|
||||||
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
|
|
||||||
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
|
|
||||||
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
|
|
||||||
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
|
|
||||||
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
|
|
||||||
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
|
|
||||||
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
|
|
||||||
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
|
|
||||||
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
|
|
||||||
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
|
|
||||||
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
|
|
||||||
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
|
|
||||||
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
|
|
||||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
|
|
||||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
|
|
||||||
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
|
|
||||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
|
|
||||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
|
|
||||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
|
|
||||||
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
|
|
||||||
#define MC_DA_CONFIG0 0x9dc
|
|
||||||
#define MC_UNTRANSLATED_REGION_CHECK 0x948
|
|
||||||
|
|
||||||
/* Memory Controller clients */
|
|
||||||
#define CLIENT_ACCESS_NUM_CLIENTS 32
|
|
||||||
typedef enum {
|
|
||||||
/* _ACCESS0 */
|
|
||||||
CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
|
||||||
|
|
||||||
/* _ACCESS1 */
|
|
||||||
CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
|
||||||
|
|
||||||
/* _ACCESS2 */
|
|
||||||
CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
|
||||||
|
|
||||||
/* _ACCESS3 */
|
|
||||||
CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
|
||||||
|
|
||||||
/* _ACCESS4 */
|
|
||||||
CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
|
||||||
CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
|
|
||||||
} McClient;
|
|
||||||
|
|
||||||
void mc_enable_for_tsec();
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "panic.h"
|
|
||||||
#include "di.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "fuse.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
static uint32_t g_panic_code = 0;
|
|
||||||
|
|
||||||
void check_panic(void) {
|
|
||||||
/* We also handle our own panics. */
|
|
||||||
/* In the case of our own panics, we assume that the display has already been initialized. */
|
|
||||||
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
|
|
||||||
uint32_t code = g_panic_code == 0 ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
|
|
||||||
|
|
||||||
has_panic = has_panic && !(APBDEV_PMC_RST_STATUS_0 != 1 && code == PANIC_CODE_SAFEMODE);
|
|
||||||
|
|
||||||
if (has_panic) {
|
|
||||||
uint32_t color;
|
|
||||||
|
|
||||||
/* Check for predefined codes: */
|
|
||||||
switch (code & MASK(20)) {
|
|
||||||
case 0x01: /* Package2 signature verification failed. */
|
|
||||||
case 0x02: /* Package2 meta verification failed. */
|
|
||||||
case 0x03: /* Package2 version check failed. */
|
|
||||||
case 0x04: /* Package2 payload verification failed. */
|
|
||||||
color = PANIC_COLOR_KERNEL;
|
|
||||||
break;
|
|
||||||
case 0x05: /* Unknown SMC. */
|
|
||||||
case 0x06: /* Unknown Abort. */
|
|
||||||
color = PANIC_COLOR_SECMON_GENERIC;
|
|
||||||
break;
|
|
||||||
case 0x07: /* Invalid CPU context. */
|
|
||||||
case 0x08: /* Invalid SE state. */
|
|
||||||
case 0x09: /* CPU is already awake (2.0.0+). */
|
|
||||||
color = PANIC_COLOR_SECMON_DEEPSLEEP;
|
|
||||||
break;
|
|
||||||
case 0x10: /* Unknown exception. */
|
|
||||||
color = PANIC_COLOR_SECMON_EXCEPTION;
|
|
||||||
break;
|
|
||||||
case 0x30: /* General bootloader error. */
|
|
||||||
case 0x31: /* Invalid DRAM ID. */
|
|
||||||
case 0x32: /* Invalid size. */
|
|
||||||
case 0x33: /* Invalid arguement. */
|
|
||||||
case 0x34: /* Bad GPT. */
|
|
||||||
case 0x35: /* Failed to boot SafeMode. */
|
|
||||||
case 0x36: /* Activity monitor fired (4.0.0+). */
|
|
||||||
color = PANIC_COLOR_BOOTLOADER_GENERIC;
|
|
||||||
break;
|
|
||||||
case 0x40: /* Kernel panic. */
|
|
||||||
color = PANIC_COLOR_KERNEL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
color = code >> 20;
|
|
||||||
color |= color << 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_for_button_and_reboot();
|
|
||||||
} else {
|
|
||||||
g_panic_code = 0;
|
|
||||||
APBDEV_PMC_SCRATCH200_0 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((noreturn)) void panic(uint32_t code) {
|
|
||||||
/* Set panic code. */
|
|
||||||
if (g_panic_code == 0) {
|
|
||||||
g_panic_code = code;
|
|
||||||
APBDEV_PMC_SCRATCH200_0 = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
fuse_disable_programming();
|
|
||||||
APBDEV_PMC_CRYPTO_OP_0 = 1; /* Disable all SE operations. */
|
|
||||||
|
|
||||||
check_panic();
|
|
||||||
while(true);
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_PANIC_H
|
|
||||||
#define FUSEE_PANIC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define PANIC_COLOR_KERNEL 0x0000FF
|
|
||||||
#define PANIC_COLOR_SECMON_EXCEPTION 0xFF7700
|
|
||||||
#define PANIC_COLOR_SECMON_GENERIC 0x00FFFF
|
|
||||||
#define PANIC_COLOR_SECMON_DEEPSLEEP 0xFF77FF /* 4.0+ color */
|
|
||||||
#define PANIC_COLOR_BOOTLOADER_GENERIC 0xAA00FF
|
|
||||||
#define PANIC_COLOR_BOOTLOADER_SAFEMODE 0xFFFFAA /* Removed */
|
|
||||||
|
|
||||||
#define PANIC_CODE_SAFEMODE 0x00000020
|
|
||||||
|
|
||||||
void check_and_display_panic(void);
|
|
||||||
__attribute__ ((noreturn)) void panic(uint32_t code);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,211 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_PINMUX_H
|
|
||||||
#define FUSEE_PINMUX_H
|
|
||||||
|
|
||||||
#define PINMUX_BASE 0x70003000
|
|
||||||
#define MAKE_PINMUX_REG(n) MAKE_REG32(PINMUX_BASE + n)
|
|
||||||
|
|
||||||
#define PINMUX_TRISTATE (1 << 4)
|
|
||||||
#define PINMUX_PARKED (1 << 5)
|
|
||||||
#define PINMUX_INPUT (1 << 6)
|
|
||||||
#define PINMUX_PULL_NONE (0 << 2)
|
|
||||||
#define PINMUX_PULL_DOWN (1 << 2)
|
|
||||||
#define PINMUX_PULL_UP (2 << 2)
|
|
||||||
#define PINMUX_SELECT_FUNCTION0 0
|
|
||||||
#define PINMUX_SELECT_FUNCTION1 1
|
|
||||||
#define PINMUX_SELECT_FUNCTION2 2
|
|
||||||
#define PINMUX_SELECT_FUNCTION3 3
|
|
||||||
#define PINMUX_DRIVE_1X (0 << 13)
|
|
||||||
#define PINMUX_DRIVE_2X (1 << 13)
|
|
||||||
#define PINMUX_DRIVE_3X (2 << 13)
|
|
||||||
#define PINMUX_DRIVE_4X (3 << 13)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t sdmmc1_clk;
|
|
||||||
uint32_t sdmmc1_cmd;
|
|
||||||
uint32_t sdmmc1_dat3;
|
|
||||||
uint32_t sdmmc1_dat2;
|
|
||||||
uint32_t sdmmc1_dat1;
|
|
||||||
uint32_t sdmmc1_dat0;
|
|
||||||
uint32_t _r18;
|
|
||||||
uint32_t sdmmc3_clk;
|
|
||||||
uint32_t sdmmc3_cmd;
|
|
||||||
uint32_t sdmmc3_dat0;
|
|
||||||
uint32_t sdmmc3_dat1;
|
|
||||||
uint32_t sdmmc3_dat2;
|
|
||||||
uint32_t sdmmc3_dat3;
|
|
||||||
uint32_t _r34;
|
|
||||||
uint32_t pex_l0_rst_n;
|
|
||||||
uint32_t pex_l0_clkreq_n;
|
|
||||||
uint32_t pex_wake_n;
|
|
||||||
uint32_t pex_l1_rst_n;
|
|
||||||
uint32_t pex_l1_clkreq_n;
|
|
||||||
uint32_t sata_led_active;
|
|
||||||
uint32_t spi1_mosi;
|
|
||||||
uint32_t spi1_miso;
|
|
||||||
uint32_t spi1_sck;
|
|
||||||
uint32_t spi1_cs0;
|
|
||||||
uint32_t spi1_cs1;
|
|
||||||
uint32_t spi2_mosi;
|
|
||||||
uint32_t spi2_miso;
|
|
||||||
uint32_t spi2_sck;
|
|
||||||
uint32_t spi2_cs0;
|
|
||||||
uint32_t spi2_cs1;
|
|
||||||
uint32_t spi4_mosi;
|
|
||||||
uint32_t spi4_miso;
|
|
||||||
uint32_t spi4_sck;
|
|
||||||
uint32_t spi4_cs0;
|
|
||||||
uint32_t qspi_sck;
|
|
||||||
uint32_t qspi_cs_n;
|
|
||||||
uint32_t qspi_io0;
|
|
||||||
uint32_t qspi_io1;
|
|
||||||
uint32_t qspi_io2;
|
|
||||||
uint32_t qspi_io3;
|
|
||||||
uint32_t _ra0;
|
|
||||||
uint32_t dmic1_clk;
|
|
||||||
uint32_t dmic1_dat;
|
|
||||||
uint32_t dmic2_clk;
|
|
||||||
uint32_t dmic2_dat;
|
|
||||||
uint32_t dmic3_clk;
|
|
||||||
uint32_t dmic3_dat;
|
|
||||||
uint32_t gen1_i2c_scl;
|
|
||||||
uint32_t gen1_i2c_sda;
|
|
||||||
uint32_t gen2_i2c_scl;
|
|
||||||
uint32_t gen2_i2c_sda;
|
|
||||||
uint32_t gen3_i2c_scl;
|
|
||||||
uint32_t gen3_i2c_sda;
|
|
||||||
uint32_t cam_i2c_scl;
|
|
||||||
uint32_t cam_i2c_sda;
|
|
||||||
uint32_t pwr_i2c_scl;
|
|
||||||
uint32_t pwr_i2c_sda;
|
|
||||||
uint32_t uart1_tx;
|
|
||||||
uint32_t uart1_rx;
|
|
||||||
uint32_t uart1_rts;
|
|
||||||
uint32_t uart1_cts;
|
|
||||||
uint32_t uart2_tx;
|
|
||||||
uint32_t uart2_rx;
|
|
||||||
uint32_t uart2_rts;
|
|
||||||
uint32_t uart2_cts;
|
|
||||||
uint32_t uart3_tx;
|
|
||||||
uint32_t uart3_rx;
|
|
||||||
uint32_t uart3_rts;
|
|
||||||
uint32_t uart3_cts;
|
|
||||||
uint32_t uart4_tx;
|
|
||||||
uint32_t uart4_rx;
|
|
||||||
uint32_t uart4_rts;
|
|
||||||
uint32_t uart4_cts;
|
|
||||||
uint32_t dap1_fs;
|
|
||||||
uint32_t dap1_din;
|
|
||||||
uint32_t dap1_dout;
|
|
||||||
uint32_t dap1_sclk;
|
|
||||||
uint32_t dap2_fs;
|
|
||||||
uint32_t dap2_din;
|
|
||||||
uint32_t dap2_dout;
|
|
||||||
uint32_t dap2_sclk;
|
|
||||||
uint32_t dap4_fs;
|
|
||||||
uint32_t dap4_din;
|
|
||||||
uint32_t dap4_dout;
|
|
||||||
uint32_t dap4_sclk;
|
|
||||||
uint32_t cam1_mclk;
|
|
||||||
uint32_t cam2_mclk;
|
|
||||||
uint32_t jtag_rtck;
|
|
||||||
uint32_t clk_32k_in;
|
|
||||||
uint32_t clk_32k_out;
|
|
||||||
uint32_t batt_bcl;
|
|
||||||
uint32_t clk_req;
|
|
||||||
uint32_t cpu_pwr_req;
|
|
||||||
uint32_t pwr_int_n;
|
|
||||||
uint32_t shutdown;
|
|
||||||
uint32_t core_pwr_req;
|
|
||||||
uint32_t aud_mclk;
|
|
||||||
uint32_t dvfs_pwm;
|
|
||||||
uint32_t dvfs_clk;
|
|
||||||
uint32_t gpio_x1_aud;
|
|
||||||
uint32_t gpio_x3_aud;
|
|
||||||
uint32_t pcc7;
|
|
||||||
uint32_t hdmi_cec;
|
|
||||||
uint32_t hdmi_int_dp_hpd;
|
|
||||||
uint32_t spdif_out;
|
|
||||||
uint32_t spdif_in;
|
|
||||||
uint32_t usb_vbus_en0;
|
|
||||||
uint32_t usb_vbus_en1;
|
|
||||||
uint32_t dp_hpd0;
|
|
||||||
uint32_t wifi_en;
|
|
||||||
uint32_t wifi_rst;
|
|
||||||
uint32_t wifi_wake_ap;
|
|
||||||
uint32_t ap_wake_bt;
|
|
||||||
uint32_t bt_rst;
|
|
||||||
uint32_t bt_wake_ap;
|
|
||||||
uint32_t ap_wake_nfc;
|
|
||||||
uint32_t nfc_en;
|
|
||||||
uint32_t nfc_int;
|
|
||||||
uint32_t gps_en;
|
|
||||||
uint32_t gps_rst;
|
|
||||||
uint32_t cam_rst;
|
|
||||||
uint32_t cam_af_en;
|
|
||||||
uint32_t cam_flash_en;
|
|
||||||
uint32_t cam1_pwdn;
|
|
||||||
uint32_t cam2_pwdn;
|
|
||||||
uint32_t cam1_strobe;
|
|
||||||
uint32_t lcd_te;
|
|
||||||
uint32_t lcd_bl_pwm;
|
|
||||||
uint32_t lcd_bl_en;
|
|
||||||
uint32_t lcd_rst;
|
|
||||||
uint32_t lcd_gpio1;
|
|
||||||
uint32_t lcd_gpio2;
|
|
||||||
uint32_t ap_ready;
|
|
||||||
uint32_t touch_rst;
|
|
||||||
uint32_t touch_clk;
|
|
||||||
uint32_t modem_wake_ap;
|
|
||||||
uint32_t touch_int;
|
|
||||||
uint32_t motion_int;
|
|
||||||
uint32_t als_prox_int;
|
|
||||||
uint32_t temp_alert;
|
|
||||||
uint32_t button_power_on;
|
|
||||||
uint32_t button_vol_up;
|
|
||||||
uint32_t button_vol_down;
|
|
||||||
uint32_t button_slide_sw;
|
|
||||||
uint32_t button_home;
|
|
||||||
uint32_t pa6;
|
|
||||||
uint32_t pe6;
|
|
||||||
uint32_t pe7;
|
|
||||||
uint32_t ph6;
|
|
||||||
uint32_t pk0;
|
|
||||||
uint32_t pk1;
|
|
||||||
uint32_t pk2;
|
|
||||||
uint32_t pk3;
|
|
||||||
uint32_t pk4;
|
|
||||||
uint32_t pk5;
|
|
||||||
uint32_t pk6;
|
|
||||||
uint32_t pk7;
|
|
||||||
uint32_t pl0;
|
|
||||||
uint32_t pl1;
|
|
||||||
uint32_t pz0;
|
|
||||||
uint32_t pz1;
|
|
||||||
uint32_t pz2;
|
|
||||||
uint32_t pz3;
|
|
||||||
uint32_t pz4;
|
|
||||||
uint32_t pz5;
|
|
||||||
} tegra_pinmux_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_pinmux_t *pinmux_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_pinmux_t *)PINMUX_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,713 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_PMC_H
|
|
||||||
#define FUSEE_PMC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
/* Power Management Controller (APBDEV_PMC_) regs */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t cntrl; /* _CNTRL_0, 0x00 */
|
|
||||||
uint32_t sec_disable; /* _SEC_DISABLE_0, 0x04 */
|
|
||||||
uint32_t pmc_swrst; /* _PMC_SWRST_0, 0x08 */
|
|
||||||
uint32_t wake_mask; /* _WAKE_MASK_0, 0x0c */
|
|
||||||
uint32_t wake_lvl; /* _WAKE_LVL_0, 0x10 */
|
|
||||||
uint32_t wake_status; /* _WAKE_STATUS_0, 0x14 */
|
|
||||||
uint32_t sw_wake_status; /* _SW_WAKE_STATUS_0, 0x18 */
|
|
||||||
uint32_t dpd_pads_oride; /* _DPD_PADS_ORIDE_0, 0x1c */
|
|
||||||
uint32_t dpd_sample; /* _DPD_SAMPLE_0, 0x20 */
|
|
||||||
uint32_t dpd_enable; /* _DPD_ENABLE_0, 0x24 */
|
|
||||||
uint32_t pwrgate_timer_off; /* _PWRGATE_TIMER_OFF_0, 0x28 */
|
|
||||||
uint32_t clamp_status; /* _CLAMP_STATUS_0, 0x2c */
|
|
||||||
uint32_t pwrgate_toggle; /* _PWRGATE_TOGGLE_0, 0x30 */
|
|
||||||
uint32_t remove_clamping; /* _REMOVE_CLAMPING_0, 0x34 */
|
|
||||||
uint32_t pwrgate_status; /* _PWRGATE_STATUS_0, 0x38 */
|
|
||||||
uint32_t pwrgood_timer; /* _PWRGOOD_TIMER_0, 0x3c */
|
|
||||||
uint32_t blink_timer; /* _BLINK_TIMER_0, 0x40 */
|
|
||||||
uint32_t no_iopower; /* _NO_IOPOWER_0, 0x44 */
|
|
||||||
uint32_t pwr_det; /* _PWR_DET_0, 0x48 */
|
|
||||||
uint32_t pwr_det_latch; /* _PWR_DET_LATCH_0, 0x4c */
|
|
||||||
uint32_t scratch0; /* _SCRATCH0_0, 0x50 */
|
|
||||||
uint32_t scratch1; /* _SCRATCH1_0, 0x54 */
|
|
||||||
uint32_t scratch2; /* _SCRATCH2_0, 0x58 */
|
|
||||||
uint32_t scratch3; /* _SCRATCH3_0, 0x5c */
|
|
||||||
uint32_t scratch4; /* _SCRATCH4_0, 0x60 */
|
|
||||||
uint32_t scratch5; /* _SCRATCH5_0, 0x64 */
|
|
||||||
uint32_t scratch6; /* _SCRATCH6_0, 0x68 */
|
|
||||||
uint32_t scratch7; /* _SCRATCH7_0, 0x6c */
|
|
||||||
uint32_t scratch8; /* _SCRATCH8_0, 0x70 */
|
|
||||||
uint32_t scratch9; /* _SCRATCH9_0, 0x74 */
|
|
||||||
uint32_t scratch10; /* _SCRATCH10_0, 0x78 */
|
|
||||||
uint32_t scratch11; /* _SCRATCH11_0, 0x7c */
|
|
||||||
uint32_t scratch12; /* _SCRATCH12_0, 0x80 */
|
|
||||||
uint32_t scratch13; /* _SCRATCH13_0, 0x84 */
|
|
||||||
uint32_t scratch14; /* _SCRATCH14_0, 0x88 */
|
|
||||||
uint32_t scratch15; /* _SCRATCH15_0, 0x8c */
|
|
||||||
uint32_t scratch16; /* _SCRATCH16_0, 0x90 */
|
|
||||||
uint32_t scratch17; /* _SCRATCH17_0, 0x94 */
|
|
||||||
uint32_t scratch18; /* _SCRATCH18_0, 0x98 */
|
|
||||||
uint32_t scratch19; /* _SCRATCH19_0, 0x9c */
|
|
||||||
uint32_t scratch20; /* _SCRATCH20_0, 0xa0 */
|
|
||||||
uint32_t scratch21; /* _SCRATCH21_0, 0xa4 */
|
|
||||||
uint32_t scratch22; /* _SCRATCH22_0, 0xa8 */
|
|
||||||
uint32_t scratch23; /* _SCRATCH23_0, 0xac */
|
|
||||||
uint32_t secure_scratch0; /* _SECURE_SCRATCH0_0, 0xb0 */
|
|
||||||
uint32_t secure_scratch1; /* _SECURE_SCRATCH1_0, 0xb4 */
|
|
||||||
uint32_t secure_scratch2; /* _SECURE_SCRATCH2_0, 0xb8 */
|
|
||||||
uint32_t secure_scratch3; /* _SECURE_SCRATCH3_0, 0xbc */
|
|
||||||
uint32_t secure_scratch4; /* _SECURE_SCRATCH4_0, 0xc0 */
|
|
||||||
uint32_t secure_scratch5; /* _SECURE_SCRATCH5_0, 0xc4 */
|
|
||||||
uint32_t cpupwrgood_timer; /* _CPUPWRGOOD_TIMER_0, 0xc8 */
|
|
||||||
uint32_t cpupwroff_timer; /* _CPUPWROFF_TIMER_0, 0xcc */
|
|
||||||
uint32_t pg_mask; /* _PG_MASK_0, 0xd0 */
|
|
||||||
uint32_t pg_mask_1; /* _PG_MASK_1_0, 0xd4 */
|
|
||||||
uint32_t auto_wake_lvl; /* _AUTO_WAKE_LVL_0, 0xd8 */
|
|
||||||
uint32_t auto_wake_lvl_mask; /* _AUTO_WAKE_LVL_MASK_0, 0xdc */
|
|
||||||
uint32_t wake_delay; /* _WAKE_DELAY_0, 0xe0 */
|
|
||||||
uint32_t pwr_det_val; /* _PWR_DET_VAL_0, 0xe4 */
|
|
||||||
uint32_t ddr_pwr; /* _DDR_PWR_0, 0xe8 */
|
|
||||||
uint32_t usb_debounce_del; /* _USB_DEBOUNCE_DEL_0, 0xec */
|
|
||||||
uint32_t usb_ao; /* _USB_AO_0, 0xf0 */
|
|
||||||
uint32_t crypto_op; /* _CRYPTO_OP_0, 0xf4 */
|
|
||||||
uint32_t pllp_wb0_override; /* _PLLP_WB0_OVERRIDE_0, 0xf8 */
|
|
||||||
uint32_t scratch24; /* _SCRATCH24_0, 0xfc */
|
|
||||||
uint32_t scratch25; /* _SCRATCH25_0, 0x100 */
|
|
||||||
uint32_t scratch26; /* _SCRATCH26_0, 0x104 */
|
|
||||||
uint32_t scratch27; /* _SCRATCH27_0, 0x108 */
|
|
||||||
uint32_t scratch28; /* _SCRATCH28_0, 0x10c */
|
|
||||||
uint32_t scratch29; /* _SCRATCH29_0, 0x110 */
|
|
||||||
uint32_t scratch30; /* _SCRATCH30_0, 0x114 */
|
|
||||||
uint32_t scratch31; /* _SCRATCH31_0, 0x118 */
|
|
||||||
uint32_t scratch32; /* _SCRATCH32_0, 0x11c */
|
|
||||||
uint32_t scratch33; /* _SCRATCH33_0, 0x120 */
|
|
||||||
uint32_t scratch34; /* _SCRATCH34_0, 0x124 */
|
|
||||||
uint32_t scratch35; /* _SCRATCH35_0, 0x128 */
|
|
||||||
uint32_t scratch36; /* _SCRATCH36_0, 0x12c */
|
|
||||||
uint32_t scratch37; /* _SCRATCH37_0, 0x130 */
|
|
||||||
uint32_t scratch38; /* _SCRATCH38_0, 0x134 */
|
|
||||||
uint32_t scratch39; /* _SCRATCH39_0, 0x138 */
|
|
||||||
uint32_t scratch40; /* _SCRATCH40_0, 0x13c */
|
|
||||||
uint32_t scratch41; /* _SCRATCH41_0, 0x140 */
|
|
||||||
uint32_t scratch42; /* _SCRATCH42_0, 0x144 */
|
|
||||||
uint32_t bondout_mirror0; /* _BONDOUT_MIRROR0_0, 0x148 */
|
|
||||||
uint32_t bondout_mirror1; /* _BONDOUT_MIRROR1_0, 0x14c */
|
|
||||||
uint32_t bondout_mirror2; /* _BONDOUT_MIRROR2_0, 0x150 */
|
|
||||||
uint32_t sys_33v_en; /* _SYS_33V_EN_0, 0x154 */
|
|
||||||
uint32_t bondout_mirror_access; /* _BONDOUT_MIRROR_ACCESS_0, 0x158 */
|
|
||||||
uint32_t gate; /* _GATE_0, 0x15c */
|
|
||||||
uint32_t wake2_mask; /* _WAKE2_MASK_0, 0x160 */
|
|
||||||
uint32_t wake2_lvl; /* _WAKE2_LVL_0, 0x164 */
|
|
||||||
uint32_t wake2_status; /* _WAKE2_STATUS_0, 0x168 */
|
|
||||||
uint32_t sw_wake2_status; /* _SW_WAKE2_STATUS_0, 0x16c */
|
|
||||||
uint32_t auto_wake2_lvl_mask; /* _AUTO_WAKE2_LVL_MASK_0, 0x170 */
|
|
||||||
uint32_t pg_mask_2; /* _PG_MASK_2_0, 0x174 */
|
|
||||||
uint32_t pg_mask_ce1; /* _PG_MASK_CE1_0, 0x178 */
|
|
||||||
uint32_t pg_mask_ce2; /* _PG_MASK_CE2_0, 0x17c */
|
|
||||||
uint32_t pg_mask_ce3; /* _PG_MASK_CE3_0, 0x180 */
|
|
||||||
uint32_t pwrgate_timer_ce_0; /* _PWRGATE_TIMER_CE_0_0, 0x184 */
|
|
||||||
uint32_t pwrgate_timer_ce_1; /* _PWRGATE_TIMER_CE_1_0, 0x188 */
|
|
||||||
uint32_t pwrgate_timer_ce_2; /* _PWRGATE_TIMER_CE_2_0, 0x18c */
|
|
||||||
uint32_t pwrgate_timer_ce_3; /* _PWRGATE_TIMER_CE_3_0, 0x190 */
|
|
||||||
uint32_t pwrgate_timer_ce_4; /* _PWRGATE_TIMER_CE_4_0, 0x194 */
|
|
||||||
uint32_t pwrgate_timer_ce_5; /* _PWRGATE_TIMER_CE_5_0, 0x198 */
|
|
||||||
uint32_t pwrgate_timer_ce_6; /* _PWRGATE_TIMER_CE_6_0, 0x19c */
|
|
||||||
uint32_t pcx_edpd_cntrl; /* _PCX_EDPD_CNTRL_0, 0x1a0 */
|
|
||||||
uint32_t osc_edpd_over; /* _OSC_EDPD_OVER_0, 0x1a4 */
|
|
||||||
uint32_t clk_out_cntrl; /* _CLK_OUT_CNTRL_0, 0x1a8 */
|
|
||||||
uint32_t sata_pwrgt; /* _SATA_PWRGT_0, 0x1ac */
|
|
||||||
uint32_t sensor_ctrl; /* _SENSOR_CTRL_0, 0x1b0 */
|
|
||||||
uint32_t rst_status; /* _RST_STATUS_0, 0x1b4 */
|
|
||||||
uint32_t io_dpd_req; /* _IO_DPD_REQ_0, 0x1b8 */
|
|
||||||
uint32_t io_dpd_status; /* _IO_DPD_STATUS_0, 0x1bc */
|
|
||||||
uint32_t io_dpd2_req; /* _IO_DPD2_REQ_0, 0x1c0 */
|
|
||||||
uint32_t io_dpd2_status; /* _IO_DPD2_STATUS_0, 0x1c4 */
|
|
||||||
uint32_t sel_dpd_tim; /* _SEL_DPD_TIM_0, 0x1c8 */
|
|
||||||
uint32_t vddp_sel; /* _VDDP_SEL_0, 0x1cc */
|
|
||||||
uint32_t ddr_cfg; /* _DDR_CFG_0, 0x1d0 */
|
|
||||||
uint32_t _0x1d4[2];
|
|
||||||
uint32_t pllm_wb0_override_freq; /* _PLLM_WB0_OVERRIDE_FREQ_0, 0x1dc */
|
|
||||||
uint32_t _0x1e0;
|
|
||||||
uint32_t pwrgate_timer_mult; /* _PWRGATE_TIMER_MULT_0, 0x1e4 */
|
|
||||||
uint32_t dsi_sel_dpd; /* _DSI_SEL_DPD_0, 0x1e8 */
|
|
||||||
uint32_t utmip_uhsic_triggers; /* _UTMIP_UHSIC_TRIGGERS_0, 0x1ec */
|
|
||||||
uint32_t utmip_uhsic_saved_state; /* _UTMIP_UHSIC_SAVED_STATE_0, 0x1f0 */
|
|
||||||
uint32_t _0x1f4;
|
|
||||||
uint32_t utmip_term_pad_cfg; /* _UTMIP_TERM_PAD_CFG_0, 0x1f8 */
|
|
||||||
uint32_t utmip_uhsic_sleep_cfg; /* _UTMIP_UHSIC_SLEEP_CFG_0, 0x1fc */
|
|
||||||
uint32_t utmip_uhsic_sleepwalk_cfg; /* _UTMIP_UHSIC_SLEEPWALK_CFG_0, 0x200 */
|
|
||||||
uint32_t utmip_sleepwalk_p0; /* _UTMIP_SLEEPWALK_P0_0, 0x204 */
|
|
||||||
uint32_t utmip_sleepwalk_p1; /* _UTMIP_SLEEPWALK_P1_0, 0x208 */
|
|
||||||
uint32_t utmip_sleepwalk_p2; /* _UTMIP_SLEEPWALK_P2_0, 0x20c */
|
|
||||||
uint32_t uhsic_sleepwalk_p0; /* _UHSIC_SLEEPWALK_P0_0, 0x210 */
|
|
||||||
uint32_t utmip_uhsic_status; /* _UTMIP_UHSIC_STATUS_0, 0x214 */
|
|
||||||
uint32_t utmip_uhsic_fake; /* _UTMIP_UHSIC_FAKE_0, 0x218 */
|
|
||||||
uint32_t bondout_mirror3; /* _BONDOUT_MIRROR3_0, 0x21c */
|
|
||||||
uint32_t bondout_mirror4; /* _BONDOUT_MIRROR4_0, 0x220 */
|
|
||||||
uint32_t secure_scratch6; /* _SECURE_SCRATCH6_0, 0x224 */
|
|
||||||
uint32_t secure_scratch7; /* _SECURE_SCRATCH7_0, 0x228 */
|
|
||||||
uint32_t scratch43; /* _SCRATCH43_0, 0x22c */
|
|
||||||
uint32_t scratch44; /* _SCRATCH44_0, 0x230 */
|
|
||||||
uint32_t scratch45; /* _SCRATCH45_0, 0x234 */
|
|
||||||
uint32_t scratch46; /* _SCRATCH46_0, 0x238 */
|
|
||||||
uint32_t scratch47; /* _SCRATCH47_0, 0x23c */
|
|
||||||
uint32_t scratch48; /* _SCRATCH48_0, 0x240 */
|
|
||||||
uint32_t scratch49; /* _SCRATCH49_0, 0x244 */
|
|
||||||
uint32_t scratch50; /* _SCRATCH50_0, 0x248 */
|
|
||||||
uint32_t scratch51; /* _SCRATCH51_0, 0x24c */
|
|
||||||
uint32_t scratch52; /* _SCRATCH52_0, 0x250 */
|
|
||||||
uint32_t scratch53; /* _SCRATCH53_0, 0x254 */
|
|
||||||
uint32_t scratch54; /* _SCRATCH54_0, 0x258 */
|
|
||||||
uint32_t scratch55; /* _SCRATCH55_0, 0x25c */
|
|
||||||
uint32_t scratch0_eco; /* _SCRATCH0_ECO_0, 0x260 */
|
|
||||||
uint32_t por_dpd_ctrl; /* _POR_DPD_CTRL_0, 0x264 */
|
|
||||||
uint32_t scratch2_eco; /* _SCRATCH2_ECO_0, 0x268 */
|
|
||||||
uint32_t utmip_uhsic_line_wakeup; /* _UTMIP_UHSIC_LINE_WAKEUP_0, 0x26c */
|
|
||||||
uint32_t utmip_bias_master_cntrl; /* _UTMIP_BIAS_MASTER_CNTRL_0, 0x270 */
|
|
||||||
uint32_t utmip_master_config; /* _UTMIP_MASTER_CONFIG_0, 0x274 */
|
|
||||||
uint32_t td_pwrgate_inter_part_timer; /* _TD_PWRGATE_INTER_PART_TIMER_0, 0x278 */
|
|
||||||
uint32_t utmip_uhsic2_triggers; /* _UTMIP_UHSIC2_TRIGGERS_0, 0x27c */
|
|
||||||
uint32_t utmip_uhsic2_saved_state; /* _UTMIP_UHSIC2_SAVED_STATE_0, 0x280 */
|
|
||||||
uint32_t utmip_uhsic2_sleep_cfg; /* _UTMIP_UHSIC2_SLEEP_CFG_0, 0x284 */
|
|
||||||
uint32_t utmip_uhsic2_sleepwalk_cfg; /* _UTMIP_UHSIC2_SLEEPWALK_CFG_0, 0x288 */
|
|
||||||
uint32_t uhsic2_sleepwalk_p1; /* _UHSIC2_SLEEPWALK_P1_0, 0x28c */
|
|
||||||
uint32_t utmip_uhsic2_status; /* _UTMIP_UHSIC2_STATUS_0, 0x290 */
|
|
||||||
uint32_t utmip_uhsic2_fake; /* _UTMIP_UHSIC2_FAKE_0, 0x294 */
|
|
||||||
uint32_t utmip_uhsic2_line_wakeup; /* _UTMIP_UHSIC2_LINE_WAKEUP_0, 0x298 */
|
|
||||||
uint32_t utmip_master2_config; /* _UTMIP_MASTER2_CONFIG_0, 0x29c */
|
|
||||||
uint32_t utmip_uhsic_rpd_cfg; /* _UTMIP_UHSIC_RPD_CFG_0, 0x2a0 */
|
|
||||||
uint32_t pg_mask_ce0; /* _PG_MASK_CE0_0, 0x2a4 */
|
|
||||||
uint32_t pg_mask_3; /* _PG_MASK_3_0, 0x2a8 */
|
|
||||||
uint32_t pg_mask_4; /* _PG_MASK_4_0, 0x2ac */
|
|
||||||
uint32_t pllm_wb0_override2; /* _PLLM_WB0_OVERRIDE2_0, 0x2b0 */
|
|
||||||
uint32_t tsc_mult; /* _TSC_MULT_0, 0x2b4 */
|
|
||||||
uint32_t cpu_vsense_override; /* _CPU_VSENSE_OVERRIDE_0, 0x2b8 */
|
|
||||||
uint32_t glb_amap_cfg; /* _GLB_AMAP_CFG_0, 0x2bc */
|
|
||||||
uint32_t sticky_bits; /* _STICKY_BITS_0, 0x2c0 */
|
|
||||||
uint32_t sec_disable2; /* _SEC_DISABLE2_0, 0x2c4 */
|
|
||||||
uint32_t weak_bias; /* _WEAK_BIAS_0, 0x2c8 */
|
|
||||||
uint32_t reg_short; /* _REG_SHORT_0, 0x2cc */
|
|
||||||
uint32_t pg_mask_andor; /* _PG_MASK_ANDOR_0, 0x2d0 */
|
|
||||||
uint32_t gpu_rg_cntrl; /* _GPU_RG_CNTRL_0, 0x2d4 */
|
|
||||||
uint32_t sec_disable3; /* _SEC_DISABLE3_0, 0x2d8 */
|
|
||||||
uint32_t pg_mask_5; /* _PG_MASK_5_0, 0x2dc */
|
|
||||||
uint32_t pg_mask_6; /* _PG_MASK_6_0, 0x2e0 */
|
|
||||||
uint32_t _0x2e4[7];
|
|
||||||
uint32_t secure_scratch8; /* _SECURE_SCRATCH8_0, 0x300 */
|
|
||||||
uint32_t secure_scratch9; /* _SECURE_SCRATCH9_0, 0x304 */
|
|
||||||
uint32_t secure_scratch10; /* _SECURE_SCRATCH10_0, 0x308 */
|
|
||||||
uint32_t secure_scratch11; /* _SECURE_SCRATCH11_0, 0x30c */
|
|
||||||
uint32_t secure_scratch12; /* _SECURE_SCRATCH12_0, 0x310 */
|
|
||||||
uint32_t secure_scratch13; /* _SECURE_SCRATCH13_0, 0x314 */
|
|
||||||
uint32_t secure_scratch14; /* _SECURE_SCRATCH14_0, 0x318 */
|
|
||||||
uint32_t secure_scratch15; /* _SECURE_SCRATCH15_0, 0x31c */
|
|
||||||
uint32_t secure_scratch16; /* _SECURE_SCRATCH16_0, 0x320 */
|
|
||||||
uint32_t secure_scratch17; /* _SECURE_SCRATCH17_0, 0x324 */
|
|
||||||
uint32_t secure_scratch18; /* _SECURE_SCRATCH18_0, 0x328 */
|
|
||||||
uint32_t secure_scratch19; /* _SECURE_SCRATCH19_0, 0x32c */
|
|
||||||
uint32_t secure_scratch20; /* _SECURE_SCRATCH20_0, 0x330 */
|
|
||||||
uint32_t secure_scratch21; /* _SECURE_SCRATCH21_0, 0x334 */
|
|
||||||
uint32_t secure_scratch22; /* _SECURE_SCRATCH22_0, 0x338 */
|
|
||||||
uint32_t secure_scratch23; /* _SECURE_SCRATCH23_0, 0x33c */
|
|
||||||
uint32_t secure_scratch24; /* _SECURE_SCRATCH24_0, 0x340 */
|
|
||||||
uint32_t secure_scratch25; /* _SECURE_SCRATCH25_0, 0x344 */
|
|
||||||
uint32_t secure_scratch26; /* _SECURE_SCRATCH26_0, 0x348 */
|
|
||||||
uint32_t secure_scratch27; /* _SECURE_SCRATCH27_0, 0x34c */
|
|
||||||
uint32_t secure_scratch28; /* _SECURE_SCRATCH28_0, 0x350 */
|
|
||||||
uint32_t secure_scratch29; /* _SECURE_SCRATCH29_0, 0x354 */
|
|
||||||
uint32_t secure_scratch30; /* _SECURE_SCRATCH30_0, 0x358 */
|
|
||||||
uint32_t secure_scratch31; /* _SECURE_SCRATCH31_0, 0x35c */
|
|
||||||
uint32_t secure_scratch32; /* _SECURE_SCRATCH32_0, 0x360 */
|
|
||||||
uint32_t secure_scratch33; /* _SECURE_SCRATCH33_0, 0x364 */
|
|
||||||
uint32_t secure_scratch34; /* _SECURE_SCRATCH34_0, 0x368 */
|
|
||||||
uint32_t secure_scratch35; /* _SECURE_SCRATCH35_0, 0x36c */
|
|
||||||
uint32_t secure_scratch36; /* _SECURE_SCRATCH36_0, 0x370 */
|
|
||||||
uint32_t secure_scratch37; /* _SECURE_SCRATCH37_0, 0x374 */
|
|
||||||
uint32_t secure_scratch38; /* _SECURE_SCRATCH38_0, 0x378 */
|
|
||||||
uint32_t secure_scratch39; /* _SECURE_SCRATCH39_0, 0x37c */
|
|
||||||
uint32_t secure_scratch40; /* _SECURE_SCRATCH40_0, 0x380 */
|
|
||||||
uint32_t secure_scratch41; /* _SECURE_SCRATCH41_0, 0x384 */
|
|
||||||
uint32_t secure_scratch42; /* _SECURE_SCRATCH42_0, 0x388 */
|
|
||||||
uint32_t secure_scratch43; /* _SECURE_SCRATCH43_0, 0x38c */
|
|
||||||
uint32_t secure_scratch44; /* _SECURE_SCRATCH44_0, 0x390 */
|
|
||||||
uint32_t secure_scratch45; /* _SECURE_SCRATCH45_0, 0x394 */
|
|
||||||
uint32_t secure_scratch46; /* _SECURE_SCRATCH46_0, 0x398 */
|
|
||||||
uint32_t secure_scratch47; /* _SECURE_SCRATCH47_0, 0x39c */
|
|
||||||
uint32_t secure_scratch48; /* _SECURE_SCRATCH48_0, 0x3a0 */
|
|
||||||
uint32_t secure_scratch49; /* _SECURE_SCRATCH49_0, 0x3a4 */
|
|
||||||
uint32_t secure_scratch50; /* _SECURE_SCRATCH50_0, 0x3a8 */
|
|
||||||
uint32_t secure_scratch51; /* _SECURE_SCRATCH51_0, 0x3ac */
|
|
||||||
uint32_t secure_scratch52; /* _SECURE_SCRATCH52_0, 0x3b0 */
|
|
||||||
uint32_t secure_scratch53; /* _SECURE_SCRATCH53_0, 0x3b4 */
|
|
||||||
uint32_t secure_scratch54; /* _SECURE_SCRATCH54_0, 0x3b8 */
|
|
||||||
uint32_t secure_scratch55; /* _SECURE_SCRATCH55_0, 0x3bc */
|
|
||||||
uint32_t secure_scratch56; /* _SECURE_SCRATCH56_0, 0x3c0 */
|
|
||||||
uint32_t secure_scratch57; /* _SECURE_SCRATCH57_0, 0x3c4 */
|
|
||||||
uint32_t secure_scratch58; /* _SECURE_SCRATCH58_0, 0x3c8 */
|
|
||||||
uint32_t secure_scratch59; /* _SECURE_SCRATCH59_0, 0x3cc */
|
|
||||||
uint32_t secure_scratch60; /* _SECURE_SCRATCH60_0, 0x3d0 */
|
|
||||||
uint32_t secure_scratch61; /* _SECURE_SCRATCH61_0, 0x3d4 */
|
|
||||||
uint32_t secure_scratch62; /* _SECURE_SCRATCH62_0, 0x3d8 */
|
|
||||||
uint32_t secure_scratch63; /* _SECURE_SCRATCH63_0, 0x3dc */
|
|
||||||
uint32_t secure_scratch64; /* _SECURE_SCRATCH64_0, 0x3e0 */
|
|
||||||
uint32_t secure_scratch65; /* _SECURE_SCRATCH65_0, 0x3e4 */
|
|
||||||
uint32_t secure_scratch66; /* _SECURE_SCRATCH66_0, 0x3e8 */
|
|
||||||
uint32_t secure_scratch67; /* _SECURE_SCRATCH67_0, 0x3ec */
|
|
||||||
uint32_t secure_scratch68; /* _SECURE_SCRATCH68_0, 0x3f0 */
|
|
||||||
uint32_t secure_scratch69; /* _SECURE_SCRATCH69_0, 0x3f4 */
|
|
||||||
uint32_t secure_scratch70; /* _SECURE_SCRATCH70_0, 0x3f8 */
|
|
||||||
uint32_t secure_scratch71; /* _SECURE_SCRATCH71_0, 0x3fc */
|
|
||||||
uint32_t secure_scratch72; /* _SECURE_SCRATCH72_0, 0x400 */
|
|
||||||
uint32_t secure_scratch73; /* _SECURE_SCRATCH73_0, 0x404 */
|
|
||||||
uint32_t secure_scratch74; /* _SECURE_SCRATCH74_0, 0x408 */
|
|
||||||
uint32_t secure_scratch75; /* _SECURE_SCRATCH75_0, 0x40c */
|
|
||||||
uint32_t secure_scratch76; /* _SECURE_SCRATCH76_0, 0x410 */
|
|
||||||
uint32_t secure_scratch77; /* _SECURE_SCRATCH77_0, 0x414 */
|
|
||||||
uint32_t secure_scratch78; /* _SECURE_SCRATCH78_0, 0x418 */
|
|
||||||
uint32_t secure_scratch79; /* _SECURE_SCRATCH79_0, 0x41c */
|
|
||||||
uint32_t _0x420[8];
|
|
||||||
uint32_t cntrl2; /* _CNTRL2_0, 0x440 */
|
|
||||||
uint32_t io_dpd_off_mask; /* _IO_DPD_OFF_MASK_0, 0x444 */
|
|
||||||
uint32_t io_dpd2_off_mask; /* _IO_DPD2_OFF_MASK_0, 0x448 */
|
|
||||||
uint32_t event_counter; /* _EVENT_COUNTER_0, 0x44c */
|
|
||||||
uint32_t fuse_control; /* _FUSE_CONTROL_0, 0x450 */
|
|
||||||
uint32_t scratch1_eco; /* _SCRATCH1_ECO_0, 0x454 */
|
|
||||||
uint32_t _0x458;
|
|
||||||
uint32_t io_dpd3_req; /* _IO_DPD3_REQ_0, 0x45c */
|
|
||||||
uint32_t io_dpd3_status; /* _IO_DPD3_STATUS_0, 0x460 */
|
|
||||||
uint32_t io_dpd4_req; /* _IO_DPD4_REQ_0, 0x464 */
|
|
||||||
uint32_t io_dpd4_status; /* _IO_DPD4_STATUS_0, 0x468 */
|
|
||||||
uint32_t _0x46c[2];
|
|
||||||
uint32_t direct_thermtrip_cfg; /* _DIRECT_THERMTRIP_CFG_0, 0x474 */
|
|
||||||
uint32_t tsosc_delay; /* _TSOSC_DELAY_0, 0x478 */
|
|
||||||
uint32_t set_sw_clamp; /* _SET_SW_CLAMP_0, 0x47c */
|
|
||||||
uint32_t debug_authentication; /* _DEBUG_AUTHENTICATION_0, 0x480 */
|
|
||||||
uint32_t aotag_cfg; /* _AOTAG_CFG_0, 0x484 */
|
|
||||||
uint32_t aotag_thresh1_cfg; /* _AOTAG_THRESH1_CFG_0, 0x488 */
|
|
||||||
uint32_t aotag_thresh2_cfg; /* _AOTAG_THRESH2_CFG_0, 0x48c */
|
|
||||||
uint32_t aotag_thresh3_cfg; /* _AOTAG_THRESH3_CFG_0, 0x490 */
|
|
||||||
uint32_t aotag_status; /* _AOTAG_STATUS_0, 0x494 */
|
|
||||||
uint32_t aotag_security; /* _AOTAG_SECURITY_0, 0x498 */
|
|
||||||
uint32_t tsensor_config0; /* _TSENSOR_CONFIG0_0, 0x49c */
|
|
||||||
uint32_t tsensor_config1; /* _TSENSOR_CONFIG1_0, 0x4a0 */
|
|
||||||
uint32_t tsensor_config2; /* _TSENSOR_CONFIG2_0, 0x4a4 */
|
|
||||||
uint32_t tsensor_status0; /* _TSENSOR_STATUS0_0, 0x4a8 */
|
|
||||||
uint32_t tsensor_status1; /* _TSENSOR_STATUS1_0, 0x4ac */
|
|
||||||
uint32_t tsensor_status2; /* _TSENSOR_STATUS2_0, 0x4b0 */
|
|
||||||
uint32_t tsensor_pdiv; /* _TSENSOR_PDIV_0, 0x4b4 */
|
|
||||||
uint32_t aotag_intr_en; /* _AOTAG_INTR_EN_0, 0x4b8 */
|
|
||||||
uint32_t aotag_intr_dis; /* _AOTAG_INTR_DIS_0, 0x4bc */
|
|
||||||
uint32_t utmip_pad_cfg0; /* _UTMIP_PAD_CFG0_0, 0x4c0 */
|
|
||||||
uint32_t utmip_pad_cfg1; /* _UTMIP_PAD_CFG1_0, 0x4c4 */
|
|
||||||
uint32_t utmip_pad_cfg2; /* _UTMIP_PAD_CFG2_0, 0x4c8 */
|
|
||||||
uint32_t utmip_pad_cfg3; /* _UTMIP_PAD_CFG3_0, 0x4cc */
|
|
||||||
uint32_t utmip_uhsic_sleep_cfg1; /* _UTMIP_UHSIC_SLEEP_CFG1_0, 0x4d0 */
|
|
||||||
uint32_t cc4_hvc_control; /* _CC4_HVC_CONTROL_0, 0x4d4 */
|
|
||||||
uint32_t wake_debounce_en; /* _WAKE_DEBOUNCE_EN_0, 0x4d8 */
|
|
||||||
uint32_t ramdump_ctl_status; /* _RAMDUMP_CTL_STATUS_0, 0x4dc */
|
|
||||||
uint32_t utmip_sleepwalk_p3; /* _UTMIP_SLEEPWALK_P3_0, 0x4e0 */
|
|
||||||
uint32_t ddr_cntrl; /* _DDR_CNTRL_0, 0x4e4 */
|
|
||||||
uint32_t _0x4e8[50];
|
|
||||||
uint32_t sec_disable4; /* _SEC_DISABLE4_0, 0x5b0 */
|
|
||||||
uint32_t sec_disable5; /* _SEC_DISABLE5_0, 0x5b4 */
|
|
||||||
uint32_t sec_disable6; /* _SEC_DISABLE6_0, 0x5b8 */
|
|
||||||
uint32_t sec_disable7; /* _SEC_DISABLE7_0, 0x5bc */
|
|
||||||
uint32_t sec_disable8; /* _SEC_DISABLE8_0, 0x5c0 */
|
|
||||||
uint32_t sec_disable9; /* _SEC_DISABLE9_0, 0x5c4 */
|
|
||||||
uint32_t sec_disable10; /* _SEC_DISABLE10_0, 0x5c8 */
|
|
||||||
uint32_t _0x5cc[13];
|
|
||||||
uint32_t scratch56; /* _SCRATCH56_0, 0x600 */
|
|
||||||
uint32_t scratch57; /* _SCRATCH57_0, 0x604 */
|
|
||||||
uint32_t scratch58; /* _SCRATCH58_0, 0x608 */
|
|
||||||
uint32_t scratch59; /* _SCRATCH59_0, 0x60c */
|
|
||||||
uint32_t scratch60; /* _SCRATCH60_0, 0x610 */
|
|
||||||
uint32_t scratch61; /* _SCRATCH61_0, 0x614 */
|
|
||||||
uint32_t scratch62; /* _SCRATCH62_0, 0x618 */
|
|
||||||
uint32_t scratch63; /* _SCRATCH63_0, 0x61c */
|
|
||||||
uint32_t scratch64; /* _SCRATCH64_0, 0x620 */
|
|
||||||
uint32_t scratch65; /* _SCRATCH65_0, 0x624 */
|
|
||||||
uint32_t scratch66; /* _SCRATCH66_0, 0x628 */
|
|
||||||
uint32_t scratch67; /* _SCRATCH67_0, 0x62c */
|
|
||||||
uint32_t scratch68; /* _SCRATCH68_0, 0x630 */
|
|
||||||
uint32_t scratch69; /* _SCRATCH69_0, 0x634 */
|
|
||||||
uint32_t scratch70; /* _SCRATCH70_0, 0x638 */
|
|
||||||
uint32_t scratch71; /* _SCRATCH71_0, 0x63c */
|
|
||||||
uint32_t scratch72; /* _SCRATCH72_0, 0x640 */
|
|
||||||
uint32_t scratch73; /* _SCRATCH73_0, 0x644 */
|
|
||||||
uint32_t scratch74; /* _SCRATCH74_0, 0x648 */
|
|
||||||
uint32_t scratch75; /* _SCRATCH75_0, 0x64c */
|
|
||||||
uint32_t scratch76; /* _SCRATCH76_0, 0x650 */
|
|
||||||
uint32_t scratch77; /* _SCRATCH77_0, 0x654 */
|
|
||||||
uint32_t scratch78; /* _SCRATCH78_0, 0x658 */
|
|
||||||
uint32_t scratch79; /* _SCRATCH79_0, 0x65c */
|
|
||||||
uint32_t scratch80; /* _SCRATCH80_0, 0x660 */
|
|
||||||
uint32_t scratch81; /* _SCRATCH81_0, 0x664 */
|
|
||||||
uint32_t scratch82; /* _SCRATCH82_0, 0x668 */
|
|
||||||
uint32_t scratch83; /* _SCRATCH83_0, 0x66c */
|
|
||||||
uint32_t scratch84; /* _SCRATCH84_0, 0x670 */
|
|
||||||
uint32_t scratch85; /* _SCRATCH85_0, 0x674 */
|
|
||||||
uint32_t scratch86; /* _SCRATCH86_0, 0x678 */
|
|
||||||
uint32_t scratch87; /* _SCRATCH87_0, 0x67c */
|
|
||||||
uint32_t scratch88; /* _SCRATCH88_0, 0x680 */
|
|
||||||
uint32_t scratch89; /* _SCRATCH89_0, 0x684 */
|
|
||||||
uint32_t scratch90; /* _SCRATCH90_0, 0x688 */
|
|
||||||
uint32_t scratch91; /* _SCRATCH91_0, 0x68c */
|
|
||||||
uint32_t scratch92; /* _SCRATCH92_0, 0x690 */
|
|
||||||
uint32_t scratch93; /* _SCRATCH93_0, 0x694 */
|
|
||||||
uint32_t scratch94; /* _SCRATCH94_0, 0x698 */
|
|
||||||
uint32_t scratch95; /* _SCRATCH95_0, 0x69c */
|
|
||||||
uint32_t scratch96; /* _SCRATCH96_0, 0x6a0 */
|
|
||||||
uint32_t scratch97; /* _SCRATCH97_0, 0x6a4 */
|
|
||||||
uint32_t scratch98; /* _SCRATCH98_0, 0x6a8 */
|
|
||||||
uint32_t scratch99; /* _SCRATCH99_0, 0x6ac */
|
|
||||||
uint32_t scratch100; /* _SCRATCH100_0, 0x6b0 */
|
|
||||||
uint32_t scratch101; /* _SCRATCH101_0, 0x6b4 */
|
|
||||||
uint32_t scratch102; /* _SCRATCH102_0, 0x6b8 */
|
|
||||||
uint32_t scratch103; /* _SCRATCH103_0, 0x6bc */
|
|
||||||
uint32_t scratch104; /* _SCRATCH104_0, 0x6c0 */
|
|
||||||
uint32_t scratch105; /* _SCRATCH105_0, 0x6c4 */
|
|
||||||
uint32_t scratch106; /* _SCRATCH106_0, 0x6c8 */
|
|
||||||
uint32_t scratch107; /* _SCRATCH107_0, 0x6cc */
|
|
||||||
uint32_t scratch108; /* _SCRATCH108_0, 0x6d0 */
|
|
||||||
uint32_t scratch109; /* _SCRATCH109_0, 0x6d4 */
|
|
||||||
uint32_t scratch110; /* _SCRATCH110_0, 0x6d8 */
|
|
||||||
uint32_t scratch111; /* _SCRATCH111_0, 0x6dc */
|
|
||||||
uint32_t scratch112; /* _SCRATCH112_0, 0x6e0 */
|
|
||||||
uint32_t scratch113; /* _SCRATCH113_0, 0x6e4 */
|
|
||||||
uint32_t scratch114; /* _SCRATCH114_0, 0x6e8 */
|
|
||||||
uint32_t scratch115; /* _SCRATCH115_0, 0x6ec */
|
|
||||||
uint32_t scratch116; /* _SCRATCH116_0, 0x6f0 */
|
|
||||||
uint32_t scratch117; /* _SCRATCH117_0, 0x6f4 */
|
|
||||||
uint32_t scratch118; /* _SCRATCH118_0, 0x6f8 */
|
|
||||||
uint32_t scratch119; /* _SCRATCH119_0, 0x6fc */
|
|
||||||
uint32_t scratch120; /* _SCRATCH120_0, 0x700 */
|
|
||||||
uint32_t scratch121; /* _SCRATCH121_0, 0x704 */
|
|
||||||
uint32_t scratch122; /* _SCRATCH122_0, 0x708 */
|
|
||||||
uint32_t scratch123; /* _SCRATCH123_0, 0x70c */
|
|
||||||
uint32_t scratch124; /* _SCRATCH124_0, 0x710 */
|
|
||||||
uint32_t scratch125; /* _SCRATCH125_0, 0x714 */
|
|
||||||
uint32_t scratch126; /* _SCRATCH126_0, 0x718 */
|
|
||||||
uint32_t scratch127; /* _SCRATCH127_0, 0x71c */
|
|
||||||
uint32_t scratch128; /* _SCRATCH128_0, 0x720 */
|
|
||||||
uint32_t scratch129; /* _SCRATCH129_0, 0x724 */
|
|
||||||
uint32_t scratch130; /* _SCRATCH130_0, 0x728 */
|
|
||||||
uint32_t scratch131; /* _SCRATCH131_0, 0x72c */
|
|
||||||
uint32_t scratch132; /* _SCRATCH132_0, 0x730 */
|
|
||||||
uint32_t scratch133; /* _SCRATCH133_0, 0x734 */
|
|
||||||
uint32_t scratch134; /* _SCRATCH134_0, 0x738 */
|
|
||||||
uint32_t scratch135; /* _SCRATCH135_0, 0x73c */
|
|
||||||
uint32_t scratch136; /* _SCRATCH136_0, 0x740 */
|
|
||||||
uint32_t scratch137; /* _SCRATCH137_0, 0x744 */
|
|
||||||
uint32_t scratch138; /* _SCRATCH138_0, 0x748 */
|
|
||||||
uint32_t scratch139; /* _SCRATCH139_0, 0x74c */
|
|
||||||
uint32_t scratch140; /* _SCRATCH140_0, 0x750 */
|
|
||||||
uint32_t scratch141; /* _SCRATCH141_0, 0x754 */
|
|
||||||
uint32_t scratch142; /* _SCRATCH142_0, 0x758 */
|
|
||||||
uint32_t scratch143; /* _SCRATCH143_0, 0x75c */
|
|
||||||
uint32_t scratch144; /* _SCRATCH144_0, 0x760 */
|
|
||||||
uint32_t scratch145; /* _SCRATCH145_0, 0x764 */
|
|
||||||
uint32_t scratch146; /* _SCRATCH146_0, 0x768 */
|
|
||||||
uint32_t scratch147; /* _SCRATCH147_0, 0x76c */
|
|
||||||
uint32_t scratch148; /* _SCRATCH148_0, 0x770 */
|
|
||||||
uint32_t scratch149; /* _SCRATCH149_0, 0x774 */
|
|
||||||
uint32_t scratch150; /* _SCRATCH150_0, 0x778 */
|
|
||||||
uint32_t scratch151; /* _SCRATCH151_0, 0x77c */
|
|
||||||
uint32_t scratch152; /* _SCRATCH152_0, 0x780 */
|
|
||||||
uint32_t scratch153; /* _SCRATCH153_0, 0x784 */
|
|
||||||
uint32_t scratch154; /* _SCRATCH154_0, 0x788 */
|
|
||||||
uint32_t scratch155; /* _SCRATCH155_0, 0x78c */
|
|
||||||
uint32_t scratch156; /* _SCRATCH156_0, 0x790 */
|
|
||||||
uint32_t scratch157; /* _SCRATCH157_0, 0x794 */
|
|
||||||
uint32_t scratch158; /* _SCRATCH158_0, 0x798 */
|
|
||||||
uint32_t scratch159; /* _SCRATCH159_0, 0x79c */
|
|
||||||
uint32_t scratch160; /* _SCRATCH160_0, 0x7a0 */
|
|
||||||
uint32_t scratch161; /* _SCRATCH161_0, 0x7a4 */
|
|
||||||
uint32_t scratch162; /* _SCRATCH162_0, 0x7a8 */
|
|
||||||
uint32_t scratch163; /* _SCRATCH163_0, 0x7ac */
|
|
||||||
uint32_t scratch164; /* _SCRATCH164_0, 0x7b0 */
|
|
||||||
uint32_t scratch165; /* _SCRATCH165_0, 0x7b4 */
|
|
||||||
uint32_t scratch166; /* _SCRATCH166_0, 0x7b8 */
|
|
||||||
uint32_t scratch167; /* _SCRATCH167_0, 0x7bc */
|
|
||||||
uint32_t scratch168; /* _SCRATCH168_0, 0x7c0 */
|
|
||||||
uint32_t scratch169; /* _SCRATCH169_0, 0x7c4 */
|
|
||||||
uint32_t scratch170; /* _SCRATCH170_0, 0x7c8 */
|
|
||||||
uint32_t scratch171; /* _SCRATCH171_0, 0x7cc */
|
|
||||||
uint32_t scratch172; /* _SCRATCH172_0, 0x7d0 */
|
|
||||||
uint32_t scratch173; /* _SCRATCH173_0, 0x7d4 */
|
|
||||||
uint32_t scratch174; /* _SCRATCH174_0, 0x7d8 */
|
|
||||||
uint32_t scratch175; /* _SCRATCH175_0, 0x7dc */
|
|
||||||
uint32_t scratch176; /* _SCRATCH176_0, 0x7e0 */
|
|
||||||
uint32_t scratch177; /* _SCRATCH177_0, 0x7e4 */
|
|
||||||
uint32_t scratch178; /* _SCRATCH178_0, 0x7e8 */
|
|
||||||
uint32_t scratch179; /* _SCRATCH179_0, 0x7ec */
|
|
||||||
uint32_t scratch180; /* _SCRATCH180_0, 0x7f0 */
|
|
||||||
uint32_t scratch181; /* _SCRATCH181_0, 0x7f4 */
|
|
||||||
uint32_t scratch182; /* _SCRATCH182_0, 0x7f8 */
|
|
||||||
uint32_t scratch183; /* _SCRATCH183_0, 0x7fc */
|
|
||||||
uint32_t scratch184; /* _SCRATCH184_0, 0x800 */
|
|
||||||
uint32_t scratch185; /* _SCRATCH185_0, 0x804 */
|
|
||||||
uint32_t scratch186; /* _SCRATCH186_0, 0x808 */
|
|
||||||
uint32_t scratch187; /* _SCRATCH187_0, 0x80c */
|
|
||||||
uint32_t scratch188; /* _SCRATCH188_0, 0x810 */
|
|
||||||
uint32_t scratch189; /* _SCRATCH189_0, 0x814 */
|
|
||||||
uint32_t scratch190; /* _SCRATCH190_0, 0x818 */
|
|
||||||
uint32_t scratch191; /* _SCRATCH191_0, 0x81c */
|
|
||||||
uint32_t scratch192; /* _SCRATCH192_0, 0x820 */
|
|
||||||
uint32_t scratch193; /* _SCRATCH193_0, 0x824 */
|
|
||||||
uint32_t scratch194; /* _SCRATCH194_0, 0x828 */
|
|
||||||
uint32_t scratch195; /* _SCRATCH195_0, 0x82c */
|
|
||||||
uint32_t scratch196; /* _SCRATCH196_0, 0x830 */
|
|
||||||
uint32_t scratch197; /* _SCRATCH197_0, 0x834 */
|
|
||||||
uint32_t scratch198; /* _SCRATCH198_0, 0x838 */
|
|
||||||
uint32_t scratch199; /* _SCRATCH199_0, 0x83c */
|
|
||||||
uint32_t scratch200; /* _SCRATCH200_0, 0x840 */
|
|
||||||
uint32_t scratch201; /* _SCRATCH201_0, 0x844 */
|
|
||||||
uint32_t scratch202; /* _SCRATCH202_0, 0x848 */
|
|
||||||
uint32_t scratch203; /* _SCRATCH203_0, 0x84c */
|
|
||||||
uint32_t scratch204; /* _SCRATCH204_0, 0x850 */
|
|
||||||
uint32_t scratch205; /* _SCRATCH205_0, 0x854 */
|
|
||||||
uint32_t scratch206; /* _SCRATCH206_0, 0x858 */
|
|
||||||
uint32_t scratch207; /* _SCRATCH207_0, 0x85c */
|
|
||||||
uint32_t scratch208; /* _SCRATCH208_0, 0x860 */
|
|
||||||
uint32_t scratch209; /* _SCRATCH209_0, 0x864 */
|
|
||||||
uint32_t scratch210; /* _SCRATCH210_0, 0x868 */
|
|
||||||
uint32_t scratch211; /* _SCRATCH211_0, 0x86c */
|
|
||||||
uint32_t scratch212; /* _SCRATCH212_0, 0x870 */
|
|
||||||
uint32_t scratch213; /* _SCRATCH213_0, 0x874 */
|
|
||||||
uint32_t scratch214; /* _SCRATCH214_0, 0x878 */
|
|
||||||
uint32_t scratch215; /* _SCRATCH215_0, 0x87c */
|
|
||||||
uint32_t scratch216; /* _SCRATCH216_0, 0x880 */
|
|
||||||
uint32_t scratch217; /* _SCRATCH217_0, 0x884 */
|
|
||||||
uint32_t scratch218; /* _SCRATCH218_0, 0x888 */
|
|
||||||
uint32_t scratch219; /* _SCRATCH219_0, 0x88c */
|
|
||||||
uint32_t scratch220; /* _SCRATCH220_0, 0x890 */
|
|
||||||
uint32_t scratch221; /* _SCRATCH221_0, 0x894 */
|
|
||||||
uint32_t scratch222; /* _SCRATCH222_0, 0x898 */
|
|
||||||
uint32_t scratch223; /* _SCRATCH223_0, 0x89c */
|
|
||||||
uint32_t scratch224; /* _SCRATCH224_0, 0x8a0 */
|
|
||||||
uint32_t scratch225; /* _SCRATCH225_0, 0x8a4 */
|
|
||||||
uint32_t scratch226; /* _SCRATCH226_0, 0x8a8 */
|
|
||||||
uint32_t scratch227; /* _SCRATCH227_0, 0x8ac */
|
|
||||||
uint32_t scratch228; /* _SCRATCH228_0, 0x8b0 */
|
|
||||||
uint32_t scratch229; /* _SCRATCH229_0, 0x8b4 */
|
|
||||||
uint32_t scratch230; /* _SCRATCH230_0, 0x8b8 */
|
|
||||||
uint32_t scratch231; /* _SCRATCH231_0, 0x8bc */
|
|
||||||
uint32_t scratch232; /* _SCRATCH232_0, 0x8c0 */
|
|
||||||
uint32_t scratch233; /* _SCRATCH233_0, 0x8c4 */
|
|
||||||
uint32_t scratch234; /* _SCRATCH234_0, 0x8c8 */
|
|
||||||
uint32_t scratch235; /* _SCRATCH235_0, 0x8cc */
|
|
||||||
uint32_t scratch236; /* _SCRATCH236_0, 0x8d0 */
|
|
||||||
uint32_t scratch237; /* _SCRATCH237_0, 0x8d4 */
|
|
||||||
uint32_t scratch238; /* _SCRATCH238_0, 0x8d8 */
|
|
||||||
uint32_t scratch239; /* _SCRATCH239_0, 0x8dc */
|
|
||||||
uint32_t scratch240; /* _SCRATCH240_0, 0x8e0 */
|
|
||||||
uint32_t scratch241; /* _SCRATCH241_0, 0x8e4 */
|
|
||||||
uint32_t scratch242; /* _SCRATCH242_0, 0x8e8 */
|
|
||||||
uint32_t scratch243; /* _SCRATCH243_0, 0x8ec */
|
|
||||||
uint32_t scratch244; /* _SCRATCH244_0, 0x8f0 */
|
|
||||||
uint32_t scratch245; /* _SCRATCH245_0, 0x8f4 */
|
|
||||||
uint32_t scratch246; /* _SCRATCH246_0, 0x8f8 */
|
|
||||||
uint32_t scratch247; /* _SCRATCH247_0, 0x8fc */
|
|
||||||
uint32_t scratch248; /* _SCRATCH248_0, 0x900 */
|
|
||||||
uint32_t scratch249; /* _SCRATCH249_0, 0x904 */
|
|
||||||
uint32_t scratch250; /* _SCRATCH250_0, 0x908 */
|
|
||||||
uint32_t scratch251; /* _SCRATCH251_0, 0x90c */
|
|
||||||
uint32_t scratch252; /* _SCRATCH252_0, 0x910 */
|
|
||||||
uint32_t scratch253; /* _SCRATCH253_0, 0x914 */
|
|
||||||
uint32_t scratch254; /* _SCRATCH254_0, 0x918 */
|
|
||||||
uint32_t scratch255; /* _SCRATCH255_0, 0x91c */
|
|
||||||
uint32_t scratch256; /* _SCRATCH256_0, 0x920 */
|
|
||||||
uint32_t scratch257; /* _SCRATCH257_0, 0x924 */
|
|
||||||
uint32_t scratch258; /* _SCRATCH258_0, 0x928 */
|
|
||||||
uint32_t scratch259; /* _SCRATCH259_0, 0x92c */
|
|
||||||
uint32_t scratch260; /* _SCRATCH260_0, 0x930 */
|
|
||||||
uint32_t scratch261; /* _SCRATCH261_0, 0x934 */
|
|
||||||
uint32_t scratch262; /* _SCRATCH262_0, 0x938 */
|
|
||||||
uint32_t scratch263; /* _SCRATCH263_0, 0x93c */
|
|
||||||
uint32_t scratch264; /* _SCRATCH264_0, 0x940 */
|
|
||||||
uint32_t scratch265; /* _SCRATCH265_0, 0x944 */
|
|
||||||
uint32_t scratch266; /* _SCRATCH266_0, 0x948 */
|
|
||||||
uint32_t scratch267; /* _SCRATCH267_0, 0x94c */
|
|
||||||
uint32_t scratch268; /* _SCRATCH268_0, 0x950 */
|
|
||||||
uint32_t scratch269; /* _SCRATCH269_0, 0x954 */
|
|
||||||
uint32_t scratch270; /* _SCRATCH270_0, 0x958 */
|
|
||||||
uint32_t scratch271; /* _SCRATCH271_0, 0x95c */
|
|
||||||
uint32_t scratch272; /* _SCRATCH272_0, 0x960 */
|
|
||||||
uint32_t scratch273; /* _SCRATCH273_0, 0x964 */
|
|
||||||
uint32_t scratch274; /* _SCRATCH274_0, 0x968 */
|
|
||||||
uint32_t scratch275; /* _SCRATCH275_0, 0x96c */
|
|
||||||
uint32_t scratch276; /* _SCRATCH276_0, 0x970 */
|
|
||||||
uint32_t scratch277; /* _SCRATCH277_0, 0x974 */
|
|
||||||
uint32_t scratch278; /* _SCRATCH278_0, 0x978 */
|
|
||||||
uint32_t scratch279; /* _SCRATCH279_0, 0x97c */
|
|
||||||
uint32_t scratch280; /* _SCRATCH280_0, 0x980 */
|
|
||||||
uint32_t scratch281; /* _SCRATCH281_0, 0x984 */
|
|
||||||
uint32_t scratch282; /* _SCRATCH282_0, 0x988 */
|
|
||||||
uint32_t scratch283; /* _SCRATCH283_0, 0x98c */
|
|
||||||
uint32_t scratch284; /* _SCRATCH284_0, 0x990 */
|
|
||||||
uint32_t scratch285; /* _SCRATCH285_0, 0x994 */
|
|
||||||
uint32_t scratch286; /* _SCRATCH286_0, 0x998 */
|
|
||||||
uint32_t scratch287; /* _SCRATCH287_0, 0x99c */
|
|
||||||
uint32_t scratch288; /* _SCRATCH288_0, 0x9a0 */
|
|
||||||
uint32_t scratch289; /* _SCRATCH289_0, 0x9a4 */
|
|
||||||
uint32_t scratch290; /* _SCRATCH290_0, 0x9a8 */
|
|
||||||
uint32_t scratch291; /* _SCRATCH291_0, 0x9ac */
|
|
||||||
uint32_t scratch292; /* _SCRATCH292_0, 0x9b0 */
|
|
||||||
uint32_t scratch293; /* _SCRATCH293_0, 0x9b4 */
|
|
||||||
uint32_t scratch294; /* _SCRATCH294_0, 0x9b8 */
|
|
||||||
uint32_t scratch295; /* _SCRATCH295_0, 0x9bc */
|
|
||||||
uint32_t scratch296; /* _SCRATCH296_0, 0x9c0 */
|
|
||||||
uint32_t scratch297; /* _SCRATCH297_0, 0x9c4 */
|
|
||||||
uint32_t scratch298; /* _SCRATCH298_0, 0x9c8 */
|
|
||||||
uint32_t scratch299; /* _SCRATCH299_0, 0x9cc */
|
|
||||||
uint32_t _0x9d0[50];
|
|
||||||
uint32_t secure_scratch80; /* _SECURE_SCRATCH80_0, 0xa98 */
|
|
||||||
uint32_t secure_scratch81; /* _SECURE_SCRATCH81_0, 0xa9c */
|
|
||||||
uint32_t secure_scratch82; /* _SECURE_SCRATCH82_0, 0xaa0 */
|
|
||||||
uint32_t secure_scratch83; /* _SECURE_SCRATCH83_0, 0xaa4 */
|
|
||||||
uint32_t secure_scratch84; /* _SECURE_SCRATCH84_0, 0xaa8 */
|
|
||||||
uint32_t secure_scratch85; /* _SECURE_SCRATCH85_0, 0xaac */
|
|
||||||
uint32_t secure_scratch86; /* _SECURE_SCRATCH86_0, 0xab0 */
|
|
||||||
uint32_t secure_scratch87; /* _SECURE_SCRATCH87_0, 0xab4 */
|
|
||||||
uint32_t secure_scratch88; /* _SECURE_SCRATCH88_0, 0xab8 */
|
|
||||||
uint32_t secure_scratch89; /* _SECURE_SCRATCH89_0, 0xabc */
|
|
||||||
uint32_t secure_scratch90; /* _SECURE_SCRATCH90_0, 0xac0 */
|
|
||||||
uint32_t secure_scratch91; /* _SECURE_SCRATCH91_0, 0xac4 */
|
|
||||||
uint32_t secure_scratch92; /* _SECURE_SCRATCH92_0, 0xac8 */
|
|
||||||
uint32_t secure_scratch93; /* _SECURE_SCRATCH93_0, 0xacc */
|
|
||||||
uint32_t secure_scratch94; /* _SECURE_SCRATCH94_0, 0xad0 */
|
|
||||||
uint32_t secure_scratch95; /* _SECURE_SCRATCH95_0, 0xad4 */
|
|
||||||
uint32_t secure_scratch96; /* _SECURE_SCRATCH96_0, 0xad8 */
|
|
||||||
uint32_t secure_scratch97; /* _SECURE_SCRATCH97_0, 0xadc */
|
|
||||||
uint32_t secure_scratch98; /* _SECURE_SCRATCH98_0, 0xae0 */
|
|
||||||
uint32_t secure_scratch99; /* _SECURE_SCRATCH99_0, 0xae4 */
|
|
||||||
uint32_t secure_scratch100; /* _SECURE_SCRATCH100_0, 0xae8 */
|
|
||||||
uint32_t secure_scratch101; /* _SECURE_SCRATCH101_0, 0xaec */
|
|
||||||
uint32_t secure_scratch102; /* _SECURE_SCRATCH102_0, 0xaf0 */
|
|
||||||
uint32_t secure_scratch103; /* _SECURE_SCRATCH103_0, 0xaf4 */
|
|
||||||
uint32_t secure_scratch104; /* _SECURE_SCRATCH104_0, 0xaf8 */
|
|
||||||
uint32_t secure_scratch105; /* _SECURE_SCRATCH105_0, 0xafc */
|
|
||||||
uint32_t secure_scratch106; /* _SECURE_SCRATCH106_0, 0xb00 */
|
|
||||||
uint32_t secure_scratch107; /* _SECURE_SCRATCH107_0, 0xb04 */
|
|
||||||
uint32_t secure_scratch108; /* _SECURE_SCRATCH108_0, 0xb08 */
|
|
||||||
uint32_t secure_scratch109; /* _SECURE_SCRATCH109_0, 0xb0c */
|
|
||||||
uint32_t secure_scratch110; /* _SECURE_SCRATCH110_0, 0xb10 */
|
|
||||||
uint32_t secure_scratch111; /* _SECURE_SCRATCH111_0, 0xb14 */
|
|
||||||
uint32_t secure_scratch112; /* _SECURE_SCRATCH112_0, 0xb18 */
|
|
||||||
uint32_t secure_scratch113; /* _SECURE_SCRATCH113_0, 0xb1c */
|
|
||||||
uint32_t secure_scratch114; /* _SECURE_SCRATCH114_0, 0xb20 */
|
|
||||||
uint32_t secure_scratch115; /* _SECURE_SCRATCH115_0, 0xb24 */
|
|
||||||
uint32_t secure_scratch116; /* _SECURE_SCRATCH116_0, 0xb28 */
|
|
||||||
uint32_t secure_scratch117; /* _SECURE_SCRATCH117_0, 0xb2c */
|
|
||||||
uint32_t secure_scratch118; /* _SECURE_SCRATCH118_0, 0xb30 */
|
|
||||||
uint32_t secure_scratch119; /* _SECURE_SCRATCH119_0, 0xb34 */
|
|
||||||
uint32_t secure_scratch120; /* _SECURE_SCRATCH120_0, 0xb38 */
|
|
||||||
uint32_t secure_scratch121; /* _SECURE_SCRATCH121_0, 0xb3c */
|
|
||||||
uint32_t secure_scratch122; /* _SECURE_SCRATCH122_0, 0xb40 */
|
|
||||||
uint32_t secure_scratch123; /* _SECURE_SCRATCH123_0, 0xb44 */
|
|
||||||
uint32_t led_breathing_ctrl; /* _LED_BREATHING_CTRL_0, 0xb48 */
|
|
||||||
uint32_t led_breathing_counter0; /* _LED_BREATHING_COUNTER0_0, 0xb4c */
|
|
||||||
uint32_t led_breathing_counter1; /* _LED_BREATHING_COUNTER1_0, 0xb50 */
|
|
||||||
uint32_t led_breathing_counter2; /* _LED_BREATHING_COUNTER2_0, 0xb54 */
|
|
||||||
uint32_t led_breathing_counter3; /* _LED_BREATHING_COUNTER3_0, 0xb58 */
|
|
||||||
uint32_t led_breathing_status; /* _LED_BREATHING_STATUS_0, 0xb5c */
|
|
||||||
uint32_t _0xb60[2];
|
|
||||||
uint32_t secure_scratch124; /* _SECURE_SCRATCH124_0, 0xb68 */
|
|
||||||
uint32_t secure_scratch125; /* _SECURE_SCRATCH125_0, 0xb6c */
|
|
||||||
uint32_t secure_scratch126; /* _SECURE_SCRATCH126_0, 0xb70 */
|
|
||||||
uint32_t secure_scratch127; /* _SECURE_SCRATCH127_0, 0xb74 */
|
|
||||||
uint32_t secure_scratch128; /* _SECURE_SCRATCH128_0, 0xb78 */
|
|
||||||
uint32_t secure_scratch129; /* _SECURE_SCRATCH129_0, 0xb7c */
|
|
||||||
uint32_t secure_scratch130; /* _SECURE_SCRATCH130_0, 0xb80 */
|
|
||||||
uint32_t secure_scratch131; /* _SECURE_SCRATCH131_0, 0xb84 */
|
|
||||||
uint32_t secure_scratch132; /* _SECURE_SCRATCH132_0, 0xb88 */
|
|
||||||
uint32_t secure_scratch133; /* _SECURE_SCRATCH133_0, 0xb8c */
|
|
||||||
uint32_t secure_scratch134; /* _SECURE_SCRATCH134_0, 0xb90 */
|
|
||||||
uint32_t secure_scratch135; /* _SECURE_SCRATCH135_0, 0xb94 */
|
|
||||||
uint32_t secure_scratch136; /* _SECURE_SCRATCH136_0, 0xb98 */
|
|
||||||
uint32_t secure_scratch137; /* _SECURE_SCRATCH137_0, 0xb9c */
|
|
||||||
uint32_t secure_scratch138; /* _SECURE_SCRATCH138_0, 0xba0 */
|
|
||||||
uint32_t secure_scratch139; /* _SECURE_SCRATCH139_0, 0xba4 */
|
|
||||||
uint32_t _0xba8[2];
|
|
||||||
uint32_t sec_disable_ns; /* _SEC_DISABLE_NS_0, 0xbb0 */
|
|
||||||
uint32_t sec_disable2_ns; /* _SEC_DISABLE2_NS_0, 0xbb4 */
|
|
||||||
uint32_t sec_disable3_ns; /* _SEC_DISABLE3_NS_0, 0xbb8 */
|
|
||||||
uint32_t sec_disable4_ns; /* _SEC_DISABLE4_NS_0, 0xbbc */
|
|
||||||
uint32_t sec_disable5_ns; /* _SEC_DISABLE5_NS_0, 0xbc0 */
|
|
||||||
uint32_t sec_disable6_ns; /* _SEC_DISABLE6_NS_0, 0xbc4 */
|
|
||||||
uint32_t sec_disable7_ns; /* _SEC_DISABLE7_NS_0, 0xbc8 */
|
|
||||||
uint32_t sec_disable8_ns; /* _SEC_DISABLE8_NS_0, 0xbcc */
|
|
||||||
uint32_t sec_disable9_ns; /* _SEC_DISABLE9_NS_0, 0xbd0 */
|
|
||||||
uint32_t sec_disable10_ns; /* _SEC_DISABLE10_NS_0, 0xbd4 */
|
|
||||||
uint32_t _0xbd8[4];
|
|
||||||
uint32_t tzram_pwr_cntrl; /* _TZRAM_PWR_CNTRL_0, 0xbe8 */
|
|
||||||
uint32_t tzram_sec_disable; /* _TZRAM_SEC_DISABLE_0, 0xbec */
|
|
||||||
uint32_t tzram_non_sec_disable; /* _TZRAM_NON_SEC_DISABLE_0, 0xbf0 */
|
|
||||||
} tegra_pmc_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_pmc_t *pmc_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_pmc_t *)PMC_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,649 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
#include "se.h"
|
|
||||||
|
|
||||||
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
|
|
||||||
/* Globals for driver. */
|
|
||||||
static unsigned int g_se_modulus_sizes[KEYSLOT_RSA_MAX];
|
|
||||||
static unsigned int g_se_exp_sizes[KEYSLOT_RSA_MAX];
|
|
||||||
|
|
||||||
/* Initialize a SE linked list. */
|
|
||||||
void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
|
|
||||||
ll->num_entries = 0; /* 1 Entry. */
|
|
||||||
|
|
||||||
if (buffer != NULL) {
|
|
||||||
ll->addr_info.address = (uint32_t) get_physical_address(buffer);
|
|
||||||
ll->addr_info.size = (uint32_t) size;
|
|
||||||
} else {
|
|
||||||
ll->addr_info.address = 0;
|
|
||||||
ll->addr_info.size = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_check_error_status_reg(void) {
|
|
||||||
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->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_verify_flags_cleared(void) {
|
|
||||||
if (se_get_regs()->SE_STATUS & 3) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the flags for an AES keyslot. */
|
|
||||||
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Misc flags. */
|
|
||||||
if (flags & ~0x80) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
|
||||||
if (flags & 0x80) {
|
|
||||||
se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the flags for an RSA keyslot. */
|
|
||||||
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Misc flags. */
|
|
||||||
if (flags & ~0x80) {
|
|
||||||
/* TODO: Why are flags assigned this way? */
|
|
||||||
se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
|
||||||
if (flags & 0x80) {
|
|
||||||
se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_aes_keyslot(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero out the whole keyslot and IV. */
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_rsa_keyslot(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero out the whole keyslot. */
|
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
|
||||||
/* Select Keyslot Modulus[i] */
|
|
||||||
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->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
|
||||||
se->SE_RSA_KEYTABLE_DATA = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (key_size >> 2); i++) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
|
||||||
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->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;
|
|
||||||
g_se_exp_sizes[keyslot] = exp_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_aes_keyslot_iv(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
|
||||||
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()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSLOT_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
uint8_t ALIGN(16) stack_buf[KEYSIZE_RSA_MAX];
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Endian swap the input. */
|
|
||||||
for (size_t i = 0; i < src_size; i++) {
|
|
||||||
stack_buf[i] = *((uint8_t *)src + src_size - i - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_get_exp_mod_output(void *buf, size_t size) {
|
|
||||||
size_t num_dwords = (size >> 2);
|
|
||||||
|
|
||||||
if (num_dwords < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t *p_out = ((uint32_t *)buf) + num_dwords - 1;
|
|
||||||
uint32_t offset = 0;
|
|
||||||
|
|
||||||
/* Copy endian swapped output. */
|
|
||||||
while (num_dwords) {
|
|
||||||
*p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset);
|
|
||||||
offset += 4;
|
|
||||||
p_out--;
|
|
||||||
num_dwords--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size) {
|
|
||||||
uint8_t message[RSA_2048_BYTES];
|
|
||||||
uint8_t h_buf[0x24];
|
|
||||||
|
|
||||||
/* Hardcode RSA with keyslot 0. */
|
|
||||||
const uint8_t public_exponent[4] = {0x00, 0x01, 0x00, 0x01};
|
|
||||||
set_rsa_keyslot(0, modulus, modulus_size, public_exponent, sizeof(public_exponent));
|
|
||||||
se_synchronous_exp_mod(0, message, sizeof(message), signature, signature_size);
|
|
||||||
|
|
||||||
/* Validate sanity byte. */
|
|
||||||
if (message[RSA_2048_BYTES - 1] != 0xBC) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy Salt into MGF1 Hash Buffer. */
|
|
||||||
memset(h_buf, 0, sizeof(h_buf));
|
|
||||||
memcpy(h_buf, message + RSA_2048_BYTES - 0x20 - 0x1, 0x20);
|
|
||||||
|
|
||||||
/* Decrypt maskedDB (via inline MGF1). */
|
|
||||||
uint8_t seed = 0;
|
|
||||||
uint8_t mgf1_buf[0x20];
|
|
||||||
for (unsigned int ofs = 0; ofs < RSA_2048_BYTES - 0x20 - 1; ofs += 0x20) {
|
|
||||||
h_buf[sizeof(h_buf) - 1] = seed++;
|
|
||||||
se_calculate_sha256(mgf1_buf, h_buf, sizeof(h_buf));
|
|
||||||
for (unsigned int i = ofs; i < ofs + 0x20 && i < RSA_2048_BYTES - 0x20 - 1; i++) {
|
|
||||||
message[i] ^= mgf1_buf[i - ofs];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Constant lmask for rsa-2048-pss. */
|
|
||||||
message[0] &= 0x7F;
|
|
||||||
|
|
||||||
/* Validate DB is of the form 0000...0001. */
|
|
||||||
for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) {
|
|
||||||
if (message[i] != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (message[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check hash correctness. */
|
|
||||||
uint8_t validate_buf[8 + 0x20 + 0x20];
|
|
||||||
uint8_t validate_hash[0x20];
|
|
||||||
|
|
||||||
memset(validate_buf, 0, sizeof(validate_buf));
|
|
||||||
se_calculate_sha256(&validate_buf[8], data, data_size);
|
|
||||||
memcpy(&validate_buf[0x28], &message[RSA_2048_BYTES - 0x20 - 0x20 - 1], 0x20);
|
|
||||||
se_calculate_sha256(validate_hash, validate_buf, sizeof(validate_buf));
|
|
||||||
return memcmp(h_buf, validate_hash, 0x20) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
se_ll_t in_ll;
|
|
||||||
se_ll_t out_ll;
|
|
||||||
|
|
||||||
ll_init(&in_ll, (void *)src, src_size);
|
|
||||||
ll_init(&out_ll, dst, dst_size);
|
|
||||||
|
|
||||||
/* Set the LLs. */
|
|
||||||
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->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
|
||||||
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
|
||||||
se->SE_OPERATION = op;
|
|
||||||
|
|
||||||
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
|
|
||||||
se_check_for_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Secure AES Functionality. */
|
|
||||||
void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
uint8_t block[0x10] = {0};
|
|
||||||
|
|
||||||
if (src_size > sizeof(block) || dst_size > sizeof(block)) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load src data into block. */
|
|
||||||
if (src_size != 0) {
|
|
||||||
memcpy(block, src, src_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Trigger AES operation. */
|
|
||||||
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. */
|
|
||||||
if (dst_size != 0) {
|
|
||||||
memcpy(dst, block, dst_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
unsigned int num_blocks = src_size >> 4;
|
|
||||||
|
|
||||||
/* Unknown what this write does, but official code writes it for CTR mode. */
|
|
||||||
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->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle final, unaligned block. */
|
|
||||||
if (aligned_size < dst_size && aligned_size < src_size) {
|
|
||||||
size_t last_block_size = dst_size - aligned_size;
|
|
||||||
if (src_size < dst_size) {
|
|
||||||
last_block_size = src_size - aligned_size;
|
|
||||||
}
|
|
||||||
se_perform_aes_block_operation(dst + aligned_size, last_block_size, (uint8_t *)src + aligned_size, src_size - aligned_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0x202);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
|
||||||
se->SE_CRYPTO_CONFIG = keyslot << 24;
|
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shift_left_xor_rb(uint8_t *key) {
|
|
||||||
uint8_t prev_high_bit = 0;
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
uint8_t cur_byte = key[0xF - i];
|
|
||||||
key[0xF - i] = (cur_byte << 1) | (prev_high_bit);
|
|
||||||
prev_high_bit = cur_byte >> 7;
|
|
||||||
}
|
|
||||||
if (prev_high_bit) {
|
|
||||||
key[0xF] ^= 0x87;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shift_left_xor_rb_le(uint8_t *key) {
|
|
||||||
uint8_t prev_high_bit = 0;
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
uint8_t cur_byte = key[i];
|
|
||||||
key[i] = (cur_byte << 1) | (prev_high_bit);
|
|
||||||
prev_high_bit = cur_byte >> 7;
|
|
||||||
}
|
|
||||||
if (prev_high_bit) {
|
|
||||||
key[0x0] ^= 0x87;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void aes_128_xts_nintendo_get_tweak(uint8_t *tweak, size_t sector) {
|
|
||||||
for (int i = 0xF; i >= 0; i--) { /* Nintendo LE custom tweak... */
|
|
||||||
tweak[i] = (unsigned char)(sector & 0xFF);
|
|
||||||
sector >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void aes_128_xts_nintendo_xor_with_tweak(unsigned int keyslot, size_t sector, uint8_t *dst, const uint8_t *src, size_t size) {
|
|
||||||
if ((size & 0xF) || size == 0) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
uint8_t tweak[0x10];
|
|
||||||
aes_128_xts_nintendo_get_tweak(tweak, sector);
|
|
||||||
se_aes_128_ecb_encrypt_block(keyslot, tweak, sizeof(tweak), tweak, sizeof(tweak));
|
|
||||||
|
|
||||||
for (unsigned int block = 0; block < (size >> 4); block++) {
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
dst[(block << 4) | i] = src[(block << 4) | i] ^ tweak[i];
|
|
||||||
}
|
|
||||||
shift_left_xor_rb_le(tweak);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keyslot_2, size_t sector, bool encrypt, void *dst, const void *src, size_t size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if ((size & 0xF) || size == 0) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XOR. */
|
|
||||||
aes_128_xts_nintendo_xor_with_tweak(keyslot_2, sector, dst, src, size);
|
|
||||||
|
|
||||||
/* Encrypt/Decrypt. */
|
|
||||||
if (encrypt) {
|
|
||||||
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
|
|
||||||
se->SE_CRYPTO_CONFIG = keyslot_1 << 24 | 0x100;
|
|
||||||
} else {
|
|
||||||
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
|
||||||
se->SE_CRYPTO_CONFIG = keyslot_1 << 24;
|
|
||||||
}
|
|
||||||
se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, size, src, size);
|
|
||||||
|
|
||||||
/* XOR. */
|
|
||||||
aes_128_xts_nintendo_xor_with_tweak(keyslot_2, sector, dst, dst, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Encrypt with AES-XTS (Nintendo's custom tweak). */
|
|
||||||
void se_aes_128_xts_nintendo_encrypt(unsigned int keyslot_1, unsigned int keyslot_2, size_t base_sector, void *dst, const void *src, size_t size, unsigned int sector_size) {
|
|
||||||
if ((size & 0xF) || size == 0) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
size_t sector = base_sector;
|
|
||||||
for (size_t ofs = 0; ofs < size; ofs += sector_size) {
|
|
||||||
aes_128_xts_nintendo_crypt_sector(keyslot_1, keyslot_2, sector, true, dst + ofs, src + ofs, sector_size);
|
|
||||||
sector++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrypt with AES-XTS (Nintendo's custom tweak). */
|
|
||||||
void se_aes_128_xts_nintendo_decrypt(unsigned int keyslot_1, unsigned int keyslot_2, size_t base_sector, void *dst, const void *src, size_t size, unsigned int sector_size) {
|
|
||||||
if ((size & 0xF) || size == 0) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
size_t sector = base_sector;
|
|
||||||
for (size_t ofs = 0; ofs < size; ofs += sector_size) {
|
|
||||||
aes_128_xts_nintendo_crypt_sector(keyslot_1, keyslot_2, sector, false, dst + ofs, src + ofs, sector_size);
|
|
||||||
sector++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate the derived key, to be XOR'd with final output block. */
|
|
||||||
uint8_t ALIGN(16) derived_key[0x10] = {0};
|
|
||||||
se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high);
|
|
||||||
shift_left_xor_rb(derived_key);
|
|
||||||
if (data_size & 0xF) {
|
|
||||||
shift_left_xor_rb(derived_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
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->SE_CRYPTO_LAST_BLOCK = num_blocks - 2;
|
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
|
||||||
se->SE_CRYPTO_CONFIG |= 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create final block. */
|
|
||||||
uint8_t ALIGN(16) last_block[0x10] = {0};
|
|
||||||
if (data_size & 0xF) {
|
|
||||||
memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF);
|
|
||||||
last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */
|
|
||||||
} else if (data_size >= 0x10) {
|
|
||||||
memcpy(last_block, data + data_size - 0x10, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
last_block[i] ^= derived_key[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform last operation. */
|
|
||||||
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->SE_HASH_RESULT, i << 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
|
|
||||||
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0);
|
|
||||||
}
|
|
||||||
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
|
|
||||||
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
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->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SHA256 Implementation. */
|
|
||||||
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->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->SE_HASH_RESULT, i << 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RNG API */
|
|
||||||
void se_initialize_rng(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* To initialize the RNG, we'll perform an RNG operation into an output buffer. */
|
|
||||||
/* This will be discarded, when done. */
|
|
||||||
uint8_t ALIGN(16) output_buf[0x10];
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t num_blocks = size >> 4;
|
|
||||||
size_t aligned_size = num_blocks << 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->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
|
|
||||||
}
|
|
||||||
if (size > aligned_size) {
|
|
||||||
se_perform_aes_block_operation(dst + aligned_size, size - aligned_size, NULL, 0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_SE_H
|
|
||||||
#define FUSEE_SE_H
|
|
||||||
|
|
||||||
#define SE_BASE 0x70012000
|
|
||||||
#define MAKE_SE_REG(n) MAKE_REG32(SE_BASE + n)
|
|
||||||
|
|
||||||
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
|
|
||||||
#define KEYSLOT_SWITCH_SRKGENKEY 0x8
|
|
||||||
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
|
|
||||||
#define KEYSLOT_SWITCH_TEMPKEY 0x9
|
|
||||||
#define KEYSLOT_SWITCH_SESSIONKEY 0xA
|
|
||||||
#define KEYSLOT_SWITCH_RNGKEY 0xB
|
|
||||||
#define KEYSLOT_SWITCH_MASTERKEY 0xC
|
|
||||||
#define KEYSLOT_SWITCH_DEVICEKEY 0xD
|
|
||||||
|
|
||||||
/* This keyslot was added in 4.0.0. */
|
|
||||||
#define KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY 0xD
|
|
||||||
#define KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY 0xE
|
|
||||||
#define KEYSLOT_SWITCH_4XOLDDEVICEKEY 0xF
|
|
||||||
|
|
||||||
/* This keyslot was added in 5.0.0. */
|
|
||||||
#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
|
|
||||||
|
|
||||||
/* Mariko keyslots. */
|
|
||||||
#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7
|
|
||||||
|
|
||||||
#define KEYSLOT_AES_MAX 0x10
|
|
||||||
#define KEYSLOT_RSA_MAX 0x2
|
|
||||||
|
|
||||||
#define KEYSIZE_AES_MAX 0x20
|
|
||||||
#define KEYSIZE_RSA_MAX 0x100
|
|
||||||
|
|
||||||
#define ALG_SHIFT (12)
|
|
||||||
#define ALG_DEC_SHIFT (8)
|
|
||||||
#define ALG_NOP (0 << ALG_SHIFT)
|
|
||||||
#define ALG_AES_ENC (1 << ALG_SHIFT)
|
|
||||||
#define ALG_AES_DEC ((1 << ALG_DEC_SHIFT) | ALG_NOP)
|
|
||||||
#define ALG_RNG (2 << ALG_SHIFT)
|
|
||||||
#define ALG_SHA (3 << ALG_SHIFT)
|
|
||||||
#define ALG_RSA (4 << ALG_SHIFT)
|
|
||||||
|
|
||||||
#define DST_SHIFT (2)
|
|
||||||
#define DST_MEMORY (0 << DST_SHIFT)
|
|
||||||
#define DST_HASHREG (1 << DST_SHIFT)
|
|
||||||
#define DST_KEYTAB (2 << DST_SHIFT)
|
|
||||||
#define DST_SRK (3 << DST_SHIFT)
|
|
||||||
#define DST_RSAREG (4 << DST_SHIFT)
|
|
||||||
|
|
||||||
#define ENCMODE_SHIFT (24)
|
|
||||||
#define DECMODE_SHIFT (16)
|
|
||||||
#define ENCMODE_SHA256 (5 << ENCMODE_SHIFT)
|
|
||||||
|
|
||||||
#define HASH_DISABLE (0x0)
|
|
||||||
#define HASH_ENABLE (0x1)
|
|
||||||
|
|
||||||
#define OP_ABORT 0
|
|
||||||
#define OP_START 1
|
|
||||||
#define OP_RESTART 2
|
|
||||||
#define OP_CTX_SAVE 3
|
|
||||||
#define OP_RESTART_IN 4
|
|
||||||
|
|
||||||
#define CTX_SAVE_SRC_SHIFT 29
|
|
||||||
#define CTX_SAVE_SRC_STICKY_BITS (0 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_KEYTABLE_AES (2 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_KEYTABLE_RSA (1 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_MEM (4 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_SRK (6 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
|
|
||||||
#define CTX_SAVE_KEY_LOW_BITS 0
|
|
||||||
#define CTX_SAVE_KEY_HIGH_BITS 1
|
|
||||||
#define CTX_SAVE_KEY_ORIGINAL_IV 2
|
|
||||||
#define CTX_SAVE_KEY_UPDATED_IV 3
|
|
||||||
|
|
||||||
#define CTX_SAVE_STICKY_BIT_INDEX_SHIFT 24
|
|
||||||
#define CTX_SAVE_KEY_INDEX_SHIFT 8
|
|
||||||
#define CTX_SAVE_RSA_KEY_INDEX_SHIFT 16
|
|
||||||
#define CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT 12
|
|
||||||
|
|
||||||
#define RSA_2048_BYTES 0x100
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
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;
|
|
||||||
uint32_t _0x820[0x5F8];
|
|
||||||
} tegra_se_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t address;
|
|
||||||
uint32_t size;
|
|
||||||
} se_addr_info_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t num_entries; /* Set to total entries - 1 */
|
|
||||||
se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */
|
|
||||||
} se_ll_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_se_t *se_get_regs(void) {
|
|
||||||
return (volatile tegra_se_t *)SE_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_check_error_status_reg(void);
|
|
||||||
void se_check_for_error(void);
|
|
||||||
void se_trigger_interrupt(void);
|
|
||||||
|
|
||||||
void se_validate_stored_vector(void);
|
|
||||||
void se_generate_stored_vector(void);
|
|
||||||
|
|
||||||
void se_verify_flags_cleared(void);
|
|
||||||
|
|
||||||
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
|
||||||
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
|
||||||
void clear_aes_keyslot(unsigned int keyslot);
|
|
||||||
void clear_rsa_keyslot(unsigned int keyslot);
|
|
||||||
|
|
||||||
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size);
|
|
||||||
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size);
|
|
||||||
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size);
|
|
||||||
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size);
|
|
||||||
void set_se_ctr(const void *ctr);
|
|
||||||
|
|
||||||
/* Secure AES API */
|
|
||||||
void se_aes_128_xts_nintendo_decrypt(unsigned int keyslot_1, unsigned int keyslot_2, unsigned int base_sector, void *dst, const void *src, size_t size, unsigned int sector_size);
|
|
||||||
void se_aes_128_xts_nintendo_encrypt(unsigned int keyslot_1, unsigned int keyslot_2, unsigned int base_sector, void *dst, const void *src, size_t size, unsigned int sector_size);
|
|
||||||
void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
|
|
||||||
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
|
|
||||||
void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size);
|
|
||||||
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv);
|
|
||||||
|
|
||||||
/* Hash API */
|
|
||||||
void se_calculate_sha256(void *dst, const void *src, size_t src_size);
|
|
||||||
|
|
||||||
/* RSA API */
|
|
||||||
void se_get_exp_mod_output(void *buf, size_t size);
|
|
||||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size);
|
|
||||||
|
|
||||||
/* RNG API */
|
|
||||||
void se_initialize_rng(unsigned int keyslot);
|
|
||||||
void se_generate_random(unsigned int keyslot, void *dst, size_t size);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.section .text.start, "ax", %progbits
|
|
||||||
.arm
|
|
||||||
.align 5
|
|
||||||
.global _start
|
|
||||||
.type _start, %function
|
|
||||||
_start:
|
|
||||||
/* Set coldboot */
|
|
||||||
mov r0, #0x0
|
|
||||||
ldr r1, =0x7000E400
|
|
||||||
str r0, [r1, #0x50]
|
|
||||||
|
|
||||||
/* Tell pk1ldr normal reboot, no error */
|
|
||||||
str r0, [r1, #0x1B4]
|
|
||||||
str r0, [r1, #0x840]
|
|
||||||
|
|
||||||
/* Cleanup SVC handler address. */
|
|
||||||
ldr r0, =0x40004C30
|
|
||||||
ldr r1, =0x6000F208
|
|
||||||
str r0, [r1]
|
|
||||||
|
|
||||||
/* Disable RCM forcefully */
|
|
||||||
mov r0, #0x4
|
|
||||||
ldr r1, =0x15DC
|
|
||||||
ldr r2, =0xE020
|
|
||||||
bl ipatch_word
|
|
||||||
|
|
||||||
/* Patch BCT signature check */
|
|
||||||
mov r0, #0x5
|
|
||||||
ldr r1, =0x4AEE
|
|
||||||
ldr r2, =0xE05B
|
|
||||||
bl ipatch_word
|
|
||||||
|
|
||||||
/* Patch bootloader read */
|
|
||||||
mov r0, #0x6
|
|
||||||
ldr r1, =0x4E88
|
|
||||||
ldr r2, =0xE018
|
|
||||||
bl ipatch_word
|
|
||||||
|
|
||||||
ldr r0, =__main_phys_start__
|
|
||||||
ldr r1, =__main_start__
|
|
||||||
mov r2, #0x0
|
|
||||||
ldr r3, =(__main_size__)
|
|
||||||
copy_panic_payload:
|
|
||||||
ldr r4, [r0, r2]
|
|
||||||
str r4, [r1, r2]
|
|
||||||
add r2, r2, #0x4
|
|
||||||
cmp r2, r3
|
|
||||||
bne copy_panic_payload
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Jump back to bootrom start. */
|
|
||||||
ldr r0, =0x101010
|
|
||||||
bx r0
|
|
||||||
|
|
||||||
/* Unused, but forces inclusion in binary. */
|
|
||||||
b main
|
|
||||||
|
|
||||||
|
|
||||||
.section .text.ipatch_word, "ax", %progbits
|
|
||||||
.arm
|
|
||||||
.align 5
|
|
||||||
.global ipatch_word
|
|
||||||
.type ipatch_word, %function
|
|
||||||
ipatch_word:
|
|
||||||
ldr r3, =0x6001dc00
|
|
||||||
lsl r0, r0, #0x2
|
|
||||||
lsr r1, r1, #0x1
|
|
||||||
lsl r1, r1, #0x10
|
|
||||||
orr r1, r1, r2
|
|
||||||
str r1, [r3, r0]
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.section .text.jump_to_main, "ax", %progbits
|
|
||||||
.arm
|
|
||||||
.align 5
|
|
||||||
.global jump_to_main
|
|
||||||
.type jump_to_main, %function
|
|
||||||
jump_to_main:
|
|
||||||
/* Insert 0x240 of NOPs, for version compatibility. */
|
|
||||||
.rept (0x240/4)
|
|
||||||
nop
|
|
||||||
.endr
|
|
||||||
/* Just jump to main */
|
|
||||||
ldr sp, =__stack_top__
|
|
||||||
b main
|
|
||||||
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_SYSREG_H
|
|
||||||
#define FUSEE_SYSREG_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define SYSREG_BASE 0x6000C000
|
|
||||||
#define SB_BASE (SYSREG_BASE + 0x200)
|
|
||||||
#define EXCP_VEC_BASE 0x6000F000
|
|
||||||
|
|
||||||
#define MAKE_SYSREG(n) MAKE_REG32(SYSREG_BASE + n)
|
|
||||||
#define MAKE_SB_REG(n) MAKE_REG32(SB_BASE + n)
|
|
||||||
#define MAKE_EXCP_VEC_REG(n) MAKE_REG32(EXCP_VEC_BASE + n)
|
|
||||||
|
|
||||||
#define AHB_ARBITRATION_DISABLE_0 MAKE_SYSREG(0x004)
|
|
||||||
#define AHB_ARBITRATION_XBAR_CTRL_0 MAKE_SYSREG(0x0E0)
|
|
||||||
#define AHB_AHB_SPARE_REG_0 MAKE_SYSREG(0x110)
|
|
||||||
|
|
||||||
#define SB_CSR_0 MAKE_SB_REG(0x00)
|
|
||||||
#define SB_PIROM_START_0 MAKE_SB_REG(0x04)
|
|
||||||
#define SB_PFCFG_0 MAKE_SB_REG(0x08)
|
|
||||||
#define SB_SECURE_SPAREREG_0_0 MAKE_SB_REG(0x0C)
|
|
||||||
#define SB_SECURE_SPAREREG_1_0 MAKE_SB_REG(0x10)
|
|
||||||
#define SB_SECURE_SPAREREG_2_0 MAKE_SB_REG(0x14)
|
|
||||||
#define SB_SECURE_SPAREREG_3_0 MAKE_SB_REG(0x18)
|
|
||||||
#define SB_SECURE_SPAREREG_4_0 MAKE_SB_REG(0x1C)
|
|
||||||
#define SB_SECURE_SPAREREG_5_0 MAKE_SB_REG(0x20)
|
|
||||||
#define SB_SECURE_SPAREREG_6_0 MAKE_SB_REG(0x24)
|
|
||||||
#define SB_SECURE_SPAREREG_7_0 MAKE_SB_REG(0x28)
|
|
||||||
#define SB_AA64_RESET_LOW_0 MAKE_SB_REG(0x30)
|
|
||||||
#define SB_AA64_RESET_HIGH_0 MAKE_SB_REG(0x34)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,101 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_TIMERS_H
|
|
||||||
#define FUSEE_TIMERS_H
|
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#define TIMERS_BASE 0x60005000
|
|
||||||
#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 0x7000E000
|
|
||||||
#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;
|
|
||||||
uint32_t COMMAND;
|
|
||||||
uint32_t PATTERN;
|
|
||||||
} watchdog_timers_t;
|
|
||||||
|
|
||||||
#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n))
|
|
||||||
#define WDT_REBOOT_PATTERN 0xC45A
|
|
||||||
#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8 * n)
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
|
@ -1,307 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_TSEC_H_
|
|
||||||
#define FUSEE_TSEC_H_
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#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 {
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return (volatile tegra_tsec_t *)TSEC_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "utils.h"
|
|
||||||
#include "se.h"
|
|
||||||
#include "fuse.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "panic.h"
|
|
||||||
#include "car.h"
|
|
||||||
#include "btn.h"
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
void wait(uint32_t microseconds) {
|
|
||||||
uint32_t old_time = TIMERUS_CNTR_1US_0;
|
|
||||||
while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
|
|
||||||
/* Spin-lock. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void watchdog_reboot(void) {
|
|
||||||
volatile watchdog_timers_t *wdt = GET_WDT(4);
|
|
||||||
wdt->PATTERN = WDT_REBOOT_PATTERN;
|
|
||||||
wdt->COMMAND = 2; /* Disable Counter. */
|
|
||||||
GET_WDT_REBOOT_CFG_REG(4) = 0xC0000000;
|
|
||||||
wdt->CONFIG = 0x8019; /* Full System Reset after Fourth Counter expires, using TIMER(9). */
|
|
||||||
wdt->COMMAND = 1; /* Enable Counter. */
|
|
||||||
while (true) {
|
|
||||||
/* Wait for reboot. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0) {
|
|
||||||
APBDEV_PMC_SCRATCH0_0 = scratch0;
|
|
||||||
|
|
||||||
/* Reset the processor. */
|
|
||||||
APBDEV_PMC_CONTROL = BIT(4);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
/* Wait for reboot. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void wait_for_button_and_reboot(void) {
|
|
||||||
uint32_t button;
|
|
||||||
while (true) {
|
|
||||||
button = btn_read();
|
|
||||||
if (button & BTN_POWER) {
|
|
||||||
pmc_reboot(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((noreturn)) void generic_panic(void) {
|
|
||||||
panic(0xFF000006);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noinline)) bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be)
|
|
||||||
{
|
|
||||||
if(as <= bs && bs <= ae)
|
|
||||||
return true;
|
|
||||||
if(bs <= as && as <= be)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_UTILS_H
|
|
||||||
#define FUSEE_UTILS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BIT(n) (1u << (n))
|
|
||||||
#define BITL(n) (1ull << (n))
|
|
||||||
#define MASK(n) (BIT(n) - 1)
|
|
||||||
#define MASKL(n) (BITL(n) - 1)
|
|
||||||
#define MASK2(a,b) (MASK(a) & ~MASK(b))
|
|
||||||
#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
|
|
||||||
|
|
||||||
#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
|
|
||||||
|
|
||||||
#define ALIGN(m) __attribute__((aligned(m)))
|
|
||||||
#define PACKED __attribute__((packed))
|
|
||||||
|
|
||||||
#define ALINLINE __attribute__((always_inline))
|
|
||||||
#define NOINLINE __attribute__((noinline))
|
|
||||||
|
|
||||||
#define SET_SYSREG(reg, val) do { temp_reg = (val); __asm__ __volatile__ ("msr " #reg ", %0" :: "r"(temp_reg) : "memory"); } while(false)
|
|
||||||
|
|
||||||
static inline uintptr_t get_physical_address(const void *addr) {
|
|
||||||
return (uintptr_t)addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t read32le(const volatile void *dword, size_t offset) {
|
|
||||||
uintptr_t addr = (uintptr_t)dword + offset;
|
|
||||||
volatile uint32_t *target = (uint32_t *)addr;
|
|
||||||
return *target;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t read32be(const volatile void *dword, size_t offset) {
|
|
||||||
return __builtin_bswap32(read32le(dword, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t read64le(const volatile void *qword, size_t offset) {
|
|
||||||
uintptr_t addr = (uintptr_t)qword + offset;
|
|
||||||
volatile uint64_t *target = (uint64_t *)addr;
|
|
||||||
return *target;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t read64be(const volatile void *qword, size_t offset) {
|
|
||||||
return __builtin_bswap64(read64le(qword, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write32le(volatile void *dword, size_t offset, uint32_t value) {
|
|
||||||
uintptr_t addr = (uintptr_t)dword + offset;
|
|
||||||
volatile uint32_t *target = (uint32_t *)addr;
|
|
||||||
*target = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write32be(volatile void *dword, size_t offset, uint32_t value) {
|
|
||||||
write32le(dword, offset, __builtin_bswap32(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write64le(volatile void *qword, size_t offset, uint64_t value) {
|
|
||||||
uintptr_t addr = (uintptr_t)qword + offset;
|
|
||||||
volatile uint64_t *target = (uint64_t *)addr;
|
|
||||||
*target = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write64be(volatile void *qword, size_t offset, uint64_t value) {
|
|
||||||
write64le(qword, offset, __builtin_bswap64(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_additive_overflow(uint32_t a, uint32_t b) {
|
|
||||||
return __builtin_add_overflow_p(a, b, (uint32_t)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_address_loadable(uintptr_t addr) {
|
|
||||||
/* FWIW the bootROM forbids loading anything between 0x40000000 and 0x40010000, using it for itself... */
|
|
||||||
return (addr >= 0x40010000u && addr < 0x40040000u) || addr >= 0x80000000u;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_address_range_loadable(uintptr_t addr, size_t size) {
|
|
||||||
return
|
|
||||||
!__builtin_add_overflow_p(addr, size, (uintptr_t)0) && /* the range doesn't overflow */
|
|
||||||
check_32bit_address_loadable(addr) && check_32bit_address_loadable(addr + size) && /* bounds are valid */
|
|
||||||
!(addr >= 0x40010000u && addr < 0x40040000u && addr + size >= 0x40040000u) /* the range doesn't cross MMIO */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be);
|
|
||||||
static inline bool overlaps_a(const void *as, const void *ae, const void *bs, const void *be) {
|
|
||||||
return overlaps((uint64_t)(uintptr_t)as, (uint64_t)(uintptr_t)ae, (uint64_t)(uintptr_t)bs, (uint64_t)(uintptr_t)be);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_address_range_in_program(uintptr_t addr, size_t size) {
|
|
||||||
extern uint8_t __chainloader_start__[], __chainloader_end__[];
|
|
||||||
extern uint8_t __stack_bottom__[], __stack_top__[];
|
|
||||||
extern uint8_t __start__[], __end__[];
|
|
||||||
uint8_t *start = (uint8_t *)addr, *end = start + size;
|
|
||||||
|
|
||||||
return overlaps_a(start, end, __chainloader_start__, __chainloader_end__) ||
|
|
||||||
overlaps_a(start, end, __stack_bottom__, __stack_top__) ||
|
|
||||||
overlaps_a(start, end, (void *)0xC0000000, (void *)0xC03C0000) || /* framebuffer */
|
|
||||||
overlaps_a(start, end, __start__, __end__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hexdump(const void* data, size_t size, uintptr_t addrbase);
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void watchdog_reboot(void);
|
|
||||||
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
|
|
||||||
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void generic_panic(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,38 +0,0 @@
|
||||||
NUM_KEYS = 2
|
|
||||||
|
|
||||||
HOVI_ENC_KEY_PRD = [
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
]
|
|
||||||
|
|
||||||
HOVI_SIG_KEY_PRD = [
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
]
|
|
||||||
|
|
||||||
HOVI_ENC_KEY_DEV = [
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
]
|
|
||||||
|
|
||||||
HOVI_SIG_KEY_DEV = [
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
]
|
|
||||||
|
|
||||||
IV = [
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
]
|
|
||||||
|
|
||||||
IV_DEV = [
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
bytearray.fromhex('00000000000000000000000000000000'),
|
|
||||||
]
|
|
||||||
|
|
||||||
assert len(HOVI_ENC_KEY_PRD) == NUM_KEYS
|
|
||||||
assert len(HOVI_SIG_KEY_PRD) == NUM_KEYS
|
|
||||||
assert len(HOVI_ENC_KEY_DEV) == NUM_KEYS
|
|
||||||
assert len(HOVI_SIG_KEY_DEV) == NUM_KEYS
|
|
||||||
assert len(IV) == NUM_KEYS
|
|
||||||
assert len(IV_DEV) == NUM_KEYS
|
|
|
@ -1,196 +0,0 @@
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
.SUFFIXES:
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEVKITARM)),)
|
|
||||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
|
||||||
endif
|
|
||||||
|
|
||||||
TOPDIR ?= $(CURDIR)
|
|
||||||
|
|
||||||
AMS := $(TOPDIR)/../../
|
|
||||||
include $(DEVKITARM)/base_rules
|
|
||||||
|
|
||||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
|
||||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
|
||||||
AMSREV := $(AMSREV)-dirty
|
|
||||||
endif
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# TARGET is the name of the output
|
|
||||||
# BUILD is the directory where object files & intermediate files will be placed
|
|
||||||
# SOURCES is a list of directories containing source code
|
|
||||||
# DATA is a list of directories containing data files
|
|
||||||
# INCLUDES is a list of directories containing header files
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
TARGET := $(notdir $(CURDIR))
|
|
||||||
BUILD := build
|
|
||||||
SOURCES := src ../../fusee/common ../../fusee/common/display ../../fusee/common/fatfs ../../fusee/common/sdmmc
|
|
||||||
DATA := data
|
|
||||||
INCLUDES := include ../../libraries/libvapours/include
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# options for code generation
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
|
||||||
DEFINES := -D__BPMP__ -DSEPT_STAGE2_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
|
||||||
|
|
||||||
CFLAGS := \
|
|
||||||
-g \
|
|
||||||
-gdwarf-4 \
|
|
||||||
-O2 \
|
|
||||||
-fomit-frame-pointer \
|
|
||||||
-ffunction-sections \
|
|
||||||
-fdata-sections \
|
|
||||||
-std=gnu11 \
|
|
||||||
-Werror \
|
|
||||||
-Wall \
|
|
||||||
-Wno-array-bounds \
|
|
||||||
-Wno-stringop-overflow \
|
|
||||||
-Wno-stringop-overread \
|
|
||||||
-fstrict-volatile-bitfields \
|
|
||||||
$(ARCH) $(DEFINES)
|
|
||||||
|
|
||||||
CFLAGS += $(INCLUDE)
|
|
||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
|
||||||
|
|
||||||
ASFLAGS := -g -gdwarf-4 $(ARCH)
|
|
||||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
|
|
||||||
|
|
||||||
LIBS :=
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# list of directories containing libraries, this must be the top level containing
|
|
||||||
# include and lib
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
LIBDIRS :=
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# no real need to edit anything past this point unless you need to add additional
|
|
||||||
# rules for different file extensions
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
|
||||||
export TOPDIR := $(CURDIR)
|
|
||||||
|
|
||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
|
||||||
$(AMS)/exosphere/program/rebootstub \
|
|
||||||
$(TOPDIR)/key_derivation
|
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
|
||||||
|
|
||||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
|
||||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) rebootstub.bin key_derivation.bin
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# use CXX for linking C++ projects, CC for standard C
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ifeq ($(strip $(CPPFILES)),)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export LD := $(CC)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
else
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export LD := $(CXX)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
|
||||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
|
||||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
|
||||||
|
|
||||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|
||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
|
||||||
-I$(CURDIR)/$(BUILD)
|
|
||||||
|
|
||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
|
||||||
|
|
||||||
.PHONY: $(BUILD) clean all check_rebootstub check_key_derivation
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
all: check_rebootstub check_key_derivation $(BUILD)
|
|
||||||
|
|
||||||
check_rebootstub:
|
|
||||||
@$(MAKE) -C $(AMS)/exosphere/program/rebootstub all
|
|
||||||
|
|
||||||
check_key_derivation:
|
|
||||||
@$(MAKE) -C key_derivation
|
|
||||||
|
|
||||||
$(BUILD): check_rebootstub check_key_derivation
|
|
||||||
ifeq ($(strip $(SEPT_00_ENC_PATH)),)
|
|
||||||
@[ -d $@ ] || mkdir -p $@
|
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
|
||||||
else
|
|
||||||
@touch $(TOPDIR)/$(TARGET).bin
|
|
||||||
@cp $(SEPT_00_ENC_PATH) $(TOPDIR)/$(TARGET)_00.enc
|
|
||||||
@cp $(SEPT_01_ENC_PATH) $(TOPDIR)/$(TARGET)_01.enc
|
|
||||||
@cp $(SEPT_DEV_00_ENC_PATH) $(TOPDIR)/$(TARGET)_dev_00.enc
|
|
||||||
@cp $(SEPT_DEV_01_ENC_PATH) $(TOPDIR)/$(TARGET)_dev_01.enc
|
|
||||||
endif
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
clean:
|
|
||||||
@echo clean ...
|
|
||||||
@$(MAKE) -C $(AMS)/exosphere/program/rebootstub clean
|
|
||||||
@$(MAKE) -C key_derivation clean
|
|
||||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET)_*.enc $(TARGET).elf
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
else
|
|
||||||
.PHONY: all
|
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# main targets
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
all : $(OUTPUT)_dev_01.enc
|
|
||||||
|
|
||||||
$(OUTPUT)_dev_01.enc : $(OUTPUT)_dev_00.enc
|
|
||||||
|
|
||||||
$(OUTPUT)_dev_00.enc : $(OUTPUT)_01.enc
|
|
||||||
|
|
||||||
$(OUTPUT)_01.enc : $(OUTPUT)_00.enc
|
|
||||||
|
|
||||||
$(OUTPUT)_00.enc : $(OUTPUT).bin
|
|
||||||
@python $(TOPDIR)/sept_sign.py $(OUTPUT).bin $(OUTPUT).enc
|
|
||||||
@echo built ... $(notdir $@)
|
|
||||||
|
|
||||||
$(OUTPUT).bin : $(OUTPUT).elf
|
|
||||||
$(OBJCOPY) -S -O binary $< $@
|
|
||||||
@echo built ... $(notdir $@)
|
|
||||||
|
|
||||||
$(OUTPUT).elf : $(OFILES)
|
|
||||||
|
|
||||||
%.elf: $(OFILES)
|
|
||||||
@echo linking $(notdir $@)
|
|
||||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
|
||||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
|
||||||
|
|
||||||
$(OFILES_SRC) : $(HFILES_BIN)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# you need a rule like this for each extension you use as binary data
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.bin.o %_bin.h: %.bin
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(bin2o)
|
|
||||||
|
|
||||||
-include $(DEPENDS)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
|
@ -1,158 +0,0 @@
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
.SUFFIXES:
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEVKITPRO)),)
|
|
||||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
|
||||||
endif
|
|
||||||
|
|
||||||
TOPDIR ?= $(CURDIR)
|
|
||||||
include $(DEVKITPRO)/devkitA64/base_rules
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# TARGET is the name of the output
|
|
||||||
# BUILD is the directory where object files & intermediate files will be placed
|
|
||||||
# SOURCES is a list of directories containing source code
|
|
||||||
# DATA is a list of directories containing data files
|
|
||||||
# INCLUDES is a list of directories containing header files
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
TARGET := $(notdir $(CURDIR))
|
|
||||||
BUILD := build
|
|
||||||
SOURCES := src
|
|
||||||
DATA := data
|
|
||||||
INCLUDES := include
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# options for code generation
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only #<- important
|
|
||||||
|
|
||||||
CFLAGS := \
|
|
||||||
-g \
|
|
||||||
-gdwarf-4 \
|
|
||||||
-Os \
|
|
||||||
-ffunction-sections \
|
|
||||||
-fdata-sections \
|
|
||||||
-fomit-frame-pointer \
|
|
||||||
-fno-inline \
|
|
||||||
-std=gnu11 \
|
|
||||||
-Werror \
|
|
||||||
-Wall \
|
|
||||||
-Wno-array-bounds \
|
|
||||||
-Wno-stringop-overflow \
|
|
||||||
-Wno-stringop-overread \
|
|
||||||
$(ARCH) $(DEFINES)
|
|
||||||
|
|
||||||
CFLAGS += $(INCLUDE)
|
|
||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
|
||||||
|
|
||||||
ASFLAGS := -g -gdwarf-4 $(ARCH)
|
|
||||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
|
|
||||||
|
|
||||||
LIBS :=
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# list of directories containing libraries, this must be the top level containing
|
|
||||||
# include and lib
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
LIBDIRS :=
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# no real need to edit anything past this point unless you need to add additional
|
|
||||||
# rules for different file extensions
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
|
||||||
export TOPDIR := $(CURDIR)
|
|
||||||
|
|
||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
|
||||||
|
|
||||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
|
||||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# use CXX for linking C++ projects, CC for standard C
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
ifeq ($(strip $(CPPFILES)),)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export LD := $(CC)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
else
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
export LD := $(CXX)
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
|
||||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
|
||||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
|
||||||
|
|
||||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|
||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
|
||||||
-I$(CURDIR)/$(BUILD)
|
|
||||||
|
|
||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
|
||||||
|
|
||||||
.PHONY: $(BUILD) clean all
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
all: $(BUILD)
|
|
||||||
|
|
||||||
$(BUILD):
|
|
||||||
@[ -d $@ ] || mkdir -p $@
|
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
clean:
|
|
||||||
@echo clean ...
|
|
||||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
else
|
|
||||||
.PHONY: all
|
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# main targets
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
all : $(OUTPUT).bin
|
|
||||||
|
|
||||||
$(OUTPUT).bin : $(OUTPUT).elf
|
|
||||||
$(OBJCOPY) -S -O binary $< $@
|
|
||||||
@echo built ... $(notdir $@)
|
|
||||||
|
|
||||||
$(OUTPUT).elf : $(OFILES)
|
|
||||||
|
|
||||||
%.elf: $(OFILES)
|
|
||||||
@echo linking $(notdir $@)
|
|
||||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
|
||||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
|
||||||
|
|
||||||
$(OFILES_SRC) : $(HFILES_BIN)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# you need a rule like this for each extension you use as binary data
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
%.bin.o : %.bin
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
@echo $(notdir $<)
|
|
||||||
@$(bin2o)
|
|
||||||
|
|
||||||
-include $(DEPENDS)
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
||||||
endif
|
|
||||||
#---------------------------------------------------------------------------------------
|
|
|
@ -1,17 +0,0 @@
|
||||||
OUTPUT_ARCH(aarch64)
|
|
||||||
|
|
||||||
ENTRY(_start)
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
. = 0x4003D000;
|
|
||||||
|
|
||||||
__start__ = ABSOLUTE(.);
|
|
||||||
|
|
||||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
|
||||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
|
||||||
.bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; }
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
|
|
||||||
__end__ = ABSOLUTE(.);
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
%rename link old_link
|
|
||||||
|
|
||||||
*link:
|
|
||||||
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
|
|
||||||
|
|
||||||
*startfile:
|
|
||||||
crti%O%s crtbegin%O%s
|
|
|
@ -1,155 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "se.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#define AL16 __attribute__((aligned(16)))
|
|
||||||
|
|
||||||
#define DERIVATION_ID_MAX 2
|
|
||||||
|
|
||||||
static const uint8_t AL16 keyblob_seed_00[0x10] = {
|
|
||||||
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 masterkey_seed[0x10] = {
|
|
||||||
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 devicekey_seed[0x10] = {
|
|
||||||
0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 devicekey_4x_seed[0x10] = {
|
|
||||||
0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 masterkey_4x_seed[0x10] = {
|
|
||||||
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 zeroes[0x10] = {
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Note: 9.0.0 did not change the TSEC firmware. Thus, the root key is the same. */
|
|
||||||
/* To avoid distribution of more and more sept binaries, we will simply derive the 9.0.0 master key */
|
|
||||||
/* on 8.1.0 and 9.0.0. Exosphere supports this already with no issues. */
|
|
||||||
|
|
||||||
static const uint8_t AL16 master_kek_seeds[DERIVATION_ID_MAX][0x10] = {
|
|
||||||
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C},
|
|
||||||
/* 8.1.0: {0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41}, */
|
|
||||||
/* 9.0.0: {0x1A, 0xEC, 0x11, 0x82, 0x2B, 0x32, 0x38, 0x7A, 0x2B, 0xED, 0xBA, 0x01, 0x47, 0x7E, 0x3B, 0x67}, */
|
|
||||||
/* 9.1.0: {0x30, 0x3F, 0x02, 0x7E, 0xD8, 0x38, 0xEC, 0xD7, 0x93, 0x25, 0x34, 0xB5, 0x30, 0xEB, 0xCA, 0x7A}, */
|
|
||||||
{0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 master_devkey_seeds[DERIVATION_ID_MAX][0x10] = {
|
|
||||||
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D},
|
|
||||||
/* 8.1.0: {0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, */
|
|
||||||
/* 9.0.0: {0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, */
|
|
||||||
/* 9.1.0: {0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, */
|
|
||||||
{0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t AL16 master_devkey_vectors[DERIVATION_ID_MAX][0x10] = {
|
|
||||||
{0xD8, 0xD3, 0x67, 0x4F, 0xF3, 0xA2, 0xA4, 0x4E, 0xE4, 0x04, 0x37, 0xC2, 0xD9, 0xCF, 0x41, 0x6F},
|
|
||||||
/* 8.1.0: {0x72, 0xD0, 0xAD, 0xEB, 0xE1, 0xF6, 0x35, 0x90, 0xB4, 0x43, 0xCC, 0x4B, 0xC4, 0xDC, 0x88, 0x0A}, */
|
|
||||||
/* 9.0.0: {0x8B, 0xD6, 0x13, 0x2F, 0xC3, 0x4D, 0x53, 0x2D, 0x10, 0xA1, 0x63, 0x85, 0x49, 0x2B, 0xCF, 0x3F}, */
|
|
||||||
/* 9.1.0: {0xA8, 0x58, 0x05, 0x8D, 0xDD, 0x9A, 0xA0, 0x2F, 0x01, 0x62, 0x4A, 0x6B, 0xC6, 0x77, 0xE9, 0x86}, */
|
|
||||||
{0x95, 0x7E, 0x99, 0xB4, 0x4B, 0xDE, 0xA0, 0xA3, 0x9A, 0x51, 0xF0, 0x32, 0xB7, 0xDF, 0x89, 0x0D},
|
|
||||||
};
|
|
||||||
|
|
||||||
void derive_keys(void) {
|
|
||||||
/* Set mailbox. */
|
|
||||||
volatile uint32_t *mailbox = (volatile uint32_t *)0x4003FF00;
|
|
||||||
const uint32_t derivation_id = *((volatile uint32_t *)0x4003E800);
|
|
||||||
|
|
||||||
if (derivation_id < DERIVATION_ID_MAX) {
|
|
||||||
uint8_t *enc_se_state = (uint8_t *)0x4003E000;
|
|
||||||
|
|
||||||
uint32_t AL16 work_buffer[4];
|
|
||||||
|
|
||||||
/* Derive Keyblob Key 00. */
|
|
||||||
se_aes_ecb_decrypt_block(0xC, work_buffer, 0x10, keyblob_seed_00, 0x10);
|
|
||||||
decrypt_data_into_keyslot(0xF, 0xE, work_buffer, 0x10);
|
|
||||||
|
|
||||||
/* Derive master kek. */
|
|
||||||
decrypt_data_into_keyslot(0xE, 0xD, master_kek_seeds[derivation_id], 0x10);
|
|
||||||
|
|
||||||
/* Clear the copy of the root key inside the SE. */
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
|
|
||||||
/* Derive master key, device master key. */
|
|
||||||
decrypt_data_into_keyslot(0xC, 0xE, masterkey_seed, 0x10);
|
|
||||||
decrypt_data_into_keyslot(0xE, 0xE, masterkey_4x_seed, 0x10);
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
|
|
||||||
/* Derive device keys. */
|
|
||||||
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
|
|
||||||
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
|
|
||||||
/* Derive firmware specific device key. */
|
|
||||||
se_aes_ecb_decrypt_block(0xA, work_buffer, 0x10, master_devkey_seeds[derivation_id], 0x10);
|
|
||||||
decrypt_data_into_keyslot(0xE, 0xE, work_buffer, 0x10);
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
|
|
||||||
/* Test against a vector. */
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
work_buffer[i] = 0;
|
|
||||||
}
|
|
||||||
if (memcmp(work_buffer, zeroes, 0x10) != 0) {
|
|
||||||
clear_aes_keyslot(0xE);
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
clear_aes_keyslot(0xC);
|
|
||||||
clear_aes_keyslot(0xA);
|
|
||||||
clear_aes_keyslot(0xF);
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
se_aes_ecb_decrypt_block(0xE, work_buffer, 0x10, master_devkey_vectors[derivation_id], 0x10);
|
|
||||||
|
|
||||||
if (memcmp(work_buffer, zeroes, 0x10) == 0) {
|
|
||||||
clear_aes_keyslot(0xE);
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
clear_aes_keyslot(0xC);
|
|
||||||
clear_aes_keyslot(0xA);
|
|
||||||
clear_aes_keyslot(0xF);
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear work buffer. */
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
work_buffer[i] = 0xCCCCCCCC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save context for real. */
|
|
||||||
se_set_in_context_save_mode(true);
|
|
||||||
se_save_context(KEYSLOT_SWITCH_SRKGENKEY, KEYSLOT_SWITCH_RNGKEY, enc_se_state);
|
|
||||||
se_set_in_context_save_mode(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear all keyslots. */
|
|
||||||
for (size_t i = 0; i < 0x10; i++) {
|
|
||||||
clear_aes_keyslot(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
*mailbox = 7;
|
|
||||||
while (1) { /* Wait for sept to handle the rest. */ }
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SEPT_KEYDERIVATION_H
|
|
||||||
#define SEPT_KEYDERIVATION_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void derive_keys(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,713 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_PMC_H
|
|
||||||
#define FUSEE_PMC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
/* Power Management Controller (APBDEV_PMC_) regs */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t cntrl; /* _CNTRL_0, 0x00 */
|
|
||||||
uint32_t sec_disable; /* _SEC_DISABLE_0, 0x04 */
|
|
||||||
uint32_t pmc_swrst; /* _PMC_SWRST_0, 0x08 */
|
|
||||||
uint32_t wake_mask; /* _WAKE_MASK_0, 0x0c */
|
|
||||||
uint32_t wake_lvl; /* _WAKE_LVL_0, 0x10 */
|
|
||||||
uint32_t wake_status; /* _WAKE_STATUS_0, 0x14 */
|
|
||||||
uint32_t sw_wake_status; /* _SW_WAKE_STATUS_0, 0x18 */
|
|
||||||
uint32_t dpd_pads_oride; /* _DPD_PADS_ORIDE_0, 0x1c */
|
|
||||||
uint32_t dpd_sample; /* _DPD_SAMPLE_0, 0x20 */
|
|
||||||
uint32_t dpd_enable; /* _DPD_ENABLE_0, 0x24 */
|
|
||||||
uint32_t pwrgate_timer_off; /* _PWRGATE_TIMER_OFF_0, 0x28 */
|
|
||||||
uint32_t clamp_status; /* _CLAMP_STATUS_0, 0x2c */
|
|
||||||
uint32_t pwrgate_toggle; /* _PWRGATE_TOGGLE_0, 0x30 */
|
|
||||||
uint32_t remove_clamping; /* _REMOVE_CLAMPING_0, 0x34 */
|
|
||||||
uint32_t pwrgate_status; /* _PWRGATE_STATUS_0, 0x38 */
|
|
||||||
uint32_t pwrgood_timer; /* _PWRGOOD_TIMER_0, 0x3c */
|
|
||||||
uint32_t blink_timer; /* _BLINK_TIMER_0, 0x40 */
|
|
||||||
uint32_t no_iopower; /* _NO_IOPOWER_0, 0x44 */
|
|
||||||
uint32_t pwr_det; /* _PWR_DET_0, 0x48 */
|
|
||||||
uint32_t pwr_det_latch; /* _PWR_DET_LATCH_0, 0x4c */
|
|
||||||
uint32_t scratch0; /* _SCRATCH0_0, 0x50 */
|
|
||||||
uint32_t scratch1; /* _SCRATCH1_0, 0x54 */
|
|
||||||
uint32_t scratch2; /* _SCRATCH2_0, 0x58 */
|
|
||||||
uint32_t scratch3; /* _SCRATCH3_0, 0x5c */
|
|
||||||
uint32_t scratch4; /* _SCRATCH4_0, 0x60 */
|
|
||||||
uint32_t scratch5; /* _SCRATCH5_0, 0x64 */
|
|
||||||
uint32_t scratch6; /* _SCRATCH6_0, 0x68 */
|
|
||||||
uint32_t scratch7; /* _SCRATCH7_0, 0x6c */
|
|
||||||
uint32_t scratch8; /* _SCRATCH8_0, 0x70 */
|
|
||||||
uint32_t scratch9; /* _SCRATCH9_0, 0x74 */
|
|
||||||
uint32_t scratch10; /* _SCRATCH10_0, 0x78 */
|
|
||||||
uint32_t scratch11; /* _SCRATCH11_0, 0x7c */
|
|
||||||
uint32_t scratch12; /* _SCRATCH12_0, 0x80 */
|
|
||||||
uint32_t scratch13; /* _SCRATCH13_0, 0x84 */
|
|
||||||
uint32_t scratch14; /* _SCRATCH14_0, 0x88 */
|
|
||||||
uint32_t scratch15; /* _SCRATCH15_0, 0x8c */
|
|
||||||
uint32_t scratch16; /* _SCRATCH16_0, 0x90 */
|
|
||||||
uint32_t scratch17; /* _SCRATCH17_0, 0x94 */
|
|
||||||
uint32_t scratch18; /* _SCRATCH18_0, 0x98 */
|
|
||||||
uint32_t scratch19; /* _SCRATCH19_0, 0x9c */
|
|
||||||
uint32_t scratch20; /* _SCRATCH20_0, 0xa0 */
|
|
||||||
uint32_t scratch21; /* _SCRATCH21_0, 0xa4 */
|
|
||||||
uint32_t scratch22; /* _SCRATCH22_0, 0xa8 */
|
|
||||||
uint32_t scratch23; /* _SCRATCH23_0, 0xac */
|
|
||||||
uint32_t secure_scratch0; /* _SECURE_SCRATCH0_0, 0xb0 */
|
|
||||||
uint32_t secure_scratch1; /* _SECURE_SCRATCH1_0, 0xb4 */
|
|
||||||
uint32_t secure_scratch2; /* _SECURE_SCRATCH2_0, 0xb8 */
|
|
||||||
uint32_t secure_scratch3; /* _SECURE_SCRATCH3_0, 0xbc */
|
|
||||||
uint32_t secure_scratch4; /* _SECURE_SCRATCH4_0, 0xc0 */
|
|
||||||
uint32_t secure_scratch5; /* _SECURE_SCRATCH5_0, 0xc4 */
|
|
||||||
uint32_t cpupwrgood_timer; /* _CPUPWRGOOD_TIMER_0, 0xc8 */
|
|
||||||
uint32_t cpupwroff_timer; /* _CPUPWROFF_TIMER_0, 0xcc */
|
|
||||||
uint32_t pg_mask; /* _PG_MASK_0, 0xd0 */
|
|
||||||
uint32_t pg_mask_1; /* _PG_MASK_1_0, 0xd4 */
|
|
||||||
uint32_t auto_wake_lvl; /* _AUTO_WAKE_LVL_0, 0xd8 */
|
|
||||||
uint32_t auto_wake_lvl_mask; /* _AUTO_WAKE_LVL_MASK_0, 0xdc */
|
|
||||||
uint32_t wake_delay; /* _WAKE_DELAY_0, 0xe0 */
|
|
||||||
uint32_t pwr_det_val; /* _PWR_DET_VAL_0, 0xe4 */
|
|
||||||
uint32_t ddr_pwr; /* _DDR_PWR_0, 0xe8 */
|
|
||||||
uint32_t usb_debounce_del; /* _USB_DEBOUNCE_DEL_0, 0xec */
|
|
||||||
uint32_t usb_ao; /* _USB_AO_0, 0xf0 */
|
|
||||||
uint32_t crypto_op; /* _CRYPTO_OP_0, 0xf4 */
|
|
||||||
uint32_t pllp_wb0_override; /* _PLLP_WB0_OVERRIDE_0, 0xf8 */
|
|
||||||
uint32_t scratch24; /* _SCRATCH24_0, 0xfc */
|
|
||||||
uint32_t scratch25; /* _SCRATCH25_0, 0x100 */
|
|
||||||
uint32_t scratch26; /* _SCRATCH26_0, 0x104 */
|
|
||||||
uint32_t scratch27; /* _SCRATCH27_0, 0x108 */
|
|
||||||
uint32_t scratch28; /* _SCRATCH28_0, 0x10c */
|
|
||||||
uint32_t scratch29; /* _SCRATCH29_0, 0x110 */
|
|
||||||
uint32_t scratch30; /* _SCRATCH30_0, 0x114 */
|
|
||||||
uint32_t scratch31; /* _SCRATCH31_0, 0x118 */
|
|
||||||
uint32_t scratch32; /* _SCRATCH32_0, 0x11c */
|
|
||||||
uint32_t scratch33; /* _SCRATCH33_0, 0x120 */
|
|
||||||
uint32_t scratch34; /* _SCRATCH34_0, 0x124 */
|
|
||||||
uint32_t scratch35; /* _SCRATCH35_0, 0x128 */
|
|
||||||
uint32_t scratch36; /* _SCRATCH36_0, 0x12c */
|
|
||||||
uint32_t scratch37; /* _SCRATCH37_0, 0x130 */
|
|
||||||
uint32_t scratch38; /* _SCRATCH38_0, 0x134 */
|
|
||||||
uint32_t scratch39; /* _SCRATCH39_0, 0x138 */
|
|
||||||
uint32_t scratch40; /* _SCRATCH40_0, 0x13c */
|
|
||||||
uint32_t scratch41; /* _SCRATCH41_0, 0x140 */
|
|
||||||
uint32_t scratch42; /* _SCRATCH42_0, 0x144 */
|
|
||||||
uint32_t bondout_mirror0; /* _BONDOUT_MIRROR0_0, 0x148 */
|
|
||||||
uint32_t bondout_mirror1; /* _BONDOUT_MIRROR1_0, 0x14c */
|
|
||||||
uint32_t bondout_mirror2; /* _BONDOUT_MIRROR2_0, 0x150 */
|
|
||||||
uint32_t sys_33v_en; /* _SYS_33V_EN_0, 0x154 */
|
|
||||||
uint32_t bondout_mirror_access; /* _BONDOUT_MIRROR_ACCESS_0, 0x158 */
|
|
||||||
uint32_t gate; /* _GATE_0, 0x15c */
|
|
||||||
uint32_t wake2_mask; /* _WAKE2_MASK_0, 0x160 */
|
|
||||||
uint32_t wake2_lvl; /* _WAKE2_LVL_0, 0x164 */
|
|
||||||
uint32_t wake2_status; /* _WAKE2_STATUS_0, 0x168 */
|
|
||||||
uint32_t sw_wake2_status; /* _SW_WAKE2_STATUS_0, 0x16c */
|
|
||||||
uint32_t auto_wake2_lvl_mask; /* _AUTO_WAKE2_LVL_MASK_0, 0x170 */
|
|
||||||
uint32_t pg_mask_2; /* _PG_MASK_2_0, 0x174 */
|
|
||||||
uint32_t pg_mask_ce1; /* _PG_MASK_CE1_0, 0x178 */
|
|
||||||
uint32_t pg_mask_ce2; /* _PG_MASK_CE2_0, 0x17c */
|
|
||||||
uint32_t pg_mask_ce3; /* _PG_MASK_CE3_0, 0x180 */
|
|
||||||
uint32_t pwrgate_timer_ce_0; /* _PWRGATE_TIMER_CE_0_0, 0x184 */
|
|
||||||
uint32_t pwrgate_timer_ce_1; /* _PWRGATE_TIMER_CE_1_0, 0x188 */
|
|
||||||
uint32_t pwrgate_timer_ce_2; /* _PWRGATE_TIMER_CE_2_0, 0x18c */
|
|
||||||
uint32_t pwrgate_timer_ce_3; /* _PWRGATE_TIMER_CE_3_0, 0x190 */
|
|
||||||
uint32_t pwrgate_timer_ce_4; /* _PWRGATE_TIMER_CE_4_0, 0x194 */
|
|
||||||
uint32_t pwrgate_timer_ce_5; /* _PWRGATE_TIMER_CE_5_0, 0x198 */
|
|
||||||
uint32_t pwrgate_timer_ce_6; /* _PWRGATE_TIMER_CE_6_0, 0x19c */
|
|
||||||
uint32_t pcx_edpd_cntrl; /* _PCX_EDPD_CNTRL_0, 0x1a0 */
|
|
||||||
uint32_t osc_edpd_over; /* _OSC_EDPD_OVER_0, 0x1a4 */
|
|
||||||
uint32_t clk_out_cntrl; /* _CLK_OUT_CNTRL_0, 0x1a8 */
|
|
||||||
uint32_t sata_pwrgt; /* _SATA_PWRGT_0, 0x1ac */
|
|
||||||
uint32_t sensor_ctrl; /* _SENSOR_CTRL_0, 0x1b0 */
|
|
||||||
uint32_t rst_status; /* _RST_STATUS_0, 0x1b4 */
|
|
||||||
uint32_t io_dpd_req; /* _IO_DPD_REQ_0, 0x1b8 */
|
|
||||||
uint32_t io_dpd_status; /* _IO_DPD_STATUS_0, 0x1bc */
|
|
||||||
uint32_t io_dpd2_req; /* _IO_DPD2_REQ_0, 0x1c0 */
|
|
||||||
uint32_t io_dpd2_status; /* _IO_DPD2_STATUS_0, 0x1c4 */
|
|
||||||
uint32_t sel_dpd_tim; /* _SEL_DPD_TIM_0, 0x1c8 */
|
|
||||||
uint32_t vddp_sel; /* _VDDP_SEL_0, 0x1cc */
|
|
||||||
uint32_t ddr_cfg; /* _DDR_CFG_0, 0x1d0 */
|
|
||||||
uint32_t _0x1d4[2];
|
|
||||||
uint32_t pllm_wb0_override_freq; /* _PLLM_WB0_OVERRIDE_FREQ_0, 0x1dc */
|
|
||||||
uint32_t _0x1e0;
|
|
||||||
uint32_t pwrgate_timer_mult; /* _PWRGATE_TIMER_MULT_0, 0x1e4 */
|
|
||||||
uint32_t dsi_sel_dpd; /* _DSI_SEL_DPD_0, 0x1e8 */
|
|
||||||
uint32_t utmip_uhsic_triggers; /* _UTMIP_UHSIC_TRIGGERS_0, 0x1ec */
|
|
||||||
uint32_t utmip_uhsic_saved_state; /* _UTMIP_UHSIC_SAVED_STATE_0, 0x1f0 */
|
|
||||||
uint32_t _0x1f4;
|
|
||||||
uint32_t utmip_term_pad_cfg; /* _UTMIP_TERM_PAD_CFG_0, 0x1f8 */
|
|
||||||
uint32_t utmip_uhsic_sleep_cfg; /* _UTMIP_UHSIC_SLEEP_CFG_0, 0x1fc */
|
|
||||||
uint32_t utmip_uhsic_sleepwalk_cfg; /* _UTMIP_UHSIC_SLEEPWALK_CFG_0, 0x200 */
|
|
||||||
uint32_t utmip_sleepwalk_p0; /* _UTMIP_SLEEPWALK_P0_0, 0x204 */
|
|
||||||
uint32_t utmip_sleepwalk_p1; /* _UTMIP_SLEEPWALK_P1_0, 0x208 */
|
|
||||||
uint32_t utmip_sleepwalk_p2; /* _UTMIP_SLEEPWALK_P2_0, 0x20c */
|
|
||||||
uint32_t uhsic_sleepwalk_p0; /* _UHSIC_SLEEPWALK_P0_0, 0x210 */
|
|
||||||
uint32_t utmip_uhsic_status; /* _UTMIP_UHSIC_STATUS_0, 0x214 */
|
|
||||||
uint32_t utmip_uhsic_fake; /* _UTMIP_UHSIC_FAKE_0, 0x218 */
|
|
||||||
uint32_t bondout_mirror3; /* _BONDOUT_MIRROR3_0, 0x21c */
|
|
||||||
uint32_t bondout_mirror4; /* _BONDOUT_MIRROR4_0, 0x220 */
|
|
||||||
uint32_t secure_scratch6; /* _SECURE_SCRATCH6_0, 0x224 */
|
|
||||||
uint32_t secure_scratch7; /* _SECURE_SCRATCH7_0, 0x228 */
|
|
||||||
uint32_t scratch43; /* _SCRATCH43_0, 0x22c */
|
|
||||||
uint32_t scratch44; /* _SCRATCH44_0, 0x230 */
|
|
||||||
uint32_t scratch45; /* _SCRATCH45_0, 0x234 */
|
|
||||||
uint32_t scratch46; /* _SCRATCH46_0, 0x238 */
|
|
||||||
uint32_t scratch47; /* _SCRATCH47_0, 0x23c */
|
|
||||||
uint32_t scratch48; /* _SCRATCH48_0, 0x240 */
|
|
||||||
uint32_t scratch49; /* _SCRATCH49_0, 0x244 */
|
|
||||||
uint32_t scratch50; /* _SCRATCH50_0, 0x248 */
|
|
||||||
uint32_t scratch51; /* _SCRATCH51_0, 0x24c */
|
|
||||||
uint32_t scratch52; /* _SCRATCH52_0, 0x250 */
|
|
||||||
uint32_t scratch53; /* _SCRATCH53_0, 0x254 */
|
|
||||||
uint32_t scratch54; /* _SCRATCH54_0, 0x258 */
|
|
||||||
uint32_t scratch55; /* _SCRATCH55_0, 0x25c */
|
|
||||||
uint32_t scratch0_eco; /* _SCRATCH0_ECO_0, 0x260 */
|
|
||||||
uint32_t por_dpd_ctrl; /* _POR_DPD_CTRL_0, 0x264 */
|
|
||||||
uint32_t scratch2_eco; /* _SCRATCH2_ECO_0, 0x268 */
|
|
||||||
uint32_t utmip_uhsic_line_wakeup; /* _UTMIP_UHSIC_LINE_WAKEUP_0, 0x26c */
|
|
||||||
uint32_t utmip_bias_master_cntrl; /* _UTMIP_BIAS_MASTER_CNTRL_0, 0x270 */
|
|
||||||
uint32_t utmip_master_config; /* _UTMIP_MASTER_CONFIG_0, 0x274 */
|
|
||||||
uint32_t td_pwrgate_inter_part_timer; /* _TD_PWRGATE_INTER_PART_TIMER_0, 0x278 */
|
|
||||||
uint32_t utmip_uhsic2_triggers; /* _UTMIP_UHSIC2_TRIGGERS_0, 0x27c */
|
|
||||||
uint32_t utmip_uhsic2_saved_state; /* _UTMIP_UHSIC2_SAVED_STATE_0, 0x280 */
|
|
||||||
uint32_t utmip_uhsic2_sleep_cfg; /* _UTMIP_UHSIC2_SLEEP_CFG_0, 0x284 */
|
|
||||||
uint32_t utmip_uhsic2_sleepwalk_cfg; /* _UTMIP_UHSIC2_SLEEPWALK_CFG_0, 0x288 */
|
|
||||||
uint32_t uhsic2_sleepwalk_p1; /* _UHSIC2_SLEEPWALK_P1_0, 0x28c */
|
|
||||||
uint32_t utmip_uhsic2_status; /* _UTMIP_UHSIC2_STATUS_0, 0x290 */
|
|
||||||
uint32_t utmip_uhsic2_fake; /* _UTMIP_UHSIC2_FAKE_0, 0x294 */
|
|
||||||
uint32_t utmip_uhsic2_line_wakeup; /* _UTMIP_UHSIC2_LINE_WAKEUP_0, 0x298 */
|
|
||||||
uint32_t utmip_master2_config; /* _UTMIP_MASTER2_CONFIG_0, 0x29c */
|
|
||||||
uint32_t utmip_uhsic_rpd_cfg; /* _UTMIP_UHSIC_RPD_CFG_0, 0x2a0 */
|
|
||||||
uint32_t pg_mask_ce0; /* _PG_MASK_CE0_0, 0x2a4 */
|
|
||||||
uint32_t pg_mask_3; /* _PG_MASK_3_0, 0x2a8 */
|
|
||||||
uint32_t pg_mask_4; /* _PG_MASK_4_0, 0x2ac */
|
|
||||||
uint32_t pllm_wb0_override2; /* _PLLM_WB0_OVERRIDE2_0, 0x2b0 */
|
|
||||||
uint32_t tsc_mult; /* _TSC_MULT_0, 0x2b4 */
|
|
||||||
uint32_t cpu_vsense_override; /* _CPU_VSENSE_OVERRIDE_0, 0x2b8 */
|
|
||||||
uint32_t glb_amap_cfg; /* _GLB_AMAP_CFG_0, 0x2bc */
|
|
||||||
uint32_t sticky_bits; /* _STICKY_BITS_0, 0x2c0 */
|
|
||||||
uint32_t sec_disable2; /* _SEC_DISABLE2_0, 0x2c4 */
|
|
||||||
uint32_t weak_bias; /* _WEAK_BIAS_0, 0x2c8 */
|
|
||||||
uint32_t reg_short; /* _REG_SHORT_0, 0x2cc */
|
|
||||||
uint32_t pg_mask_andor; /* _PG_MASK_ANDOR_0, 0x2d0 */
|
|
||||||
uint32_t gpu_rg_cntrl; /* _GPU_RG_CNTRL_0, 0x2d4 */
|
|
||||||
uint32_t sec_disable3; /* _SEC_DISABLE3_0, 0x2d8 */
|
|
||||||
uint32_t pg_mask_5; /* _PG_MASK_5_0, 0x2dc */
|
|
||||||
uint32_t pg_mask_6; /* _PG_MASK_6_0, 0x2e0 */
|
|
||||||
uint32_t _0x2e4[7];
|
|
||||||
uint32_t secure_scratch8; /* _SECURE_SCRATCH8_0, 0x300 */
|
|
||||||
uint32_t secure_scratch9; /* _SECURE_SCRATCH9_0, 0x304 */
|
|
||||||
uint32_t secure_scratch10; /* _SECURE_SCRATCH10_0, 0x308 */
|
|
||||||
uint32_t secure_scratch11; /* _SECURE_SCRATCH11_0, 0x30c */
|
|
||||||
uint32_t secure_scratch12; /* _SECURE_SCRATCH12_0, 0x310 */
|
|
||||||
uint32_t secure_scratch13; /* _SECURE_SCRATCH13_0, 0x314 */
|
|
||||||
uint32_t secure_scratch14; /* _SECURE_SCRATCH14_0, 0x318 */
|
|
||||||
uint32_t secure_scratch15; /* _SECURE_SCRATCH15_0, 0x31c */
|
|
||||||
uint32_t secure_scratch16; /* _SECURE_SCRATCH16_0, 0x320 */
|
|
||||||
uint32_t secure_scratch17; /* _SECURE_SCRATCH17_0, 0x324 */
|
|
||||||
uint32_t secure_scratch18; /* _SECURE_SCRATCH18_0, 0x328 */
|
|
||||||
uint32_t secure_scratch19; /* _SECURE_SCRATCH19_0, 0x32c */
|
|
||||||
uint32_t secure_scratch20; /* _SECURE_SCRATCH20_0, 0x330 */
|
|
||||||
uint32_t secure_scratch21; /* _SECURE_SCRATCH21_0, 0x334 */
|
|
||||||
uint32_t secure_scratch22; /* _SECURE_SCRATCH22_0, 0x338 */
|
|
||||||
uint32_t secure_scratch23; /* _SECURE_SCRATCH23_0, 0x33c */
|
|
||||||
uint32_t secure_scratch24; /* _SECURE_SCRATCH24_0, 0x340 */
|
|
||||||
uint32_t secure_scratch25; /* _SECURE_SCRATCH25_0, 0x344 */
|
|
||||||
uint32_t secure_scratch26; /* _SECURE_SCRATCH26_0, 0x348 */
|
|
||||||
uint32_t secure_scratch27; /* _SECURE_SCRATCH27_0, 0x34c */
|
|
||||||
uint32_t secure_scratch28; /* _SECURE_SCRATCH28_0, 0x350 */
|
|
||||||
uint32_t secure_scratch29; /* _SECURE_SCRATCH29_0, 0x354 */
|
|
||||||
uint32_t secure_scratch30; /* _SECURE_SCRATCH30_0, 0x358 */
|
|
||||||
uint32_t secure_scratch31; /* _SECURE_SCRATCH31_0, 0x35c */
|
|
||||||
uint32_t secure_scratch32; /* _SECURE_SCRATCH32_0, 0x360 */
|
|
||||||
uint32_t secure_scratch33; /* _SECURE_SCRATCH33_0, 0x364 */
|
|
||||||
uint32_t secure_scratch34; /* _SECURE_SCRATCH34_0, 0x368 */
|
|
||||||
uint32_t secure_scratch35; /* _SECURE_SCRATCH35_0, 0x36c */
|
|
||||||
uint32_t secure_scratch36; /* _SECURE_SCRATCH36_0, 0x370 */
|
|
||||||
uint32_t secure_scratch37; /* _SECURE_SCRATCH37_0, 0x374 */
|
|
||||||
uint32_t secure_scratch38; /* _SECURE_SCRATCH38_0, 0x378 */
|
|
||||||
uint32_t secure_scratch39; /* _SECURE_SCRATCH39_0, 0x37c */
|
|
||||||
uint32_t secure_scratch40; /* _SECURE_SCRATCH40_0, 0x380 */
|
|
||||||
uint32_t secure_scratch41; /* _SECURE_SCRATCH41_0, 0x384 */
|
|
||||||
uint32_t secure_scratch42; /* _SECURE_SCRATCH42_0, 0x388 */
|
|
||||||
uint32_t secure_scratch43; /* _SECURE_SCRATCH43_0, 0x38c */
|
|
||||||
uint32_t secure_scratch44; /* _SECURE_SCRATCH44_0, 0x390 */
|
|
||||||
uint32_t secure_scratch45; /* _SECURE_SCRATCH45_0, 0x394 */
|
|
||||||
uint32_t secure_scratch46; /* _SECURE_SCRATCH46_0, 0x398 */
|
|
||||||
uint32_t secure_scratch47; /* _SECURE_SCRATCH47_0, 0x39c */
|
|
||||||
uint32_t secure_scratch48; /* _SECURE_SCRATCH48_0, 0x3a0 */
|
|
||||||
uint32_t secure_scratch49; /* _SECURE_SCRATCH49_0, 0x3a4 */
|
|
||||||
uint32_t secure_scratch50; /* _SECURE_SCRATCH50_0, 0x3a8 */
|
|
||||||
uint32_t secure_scratch51; /* _SECURE_SCRATCH51_0, 0x3ac */
|
|
||||||
uint32_t secure_scratch52; /* _SECURE_SCRATCH52_0, 0x3b0 */
|
|
||||||
uint32_t secure_scratch53; /* _SECURE_SCRATCH53_0, 0x3b4 */
|
|
||||||
uint32_t secure_scratch54; /* _SECURE_SCRATCH54_0, 0x3b8 */
|
|
||||||
uint32_t secure_scratch55; /* _SECURE_SCRATCH55_0, 0x3bc */
|
|
||||||
uint32_t secure_scratch56; /* _SECURE_SCRATCH56_0, 0x3c0 */
|
|
||||||
uint32_t secure_scratch57; /* _SECURE_SCRATCH57_0, 0x3c4 */
|
|
||||||
uint32_t secure_scratch58; /* _SECURE_SCRATCH58_0, 0x3c8 */
|
|
||||||
uint32_t secure_scratch59; /* _SECURE_SCRATCH59_0, 0x3cc */
|
|
||||||
uint32_t secure_scratch60; /* _SECURE_SCRATCH60_0, 0x3d0 */
|
|
||||||
uint32_t secure_scratch61; /* _SECURE_SCRATCH61_0, 0x3d4 */
|
|
||||||
uint32_t secure_scratch62; /* _SECURE_SCRATCH62_0, 0x3d8 */
|
|
||||||
uint32_t secure_scratch63; /* _SECURE_SCRATCH63_0, 0x3dc */
|
|
||||||
uint32_t secure_scratch64; /* _SECURE_SCRATCH64_0, 0x3e0 */
|
|
||||||
uint32_t secure_scratch65; /* _SECURE_SCRATCH65_0, 0x3e4 */
|
|
||||||
uint32_t secure_scratch66; /* _SECURE_SCRATCH66_0, 0x3e8 */
|
|
||||||
uint32_t secure_scratch67; /* _SECURE_SCRATCH67_0, 0x3ec */
|
|
||||||
uint32_t secure_scratch68; /* _SECURE_SCRATCH68_0, 0x3f0 */
|
|
||||||
uint32_t secure_scratch69; /* _SECURE_SCRATCH69_0, 0x3f4 */
|
|
||||||
uint32_t secure_scratch70; /* _SECURE_SCRATCH70_0, 0x3f8 */
|
|
||||||
uint32_t secure_scratch71; /* _SECURE_SCRATCH71_0, 0x3fc */
|
|
||||||
uint32_t secure_scratch72; /* _SECURE_SCRATCH72_0, 0x400 */
|
|
||||||
uint32_t secure_scratch73; /* _SECURE_SCRATCH73_0, 0x404 */
|
|
||||||
uint32_t secure_scratch74; /* _SECURE_SCRATCH74_0, 0x408 */
|
|
||||||
uint32_t secure_scratch75; /* _SECURE_SCRATCH75_0, 0x40c */
|
|
||||||
uint32_t secure_scratch76; /* _SECURE_SCRATCH76_0, 0x410 */
|
|
||||||
uint32_t secure_scratch77; /* _SECURE_SCRATCH77_0, 0x414 */
|
|
||||||
uint32_t secure_scratch78; /* _SECURE_SCRATCH78_0, 0x418 */
|
|
||||||
uint32_t secure_scratch79; /* _SECURE_SCRATCH79_0, 0x41c */
|
|
||||||
uint32_t _0x420[8];
|
|
||||||
uint32_t cntrl2; /* _CNTRL2_0, 0x440 */
|
|
||||||
uint32_t io_dpd_off_mask; /* _IO_DPD_OFF_MASK_0, 0x444 */
|
|
||||||
uint32_t io_dpd2_off_mask; /* _IO_DPD2_OFF_MASK_0, 0x448 */
|
|
||||||
uint32_t event_counter; /* _EVENT_COUNTER_0, 0x44c */
|
|
||||||
uint32_t fuse_control; /* _FUSE_CONTROL_0, 0x450 */
|
|
||||||
uint32_t scratch1_eco; /* _SCRATCH1_ECO_0, 0x454 */
|
|
||||||
uint32_t _0x458;
|
|
||||||
uint32_t io_dpd3_req; /* _IO_DPD3_REQ_0, 0x45c */
|
|
||||||
uint32_t io_dpd3_status; /* _IO_DPD3_STATUS_0, 0x460 */
|
|
||||||
uint32_t io_dpd4_req; /* _IO_DPD4_REQ_0, 0x464 */
|
|
||||||
uint32_t io_dpd4_status; /* _IO_DPD4_STATUS_0, 0x468 */
|
|
||||||
uint32_t _0x46c[2];
|
|
||||||
uint32_t direct_thermtrip_cfg; /* _DIRECT_THERMTRIP_CFG_0, 0x474 */
|
|
||||||
uint32_t tsosc_delay; /* _TSOSC_DELAY_0, 0x478 */
|
|
||||||
uint32_t set_sw_clamp; /* _SET_SW_CLAMP_0, 0x47c */
|
|
||||||
uint32_t debug_authentication; /* _DEBUG_AUTHENTICATION_0, 0x480 */
|
|
||||||
uint32_t aotag_cfg; /* _AOTAG_CFG_0, 0x484 */
|
|
||||||
uint32_t aotag_thresh1_cfg; /* _AOTAG_THRESH1_CFG_0, 0x488 */
|
|
||||||
uint32_t aotag_thresh2_cfg; /* _AOTAG_THRESH2_CFG_0, 0x48c */
|
|
||||||
uint32_t aotag_thresh3_cfg; /* _AOTAG_THRESH3_CFG_0, 0x490 */
|
|
||||||
uint32_t aotag_status; /* _AOTAG_STATUS_0, 0x494 */
|
|
||||||
uint32_t aotag_security; /* _AOTAG_SECURITY_0, 0x498 */
|
|
||||||
uint32_t tsensor_config0; /* _TSENSOR_CONFIG0_0, 0x49c */
|
|
||||||
uint32_t tsensor_config1; /* _TSENSOR_CONFIG1_0, 0x4a0 */
|
|
||||||
uint32_t tsensor_config2; /* _TSENSOR_CONFIG2_0, 0x4a4 */
|
|
||||||
uint32_t tsensor_status0; /* _TSENSOR_STATUS0_0, 0x4a8 */
|
|
||||||
uint32_t tsensor_status1; /* _TSENSOR_STATUS1_0, 0x4ac */
|
|
||||||
uint32_t tsensor_status2; /* _TSENSOR_STATUS2_0, 0x4b0 */
|
|
||||||
uint32_t tsensor_pdiv; /* _TSENSOR_PDIV_0, 0x4b4 */
|
|
||||||
uint32_t aotag_intr_en; /* _AOTAG_INTR_EN_0, 0x4b8 */
|
|
||||||
uint32_t aotag_intr_dis; /* _AOTAG_INTR_DIS_0, 0x4bc */
|
|
||||||
uint32_t utmip_pad_cfg0; /* _UTMIP_PAD_CFG0_0, 0x4c0 */
|
|
||||||
uint32_t utmip_pad_cfg1; /* _UTMIP_PAD_CFG1_0, 0x4c4 */
|
|
||||||
uint32_t utmip_pad_cfg2; /* _UTMIP_PAD_CFG2_0, 0x4c8 */
|
|
||||||
uint32_t utmip_pad_cfg3; /* _UTMIP_PAD_CFG3_0, 0x4cc */
|
|
||||||
uint32_t utmip_uhsic_sleep_cfg1; /* _UTMIP_UHSIC_SLEEP_CFG1_0, 0x4d0 */
|
|
||||||
uint32_t cc4_hvc_control; /* _CC4_HVC_CONTROL_0, 0x4d4 */
|
|
||||||
uint32_t wake_debounce_en; /* _WAKE_DEBOUNCE_EN_0, 0x4d8 */
|
|
||||||
uint32_t ramdump_ctl_status; /* _RAMDUMP_CTL_STATUS_0, 0x4dc */
|
|
||||||
uint32_t utmip_sleepwalk_p3; /* _UTMIP_SLEEPWALK_P3_0, 0x4e0 */
|
|
||||||
uint32_t ddr_cntrl; /* _DDR_CNTRL_0, 0x4e4 */
|
|
||||||
uint32_t _0x4e8[50];
|
|
||||||
uint32_t sec_disable4; /* _SEC_DISABLE4_0, 0x5b0 */
|
|
||||||
uint32_t sec_disable5; /* _SEC_DISABLE5_0, 0x5b4 */
|
|
||||||
uint32_t sec_disable6; /* _SEC_DISABLE6_0, 0x5b8 */
|
|
||||||
uint32_t sec_disable7; /* _SEC_DISABLE7_0, 0x5bc */
|
|
||||||
uint32_t sec_disable8; /* _SEC_DISABLE8_0, 0x5c0 */
|
|
||||||
uint32_t sec_disable9; /* _SEC_DISABLE9_0, 0x5c4 */
|
|
||||||
uint32_t sec_disable10; /* _SEC_DISABLE10_0, 0x5c8 */
|
|
||||||
uint32_t _0x5cc[13];
|
|
||||||
uint32_t scratch56; /* _SCRATCH56_0, 0x600 */
|
|
||||||
uint32_t scratch57; /* _SCRATCH57_0, 0x604 */
|
|
||||||
uint32_t scratch58; /* _SCRATCH58_0, 0x608 */
|
|
||||||
uint32_t scratch59; /* _SCRATCH59_0, 0x60c */
|
|
||||||
uint32_t scratch60; /* _SCRATCH60_0, 0x610 */
|
|
||||||
uint32_t scratch61; /* _SCRATCH61_0, 0x614 */
|
|
||||||
uint32_t scratch62; /* _SCRATCH62_0, 0x618 */
|
|
||||||
uint32_t scratch63; /* _SCRATCH63_0, 0x61c */
|
|
||||||
uint32_t scratch64; /* _SCRATCH64_0, 0x620 */
|
|
||||||
uint32_t scratch65; /* _SCRATCH65_0, 0x624 */
|
|
||||||
uint32_t scratch66; /* _SCRATCH66_0, 0x628 */
|
|
||||||
uint32_t scratch67; /* _SCRATCH67_0, 0x62c */
|
|
||||||
uint32_t scratch68; /* _SCRATCH68_0, 0x630 */
|
|
||||||
uint32_t scratch69; /* _SCRATCH69_0, 0x634 */
|
|
||||||
uint32_t scratch70; /* _SCRATCH70_0, 0x638 */
|
|
||||||
uint32_t scratch71; /* _SCRATCH71_0, 0x63c */
|
|
||||||
uint32_t scratch72; /* _SCRATCH72_0, 0x640 */
|
|
||||||
uint32_t scratch73; /* _SCRATCH73_0, 0x644 */
|
|
||||||
uint32_t scratch74; /* _SCRATCH74_0, 0x648 */
|
|
||||||
uint32_t scratch75; /* _SCRATCH75_0, 0x64c */
|
|
||||||
uint32_t scratch76; /* _SCRATCH76_0, 0x650 */
|
|
||||||
uint32_t scratch77; /* _SCRATCH77_0, 0x654 */
|
|
||||||
uint32_t scratch78; /* _SCRATCH78_0, 0x658 */
|
|
||||||
uint32_t scratch79; /* _SCRATCH79_0, 0x65c */
|
|
||||||
uint32_t scratch80; /* _SCRATCH80_0, 0x660 */
|
|
||||||
uint32_t scratch81; /* _SCRATCH81_0, 0x664 */
|
|
||||||
uint32_t scratch82; /* _SCRATCH82_0, 0x668 */
|
|
||||||
uint32_t scratch83; /* _SCRATCH83_0, 0x66c */
|
|
||||||
uint32_t scratch84; /* _SCRATCH84_0, 0x670 */
|
|
||||||
uint32_t scratch85; /* _SCRATCH85_0, 0x674 */
|
|
||||||
uint32_t scratch86; /* _SCRATCH86_0, 0x678 */
|
|
||||||
uint32_t scratch87; /* _SCRATCH87_0, 0x67c */
|
|
||||||
uint32_t scratch88; /* _SCRATCH88_0, 0x680 */
|
|
||||||
uint32_t scratch89; /* _SCRATCH89_0, 0x684 */
|
|
||||||
uint32_t scratch90; /* _SCRATCH90_0, 0x688 */
|
|
||||||
uint32_t scratch91; /* _SCRATCH91_0, 0x68c */
|
|
||||||
uint32_t scratch92; /* _SCRATCH92_0, 0x690 */
|
|
||||||
uint32_t scratch93; /* _SCRATCH93_0, 0x694 */
|
|
||||||
uint32_t scratch94; /* _SCRATCH94_0, 0x698 */
|
|
||||||
uint32_t scratch95; /* _SCRATCH95_0, 0x69c */
|
|
||||||
uint32_t scratch96; /* _SCRATCH96_0, 0x6a0 */
|
|
||||||
uint32_t scratch97; /* _SCRATCH97_0, 0x6a4 */
|
|
||||||
uint32_t scratch98; /* _SCRATCH98_0, 0x6a8 */
|
|
||||||
uint32_t scratch99; /* _SCRATCH99_0, 0x6ac */
|
|
||||||
uint32_t scratch100; /* _SCRATCH100_0, 0x6b0 */
|
|
||||||
uint32_t scratch101; /* _SCRATCH101_0, 0x6b4 */
|
|
||||||
uint32_t scratch102; /* _SCRATCH102_0, 0x6b8 */
|
|
||||||
uint32_t scratch103; /* _SCRATCH103_0, 0x6bc */
|
|
||||||
uint32_t scratch104; /* _SCRATCH104_0, 0x6c0 */
|
|
||||||
uint32_t scratch105; /* _SCRATCH105_0, 0x6c4 */
|
|
||||||
uint32_t scratch106; /* _SCRATCH106_0, 0x6c8 */
|
|
||||||
uint32_t scratch107; /* _SCRATCH107_0, 0x6cc */
|
|
||||||
uint32_t scratch108; /* _SCRATCH108_0, 0x6d0 */
|
|
||||||
uint32_t scratch109; /* _SCRATCH109_0, 0x6d4 */
|
|
||||||
uint32_t scratch110; /* _SCRATCH110_0, 0x6d8 */
|
|
||||||
uint32_t scratch111; /* _SCRATCH111_0, 0x6dc */
|
|
||||||
uint32_t scratch112; /* _SCRATCH112_0, 0x6e0 */
|
|
||||||
uint32_t scratch113; /* _SCRATCH113_0, 0x6e4 */
|
|
||||||
uint32_t scratch114; /* _SCRATCH114_0, 0x6e8 */
|
|
||||||
uint32_t scratch115; /* _SCRATCH115_0, 0x6ec */
|
|
||||||
uint32_t scratch116; /* _SCRATCH116_0, 0x6f0 */
|
|
||||||
uint32_t scratch117; /* _SCRATCH117_0, 0x6f4 */
|
|
||||||
uint32_t scratch118; /* _SCRATCH118_0, 0x6f8 */
|
|
||||||
uint32_t scratch119; /* _SCRATCH119_0, 0x6fc */
|
|
||||||
uint32_t scratch120; /* _SCRATCH120_0, 0x700 */
|
|
||||||
uint32_t scratch121; /* _SCRATCH121_0, 0x704 */
|
|
||||||
uint32_t scratch122; /* _SCRATCH122_0, 0x708 */
|
|
||||||
uint32_t scratch123; /* _SCRATCH123_0, 0x70c */
|
|
||||||
uint32_t scratch124; /* _SCRATCH124_0, 0x710 */
|
|
||||||
uint32_t scratch125; /* _SCRATCH125_0, 0x714 */
|
|
||||||
uint32_t scratch126; /* _SCRATCH126_0, 0x718 */
|
|
||||||
uint32_t scratch127; /* _SCRATCH127_0, 0x71c */
|
|
||||||
uint32_t scratch128; /* _SCRATCH128_0, 0x720 */
|
|
||||||
uint32_t scratch129; /* _SCRATCH129_0, 0x724 */
|
|
||||||
uint32_t scratch130; /* _SCRATCH130_0, 0x728 */
|
|
||||||
uint32_t scratch131; /* _SCRATCH131_0, 0x72c */
|
|
||||||
uint32_t scratch132; /* _SCRATCH132_0, 0x730 */
|
|
||||||
uint32_t scratch133; /* _SCRATCH133_0, 0x734 */
|
|
||||||
uint32_t scratch134; /* _SCRATCH134_0, 0x738 */
|
|
||||||
uint32_t scratch135; /* _SCRATCH135_0, 0x73c */
|
|
||||||
uint32_t scratch136; /* _SCRATCH136_0, 0x740 */
|
|
||||||
uint32_t scratch137; /* _SCRATCH137_0, 0x744 */
|
|
||||||
uint32_t scratch138; /* _SCRATCH138_0, 0x748 */
|
|
||||||
uint32_t scratch139; /* _SCRATCH139_0, 0x74c */
|
|
||||||
uint32_t scratch140; /* _SCRATCH140_0, 0x750 */
|
|
||||||
uint32_t scratch141; /* _SCRATCH141_0, 0x754 */
|
|
||||||
uint32_t scratch142; /* _SCRATCH142_0, 0x758 */
|
|
||||||
uint32_t scratch143; /* _SCRATCH143_0, 0x75c */
|
|
||||||
uint32_t scratch144; /* _SCRATCH144_0, 0x760 */
|
|
||||||
uint32_t scratch145; /* _SCRATCH145_0, 0x764 */
|
|
||||||
uint32_t scratch146; /* _SCRATCH146_0, 0x768 */
|
|
||||||
uint32_t scratch147; /* _SCRATCH147_0, 0x76c */
|
|
||||||
uint32_t scratch148; /* _SCRATCH148_0, 0x770 */
|
|
||||||
uint32_t scratch149; /* _SCRATCH149_0, 0x774 */
|
|
||||||
uint32_t scratch150; /* _SCRATCH150_0, 0x778 */
|
|
||||||
uint32_t scratch151; /* _SCRATCH151_0, 0x77c */
|
|
||||||
uint32_t scratch152; /* _SCRATCH152_0, 0x780 */
|
|
||||||
uint32_t scratch153; /* _SCRATCH153_0, 0x784 */
|
|
||||||
uint32_t scratch154; /* _SCRATCH154_0, 0x788 */
|
|
||||||
uint32_t scratch155; /* _SCRATCH155_0, 0x78c */
|
|
||||||
uint32_t scratch156; /* _SCRATCH156_0, 0x790 */
|
|
||||||
uint32_t scratch157; /* _SCRATCH157_0, 0x794 */
|
|
||||||
uint32_t scratch158; /* _SCRATCH158_0, 0x798 */
|
|
||||||
uint32_t scratch159; /* _SCRATCH159_0, 0x79c */
|
|
||||||
uint32_t scratch160; /* _SCRATCH160_0, 0x7a0 */
|
|
||||||
uint32_t scratch161; /* _SCRATCH161_0, 0x7a4 */
|
|
||||||
uint32_t scratch162; /* _SCRATCH162_0, 0x7a8 */
|
|
||||||
uint32_t scratch163; /* _SCRATCH163_0, 0x7ac */
|
|
||||||
uint32_t scratch164; /* _SCRATCH164_0, 0x7b0 */
|
|
||||||
uint32_t scratch165; /* _SCRATCH165_0, 0x7b4 */
|
|
||||||
uint32_t scratch166; /* _SCRATCH166_0, 0x7b8 */
|
|
||||||
uint32_t scratch167; /* _SCRATCH167_0, 0x7bc */
|
|
||||||
uint32_t scratch168; /* _SCRATCH168_0, 0x7c0 */
|
|
||||||
uint32_t scratch169; /* _SCRATCH169_0, 0x7c4 */
|
|
||||||
uint32_t scratch170; /* _SCRATCH170_0, 0x7c8 */
|
|
||||||
uint32_t scratch171; /* _SCRATCH171_0, 0x7cc */
|
|
||||||
uint32_t scratch172; /* _SCRATCH172_0, 0x7d0 */
|
|
||||||
uint32_t scratch173; /* _SCRATCH173_0, 0x7d4 */
|
|
||||||
uint32_t scratch174; /* _SCRATCH174_0, 0x7d8 */
|
|
||||||
uint32_t scratch175; /* _SCRATCH175_0, 0x7dc */
|
|
||||||
uint32_t scratch176; /* _SCRATCH176_0, 0x7e0 */
|
|
||||||
uint32_t scratch177; /* _SCRATCH177_0, 0x7e4 */
|
|
||||||
uint32_t scratch178; /* _SCRATCH178_0, 0x7e8 */
|
|
||||||
uint32_t scratch179; /* _SCRATCH179_0, 0x7ec */
|
|
||||||
uint32_t scratch180; /* _SCRATCH180_0, 0x7f0 */
|
|
||||||
uint32_t scratch181; /* _SCRATCH181_0, 0x7f4 */
|
|
||||||
uint32_t scratch182; /* _SCRATCH182_0, 0x7f8 */
|
|
||||||
uint32_t scratch183; /* _SCRATCH183_0, 0x7fc */
|
|
||||||
uint32_t scratch184; /* _SCRATCH184_0, 0x800 */
|
|
||||||
uint32_t scratch185; /* _SCRATCH185_0, 0x804 */
|
|
||||||
uint32_t scratch186; /* _SCRATCH186_0, 0x808 */
|
|
||||||
uint32_t scratch187; /* _SCRATCH187_0, 0x80c */
|
|
||||||
uint32_t scratch188; /* _SCRATCH188_0, 0x810 */
|
|
||||||
uint32_t scratch189; /* _SCRATCH189_0, 0x814 */
|
|
||||||
uint32_t scratch190; /* _SCRATCH190_0, 0x818 */
|
|
||||||
uint32_t scratch191; /* _SCRATCH191_0, 0x81c */
|
|
||||||
uint32_t scratch192; /* _SCRATCH192_0, 0x820 */
|
|
||||||
uint32_t scratch193; /* _SCRATCH193_0, 0x824 */
|
|
||||||
uint32_t scratch194; /* _SCRATCH194_0, 0x828 */
|
|
||||||
uint32_t scratch195; /* _SCRATCH195_0, 0x82c */
|
|
||||||
uint32_t scratch196; /* _SCRATCH196_0, 0x830 */
|
|
||||||
uint32_t scratch197; /* _SCRATCH197_0, 0x834 */
|
|
||||||
uint32_t scratch198; /* _SCRATCH198_0, 0x838 */
|
|
||||||
uint32_t scratch199; /* _SCRATCH199_0, 0x83c */
|
|
||||||
uint32_t scratch200; /* _SCRATCH200_0, 0x840 */
|
|
||||||
uint32_t scratch201; /* _SCRATCH201_0, 0x844 */
|
|
||||||
uint32_t scratch202; /* _SCRATCH202_0, 0x848 */
|
|
||||||
uint32_t scratch203; /* _SCRATCH203_0, 0x84c */
|
|
||||||
uint32_t scratch204; /* _SCRATCH204_0, 0x850 */
|
|
||||||
uint32_t scratch205; /* _SCRATCH205_0, 0x854 */
|
|
||||||
uint32_t scratch206; /* _SCRATCH206_0, 0x858 */
|
|
||||||
uint32_t scratch207; /* _SCRATCH207_0, 0x85c */
|
|
||||||
uint32_t scratch208; /* _SCRATCH208_0, 0x860 */
|
|
||||||
uint32_t scratch209; /* _SCRATCH209_0, 0x864 */
|
|
||||||
uint32_t scratch210; /* _SCRATCH210_0, 0x868 */
|
|
||||||
uint32_t scratch211; /* _SCRATCH211_0, 0x86c */
|
|
||||||
uint32_t scratch212; /* _SCRATCH212_0, 0x870 */
|
|
||||||
uint32_t scratch213; /* _SCRATCH213_0, 0x874 */
|
|
||||||
uint32_t scratch214; /* _SCRATCH214_0, 0x878 */
|
|
||||||
uint32_t scratch215; /* _SCRATCH215_0, 0x87c */
|
|
||||||
uint32_t scratch216; /* _SCRATCH216_0, 0x880 */
|
|
||||||
uint32_t scratch217; /* _SCRATCH217_0, 0x884 */
|
|
||||||
uint32_t scratch218; /* _SCRATCH218_0, 0x888 */
|
|
||||||
uint32_t scratch219; /* _SCRATCH219_0, 0x88c */
|
|
||||||
uint32_t scratch220; /* _SCRATCH220_0, 0x890 */
|
|
||||||
uint32_t scratch221; /* _SCRATCH221_0, 0x894 */
|
|
||||||
uint32_t scratch222; /* _SCRATCH222_0, 0x898 */
|
|
||||||
uint32_t scratch223; /* _SCRATCH223_0, 0x89c */
|
|
||||||
uint32_t scratch224; /* _SCRATCH224_0, 0x8a0 */
|
|
||||||
uint32_t scratch225; /* _SCRATCH225_0, 0x8a4 */
|
|
||||||
uint32_t scratch226; /* _SCRATCH226_0, 0x8a8 */
|
|
||||||
uint32_t scratch227; /* _SCRATCH227_0, 0x8ac */
|
|
||||||
uint32_t scratch228; /* _SCRATCH228_0, 0x8b0 */
|
|
||||||
uint32_t scratch229; /* _SCRATCH229_0, 0x8b4 */
|
|
||||||
uint32_t scratch230; /* _SCRATCH230_0, 0x8b8 */
|
|
||||||
uint32_t scratch231; /* _SCRATCH231_0, 0x8bc */
|
|
||||||
uint32_t scratch232; /* _SCRATCH232_0, 0x8c0 */
|
|
||||||
uint32_t scratch233; /* _SCRATCH233_0, 0x8c4 */
|
|
||||||
uint32_t scratch234; /* _SCRATCH234_0, 0x8c8 */
|
|
||||||
uint32_t scratch235; /* _SCRATCH235_0, 0x8cc */
|
|
||||||
uint32_t scratch236; /* _SCRATCH236_0, 0x8d0 */
|
|
||||||
uint32_t scratch237; /* _SCRATCH237_0, 0x8d4 */
|
|
||||||
uint32_t scratch238; /* _SCRATCH238_0, 0x8d8 */
|
|
||||||
uint32_t scratch239; /* _SCRATCH239_0, 0x8dc */
|
|
||||||
uint32_t scratch240; /* _SCRATCH240_0, 0x8e0 */
|
|
||||||
uint32_t scratch241; /* _SCRATCH241_0, 0x8e4 */
|
|
||||||
uint32_t scratch242; /* _SCRATCH242_0, 0x8e8 */
|
|
||||||
uint32_t scratch243; /* _SCRATCH243_0, 0x8ec */
|
|
||||||
uint32_t scratch244; /* _SCRATCH244_0, 0x8f0 */
|
|
||||||
uint32_t scratch245; /* _SCRATCH245_0, 0x8f4 */
|
|
||||||
uint32_t scratch246; /* _SCRATCH246_0, 0x8f8 */
|
|
||||||
uint32_t scratch247; /* _SCRATCH247_0, 0x8fc */
|
|
||||||
uint32_t scratch248; /* _SCRATCH248_0, 0x900 */
|
|
||||||
uint32_t scratch249; /* _SCRATCH249_0, 0x904 */
|
|
||||||
uint32_t scratch250; /* _SCRATCH250_0, 0x908 */
|
|
||||||
uint32_t scratch251; /* _SCRATCH251_0, 0x90c */
|
|
||||||
uint32_t scratch252; /* _SCRATCH252_0, 0x910 */
|
|
||||||
uint32_t scratch253; /* _SCRATCH253_0, 0x914 */
|
|
||||||
uint32_t scratch254; /* _SCRATCH254_0, 0x918 */
|
|
||||||
uint32_t scratch255; /* _SCRATCH255_0, 0x91c */
|
|
||||||
uint32_t scratch256; /* _SCRATCH256_0, 0x920 */
|
|
||||||
uint32_t scratch257; /* _SCRATCH257_0, 0x924 */
|
|
||||||
uint32_t scratch258; /* _SCRATCH258_0, 0x928 */
|
|
||||||
uint32_t scratch259; /* _SCRATCH259_0, 0x92c */
|
|
||||||
uint32_t scratch260; /* _SCRATCH260_0, 0x930 */
|
|
||||||
uint32_t scratch261; /* _SCRATCH261_0, 0x934 */
|
|
||||||
uint32_t scratch262; /* _SCRATCH262_0, 0x938 */
|
|
||||||
uint32_t scratch263; /* _SCRATCH263_0, 0x93c */
|
|
||||||
uint32_t scratch264; /* _SCRATCH264_0, 0x940 */
|
|
||||||
uint32_t scratch265; /* _SCRATCH265_0, 0x944 */
|
|
||||||
uint32_t scratch266; /* _SCRATCH266_0, 0x948 */
|
|
||||||
uint32_t scratch267; /* _SCRATCH267_0, 0x94c */
|
|
||||||
uint32_t scratch268; /* _SCRATCH268_0, 0x950 */
|
|
||||||
uint32_t scratch269; /* _SCRATCH269_0, 0x954 */
|
|
||||||
uint32_t scratch270; /* _SCRATCH270_0, 0x958 */
|
|
||||||
uint32_t scratch271; /* _SCRATCH271_0, 0x95c */
|
|
||||||
uint32_t scratch272; /* _SCRATCH272_0, 0x960 */
|
|
||||||
uint32_t scratch273; /* _SCRATCH273_0, 0x964 */
|
|
||||||
uint32_t scratch274; /* _SCRATCH274_0, 0x968 */
|
|
||||||
uint32_t scratch275; /* _SCRATCH275_0, 0x96c */
|
|
||||||
uint32_t scratch276; /* _SCRATCH276_0, 0x970 */
|
|
||||||
uint32_t scratch277; /* _SCRATCH277_0, 0x974 */
|
|
||||||
uint32_t scratch278; /* _SCRATCH278_0, 0x978 */
|
|
||||||
uint32_t scratch279; /* _SCRATCH279_0, 0x97c */
|
|
||||||
uint32_t scratch280; /* _SCRATCH280_0, 0x980 */
|
|
||||||
uint32_t scratch281; /* _SCRATCH281_0, 0x984 */
|
|
||||||
uint32_t scratch282; /* _SCRATCH282_0, 0x988 */
|
|
||||||
uint32_t scratch283; /* _SCRATCH283_0, 0x98c */
|
|
||||||
uint32_t scratch284; /* _SCRATCH284_0, 0x990 */
|
|
||||||
uint32_t scratch285; /* _SCRATCH285_0, 0x994 */
|
|
||||||
uint32_t scratch286; /* _SCRATCH286_0, 0x998 */
|
|
||||||
uint32_t scratch287; /* _SCRATCH287_0, 0x99c */
|
|
||||||
uint32_t scratch288; /* _SCRATCH288_0, 0x9a0 */
|
|
||||||
uint32_t scratch289; /* _SCRATCH289_0, 0x9a4 */
|
|
||||||
uint32_t scratch290; /* _SCRATCH290_0, 0x9a8 */
|
|
||||||
uint32_t scratch291; /* _SCRATCH291_0, 0x9ac */
|
|
||||||
uint32_t scratch292; /* _SCRATCH292_0, 0x9b0 */
|
|
||||||
uint32_t scratch293; /* _SCRATCH293_0, 0x9b4 */
|
|
||||||
uint32_t scratch294; /* _SCRATCH294_0, 0x9b8 */
|
|
||||||
uint32_t scratch295; /* _SCRATCH295_0, 0x9bc */
|
|
||||||
uint32_t scratch296; /* _SCRATCH296_0, 0x9c0 */
|
|
||||||
uint32_t scratch297; /* _SCRATCH297_0, 0x9c4 */
|
|
||||||
uint32_t scratch298; /* _SCRATCH298_0, 0x9c8 */
|
|
||||||
uint32_t scratch299; /* _SCRATCH299_0, 0x9cc */
|
|
||||||
uint32_t _0x9d0[50];
|
|
||||||
uint32_t secure_scratch80; /* _SECURE_SCRATCH80_0, 0xa98 */
|
|
||||||
uint32_t secure_scratch81; /* _SECURE_SCRATCH81_0, 0xa9c */
|
|
||||||
uint32_t secure_scratch82; /* _SECURE_SCRATCH82_0, 0xaa0 */
|
|
||||||
uint32_t secure_scratch83; /* _SECURE_SCRATCH83_0, 0xaa4 */
|
|
||||||
uint32_t secure_scratch84; /* _SECURE_SCRATCH84_0, 0xaa8 */
|
|
||||||
uint32_t secure_scratch85; /* _SECURE_SCRATCH85_0, 0xaac */
|
|
||||||
uint32_t secure_scratch86; /* _SECURE_SCRATCH86_0, 0xab0 */
|
|
||||||
uint32_t secure_scratch87; /* _SECURE_SCRATCH87_0, 0xab4 */
|
|
||||||
uint32_t secure_scratch88; /* _SECURE_SCRATCH88_0, 0xab8 */
|
|
||||||
uint32_t secure_scratch89; /* _SECURE_SCRATCH89_0, 0xabc */
|
|
||||||
uint32_t secure_scratch90; /* _SECURE_SCRATCH90_0, 0xac0 */
|
|
||||||
uint32_t secure_scratch91; /* _SECURE_SCRATCH91_0, 0xac4 */
|
|
||||||
uint32_t secure_scratch92; /* _SECURE_SCRATCH92_0, 0xac8 */
|
|
||||||
uint32_t secure_scratch93; /* _SECURE_SCRATCH93_0, 0xacc */
|
|
||||||
uint32_t secure_scratch94; /* _SECURE_SCRATCH94_0, 0xad0 */
|
|
||||||
uint32_t secure_scratch95; /* _SECURE_SCRATCH95_0, 0xad4 */
|
|
||||||
uint32_t secure_scratch96; /* _SECURE_SCRATCH96_0, 0xad8 */
|
|
||||||
uint32_t secure_scratch97; /* _SECURE_SCRATCH97_0, 0xadc */
|
|
||||||
uint32_t secure_scratch98; /* _SECURE_SCRATCH98_0, 0xae0 */
|
|
||||||
uint32_t secure_scratch99; /* _SECURE_SCRATCH99_0, 0xae4 */
|
|
||||||
uint32_t secure_scratch100; /* _SECURE_SCRATCH100_0, 0xae8 */
|
|
||||||
uint32_t secure_scratch101; /* _SECURE_SCRATCH101_0, 0xaec */
|
|
||||||
uint32_t secure_scratch102; /* _SECURE_SCRATCH102_0, 0xaf0 */
|
|
||||||
uint32_t secure_scratch103; /* _SECURE_SCRATCH103_0, 0xaf4 */
|
|
||||||
uint32_t secure_scratch104; /* _SECURE_SCRATCH104_0, 0xaf8 */
|
|
||||||
uint32_t secure_scratch105; /* _SECURE_SCRATCH105_0, 0xafc */
|
|
||||||
uint32_t secure_scratch106; /* _SECURE_SCRATCH106_0, 0xb00 */
|
|
||||||
uint32_t secure_scratch107; /* _SECURE_SCRATCH107_0, 0xb04 */
|
|
||||||
uint32_t secure_scratch108; /* _SECURE_SCRATCH108_0, 0xb08 */
|
|
||||||
uint32_t secure_scratch109; /* _SECURE_SCRATCH109_0, 0xb0c */
|
|
||||||
uint32_t secure_scratch110; /* _SECURE_SCRATCH110_0, 0xb10 */
|
|
||||||
uint32_t secure_scratch111; /* _SECURE_SCRATCH111_0, 0xb14 */
|
|
||||||
uint32_t secure_scratch112; /* _SECURE_SCRATCH112_0, 0xb18 */
|
|
||||||
uint32_t secure_scratch113; /* _SECURE_SCRATCH113_0, 0xb1c */
|
|
||||||
uint32_t secure_scratch114; /* _SECURE_SCRATCH114_0, 0xb20 */
|
|
||||||
uint32_t secure_scratch115; /* _SECURE_SCRATCH115_0, 0xb24 */
|
|
||||||
uint32_t secure_scratch116; /* _SECURE_SCRATCH116_0, 0xb28 */
|
|
||||||
uint32_t secure_scratch117; /* _SECURE_SCRATCH117_0, 0xb2c */
|
|
||||||
uint32_t secure_scratch118; /* _SECURE_SCRATCH118_0, 0xb30 */
|
|
||||||
uint32_t secure_scratch119; /* _SECURE_SCRATCH119_0, 0xb34 */
|
|
||||||
uint32_t secure_scratch120; /* _SECURE_SCRATCH120_0, 0xb38 */
|
|
||||||
uint32_t secure_scratch121; /* _SECURE_SCRATCH121_0, 0xb3c */
|
|
||||||
uint32_t secure_scratch122; /* _SECURE_SCRATCH122_0, 0xb40 */
|
|
||||||
uint32_t secure_scratch123; /* _SECURE_SCRATCH123_0, 0xb44 */
|
|
||||||
uint32_t led_breathing_ctrl; /* _LED_BREATHING_CTRL_0, 0xb48 */
|
|
||||||
uint32_t led_breathing_counter0; /* _LED_BREATHING_COUNTER0_0, 0xb4c */
|
|
||||||
uint32_t led_breathing_counter1; /* _LED_BREATHING_COUNTER1_0, 0xb50 */
|
|
||||||
uint32_t led_breathing_counter2; /* _LED_BREATHING_COUNTER2_0, 0xb54 */
|
|
||||||
uint32_t led_breathing_counter3; /* _LED_BREATHING_COUNTER3_0, 0xb58 */
|
|
||||||
uint32_t led_breathing_status; /* _LED_BREATHING_STATUS_0, 0xb5c */
|
|
||||||
uint32_t _0xb60[2];
|
|
||||||
uint32_t secure_scratch124; /* _SECURE_SCRATCH124_0, 0xb68 */
|
|
||||||
uint32_t secure_scratch125; /* _SECURE_SCRATCH125_0, 0xb6c */
|
|
||||||
uint32_t secure_scratch126; /* _SECURE_SCRATCH126_0, 0xb70 */
|
|
||||||
uint32_t secure_scratch127; /* _SECURE_SCRATCH127_0, 0xb74 */
|
|
||||||
uint32_t secure_scratch128; /* _SECURE_SCRATCH128_0, 0xb78 */
|
|
||||||
uint32_t secure_scratch129; /* _SECURE_SCRATCH129_0, 0xb7c */
|
|
||||||
uint32_t secure_scratch130; /* _SECURE_SCRATCH130_0, 0xb80 */
|
|
||||||
uint32_t secure_scratch131; /* _SECURE_SCRATCH131_0, 0xb84 */
|
|
||||||
uint32_t secure_scratch132; /* _SECURE_SCRATCH132_0, 0xb88 */
|
|
||||||
uint32_t secure_scratch133; /* _SECURE_SCRATCH133_0, 0xb8c */
|
|
||||||
uint32_t secure_scratch134; /* _SECURE_SCRATCH134_0, 0xb90 */
|
|
||||||
uint32_t secure_scratch135; /* _SECURE_SCRATCH135_0, 0xb94 */
|
|
||||||
uint32_t secure_scratch136; /* _SECURE_SCRATCH136_0, 0xb98 */
|
|
||||||
uint32_t secure_scratch137; /* _SECURE_SCRATCH137_0, 0xb9c */
|
|
||||||
uint32_t secure_scratch138; /* _SECURE_SCRATCH138_0, 0xba0 */
|
|
||||||
uint32_t secure_scratch139; /* _SECURE_SCRATCH139_0, 0xba4 */
|
|
||||||
uint32_t _0xba8[2];
|
|
||||||
uint32_t sec_disable_ns; /* _SEC_DISABLE_NS_0, 0xbb0 */
|
|
||||||
uint32_t sec_disable2_ns; /* _SEC_DISABLE2_NS_0, 0xbb4 */
|
|
||||||
uint32_t sec_disable3_ns; /* _SEC_DISABLE3_NS_0, 0xbb8 */
|
|
||||||
uint32_t sec_disable4_ns; /* _SEC_DISABLE4_NS_0, 0xbbc */
|
|
||||||
uint32_t sec_disable5_ns; /* _SEC_DISABLE5_NS_0, 0xbc0 */
|
|
||||||
uint32_t sec_disable6_ns; /* _SEC_DISABLE6_NS_0, 0xbc4 */
|
|
||||||
uint32_t sec_disable7_ns; /* _SEC_DISABLE7_NS_0, 0xbc8 */
|
|
||||||
uint32_t sec_disable8_ns; /* _SEC_DISABLE8_NS_0, 0xbcc */
|
|
||||||
uint32_t sec_disable9_ns; /* _SEC_DISABLE9_NS_0, 0xbd0 */
|
|
||||||
uint32_t sec_disable10_ns; /* _SEC_DISABLE10_NS_0, 0xbd4 */
|
|
||||||
uint32_t _0xbd8[4];
|
|
||||||
uint32_t tzram_pwr_cntrl; /* _TZRAM_PWR_CNTRL_0, 0xbe8 */
|
|
||||||
uint32_t tzram_sec_disable; /* _TZRAM_SEC_DISABLE_0, 0xbec */
|
|
||||||
uint32_t tzram_non_sec_disable; /* _TZRAM_NON_SEC_DISABLE_0, 0xbf0 */
|
|
||||||
} tegra_pmc_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_pmc_t *pmc_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_pmc_t *)PMC_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,757 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
#include "se.h"
|
|
||||||
|
|
||||||
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
|
|
||||||
/* Globals for driver. */
|
|
||||||
static unsigned int g_se_modulus_sizes[KEYSLOT_RSA_MAX];
|
|
||||||
static unsigned int g_se_exp_sizes[KEYSLOT_RSA_MAX];
|
|
||||||
|
|
||||||
/* Initialize a SE linked list. */
|
|
||||||
void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
|
|
||||||
ll->num_entries = 0; /* 1 Entry. */
|
|
||||||
|
|
||||||
if (buffer != NULL) {
|
|
||||||
ll->addr_info.address = (uint32_t) get_physical_address(buffer);
|
|
||||||
ll->addr_info.size = (uint32_t) size;
|
|
||||||
} else {
|
|
||||||
ll->addr_info.address = 0;
|
|
||||||
ll->addr_info.size = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_check_error_status_reg(void) {
|
|
||||||
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->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_verify_flags_cleared(void) {
|
|
||||||
if (se_get_regs()->SE_STATUS & 3) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the flags for an AES keyslot. */
|
|
||||||
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Misc flags. */
|
|
||||||
if (flags & ~0x80) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
|
||||||
if (flags & 0x80) {
|
|
||||||
se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the flags for an RSA keyslot. */
|
|
||||||
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Misc flags. */
|
|
||||||
if (flags & ~0x80) {
|
|
||||||
/* TODO: Why are flags assigned this way? */
|
|
||||||
se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
|
||||||
if (flags & 0x80) {
|
|
||||||
se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_aes_keyslot(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero out the whole keyslot and IV. */
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_rsa_keyslot(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero out the whole keyslot. */
|
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
|
||||||
/* Select Keyslot Modulus[i] */
|
|
||||||
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->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
|
||||||
se->SE_RSA_KEYTABLE_DATA = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (key_size >> 2); i++) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
|
||||||
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->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;
|
|
||||||
g_se_exp_sizes[keyslot] = exp_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_aes_keyslot_iv(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
|
||||||
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()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSLOT_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write config, validate. */
|
|
||||||
se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB);
|
|
||||||
if (se->SE_CONFIG != (ALG_AES_DEC | DST_KEYTAB)) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
se->SE_CRYPTO_CONFIG = keyslot_src << 24;
|
|
||||||
if (se->SE_CRYPTO_CONFIG != (keyslot_src << 24)) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
se->SE_CRYPTO_LAST_BLOCK = 0;
|
|
||||||
if (se->SE_CRYPTO_LAST_BLOCK != 0) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8;
|
|
||||||
if (se->SE_CRYPTO_KEYTABLE_DST != (keyslot_dst << 8)) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear address context. */
|
|
||||||
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->SE_IN_LL_ADDR == 0 || se->SE_OUT_LL_ADDR == 0) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
uint8_t ALIGN(16) stack_buf[KEYSIZE_RSA_MAX];
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Endian swap the input. */
|
|
||||||
for (size_t i = 0; i < src_size; i++) {
|
|
||||||
stack_buf[i] = *((uint8_t *)src + src_size - i - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_get_exp_mod_output(void *buf, size_t size) {
|
|
||||||
size_t num_dwords = (size >> 2);
|
|
||||||
|
|
||||||
if (num_dwords < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t *p_out = ((uint32_t *)buf) + num_dwords - 1;
|
|
||||||
uint32_t offset = 0;
|
|
||||||
|
|
||||||
/* Copy endian swapped output. */
|
|
||||||
while (num_dwords) {
|
|
||||||
*p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset);
|
|
||||||
offset += 4;
|
|
||||||
p_out--;
|
|
||||||
num_dwords--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size) {
|
|
||||||
uint8_t message[RSA_2048_BYTES];
|
|
||||||
uint8_t h_buf[0x24];
|
|
||||||
|
|
||||||
/* Hardcode RSA with keyslot 0. */
|
|
||||||
const uint8_t public_exponent[4] = {0x00, 0x01, 0x00, 0x01};
|
|
||||||
set_rsa_keyslot(0, modulus, modulus_size, public_exponent, sizeof(public_exponent));
|
|
||||||
se_synchronous_exp_mod(0, message, sizeof(message), signature, signature_size);
|
|
||||||
|
|
||||||
/* Validate sanity byte. */
|
|
||||||
if (message[RSA_2048_BYTES - 1] != 0xBC) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy Salt into MGF1 Hash Buffer. */
|
|
||||||
memset(h_buf, 0, sizeof(h_buf));
|
|
||||||
memcpy(h_buf, message + RSA_2048_BYTES - 0x20 - 0x1, 0x20);
|
|
||||||
|
|
||||||
/* Decrypt maskedDB (via inline MGF1). */
|
|
||||||
uint8_t seed = 0;
|
|
||||||
uint8_t mgf1_buf[0x20];
|
|
||||||
for (unsigned int ofs = 0; ofs < RSA_2048_BYTES - 0x20 - 1; ofs += 0x20) {
|
|
||||||
h_buf[sizeof(h_buf) - 1] = seed++;
|
|
||||||
se_calculate_sha256(mgf1_buf, h_buf, sizeof(h_buf));
|
|
||||||
for (unsigned int i = ofs; i < ofs + 0x20 && i < RSA_2048_BYTES - 0x20 - 1; i++) {
|
|
||||||
message[i] ^= mgf1_buf[i - ofs];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Constant lmask for rsa-2048-pss. */
|
|
||||||
message[0] &= 0x7F;
|
|
||||||
|
|
||||||
/* Validate DB is of the form 0000...0001. */
|
|
||||||
for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) {
|
|
||||||
if (message[i] != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (message[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check hash correctness. */
|
|
||||||
uint8_t validate_buf[8 + 0x20 + 0x20];
|
|
||||||
uint8_t validate_hash[0x20];
|
|
||||||
|
|
||||||
memset(validate_buf, 0, sizeof(validate_buf));
|
|
||||||
se_calculate_sha256(&validate_buf[8], data, data_size);
|
|
||||||
memcpy(&validate_buf[0x28], &message[RSA_2048_BYTES - 0x20 - 0x20 - 1], 0x20);
|
|
||||||
se_calculate_sha256(validate_hash, validate_buf, sizeof(validate_buf));
|
|
||||||
return memcmp(h_buf, validate_hash, 0x20) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
se_ll_t in_ll;
|
|
||||||
se_ll_t out_ll;
|
|
||||||
|
|
||||||
ll_init(&in_ll, (void *)src, src_size);
|
|
||||||
ll_init(&out_ll, dst, dst_size);
|
|
||||||
|
|
||||||
/* Set the LLs. */
|
|
||||||
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->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
|
||||||
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
|
||||||
|
|
||||||
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->SE_OPERATION = op;
|
|
||||||
|
|
||||||
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
|
|
||||||
se_check_for_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Secure AES Functionality. */
|
|
||||||
void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
uint8_t block[0x10] = {0};
|
|
||||||
|
|
||||||
if (src_size > sizeof(block) || dst_size > sizeof(block)) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load src data into block. */
|
|
||||||
if (src_size != 0) {
|
|
||||||
memcpy(block, src, src_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Trigger AES operation. */
|
|
||||||
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. */
|
|
||||||
if (dst_size != 0) {
|
|
||||||
memcpy(dst, block, dst_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
unsigned int num_blocks = src_size >> 4;
|
|
||||||
|
|
||||||
/* Unknown what this write does, but official code writes it for CTR mode. */
|
|
||||||
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->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle final, unaligned block. */
|
|
||||||
if (aligned_size < dst_size && aligned_size < src_size) {
|
|
||||||
size_t last_block_size = dst_size - aligned_size;
|
|
||||||
if (src_size < dst_size) {
|
|
||||||
last_block_size = src_size - aligned_size;
|
|
||||||
}
|
|
||||||
se_perform_aes_block_operation(dst + aligned_size, last_block_size, (uint8_t *)src + aligned_size, src_size - aligned_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0x202);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
|
||||||
se->SE_CRYPTO_CONFIG = keyslot << 24;
|
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shift_left_xor_rb(uint8_t *key) {
|
|
||||||
uint8_t prev_high_bit = 0;
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
uint8_t cur_byte = key[0xF - i];
|
|
||||||
key[0xF - i] = (cur_byte << 1) | (prev_high_bit);
|
|
||||||
prev_high_bit = cur_byte >> 7;
|
|
||||||
}
|
|
||||||
if (prev_high_bit) {
|
|
||||||
key[0xF] ^= 0x87;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shift_left_xor_rb_le(uint8_t *key) {
|
|
||||||
uint8_t prev_high_bit = 0;
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
uint8_t cur_byte = key[i];
|
|
||||||
key[i] = (cur_byte << 1) | (prev_high_bit);
|
|
||||||
prev_high_bit = cur_byte >> 7;
|
|
||||||
}
|
|
||||||
if (prev_high_bit) {
|
|
||||||
key[0x0] ^= 0x87;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate the derived key, to be XOR'd with final output block. */
|
|
||||||
uint8_t ALIGN(16) derived_key[0x10] = {0};
|
|
||||||
se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high);
|
|
||||||
shift_left_xor_rb(derived_key);
|
|
||||||
if (data_size & 0xF) {
|
|
||||||
shift_left_xor_rb(derived_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
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->SE_CRYPTO_LAST_BLOCK = num_blocks - 2;
|
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
|
||||||
se->SE_CRYPTO_CONFIG |= 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create final block. */
|
|
||||||
uint8_t ALIGN(16) last_block[0x10] = {0};
|
|
||||||
if (data_size & 0xF) {
|
|
||||||
memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF);
|
|
||||||
last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */
|
|
||||||
} else if (data_size >= 0x10) {
|
|
||||||
memcpy(last_block, data + data_size - 0x10, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
|
||||||
last_block[i] ^= derived_key[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform last operation. */
|
|
||||||
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->SE_HASH_RESULT, i << 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
|
|
||||||
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0);
|
|
||||||
}
|
|
||||||
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
|
|
||||||
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
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->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_aes_128_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY) | (0x000 << 16);
|
|
||||||
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x66;
|
|
||||||
clear_aes_keyslot_iv(keyslot);
|
|
||||||
se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SHA256 Implementation. */
|
|
||||||
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->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->SE_HASH_RESULT, i << 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RNG API */
|
|
||||||
void se_initialize_rng(unsigned int keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* To initialize the RNG, we'll perform an RNG operation into an output buffer. */
|
|
||||||
/* This will be discarded, when done. */
|
|
||||||
uint8_t ALIGN(16) output_buf[0x10];
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t num_blocks = size >> 4;
|
|
||||||
size_t aligned_size = num_blocks << 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->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
|
||||||
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
|
|
||||||
}
|
|
||||||
if (size > aligned_size) {
|
|
||||||
se_perform_aes_block_operation(dst + aligned_size, size - aligned_size, NULL, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
if (dst_keyslot >= KEYSLOT_AES_MAX || rng_keyslot >= KEYSLOT_AES_MAX) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup Config. */
|
|
||||||
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->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8);
|
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
|
||||||
/* Generate high part of key. */
|
|
||||||
se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8) | 1;
|
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SE context save API. */
|
|
||||||
void se_set_in_context_save_mode(bool is_context_save_mode) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
uint32_t val = se->SE_SE_SECURITY;
|
|
||||||
if (is_context_save_mode) {
|
|
||||||
val |= 0x10000;
|
|
||||||
} else {
|
|
||||||
val &= 0xFFFEFFFF;
|
|
||||||
}
|
|
||||||
se->SE_SE_SECURITY = val;
|
|
||||||
/* Perform a useless read from flags reg. */
|
|
||||||
(void)(se->SE_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_generate_srk(unsigned int srkgen_keyslot) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_encrypt_with_srk(void *dst, size_t dst_size, const void *src, size_t src_size) {
|
|
||||||
uint8_t output[0x80];
|
|
||||||
uint8_t *aligned_out = (uint8_t *)(((uintptr_t)output + 0x7F) & ~0x3F);
|
|
||||||
if (dst_size > 0x10) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst_size) {
|
|
||||||
trigger_se_blocking_op(OP_CTX_SAVE, aligned_out, dst_size, src, src_size);
|
|
||||||
memcpy(dst, aligned_out, dst_size);
|
|
||||||
} else {
|
|
||||||
trigger_se_blocking_op(OP_CTX_SAVE, aligned_out, 0, src, src_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void *dst) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
uint8_t _work_buf[0x80];
|
|
||||||
uint8_t *work_buf = (uint8_t *)(((uintptr_t)_work_buf + 0x7F) & ~0x3F);
|
|
||||||
|
|
||||||
/* Generate the SRK (context save encryption key). */
|
|
||||||
se_generate_random_key(srkgen_keyslot, rng_keyslot);
|
|
||||||
se_generate_srk(srkgen_keyslot);
|
|
||||||
|
|
||||||
se_generate_random(rng_keyslot, work_buf, 0x10);
|
|
||||||
|
|
||||||
/* Save random initial block. */
|
|
||||||
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->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->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->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->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->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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save RSA Keytable. */
|
|
||||||
uint8_t *rsa_ctx_out = (uint8_t *)dst + 0x430;
|
|
||||||
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->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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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->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->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK);
|
|
||||||
se->SE_CRYPTO_LAST_BLOCK = 0;
|
|
||||||
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
|
||||||
se->SE_CONFIG = 0;
|
|
||||||
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
|
||||||
}
|
|
|
@ -1,216 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#ifndef FUSEE_SE_H
|
|
||||||
#define FUSEE_SE_H
|
|
||||||
|
|
||||||
#define SE_BASE 0x70012000
|
|
||||||
#define MAKE_SE_REG(n) MAKE_REG32(SE_BASE + n)
|
|
||||||
|
|
||||||
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
|
|
||||||
#define KEYSLOT_SWITCH_SRKGENKEY 0x8
|
|
||||||
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
|
|
||||||
#define KEYSLOT_SWITCH_TEMPKEY 0x9
|
|
||||||
#define KEYSLOT_SWITCH_SESSIONKEY 0xA
|
|
||||||
#define KEYSLOT_SWITCH_RNGKEY 0xB
|
|
||||||
#define KEYSLOT_SWITCH_MASTERKEY 0xC
|
|
||||||
#define KEYSLOT_SWITCH_DEVICEKEY 0xD
|
|
||||||
|
|
||||||
/* This keyslot was added in 4.0.0. */
|
|
||||||
#define KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY 0xD
|
|
||||||
#define KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY 0xE
|
|
||||||
#define KEYSLOT_SWITCH_4XOLDDEVICEKEY 0xF
|
|
||||||
|
|
||||||
/* This keyslot was added in 5.0.0. */
|
|
||||||
#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
|
|
||||||
|
|
||||||
/* Mariko keyslots. */
|
|
||||||
#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7
|
|
||||||
|
|
||||||
#define KEYSLOT_AES_MAX 0x10
|
|
||||||
#define KEYSLOT_RSA_MAX 0x2
|
|
||||||
|
|
||||||
#define KEYSIZE_AES_MAX 0x20
|
|
||||||
#define KEYSIZE_RSA_MAX 0x100
|
|
||||||
|
|
||||||
#define ALG_SHIFT (12)
|
|
||||||
#define ALG_DEC_SHIFT (8)
|
|
||||||
#define ALG_NOP (0 << ALG_SHIFT)
|
|
||||||
#define ALG_AES_ENC (1 << ALG_SHIFT)
|
|
||||||
#define ALG_AES_DEC ((1 << ALG_DEC_SHIFT) | ALG_NOP)
|
|
||||||
#define ALG_RNG (2 << ALG_SHIFT)
|
|
||||||
#define ALG_SHA (3 << ALG_SHIFT)
|
|
||||||
#define ALG_RSA (4 << ALG_SHIFT)
|
|
||||||
|
|
||||||
#define DST_SHIFT (2)
|
|
||||||
#define DST_MEMORY (0 << DST_SHIFT)
|
|
||||||
#define DST_HASHREG (1 << DST_SHIFT)
|
|
||||||
#define DST_KEYTAB (2 << DST_SHIFT)
|
|
||||||
#define DST_SRK (3 << DST_SHIFT)
|
|
||||||
#define DST_RSAREG (4 << DST_SHIFT)
|
|
||||||
|
|
||||||
#define ENCMODE_SHIFT (24)
|
|
||||||
#define DECMODE_SHIFT (16)
|
|
||||||
#define ENCMODE_SHA256 (5 << ENCMODE_SHIFT)
|
|
||||||
|
|
||||||
#define HASH_DISABLE (0x0)
|
|
||||||
#define HASH_ENABLE (0x1)
|
|
||||||
|
|
||||||
#define OP_ABORT 0
|
|
||||||
#define OP_START 1
|
|
||||||
#define OP_RESTART 2
|
|
||||||
#define OP_CTX_SAVE 3
|
|
||||||
#define OP_RESTART_IN 4
|
|
||||||
|
|
||||||
#define CTX_SAVE_SRC_SHIFT 29
|
|
||||||
#define CTX_SAVE_SRC_STICKY_BITS (0 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_KEYTABLE_AES (2 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_KEYTABLE_RSA (1 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_MEM (4 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
#define CTX_SAVE_SRC_SRK (6 << CTX_SAVE_SRC_SHIFT)
|
|
||||||
|
|
||||||
#define CTX_SAVE_KEY_LOW_BITS 0
|
|
||||||
#define CTX_SAVE_KEY_HIGH_BITS 1
|
|
||||||
#define CTX_SAVE_KEY_ORIGINAL_IV 2
|
|
||||||
#define CTX_SAVE_KEY_UPDATED_IV 3
|
|
||||||
|
|
||||||
#define CTX_SAVE_STICKY_BIT_INDEX_SHIFT 24
|
|
||||||
#define CTX_SAVE_KEY_INDEX_SHIFT 8
|
|
||||||
#define CTX_SAVE_RSA_KEY_INDEX_SHIFT 16
|
|
||||||
#define CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT 12
|
|
||||||
|
|
||||||
#define RSA_2048_BYTES 0x100
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
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;
|
|
||||||
uint32_t _0x820[0x5F8];
|
|
||||||
} tegra_se_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t address;
|
|
||||||
uint32_t size;
|
|
||||||
} se_addr_info_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t num_entries; /* Set to total entries - 1 */
|
|
||||||
se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */
|
|
||||||
} se_ll_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_se_t *se_get_regs(void) {
|
|
||||||
return (volatile tegra_se_t *)SE_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void se_check_error_status_reg(void);
|
|
||||||
void se_check_for_error(void);
|
|
||||||
void se_trigger_interrupt(void);
|
|
||||||
|
|
||||||
void se_validate_stored_vector(void);
|
|
||||||
void se_generate_stored_vector(void);
|
|
||||||
|
|
||||||
void se_verify_flags_cleared(void);
|
|
||||||
|
|
||||||
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
|
||||||
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
|
||||||
void clear_aes_keyslot(unsigned int keyslot);
|
|
||||||
void clear_rsa_keyslot(unsigned int keyslot);
|
|
||||||
|
|
||||||
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size);
|
|
||||||
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size);
|
|
||||||
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size);
|
|
||||||
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size);
|
|
||||||
void set_se_ctr(const void *ctr);
|
|
||||||
|
|
||||||
/* Secure AES API */
|
|
||||||
void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
|
|
||||||
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
|
|
||||||
void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size);
|
|
||||||
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv);
|
|
||||||
void se_aes_128_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
|
|
||||||
/* Hash API */
|
|
||||||
void se_calculate_sha256(void *dst, const void *src, size_t src_size);
|
|
||||||
|
|
||||||
/* RSA API */
|
|
||||||
void se_get_exp_mod_output(void *buf, size_t size);
|
|
||||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
|
||||||
bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size);
|
|
||||||
|
|
||||||
/* RNG API */
|
|
||||||
void se_initialize_rng(unsigned int keyslot);
|
|
||||||
void se_generate_random(unsigned int keyslot, void *dst, size_t size);
|
|
||||||
|
|
||||||
/* SE context save API. */
|
|
||||||
void se_generate_srk(unsigned int srkgen_keyslot);
|
|
||||||
void se_set_in_context_save_mode(bool is_context_save_mode);
|
|
||||||
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot);
|
|
||||||
void se_save_context(unsigned int srk_keyslot, unsigned int rng_keyslot, void *dst);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,100 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* For some reason GAS doesn't know about it, even with .cpu cortex-a57 */
|
|
||||||
#define cpuactlr_el1 s3_1_c15_c2_0
|
|
||||||
#define cpuectlr_el1 s3_1_c15_c2_1
|
|
||||||
|
|
||||||
.macro RESET_CORE
|
|
||||||
mov x0, #(1 << 63)
|
|
||||||
msr cpuactlr_el1, x0 /* disable regional clock gating */
|
|
||||||
isb
|
|
||||||
mov x0, #3
|
|
||||||
msr rmr_el3, x0
|
|
||||||
isb
|
|
||||||
dsb sy
|
|
||||||
/* Nintendo forgot to copy-paste the branch instruction below. */
|
|
||||||
1:
|
|
||||||
wfi
|
|
||||||
b 1b
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro ERRATUM_INVALIDATE_BTB_AT_BOOT
|
|
||||||
/* Nintendo copy-pasted https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/nvidia/tegra/common/aarch64/tegra_helpers.S#L312 */
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
/* The following comments are mine. */
|
|
||||||
/* mask all interrupts */
|
|
||||||
msr daifset, 0b1111
|
|
||||||
|
|
||||||
/*
|
|
||||||
Enable invalidates of branch target buffer, then flush
|
|
||||||
the entire instruction cache at the local level, and
|
|
||||||
with the reg change, the branch target buffer, then disable
|
|
||||||
invalidates of the branch target buffer again.
|
|
||||||
*/
|
|
||||||
mrs x0, cpuactlr_el1
|
|
||||||
orr x0, x0, #1
|
|
||||||
msr cpuactlr_el1, x0
|
|
||||||
|
|
||||||
dsb sy
|
|
||||||
isb
|
|
||||||
ic iallu
|
|
||||||
dsb sy
|
|
||||||
isb
|
|
||||||
|
|
||||||
mrs x0, cpuactlr_el1
|
|
||||||
bic x0, x0, #1
|
|
||||||
msr cpuactlr_el1, x0
|
|
||||||
|
|
||||||
.rept 7
|
|
||||||
nop /* wait long enough for the write to cpuactlr_el1 to have completed */
|
|
||||||
.endr
|
|
||||||
|
|
||||||
/* if the OS lock is set, disable it and request a warm reset */
|
|
||||||
mrs x0, oslsr_el1
|
|
||||||
ands x0, x0, #2
|
|
||||||
b.eq 2f
|
|
||||||
mov x0, xzr
|
|
||||||
msr oslar_el1, x0
|
|
||||||
|
|
||||||
RESET_CORE
|
|
||||||
|
|
||||||
.rept 65
|
|
||||||
nop /* guard against speculative excecution */
|
|
||||||
.endr
|
|
||||||
|
|
||||||
2:
|
|
||||||
/* set the OS lock */
|
|
||||||
mov x0, #1
|
|
||||||
msr oslar_el1, x0
|
|
||||||
.endm
|
|
||||||
|
|
||||||
|
|
||||||
.section .text.start
|
|
||||||
.align 4
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
ERRATUM_INVALIDATE_BTB_AT_BOOT
|
|
||||||
msr spsel, #0
|
|
||||||
ldr x0, =__start__
|
|
||||||
mov sp, x0
|
|
||||||
mov fp, #0x0
|
|
||||||
|
|
||||||
bl derive_keys
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "utils.h"
|
|
||||||
#include "se.h"
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
__attribute__ ((noreturn)) void generic_panic(void) {
|
|
||||||
/* Clear keyslots. */
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
clear_aes_keyslot(0xE);
|
|
||||||
for (size_t i = 0; i < 0x10; i++) {
|
|
||||||
clear_aes_keyslot(i);
|
|
||||||
}
|
|
||||||
clear_aes_keyslot(0xD);
|
|
||||||
clear_aes_keyslot(0xE);
|
|
||||||
while(1) { /* ... */ }
|
|
||||||
}
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_UTILS_H
|
|
||||||
#define FUSEE_UTILS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BIT(n) (1u << (n))
|
|
||||||
#define BITL(n) (1ull << (n))
|
|
||||||
#define MASK(n) (BIT(n) - 1)
|
|
||||||
#define MASKL(n) (BITL(n) - 1)
|
|
||||||
#define MASK2(a,b) (MASK(a) & ~MASK(b))
|
|
||||||
#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
|
|
||||||
|
|
||||||
#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
|
|
||||||
|
|
||||||
#define ALIGN(m) __attribute__((aligned(m)))
|
|
||||||
#define PACKED __attribute__((packed))
|
|
||||||
|
|
||||||
#define ALINLINE __attribute__((always_inline))
|
|
||||||
#define NOINLINE __attribute__((noinline))
|
|
||||||
|
|
||||||
#define SET_SYSREG(reg, val) do { temp_reg = (val); __asm__ __volatile__ ("msr " #reg ", %0" :: "r"(temp_reg) : "memory"); } while(false)
|
|
||||||
|
|
||||||
static inline uintptr_t get_physical_address(const void *addr) {
|
|
||||||
return (uintptr_t)addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t read32le(const volatile void *dword, size_t offset) {
|
|
||||||
uintptr_t addr = (uintptr_t)dword + offset;
|
|
||||||
volatile uint32_t *target = (uint32_t *)addr;
|
|
||||||
return *target;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t read32be(const volatile void *dword, size_t offset) {
|
|
||||||
return __builtin_bswap32(read32le(dword, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t read64le(const volatile void *qword, size_t offset) {
|
|
||||||
uintptr_t addr = (uintptr_t)qword + offset;
|
|
||||||
volatile uint64_t *target = (uint64_t *)addr;
|
|
||||||
return *target;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t read64be(const volatile void *qword, size_t offset) {
|
|
||||||
return __builtin_bswap64(read64le(qword, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write32le(volatile void *dword, size_t offset, uint32_t value) {
|
|
||||||
uintptr_t addr = (uintptr_t)dword + offset;
|
|
||||||
volatile uint32_t *target = (uint32_t *)addr;
|
|
||||||
*target = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write32be(volatile void *dword, size_t offset, uint32_t value) {
|
|
||||||
write32le(dword, offset, __builtin_bswap32(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write64le(volatile void *qword, size_t offset, uint64_t value) {
|
|
||||||
uintptr_t addr = (uintptr_t)qword + offset;
|
|
||||||
volatile uint64_t *target = (uint64_t *)addr;
|
|
||||||
*target = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void write64be(volatile void *qword, size_t offset, uint64_t value) {
|
|
||||||
write64le(qword, offset, __builtin_bswap64(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_additive_overflow(uint32_t a, uint32_t b) {
|
|
||||||
return __builtin_add_overflow_p(a, b, (uint32_t)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_address_loadable(uintptr_t addr) {
|
|
||||||
/* FWIW the bootROM forbids loading anything between 0x40000000 and 0x40010000, using it for itself... */
|
|
||||||
return (addr >= 0x40010000u && addr < 0x40040000u) || addr >= 0x80000000u;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_address_range_loadable(uintptr_t addr, size_t size) {
|
|
||||||
return
|
|
||||||
!__builtin_add_overflow_p(addr, size, (uintptr_t)0) && /* the range doesn't overflow */
|
|
||||||
check_32bit_address_loadable(addr) && check_32bit_address_loadable(addr + size) && /* bounds are valid */
|
|
||||||
!(addr >= 0x40010000u && addr < 0x40040000u && addr + size >= 0x40040000u) /* the range doesn't cross MMIO */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be);
|
|
||||||
static inline bool overlaps_a(const void *as, const void *ae, const void *bs, const void *be) {
|
|
||||||
return overlaps((uint64_t)(uintptr_t)as, (uint64_t)(uintptr_t)ae, (uint64_t)(uintptr_t)bs, (uint64_t)(uintptr_t)be);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool check_32bit_address_range_in_program(uintptr_t addr, size_t size) {
|
|
||||||
extern uint8_t __chainloader_start__[], __chainloader_end__[];
|
|
||||||
extern uint8_t __stack_bottom__[], __stack_top__[];
|
|
||||||
extern uint8_t __start__[], __end__[];
|
|
||||||
uint8_t *start = (uint8_t *)addr, *end = start + size;
|
|
||||||
|
|
||||||
return overlaps_a(start, end, __chainloader_start__, __chainloader_end__) ||
|
|
||||||
overlaps_a(start, end, __stack_bottom__, __stack_top__) ||
|
|
||||||
overlaps_a(start, end, (void *)0xC0000000, (void *)0xC03C0000) || /* framebuffer */
|
|
||||||
overlaps_a(start, end, __start__, __end__);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void generic_panic(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,193 +0,0 @@
|
||||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
|
||||||
OUTPUT_ARCH(arm)
|
|
||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
PHDRS
|
|
||||||
{
|
|
||||||
crt0 PT_LOAD;
|
|
||||||
chainloader PT_LOAD;
|
|
||||||
main PT_LOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mostly copied from https://github.com/devkitPro/buildscripts/blob/master/dkarm-eabi/crtls/3dsx.ld */
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
NULL : ORIGIN = 0x00000000, LENGTH = 0x1000
|
|
||||||
main : ORIGIN = 0x40010000, LENGTH = 0x20000
|
|
||||||
low_iram : ORIGIN = 0x40002000, LENGTH = 0x6000
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
PROVIDE(__start__ = 0x40010000);
|
|
||||||
PROVIDE(__stack_top__ = 0x40010000);
|
|
||||||
PROVIDE(__stack_bottom__ = 0x40008000);
|
|
||||||
PROVIDE(__heap_start__ = 0);
|
|
||||||
PROVIDE(__heap_end__ = 0);
|
|
||||||
|
|
||||||
. = __start__;
|
|
||||||
|
|
||||||
.crt0 :
|
|
||||||
{
|
|
||||||
KEEP( *(.text.start) )
|
|
||||||
KEEP( *(.init) )
|
|
||||||
. = ALIGN(32);
|
|
||||||
} >main :crt0
|
|
||||||
|
|
||||||
.chainloader_loadable :
|
|
||||||
{
|
|
||||||
. = ALIGN(32);
|
|
||||||
PROVIDE (__chainloader_start__ = ABSOLUTE(.));
|
|
||||||
PROVIDE (__chainloader_lma__ = LOADADDR(.chainloader_loadable));
|
|
||||||
KEEP(*(.chainloader.text.start))
|
|
||||||
chainloader.o(.text*)
|
|
||||||
chainloader.o(.rodata*)
|
|
||||||
chainloader.o(.data*)
|
|
||||||
. = ALIGN(32);
|
|
||||||
} >low_iram AT>main :chainloader
|
|
||||||
|
|
||||||
.chainloader_bss (NOLOAD) :
|
|
||||||
{
|
|
||||||
. = ALIGN(32);
|
|
||||||
PROVIDE (__chainloader_bss_start__ = ABSOLUTE(.));
|
|
||||||
chainloader.o(.bss* COMMON)
|
|
||||||
. = ALIGN(32);
|
|
||||||
PROVIDE (__chainloader_end__ = ABSOLUTE(.));
|
|
||||||
} >low_iram :NONE
|
|
||||||
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
. = ALIGN(32);
|
|
||||||
/* .text */
|
|
||||||
*(.text)
|
|
||||||
*(.text.*)
|
|
||||||
*(.glue_7)
|
|
||||||
*(.glue_7t)
|
|
||||||
*(.stub)
|
|
||||||
*(.gnu.warning)
|
|
||||||
*(.gnu.linkonce.t*)
|
|
||||||
|
|
||||||
/* .fini */
|
|
||||||
KEEP( *(.fini) )
|
|
||||||
. = ALIGN(8);
|
|
||||||
} >main :main
|
|
||||||
|
|
||||||
.rodata :
|
|
||||||
{
|
|
||||||
*(.rodata)
|
|
||||||
*(.roda)
|
|
||||||
*(.rodata.*)
|
|
||||||
*all.rodata*(*)
|
|
||||||
*(.gnu.linkonce.r*)
|
|
||||||
SORT(CONSTRUCTORS)
|
|
||||||
. = ALIGN(8);
|
|
||||||
} >main
|
|
||||||
|
|
||||||
.preinit_array :
|
|
||||||
{
|
|
||||||
PROVIDE (__preinit_array_start = .);
|
|
||||||
KEEP (*(.preinit_array))
|
|
||||||
PROVIDE (__preinit_array_end = .);
|
|
||||||
} >main
|
|
||||||
|
|
||||||
.init_array ALIGN(4) :
|
|
||||||
{
|
|
||||||
PROVIDE (__init_array_start = .);
|
|
||||||
KEEP (*(SORT(.init_array.*)))
|
|
||||||
KEEP (*(.init_array))
|
|
||||||
PROVIDE (__init_array_end = .);
|
|
||||||
} >main
|
|
||||||
|
|
||||||
.fini_array ALIGN(4) :
|
|
||||||
{
|
|
||||||
PROVIDE (__fini_array_start = .);
|
|
||||||
KEEP (*(.fini_array))
|
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
|
||||||
PROVIDE (__fini_array_end = .);
|
|
||||||
} >main
|
|
||||||
|
|
||||||
.ctors ALIGN(4) :
|
|
||||||
{
|
|
||||||
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
|
||||||
KEEP (*(.ctors))
|
|
||||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
|
||||||
} >main
|
|
||||||
|
|
||||||
.dtors ALIGN(4) :
|
|
||||||
{
|
|
||||||
KEEP (*crtbegin.o(.dtors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
|
||||||
KEEP (*(.dtors))
|
|
||||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
|
||||||
} >main
|
|
||||||
|
|
||||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) __exidx_start = ABSOLUTE(.);} >main
|
|
||||||
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = ABSOLUTE(.);} >main
|
|
||||||
|
|
||||||
.data :
|
|
||||||
{
|
|
||||||
*(.data)
|
|
||||||
*(.data.*)
|
|
||||||
*(.gnu.linkonce.d*)
|
|
||||||
CONSTRUCTORS
|
|
||||||
. = ALIGN(32);
|
|
||||||
} >main
|
|
||||||
|
|
||||||
.bss (NOLOAD) :
|
|
||||||
{
|
|
||||||
. = ALIGN(32);
|
|
||||||
PROVIDE (__bss_start__ = ABSOLUTE(.));
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.bss.*)
|
|
||||||
*(.gnu.linkonce.b*)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN(32);
|
|
||||||
PROVIDE (__bss_end__ = ABSOLUTE(.));
|
|
||||||
} >main :NONE
|
|
||||||
. = ALIGN(32);
|
|
||||||
__end__ = ABSOLUTE(.) ;
|
|
||||||
|
|
||||||
/* ==================
|
|
||||||
==== Metadata ====
|
|
||||||
================== */
|
|
||||||
|
|
||||||
/* Discard sections that difficult post-processing */
|
|
||||||
/DISCARD/ : { *(.group .comment .note) }
|
|
||||||
|
|
||||||
/* Stabs debugging sections. */
|
|
||||||
.stab 0 : { *(.stab) }
|
|
||||||
.stabstr 0 : { *(.stabstr) }
|
|
||||||
.stab.excl 0 : { *(.stab.excl) }
|
|
||||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
|
||||||
.stab.index 0 : { *(.stab.index) }
|
|
||||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
|
||||||
|
|
||||||
/* DWARF debug sections.
|
|
||||||
Symbols in the DWARF debugging sections are relative to the beginning
|
|
||||||
of the section so we begin them at 0. */
|
|
||||||
|
|
||||||
/* DWARF 1 */
|
|
||||||
.debug 0 : { *(.debug) }
|
|
||||||
.line 0 : { *(.line) }
|
|
||||||
|
|
||||||
/* GNU DWARF 1 extensions */
|
|
||||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
|
||||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
|
||||||
|
|
||||||
/* DWARF 1.1 and DWARF 2 */
|
|
||||||
.debug_aranges 0 : { *(.debug_aranges) }
|
|
||||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
||||||
|
|
||||||
/* DWARF 2 */
|
|
||||||
.debug_info 0 : { *(.debug_info) }
|
|
||||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
||||||
.debug_line 0 : { *(.debug_line) }
|
|
||||||
.debug_frame 0 : { *(.debug_frame) }
|
|
||||||
.debug_str 0 : { *(.debug_str) }
|
|
||||||
.debug_loc 0 : { *(.debug_loc) }
|
|
||||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
%rename link old_link
|
|
||||||
|
|
||||||
*link:
|
|
||||||
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
|
|
||||||
|
|
||||||
*startfile:
|
|
||||||
crti%O%s crtbegin%O%s
|
|
|
@ -1,84 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
import sys, os
|
|
||||||
from struct import pack as pk, unpack as up
|
|
||||||
from Crypto.Cipher import AES
|
|
||||||
from Crypto.Hash import CMAC
|
|
||||||
try:
|
|
||||||
import KEYS
|
|
||||||
except ImportError:
|
|
||||||
import KEYS_template as KEYS
|
|
||||||
print('Warning: output will not work on 7.0.0+!')
|
|
||||||
|
|
||||||
|
|
||||||
def shift_left_xor_rb(s):
|
|
||||||
if hasattr(int, "from_bytes"):
|
|
||||||
N = int.from_bytes(s, byteorder="big")
|
|
||||||
else:
|
|
||||||
N = int(s.encode('hex'), 16)
|
|
||||||
|
|
||||||
if N & (1 << 127):
|
|
||||||
N = ((N << 1) ^ 0x87) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
|
||||||
else:
|
|
||||||
N = ((N << 1) ^ 0x00) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
|
||||||
return bytearray.fromhex('%032x' % N)
|
|
||||||
|
|
||||||
|
|
||||||
def sxor(x, y):
|
|
||||||
return bytearray(a^b for a,b in zip(x, y))
|
|
||||||
|
|
||||||
|
|
||||||
def get_last_block_for_desired_mac(key, data, desired_mac):
|
|
||||||
assert len(desired_mac) == 0x10
|
|
||||||
k1 = shift_left_xor_rb(AES.new(key, AES.MODE_ECB).encrypt(bytearray(0x10)))
|
|
||||||
if len(data) & 0xF:
|
|
||||||
k1 = shift_left_xor_rb(k1)
|
|
||||||
data = data + b'\x80'
|
|
||||||
data = data + bytearray((0x10 - (len(data) & 0xF)) & 0xF)
|
|
||||||
num_blocks = (len(data) + 0xF) >> 4
|
|
||||||
last_block = sxor(bytearray(AES.new(key, AES.MODE_ECB).decrypt(desired_mac)), bytearray(k1))
|
|
||||||
if len(data) > 0x0:
|
|
||||||
last_block = sxor(last_block, bytearray(AES.new(key, AES.MODE_CBC, bytearray(0x10)).encrypt(data)[-0x10:]))
|
|
||||||
return last_block
|
|
||||||
|
|
||||||
|
|
||||||
def sign_encrypt_code(code, sig_key, enc_key, iv, desired_mac, version):
|
|
||||||
# Pad with 0x20 of zeroes.
|
|
||||||
code = code + bytearray(0x20)
|
|
||||||
code_len = len(code)
|
|
||||||
code_len += 0xFFF
|
|
||||||
code_len &= ~0xFFF
|
|
||||||
code = code + bytearray(code_len - len(code))
|
|
||||||
|
|
||||||
# Insert version
|
|
||||||
code = code[:8] + pk('<I', version) + code[12:]
|
|
||||||
|
|
||||||
# Add empty trustzone, warmboot segments.
|
|
||||||
code = code + bytearray(0x1FE0 - 0x10)
|
|
||||||
pk11_hdr = b'PK11' + pk('<IIIIIII', 0x1000, 0, 0, code_len - 0x20, 0, 0x1000, 0)
|
|
||||||
pk11 = pk11_hdr + code
|
|
||||||
enc_pk11 = AES.new(enc_key, AES.MODE_CBC, iv).encrypt(pk11)
|
|
||||||
enc_pk11 = pk('<IIII', len(pk11) + 0x10, 0, 0, 0) + iv + enc_pk11
|
|
||||||
enc_pk11 = enc_pk11 + get_last_block_for_desired_mac(sig_key, enc_pk11, desired_mac)
|
|
||||||
enc_pk11 = enc_pk11 + CMAC.new(sig_key, enc_pk11, AES).digest()
|
|
||||||
return enc_pk11
|
|
||||||
|
|
||||||
|
|
||||||
def main(argc, argv):
|
|
||||||
if argc != 3:
|
|
||||||
print('Usage: %s input output' % argv[0])
|
|
||||||
return 1
|
|
||||||
with open(argv[1], 'rb') as f:
|
|
||||||
code = f.read()
|
|
||||||
if len(code) & 0xF:
|
|
||||||
code = code + bytearray(0x10 - (len(code) & 0xF))
|
|
||||||
fn, fext = os.path.splitext(argv[2])
|
|
||||||
for key in range(KEYS.NUM_KEYS):
|
|
||||||
with open(fn + ('_%02X' % key) + fext, 'wb') as f:
|
|
||||||
f.write(sign_encrypt_code(code, KEYS.HOVI_SIG_KEY_PRD[key], KEYS.HOVI_ENC_KEY_PRD[key], KEYS.IV[key], b'THANKS_NVIDIA_<3', key))
|
|
||||||
with open(fn + ('_dev_%02X' % key) + fext, 'wb') as f:
|
|
||||||
f.write(sign_encrypt_code(code, KEYS.HOVI_SIG_KEY_DEV[key], KEYS.HOVI_ENC_KEY_DEV[key], KEYS.IV_DEV[key], b'THANKS_NVIDIA_<3', key))
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main(len(sys.argv), sys.argv))
|
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_APB_MISC_H
|
|
||||||
#define FUSEE_APB_MISC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define APB_MISC_BASE 0x70000000
|
|
||||||
#define APB_PADCTL_BASE 0x70000810
|
|
||||||
#define MAKE_APB_MISC_REG(n) MAKE_REG32(APB_MISC_BASE + n)
|
|
||||||
#define MAKE_APB_PADCTL_REG(n) MAKE_REG32(APB_PADCTL_BASE + n)
|
|
||||||
|
|
||||||
#define APB_MISC_PP_PINMUX_GLOBAL_0 MAKE_APB_MISC_REG(0x40)
|
|
||||||
#define APB_MISC_GP_DSI_PAD_CONTROL_0 MAKE_APB_MISC_REG(0xAC0)
|
|
||||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB64)
|
|
||||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB68)
|
|
||||||
|
|
||||||
#define SDMMC1_PAD_CAL_DRVUP_SHIFT (20)
|
|
||||||
#define SDMMC1_PAD_CAL_DRVDN_SHIFT (12)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_SHIFT (28)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_SHIFT (30)
|
|
||||||
#define SDMMC1_PAD_CAL_DRVUP_MASK (0x7Fu << SDMMC1_PAD_CAL_DRVUP_SHIFT)
|
|
||||||
#define SDMMC1_PAD_CAL_DRVDN_MASK (0x7Fu << SDMMC1_PAD_CAL_DRVDN_SHIFT)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_MASK (0x03u << SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_SHIFT)
|
|
||||||
#define SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_MASK (0x03u << SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_SHIFT)
|
|
||||||
|
|
||||||
#define EMMC2_PAD_DRVUP_COMP_SHIFT (8)
|
|
||||||
#define EMMC2_PAD_DRVDN_COMP_SHIFT (2)
|
|
||||||
#define EMMC2_PAD_DRVUP_COMP_MASK (0x3Fu << EMMC2_PAD_DRVUP_COMP_SHIFT)
|
|
||||||
#define EMMC2_PAD_DRVDN_COMP_MASK (0x3Fu << EMMC2_PAD_DRVDN_COMP_SHIFT)
|
|
||||||
|
|
||||||
#define SDMMC2_PAD_CAL_DRVUP_SHIFT (20)
|
|
||||||
#define SDMMC2_PAD_CAL_DRVDN_SHIFT (12)
|
|
||||||
#define SDMMC2_PAD_CAL_DRVUP_MASK (0x7Fu << SDMMC2_PAD_CAL_DRVUP_SHIFT)
|
|
||||||
#define SDMMC2_PAD_CAL_DRVDN_MASK (0x7Fu << SDMMC2_PAD_CAL_DRVDN_SHIFT)
|
|
||||||
|
|
||||||
#define EMMC4_PAD_DRVUP_COMP_SHIFT (8)
|
|
||||||
#define EMMC4_PAD_DRVDN_COMP_SHIFT (2)
|
|
||||||
#define EMMC4_PAD_DRVUP_COMP_MASK (0x3Fu << EMMC4_PAD_DRVUP_COMP_SHIFT)
|
|
||||||
#define EMMC4_PAD_DRVDN_COMP_MASK (0x3Fu << EMMC4_PAD_DRVDN_COMP_SHIFT)
|
|
||||||
|
|
||||||
#define PADCTL_SDMMC1_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC3_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC2_ENABLE_DATA_IN (0xFF << 8)
|
|
||||||
#define PADCTL_SDMMC2_ENABLE_CLK_IN (0x3 << 4)
|
|
||||||
#define PADCTL_SDMMC2_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC4_ENABLE_DATA_IN (0xFF << 8)
|
|
||||||
#define PADCTL_SDMMC4_ENABLE_CLK_IN (0x3 << 4)
|
|
||||||
#define PADCTL_SDMMC4_DEEP_LOOPBACK (1 << 0)
|
|
||||||
#define PADCTL_SDMMC1_CD_SOURCE (1 << 0)
|
|
||||||
#define PADCTL_SDMMC1_WP_SOURCE (1 << 1)
|
|
||||||
#define PADCTL_SDMMC3_CD_SOURCE (1 << 2)
|
|
||||||
#define PADCTL_SDMMC3_WP_SOURCE (1 << 3)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t asdbgreg; /* 0x810 */
|
|
||||||
uint32_t _0x814[0x31];
|
|
||||||
uint32_t sdmmc1_clk_lpbk_control; /* 0x8D4 */
|
|
||||||
uint32_t sdmmc3_clk_lpbk_control; /* 0x8D8 */
|
|
||||||
uint32_t emmc2_pad_cfg_control; /* 0x8DC */
|
|
||||||
uint32_t emmc4_pad_cfg_control; /* 0x8E0 */
|
|
||||||
uint32_t _0x8E4[0x6E];
|
|
||||||
uint32_t sdmmc1_pad_cfgpadctrl; /* 0xA98 */
|
|
||||||
uint32_t emmc2_pad_cfgpadctrl; /* 0xA9C */
|
|
||||||
uint32_t emmc2_pad_drv_type_cfgpadctrl; /* 0xAA0 */
|
|
||||||
uint32_t emmc2_pad_pupd_cfgpadctrl; /* 0xAA4 */
|
|
||||||
uint32_t _0xAA8[0x03];
|
|
||||||
uint32_t sdmmc3_pad_cfgpadctrl; /* 0xAB0 */
|
|
||||||
uint32_t emmc4_pad_cfgpadctrl; /* 0xAB4 */
|
|
||||||
uint32_t emmc4_pad_drv_type_cfgpadctrl; /* 0xAB8 */
|
|
||||||
uint32_t emmc4_pad_pupd_cfgpadctrl; /* 0xABC */
|
|
||||||
uint32_t _0xAC0[0x2E];
|
|
||||||
uint32_t vgpio_gpio_mux_sel; /* 0xB74 */
|
|
||||||
uint32_t qspi_sck_lpbk_control; /* 0xB78 */
|
|
||||||
} tegra_padctl_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_padctl_t *padctl_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_padctl_t *)APB_PADCTL_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "btn.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "timers.h"
|
|
||||||
|
|
||||||
uint32_t btn_read()
|
|
||||||
{
|
|
||||||
uint32_t res = 0;
|
|
||||||
|
|
||||||
if (!gpio_read(GPIO_BUTTON_VOL_DOWN))
|
|
||||||
res |= BTN_VOL_DOWN;
|
|
||||||
|
|
||||||
if (!gpio_read(GPIO_BUTTON_VOL_UP))
|
|
||||||
res |= BTN_VOL_UP;
|
|
||||||
|
|
||||||
uint32_t val = 0;
|
|
||||||
if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x15, &val, 1))
|
|
||||||
{
|
|
||||||
if (val & 0x4)
|
|
||||||
res |= BTN_POWER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t btn_wait()
|
|
||||||
{
|
|
||||||
uint32_t res = 0, btn = btn_read();
|
|
||||||
int pwr = 0;
|
|
||||||
|
|
||||||
if (btn & BTN_POWER)
|
|
||||||
{
|
|
||||||
pwr = 1;
|
|
||||||
btn &= ~BTN_POWER;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
res = btn_read();
|
|
||||||
|
|
||||||
if (!(res & BTN_POWER) && pwr)
|
|
||||||
pwr = 0;
|
|
||||||
else if (pwr)
|
|
||||||
res &= ~BTN_POWER;
|
|
||||||
} while (btn == res);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask)
|
|
||||||
{
|
|
||||||
uint32_t timeout = get_time_ms() + time_ms;
|
|
||||||
uint32_t res = btn_read() & mask;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!(res & mask))
|
|
||||||
res = btn_read() & mask;
|
|
||||||
} while (get_time_ms() < timeout);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_BTN_H_
|
|
||||||
#define FUSEE_BTN_H_
|
|
||||||
|
|
||||||
#define BTN_POWER 0x1
|
|
||||||
#define BTN_VOL_DOWN 0x2
|
|
||||||
#define BTN_VOL_UP 0x4
|
|
||||||
|
|
||||||
uint32_t btn_read();
|
|
||||||
uint32_t btn_wait();
|
|
||||||
uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "car.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
|
||||||
switch (dev) {
|
|
||||||
case CARDEVICE_UARTA: return 0x178;
|
|
||||||
case CARDEVICE_UARTB: return 0x17C;
|
|
||||||
case CARDEVICE_UARTC: return 0x1A0;
|
|
||||||
case CARDEVICE_I2C1: return 0x124;
|
|
||||||
case CARDEVICE_I2C5: return 0x128;
|
|
||||||
case CARDEVICE_TZRAM: return 0;
|
|
||||||
case CARDEVICE_SE: return 0x42C;
|
|
||||||
case CARDEVICE_HOST1X: return 0x180;
|
|
||||||
case CARDEVICE_TSEC: return 0x1F4;
|
|
||||||
case CARDEVICE_SOR_SAFE: return 0;
|
|
||||||
case CARDEVICE_SOR0: return 0;
|
|
||||||
case CARDEVICE_SOR1: return 0x410;
|
|
||||||
case CARDEVICE_KFUSE: return 0;
|
|
||||||
case CARDEVICE_CL_DVFS: return 0;
|
|
||||||
case CARDEVICE_CORESIGHT: return 0x1D4;
|
|
||||||
case CARDEVICE_MSELECT: return 0x3B4;
|
|
||||||
case CARDEVICE_ACTMON: return 0x3E8;
|
|
||||||
case CARDEVICE_BPMP: return 0;
|
|
||||||
default: generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_val(CarDevice dev) {
|
|
||||||
switch (dev) {
|
|
||||||
case CARDEVICE_UARTA: return 0;
|
|
||||||
case CARDEVICE_UARTB: return 0;
|
|
||||||
case CARDEVICE_UARTC: return 0;
|
|
||||||
case CARDEVICE_I2C1: return 6;
|
|
||||||
case CARDEVICE_I2C5: return 6;
|
|
||||||
case CARDEVICE_TZRAM: return 0;
|
|
||||||
case CARDEVICE_SE: return 0;
|
|
||||||
case CARDEVICE_HOST1X: return 4;
|
|
||||||
case CARDEVICE_TSEC: return 0;
|
|
||||||
case CARDEVICE_SOR_SAFE: return 0;
|
|
||||||
case CARDEVICE_SOR0: return 0;
|
|
||||||
case CARDEVICE_SOR1: return 0;
|
|
||||||
case CARDEVICE_KFUSE: return 0;
|
|
||||||
case CARDEVICE_CL_DVFS: return 0;
|
|
||||||
case CARDEVICE_CORESIGHT: return 0;
|
|
||||||
case CARDEVICE_MSELECT: return 0;
|
|
||||||
case CARDEVICE_ACTMON: return 6;
|
|
||||||
case CARDEVICE_BPMP: return 0;
|
|
||||||
default: generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_div(CarDevice dev) {
|
|
||||||
switch (dev) {
|
|
||||||
case CARDEVICE_UARTA: return 0;
|
|
||||||
case CARDEVICE_UARTB: return 0;
|
|
||||||
case CARDEVICE_UARTC: return 0;
|
|
||||||
case CARDEVICE_I2C1: return 0;
|
|
||||||
case CARDEVICE_I2C5: return 0;
|
|
||||||
case CARDEVICE_TZRAM: return 0;
|
|
||||||
case CARDEVICE_SE: return 0;
|
|
||||||
case CARDEVICE_HOST1X: return 3;
|
|
||||||
case CARDEVICE_TSEC: return 2;
|
|
||||||
case CARDEVICE_SOR_SAFE: return 0;
|
|
||||||
case CARDEVICE_SOR0: return 0;
|
|
||||||
case CARDEVICE_SOR1: return 2;
|
|
||||||
case CARDEVICE_KFUSE: return 0;
|
|
||||||
case CARDEVICE_CL_DVFS: return 0;
|
|
||||||
case CARDEVICE_CORESIGHT: return 4;
|
|
||||||
case CARDEVICE_MSELECT: return 6;
|
|
||||||
case CARDEVICE_ACTMON: return 0;
|
|
||||||
case CARDEVICE_BPMP: return 0;
|
|
||||||
default: generic_panic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
|
|
||||||
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
|
|
||||||
|
|
||||||
void clk_enable(CarDevice dev) {
|
|
||||||
uint32_t clk_source_reg;
|
|
||||||
if ((clk_source_reg = get_clk_source_reg(dev))) {
|
|
||||||
MAKE_CAR_REG(clk_source_reg) = (get_clk_source_val(dev) << 29) | get_clk_source_div(dev);
|
|
||||||
}
|
|
||||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clk_disable(CarDevice dev) {
|
|
||||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
void rst_enable(CarDevice dev) {
|
|
||||||
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clkrst_disable(CarDevice dev) {
|
|
||||||
rst_enable(dev);
|
|
||||||
clk_disable(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clkrst_reboot(CarDevice dev) {
|
|
||||||
clkrst_disable(dev);
|
|
||||||
if (dev == CARDEVICE_KFUSE) {
|
|
||||||
/* Workaround for KFUSE clock. */
|
|
||||||
clk_enable(dev);
|
|
||||||
udelay(100);
|
|
||||||
rst_disable(dev);
|
|
||||||
udelay(200);
|
|
||||||
} else {
|
|
||||||
clkrst_enable(dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clkrst_enable_fuse_regs(bool enable) {
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
car->misc_clk_enb = ((car->misc_clk_enb & 0xEFFFFFFF) | ((enable & 1) << 28));
|
|
||||||
}
|
|
|
@ -1,510 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_CAR_H
|
|
||||||
#define FUSEE_CAR_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define CAR_BASE 0x60006000
|
|
||||||
#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
|
|
||||||
|
|
||||||
#define CLK_L_SDMMC1 (1 << 14)
|
|
||||||
#define CLK_L_SDMMC2 (1 << 9)
|
|
||||||
#define CLK_U_SDMMC3 (1 << 5)
|
|
||||||
#define CLK_L_SDMMC4 (1 << 15)
|
|
||||||
|
|
||||||
#define CLK_SOURCE_MASK (0b111 << 29)
|
|
||||||
#define CLK_SOURCE_FIRST (0b000 << 29)
|
|
||||||
#define CLK_DIVIDER_MASK (0xff << 0)
|
|
||||||
#define CLK_DIVIDER_UNITY (0x00 << 0)
|
|
||||||
|
|
||||||
#define NUM_CAR_BANKS 7
|
|
||||||
|
|
||||||
/* Clock and reset devices. */
|
|
||||||
typedef enum {
|
|
||||||
CARDEVICE_BPMP = ((0 << 5) | 0x1),
|
|
||||||
CARDEVICE_UARTA = ((0 << 5) | 0x6),
|
|
||||||
CARDEVICE_UARTB = ((0 << 5) | 0x7),
|
|
||||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
|
||||||
CARDEVICE_USBD = ((0 << 5) | 0x16),
|
|
||||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
|
||||||
CARDEVICE_AHBDMA = ((1 << 5) | 0x1),
|
|
||||||
CARDEVICE_APBDMA = ((1 << 5) | 0x2),
|
|
||||||
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
|
|
||||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
|
||||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
|
||||||
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
|
|
||||||
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
|
||||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
|
||||||
CARDEVICE_MSELECT = ((3 << 5) | 0x8),
|
|
||||||
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
|
||||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
|
||||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
|
||||||
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
|
|
||||||
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
|
|
||||||
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
|
|
||||||
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
|
|
||||||
} CarDevice;
|
|
||||||
|
|
||||||
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t rst_src; /* _RST_SOURCE_0, 0x00 */
|
|
||||||
|
|
||||||
/* _RST_DEVICES_L/H/U_0 0x4-0xc */
|
|
||||||
uint32_t rst_dev_l;
|
|
||||||
uint32_t rst_dev_h;
|
|
||||||
uint32_t rst_dev_u;
|
|
||||||
|
|
||||||
/* _CLK_OUT_ENB_L/H/U_0 0x10-0x18 */
|
|
||||||
uint32_t clk_out_enb_l;
|
|
||||||
uint32_t clk_out_enb_h;
|
|
||||||
uint32_t clk_out_enb_u;
|
|
||||||
|
|
||||||
uint32_t _0x1C;
|
|
||||||
uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
|
|
||||||
uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0, 0x24 */
|
|
||||||
uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
|
|
||||||
uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0, 0x2c */
|
|
||||||
uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
|
|
||||||
uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
|
|
||||||
uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0, 0x38 */
|
|
||||||
uint32_t _0x3C;
|
|
||||||
uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0, 0x40 */
|
|
||||||
uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
|
|
||||||
uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
|
|
||||||
uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4c */
|
|
||||||
uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
|
|
||||||
uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
|
|
||||||
uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
|
|
||||||
uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0, 0x5c */
|
|
||||||
uint32_t _0x60[2];
|
|
||||||
uint32_t plle_ss_cntl; /* _PLLE_SS_CNTL_0, 0x68 */
|
|
||||||
uint32_t plle_misc1; /* _PLLE_MISC1_0, 0x6c */
|
|
||||||
uint32_t _0x70[4];
|
|
||||||
|
|
||||||
/* PLLC 0x80-0x8c */
|
|
||||||
uint32_t pllc_base;
|
|
||||||
uint32_t pllc_out;
|
|
||||||
uint32_t pllc_misc0;
|
|
||||||
uint32_t pllc_misc1;
|
|
||||||
|
|
||||||
/* PLLM 0x90-0x9c */
|
|
||||||
uint32_t pllm_base;
|
|
||||||
uint32_t pllm_out;
|
|
||||||
uint32_t pllm_misc1;
|
|
||||||
uint32_t pllm_misc2;
|
|
||||||
|
|
||||||
/* PLLP 0xa0-0xac */
|
|
||||||
uint32_t pllp_base;
|
|
||||||
uint32_t pllp_outa;
|
|
||||||
uint32_t pllp_outb;
|
|
||||||
uint32_t pllp_misc;
|
|
||||||
|
|
||||||
/* PLLA 0xb0-0xbc */
|
|
||||||
uint32_t plla_base;
|
|
||||||
uint32_t plla_out;
|
|
||||||
uint32_t plla_misc0;
|
|
||||||
uint32_t plla_misc1;
|
|
||||||
|
|
||||||
/* PLLU 0xc0-0xcc */
|
|
||||||
uint32_t pllu_base;
|
|
||||||
uint32_t pllu_out;
|
|
||||||
uint32_t pllu_misc1;
|
|
||||||
uint32_t pllu_misc2;
|
|
||||||
|
|
||||||
/* PLLD 0xd0-0xdc */
|
|
||||||
uint32_t plld_base;
|
|
||||||
uint32_t plld_out;
|
|
||||||
uint32_t plld_misc1;
|
|
||||||
uint32_t plld_misc2;
|
|
||||||
|
|
||||||
/* PLLX 0xe0-0xe4 */
|
|
||||||
uint32_t pllx_base;
|
|
||||||
uint32_t pllx_misc;
|
|
||||||
|
|
||||||
/* PLLE 0xe8-0xf4 */
|
|
||||||
uint32_t plle_base;
|
|
||||||
uint32_t plle_misc;
|
|
||||||
uint32_t plle_ss_cntl1;
|
|
||||||
uint32_t plle_ss_cntl2;
|
|
||||||
|
|
||||||
uint32_t lvl2_clk_gate_ovra; /* _LVL2_CLK_GATE_OVRA_0, 0xf8 */
|
|
||||||
uint32_t lvl2_clk_gate_ovrb; /* _LVL2_CLK_GATE_OVRB_0, 0xfc */
|
|
||||||
|
|
||||||
uint32_t clk_source_i2s2; /* _CLK_SOURCE_I2S2_0, 0x100 */
|
|
||||||
uint32_t clk_source_i2s3; /* _CLK_SOURCE_I2S3_0, 0x104 */
|
|
||||||
uint32_t clk_source_spdif_out; /* _CLK_SOURCE_SPDIF_OUT_0, 0x108 */
|
|
||||||
uint32_t clk_source_spdif_in; /* _CLK_SOURCE_SPDIF_IN_0, 0x10c */
|
|
||||||
uint32_t clk_source_pwm; /* _CLK_SOURCE_PWM_0, 0x110 */
|
|
||||||
uint32_t _0x114;
|
|
||||||
uint32_t clk_source_spi2; /* _CLK_SOURCE_SPI2_0, 0x118 */
|
|
||||||
uint32_t clk_source_spi3; /* _CLK_SOURCE_SPI3_0, 0x11c */
|
|
||||||
uint32_t _0x120;
|
|
||||||
uint32_t clk_source_i2c1; /* _CLK_SOURCE_I2C1_0, 0x124 */
|
|
||||||
uint32_t clk_source_i2c5; /* _CLK_SOURCE_I2C5_0, 0x128 */
|
|
||||||
uint32_t _0x12c[2];
|
|
||||||
uint32_t clk_source_spi1; /* _CLK_SOURCE_SPI1_0, 0x134 */
|
|
||||||
uint32_t clk_source_disp1; /* _CLK_SOURCE_DISP1_0, 0x138 */
|
|
||||||
uint32_t clk_source_disp2; /* _CLK_SOURCE_DISP2_0, 0x13c */
|
|
||||||
uint32_t _0x140;
|
|
||||||
uint32_t clk_source_isp; /* _CLK_SOURCE_ISP_0, 0x144 */
|
|
||||||
uint32_t clk_source_vi; /* _CLK_SOURCE_VI_0, 0x148 */
|
|
||||||
uint32_t _0x14c;
|
|
||||||
uint32_t clk_source_sdmmc1; /* _CLK_SOURCE_SDMMC1_0, 0x150 */
|
|
||||||
uint32_t clk_source_sdmmc2; /* _CLK_SOURCE_SDMMC2_0, 0x154 */
|
|
||||||
uint32_t _0x158[3];
|
|
||||||
uint32_t clk_source_sdmmc4; /* _CLK_SOURCE_SDMMC4_0, 0x164 */
|
|
||||||
uint32_t _0x168[4];
|
|
||||||
uint32_t clk_source_uarta; /* _CLK_SOURCE_UARTA_0, 0x178 */
|
|
||||||
uint32_t clk_source_uartb; /* _CLK_SOURCE_UARTB_0, 0x17c */
|
|
||||||
uint32_t clk_source_host1x; /* _CLK_SOURCE_HOST1X_0, 0x180 */
|
|
||||||
uint32_t _0x184[5];
|
|
||||||
uint32_t clk_source_i2c2; /* _CLK_SOURCE_I2C2_0, 0x198 */
|
|
||||||
uint32_t clk_source_emc; /* _CLK_SOURCE_EMC_0, 0x19c */
|
|
||||||
uint32_t clk_source_uartc; /* _CLK_SOURCE_UARTC_0, 0x1a0 */
|
|
||||||
uint32_t _0x1a4;
|
|
||||||
uint32_t clk_source_vi_sensor; /* _CLK_SOURCE_VI_SENSOR_0, 0x1a8 */
|
|
||||||
uint32_t _0x1ac[2];
|
|
||||||
uint32_t clk_source_spi4; /* _CLK_SOURCE_SPI4_0, 0x1b4 */
|
|
||||||
uint32_t clk_source_i2c3; /* _CLK_SOURCE_I2C3_0, 0x1b8 */
|
|
||||||
uint32_t clk_source_sdmmc3; /* _CLK_SOURCE_SDMMC3_0, 0x1bc */
|
|
||||||
uint32_t clk_source_uartd; /* _CLK_SOURCE_UARTD_0, 0x1c0 */
|
|
||||||
uint32_t _0x1c4[2];
|
|
||||||
uint32_t clk_source_owr; /* _CLK_SOURCE_OWR_0, 0x1cc */
|
|
||||||
uint32_t _0x1d0;
|
|
||||||
uint32_t clk_source_csite; /* _CLK_SOURCE_CSITE_0, 0x1d4 */
|
|
||||||
uint32_t clk_source_i2s1; /* _CLK_SOURCE_I2S1_0, 0x1d8 */
|
|
||||||
uint32_t clk_source_dtv; /* _CLK_SOURCE_DTV_0, 0x1dc */
|
|
||||||
uint32_t _0x1e0[5];
|
|
||||||
uint32_t clk_source_tsec; /* _CLK_SOURCE_TSEC_0, 0x1f4 */
|
|
||||||
uint32_t _0x1f8;
|
|
||||||
|
|
||||||
uint32_t clk_spare2; /* _CLK_SPARE2_0, 0x1fc */
|
|
||||||
uint32_t _0x200[32];
|
|
||||||
|
|
||||||
uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
|
|
||||||
uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
|
|
||||||
uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
|
|
||||||
|
|
||||||
uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
|
|
||||||
uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
|
|
||||||
uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
|
|
||||||
|
|
||||||
uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
|
|
||||||
uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
|
|
||||||
uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
|
|
||||||
|
|
||||||
uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
|
|
||||||
uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
|
|
||||||
uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
|
|
||||||
|
|
||||||
uint32_t _0x2b0[17];
|
|
||||||
uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
|
|
||||||
uint32_t _0x2f8[2];
|
|
||||||
|
|
||||||
/* _RST_DEV_L/H/U_SET_0 0x300-0x314 */
|
|
||||||
uint32_t rst_dev_l_set;
|
|
||||||
uint32_t rst_dev_l_clr;
|
|
||||||
uint32_t rst_dev_h_set;
|
|
||||||
uint32_t rst_dev_h_clr;
|
|
||||||
uint32_t rst_dev_u_set;
|
|
||||||
uint32_t rst_dev_u_clr;
|
|
||||||
|
|
||||||
uint32_t _0x318[2];
|
|
||||||
|
|
||||||
/* _CLK_ENB_L/H/U_CLR_0 0x320-0x334 */
|
|
||||||
uint32_t clk_enb_l_set;
|
|
||||||
uint32_t clk_enb_l_clr;
|
|
||||||
uint32_t clk_enb_h_set;
|
|
||||||
uint32_t clk_enb_h_clr;
|
|
||||||
uint32_t clk_enb_u_set;
|
|
||||||
uint32_t clk_enb_u_clr;
|
|
||||||
|
|
||||||
uint32_t _0x338;
|
|
||||||
uint32_t ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD_0, 0x33c */
|
|
||||||
uint32_t rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
|
|
||||||
uint32_t rst_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
|
|
||||||
|
|
||||||
/* Additional (T30) registers */
|
|
||||||
uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
|
|
||||||
uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
|
|
||||||
|
|
||||||
uint32_t _0x350[2];
|
|
||||||
uint32_t rst_dev_v; /* _RST_DEVICES_V_0, 0x358 */
|
|
||||||
uint32_t rst_dev_w; /* _RST_DEVICES_W_0, 0x35c */
|
|
||||||
uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V_0, 0x360 */
|
|
||||||
uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_W_0, 0x364 */
|
|
||||||
uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
|
|
||||||
uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36c */
|
|
||||||
uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
|
|
||||||
uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
|
|
||||||
uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
|
|
||||||
uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37c */
|
|
||||||
uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
|
|
||||||
uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
|
|
||||||
uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
|
|
||||||
uint32_t _0x38c[5];
|
|
||||||
uint32_t lvl2_clk_gate_ovrc; /* _LVL2_CLK_GATE_OVRC, 0x3a0 */
|
|
||||||
uint32_t lvl2_clk_gate_ovrd; /* _LVL2_CLK_GATE_OVRD, 0x3a4 */
|
|
||||||
uint32_t _0x3a8[2];
|
|
||||||
|
|
||||||
uint32_t _0x3b0;
|
|
||||||
uint32_t clk_source_mselect; /* _CLK_SOURCE_MSELECT_0, 0x3b4 */
|
|
||||||
uint32_t clk_source_tsensor; /* _CLK_SOURCE_TSENSOR_0, 0x3b8 */
|
|
||||||
uint32_t clk_source_i2s4; /* _CLK_SOURCE_I2S4_0, 0x3bc */
|
|
||||||
uint32_t clk_source_i2s5; /* _CLK_SOURCE_I2S5_0, 0x3c0 */
|
|
||||||
uint32_t clk_source_i2c4; /* _CLK_SOURCE_I2C4_0, 0x3c4 */
|
|
||||||
uint32_t _0x3c8[2];
|
|
||||||
uint32_t clk_source_ahub; /* _CLK_SOURCE_AHUB_0, 0x3d0 */
|
|
||||||
uint32_t _0x3d4[4];
|
|
||||||
uint32_t clk_source_hda2codec_2x; /* _CLK_SOURCE_HDA2CODEC_2X_0, 0x3e4 */
|
|
||||||
uint32_t clk_source_actmon; /* _CLK_SOURCE_ACTMON_0, 0x3e8 */
|
|
||||||
uint32_t clk_source_extperiph1; /* _CLK_SOURCE_EXTPERIPH1_0, 0x3ec */
|
|
||||||
uint32_t clk_source_extperiph2; /* _CLK_SOURCE_EXTPERIPH2_0, 0x3f0 */
|
|
||||||
uint32_t clk_source_extperiph3; /* _CLK_SOURCE_EXTPERIPH3_0, 0x3f4 */
|
|
||||||
uint32_t _0x3f8;
|
|
||||||
uint32_t clk_source_i2c_slow; /* _CLK_SOURCE_I2C_SLOW_0, 0x3fc */
|
|
||||||
uint32_t clk_source_sys; /* _CLK_SOURCE_SYS_0, 0x400 */
|
|
||||||
uint32_t clk_source_ispb; /* _CLK_SOURCE_ISPB_0, 0x404 */
|
|
||||||
uint32_t _0x408[2];
|
|
||||||
uint32_t clk_source_sor1; /* _CLK_SOURCE_SOR1_0, 0x410 */
|
|
||||||
uint32_t clk_source_sor0; /* _CLK_SOURCE_SOR0_0, 0x414 */
|
|
||||||
uint32_t _0x418[2];
|
|
||||||
uint32_t clk_source_sata_oob; /* _CLK_SOURCE_SATA_OOB_0, 0x420 */
|
|
||||||
uint32_t clk_source_sata; /* _CLK_SOURCE_SATA_0, 0x424 */
|
|
||||||
uint32_t clk_source_hda; /* _CLK_SOURCE_HDA_0, 0x428 */
|
|
||||||
uint32_t clk_source_se; /* _CLK_SOURCE_SE_0, 0x42c */
|
|
||||||
|
|
||||||
/* _RST_DEV_V/W_SET_0 0x430-0x43c */
|
|
||||||
uint32_t rst_dev_v_set;
|
|
||||||
uint32_t rst_dev_v_clr;
|
|
||||||
uint32_t rst_dev_w_set;
|
|
||||||
uint32_t rst_dev_w_clr;
|
|
||||||
|
|
||||||
/* _CLK_ENB_V/W_CLR_0 0x440-0x44c */
|
|
||||||
uint32_t clk_enb_v_set;
|
|
||||||
uint32_t clk_enb_v_clr;
|
|
||||||
uint32_t clk_enb_w_set;
|
|
||||||
uint32_t clk_enb_w_clr;
|
|
||||||
|
|
||||||
/* Additional (T114+) registers */
|
|
||||||
uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
|
|
||||||
uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
|
|
||||||
uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
|
|
||||||
uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45c */
|
|
||||||
uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
|
|
||||||
uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
|
|
||||||
uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
|
|
||||||
uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46c */
|
|
||||||
uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
|
|
||||||
uint32_t _0x474;
|
|
||||||
uint32_t intstatus; /* _INTSTATUS_0, 0x478 */
|
|
||||||
uint32_t intmask; /* _INTMASK_0, 0x47c */
|
|
||||||
uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
|
|
||||||
uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
|
|
||||||
uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
|
|
||||||
|
|
||||||
uint32_t plle_aux; /* _PLLE_AUX_0, 0x48c */
|
|
||||||
uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
|
|
||||||
uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
|
|
||||||
uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
|
|
||||||
|
|
||||||
uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49c */
|
|
||||||
uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4a0 */
|
|
||||||
uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4a4 */
|
|
||||||
uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4a8 */
|
|
||||||
uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4ac */
|
|
||||||
uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4b0 */
|
|
||||||
uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4b4 */
|
|
||||||
|
|
||||||
uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4b8 */
|
|
||||||
uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4bc */
|
|
||||||
uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4c0 */
|
|
||||||
uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4c4 */
|
|
||||||
uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4c8 */
|
|
||||||
uint32_t pllrefe_out; /* _PLLREFE_OUT_0, 0x4cc */
|
|
||||||
uint32_t cpu_finetrim_byp; /* _CPU_FINETRIM_BYP_0, 0x4d0 */
|
|
||||||
uint32_t cpu_finetrim_select; /* _CPU_FINETRIM_SELECT_0, 0x4d4 */
|
|
||||||
uint32_t cpu_finetrim_dr; /* _CPU_FINETRIM_DR_0, 0x4d8 */
|
|
||||||
uint32_t cpu_finetrim_df; /* _CPU_FINETRIM_DF_0, 0x4dc */
|
|
||||||
uint32_t cpu_finetrim_f; /* _CPU_FINETRIM_F_0, 0x4e0 */
|
|
||||||
uint32_t cpu_finetrim_r; /* _CPU_FINETRIM_R_0, 0x4e4 */
|
|
||||||
uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4e8 */
|
|
||||||
uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4ec */
|
|
||||||
uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4f0 */
|
|
||||||
uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4f4 */
|
|
||||||
uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4f8 */
|
|
||||||
uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4fc */
|
|
||||||
uint32_t pllc3_misc0; /* _PLLC3_MISC_0_0, 0x500 */
|
|
||||||
uint32_t pllc3_misc1; /* _PLLC3_MISC_1_0, 0x504 */
|
|
||||||
uint32_t pllc3_misc2; /* _PLLC3_MISC_2_0, 0x508 */
|
|
||||||
uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50c */
|
|
||||||
uint32_t pllx_misc1; /* _PLLX_MISC_1_0, 0x510 */
|
|
||||||
uint32_t pllx_misc2; /* _PLLX_MISC_2_0, 0x514 */
|
|
||||||
uint32_t pllx_misc3; /* _PLLX_MISC_3_0, 0x518 */
|
|
||||||
uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51c */
|
|
||||||
uint32_t xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG0_1, 0x520 */
|
|
||||||
uint32_t plle_aux1; /* _PLLE_AUX1_0, 0x524 */
|
|
||||||
uint32_t pllp_reshift; /* _PLLP_RESHIFT_0, 0x528 */
|
|
||||||
uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52c */
|
|
||||||
uint32_t pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0_0, 0x530 */
|
|
||||||
uint32_t xusb_pll_cfg0; /* _XUSB_PLL_CFG0_0, 0x534 */
|
|
||||||
uint32_t _0x538;
|
|
||||||
uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53c */
|
|
||||||
uint32_t clk_cpug_misc; /* _CLK_CPUG_MISC_0, 0x540 */
|
|
||||||
uint32_t clk_cpulp_misc; /* _CLK_CPULP_MISC_0, 0x544 */
|
|
||||||
uint32_t pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG_0, 0x548 */
|
|
||||||
uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54c */
|
|
||||||
uint32_t pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS_0, 0x550 */
|
|
||||||
uint32_t lvl2_clk_gate_ovre; /* _LVL2_CLK_GATE_OVRE, 0x554 */
|
|
||||||
uint32_t super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER_0, 0x558 */
|
|
||||||
uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55c */
|
|
||||||
uint32_t audio_sync_clk_dmic1; /* _AUDIO_SYNC_CLK_DMIC1_0, 0x560 */
|
|
||||||
uint32_t audio_sync_clk_dmic2; /* _AUDIO_SYNC_CLK_DMIC2_0, 0x564 */
|
|
||||||
|
|
||||||
uint32_t _0x568[2];
|
|
||||||
uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG, 0x570 */
|
|
||||||
uint32_t plld2_ss_ctrl1; /* _PLLD2_SS_CTRL1_0, 0x574 */
|
|
||||||
uint32_t plld2_ss_ctrl2; /* _PLLD2_SS_CTRL2_0, 0x578 */
|
|
||||||
uint32_t _0x57c[5];
|
|
||||||
|
|
||||||
uint32_t plldp_base; /* _PLLDP_BASE, 0x590*/
|
|
||||||
uint32_t plldp_misc; /* _PLLDP_MISC, 0x594 */
|
|
||||||
uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
|
|
||||||
uint32_t plldp_ss_ctrl1; /* _PLLDP_SS_CTRL1_0, 0x59c */
|
|
||||||
uint32_t plldp_ss_ctrl2; /* _PLLDP_SS_CTRL2_0, 0x5a0 */
|
|
||||||
uint32_t pllc4_base; /* _PLLC4_BASE_0, 0x5a4 */
|
|
||||||
uint32_t pllc4_misc; /* _PLLC4_MISC_0, 0x5a8 */
|
|
||||||
uint32_t _0x5ac[6];
|
|
||||||
uint32_t clk_spare0; /* _CLK_SPARE0_0, 0x5c4 */
|
|
||||||
uint32_t clk_spare1; /* _CLK_SPARE1_0, 0x5c8 */
|
|
||||||
uint32_t gpu_isob_ctrl; /* _GPU_ISOB_CTRL_0, 0x5cc */
|
|
||||||
uint32_t pllc_misc2; /* _PLLC_MISC_2_0, 0x5d0 */
|
|
||||||
uint32_t pllc_misc3; /* _PLLC_MISC_3_0, 0x5d4 */
|
|
||||||
uint32_t plla_misc2; /* _PLLA_MISC2_0, 0x5d8 */
|
|
||||||
uint32_t _0x5dc[2];
|
|
||||||
uint32_t pllc4_out; /* _PLLC4_OUT_0, 0x5e4 */
|
|
||||||
uint32_t pllmb_base; /* _PLLMB_BASE_0, 0x5e8 */
|
|
||||||
uint32_t pllmb_misc1; /* _PLLMB_MISC1_0, 0x5ec */
|
|
||||||
uint32_t pllx_misc4; /* _PLLX_MISC_4_0, 0x5f0 */
|
|
||||||
uint32_t pllx_misc5; /* _PLLX_MISC_5_0, 0x5f4 */
|
|
||||||
uint32_t _0x5f8[2];
|
|
||||||
|
|
||||||
uint32_t clk_source_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST_0, 0x600 */
|
|
||||||
uint32_t clk_source_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON_0, 0x604 */
|
|
||||||
uint32_t clk_source_xusb_fs; /* _CLK_SOURCE_XUSB_FS_0, 0x608 */
|
|
||||||
uint32_t clk_source_xusb_core_dev; /* _CLK_SOURCE_XUSB_CORE_DEV_0, 0x60c */
|
|
||||||
uint32_t clk_source_xusb_ss; /* _CLK_SOURCE_XUSB_SS_0, 0x610 */
|
|
||||||
uint32_t clk_source_cilab; /* _CLK_SOURCE_CILAB_0, 0x614 */
|
|
||||||
uint32_t clk_source_cilcd; /* _CLK_SOURCE_CILCD_0, 0x618 */
|
|
||||||
uint32_t clk_source_cilef; /* _CLK_SOURCE_CILEF_0, 0x61c */
|
|
||||||
uint32_t clk_source_dsia_lp; /* _CLK_SOURCE_DSIA_LP_0, 0x620 */
|
|
||||||
uint32_t clk_source_dsib_lp; /* _CLK_SOURCE_DSIB_LP_0, 0x624 */
|
|
||||||
uint32_t clk_source_entropy; /* _CLK_SOURCE_ENTROPY_0, 0x628 */
|
|
||||||
uint32_t clk_source_dvfs_ref; /* _CLK_SOURCE_DVFS_REF_0, 0x62c */
|
|
||||||
uint32_t clk_source_dvfs_soc; /* _CLK_SOURCE_DVFS_SOC_0, 0x630 */
|
|
||||||
uint32_t _0x634[3];
|
|
||||||
uint32_t clk_source_emc_latency; /* _CLK_SOURCE_EMC_LATENCY_0, 0x640 */
|
|
||||||
uint32_t clk_source_soc_therm; /* _CLK_SOURCE_SOC_THERM_0, 0x644 */
|
|
||||||
uint32_t _0x648;
|
|
||||||
uint32_t clk_source_dmic1; /* _CLK_SOURCE_DMIC1_0, 0x64c */
|
|
||||||
uint32_t clk_source_dmic2; /* _CLK_SOURCE_DMIC2_0, 0x650 */
|
|
||||||
uint32_t _0x654;
|
|
||||||
uint32_t clk_source_vi_sensor2; /* _CLK_SOURCE_VI_SENSOR2_0, 0x658 */
|
|
||||||
uint32_t clk_source_i2c6; /* _CLK_SOURCE_I2C6_0, 0x65c */
|
|
||||||
uint32_t clk_source_mipibif; /* _CLK_SOURCE_MIPIBIF_0, 0x660 */
|
|
||||||
uint32_t clk_source_emc_dll; /* _CLK_SOURCE_EMC_DLL_0, 0x664 */
|
|
||||||
uint32_t _0x668;
|
|
||||||
uint32_t clk_source_uart_fst_mipi_cal; /* _CLK_SOURCE_UART_FST_MIPI_CAL_0, 0x66c */
|
|
||||||
uint32_t _0x670[2];
|
|
||||||
uint32_t clk_source_vic; /* _CLK_SOURCE_VIC_0, 0x678 */
|
|
||||||
|
|
||||||
uint32_t pllp_outc; /* _PLLP_OUTC_0, 0x67c */
|
|
||||||
uint32_t pllp_misc1; /* _PLLP_MISC1_0, 0x680 */
|
|
||||||
uint32_t _0x684[2];
|
|
||||||
uint32_t emc_div_clk_shaper_ctrl; /* _EMC_DIV_CLK_SHAPER_CTRL_0, 0x68c */
|
|
||||||
uint32_t emc_pllc_shaper_ctrl; /* _EMC_PLLC_SHAPER_CTRL_0, 0x690 */
|
|
||||||
|
|
||||||
uint32_t clk_source_sdmmc_legacy_tm; /* _CLK_SOURCE_SDMMC_LEGACY_TM_0, 0x694 */
|
|
||||||
uint32_t clk_source_nvdec; /* _CLK_SOURCE_NVDEC_0, 0x698 */
|
|
||||||
uint32_t clk_source_nvjpg; /* _CLK_SOURCE_NVJPG_0, 0x69c */
|
|
||||||
uint32_t clk_source_nvenc; /* _CLK_SOURCE_NVENC_0, 0x6a0 */
|
|
||||||
|
|
||||||
uint32_t plla1_base; /* _PLLA1_BASE_0, 0x6a4 */
|
|
||||||
uint32_t plla1_misc0; /* _PLLA1_MISC_0_0, 0x6a8 */
|
|
||||||
uint32_t plla1_misc1; /* _PLLA1_MISC_1_0, 0x6ac */
|
|
||||||
uint32_t plla1_misc2; /* _PLLA1_MISC_2_0, 0x6b0 */
|
|
||||||
uint32_t plla1_misc3; /* _PLLA1_MISC_3_0, 0x6b4 */
|
|
||||||
uint32_t audio_sync_clk_dmic3; /* _AUDIO_SYNC_CLK_DMIC3_0, 0x6b8 */
|
|
||||||
|
|
||||||
uint32_t clk_source_dmic3; /* _CLK_SOURCE_DMIC3_0, 0x6bc */
|
|
||||||
uint32_t clk_source_ape; /* _CLK_SOURCE_APE_0, 0x6c0 */
|
|
||||||
uint32_t clk_source_qspi; /* _CLK_SOURCE_QSPI_0, 0x6c4 */
|
|
||||||
uint32_t clk_source_vi_i2c; /* _CLK_SOURCE_VI_I2C_0, 0x6c8 */
|
|
||||||
uint32_t clk_source_usb2_hsic_trk; /* _CLK_SOURCE_USB2_HSIC_TRK_0, 0x6cc */
|
|
||||||
uint32_t clk_source_pex_sata_usb_rx_byp; /* _CLK_SOURCE_PEX_SATA_USB_RX_BYP_0, 0x6d0 */
|
|
||||||
uint32_t clk_source_maud; /* _CLK_SOURCE_MAUD_0, 0x6d4 */
|
|
||||||
uint32_t clk_source_tsecb; /* _CLK_SOURCE_TSECB_0, 0x6d8 */
|
|
||||||
|
|
||||||
uint32_t clk_cpug_misc1; /* _CLK_CPUG_MISC1_0, 0x6dc */
|
|
||||||
uint32_t aclk_burst_policy; /* _ACLK_BURST_POLICY_0, 0x6e0 */
|
|
||||||
uint32_t super_aclk_divider; /* _SUPER_ACLK_DIVIDER_0, 0x6e4 */
|
|
||||||
|
|
||||||
uint32_t nvenc_super_clk_divider; /* _NVENC_SUPER_CLK_DIVIDER_0, 0x6e8 */
|
|
||||||
uint32_t vi_super_clk_divider; /* _VI_SUPER_CLK_DIVIDER_0, 0x6ec */
|
|
||||||
uint32_t vic_super_clk_divider; /* _VIC_SUPER_CLK_DIVIDER_0, 0x6f0 */
|
|
||||||
uint32_t nvdec_super_clk_divider; /* _NVDEC_SUPER_CLK_DIVIDER_0, 0x6f4 */
|
|
||||||
uint32_t isp_super_clk_divider; /* _ISP_SUPER_CLK_DIVIDER_0, 0x6f8 */
|
|
||||||
uint32_t ispb_super_clk_divider; /* _ISPB_SUPER_CLK_DIVIDER_0, 0x6fc */
|
|
||||||
uint32_t nvjpg_super_clk_divider; /* _NVJPG_SUPER_CLK_DIVIDER_0, 0x700 */
|
|
||||||
uint32_t se_super_clk_divider; /* _SE_SUPER_CLK_DIVIDER_0, 0x704 */
|
|
||||||
uint32_t tsec_super_clk_divider; /* _TSEC_SUPER_CLK_DIVIDER_0, 0x708 */
|
|
||||||
uint32_t tsecb_super_clk_divider; /* _TSECB_SUPER_CLK_DIVIDER_0, 0x70c */
|
|
||||||
|
|
||||||
uint32_t clk_source_uartape; /* _CLK_SOURCE_UARTAPE_0, 0x710 */
|
|
||||||
uint32_t clk_cpug_misc2; /* _CLK_CPUG_MISC2_0, 0x714 */
|
|
||||||
uint32_t clk_source_dbgapb; /* _CLK_SOURCE_DBGAPB_0, 0x718 */
|
|
||||||
uint32_t clk_ccplex_cc4_ret_clk_enb; /* _CLK_CCPLEX_CC4_RET_CLK_ENB_0, 0x71c */
|
|
||||||
uint32_t actmon_cpu_clk; /* _ACTMON_CPU_CLK_0, 0x720 */
|
|
||||||
uint32_t clk_source_emc_safe; /* _CLK_SOURCE_EMC_SAFE_0, 0x724 */
|
|
||||||
uint32_t sdmmc2_pllc4_out0_shaper_ctrl; /* _SDMMC2_PLLC4_OUT0_SHAPER_CTRL_0, 0x728 */
|
|
||||||
uint32_t sdmmc2_pllc4_out1_shaper_ctrl; /* _SDMMC2_PLLC4_OUT1_SHAPER_CTRL_0, 0x72c */
|
|
||||||
uint32_t sdmmc2_pllc4_out2_shaper_ctrl; /* _SDMMC2_PLLC4_OUT2_SHAPER_CTRL_0, 0x730 */
|
|
||||||
uint32_t sdmmc2_div_clk_shaper_ctrl; /* _SDMMC2_DIV_CLK_SHAPER_CTRL_0, 0x734 */
|
|
||||||
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
|
|
||||||
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
|
|
||||||
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
|
|
||||||
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
|
|
||||||
} tegra_car_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_car_t *car_get_regs(void) {
|
|
||||||
return (volatile tegra_car_t *)CAR_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clk_enable(CarDevice dev);
|
|
||||||
void clk_disable(CarDevice dev);
|
|
||||||
void rst_enable(CarDevice dev);
|
|
||||||
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
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "chainloader.h"
|
|
||||||
|
|
||||||
int g_chainloader_argc = 0;
|
|
||||||
char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE] = {0};
|
|
||||||
chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES] = {0}; /* keep them sorted */
|
|
||||||
size_t g_chainloader_num_entries = 0;
|
|
||||||
uintptr_t g_chainloader_entrypoint = 0;
|
|
||||||
|
|
||||||
#pragma GCC optimize (3)
|
|
||||||
|
|
||||||
static void *xmemmove(void *dst, const void *src, size_t len)
|
|
||||||
{
|
|
||||||
const uint8_t *src8 = (const uint8_t *)src;
|
|
||||||
uint8_t *dst8 = (uint8_t *)dst;
|
|
||||||
|
|
||||||
if (dst8 < src8) {
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
dst8[i] = src8[i];
|
|
||||||
}
|
|
||||||
} else if (dst8 > src8) {
|
|
||||||
for (size_t i = len; len > 0; len--)
|
|
||||||
dst8[i - 1] = src8[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relocate_and_chainload_main(void) {
|
|
||||||
for(size_t i = 0; i < g_chainloader_num_entries; i++) {
|
|
||||||
chainloader_entry_t *entry = &g_chainloader_entries[i];
|
|
||||||
xmemmove((void *)entry->load_address, (const void *)entry->src_address, entry->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
((void (*)(int, void *))g_chainloader_entrypoint)(g_chainloader_argc, g_chainloader_arg_data);
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_CHAINLOADER_H
|
|
||||||
#define FUSEE_CHAINLOADER_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define CHAINLOADER_ARG_DATA_MAX_SIZE 0x5400
|
|
||||||
#define CHAINLOADER_MAX_ENTRIES 128
|
|
||||||
|
|
||||||
typedef struct chainloader_entry_t {
|
|
||||||
uintptr_t load_address;
|
|
||||||
uintptr_t src_address;
|
|
||||||
size_t size;
|
|
||||||
size_t num;
|
|
||||||
} chainloader_entry_t;
|
|
||||||
|
|
||||||
extern int g_chainloader_argc;
|
|
||||||
extern chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES]; /* keep them sorted */
|
|
||||||
extern size_t g_chainloader_num_entries;
|
|
||||||
extern uintptr_t g_chainloader_entrypoint;
|
|
||||||
|
|
||||||
extern char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE];
|
|
||||||
|
|
||||||
void relocate_and_chainload(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,178 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "cluster.h"
|
|
||||||
#include "flow.h"
|
|
||||||
#include "sysreg.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "car.h"
|
|
||||||
#include "mc.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "max77620.h"
|
|
||||||
|
|
||||||
void _cluster_enable_power()
|
|
||||||
{
|
|
||||||
/* Reboot I2C5. */
|
|
||||||
clkrst_reboot(CARDEVICE_I2C5);
|
|
||||||
i2c_init(I2C_5);
|
|
||||||
|
|
||||||
uint8_t val = 0;
|
|
||||||
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_AME_GPIO, &val, 1);
|
|
||||||
|
|
||||||
val &= 0xDF;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_AME_GPIO, &val, 1);
|
|
||||||
val = 0x09;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_GPIO5, &val, 1);
|
|
||||||
|
|
||||||
/* Enable power. */
|
|
||||||
val = 0x20;
|
|
||||||
i2c_send(I2C_5, MAX77621_CPU_I2C_ADDR, 0x02, &val, 1);
|
|
||||||
val = 0x8D;
|
|
||||||
i2c_send(I2C_5, MAX77621_CPU_I2C_ADDR, 0x03, &val, 1);
|
|
||||||
val = 0xB7;
|
|
||||||
i2c_send(I2C_5, MAX77621_CPU_I2C_ADDR, 0x00, &val, 1);
|
|
||||||
val = 0xB7;
|
|
||||||
i2c_send(I2C_5, MAX77621_CPU_I2C_ADDR, 0x01, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _cluster_pmc_enable_partition(uint32_t part, uint32_t toggle)
|
|
||||||
{
|
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
|
||||||
|
|
||||||
/* Check if the partition has already been turned on. */
|
|
||||||
if (pmc->pwrgate_status & part)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
uint32_t i = 5001;
|
|
||||||
while (pmc->pwrgate_toggle & 0x100)
|
|
||||||
{
|
|
||||||
udelay(1);
|
|
||||||
i--;
|
|
||||||
if (i < 1)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pmc->pwrgate_toggle = (toggle | 0x100);
|
|
||||||
|
|
||||||
i = 5001;
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
if (pmc->pwrgate_status & part)
|
|
||||||
break;
|
|
||||||
|
|
||||||
udelay(1);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cluster_boot_cpu0(uint32_t entry)
|
|
||||||
{
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
|
|
||||||
/* Set ACTIVE_CLUSER to FAST. */
|
|
||||||
FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 &= 0xFFFFFFFE;
|
|
||||||
|
|
||||||
_cluster_enable_power();
|
|
||||||
|
|
||||||
if (!(car->pllx_base & 0x40000000))
|
|
||||||
{
|
|
||||||
car->pllx_misc3 &= 0xFFFFFFF7;
|
|
||||||
udelay(2);
|
|
||||||
car->pllx_base = 0x80404E02;
|
|
||||||
car->pllx_base = 0x404E02;
|
|
||||||
car->pllx_misc = ((car->pllx_misc & 0xFFFBFFFF) | 0x40000);
|
|
||||||
car->pllx_base = 0x40404E02;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!(car->pllx_base & 0x8000000)) {
|
|
||||||
/* Wait. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure MSELECT source and enable clock. */
|
|
||||||
car->clk_source_mselect = ((car->clk_source_mselect & 0x1FFFFF00) | 6);
|
|
||||||
car->clk_out_enb_v = ((car->clk_out_enb_v & 0xFFFFFFF7) | 8);
|
|
||||||
|
|
||||||
/* Configure initial CPU clock frequency and enable clock. */
|
|
||||||
car->cclk_brst_pol = 0x20008888;
|
|
||||||
car->super_cclk_div = 0x80000000;
|
|
||||||
car->clk_enb_v_set = 1;
|
|
||||||
|
|
||||||
clkrst_reboot(CARDEVICE_CORESIGHT);
|
|
||||||
|
|
||||||
/* CAR2PMC_CPU_ACK_WIDTH should be set to 0. */
|
|
||||||
car->cpu_softrst_ctrl2 &= 0xFFFFF000;
|
|
||||||
|
|
||||||
/* Enable CPU rail. */
|
|
||||||
_cluster_pmc_enable_partition(1, 0);
|
|
||||||
|
|
||||||
/* Enable cluster 0 non-CPU. */
|
|
||||||
_cluster_pmc_enable_partition(0x8000, 15);
|
|
||||||
|
|
||||||
/* Enable CE0. */
|
|
||||||
_cluster_pmc_enable_partition(0x4000, 14);
|
|
||||||
|
|
||||||
/* Request and wait for RAM repair. */
|
|
||||||
FLOW_CTLR_RAM_REPAIR_0 = 1;
|
|
||||||
while (!(FLOW_CTLR_RAM_REPAIR_0 & 2)) {
|
|
||||||
/* Wait. */
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKE_EXCP_VEC_REG(0x100) = 0;
|
|
||||||
|
|
||||||
/* Check for reset vector lock. */
|
|
||||||
if (SB_CSR_0 & 2) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set reset vector. */
|
|
||||||
SB_AA64_RESET_LOW_0 = (entry | 1);
|
|
||||||
SB_AA64_RESET_HIGH_0 = 0;
|
|
||||||
|
|
||||||
/* Non-secure reset vector write disable. */
|
|
||||||
SB_CSR_0 = 2;
|
|
||||||
(void)SB_CSR_0;
|
|
||||||
|
|
||||||
/* Validate reset vector lock + RESET_LOW/HIGH values. */
|
|
||||||
if (!(SB_CSR_0 & 2)) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Should we even bother taking as a parameter? */
|
|
||||||
if (SB_AA64_RESET_LOW_0 != (0x4003D000 | 1) || SB_AA64_RESET_HIGH_0 != 0) {
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set CPU_STRICT_TZ_APERTURE_CHECK. */
|
|
||||||
/* NOTE: [4.0.0+] This was added, but it breaks Exosphère. */
|
|
||||||
/* MAKE_MC_REG(MC_TZ_SECURITY_CTRL) = 1; */
|
|
||||||
|
|
||||||
/* Clear MSELECT reset. */
|
|
||||||
car->rst_dev_v &= 0xFFFFFFF7;
|
|
||||||
|
|
||||||
/* Clear NONCPU reset. */
|
|
||||||
car->rst_cpug_cmplx_clr = 0x20000000;
|
|
||||||
|
|
||||||
/* Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.*/
|
|
||||||
/* NOTE: [5.0.0+] This was changed so only CPU0 reset is cleared. */
|
|
||||||
/* car->rst_cpug_cmplx_clr = 0x411F000F; */
|
|
||||||
car->rst_cpug_cmplx_clr = 0x41010001;
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_CLUSTER_H_
|
|
||||||
#define FUSEE_CLUSTER_H_
|
|
||||||
|
|
||||||
void cluster_boot_cpu0(uint32_t entry);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,465 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "di.h"
|
|
||||||
#include "fuse.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "max77620.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "pinmux.h"
|
|
||||||
#include "car.h"
|
|
||||||
#include "apb_misc.h"
|
|
||||||
|
|
||||||
#include "di.inl"
|
|
||||||
|
|
||||||
static uint32_t g_lcd_vendor = 0;
|
|
||||||
|
|
||||||
/* Determine the current SoC for Mariko specific code. */
|
|
||||||
static bool is_soc_mariko() {
|
|
||||||
return (fuse_get_soc_type() == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_dsi_sleep_or_register_writes(const dsi_sleep_or_register_write_t *writes, uint32_t num_writes) {
|
|
||||||
for (uint32_t i = 0; i < num_writes; i++) {
|
|
||||||
if (writes[i].kind == 1) {
|
|
||||||
udelay(1000 * writes[i].offset);
|
|
||||||
} else {
|
|
||||||
*(volatile uint32_t *)(DSI_BASE + sizeof(uint32_t) * writes[i].offset) = writes[i].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_register_writes(uint32_t base_address, const register_write_t *writes, uint32_t num_writes) {
|
|
||||||
for (uint32_t i = 0; i < num_writes; i++) {
|
|
||||||
*(volatile uint32_t *)(base_address + writes[i].offset) = writes[i].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dsi_wait(uint32_t timeout, uint32_t offset, uint32_t mask, uint32_t delay) {
|
|
||||||
uint32_t end = get_time_us() + timeout;
|
|
||||||
while ((get_time_us() < end) && (MAKE_DSI_REG(offset) & mask)) {
|
|
||||||
/* Wait. */
|
|
||||||
}
|
|
||||||
udelay(delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display_init(void) {
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
|
||||||
bool is_mariko = is_soc_mariko();
|
|
||||||
uint32_t hardware_type = fuse_get_hardware_type();
|
|
||||||
|
|
||||||
/* Power on. */
|
|
||||||
if (is_mariko) {
|
|
||||||
uint8_t val = 0x3A;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1);
|
|
||||||
val = 0x71;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1);
|
|
||||||
val = 0xD0;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
|
|
||||||
} else {
|
|
||||||
uint8_t val = 0xD0;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
|
|
||||||
car->rst_dev_h_clr = 0x1010000;
|
|
||||||
car->clk_enb_h_set = 0x1010000;
|
|
||||||
car->rst_dev_l_clr = 0x18000000;
|
|
||||||
car->clk_enb_l_set = 0x18000000;
|
|
||||||
car->clk_enb_x_set = 0x20000;
|
|
||||||
car->clk_source_uart_fst_mipi_cal = 0xA;
|
|
||||||
car->clk_enb_w_set = 0x80000;
|
|
||||||
car->clk_source_dsia_lp = 0xA;
|
|
||||||
|
|
||||||
/* DPD idle. */
|
|
||||||
pmc->io_dpd_req = 0x40000000;
|
|
||||||
pmc->io_dpd2_req = 0x40000000;
|
|
||||||
|
|
||||||
/* Configure pins. */
|
|
||||||
pinmux->nfc_en &= ~PINMUX_TRISTATE;
|
|
||||||
pinmux->nfc_int &= ~PINMUX_TRISTATE;
|
|
||||||
pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE;
|
|
||||||
pinmux->lcd_bl_en &= ~PINMUX_TRISTATE;
|
|
||||||
pinmux->lcd_rst &= ~PINMUX_TRISTATE;
|
|
||||||
|
|
||||||
if (is_mariko && (hardware_type == 5)) {
|
|
||||||
/* HardwareType_Five only configures GPIO_LCD_BL_RST. */
|
|
||||||
gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
|
|
||||||
} else {
|
|
||||||
/* Configure Backlight +-5V GPIOs. */
|
|
||||||
gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT);
|
|
||||||
gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT);
|
|
||||||
|
|
||||||
/* Enable Backlight +5V. */
|
|
||||||
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH);
|
|
||||||
|
|
||||||
udelay(10000);
|
|
||||||
|
|
||||||
/* Enable Backlight -5V. */
|
|
||||||
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH);
|
|
||||||
|
|
||||||
udelay(10000);
|
|
||||||
|
|
||||||
/* Configure Backlight PWM, EN and RST GPIOs. */
|
|
||||||
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT);
|
|
||||||
gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT);
|
|
||||||
gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
|
|
||||||
|
|
||||||
/* Enable Backlight EN. */
|
|
||||||
gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure display interface and display. */
|
|
||||||
MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0;
|
|
||||||
if (is_mariko) {
|
|
||||||
MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0;
|
|
||||||
APB_MISC_GP_DSI_PAD_CONTROL_0 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4);
|
|
||||||
} else {
|
|
||||||
do_register_writes(CAR_BASE, display_config_plld_01_erista, 4);
|
|
||||||
}
|
|
||||||
do_register_writes(DI_BASE, display_config_dc_01, 94);
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8);
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1);
|
|
||||||
} else {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14);
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7);
|
|
||||||
} else {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10);
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
|
|
||||||
} else {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12);
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
|
|
||||||
} else {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14);
|
|
||||||
|
|
||||||
udelay(10000);
|
|
||||||
|
|
||||||
/* Enable Backlight RST. */
|
|
||||||
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH);
|
|
||||||
|
|
||||||
udelay(60000);
|
|
||||||
|
|
||||||
if (is_mariko && (hardware_type == 5)) {
|
|
||||||
MAKE_DSI_REG(DSI_BTA_TIMING) = 0x40103;
|
|
||||||
} else {
|
|
||||||
MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204;
|
|
||||||
}
|
|
||||||
MAKE_DSI_REG(DSI_WR_DATA) = 0x337;
|
|
||||||
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
|
|
||||||
dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5);
|
|
||||||
|
|
||||||
MAKE_DSI_REG(DSI_WR_DATA) = 0x406;
|
|
||||||
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
|
|
||||||
dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5);
|
|
||||||
|
|
||||||
MAKE_DSI_REG(DSI_HOST_CONTROL) = (DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC);
|
|
||||||
dsi_wait(150000, DSI_HOST_CONTROL, DSI_HOST_CONTROL_IMM_BTA, 5000);
|
|
||||||
|
|
||||||
/* Parse LCD vendor. */
|
|
||||||
uint32_t host_response[3];
|
|
||||||
for (uint32_t i = 0; i < 3; i++) {
|
|
||||||
host_response[i] = MAKE_DSI_REG(DSI_RD_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The last word from host response is:
|
|
||||||
Bits 0-7: FAB
|
|
||||||
Bits 8-15: REV
|
|
||||||
Bits 16-23: Minor REV
|
|
||||||
*/
|
|
||||||
if ((host_response[2] & 0xFF) == 0x10) {
|
|
||||||
g_lcd_vendor = 0;
|
|
||||||
} else {
|
|
||||||
g_lcd_vendor = (host_response[2] >> 8) & 0xFF00;
|
|
||||||
}
|
|
||||||
g_lcd_vendor = (g_lcd_vendor & 0xFFFFFF00) | (host_response[2] & 0xFF);
|
|
||||||
|
|
||||||
/* LCD vendor specific configuration. */
|
|
||||||
switch (g_lcd_vendor) {
|
|
||||||
case 0x10: /* Japan Display Inc screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_jdi_specific_init_01, 48);
|
|
||||||
break;
|
|
||||||
case 0xF20: /* Innolux nx-abca2 screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_innolux_nx_abca2_specific_init_01, 14);
|
|
||||||
break;
|
|
||||||
case 0xF30: /* AUO nx-abca2 screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_init_01, 14);
|
|
||||||
break;
|
|
||||||
case 0x2050: /* Unknown nx-abcd screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_50_nx_abcd_specific_init_01, 13);
|
|
||||||
break;
|
|
||||||
case 0x1020: /* Innolux nx-abcc screens. */
|
|
||||||
case 0x1030: /* AUO nx-abcc screens. */
|
|
||||||
case 0x1040: /* Unknown nx-abcc screens. */
|
|
||||||
default:
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_innolux_auo_40_nx_abcc_specific_init_01, 5);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
udelay(20000);
|
|
||||||
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3);
|
|
||||||
} else {
|
|
||||||
do_register_writes(CAR_BASE, display_config_plld_02_erista, 3);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1);
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
|
|
||||||
} else {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19);
|
|
||||||
MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10);
|
|
||||||
|
|
||||||
udelay(10000);
|
|
||||||
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2);
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2);
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
|
|
||||||
} else {
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2);
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6);
|
|
||||||
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
udelay(10000);
|
|
||||||
|
|
||||||
do_register_writes(DI_BASE, display_config_dc_02, 113);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display_end(void) {
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
|
||||||
bool is_mariko = is_soc_mariko();
|
|
||||||
|
|
||||||
/* Disable Backlight. */
|
|
||||||
display_backlight(false);
|
|
||||||
|
|
||||||
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1;
|
|
||||||
MAKE_DSI_REG(DSI_WR_DATA) = 0x2805;
|
|
||||||
|
|
||||||
/* Wait 5 frames. */
|
|
||||||
uint32_t start_val = MAKE_HOST1X_REG(0x30A4);
|
|
||||||
while (MAKE_HOST1X_REG(0x30A4) < start_val + 5) {
|
|
||||||
/* Wait. */
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKE_DI_REG(DC_CMD_STATE_ACCESS) = (READ_MUX | WRITE_MUX);
|
|
||||||
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0;
|
|
||||||
|
|
||||||
do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13);
|
|
||||||
udelay(40000);
|
|
||||||
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4);
|
|
||||||
} else {
|
|
||||||
do_register_writes(CAR_BASE, display_config_plld_01_erista, 4);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2);
|
|
||||||
if (is_mariko) {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
|
|
||||||
} else {
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
|
|
||||||
}
|
|
||||||
do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13);
|
|
||||||
|
|
||||||
if (g_lcd_vendor != 0x2050) {
|
|
||||||
udelay(10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LCD vendor specific shutdown. */
|
|
||||||
switch (g_lcd_vendor) {
|
|
||||||
case 0x10: /* Japan Display Inc screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_jdi_specific_fini_01, 22);
|
|
||||||
break;
|
|
||||||
case 0xF30: /* AUO nx-abca2 screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_fini_01, 38);
|
|
||||||
break;
|
|
||||||
case 0x1020: /* Innolux nx-abcc screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_innolux_nx_abcc_specific_fini_01, 10);
|
|
||||||
break;
|
|
||||||
case 0x1030: /* AUO nx-abcc screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_auo_nx_abcc_specific_fini_01, 10);
|
|
||||||
break;
|
|
||||||
case 0x1040: /* Unknown nx-abcc screens. */
|
|
||||||
do_dsi_sleep_or_register_writes(display_config_40_nx_abcc_specific_fini_01, 10);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKE_DSI_REG(DSI_WR_DATA) = 0x1005;
|
|
||||||
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
|
|
||||||
udelay((g_lcd_vendor == 0x2050) ? 120000 : 50000);
|
|
||||||
|
|
||||||
/* Disable Backlight RST. */
|
|
||||||
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
|
|
||||||
|
|
||||||
if (g_lcd_vendor == 0x2050) {
|
|
||||||
udelay(30000);
|
|
||||||
} else {
|
|
||||||
udelay(10000);
|
|
||||||
|
|
||||||
/* Disable Backlight -5V. */
|
|
||||||
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW);
|
|
||||||
|
|
||||||
udelay(10000);
|
|
||||||
|
|
||||||
/* Disable Backlight +5V. */
|
|
||||||
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW);
|
|
||||||
|
|
||||||
udelay(10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable clocks. */
|
|
||||||
car->rst_dev_h_set = 0x1010000;
|
|
||||||
car->clk_enb_h_clr = 0x1010000;
|
|
||||||
car->rst_dev_l_set = 0x18000000;
|
|
||||||
car->clk_enb_l_clr = 0x18000000;
|
|
||||||
|
|
||||||
MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF));
|
|
||||||
MAKE_DSI_REG(DSI_POWER_CONTROL) = 0;
|
|
||||||
|
|
||||||
if (!is_mariko) {
|
|
||||||
/* Backlight PWM. */
|
|
||||||
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO);
|
|
||||||
|
|
||||||
pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE);
|
|
||||||
pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void display_backlight(bool enable) {
|
|
||||||
if (g_lcd_vendor == 0x2050) {
|
|
||||||
int brightness = enable ? 100 : 0;
|
|
||||||
|
|
||||||
/* Enable FRAME_END_INT */
|
|
||||||
MAKE_DI_REG(DC_CMD_INT_ENABLE) = 2;
|
|
||||||
|
|
||||||
/* Configure DSI_LINE_TYPE as FOUR */
|
|
||||||
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1;
|
|
||||||
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 9;
|
|
||||||
|
|
||||||
/* Set and wait for FRAME_END_INT */
|
|
||||||
MAKE_DI_REG(DC_CMD_INT_STATUS) = 2;
|
|
||||||
while ((MAKE_DI_REG(DC_CMD_INT_STATUS) & 2) != 0) {
|
|
||||||
/* Wait */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure display brightness. */
|
|
||||||
const uint32_t brightness_val = ((0x7FF * brightness) / 100);
|
|
||||||
MAKE_DSI_REG(DSI_WR_DATA) = 0x339;
|
|
||||||
MAKE_DSI_REG(DSI_WR_DATA) = (brightness_val & 0x700) | ((brightness_val & 0xFF) << 16) | 0x51;
|
|
||||||
|
|
||||||
/* Set and wait for FRAME_END_INT */
|
|
||||||
MAKE_DI_REG(DC_CMD_INT_STATUS) = 2;
|
|
||||||
while ((MAKE_DI_REG(DC_CMD_INT_STATUS) & 2) != 0) {
|
|
||||||
/* Wait */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set client sync point block reset. */
|
|
||||||
MAKE_DSI_REG(DSI_INCR_SYNCPT_CNTRL) = 1;
|
|
||||||
udelay(300000);
|
|
||||||
|
|
||||||
/* Clear client sync point block resest. */
|
|
||||||
MAKE_DSI_REG(DSI_INCR_SYNCPT_CNTRL) = 0;
|
|
||||||
udelay(300000);
|
|
||||||
|
|
||||||
/* Clear DSI_LINE_TYPE config. */
|
|
||||||
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0;
|
|
||||||
|
|
||||||
/* Disable FRAME_END_INT */
|
|
||||||
MAKE_DI_REG(DC_CMD_INT_ENABLE) = 0;
|
|
||||||
MAKE_DI_REG(DC_CMD_INT_STATUS) = 2;
|
|
||||||
} else {
|
|
||||||
/* Enable Backlight PWM. */
|
|
||||||
gpio_write(GPIO_LCD_BL_PWM, enable ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void display_color_screen(uint32_t color) {
|
|
||||||
do_register_writes(DI_BASE, display_config_solid_color, 8);
|
|
||||||
|
|
||||||
/* Configure display to show single color. */
|
|
||||||
MAKE_DI_REG(DC_WIN_AD_WIN_OPTIONS) = 0;
|
|
||||||
MAKE_DI_REG(DC_WIN_BD_WIN_OPTIONS) = 0;
|
|
||||||
MAKE_DI_REG(DC_WIN_CD_WIN_OPTIONS) = 0;
|
|
||||||
MAKE_DI_REG(DC_DISP_BLEND_BACKGROUND_COLOR) = color;
|
|
||||||
MAKE_DI_REG(DC_CMD_STATE_CONTROL) = ((MAKE_DI_REG(DC_CMD_STATE_CONTROL) & 0xFFFFFFFE) | GENERAL_ACT_REQ);
|
|
||||||
|
|
||||||
udelay(35000);
|
|
||||||
|
|
||||||
display_backlight(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t *display_init_framebuffer(void *address) {
|
|
||||||
static register_write_t conf[sizeof(display_config_frame_buffer)/sizeof(register_write_t)] = {0};
|
|
||||||
if (conf[0].value == 0) {
|
|
||||||
for (uint32_t i = 0; i < sizeof(display_config_frame_buffer)/sizeof(register_write_t); i++) {
|
|
||||||
conf[i] = display_config_frame_buffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t *lfb_addr = (uint32_t *)address;
|
|
||||||
conf[19].value = (uint32_t)address;
|
|
||||||
|
|
||||||
/* This configures the framebuffer @ address with a resolution of 1280x720 (line stride 768). */
|
|
||||||
do_register_writes(DI_BASE, conf, 32);
|
|
||||||
|
|
||||||
udelay(35000);
|
|
||||||
|
|
||||||
return lfb_addr;
|
|
||||||
}
|
|
|
@ -1,400 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_DI_H_
|
|
||||||
#define FUSEE_DI_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define HOST1X_BASE 0x50000000
|
|
||||||
#define DI_BASE 0x54200000
|
|
||||||
#define DSI_BASE 0x54300000
|
|
||||||
#define VIC_BASE 0x54340000
|
|
||||||
#define MIPI_CAL_BASE 0x700E3000
|
|
||||||
#define MAKE_HOST1X_REG(n) MAKE_REG32(HOST1X_BASE + n)
|
|
||||||
#define MAKE_DI_REG(n) MAKE_REG32(DI_BASE + n * 4)
|
|
||||||
#define MAKE_DSI_REG(n) MAKE_REG32(DSI_BASE + n * 4)
|
|
||||||
#define MAKE_MIPI_CAL_REG(n) MAKE_REG32(MIPI_CAL_BASE + n)
|
|
||||||
#define MAKE_VIC_REG(n) MAKE_REG32(VIC_BASE + n)
|
|
||||||
|
|
||||||
/* Clock and reset registers. */
|
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DISP1 0x138
|
|
||||||
#define CLK_RST_CONTROLLER_PLLD_BASE 0xD0
|
|
||||||
#define CLK_RST_CONTROLLER_PLLD_MISC1 0xD8
|
|
||||||
#define CLK_RST_CONTROLLER_PLLD_MISC 0xDC
|
|
||||||
|
|
||||||
/* Display registers. */
|
|
||||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
|
||||||
|
|
||||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
|
||||||
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
|
|
||||||
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
|
|
||||||
|
|
||||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
|
||||||
#define SYNCPT_VSYNC_ENABLE (1 << 8)
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_COMMAND 0x32
|
|
||||||
#define DISP_CTRL_MODE_STOP (0 << 5)
|
|
||||||
#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
|
|
||||||
#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
|
|
||||||
#define DISP_CTRL_MODE_MASK (3 << 5)
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
|
|
||||||
#define PW0_ENABLE (1 << 0)
|
|
||||||
#define PW1_ENABLE (1 << 2)
|
|
||||||
#define PW2_ENABLE (1 << 4)
|
|
||||||
#define PW3_ENABLE (1 << 6)
|
|
||||||
#define PW4_ENABLE (1 << 8)
|
|
||||||
#define PM0_ENABLE (1 << 16)
|
|
||||||
#define PM1_ENABLE (1 << 18)
|
|
||||||
|
|
||||||
#define DC_CMD_INT_STATUS 0x37
|
|
||||||
#define DC_CMD_INT_MASK 0x38
|
|
||||||
#define DC_CMD_INT_ENABLE 0x39
|
|
||||||
|
|
||||||
#define DC_CMD_STATE_ACCESS 0x40
|
|
||||||
#define READ_MUX (1 << 0)
|
|
||||||
#define WRITE_MUX (1 << 2)
|
|
||||||
|
|
||||||
#define DC_CMD_STATE_CONTROL 0x41
|
|
||||||
#define GENERAL_ACT_REQ (1 << 0)
|
|
||||||
#define WIN_A_ACT_REQ (1 << 1)
|
|
||||||
#define WIN_B_ACT_REQ (1 << 2)
|
|
||||||
#define WIN_C_ACT_REQ (1 << 3)
|
|
||||||
#define CURSOR_ACT_REQ (1 << 7)
|
|
||||||
#define GENERAL_UPDATE (1 << 8)
|
|
||||||
#define WIN_A_UPDATE (1 << 9)
|
|
||||||
#define WIN_B_UPDATE (1 << 10)
|
|
||||||
#define WIN_C_UPDATE (1 << 11)
|
|
||||||
#define CURSOR_UPDATE (1 << 15)
|
|
||||||
#define NC_HOST_TRIG (1 << 24)
|
|
||||||
|
|
||||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
|
||||||
#define WINDOW_A_SELECT (1 << 4)
|
|
||||||
#define WINDOW_B_SELECT (1 << 5)
|
|
||||||
#define WINDOW_C_SELECT (1 << 6)
|
|
||||||
|
|
||||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
|
||||||
|
|
||||||
#define DC_COM_CRC_CONTROL 0x300
|
|
||||||
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
|
|
||||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
|
||||||
|
|
||||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_WIN_OPTIONS 0x402
|
|
||||||
#define HDMI_ENABLE (1 << 30)
|
|
||||||
#define DSI_ENABLE (1 << 29)
|
|
||||||
#define SOR1_TIMING_CYA (1 << 27)
|
|
||||||
#define SOR1_ENABLE (1 << 26)
|
|
||||||
#define SOR_ENABLE (1 << 25)
|
|
||||||
#define CURSOR_ENABLE (1 << 16)
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
|
||||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
|
||||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
|
||||||
#define DC_DISP_REF_TO_SYNC 0x406
|
|
||||||
#define DC_DISP_SYNC_WIDTH 0x407
|
|
||||||
#define DC_DISP_BACK_PORCH 0x408
|
|
||||||
#define DC_DISP_ACTIVE 0x409
|
|
||||||
#define DC_DISP_FRONT_PORCH 0x40A
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
|
|
||||||
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
|
|
||||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
|
|
||||||
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF2S (4 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF3S (5 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DFSPI (6 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
|
|
||||||
#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
|
|
||||||
#define DISP_ALIGNMENT_MSB (0 << 8)
|
|
||||||
#define DISP_ALIGNMENT_LSB (1 << 8)
|
|
||||||
#define DISP_ORDER_RED_BLUE (0 << 9)
|
|
||||||
#define DISP_ORDER_BLUE_RED (1 << 9)
|
|
||||||
|
|
||||||
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
|
||||||
#define DITHER_CONTROL_MASK (3 << 8)
|
|
||||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
|
||||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
|
||||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
|
||||||
#define BASE_COLOR_SIZE_MASK (0xf << 0)
|
|
||||||
#define BASE_COLOR_SIZE_666 (0 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_111 (1 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_222 (2 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_333 (3 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_444 (4 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_555 (5 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_565 (6 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_332 (7 << 0)
|
|
||||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
|
||||||
|
|
||||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
|
||||||
#define SC1_H_QUALIFIER_NONE (1 << 16)
|
|
||||||
#define SC0_H_QUALIFIER_NONE (1 << 0)
|
|
||||||
|
|
||||||
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
|
|
||||||
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
|
|
||||||
#define DE_SELECT_ACTIVE (1 << 0)
|
|
||||||
#define DE_SELECT_ACTIVE_IS (2 << 0)
|
|
||||||
#define DE_CONTROL_ONECLK (0 << 2)
|
|
||||||
#define DE_CONTROL_NORMAL (1 << 2)
|
|
||||||
#define DE_CONTROL_EARLY_EXT (2 << 2)
|
|
||||||
#define DE_CONTROL_EARLY (3 << 2)
|
|
||||||
#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
|
|
||||||
|
|
||||||
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
|
|
||||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
|
||||||
|
|
||||||
#define DC_WIN_CSC_YOF 0x611
|
|
||||||
#define DC_WIN_CSC_KYRGB 0x612
|
|
||||||
#define DC_WIN_CSC_KUR 0x613
|
|
||||||
#define DC_WIN_CSC_KVR 0x614
|
|
||||||
#define DC_WIN_CSC_KUG 0x615
|
|
||||||
#define DC_WIN_CSC_KVG 0x616
|
|
||||||
#define DC_WIN_CSC_KUB 0x617
|
|
||||||
#define DC_WIN_CSC_KVB 0x618
|
|
||||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
|
||||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
|
||||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
|
||||||
|
|
||||||
/* The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER). */
|
|
||||||
#define DC_WIN_WIN_OPTIONS 0x700
|
|
||||||
#define H_DIRECTION (1 << 0)
|
|
||||||
#define V_DIRECTION (1 << 2)
|
|
||||||
#define COLOR_EXPAND (1 << 6)
|
|
||||||
#define CSC_ENABLE (1 << 18)
|
|
||||||
#define WIN_ENABLE (1 << 30)
|
|
||||||
|
|
||||||
#define DC_WIN_COLOR_DEPTH 0x703
|
|
||||||
#define WIN_COLOR_DEPTH_P1 0x0
|
|
||||||
#define WIN_COLOR_DEPTH_P2 0x1
|
|
||||||
#define WIN_COLOR_DEPTH_P4 0x2
|
|
||||||
#define WIN_COLOR_DEPTH_P8 0x3
|
|
||||||
#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
|
|
||||||
#define WIN_COLOR_DEPTH_B5G5R5A 0x5
|
|
||||||
#define WIN_COLOR_DEPTH_B5G6R5 0x6
|
|
||||||
#define WIN_COLOR_DEPTH_AB5G5R5 0x7
|
|
||||||
#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
|
|
||||||
#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
|
|
||||||
#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
|
|
||||||
#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422 0x10
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422 0x11
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr420P 0x12
|
|
||||||
#define WIN_COLOR_DEPTH_YUV420P 0x13
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422P 0x14
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422P 0x15
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422R 0x16
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
|
||||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
|
||||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
|
||||||
|
|
||||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
|
||||||
#define DC_WIN_POSITION 0x704
|
|
||||||
|
|
||||||
#define DC_WIN_SIZE 0x705
|
|
||||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
|
||||||
#define V_SIZE(x) (((x) & 0x1fff) << 16)
|
|
||||||
|
|
||||||
#define DC_WIN_PRESCALED_SIZE 0x706
|
|
||||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
|
|
||||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
|
|
||||||
|
|
||||||
#define DC_WIN_H_INITIAL_DDA 0x707
|
|
||||||
#define DC_WIN_V_INITIAL_DDA 0x708
|
|
||||||
|
|
||||||
#define DC_WIN_DDA_INC 0x709
|
|
||||||
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
|
|
||||||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
|
||||||
|
|
||||||
#define DC_WIN_LINE_STRIDE 0x70A
|
|
||||||
#define DC_WIN_DV_CONTROL 0x70E
|
|
||||||
#define DC_WINBUF_BLEND_LAYER_CONTROL 0x716
|
|
||||||
|
|
||||||
/* The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
|
|
||||||
#define DC_WINBUF_START_ADDR 0x800
|
|
||||||
#define DC_WINBUF_ADDR_H_OFFSET 0x806
|
|
||||||
#define DC_WINBUF_ADDR_V_OFFSET 0x808
|
|
||||||
#define DC_WINBUF_SURFACE_KIND 0x80B
|
|
||||||
|
|
||||||
/* Display serial interface registers. */
|
|
||||||
#define DSI_INCR_SYNCPT_CNTRL 0x1
|
|
||||||
|
|
||||||
#define DSI_RD_DATA 0x9
|
|
||||||
#define DSI_WR_DATA 0xA
|
|
||||||
|
|
||||||
#define DSI_POWER_CONTROL 0xB
|
|
||||||
#define DSI_POWER_CONTROL_ENABLE 1
|
|
||||||
|
|
||||||
#define DSI_INT_ENABLE 0xC
|
|
||||||
#define DSI_INT_STATUS 0xD
|
|
||||||
#define DSI_INT_MASK 0xE
|
|
||||||
|
|
||||||
#define DSI_HOST_CONTROL 0xF
|
|
||||||
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
|
|
||||||
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
|
|
||||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
|
||||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
|
||||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
|
||||||
#define DSI_HOST_CONTROL_RAW (1 << 6)
|
|
||||||
#define DSI_HOST_CONTROL_HS (1 << 5)
|
|
||||||
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
|
|
||||||
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
|
|
||||||
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
|
|
||||||
#define DSI_HOST_CONTROL_CS (1 << 1)
|
|
||||||
#define DSI_HOST_CONTROL_ECC (1 << 0)
|
|
||||||
|
|
||||||
#define DSI_CONTROL 0x10
|
|
||||||
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
|
|
||||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
|
||||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
|
||||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
|
||||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
|
||||||
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
|
|
||||||
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
|
|
||||||
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
|
|
||||||
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
|
|
||||||
|
|
||||||
#define DSI_SOL_DELAY 0x11
|
|
||||||
#define DSI_MAX_THRESHOLD 0x12
|
|
||||||
|
|
||||||
#define DSI_TRIGGER 0x13
|
|
||||||
#define DSI_TRIGGER_HOST (1 << 1)
|
|
||||||
#define DSI_TRIGGER_VIDEO (1 << 0)
|
|
||||||
|
|
||||||
#define DSI_TX_CRC 0x14
|
|
||||||
#define DSI_STATUS 0x15
|
|
||||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
|
||||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
|
||||||
#define DSI_INIT_SEQ_DATA_1 0x1C
|
|
||||||
#define DSI_INIT_SEQ_DATA_2 0x1D
|
|
||||||
#define DSI_INIT_SEQ_DATA_3 0x1E
|
|
||||||
#define DSI_PKT_SEQ_0_LO 0x23
|
|
||||||
#define DSI_PKT_SEQ_0_HI 0x24
|
|
||||||
#define DSI_PKT_SEQ_1_LO 0x25
|
|
||||||
#define DSI_PKT_SEQ_1_HI 0x26
|
|
||||||
#define DSI_PKT_SEQ_2_LO 0x27
|
|
||||||
#define DSI_PKT_SEQ_2_HI 0x28
|
|
||||||
#define DSI_PKT_SEQ_3_LO 0x29
|
|
||||||
#define DSI_PKT_SEQ_3_HI 0x2A
|
|
||||||
#define DSI_PKT_SEQ_4_LO 0x2B
|
|
||||||
#define DSI_PKT_SEQ_4_HI 0x2C
|
|
||||||
#define DSI_PKT_SEQ_5_LO 0x2D
|
|
||||||
#define DSI_PKT_SEQ_5_HI 0x2E
|
|
||||||
#define DSI_DCS_CMDS 0x33
|
|
||||||
#define DSI_PKT_LEN_0_1 0x34
|
|
||||||
#define DSI_PKT_LEN_2_3 0x35
|
|
||||||
#define DSI_PKT_LEN_4_5 0x36
|
|
||||||
#define DSI_PKT_LEN_6_7 0x37
|
|
||||||
#define DSI_PHY_TIMING_0 0x3C
|
|
||||||
#define DSI_PHY_TIMING_1 0x3D
|
|
||||||
#define DSI_PHY_TIMING_2 0x3E
|
|
||||||
#define DSI_BTA_TIMING 0x3F
|
|
||||||
|
|
||||||
#define DSI_TIMEOUT_0 0x44
|
|
||||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
|
||||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
|
||||||
|
|
||||||
#define DSI_TIMEOUT_1 0x45
|
|
||||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
|
||||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
|
||||||
|
|
||||||
#define DSI_TO_TALLY 0x46
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_0 0x4B
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
|
|
||||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_CD 0x4C
|
|
||||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_1 0x4F
|
|
||||||
#define DSI_PAD_CONTROL_2 0x50
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_3 0x51
|
|
||||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
|
||||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
|
||||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
|
||||||
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
|
|
||||||
|
|
||||||
#define DSI_PAD_CONTROL_4 0x52
|
|
||||||
#define DSI_PAD_CONTROL_5_MARIKO 0x53
|
|
||||||
#define DSI_PAD_CONTROL_6_MARIKO 0x54
|
|
||||||
#define DSI_PAD_CONTROL_7_MARIKO 0x55
|
|
||||||
#define DSI_INIT_SEQ_DATA_15 0x5F
|
|
||||||
#define DSI_INIT_SEQ_DATA_15_MARIKO 0x62
|
|
||||||
|
|
||||||
/* MIPI calibration registers. */
|
|
||||||
#define MIPI_CAL_MIPI_CAL_CTRL 0x0
|
|
||||||
#define MIPI_CAL_MIPI_CAL_AUTOCAL_CTRL0 0x4
|
|
||||||
#define MIPI_CAL_CIL_MIPI_CAL_STATUS 0x8
|
|
||||||
#define MIPI_CAL_CIL_MIPI_CAL_STATUS_2 0xC
|
|
||||||
#define MIPI_CAL_CILA_MIPI_CAL_CONFIG 0x14
|
|
||||||
#define MIPI_CAL_CILB_MIPI_CAL_CONFIG 0x18
|
|
||||||
#define MIPI_CAL_CILC_MIPI_CAL_CONFIG 0x1C
|
|
||||||
#define MIPI_CAL_CILD_MIPI_CAL_CONFIG 0x20
|
|
||||||
#define MIPI_CAL_CILE_MIPI_CAL_CONFIG 0x24
|
|
||||||
#define MIPI_CAL_CILF_MIPI_CAL_CONFIG 0x28
|
|
||||||
#define MIPI_CAL_DSIA_MIPI_CAL_CONFIG 0x38
|
|
||||||
#define MIPI_CAL_DSIB_MIPI_CAL_CONFIG 0x3C
|
|
||||||
#define MIPI_CAL_DSIC_MIPI_CAL_CONFIG 0x40
|
|
||||||
#define MIPI_CAL_DSID_MIPI_CAL_CONFIG 0x44
|
|
||||||
#define MIPI_CAL_MIPI_BIAS_PAD_CFG0 0x58
|
|
||||||
#define MIPI_CAL_MIPI_BIAS_PAD_CFG1 0x5C
|
|
||||||
#define MIPI_CAL_MIPI_BIAS_PAD_CFG2 0x60
|
|
||||||
#define MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2 0x64
|
|
||||||
#define MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2 0x68
|
|
||||||
#define MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2 0x70
|
|
||||||
#define MIPI_CAL_DSID_MIPI_CAL_CONFIG_2 0x74
|
|
||||||
|
|
||||||
void display_init(void);
|
|
||||||
void display_end(void);
|
|
||||||
|
|
||||||
/* Switches screen backlight ON/OFF. */
|
|
||||||
void display_backlight(bool enable);
|
|
||||||
|
|
||||||
/* Show one single color on the display. */
|
|
||||||
void display_color_screen(uint32_t color);
|
|
||||||
|
|
||||||
/* Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
|
||||||
uint32_t *display_init_framebuffer(void *address);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,773 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t value;
|
|
||||||
} register_write_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t kind;
|
|
||||||
uint16_t offset;
|
|
||||||
uint32_t value;
|
|
||||||
} dsi_sleep_or_register_write_t;
|
|
||||||
|
|
||||||
static const uint32_t display_config_frame_buffer_address = 0xC0000000;
|
|
||||||
|
|
||||||
static const register_write_t display_config_plld_01_erista[4] = {
|
|
||||||
{CLK_RST_CONTROLLER_CLK_SOURCE_DISP1, 0x40000000},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4830A001},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000020},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002D0AAA},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_plld_01_mariko[4] = {
|
|
||||||
{CLK_RST_CONTROLLER_CLK_SOURCE_DISP1, 0x40000000},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4830A001},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000000},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002DFC00},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dc_01[94] = {
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_REG_ACT_CONTROL, 0x54},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_DV_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_YOF, 0xF0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KYRGB, 0x12A},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVR, 0x198},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUG, 0x39B},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVG, 0x32F},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUB, 0x204},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVB, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_DV_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_YOF, 0xF0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KYRGB, 0x12A},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVR, 0x198},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUG, 0x39B},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVG, 0x32F},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUB, 0x204},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVB, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_DV_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_YOF, 0xF0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KYRGB, 0x12A},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVR, 0x198},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUG, 0x39B},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVG, 0x32F},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUB, 0x204},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVB, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
|
||||||
{sizeof(uint32_t) * DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
|
||||||
{sizeof(uint32_t) * DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_COM_CRC_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_01[8] = {
|
|
||||||
{sizeof(uint32_t) * DSI_WR_DATA, 0x0},
|
|
||||||
{sizeof(uint32_t) * DSI_INT_ENABLE, 0x0},
|
|
||||||
{sizeof(uint32_t) * DSI_INT_STATUS, 0x0},
|
|
||||||
{sizeof(uint32_t) * DSI_INT_MASK, 0x0},
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_DATA_0, 0x0},
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_DATA_1, 0x0},
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_DATA_2, 0x0},
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_DATA_3, 0x0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_02_erista[1] = {
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_DATA_15, 0x0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_02_mariko[1] = {
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_DATA_15_MARIKO, 0x0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_03[14] = {
|
|
||||||
{sizeof(uint32_t) * DSI_DCS_CMDS, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_0_LO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_1_LO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_2_LO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_3_LO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_4_LO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_5_LO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_0_HI, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_1_HI, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_2_HI, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_3_HI, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_4_HI, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_5_HI, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_CONTROL, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_04_erista[0] = {
|
|
||||||
/* No register writes. */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_04_mariko[7] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_1, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_2, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_3, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_4, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_5_MARIKO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_6_MARIKO, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_7_MARIKO, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_05[10] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_CD, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_SOL_DELAY, 0x18},
|
|
||||||
{sizeof(uint32_t) * DSI_MAX_THRESHOLD, 0x1E0},
|
|
||||||
{sizeof(uint32_t) * DSI_TRIGGER, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_0_1, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_2_3, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_4_5, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_6_7, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_1, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_06[12] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_1, 0x40A0E05},
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_2, 0x30109},
|
|
||||||
{sizeof(uint32_t) * DSI_BTA_TIMING, 0x190A14},
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
|
||||||
{sizeof(uint32_t) * DSI_TO_TALLY, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_1, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_07[14] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_1, 0x40A0E05},
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_2, 0x30118},
|
|
||||||
{sizeof(uint32_t) * DSI_BTA_TIMING, 0x190A14},
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
|
||||||
{sizeof(uint32_t) * DSI_TO_TALLY, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
|
||||||
{sizeof(uint32_t) * DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_MAX_THRESHOLD, 0x40},
|
|
||||||
{sizeof(uint32_t) * DSI_TRIGGER, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_TX_CRC, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_CONTROL, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_phy_timing_erista[1] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_0, 0x6070601},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_phy_timing_mariko[1] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_0, 0x6070603},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_jdi_specific_init_01[48] = {
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0xBD15},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x1939},
|
|
||||||
{0, DSI_WR_DATA, 0xAAAAAAD8},
|
|
||||||
{0, DSI_WR_DATA, 0xAAAAAAEB},
|
|
||||||
{0, DSI_WR_DATA, 0xAAEBAAAA},
|
|
||||||
{0, DSI_WR_DATA, 0xAAAAAAAA},
|
|
||||||
{0, DSI_WR_DATA, 0xAAAAAAEB},
|
|
||||||
{0, DSI_WR_DATA, 0xAAEBAAAA},
|
|
||||||
{0, DSI_WR_DATA, 0xAA},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x1BD15},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x2739},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFD8},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFF},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x2BD15},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0xF39},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFD8},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFFFF},
|
|
||||||
{0, DSI_WR_DATA, 0xFFFFFF},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0xBD15},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x6D915},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0xB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x1105},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0xB4, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x2905},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_innolux_nx_abca2_specific_init_01[14] = {
|
|
||||||
{0, DSI_WR_DATA, 0x1105},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0xB4, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x739},
|
|
||||||
{0, DSI_WR_DATA, 0x751548B1},
|
|
||||||
{0, DSI_WR_DATA, 0x143209},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x2905},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_auo_nx_abca2_specific_init_01[14] = {
|
|
||||||
{0, DSI_WR_DATA, 0x1105},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0xB4, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x739},
|
|
||||||
{0, DSI_WR_DATA, 0x711148B1},
|
|
||||||
{0, DSI_WR_DATA, 0x143209},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x2905},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_innolux_auo_40_nx_abcc_specific_init_01[5] = {
|
|
||||||
{0, DSI_WR_DATA, 0x1105},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x78, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x2905},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_50_nx_abcd_specific_init_01[13] = {
|
|
||||||
{0, DSI_WR_DATA, 0x1105},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0xB4, 0},
|
|
||||||
{0, DSI_WR_DATA, 0xA015},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x205315},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x339},
|
|
||||||
{0, DSI_WR_DATA, 0xFF0751},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0x2905},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_plld_02_erista[3] = {
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4810c001},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000020},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002D0AAA},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_plld_02_mariko[3] = {
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4810c001},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000000},
|
|
||||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002DFC00},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_08[1] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_1, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_09[19] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_1, 0x40A0E05},
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_2, 0x30172},
|
|
||||||
{sizeof(uint32_t) * DSI_BTA_TIMING, 0x190A14},
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
|
||||||
{sizeof(uint32_t) * DSI_TO_TALLY, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_0_LO, 0x40000208},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_2_LO, 0x40000308},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_4_LO, 0x40000308},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_1_LO, 0x40000308},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_3_LO, 0x3F3B2B08},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_3_HI, 0x2CC},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_SEQ_5_HI, 0x2CC},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_0_1, 0xCE0000},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_2_3, 0x87001A2},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_4_5, 0x190},
|
|
||||||
{sizeof(uint32_t) * DSI_PKT_LEN_6_7, 0x190},
|
|
||||||
{sizeof(uint32_t) * DSI_HOST_CONTROL, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_10[10] = {
|
|
||||||
{sizeof(uint32_t) * DSI_TRIGGER, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_SOL_DELAY, 6},
|
|
||||||
{sizeof(uint32_t) * DSI_MAX_THRESHOLD, 0x1E0},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
|
||||||
{sizeof(uint32_t) * DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
|
||||||
{sizeof(uint32_t) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_11_erista[4] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_1, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_2, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_4, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_init_11_mariko[7] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_1, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_2, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_3, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_4, 0x77777},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_5_MARIKO, 0x77777},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_6_MARIKO, DSI_PAD_PREEMP_PD_CLK(0x1) | DSI_PAD_PREEMP_PU_CLK(0x1) | DSI_PAD_PREEMP_PD(0x01) | DSI_PAD_PREEMP_PU(0x1)},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_7_MARIKO, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_mipi_cal_01[4] = {
|
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
|
||||||
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 1},
|
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_mipi_cal_02_erista[2] = {
|
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0x10010},
|
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG1, 0x300},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_mipi_cal_02_mariko[2] = {
|
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0x10010},
|
|
||||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG1, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_mipi_cal_03_erista[6] = {
|
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002},
|
|
||||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_mipi_cal_03_mariko[6] = {
|
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
|
||||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000},
|
|
||||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_mipi_cal_04[10] = {
|
|
||||||
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_CILD_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_CILE_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_CILF_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG, 0},
|
|
||||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
|
|
||||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
|
|
||||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0},
|
|
||||||
{MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dc_02[113] = {
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_DV_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_YOF, 0xF0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KYRGB, 0x12A},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVR, 0x198},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUG, 0x39B},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVG, 0x32F},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUB, 0x204},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVB, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_DV_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_YOF, 0xF0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KYRGB, 0x12A},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVR, 0x198},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUG, 0x39B},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVG, 0x32F},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUB, 0x204},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVB, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_DV_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_YOF, 0xF0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KYRGB, 0x12A},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVR, 0x198},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUG, 0x39B},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVG, 0x32F},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KUB, 0x204},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_CSC_KVB, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
|
||||||
{sizeof(uint32_t) * DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
|
||||||
{sizeof(uint32_t) * DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
|
||||||
{sizeof(uint32_t) * DC_COM_CRC_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_TIMING_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_REF_TO_SYNC, (1 << 16)},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_SYNC_WIDTH, 0x10048},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_BACK_PORCH, 0x90048},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_ACTIVE, 0x50002D0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_FRONT_PORCH, 0xA0088},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
|
||||||
{sizeof(uint32_t) * DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_CLOCK_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_FRONT_PORCH, 0xA0088},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_frame_buffer[32] = {
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_POSITION, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_H_INITIAL_DDA, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_V_INITIAL_DDA, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_LINE_STRIDE, 0x6000C00},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_BUFFER_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_SURFACE_KIND, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_START_ADDR, display_config_frame_buffer_address},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_ADDR_H_OFFSET, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WINBUF_ADDR_V_OFFSET, 0},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, WIN_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_solid_color[8] = {
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
|
||||||
{sizeof(uint32_t) * DC_WIN_WIN_OPTIONS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dc_01_fini_01[13] = {
|
|
||||||
{sizeof(uint32_t) * DC_DISP_FRONT_PORCH, 0xA0088},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_INT_MASK, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_ACCESS, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_INT_ENABLE, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_CONT_SYNCPT_VSYNC, 0},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
|
||||||
{sizeof(uint32_t) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_fini_01[2] = {
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_PAD_CONTROL_1, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const register_write_t display_config_dsi_01_fini_02[13] = {
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_1, 0x40A0E05},
|
|
||||||
{sizeof(uint32_t) * DSI_PHY_TIMING_2, 0x30109},
|
|
||||||
{sizeof(uint32_t) * DSI_BTA_TIMING, 0x190A14},
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
|
|
||||||
{sizeof(uint32_t) * DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
|
||||||
{sizeof(uint32_t) * DSI_TO_TALLY, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
|
||||||
{sizeof(uint32_t) * DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
|
||||||
{sizeof(uint32_t) * DSI_MAX_THRESHOLD, 0x40},
|
|
||||||
{sizeof(uint32_t) * DSI_TRIGGER, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_TX_CRC, 0},
|
|
||||||
{sizeof(uint32_t) * DSI_INIT_SEQ_CONTROL, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_jdi_specific_fini_01[22] = {
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x2139},
|
|
||||||
{0, DSI_WR_DATA, 0x191919D5},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0xB39},
|
|
||||||
{0, DSI_WR_DATA, 0x4F0F41B1},
|
|
||||||
{0, DSI_WR_DATA, 0xF179A433},
|
|
||||||
{0, DSI_WR_DATA, 0x2D81},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0xB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_auo_nx_abca2_specific_fini_01[38] = {
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x2C39},
|
|
||||||
{0, DSI_WR_DATA, 0x191919D5},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x2C39},
|
|
||||||
{0, DSI_WR_DATA, 0x191919D6},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_WR_DATA, 0x19191919},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0xB39},
|
|
||||||
{0, DSI_WR_DATA, 0x711148B1},
|
|
||||||
{0, DSI_WR_DATA, 0x71143209},
|
|
||||||
{0, DSI_WR_DATA, 0x114D31},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0xB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_innolux_nx_abcc_specific_fini_01[10] = {
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0xB39},
|
|
||||||
{0, DSI_WR_DATA, 0x751548B1},
|
|
||||||
{0, DSI_WR_DATA, 0x71143209},
|
|
||||||
{0, DSI_WR_DATA, 0x115631},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_auo_nx_abcc_specific_fini_01[10] = {
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0xB39},
|
|
||||||
{0, DSI_WR_DATA, 0x711148B1},
|
|
||||||
{0, DSI_WR_DATA, 0x71143209},
|
|
||||||
{0, DSI_WR_DATA, 0x114D31},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dsi_sleep_or_register_write_t display_config_40_nx_abcc_specific_fini_01[10] = {
|
|
||||||
{0, DSI_WR_DATA, 0x439},
|
|
||||||
{0, DSI_WR_DATA, 0x9483FFB9},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
{0, DSI_WR_DATA, 0xB39},
|
|
||||||
{0, DSI_WR_DATA, 0x731348B1},
|
|
||||||
{0, DSI_WR_DATA, 0x71243209},
|
|
||||||
{0, DSI_WR_DATA, 0x4C31},
|
|
||||||
{0, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
|
||||||
{1, 0x5, 0},
|
|
||||||
};
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "exception_handlers.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "../../../fusee/common/log.h"
|
|
||||||
#include "../../../fusee/common/vsprintf.h"
|
|
||||||
|
|
||||||
#define CODE_DUMP_SIZE 0x30
|
|
||||||
#define STACK_DUMP_SIZE 0x30
|
|
||||||
|
|
||||||
extern const uint32_t exception_handler_table[];
|
|
||||||
|
|
||||||
static const char *exception_names[] = {
|
|
||||||
"Reset", "Undefined instruction", "SWI", "Prefetch abort", "Data abort", "Reserved", "IRQ", "FIQ",
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *register_names[] = {
|
|
||||||
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12",
|
|
||||||
"SP", "LR", "PC", "CPSR",
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Adapted from https://gist.github.com/ccbrown/9722406 */
|
|
||||||
static void hexdump(const void* data, size_t size, uintptr_t addrbase, char* strbuf) {
|
|
||||||
const uint8_t *d = (const uint8_t *)data;
|
|
||||||
char ascii[17] = {0};
|
|
||||||
ascii[16] = '\0';
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
if (i % 16 == 0) {
|
|
||||||
strbuf += sprintf(strbuf, "%0*" PRIXPTR ": | ", 2 * sizeof(addrbase), addrbase + i);
|
|
||||||
}
|
|
||||||
strbuf += sprintf(strbuf, "%02X ", d[i]);
|
|
||||||
if (d[i] >= ' ' && d[i] <= '~') {
|
|
||||||
ascii[i % 16] = d[i];
|
|
||||||
} else {
|
|
||||||
ascii[i % 16] = '.';
|
|
||||||
}
|
|
||||||
if ((i+1) % 8 == 0 || i+1 == size) {
|
|
||||||
strbuf += sprintf(strbuf, " ");
|
|
||||||
if ((i+1) % 16 == 0) {
|
|
||||||
strbuf += sprintf(strbuf, "| %s \n", ascii);
|
|
||||||
} else if (i+1 == size) {
|
|
||||||
ascii[(i+1) % 16] = '\0';
|
|
||||||
if ((i+1) % 16 <= 8) {
|
|
||||||
strbuf += sprintf(strbuf, " ");
|
|
||||||
}
|
|
||||||
for (size_t j = (i+1) % 16; j < 16; j++) {
|
|
||||||
strbuf += sprintf(strbuf, " ");
|
|
||||||
}
|
|
||||||
strbuf += sprintf(strbuf, "| %s \n", ascii);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_exception_handlers(void) {
|
|
||||||
volatile uint32_t *bpmp_exception_handler_table = (volatile uint32_t *)0x6000F200;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
if (exception_handler_table[i] != 0) {
|
|
||||||
bpmp_exception_handler_table[i] = exception_handler_table[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void exception_handler_main(uint32_t *registers, unsigned int exception_type) {
|
|
||||||
char exception_log[0x400] = {0};
|
|
||||||
uint8_t code_dump[CODE_DUMP_SIZE] = {0};
|
|
||||||
uint8_t stack_dump[STACK_DUMP_SIZE] = {0};
|
|
||||||
size_t code_dump_size = 0;
|
|
||||||
size_t stack_dump_size = 0;
|
|
||||||
|
|
||||||
uint32_t pc = registers[15];
|
|
||||||
uint32_t cpsr = registers[16];
|
|
||||||
uint32_t instr_addr = pc + ((cpsr & 0x20) ? 2 : 4) - CODE_DUMP_SIZE;
|
|
||||||
|
|
||||||
sprintf(exception_log, "An exception occurred!\n");
|
|
||||||
|
|
||||||
code_dump_size = safecpy(code_dump, (const void *)instr_addr, CODE_DUMP_SIZE);
|
|
||||||
stack_dump_size = safecpy(stack_dump, (const void *)registers[13], STACK_DUMP_SIZE);
|
|
||||||
|
|
||||||
sprintf(exception_log + strlen(exception_log), "\nException type: %s\n", exception_names[exception_type]);
|
|
||||||
sprintf(exception_log + strlen(exception_log), "\nRegisters:\n");
|
|
||||||
|
|
||||||
/* Print r0 to pc. */
|
|
||||||
for (int i = 0; i < 16; i += 2) {
|
|
||||||
sprintf(exception_log + strlen(exception_log), "%-7s%08"PRIX32" %-7s%08"PRIX32"\n",
|
|
||||||
register_names[i], registers[i], register_names[i+1], registers[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print cpsr. */
|
|
||||||
sprintf(exception_log + strlen(exception_log), "%-7s%08"PRIX32"\n", register_names[16], registers[16]);
|
|
||||||
|
|
||||||
/* Print code and stack regions. */
|
|
||||||
sprintf(exception_log + strlen(exception_log), "\nCode dump:\n");
|
|
||||||
hexdump(code_dump, code_dump_size, instr_addr, exception_log + strlen(exception_log));
|
|
||||||
sprintf(exception_log + strlen(exception_log), "\nStack dump:\n");
|
|
||||||
hexdump(stack_dump, stack_dump_size, registers[13], exception_log + strlen(exception_log));
|
|
||||||
sprintf(exception_log + strlen(exception_log), "\n");
|
|
||||||
|
|
||||||
/* Throw fatal error with the full exception log. */
|
|
||||||
fatal_error(exception_log);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_EXCEPTION_HANDLERS_H
|
|
||||||
#define FUSEE_EXCEPTION_HANDLERS_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
/* Copies up to len bytes, stops and returns the read length on data fault. */
|
|
||||||
size_t safecpy(void *dst, const void *src, size_t len);
|
|
||||||
|
|
||||||
void setup_exception_handlers(void);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,125 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.macro GEN_USUAL_HANDLER name, index, lr_arm_displ, lr_thumb_displ
|
|
||||||
_exception_handler_\name:
|
|
||||||
ldr sp, =_regs
|
|
||||||
stmia sp!, {r0-r7}
|
|
||||||
|
|
||||||
/* Adjust lr to make it point to the location where the exception occured. */
|
|
||||||
mrs r1, spsr
|
|
||||||
tst r1, #0x20
|
|
||||||
subeq lr, lr, #\lr_arm_displ
|
|
||||||
subne lr, lr, #\lr_thumb_displ
|
|
||||||
|
|
||||||
mov r0, sp
|
|
||||||
mov r1, #\index
|
|
||||||
b _exception_handler_common
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.section .text.exception_handlers_asm, "ax", %progbits
|
|
||||||
.arm
|
|
||||||
.align 5
|
|
||||||
|
|
||||||
_exception_handler_common:
|
|
||||||
mrs r2, spsr
|
|
||||||
mrs r3, cpsr
|
|
||||||
|
|
||||||
/* Mask interrupts. */
|
|
||||||
orr r3, #0xC0
|
|
||||||
msr cpsr_cx, r3
|
|
||||||
|
|
||||||
/* Switch to the mode that triggered the interrupt, get the remaining regs, switch back. */
|
|
||||||
ands r4, r2, #0xF
|
|
||||||
moveq r4, #0xF /* usr => sys */
|
|
||||||
bic r5, r3, #0xF
|
|
||||||
orr r5, r4
|
|
||||||
msr cpsr_c, r5
|
|
||||||
stmia r0!, {r8-lr}
|
|
||||||
msr cpsr_c, r3
|
|
||||||
|
|
||||||
str lr, [r0], #4
|
|
||||||
str r2, [r0]
|
|
||||||
|
|
||||||
/* Finally, switch to system mode, setting interrupts and clearing the flags; set sp as well. */
|
|
||||||
msr cpsr_cxsf, #0xDF
|
|
||||||
ldr sp, =(_exception_handler_stack + 0x1000)
|
|
||||||
ldr r0, =_regs
|
|
||||||
bl exception_handler_main
|
|
||||||
b .
|
|
||||||
|
|
||||||
GEN_USUAL_HANDLER undefined_instruction, 1, 4, 2
|
|
||||||
GEN_USUAL_HANDLER swi, 2, 4, 2
|
|
||||||
GEN_USUAL_HANDLER prefetch_abort, 3, 4, 4
|
|
||||||
GEN_USUAL_HANDLER data_abort_normal, 4, 8, 8
|
|
||||||
GEN_USUAL_HANDLER fiq, 7, 4, 4
|
|
||||||
|
|
||||||
_exception_handler_data_abort:
|
|
||||||
/* Mask interrupts (abort mode). */
|
|
||||||
msr cpsr_cx, #0xD7
|
|
||||||
|
|
||||||
adr sp, safecpy+8
|
|
||||||
cmp lr, sp
|
|
||||||
blo _exception_handler_data_abort_normal
|
|
||||||
adr sp, _safecpy_end+8
|
|
||||||
cmp lr, sp
|
|
||||||
bhs _exception_handler_data_abort_normal
|
|
||||||
|
|
||||||
/* Set the flags, set r12 to 0 for safecpy, return from exception. */
|
|
||||||
msr spsr_f, #(1 << 30)
|
|
||||||
mov r12, #0
|
|
||||||
subs pc, lr, #4
|
|
||||||
|
|
||||||
.global safecpy
|
|
||||||
.type safecpy, %function
|
|
||||||
safecpy:
|
|
||||||
push {r4, lr}
|
|
||||||
mov r3, #0
|
|
||||||
movs r12, #1
|
|
||||||
|
|
||||||
_safecpy_loop:
|
|
||||||
ldrb r4, [r1, r3]
|
|
||||||
cmp r12, #0
|
|
||||||
beq _safecpy_loop_end
|
|
||||||
strb r4, [r0, r3]
|
|
||||||
add r3, #1
|
|
||||||
cmp r3, r2
|
|
||||||
blo _safecpy_loop
|
|
||||||
|
|
||||||
_safecpy_loop_end:
|
|
||||||
mov r0, r3
|
|
||||||
pop {r4, lr}
|
|
||||||
bx lr /* Need to do that separately on ARMv4. */
|
|
||||||
|
|
||||||
_safecpy_end:
|
|
||||||
|
|
||||||
.section .rodata.exception_handlers_asm, "a", %progbits
|
|
||||||
.align 2
|
|
||||||
.global exception_handler_table
|
|
||||||
exception_handler_table:
|
|
||||||
.word 0 /* Reset */
|
|
||||||
.word _exception_handler_undefined_instruction
|
|
||||||
.word _exception_handler_swi
|
|
||||||
.word _exception_handler_prefetch_abort
|
|
||||||
.word _exception_handler_data_abort
|
|
||||||
.word 0 /* Reserved */
|
|
||||||
.word 0 /* IRQ */
|
|
||||||
.word _exception_handler_fiq
|
|
||||||
|
|
||||||
.section .bss.exception_handlers_asm, "w", %nobits
|
|
||||||
.align 4
|
|
||||||
_exception_handler_stack: .skip 0x1000
|
|
||||||
_regs: .skip (4 * 17)
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_FLOW_CTLR_H
|
|
||||||
#define FUSEE_FLOW_CTLR_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define FLOW_CTLR_BASE 0x60007000
|
|
||||||
#define MAKE_FLOW_REG(n) MAKE_REG32(FLOW_CTLR_BASE + n)
|
|
||||||
|
|
||||||
#define FLOW_CTLR_HALT_COP_EVENTS_0 MAKE_FLOW_REG(0x004)
|
|
||||||
#define FLOW_CTLR_RAM_REPAIR_0 MAKE_FLOW_REG(0x040)
|
|
||||||
#define FLOW_CTLR_FLOW_DBG_QUAL_0 MAKE_FLOW_REG(0x050)
|
|
||||||
#define FLOW_CTLR_L2FLUSH_CONTROL_0 MAKE_FLOW_REG(0x094)
|
|
||||||
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 MAKE_FLOW_REG(0x098)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,138 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "fs_utils.h"
|
|
||||||
#include "mc.h"
|
|
||||||
#include "../../../fusee/common/fatfs/ff.h"
|
|
||||||
#include "../../../fusee/common/log.h"
|
|
||||||
|
|
||||||
FATFS sd_fs;
|
|
||||||
static bool g_sd_mounted = false;
|
|
||||||
static bool g_sd_initialized = false;
|
|
||||||
static bool g_ahb_redirect_enabled = false;
|
|
||||||
sdmmc_t g_sd_sdmmc;
|
|
||||||
sdmmc_device_t g_sd_device;
|
|
||||||
|
|
||||||
bool mount_sd(void)
|
|
||||||
{
|
|
||||||
/* Already mounted. */
|
|
||||||
if (g_sd_mounted)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* Enable AHB redirection if necessary. */
|
|
||||||
if (!g_ahb_redirect_enabled) {
|
|
||||||
mc_enable_ahb_redirect();
|
|
||||||
g_ahb_redirect_enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_sd_initialized) {
|
|
||||||
/* Initialize SD. */
|
|
||||||
if (sdmmc_device_sd_init(&g_sd_device, &g_sd_sdmmc, SDMMC_BUS_WIDTH_4BIT, SDMMC_SPEED_SD_SDR104))
|
|
||||||
{
|
|
||||||
g_sd_initialized = true;
|
|
||||||
|
|
||||||
/* Mount SD. */
|
|
||||||
if (f_mount(&sd_fs, "", 1) == FR_OK) {
|
|
||||||
print(SCREEN_LOG_LEVEL_INFO, "Mounted SD card!\n");
|
|
||||||
g_sd_mounted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fatal_error("Failed to initialize the SD card!.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_sd_mounted;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unmount_sd(void)
|
|
||||||
{
|
|
||||||
if (g_sd_mounted)
|
|
||||||
{
|
|
||||||
f_mount(NULL, "", 1);
|
|
||||||
sdmmc_device_finish(&g_sd_device);
|
|
||||||
g_sd_mounted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable AHB redirection if necessary. */
|
|
||||||
if (g_ahb_redirect_enabled) {
|
|
||||||
mc_disable_ahb_redirect();
|
|
||||||
g_ahb_redirect_enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t get_file_size(const char *filename)
|
|
||||||
{
|
|
||||||
/* SD card hasn't been mounted yet. */
|
|
||||||
if (!g_sd_mounted)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Open the file for reading. */
|
|
||||||
FIL f;
|
|
||||||
if (f_open(&f, filename, FA_READ) != FR_OK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Get the file size. */
|
|
||||||
uint32_t file_size = f_size(&f);
|
|
||||||
|
|
||||||
/* Close the file. */
|
|
||||||
f_close(&f);
|
|
||||||
|
|
||||||
return file_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int read_from_file(void *dst, uint32_t dst_size, const char *filename)
|
|
||||||
{
|
|
||||||
/* SD card hasn't been mounted yet. */
|
|
||||||
if (!g_sd_mounted)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Open the file for reading. */
|
|
||||||
FIL f;
|
|
||||||
if (f_open(&f, filename, FA_READ) != FR_OK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Sync. */
|
|
||||||
f_sync(&f);
|
|
||||||
|
|
||||||
/* Read from file. */
|
|
||||||
UINT br = 0;
|
|
||||||
int res = f_read(&f, dst, dst_size, &br);
|
|
||||||
f_close(&f);
|
|
||||||
|
|
||||||
return (res == FR_OK) ? (int)br : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write_to_file(void *src, uint32_t src_size, const char *filename)
|
|
||||||
{
|
|
||||||
/* SD card hasn't been mounted yet. */
|
|
||||||
if (!g_sd_mounted)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Open the file for writing. */
|
|
||||||
FIL f;
|
|
||||||
if (f_open(&f, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Sync. */
|
|
||||||
f_sync(&f);
|
|
||||||
|
|
||||||
/* Write to file. */
|
|
||||||
UINT bw = 0;
|
|
||||||
int res = f_write(&f, src, src_size, &bw);
|
|
||||||
f_close(&f);
|
|
||||||
|
|
||||||
return (res == FR_OK) ? (int)bw : 0;
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_FS_UTILS_H
|
|
||||||
#define FUSEE_FS_UTILS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "../../../fusee/common/sdmmc/sdmmc.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
extern sdmmc_t g_sd_sdmmc;
|
|
||||||
extern sdmmc_device_t g_sd_device;
|
|
||||||
|
|
||||||
bool mount_sd(void);
|
|
||||||
void unmount_sd(void);
|
|
||||||
uint32_t get_file_size(const char *filename);
|
|
||||||
int read_from_file(void *dst, uint32_t dst_size, const char *filename);
|
|
||||||
int write_to_file(void *src, uint32_t src_size, const char *filename);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,346 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <vapours/ams_version.h>
|
|
||||||
|
|
||||||
#include "car.h"
|
|
||||||
#include "fuse.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "timers.h"
|
|
||||||
|
|
||||||
/* 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable 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_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. */
|
|
||||||
void fuse_disable_power(void) {
|
|
||||||
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. */
|
|
||||||
static 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) {
|
|
||||||
ctrl_val = fuse->FUSE_FUSECTRL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_FUSEADDR = addr;
|
|
||||||
|
|
||||||
/* Enable read operation in control register. */
|
|
||||||
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
ctrl_val |= 0x1; /* Set READ command. */
|
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
|
||||||
|
|
||||||
/* Wait for idle state. */
|
|
||||||
fuse_wait_idle();
|
|
||||||
|
|
||||||
return fuse->FUSE_FUSERDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_FUSEADDR = addr;
|
|
||||||
fuse->FUSE_FUSEWDATA = value;
|
|
||||||
|
|
||||||
/* Enable write operation in control register. */
|
|
||||||
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
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 fuse 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_FUSECTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
|
||||||
|
|
||||||
/* Wait for idle state. */
|
|
||||||
fuse_wait_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the SKU info register. */
|
|
||||||
uint32_t fuse_get_sku_info(void) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
return fuse_chip->FUSE_SKU_INFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the bootrom patch version. */
|
|
||||||
uint32_t fuse_get_bootrom_patch_version(void) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a spare bit register. */
|
|
||||||
uint32_t fuse_get_spare_bit(uint32_t index) {
|
|
||||||
uint32_t soc_type = fuse_get_soc_type();
|
|
||||||
if (soc_type == 0) {
|
|
||||||
if (index < 32) {
|
|
||||||
volatile tegra_fuse_chip_erista_t *fuse_chip = fuse_chip_erista_get_regs();
|
|
||||||
return fuse_chip->FUSE_SPARE_BIT[index];
|
|
||||||
}
|
|
||||||
} else if (soc_type == 1) {
|
|
||||||
if (index < 30) {
|
|
||||||
volatile tegra_fuse_chip_mariko_t *fuse_chip = fuse_chip_mariko_get_regs();
|
|
||||||
return fuse_chip->FUSE_SPARE_BIT[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a reserved ODM register. */
|
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t index) {
|
|
||||||
if (index < 8) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM0[index];
|
|
||||||
} else {
|
|
||||||
uint32_t soc_type = fuse_get_soc_type();
|
|
||||||
if (soc_type == 1) {
|
|
||||||
volatile tegra_fuse_chip_mariko_t *fuse_chip = fuse_chip_mariko_get_regs();
|
|
||||||
if (index < 22) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM8[index - 8];
|
|
||||||
} else if (index < 25) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM22[index - 22];
|
|
||||||
} else if (index < 26) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM25;
|
|
||||||
} else if (index < 29) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM26[index - 26];
|
|
||||||
} else if (index < 30) {
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM29;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the DramId. */
|
|
||||||
uint32_t fuse_get_dram_id(void) {
|
|
||||||
return ((fuse_get_reserved_odm(4) >> 3) & 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the DeviceId. */
|
|
||||||
uint64_t fuse_get_device_id(void) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the HardwareType with firmware specific checks. */
|
|
||||||
uint32_t fuse_get_hardware_type_with_firmware_check(uint32_t target_firmware) {
|
|
||||||
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 (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
uint32_t fuse_spare_bit9 = (fuse_chip->FUSE_SPARE_BIT[9] & 1);
|
|
||||||
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x00: return (fuse_spare_bit9 == 0) ? 0 : 3;
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 1; /* HardwareType_Copper */
|
|
||||||
default: return 3; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
|
||||||
|
|
||||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 1; /* HardwareType_Copper */
|
|
||||||
case 0x04: return 3; /* HardwareType_Iowa */
|
|
||||||
default: return 4; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 4; /* HardwareType_Calcio */
|
|
||||||
case 0x04: return 3; /* HardwareType_Iowa */
|
|
||||||
case 0x08: return 2; /* HardwareType_Hoag */
|
|
||||||
default: return 0xF; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (hardware_type) {
|
|
||||||
case 0x01: return 0; /* HardwareType_Icosa */
|
|
||||||
case 0x02: return 4; /* HardwareType_Calcio */
|
|
||||||
case 0x04: return 3; /* HardwareType_Iowa */
|
|
||||||
case 0x08: return 2; /* HardwareType_Hoag */
|
|
||||||
case 0x10: return 5; /* HardwareType_Five */
|
|
||||||
default: return 0xF; /* HardwareType_Undefined */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the HardwareType. */
|
|
||||||
uint32_t fuse_get_hardware_type(void) {
|
|
||||||
return fuse_get_hardware_type_with_firmware_check(ATMOSPHERE_TARGET_FIRMWARE_CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the HardwareState. */
|
|
||||||
uint32_t fuse_get_hardware_state(void) {
|
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
|
||||||
uint32_t hardware_state = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
|
|
||||||
|
|
||||||
switch (hardware_state) {
|
|
||||||
case 0x03: return 0; /* HardwareState_Development */
|
|
||||||
case 0x04: return 1; /* HardwareState_Production */
|
|
||||||
default: return 2; /* HardwareState_Undefined */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the 16-byte HardwareInfo and copy to output buffer. */
|
|
||||||
void fuse_get_hardware_info(void *dst) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
uint32_t hw_info[0x4];
|
|
||||||
|
|
||||||
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 = 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);
|
|
||||||
|
|
||||||
memcpy(dst, hw_info, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if have a new ODM fuse format. */
|
|
||||||
bool fuse_is_new_format(void) {
|
|
||||||
return ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the DeviceUniqueKeyGeneration. */
|
|
||||||
uint32_t fuse_get_device_unique_key_generation(void) {
|
|
||||||
if (fuse_is_new_format()) {
|
|
||||||
return (fuse_get_reserved_odm(2) & 0x1F);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the SocType from the HardwareType. */
|
|
||||||
uint32_t fuse_get_soc_type(void) {
|
|
||||||
switch (fuse_get_hardware_type()) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
return 0; /* SocType_Erista */
|
|
||||||
case 3:
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
return 1; /* SocType_Mariko */
|
|
||||||
default:
|
|
||||||
return 0xF; /* SocType_Undefined */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the Regulator type. */
|
|
||||||
uint32_t fuse_get_regulator(void) {
|
|
||||||
if (fuse_get_soc_type() == 1) {
|
|
||||||
return ((fuse_get_reserved_odm(28) & 1) + 1); /* Regulator_Mariko_Max77812_A or Regulator_Mariko_Max77812_B */
|
|
||||||
} else {
|
|
||||||
return 0; /* Regulator_Erista_Max77621 */
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,484 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
|
||||||
#define FUSEE_FUSE_H
|
|
||||||
|
|
||||||
#define FUSE_BASE 0x7000F800
|
|
||||||
#define FUSE_CHIP_BASE (FUSE_BASE + 0x98)
|
|
||||||
#define MAKE_FUSE_REG(n) MAKE_REG32(FUSE_BASE + n)
|
|
||||||
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
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_DISABLEREGPROGRAM;
|
|
||||||
uint32_t FUSE_WRITE_ACCESS_SW;
|
|
||||||
uint32_t FUSE_PWR_GOOD_SW;
|
|
||||||
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 _0x94;
|
|
||||||
} tegra_fuse_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t _0x98[0x1A];
|
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
|
||||||
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_CALIB;
|
|
||||||
uint32_t FUSE_CPU_IDDQ_CALIB;
|
|
||||||
uint32_t _0x11C[0x3];
|
|
||||||
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 _0x144;
|
|
||||||
uint32_t FUSE_FA;
|
|
||||||
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_TSENSOR1_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR2_CALIB;
|
|
||||||
uint32_t _0x18C;
|
|
||||||
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[0x5];
|
|
||||||
uint32_t FUSE_ARM_JTAG_DIS;
|
|
||||||
uint32_t FUSE_BOOT_DEVICE_INFO;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
|
||||||
uint32_t FUSE_OPT_VP9_DISABLE;
|
|
||||||
uint32_t FUSE_RESERVED_ODM0[0x8];
|
|
||||||
uint32_t FUSE_OBS_DIS;
|
|
||||||
uint32_t _0x1EC;
|
|
||||||
uint32_t FUSE_USB_CALIB;
|
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
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 _0x224;
|
|
||||||
uint32_t FUSE_GPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR3_CALIB;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT0;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT1;
|
|
||||||
uint32_t _0x238[0x3];
|
|
||||||
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
|
||||||
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 _0x268[0x5];
|
|
||||||
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
|
||||||
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 _0x294;
|
|
||||||
uint32_t FUSE_APB2JTAG_DISABLE;
|
|
||||||
uint32_t FUSE_ODM_INFO;
|
|
||||||
uint32_t _0x2A0[0x2];
|
|
||||||
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
uint32_t _0x2AC[0x5];
|
|
||||||
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 _0x2D8;
|
|
||||||
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 _0x2FC[0x2];
|
|
||||||
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 _0x324[0x5];
|
|
||||||
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 FUSE_RESERVED_FIELD;
|
|
||||||
uint32_t _0x358[0x9];
|
|
||||||
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
|
||||||
} tegra_fuse_chip_common_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t _0x98[0x1A];
|
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
|
||||||
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_CALIB;
|
|
||||||
uint32_t FUSE_CPU_IDDQ_CALIB;
|
|
||||||
uint32_t _0x11C[0x3];
|
|
||||||
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 _0x144;
|
|
||||||
uint32_t FUSE_FA;
|
|
||||||
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_TSENSOR1_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR2_CALIB;
|
|
||||||
uint32_t _0x18C;
|
|
||||||
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[0x5];
|
|
||||||
uint32_t FUSE_ARM_JTAG_DIS;
|
|
||||||
uint32_t FUSE_BOOT_DEVICE_INFO;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
|
||||||
uint32_t FUSE_OPT_VP9_DISABLE;
|
|
||||||
uint32_t FUSE_RESERVED_ODM0[0x8];
|
|
||||||
uint32_t FUSE_OBS_DIS;
|
|
||||||
uint32_t _0x1EC;
|
|
||||||
uint32_t FUSE_USB_CALIB;
|
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
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; /* Erista only. */
|
|
||||||
uint32_t FUSE_GPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR3_CALIB;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT0;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT1;
|
|
||||||
uint32_t _0x238[0x3];
|
|
||||||
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
|
||||||
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; /* Erista only. */
|
|
||||||
uint32_t _0x26C[0x4];
|
|
||||||
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
|
||||||
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 _0x294;
|
|
||||||
uint32_t FUSE_APB2JTAG_DISABLE;
|
|
||||||
uint32_t FUSE_ODM_INFO;
|
|
||||||
uint32_t _0x2A0[0x2];
|
|
||||||
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
uint32_t _0x2AC[0x5];
|
|
||||||
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 _0x2D8;
|
|
||||||
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 _0x2FC[0x2];
|
|
||||||
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; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_PDP; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_REG; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_SP; /* Erista only. */
|
|
||||||
uint32_t FUSE_OPT_RAM_SVOP_SMPDP; /* Erista only. */
|
|
||||||
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 FUSE_RESERVED_FIELD;
|
|
||||||
uint32_t _0x358[0x9];
|
|
||||||
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
|
||||||
} tegra_fuse_chip_erista_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t FUSE_RESERVED_ODM8[0xE]; /* Mariko only. */
|
|
||||||
uint32_t FUSE_KEK[0x4]; /* Mariko only. */
|
|
||||||
uint32_t FUSE_BEK[0x4]; /* Mariko only. */
|
|
||||||
uint32_t _0xF0; /* Mariko only. */
|
|
||||||
uint32_t _0xF4; /* Mariko only. */
|
|
||||||
uint32_t _0xF8; /* Mariko only. */
|
|
||||||
uint32_t _0xFC; /* Mariko only. */
|
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
|
||||||
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_CALIB;
|
|
||||||
uint32_t FUSE_CPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_RESERVED_ODM22[0x3]; /* Mariko only. */
|
|
||||||
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_ODM25; /* Mariko only. */
|
|
||||||
uint32_t FUSE_FA;
|
|
||||||
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_TSENSOR1_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR2_CALIB;
|
|
||||||
uint32_t FUSE_OPT_SECURE_SCC_DIS; /* Mariko only. */
|
|
||||||
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[0x5];
|
|
||||||
uint32_t FUSE_ARM_JTAG_DIS;
|
|
||||||
uint32_t FUSE_BOOT_DEVICE_INFO;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
|
||||||
uint32_t FUSE_OPT_VP9_DISABLE;
|
|
||||||
uint32_t FUSE_RESERVED_ODM0[0x8];
|
|
||||||
uint32_t FUSE_OBS_DIS;
|
|
||||||
uint32_t _0x1EC; /* Mariko only. */
|
|
||||||
uint32_t FUSE_USB_CALIB;
|
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
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 _0x224; /* Mariko only. */
|
|
||||||
uint32_t FUSE_GPU_IDDQ_CALIB;
|
|
||||||
uint32_t FUSE_TSENSOR3_CALIB;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT0;
|
|
||||||
uint32_t FUSE_CLOCK_BOUNDOUT1;
|
|
||||||
uint32_t FUSE_RESERVED_ODM26[0x3]; /* Mariko only. */
|
|
||||||
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
|
||||||
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_BOOT_SECURITY_INFO; /* Mariko only. */
|
|
||||||
uint32_t _0x26C; /* Mariko only. */
|
|
||||||
uint32_t _0x270; /* Mariko only. */
|
|
||||||
uint32_t _0x274; /* Mariko only. */
|
|
||||||
uint32_t _0x278; /* Mariko only. */
|
|
||||||
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
|
||||||
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 FUSE_RESERVED_ODM29; /* Mariko only. */
|
|
||||||
uint32_t FUSE_APB2JTAG_DISABLE;
|
|
||||||
uint32_t FUSE_ODM_INFO;
|
|
||||||
uint32_t _0x2A0[0x2];
|
|
||||||
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
uint32_t _0x2AC;
|
|
||||||
uint32_t _0x2B0; /* Mariko only. */
|
|
||||||
uint32_t _0x2B4; /* Mariko only. */
|
|
||||||
uint32_t _0x2B8; /* Mariko only. */
|
|
||||||
uint32_t _0x2BC; /* Mariko only. */
|
|
||||||
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 _0x2D8;
|
|
||||||
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 _0x2FC[0x2];
|
|
||||||
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 _0x324; /* Mariko only. */
|
|
||||||
uint32_t _0x328; /* Mariko only. */
|
|
||||||
uint32_t _0x32C; /* Mariko only. */
|
|
||||||
uint32_t _0x330; /* Mariko only. */
|
|
||||||
uint32_t _0x334; /* Mariko only. */
|
|
||||||
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 FUSE_RESERVED_FIELD;
|
|
||||||
uint32_t _0x358[0x9];
|
|
||||||
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
uint32_t FUSE_SPARE_BIT[0x1E];
|
|
||||||
} tegra_fuse_chip_mariko_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_t *fuse_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_t *)FUSE_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_common_t *fuse_chip_common_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_chip_common_t *)FUSE_CHIP_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_erista_t *fuse_chip_erista_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_chip_erista_t *)FUSE_CHIP_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_mariko_t *fuse_chip_mariko_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_fuse_chip_mariko_t *)FUSE_CHIP_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_init(void);
|
|
||||||
void fuse_disable_programming(void);
|
|
||||||
void fuse_disable_private_key(void);
|
|
||||||
void fuse_enable_power(void);
|
|
||||||
void fuse_disable_power(void);
|
|
||||||
|
|
||||||
uint32_t fuse_get_sku_info(void);
|
|
||||||
uint32_t fuse_get_spare_bit(uint32_t index);
|
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t index);
|
|
||||||
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_with_firmware_check(uint32_t target_firmware);
|
|
||||||
uint32_t fuse_get_hardware_type(void);
|
|
||||||
uint32_t fuse_get_retail_type(void);
|
|
||||||
void fuse_get_hardware_info(void *dst);
|
|
||||||
bool fuse_is_new_format(void);
|
|
||||||
uint32_t fuse_get_device_unique_key_generation(void);
|
|
||||||
uint32_t fuse_get_soc_type(void);
|
|
||||||
uint32_t fuse_get_regulator(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
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
/* Set GPIO's value. */
|
|
||||||
static void gpio_register_set(uint32_t pin, bool do_set, uint32_t offset) {
|
|
||||||
volatile tegra_gpio_t *gpio = gpio_get_regs();
|
|
||||||
|
|
||||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
|
||||||
volatile uint32_t *cluster = (uint32_t *)((uintptr_t)&gpio->bank[(pin >> GPIO_BANK_SHIFT)] + offset);
|
|
||||||
|
|
||||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
|
||||||
uint32_t port = ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
|
|
||||||
uint32_t mask = (1 << (pin & GPIO_PIN_MASK));
|
|
||||||
|
|
||||||
/* Set or clear the bit, as appropriate. */
|
|
||||||
if (do_set)
|
|
||||||
cluster[port] |= mask;
|
|
||||||
else
|
|
||||||
cluster[port] &= ~mask;
|
|
||||||
|
|
||||||
/* Dummy read. */
|
|
||||||
cluster[port];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get GPIO's value. */
|
|
||||||
static bool gpio_register_get(uint32_t pin, uint32_t offset) {
|
|
||||||
volatile tegra_gpio_t *gpio = gpio_get_regs();
|
|
||||||
|
|
||||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
|
||||||
volatile uint32_t *cluster = (uint32_t *)((uintptr_t)&gpio->bank[(pin >> GPIO_BANK_SHIFT)] + offset);
|
|
||||||
|
|
||||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
|
||||||
uint32_t port = ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
|
|
||||||
uint32_t mask = (1 << (pin & GPIO_PIN_MASK));
|
|
||||||
|
|
||||||
/* Convert the given value to a boolean. */
|
|
||||||
return !!(cluster[port] & mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure GPIO's mode. */
|
|
||||||
void gpio_configure_mode(uint32_t pin, uint32_t mode) {
|
|
||||||
gpio_register_set(pin, mode == GPIO_MODE_GPIO, offsetof(tegra_gpio_bank_t, config));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure GPIO's direction. */
|
|
||||||
void gpio_configure_direction(uint32_t pin, uint32_t dir) {
|
|
||||||
gpio_register_set(pin, dir == GPIO_DIRECTION_OUTPUT, offsetof(tegra_gpio_bank_t, direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write to GPIO. */
|
|
||||||
void gpio_write(uint32_t pin, uint32_t value) {
|
|
||||||
gpio_register_set(pin, value == GPIO_LEVEL_HIGH, offsetof(tegra_gpio_bank_t, out));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read from GPIO. */
|
|
||||||
uint32_t gpio_read(uint32_t pin) {
|
|
||||||
return gpio_register_get(pin, offsetof(tegra_gpio_bank_t, in));
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_GPIO_H
|
|
||||||
#define FUSEE_GPIO_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define GPIO_BASE 0x6000D000
|
|
||||||
#define MAKE_GPIO_REG(n) MAKE_REG32(GPIO_BASE + n)
|
|
||||||
|
|
||||||
#define TEGRA_GPIO_PORTS 4
|
|
||||||
#define TEGRA_GPIO_BANKS 8
|
|
||||||
#define GPIO_BANK_SHIFT 5
|
|
||||||
#define GPIO_PORT_SHIFT 3
|
|
||||||
#define GPIO_PORT_MASK 0x03
|
|
||||||
#define GPIO_PIN_MASK 0x07
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
TEGRA_GPIO_PORT_A = 0,
|
|
||||||
TEGRA_GPIO_PORT_B = 1,
|
|
||||||
TEGRA_GPIO_PORT_C = 2,
|
|
||||||
TEGRA_GPIO_PORT_D = 3,
|
|
||||||
TEGRA_GPIO_PORT_E = 4,
|
|
||||||
TEGRA_GPIO_PORT_F = 5,
|
|
||||||
TEGRA_GPIO_PORT_G = 6,
|
|
||||||
TEGRA_GPIO_PORT_H = 7,
|
|
||||||
TEGRA_GPIO_PORT_I = 8,
|
|
||||||
TEGRA_GPIO_PORT_J = 9,
|
|
||||||
TEGRA_GPIO_PORT_K = 10,
|
|
||||||
TEGRA_GPIO_PORT_L = 11,
|
|
||||||
TEGRA_GPIO_PORT_M = 12,
|
|
||||||
TEGRA_GPIO_PORT_N = 13,
|
|
||||||
TEGRA_GPIO_PORT_O = 14,
|
|
||||||
TEGRA_GPIO_PORT_P = 15,
|
|
||||||
TEGRA_GPIO_PORT_Q = 16,
|
|
||||||
TEGRA_GPIO_PORT_R = 17,
|
|
||||||
TEGRA_GPIO_PORT_S = 18,
|
|
||||||
TEGRA_GPIO_PORT_T = 19,
|
|
||||||
TEGRA_GPIO_PORT_U = 20,
|
|
||||||
TEGRA_GPIO_PORT_V = 21,
|
|
||||||
TEGRA_GPIO_PORT_W = 22,
|
|
||||||
TEGRA_GPIO_PORT_X = 23,
|
|
||||||
TEGRA_GPIO_PORT_Y = 24,
|
|
||||||
TEGRA_GPIO_PORT_Z = 25,
|
|
||||||
TEGRA_GPIO_PORT_AA = 26,
|
|
||||||
TEGRA_GPIO_PORT_BB = 27,
|
|
||||||
TEGRA_GPIO_PORT_CC = 28,
|
|
||||||
TEGRA_GPIO_PORT_DD = 29,
|
|
||||||
TEGRA_GPIO_PORT_EE = 30,
|
|
||||||
TEGRA_GPIO_PORT_FF = 31,
|
|
||||||
} tegra_gpio_port;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t config[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t direction[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t out[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t in[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_status[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_enable[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_level[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t int_clear[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_config[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_dir_out[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_out[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_in[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_status[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_enable[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_level[TEGRA_GPIO_PORTS];
|
|
||||||
uint32_t masked_int_clear[TEGRA_GPIO_PORTS];
|
|
||||||
} tegra_gpio_bank_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
tegra_gpio_bank_t bank[TEGRA_GPIO_BANKS];
|
|
||||||
} tegra_gpio_t;
|
|
||||||
|
|
||||||
static inline volatile tegra_gpio_t *gpio_get_regs(void)
|
|
||||||
{
|
|
||||||
return (volatile tegra_gpio_t *)GPIO_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TEGRA_GPIO(port, offset) \
|
|
||||||
((TEGRA_GPIO_PORT_##port * 8) + offset)
|
|
||||||
|
|
||||||
/* Mode select */
|
|
||||||
#define GPIO_MODE_SFIO 0
|
|
||||||
#define GPIO_MODE_GPIO 1
|
|
||||||
|
|
||||||
/* Direction */
|
|
||||||
#define GPIO_DIRECTION_INPUT 0
|
|
||||||
#define GPIO_DIRECTION_OUTPUT 1
|
|
||||||
|
|
||||||
/* Level */
|
|
||||||
#define GPIO_LEVEL_LOW 0
|
|
||||||
#define GPIO_LEVEL_HIGH 1
|
|
||||||
|
|
||||||
/* Named GPIOs */
|
|
||||||
#define GPIO_BUTTON_VOL_DOWN TEGRA_GPIO(X, 7)
|
|
||||||
#define GPIO_BUTTON_VOL_UP TEGRA_GPIO(X, 6)
|
|
||||||
#define GPIO_MICROSD_CARD_DETECT TEGRA_GPIO(Z, 1)
|
|
||||||
#define GPIO_MICROSD_WRITE_PROTECT TEGRA_GPIO(Z, 4)
|
|
||||||
#define GPIO_MICROSD_SUPPLY_ENABLE TEGRA_GPIO(E, 4)
|
|
||||||
#define GPIO_LCD_BL_P5V TEGRA_GPIO(I, 0)
|
|
||||||
#define GPIO_LCD_BL_N5V TEGRA_GPIO(I, 1)
|
|
||||||
#define GPIO_LCD_BL_PWM TEGRA_GPIO(V, 0)
|
|
||||||
#define GPIO_LCD_BL_EN TEGRA_GPIO(V, 1)
|
|
||||||
#define GPIO_LCD_BL_RST TEGRA_GPIO(V, 2)
|
|
||||||
|
|
||||||
void gpio_configure_mode(uint32_t pin, uint32_t mode);
|
|
||||||
void gpio_configure_direction(uint32_t pin, uint32_t dir);
|
|
||||||
void gpio_write(uint32_t pin, uint32_t value);
|
|
||||||
uint32_t gpio_read(uint32_t pin);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,327 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hwinit.h"
|
|
||||||
#include "apb_misc.h"
|
|
||||||
#include "car.h"
|
|
||||||
#include "di.h"
|
|
||||||
#include "fuse.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "max77620.h"
|
|
||||||
#include "mc.h"
|
|
||||||
#include "pinmux.h"
|
|
||||||
#include "pmc.h"
|
|
||||||
#include "se.h"
|
|
||||||
#include "sdram.h"
|
|
||||||
#include "sysctr0.h"
|
|
||||||
#include "sysreg.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "uart.h"
|
|
||||||
|
|
||||||
/* Determine the current SoC for Mariko specific code. */
|
|
||||||
static bool is_soc_mariko() {
|
|
||||||
return (fuse_get_soc_type() == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void config_oscillators(void) {
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
|
||||||
|
|
||||||
car->spare_reg0 = ((car->spare_reg0 & 0xFFFFFFF3) | 4);
|
|
||||||
|
|
||||||
SYSCTR0_CNTFID0_0 = 19200000;
|
|
||||||
TIMERUS_USEC_CFG_0 = 0x45F;
|
|
||||||
|
|
||||||
car->osc_ctrl = 0x50000071;
|
|
||||||
pmc->osc_edpd_over = ((pmc->osc_edpd_over & 0xFFFFFF81) | 0xE);
|
|
||||||
pmc->osc_edpd_over = ((pmc->osc_edpd_over & 0xFFBFFFFF) | 0x400000);
|
|
||||||
pmc->cntrl2 = ((pmc->cntrl2 & 0xFFFFEFFF) | 0x1000);
|
|
||||||
pmc->scratch188 = ((pmc->scratch188 & 0xFCFFFFFF) | 0x2000000);
|
|
||||||
car->clk_sys_rate = 0x10;
|
|
||||||
car->pllmb_base &= 0xBFFFFFFF;
|
|
||||||
pmc->tsc_mult = ((pmc->tsc_mult & 0xFFFF0000) | 0x249F); /* 0x249F = 19200000 * (16 / 32.768 kHz) */
|
|
||||||
car->sclk_brst_pol = 0x20004444;
|
|
||||||
car->super_sclk_div = 0x80000000;
|
|
||||||
car->clk_sys_rate = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void config_gpios(void) {
|
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
|
||||||
bool is_mariko = is_soc_mariko();
|
|
||||||
|
|
||||||
if (is_mariko) {
|
|
||||||
uint32_t hardware_type = fuse_get_hardware_type();
|
|
||||||
|
|
||||||
/* Only for HardwareType_Iowa and HardwareType_Five. */
|
|
||||||
if ((hardware_type == 3) || (hardware_type == 5)) {
|
|
||||||
pinmux->uart2_tx = 0;
|
|
||||||
pinmux->uart3_tx = 0;
|
|
||||||
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
|
|
||||||
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pinmux->uart2_tx = 0;
|
|
||||||
pinmux->uart3_tx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pinmux->pe6 = PINMUX_INPUT;
|
|
||||||
pinmux->ph6 = PINMUX_INPUT;
|
|
||||||
if (!is_mariko) {
|
|
||||||
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
|
|
||||||
}
|
|
||||||
gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO);
|
|
||||||
if (!is_mariko) {
|
|
||||||
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
|
|
||||||
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
|
|
||||||
}
|
|
||||||
gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT);
|
|
||||||
gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT);
|
|
||||||
|
|
||||||
i2c_config(I2C_1);
|
|
||||||
i2c_config(I2C_5);
|
|
||||||
uart_config(UART_A);
|
|
||||||
|
|
||||||
/* Configure volume up/down buttons as inputs. */
|
|
||||||
gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_mode(GPIO_BUTTON_VOL_DOWN, GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT);
|
|
||||||
gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT);
|
|
||||||
|
|
||||||
if (is_mariko) {
|
|
||||||
/* Configure home button as input. */
|
|
||||||
gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO);
|
|
||||||
gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbist_workaround(void) {
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
|
|
||||||
car->clk_source_sor1 = ((car->clk_source_sor1 | 0x8000) & 0xFFFFBFFF);
|
|
||||||
car->plld_base |= 0x40800000u;
|
|
||||||
car->rst_dev_y_clr = 0x40;
|
|
||||||
car->rst_dev_x_clr = 0x40000;
|
|
||||||
car->rst_dev_l_clr = 0x18000000;
|
|
||||||
udelay(2);
|
|
||||||
|
|
||||||
/* Setup I2S. */
|
|
||||||
MAKE_I2S_REG(0x0A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x088) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x1A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x188) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x2A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x288) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x3A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x388) &= 0xFFFFFFFE;
|
|
||||||
MAKE_I2S_REG(0x4A0) |= 0x400;
|
|
||||||
MAKE_I2S_REG(0x488) &= 0xFFFFFFFE;
|
|
||||||
|
|
||||||
MAKE_DI_REG(DC_COM_DSC_TOP_CTL) |= 4;
|
|
||||||
MAKE_VIC_REG(0x8C) = 0xFFFFFFFF;
|
|
||||||
udelay(2);
|
|
||||||
|
|
||||||
/* Set devices in reset. */
|
|
||||||
car->rst_dev_y_set = 0x40;
|
|
||||||
car->rst_dev_l_set = 0x18000000;
|
|
||||||
car->rst_dev_x_set = 0x40000;
|
|
||||||
|
|
||||||
/* Clock out enables. */
|
|
||||||
car->clk_out_enb_h = 0xC0;
|
|
||||||
car->clk_out_enb_l = 0x80000130;
|
|
||||||
car->clk_out_enb_u = 0x1F00200;
|
|
||||||
car->clk_out_enb_v = 0x80400808;
|
|
||||||
car->clk_out_enb_w = 0x402000FC;
|
|
||||||
car->clk_out_enb_x = 0x23000780;
|
|
||||||
car->clk_out_enb_y = 0x300;
|
|
||||||
|
|
||||||
/* LVL2 clock gate overrides. */
|
|
||||||
car->lvl2_clk_gate_ovra = 0;
|
|
||||||
car->lvl2_clk_gate_ovrb = 0;
|
|
||||||
car->lvl2_clk_gate_ovrc = 0;
|
|
||||||
car->lvl2_clk_gate_ovrd = 0;
|
|
||||||
car->lvl2_clk_gate_ovre = 0;
|
|
||||||
|
|
||||||
/* Configure clock sources. */
|
|
||||||
car->plld_base &= 0x1F7FFFFF;
|
|
||||||
car->clk_source_sor1 &= 0xFFFF3FFF;
|
|
||||||
car->clk_source_vi = ((car->clk_source_vi & 0x1FFFFFFF) | 0x80000000);
|
|
||||||
car->clk_source_host1x = ((car->clk_source_host1x & 0x1FFFFFFF) | 0x80000000);
|
|
||||||
car->clk_source_nvenc = ((car->clk_source_nvenc & 0x1FFFFFFF) | 0x80000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void config_se_brom(void) {
|
|
||||||
volatile tegra_fuse_chip_common_t *fuse_chip = fuse_chip_common_get_regs();
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
|
||||||
|
|
||||||
/* Bootrom part we skipped. */
|
|
||||||
uint32_t sbk[4] = {fuse_chip->FUSE_PRIVATE_KEY[0], fuse_chip->FUSE_PRIVATE_KEY[1], fuse_chip->FUSE_PRIVATE_KEY[2], fuse_chip->FUSE_PRIVATE_KEY[3]};
|
|
||||||
set_aes_keyslot(0xE, sbk, 0x10);
|
|
||||||
|
|
||||||
/* Lock SBK from being read. */
|
|
||||||
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->SE_INT_STATUS = 0x1F;
|
|
||||||
|
|
||||||
/* Lock SSK (although it's not set and unused anyways). */
|
|
||||||
se->SE_CRYPTO_KEYTABLE_ACCESS[0xF] = 0x7E;
|
|
||||||
|
|
||||||
/* Clear the boot reason to avoid problems later */
|
|
||||||
pmc->scratch200 = 0;
|
|
||||||
pmc->rst_status = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx_hwinit(bool enable_log) {
|
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
|
||||||
bool is_mariko = is_soc_mariko();
|
|
||||||
|
|
||||||
if (!is_mariko) {
|
|
||||||
/* Bootrom stuff we skipped by going through RCM. */
|
|
||||||
config_se_brom();
|
|
||||||
|
|
||||||
AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F;
|
|
||||||
pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD);
|
|
||||||
|
|
||||||
/* Apply the memory built-in self test workaround. */
|
|
||||||
mbist_workaround();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable SE clock. */
|
|
||||||
clkrst_reboot(CARDEVICE_SE);
|
|
||||||
if (is_mariko) {
|
|
||||||
/* Lock the SE clock. */
|
|
||||||
car->clk_source_se |= 0x100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the fuse driver. */
|
|
||||||
fuse_init();
|
|
||||||
|
|
||||||
if (!is_mariko) {
|
|
||||||
/* Initialize the memory controller. */
|
|
||||||
mc_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure oscillators. */
|
|
||||||
config_oscillators();
|
|
||||||
|
|
||||||
/* Disable pinmux tristate input clamping. */
|
|
||||||
APB_MISC_PP_PINMUX_GLOBAL_0 = 0;
|
|
||||||
|
|
||||||
/* Configure GPIOs. */
|
|
||||||
config_gpios();
|
|
||||||
|
|
||||||
/* UART debugging. */
|
|
||||||
if (enable_log) {
|
|
||||||
clkrst_reboot(CARDEVICE_UARTA);
|
|
||||||
uart_init(UART_A, 115200);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable CL-DVFS clock. */
|
|
||||||
clkrst_reboot(CARDEVICE_CL_DVFS);
|
|
||||||
|
|
||||||
/* Enable I2C1 clock. */
|
|
||||||
clkrst_reboot(CARDEVICE_I2C1);
|
|
||||||
|
|
||||||
/* Enable I2C5 clock. */
|
|
||||||
clkrst_reboot(CARDEVICE_I2C5);
|
|
||||||
|
|
||||||
/* Enable TZRAM clock. */
|
|
||||||
clkrst_reboot(CARDEVICE_TZRAM);
|
|
||||||
|
|
||||||
/* Initialize I2C5. */
|
|
||||||
i2c_init(I2C_5);
|
|
||||||
|
|
||||||
/* Configure the PMIC. */
|
|
||||||
if (is_mariko) {
|
|
||||||
uint8_t val = 0x40;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
|
|
||||||
val = 0x78;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
|
|
||||||
} else {
|
|
||||||
uint8_t val = 0x40;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
|
|
||||||
val = 0x60;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
|
|
||||||
val = 0x38;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
|
|
||||||
val = 0x3A;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1);
|
|
||||||
val = 0x38;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1);
|
|
||||||
val = 0xF;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1);
|
|
||||||
val = 0xC7;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1);
|
|
||||||
val = 0x4F;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1);
|
|
||||||
val = 0x29;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1);
|
|
||||||
val = 0x1B;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1);
|
|
||||||
|
|
||||||
/* NOTE: [3.0.0+] This was added. */
|
|
||||||
val = 0x22;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1);
|
|
||||||
|
|
||||||
/* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */
|
|
||||||
/*
|
|
||||||
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
|
|
||||||
val |= 0x40;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure SD0 voltage. */
|
|
||||||
uint8_t val = 0x24;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1);
|
|
||||||
|
|
||||||
/* Enable LDO8 in HardwareType_Hoag only. */
|
|
||||||
if (is_mariko && (fuse_get_hardware_type() == 2)) {
|
|
||||||
val = 0xE8;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO8_CFG, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize I2C1. */
|
|
||||||
i2c_init(I2C_1);
|
|
||||||
|
|
||||||
/* Set super clock burst policy. */
|
|
||||||
car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333);
|
|
||||||
|
|
||||||
if (is_mariko) {
|
|
||||||
/* Mariko only PMC configuration for TZRAM. */
|
|
||||||
pmc->tzram_pwr_cntrl &= 0xFFFFFFFE;
|
|
||||||
pmc->tzram_non_sec_disable = 0x3;
|
|
||||||
pmc->tzram_sec_disable = 0x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save SDRAM parameters to scratch. */
|
|
||||||
sdram_save_params(sdram_get_params(fuse_get_dram_id()));
|
|
||||||
|
|
||||||
/* Initialize SDRAM. */
|
|
||||||
sdram_init();
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 naehrwert
|
|
||||||
* Copyright (c) 2018 CTCaer
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_HWINIT_H_
|
|
||||||
#define FUSEE_HWINIT_H_
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define I2S_BASE 0x702D1000
|
|
||||||
#define MAKE_I2S_REG(n) MAKE_REG32(I2S_BASE + n)
|
|
||||||
|
|
||||||
void nx_hwinit(bool enable_log);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,252 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "pinmux.h"
|
|
||||||
|
|
||||||
/* Prototypes for internal commands. */
|
|
||||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
|
|
||||||
void i2c_load_config(volatile tegra_i2c_t *regs);
|
|
||||||
|
|
||||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
|
||||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
|
||||||
|
|
||||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
|
|
||||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
|
|
||||||
|
|
||||||
/* Configure I2C pinmux. */
|
|
||||||
void i2c_config(I2CDevice id) {
|
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
|
||||||
|
|
||||||
switch (id) {
|
|
||||||
case I2C_1:
|
|
||||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->gen1_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_2:
|
|
||||||
pinmux->gen2_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->gen2_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_3:
|
|
||||||
pinmux->gen3_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->gen3_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_4:
|
|
||||||
pinmux->cam_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->cam_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_5:
|
|
||||||
pinmux->pwr_i2c_scl = PINMUX_INPUT;
|
|
||||||
pinmux->pwr_i2c_sda = PINMUX_INPUT;
|
|
||||||
break;
|
|
||||||
case I2C_6:
|
|
||||||
/* Unused. */
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize I2C based on registers. */
|
|
||||||
void i2c_init(I2CDevice id) {
|
|
||||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
|
||||||
|
|
||||||
/* Setup divisor, and clear the bus. */
|
|
||||||
regs->I2C_I2C_CLK_DIVISOR_REGISTER_0 = 0x50001;
|
|
||||||
regs->I2C_I2C_BUS_CLEAR_CONFIG_0 = 0x90003;
|
|
||||||
|
|
||||||
/* Load hardware configuration. */
|
|
||||||
i2c_load_config(regs);
|
|
||||||
|
|
||||||
/* Wait a while until BUS_CLEAR_DONE is set. */
|
|
||||||
for (unsigned int i = 0; i < 10; i++) {
|
|
||||||
udelay(20000);
|
|
||||||
if (regs->I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the BUS_CLEAR_STATUS. Result doesn't matter. */
|
|
||||||
regs->I2C_I2C_BUS_CLEAR_STATUS_0;
|
|
||||||
|
|
||||||
/* Read and set the Interrupt Status. */
|
|
||||||
uint32_t int_status = regs->I2C_INTERRUPT_STATUS_REGISTER_0;
|
|
||||||
regs->I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
|
|
||||||
void i2c_send_pmic_cpu_shutdown_cmd(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* PMIC == Device 4:3C. */
|
|
||||||
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
|
|
||||||
val |= 4;
|
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Queries the value of TI charger bit over I2C. */
|
|
||||||
bool i2c_query_ti_charger_bit_7(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* TI Charger = Device 0:6B. */
|
|
||||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
return (val & 0x80) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clears TI charger bit over I2C. */
|
|
||||||
void i2c_clear_ti_charger_bit_7(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* TI Charger = Device 0:6B. */
|
|
||||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
val &= 0x7F;
|
|
||||||
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets TI charger bit over I2C. */
|
|
||||||
void i2c_set_ti_charger_bit_7(void) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
/* TI Charger = Device 0:6B. */
|
|
||||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
val |= 0x80;
|
|
||||||
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get registers pointer based on I2C ID. */
|
|
||||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
|
|
||||||
switch (id) {
|
|
||||||
case I2C_1:
|
|
||||||
return I2C1_REGS;
|
|
||||||
case I2C_2:
|
|
||||||
return I2C2_REGS;
|
|
||||||
case I2C_3:
|
|
||||||
return I2C3_REGS;
|
|
||||||
case I2C_4:
|
|
||||||
return I2C4_REGS;
|
|
||||||
case I2C_5:
|
|
||||||
return I2C5_REGS;
|
|
||||||
case I2C_6:
|
|
||||||
return I2C6_REGS;
|
|
||||||
default:
|
|
||||||
generic_panic();
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load hardware config for I2C4. */
|
|
||||||
void i2c_load_config(volatile tegra_i2c_t *regs) {
|
|
||||||
/* Set MSTR_CONFIG_LOAD, TIMEOUT_CONFIG_LOAD, undocumented bit. */
|
|
||||||
regs->I2C_I2C_CONFIG_LOAD_0 = 0x25;
|
|
||||||
|
|
||||||
/* Wait a bit for master config to be loaded. */
|
|
||||||
for (unsigned int i = 0; i < 20; i++) {
|
|
||||||
udelay(1);
|
|
||||||
if (!(regs->I2C_I2C_CONFIG_LOAD_0 & 1)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reads a register from a device over I2C, writes result to output. */
|
|
||||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
|
||||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
|
||||||
uint32_t val = r;
|
|
||||||
|
|
||||||
/* Write single byte register ID to device. */
|
|
||||||
if (!i2c_write(regs, device, &val, 1)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* Limit output size to 32-bits. */
|
|
||||||
if (dst_size > 4) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i2c_read(regs, device, dst, dst_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Writes a value to a register over I2C. */
|
|
||||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
|
||||||
uint32_t val = r;
|
|
||||||
if (src_size == 0) {
|
|
||||||
return true;
|
|
||||||
} else if (src_size <= 3) {
|
|
||||||
memcpy(((uint8_t *)&val) + 1, src, src_size);
|
|
||||||
return i2c_write(i2c_get_registers_from_id(id), device, &val, src_size + 1);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Writes bytes to device over I2C. */
|
|
||||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size) {
|
|
||||||
if (src_size > 4) {
|
|
||||||
return false;
|
|
||||||
} else if (src_size == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set device for 7-bit write mode. */
|
|
||||||
regs->I2C_I2C_CMD_ADDR0_0 = device << 1;
|
|
||||||
|
|
||||||
/* Load in data to write. */
|
|
||||||
regs->I2C_I2C_CMD_DATA1_0 = read32le(src, 0);
|
|
||||||
|
|
||||||
/* Set config with LENGTH = src_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((src_size << 1) - 2) | 0x2800;
|
|
||||||
|
|
||||||
i2c_load_config(regs);
|
|
||||||
|
|
||||||
/* Config |= SEND; */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
|
|
||||||
|
|
||||||
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
|
||||||
/* Wait until not busy. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return CMD1_STAT == SL1_XFER_SUCCESSFUL. */
|
|
||||||
return (regs->I2C_I2C_STATUS_0 & 0xF) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reads bytes from device over I2C. */
|
|
||||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size) {
|
|
||||||
if (dst_size > 4) {
|
|
||||||
return false;
|
|
||||||
} else if (dst_size == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set device for 7-bit read mode. */
|
|
||||||
regs->I2C_I2C_CMD_ADDR0_0 = (device << 1) | 1;
|
|
||||||
|
|
||||||
/* Set config with LENGTH = dst_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((dst_size << 1) - 2) | 0x2840;
|
|
||||||
|
|
||||||
i2c_load_config(regs);
|
|
||||||
|
|
||||||
/* Config |= SEND; */
|
|
||||||
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
|
|
||||||
|
|
||||||
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
|
||||||
/* Wait until not busy. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure success. */
|
|
||||||
if ((regs->I2C_I2C_STATUS_0 & 0xF) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t val = regs->I2C_I2C_CMD_DATA1_0;
|
|
||||||
memcpy(dst, &val, dst_size);
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUSEE_I2C_H
|
|
||||||
#define FUSEE_I2C_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define I2C1234_BASE 0x7000C000
|
|
||||||
#define I2C56_BASE 0x7000D000
|
|
||||||
|
|
||||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
|
||||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
|
||||||
#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31
|
|
||||||
#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33
|
|
||||||
#define MAX17050_I2C_ADDR 0x36
|
|
||||||
#define MAX77620_PWR_I2C_ADDR 0x3C
|
|
||||||
#define MAX77620_RTC_I2C_ADDR 0x68
|
|
||||||
#define BQ24193_I2C_ADDR 0x6B
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
I2C_1 = 0,
|
|
||||||
I2C_2 = 1,
|
|
||||||
I2C_3 = 2,
|
|
||||||
I2C_4 = 3,
|
|
||||||
I2C_5 = 4,
|
|
||||||
I2C_6 = 5,
|
|
||||||
} I2CDevice;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t I2C_I2C_CNFG_0;
|
|
||||||
uint32_t I2C_I2C_CMD_ADDR0_0;
|
|
||||||
uint32_t I2C_I2C_CMD_ADDR1_0;
|
|
||||||
uint32_t I2C_I2C_CMD_DATA1_0;
|
|
||||||
uint32_t I2C_I2C_CMD_DATA2_0;
|
|
||||||
uint32_t _0x14;
|
|
||||||
uint32_t _0x18;
|
|
||||||
uint32_t I2C_I2C_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_SL_CNFG_0;
|
|
||||||
uint32_t I2C_I2C_SL_RCVD_0;
|
|
||||||
uint32_t I2C_I2C_SL_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_SL_ADDR1_0;
|
|
||||||
uint32_t I2C_I2C_SL_ADDR2_0;
|
|
||||||
uint32_t I2C_I2C_TLOW_SEXT_0;
|
|
||||||
uint32_t _0x38;
|
|
||||||
uint32_t I2C_I2C_SL_DELAY_COUNT_0;
|
|
||||||
uint32_t I2C_I2C_SL_INT_MASK_0;
|
|
||||||
uint32_t I2C_I2C_SL_INT_SOURCE_0;
|
|
||||||
uint32_t I2C_I2C_SL_INT_SET_0;
|
|
||||||
uint32_t _0x4C;
|
|
||||||
uint32_t I2C_I2C_TX_PACKET_FIFO_0;
|
|
||||||
uint32_t I2C_I2C_RX_FIFO_0;
|
|
||||||
uint32_t I2C_PACKET_TRANSFER_STATUS_0;
|
|
||||||
uint32_t I2C_FIFO_CONTROL_0;
|
|
||||||
uint32_t I2C_FIFO_STATUS_0;
|
|
||||||
uint32_t I2C_INTERRUPT_MASK_REGISTER_0;
|
|
||||||
uint32_t I2C_INTERRUPT_STATUS_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_CLK_DIVISOR_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_INTERRUPT_SOURCE_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_INTERRUPT_SET_REGISTER_0;
|
|
||||||
uint32_t I2C_I2C_SLV_TX_PACKET_FIFO_0;
|
|
||||||
uint32_t I2C_I2C_SLV_RX_FIFO_0;
|
|
||||||
uint32_t I2C_I2C_SLV_PACKET_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_BUS_CLEAR_CONFIG_0;
|
|
||||||
uint32_t I2C_I2C_BUS_CLEAR_STATUS_0;
|
|
||||||
uint32_t I2C_I2C_CONFIG_LOAD_0;
|
|
||||||
uint32_t _0x90;
|
|
||||||
uint32_t I2C_I2C_INTERFACE_TIMING_0_0;
|
|
||||||
uint32_t I2C_I2C_INTERFACE_TIMING_1_0;
|
|
||||||
uint32_t I2C_I2C_HS_INTERFACE_TIMING_0_0;
|
|
||||||
uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0;
|
|
||||||
} tegra_i2c_t;
|
|
||||||
|
|
||||||
#define I2C1_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x000))
|
|
||||||
#define I2C2_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x400))
|
|
||||||
#define I2C3_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x500))
|
|
||||||
#define I2C4_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x700))
|
|
||||||
#define I2C5_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x000))
|
|
||||||
#define I2C6_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x100))
|
|
||||||
|
|
||||||
void i2c_config(I2CDevice id);
|
|
||||||
|
|
||||||
void i2c_init(I2CDevice id);
|
|
||||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
|
||||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
|
||||||
|
|
||||||
void i2c_send_pmic_cpu_shutdown_cmd(void);
|
|
||||||
bool i2c_query_ti_charger_bit_7(void);
|
|
||||||
void i2c_clear_ti_charger_bit_7(void);
|
|
||||||
void i2c_set_ti_charger_bit_7(void);
|
|
||||||
|
|
||||||
#endif
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue