ams: revamp target firmware

This commit is contained in:
Michael Scire
2020-05-06 22:29:07 -07:00
parent 85cd2c97a0
commit 8e75a4169d
48 changed files with 863 additions and 693 deletions

View File

@@ -52,7 +52,7 @@ void setup_dram_magic_numbers(void) {
unsigned int target_fw = exosphere_get_target_firmware();
(*(volatile uint32_t *)(0x8005FFFC)) = 0xC0EDBBCC; /* Access test value. */
flush_dcache_range((void *)0x8005FFFC, (void *)0x80060000);
if (ATMOSPHERE_TARGET_FIRMWARE_600 <= target_fw) {
if (ATMOSPHERE_TARGET_FIRMWARE_6_0_0 <= target_fw) {
(*(volatile uint32_t *)(0x8005FF00)) = 0x00000083; /* SKU code. */
(*(volatile uint32_t *)(0x8005FF04)) = 0x00000002;
(*(volatile uint32_t *)(0x8005FF08)) = 0x00000210; /* Tegra210 code. */
@@ -81,7 +81,7 @@ void bootup_misc_mmio(void) {
se_generate_random_key(KEYSLOT_SWITCH_SRKGENKEY, KEYSLOT_SWITCH_RNGKEY);
se_generate_srk(KEYSLOT_SWITCH_SRKGENKEY);
if (!g_has_booted_up && (ATMOSPHERE_TARGET_FIRMWARE_600 > exosphere_get_target_firmware())) {
if (!g_has_booted_up && (ATMOSPHERE_TARGET_FIRMWARE_6_0_0 > exosphere_get_target_firmware())) {
setup_dram_magic_numbers();
}
@@ -116,7 +116,7 @@ void bootup_misc_mmio(void) {
configure_default_carveouts();
/* Mark registers secure world only. */
if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_100) {
if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_1_0_0) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SATA | APB_SSER0_LA;
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 = APB_SSER1_SPI1 | APB_SSER1_SPI2 | APB_SSER1_SPI3 | APB_SSER1_SPI5 | APB_SSER1_SPI6 | APB_SSER1_I2C4 | APB_SSER1_I2C6;
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = 1 << 4 | 1 << 5 | APB_SSER2_DDS; /* bits 4 and 5 are not labeled in 21.1.7.3 */
@@ -133,7 +133,7 @@ void bootup_misc_mmio(void) {
/* Also mark I2C4 secure only, */
sec_disable_1 |= APB_SSER1_I2C4;
}
if (hardware_type != 0 && exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (hardware_type != 0 && exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
/* Starting on 4.x on non-dev units, mark UARTB, UARTC, SPI4, I2C3 secure only. */
sec_disable_1 |= APB_SSER1_UART_B | APB_SSER1_UART_C | APB_SSER1_SPI4 | APB_SSER1_I2C3;
/* Starting on 4.x on non-dev units, mark SDMMC1 secure only. */
@@ -151,7 +151,7 @@ void bootup_misc_mmio(void) {
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_4) = 0xFFFFFFFF;
/* Set SMMU ASID security registers. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
MAKE_MC_REG(MC_SMMU_ASID_SECURITY) = 0xE;
} else {
MAKE_MC_REG(MC_SMMU_ASID_SECURITY) = 0x0;
@@ -164,7 +164,7 @@ void bootup_misc_mmio(void) {
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_6) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_7) = 0;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
}
MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0;
@@ -180,7 +180,7 @@ void bootup_misc_mmio(void) {
/* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */
uint32_t reset_vec;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
reset_vec = TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
} else {
reset_vec = TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
@@ -206,7 +206,7 @@ void bootup_misc_mmio(void) {
intr_set_cpu_mask(INTERRUPT_ID_SECURITY_ENGINE, 8);
intr_set_edge_level(INTERRUPT_ID_SECURITY_ENGINE, 0);
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
intr_set_priority(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
intr_set_group(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
intr_set_enabled(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 1);
@@ -221,14 +221,14 @@ void bootup_misc_mmio(void) {
uart_init(UART_A, 115200);
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);
}
for (unsigned int core = 1; core < NUM_CPU_CORES; core++) {
set_core_is_active(core, false);
}
g_has_booted_up = true;
} else if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
} else if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
/* Disable AHB redirect. */
MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
MAKE_MC_REG(MC_IRAM_TOM) = 0;
@@ -238,7 +238,7 @@ void bootup_misc_mmio(void) {
}
void setup_4x_mmio(void) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
configure_gpu_ucode_carveout();
}
@@ -361,9 +361,9 @@ void identity_unmap_iram_cd_tzram(void) {
}
void secure_additional_devices(void) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 |= APB_SSER0_PMC; /* make PMC secure-only (2.x+) */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 |= APB_SSER1_MC0 | APB_SSER1_MC1 | APB_SSER1_MCB; /* make MC0, MC1, MCB secure-only (4.x+) */
}
}

View File

@@ -13,7 +13,7 @@
* 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 "arm.h"
@@ -26,7 +26,7 @@
#undef MAILBOX_NX_BOOTLOADER_BASE
#undef TIMERS_BASE
#define MAILBOX_NX_BOOTLOADER_BASE(targetfw) (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) ? (MMIO_GET_DEVICE_7X_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX)) : (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX))
#define MAILBOX_NX_BOOTLOADER_BASE(targetfw) (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) ? (MMIO_GET_DEVICE_7X_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX)) : (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX))
#define TIMERS_BASE (MMIO_GET_DEVICE_PA(MMIO_DEVID_TMRs_WDTs))
extern const uint8_t __start_cold[];
@@ -52,11 +52,11 @@ static void mmio_map_all_devices(uintptr_t *mmu_l3_tbl, unsigned int target_firm
static const uintptr_t pas[] = { TUPLE_FOLD_LEFT_0(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
static const bool is_secure[] = { TUPLE_FOLD_LEFT_2(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
static const uintptr_t pas_7x[] = { TUPLE_FOLD_LEFT_0(EVAL(MMIO_DEVID_MAX), _MMAPDEV7X, COMMA) };
for(size_t i = 0, offset = 0; i < MMIO_DEVID_MAX; i++) {
uintptr_t pa = (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) ? pas[i] : pas_7x[i];
uintptr_t pa = (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) ? pas[i] : pas_7x[i];
mmio_map_device(mmu_l3_tbl, MMIO_BASE + offset, pa, sizes[i], is_secure[i]);
offset += sizes[i];
offset += 0x1000;
@@ -92,9 +92,9 @@ static void tzram_map_all_segments(uintptr_t *mmu_l3_tbl, unsigned int target_fi
static const bool is_executable[] = { TUPLE_FOLD_LEFT_3(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
static const uintptr_t offs_5x[] = { TUPLE_FOLD_LEFT_0(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZ5XS, COMMA) };
for(size_t i = 0, offset = 0; i < TZRAM_SEGMENT_ID_MAX; i++) {
uintptr_t off = (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_500) ? offs[i] : offs_5x[i];
uintptr_t off = (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) ? offs[i] : offs_5x[i];
tzram_map_segment(mmu_l3_tbl, TZRAM_SEGMENT_BASE + offset, 0x7C010000ull + off, sizes[i], is_executable[i]);
offset += increments[i];
}
@@ -102,9 +102,9 @@ static void tzram_map_all_segments(uintptr_t *mmu_l3_tbl, unsigned int target_fi
static void configure_ttbls(unsigned int target_firmware) {
uintptr_t *mmu_l1_tbl;
uintptr_t *mmu_l2_tbl;
uintptr_t *mmu_l2_tbl;
uintptr_t *mmu_l3_tbl;
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_500) {
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
@@ -154,12 +154,12 @@ uintptr_t get_coldboot_crt0_temp_stack_address(void) {
}
uintptr_t get_coldboot_crt0_stack_address(void) {
if (exosphere_get_target_firmware_for_init() < ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware_for_init() < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
} else {
return TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
}
}
void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, uintptr_t start_cold) {
@@ -196,7 +196,7 @@ void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, uintptr_t start_cold)
init_dma_controllers(g_exosphere_target_firmware_for_init);
configure_ttbls(g_exosphere_target_firmware_for_init);
if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) {
if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
set_memory_registers_enable_mmu_1x_ttbr0();
} else {
set_memory_registers_enable_mmu_5x_ttbr0();

View File

@@ -203,7 +203,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_BOOTREASON:
/* For some reason, Nintendo removed it on 4.0 */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
*p_outvalue = bootconfig_get_boot_reason();
} else {
result = 2;
@@ -238,7 +238,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_ISQUESTUNIT:
/* Added on 3.0, used to determine whether console is a kiosk unit. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_3_0_0) {
*p_outvalue = (fuse_get_reserved_odm(4) >> 10) & 1;
} else {
result = 2;
@@ -246,7 +246,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_NEWHARDWARETYPE_5X:
/* Added in 5.x, currently hardcoded to 0. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
*p_outvalue = 0;
} else {
result = 2;
@@ -254,7 +254,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_NEWKEYGENERATION_5X:
/* Added in 5.x. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
*p_outvalue = fuse_get_5x_key_generation();
} else {
result = 2;
@@ -262,7 +262,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_PACKAGE2HASH_5X:
/* Added in 5.x. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500 && bootconfig_is_recovery_boot()) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0 && bootconfig_is_recovery_boot()) {
bootconfig_get_package2_hash_for_recovery(p_outvalue);
} else {
result = 2;
@@ -270,11 +270,11 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_EXOSPHERE_VERSION:
/* UNOFFICIAL: Gets information about the current exosphere version. */
*p_outvalue = ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MAJOR & 0xFF) << 32ull) |
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 24ull) |
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 16ull) |
((uint64_t)(exosphere_get_target_firmware() & 0xFF) << 8ull) |
((uint64_t)(mkey_get_revision() & 0xFF) << 0ull);
*p_outvalue = ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MAJOR & 0xFF) << 56ull) |
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 48ull) |
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 40ull) |
((uint64_t)(mkey_get_revision() & 0xFF) << 32ull) |
((uint64_t)(exosphere_get_target_firmware()) << 0ull);
break;
case CONFIGITEM_NEEDS_REBOOT:
/* UNOFFICIAL: The fact that we are executing means we aren't in the process of rebooting. */

View File

@@ -13,7 +13,7 @@
* 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 "arm.h"
@@ -99,8 +99,8 @@ uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
static const uint32_t status_masks[NUM_CPU_CORES] = {0x4000, 0x200, 0x400, 0x800};
static const uint32_t toggle_vals[NUM_CPU_CORES] = {0xE, 0x9, 0xA, 0xB};
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
/* Reset the core */
CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET_0 = (1 << (core + 0x10)) | (1 << core);
}
@@ -133,11 +133,11 @@ uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
}
CPU_ON_SUCCESS:
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
/* Start the core */
CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 = (1 << (core + 0x10)) | (1 << core);
}
return 0;
}

View File

@@ -196,7 +196,7 @@ uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
/* Firmware from versions 1.0.0 to 3.0.2. */
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
if (hardware_type >= 1) {
return (hardware_type > 2) ? 3 : hardware_type - 1;
@@ -205,7 +205,7 @@ uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
} else {
return 3;
}
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { /* Firmware versions from 4.0.0 to 6.2.0. */
static const uint32_t types[] = {0,1,4,3};
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
hardware_type--;
@@ -262,30 +262,39 @@ uint32_t fuse_get_5x_key_generation(void) {
/* Returns the fuse version expected for the firmware. */
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware) {
static const uint8_t expected_versions[ATMOSPHERE_TARGET_FIRMWARE_COUNT+1] = {
[ATMOSPHERE_TARGET_FIRMWARE_100] = 1,
[ATMOSPHERE_TARGET_FIRMWARE_200] = 2,
[ATMOSPHERE_TARGET_FIRMWARE_300] = 3,
/* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */
[ATMOSPHERE_TARGET_FIRMWARE_400] = 5,
[ATMOSPHERE_TARGET_FIRMWARE_500] = 6,
[ATMOSPHERE_TARGET_FIRMWARE_600] = 7,
[ATMOSPHERE_TARGET_FIRMWARE_620] = 8,
[ATMOSPHERE_TARGET_FIRMWARE_700] = 9,
[ATMOSPHERE_TARGET_FIRMWARE_800] = 9,
[ATMOSPHERE_TARGET_FIRMWARE_810] = 10,
[ATMOSPHERE_TARGET_FIRMWARE_900] = 11,
[ATMOSPHERE_TARGET_FIRMWARE_910] = 12,
[ATMOSPHERE_TARGET_FIRMWARE_1000] = 13,
};
if (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_COUNT) {
generic_panic();
if (fuse_get_retail_type() != 0) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
return 13;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_9_1_0) {
return 12;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_9_0_0) {
return 11;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
return 10;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
return 9;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
return 8;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
return 7;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
return 6;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
return 5;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_3_0_2) {
return 4;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_3_0_0) {
return 3;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
return 2;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_1_0_0) {
return 1;
} else {
return 0;
}
} else {
return (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_3_0_0) ? 1 : 0;
}
if (fuse_get_retail_type() != 0)
return expected_versions[target_firmware];
else
return (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_200) ? 1 : 0;
}
/* Check for RCM bug patches. */

View File

@@ -47,7 +47,7 @@ void configure_gpu_ucode_carveout(void) {
carveout->size_big_pages = 2; /* 0x40000 */
carveout->client_access_0 = 0;
carveout->client_access_1 = 0;
carveout->client_access_2 = (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) ? (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR) | BIT(CSR_TSECSRD)) : (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
carveout->client_access_2 = (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) ? (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR) | BIT(CSR_TSECSRD)) : (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
carveout->client_access_3 = 0;
carveout->client_access_4 = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
carveout->client_force_internal_access_0 = 0;
@@ -77,7 +77,7 @@ void configure_default_carveouts(void) {
carveout->config = 0x4000006;
/* Configure Carveout 2 (GPU UCODE) */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
configure_gpu_ucode_carveout();
}
@@ -99,7 +99,7 @@ void configure_default_carveouts(void) {
carveout->config = 0x4401E7E;
/* Configure default Kernel carveouts based on 2.0.0+. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
/* Configure Carveout 4 (KERNEL_BUILTINS) */
configure_kernel_carveout(4, g_saved_carveouts[0].address, g_saved_carveouts[0].size);
@@ -140,11 +140,11 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
carveout->size_big_pages = (uint32_t)(size >> 17);
carveout->client_access_0 = (BIT(CSR_PTCR) | BIT(CSR_DISPLAY0A) | BIT(CSR_DISPLAY0AB) | BIT(CSR_DISPLAY0B) | BIT(CSR_DISPLAY0BB) | BIT(CSR_DISPLAY0C) | BIT(CSR_DISPLAY0CB) | BIT(CSR_AFIR) | BIT(CSR_DISPLAYHC) | BIT(CSR_DISPLAYHCB) | BIT(CSR_HDAR) | BIT(CSR_HOST1XDMAR) | BIT(CSR_HOST1XR) | BIT(CSR_NVENCSRD) | BIT(CSR_PPCSAHBDMAR) | BIT(CSR_PPCSAHBSLVR));
carveout->client_access_1 = (BIT(CSR_MPCORER) | BIT(CSW_NVENCSWR) | BIT(CSW_AFIW) | BIT(CSW_HDAW) | BIT(CSW_HOST1XW) | BIT(CSW_MPCOREW) | BIT(CSW_PPCSAHBDMAW) | BIT(CSW_PPCSAHBSLVW));
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_810) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
carveout->client_access_2 = (BIT(CSR_XUSB_HOSTR) | BIT(CSW_XUSB_HOSTW) | BIT(CSR_XUSB_DEVR) | BIT(CSW_XUSB_DEVW));
carveout->client_access_3 = (BIT(CSR_SDMMCRA) | BIT(CSR_SDMMCRAA) | BIT(CSR_SDMMCRAB) | BIT(CSW_SDMMCWA) | BIT(CSW_SDMMCWAA) | BIT(CSW_SDMMCWAB) | BIT(CSR_VICSRD) | BIT(CSW_VICSWR) | BIT(CSR_DISPLAYD) | BIT(CSR_APER) | BIT(CSW_APEW) | BIT(CSR_NVJPGSRD) | BIT(CSW_NVJPGSWR));
carveout->client_access_4 = (BIT(CSR_SESRD) | BIT(CSW_SESWR));
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_800) {
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_8_0_0) {
carveout->client_access_2 = (BIT(CSR_XUSB_HOSTR) | BIT(CSW_XUSB_HOSTW) | BIT(CSR_XUSB_DEVR) | BIT(CSW_XUSB_DEVW));
carveout->client_access_3 = (BIT(CSR_SDMMCRA) | BIT(CSR_SDMMCRAA) | BIT(CSR_SDMMCRAB) | BIT(CSW_SDMMCWA) | BIT(CSW_SDMMCWAA) | BIT(CSW_SDMMCWAB) | BIT(CSR_VICSRD) | BIT(CSW_VICSWR) | BIT(CSR_DISPLAYD) | BIT(CSR_NVDECSRD) | BIT(CSW_NVDECSWR) | BIT(CSR_APER) | BIT(CSW_APEW) | BIT(CSR_NVJPGSRD) | BIT(CSW_NVJPGSWR));
carveout->client_access_4 = (BIT(CSR_SESRD) | BIT(CSW_SESWR) | BIT(CSR_TSECSRDB) | BIT(CSW_TSECSWRB));
@@ -153,10 +153,10 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
carveout->client_access_3 = (BIT(CSR_SDMMCRA) | BIT(CSR_SDMMCRAA) | BIT(CSR_SDMMCRAB) | BIT(CSW_SDMMCWA) | BIT(CSW_SDMMCWAA) | BIT(CSW_SDMMCWAB) | BIT(CSR_VICSRD) | BIT(CSW_VICSWR) | BIT(CSR_DISPLAYD) | BIT(CSR_NVDECSRD) | BIT(CSW_NVDECSWR) | BIT(CSR_APER) | BIT(CSW_APEW) | BIT(CSR_NVJPGSRD) | BIT(CSW_NVJPGSWR));
carveout->client_access_4 = (BIT(CSR_SESRD) | BIT(CSW_SESWR));
}
carveout->client_force_internal_access_0 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) && (carveout_id == 4)) ? BIT(CSR_AVPCARM7R) : 0;
carveout->client_force_internal_access_1 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) && (carveout_id == 4)) ? BIT(CSW_AVPCARM7W) : 0;
carveout->client_force_internal_access_0 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) && (carveout_id == 4)) ? BIT(CSR_AVPCARM7R) : 0;
carveout->client_force_internal_access_1 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) && (carveout_id == 4)) ? BIT(CSW_AVPCARM7W) : 0;
carveout->client_force_internal_access_2 = 0;
carveout->client_force_internal_access_3 = 0;
carveout->client_force_internal_access_4 = 0;
carveout->config = (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_800) ? 0x4CB : 0x8B;
carveout->config = (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_8_0_0) ? 0x4CB : 0x8B;
}

View File

@@ -82,7 +82,7 @@ static void derive_new_device_keys(unsigned int keygen_keyslot) {
break;
} else if (relative_revision == mkey_get_revision()) {
/* On 7.0.0, sept will have derived this key for us already. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_700) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
decrypt_data_into_keyslot(KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
}
} else {
@@ -133,25 +133,15 @@ static void setup_se(void) {
mkey_detect_revision();
/* Derive new device keys. */
switch (exosphere_get_target_firmware()) {
case ATMOSPHERE_TARGET_FIRMWARE_100:
case ATMOSPHERE_TARGET_FIRMWARE_200:
case ATMOSPHERE_TARGET_FIRMWARE_300:
break;
case ATMOSPHERE_TARGET_FIRMWARE_400:
derive_new_device_keys(KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY);
break;
case ATMOSPHERE_TARGET_FIRMWARE_500:
case ATMOSPHERE_TARGET_FIRMWARE_600:
case ATMOSPHERE_TARGET_FIRMWARE_620:
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
{
const uint32_t target_fw = exosphere_get_target_firmware();
if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
break;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
derive_new_device_keys(KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY);
} else {
/* No new keys to derive */
}
}
se_initialize_rng(KEYSLOT_SWITCH_DEVICEKEY);
@@ -176,7 +166,7 @@ static void setup_boot_config(void) {
bootconfig_clear();
} else {
void *bootconfig_ptr = NX_BOOTLOADER_BOOTCONFIG_POINTER;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
bootconfig_ptr = NX_BOOTLOADER_BOOTCONFIG_POINTER_6X;
}
flush_dcache_range((uint8_t *)bootconfig_ptr, (uint8_t *)bootconfig_ptr + sizeof(bootconfig_t));
@@ -447,30 +437,20 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke
static void copy_warmboot_bin_to_dram() {
uint8_t *warmboot_src;
switch (exosphere_get_target_firmware()) {
case ATMOSPHERE_TARGET_FIRMWARE_100:
case ATMOSPHERE_TARGET_FIRMWARE_200:
case ATMOSPHERE_TARGET_FIRMWARE_300:
default:
generic_panic();
break;
case ATMOSPHERE_TARGET_FIRMWARE_400:
case ATMOSPHERE_TARGET_FIRMWARE_500:
warmboot_src = (uint8_t *)0x4003B000;
break;
case ATMOSPHERE_TARGET_FIRMWARE_600:
case ATMOSPHERE_TARGET_FIRMWARE_620:
warmboot_src = (uint8_t *)0x4003D800;
break;
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
{
const uint32_t target_fw = exosphere_get_target_firmware();
if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
warmboot_src = (uint8_t *)0x4003E000;
break;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
warmboot_src = (uint8_t *)0x4003D800;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
warmboot_src = (uint8_t *)0x4003B000;
} else {
return;
}
}
uint8_t *warmboot_dst = (uint8_t *)0x8000D000;
const size_t warmboot_size = 0x2000;
@@ -522,40 +502,31 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
setup_se();
/* Perform initial PMC register writes, if relevant. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
MAKE_REG32(PMC_BASE + 0x054) = 0x8000D000;
MAKE_REG32(PMC_BASE + 0x0A0) &= 0xFFF3FFFF;
MAKE_REG32(PMC_BASE + 0x818) &= 0xFFFFFFFE;
MAKE_REG32(PMC_BASE + 0x334) |= 0x10;
switch (exosphere_get_target_firmware()) {
case ATMOSPHERE_TARGET_FIRMWARE_400:
MAKE_REG32(PMC_BASE + 0x360) = 0x105;
break;
case ATMOSPHERE_TARGET_FIRMWARE_500:
MAKE_REG32(PMC_BASE + 0x360) = 6;
break;
case ATMOSPHERE_TARGET_FIRMWARE_600:
MAKE_REG32(PMC_BASE + 0x360) = 0x87;
break;
case ATMOSPHERE_TARGET_FIRMWARE_620:
MAKE_REG32(PMC_BASE + 0x360) = 0xA8;
break;
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
MAKE_REG32(PMC_BASE + 0x360) = 0x129;
break;
case ATMOSPHERE_TARGET_FIRMWARE_810:
MAKE_REG32(PMC_BASE + 0x360) = 0x14A;
break;
case ATMOSPHERE_TARGET_FIRMWARE_900:
MAKE_REG32(PMC_BASE + 0x360) = 0x16B;
break;
case ATMOSPHERE_TARGET_FIRMWARE_910:
MAKE_REG32(PMC_BASE + 0x360) = 0x18C;
break;
case ATMOSPHERE_TARGET_FIRMWARE_1000:
MAKE_REG32(PMC_BASE + 0x360) = 0x1AD;
break;
const uint32_t target_fw = exosphere_get_target_firmware();
if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x105;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_9_1_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x18C;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_9_0_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x16B;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x14A;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x129;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x0A8;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x087;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x006;
} else if (target_fw >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
MAKE_REG32(PMC_BASE + 0x360) = 0x105;
}
}
@@ -587,7 +558,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
setup_boot_config();
/* Set sysctr0 registers based on bootconfig. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
uint64_t sysctr0_val = bootconfig_get_value_for_sysctr0();
MAKE_SYSCTR0_REG(0x8) = (uint32_t)((sysctr0_val >> 0) & 0xFFFFFFFFULL);
MAKE_SYSCTR0_REG(0xC) = (uint32_t)((sysctr0_val >> 32) & 0xFFFFFFFFULL);
@@ -595,10 +566,10 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
}
/* Synchronize with NX BOOTLOADER. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X);
copy_warmboot_bin_to_dram();
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
setup_dram_magic_numbers();
}
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_LOADED_PACKAGE2_4X);
@@ -651,7 +622,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
}
/* Synchronize with NX BOOTLOADER. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_FINISHED_4X);
setup_4x_mmio();
} else {

View File

@@ -26,7 +26,7 @@
/* Physaddr 0x40002EF8 */
static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_NXBOOTLOADER_MAILBOX) + ((targetfw >= ATMOSPHERE_TARGET_FIRMWARE_700) ? (0x000ull) : (0xE00ull));
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_NXBOOTLOADER_MAILBOX) + ((targetfw >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) ? (0x000ull) : (0xE00ull));
}
#define MAILBOX_NX_BOOTLOADER_BASE(targetfw) (get_nx_bootloader_mailbox_base(targetfw))

View File

@@ -90,14 +90,14 @@ static void mitigate_jamais_vu(void) {
}
/* For debugging, make this check always pass. */
if ((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3)) {
if ((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_4_0_0 || (get_debug_authentication_status() & 3) == 3)) {
FLOW_CTLR_HALT_COP_EVENTS_0 = 0x50000000;
} else {
FLOW_CTLR_HALT_COP_EVENTS_0 = 0x40000000;
}
/* Jamais Vu mitigation #2: Ensure the BPMP is halted. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_4_0_0 || (get_debug_authentication_status() & 3) == 3) {
/* BPMP should just be plainly halted, in debugging conditions. */
if (FLOW_CTLR_HALT_COP_EVENTS_0 != 0x50000000) {
generic_panic();
@@ -167,7 +167,7 @@ static void save_tzram_state(void) {
uint8_t *tzram_encryption_dst = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM));
uint8_t *tzram_encryption_src = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM));
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
tzram_encryption_src += 0x2000ull;
}
uint8_t *tzram_store_address = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_TZRAM));
@@ -204,7 +204,7 @@ static void save_tzram_state(void) {
APBDEV_PMC_SEC_DISABLE8_0 = 0x550000;
/* Perform pre-2.0.0 PMC writes. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_200) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
/* TODO: Give these writes appropriate defines in pmc.h */
/* Save Encrypted context location + lock scratch register. */
@@ -272,7 +272,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
notify_pmic_shutdown();
/* Validate that the shutdown has correct context. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
mitigate_jamais_vu();
}
@@ -280,7 +280,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
configure_pmc_for_deep_powerdown();
/* Ensure that BPMP SC7 firmware is active. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
setup_bpmp_sc7_firmware();
}
@@ -294,7 +294,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
/* Ensure that other cores are already asleep. */
if (!(APBDEV_PMC_PWRGATE_STATUS_0 & 0xE00)) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
call_with_stack_pointer(get_smc_core012_stack_address(), save_se_and_power_down_cpu);
} else {
save_se_and_power_down_cpu();

View File

@@ -13,7 +13,7 @@
* 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 <string.h>
@@ -37,7 +37,7 @@ static const uint8_t g_seal_key_sources[CRYPTOUSECASE_MAX_5X][0x10] = {
};
bool usecase_is_invalid(unsigned int usecase) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
return usecase >= CRYPTOUSECASE_MAX_5X;
} else {
return usecase >= CRYPTOUSECASE_MAX;
@@ -59,7 +59,7 @@ void seal_titlekey(void *dst, size_t dst_size, const void *src, size_t src_size)
if (dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
seal_key_internal(dst, src, g_titlekey_seal_key_source);
}
@@ -68,7 +68,7 @@ void unseal_titlekey(unsigned int keyslot, const void *src, size_t src_size) {
if (src_size != 0x10) {
generic_panic();
}
unseal_key_internal(keyslot, src, g_titlekey_seal_key_source);
}
@@ -77,8 +77,8 @@ void seal_key(void *dst, size_t dst_size, const void *src, size_t src_size, unsi
if (usecase_is_invalid(usecase) || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
seal_key_internal(dst, src, g_seal_key_sources[usecase]);
}
@@ -86,6 +86,6 @@ void unseal_key(unsigned int keyslot, const void *src, size_t src_size, unsigned
if (usecase_is_invalid(usecase) || src_size != 0x10) {
generic_panic();
}
unseal_key_internal(keyslot, src, g_seal_key_sources[usecase]);
}

View File

@@ -169,36 +169,23 @@ void set_suspend_for_debug(void) {
}
void set_version_specific_smcs(void) {
switch (exosphere_get_target_firmware()) {
case ATMOSPHERE_TARGET_FIRMWARE_100:
/* 1.0.0 doesn't have ConfigureCarveout or ReadWriteRegister. */
g_smc_priv_table[7].handler = NULL;
g_smc_priv_table[8].handler = NULL;
/* 1.0.0 doesn't have UnwrapAesWrappedTitlekey. */
g_smc_user_table[0x12].handler = NULL;
break;
case ATMOSPHERE_TARGET_FIRMWARE_200:
case ATMOSPHERE_TARGET_FIRMWARE_300:
case ATMOSPHERE_TARGET_FIRMWARE_400:
/* Do nothing. */
break;
case ATMOSPHERE_TARGET_FIRMWARE_500:
case ATMOSPHERE_TARGET_FIRMWARE_600:
case ATMOSPHERE_TARGET_FIRMWARE_620:
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
/* No more LoadSecureExpModKey. */
g_smc_user_table[0xE].handler = NULL;
g_smc_user_table[0xC].id = 0xC300D60C;
g_smc_user_table[0xC].handler = smc_encrypt_rsa_key_for_import;
g_smc_user_table[0xD].handler = smc_decrypt_or_import_rsa_key;
break;
default:
panic_predefined(0xA);
const uint32_t target_firmware = exosphere_get_target_firmware();
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
/* No more LoadSecureExpModKey. */
g_smc_user_table[0xE].handler = NULL;
g_smc_user_table[0xC].id = 0xC300D60C;
g_smc_user_table[0xC].handler = smc_encrypt_rsa_key_for_import;
g_smc_user_table[0xD].handler = smc_decrypt_or_import_rsa_key;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_2_0_0) {
/* Nothing to do. */
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_1_0_0) {
/* 1.0.0 doesn't have ConfigureCarveout or ReadWriteRegister. */
g_smc_priv_table[7].handler = NULL;
g_smc_priv_table[8].handler = NULL;
/* 1.0.0 doesn't have UnwrapAesWrappedTitlekey. */
g_smc_user_table[0x12].handler = NULL;
} else {
panic_predefined(0xA);
}
}
@@ -306,7 +293,7 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
#endif
/* Call function. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_800 ||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_8_0_0 ||
(g_smc_tables[handler_id].handlers[smc_id].blacklist_mask & g_smc_blacklist_mask) == 0) {
args->X[0] = smc_handler(args);
} else {
@@ -636,7 +623,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
return 2;
}
} else {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
static const uint8_t mc_whitelist_5x[0xD00/(sizeof(uint32_t) * 8)] = {
0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -687,7 +674,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
break;
}
}
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
if (MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address && address < MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) + 0xD00) {
/* Memory Controller RW supported only on 4.0.0+ */
static const uint8_t mc_whitelist[0x68] = {
@@ -730,7 +717,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
/* Return old value. */
args->X[1] = old_value;
return 0;
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400 && (address == 0x7001923C || address == 0x70019298)) {
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0 && (address == 0x7001923C || address == 0x70019298)) {
/* These addresses are not allowed by the whitelist. */
/* They correspond to SMMU DISABLE for the BPMP, and for APB-DMA. */
/* However, smcReadWriteRegister returns 0 for these addresses despite not actually performing the write. */
@@ -759,7 +746,7 @@ uint32_t smc_configure_carveout(smc_args_t *args) {
}
/* Configuration is one-shot, and cannot be done multiple times. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_300) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_3_0_0) {
if (g_configured_carveouts[carveout_id]) {
return 2;
}

View File

@@ -122,23 +122,10 @@ static void validate_rsa_result(unsigned int which) {
}
static bool is_user_keyslot_valid(unsigned int keyslot) {
switch (exosphere_get_target_firmware()) {
case ATMOSPHERE_TARGET_FIRMWARE_100:
case ATMOSPHERE_TARGET_FIRMWARE_200:
case ATMOSPHERE_TARGET_FIRMWARE_300:
case ATMOSPHERE_TARGET_FIRMWARE_400:
case ATMOSPHERE_TARGET_FIRMWARE_500:
return keyslot <= 3;
case ATMOSPHERE_TARGET_FIRMWARE_600:
case ATMOSPHERE_TARGET_FIRMWARE_620:
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
default:
return keyslot <= 5;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
return keyslot <= 5;
} else {
return keyslot <= 3;
}
}
@@ -262,7 +249,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
uint8_t mask_id = (uint8_t)((packed_options >> 1) & 3);
/* Switches the output based on how it will be used. */
uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500 ? 7 : 3));
uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0 ? 7 : 3));
/* Switched the output based on whether it should be console unique. */
bool is_personalized = (int)(packed_options & 1);
@@ -270,7 +257,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
bool is_recovery_boot = configitem_is_recovery_boot();
/* 5.0.0+ Bounds checking. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
if (is_personalized) {
if (master_key_rev >= MASTERKEY_REVISION_MAX || (MASTERKEY_REVISION_300 <= master_key_rev && master_key_rev < MASTERKEY_REVISION_400_410)) {
return 2;
@@ -324,9 +311,9 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
unsigned int keyslot;
if (is_personalized) {
/* Behavior changed in 4.0.0, and in 5.0.0. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
keyslot = devkey_get_keyslot(master_key_rev);
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
if (master_key_rev >= 1) {
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
} else {
@@ -399,7 +386,7 @@ uint32_t user_crypt_aes(smc_args_t *args) {
uint32_t keyslot = args->X[1] & 3;
uint32_t mode = (args->X[1] >> 4) & 3;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
keyslot = args->X[1] & 7;
}
@@ -415,7 +402,7 @@ uint32_t user_crypt_aes(smc_args_t *args) {
return 2;
}
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
/* Disallow dma lists outside of safe range. */
if (in_ll_paddr - 0x80000000 >= 0x3FF7F5) {
return 2;
@@ -463,7 +450,7 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
if (master_key_rev > 0) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
master_key_rev = 0;
}
@@ -479,9 +466,9 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
unsigned int keyslot;
/* Behavior changed in 5.0.0. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
keyslot = devkey_get_keyslot(master_key_rev);
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
if (master_key_rev >= 1) {
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
} else {
@@ -560,7 +547,7 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -609,7 +596,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -667,7 +654,7 @@ uint32_t user_load_secure_exp_mod_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -723,7 +710,7 @@ uint32_t user_secure_exp_mod(smc_args_t *args) {
void *user_modulus = (void *)args->X[2];
unsigned int exponent_id = 1;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
switch (args->X[3]) {
case 0:
exponent_id = 1;
@@ -753,7 +740,7 @@ uint32_t user_secure_exp_mod(smc_args_t *args) {
set_exp_mod_result(3);
/* Hardcode RSA keyslot 0. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_1000) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
set_rsa_keyslot(0, modulus, 0x100, g_imported_exponents[exponent_id], 0x100);
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
} else if (load_imported_rsa_keypair(0, exponent_id)) {
@@ -780,7 +767,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
unsigned int option = (unsigned int)args->X[7];
unsigned int master_key_rev;
unsigned int titlekey_type;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
master_key_rev = option & 0x3F;
titlekey_type = (option >> 6) & 1;
} else {
@@ -792,7 +779,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_3_0_0) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
@@ -857,7 +844,7 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) {
if (master_key_rev > 0) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_3_0_0) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
@@ -953,7 +940,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function only exists in 5.x+. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -1019,7 +1006,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
}
/* Modulus import isn't implemented on < 10.0.0. */
import_modulus &= (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_1000);
import_modulus &= (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0);
/* Import the key. */
import_rsa_exponent(exponent_id, user_data, 0x100);

View File

@@ -40,7 +40,7 @@ void tkey_set_master_key_rev(unsigned int master_key_rev) {
}
static void tkey_validate_type(unsigned int type) {
if (type > TITLEKEY_TYPE_MAX || (type > 0 && exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_600)) {
if (type > TITLEKEY_TYPE_MAX || (type > 0 && exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_6_0_0)) {
generic_panic();
}
}

View File

@@ -25,7 +25,7 @@
#undef MC_BASE
#define MC_BASE (MMIO_GET_DEVICE_PA(MMIO_DEVID_MC))
#define WARMBOOT_GET_TZRAM_SEGMENT_PA(x) ((g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) \
#define WARMBOOT_GET_TZRAM_SEGMENT_PA(x) ((g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) \
? TZRAM_GET_SEGMENT_PA(x) : TZRAM_GET_SEGMENT_5X_PA(x))
/* start.s */
@@ -53,7 +53,7 @@ void warmboot_crt0_critical_section_enter(volatile critical_section_t *critical_
}
void init_dma_controllers(unsigned int target_firmware) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
/* Set some unknown registers in HOST1X. */
MAKE_REG32(0x500038F8) &= 0xFFFFFFFE;
MAKE_REG32(0x50003300) = 0;
@@ -213,7 +213,7 @@ void warmboot_init(void) {
/*identity_remap_tzram();*/
/* Nintendo pointlessly fully invalidate the TLB & invalidate the data cache on the modified ranges here */
if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) {
if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
set_memory_registers_enable_mmu_1x_ttbr0();
} else {
set_memory_registers_enable_mmu_5x_ttbr0();

View File

@@ -13,7 +13,7 @@
* 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 "utils.h"
#include "mmu.h"
#include "memory_map.h"
@@ -53,7 +53,7 @@ void __attribute__((noreturn)) warmboot_main(void) {
- warmboot (core 3)
- cpu_on
*/
if (is_core_active(get_core_id())) {
panic(0xF7F00009); /* invalid CPU context */
}
@@ -70,7 +70,7 @@ void __attribute__((noreturn)) warmboot_main(void) {
clkrst_reboot(CARDEVICE_UARTA);
uart_init(UART_A, 115200);
}
if (!configitem_is_retail()) {
uart_send(UART_A, "OHAYO", 6);
uart_wait_idle(UART_A, UART_VENDOR_STATE_TX_IDLE);
@@ -87,15 +87,15 @@ void __attribute__((noreturn)) warmboot_main(void) {
/* Make PMC (2.x+), MC (4.x+) registers secure-only */
secure_additional_devices();
if ((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) ||
((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_800) && configitem_get_hardware_type() == 0) ||
if ((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) ||
((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_8_0_0) && configitem_get_hardware_type() == 0) ||
(configitem_is_hiz_mode_enabled())) {
warmboot_configure_hiz_mode();
}
clear_user_smc_in_progress();
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
setup_4x_mmio();
}
}