diff --git a/bdk/display/di.c b/bdk/display/di.c index 26e905a..1c79823 100644 --- a/bdk/display/di.c +++ b/bdk/display/di.c @@ -507,6 +507,11 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) PWM(PWM_CONTROLLER_PWM_CSR_0) = 0; } +u32 display_get_backlight_brightness() +{ + return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF); +} + static void _display_panel_and_hw_end(bool no_panel_deinit) { if (no_panel_deinit) diff --git a/bdk/display/di.h b/bdk/display/di.h index 5db7b67..7682bdb 100644 --- a/bdk/display/di.h +++ b/bdk/display/di.h @@ -650,8 +650,9 @@ * [10] 81 [26]: JDI LPM062M326A * [10] 96 [09]: JDI LAM062M109A * [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1) - * [20] 95 [0F]: InnoLux P062CCA-AZ2 - * [20] 96 [0F]: InnoLux P062CCA-AZ3 + * [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1) + * [20] 96 [0F]: InnoLux P062CCA-AZ3 [UNCONFIRMED MODEL REV] + * [20] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV] * [30] 94 [0F]: AUO A062TAN01 (59.06A33.001) * [30] 95 [0F]: AUO A062TAN02 (59.06A33.002) * @@ -706,6 +707,7 @@ void display_color_screen(u32 color); /*! Switches screen backlight ON/OFF. */ void display_backlight(bool enable); void display_backlight_brightness(u32 brightness, u32 step_delay); +u32 display_get_backlight_brightness(); /*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */ u32 *display_init_framebuffer_pitch(); diff --git a/bdk/ianos/ianos.c b/bdk/ianos/ianos.c index 5eca1b6..8deca45 100644 --- a/bdk/ianos/ianos.c +++ b/bdk/ianos/ianos.c @@ -21,6 +21,7 @@ #include "elfload/elfload.h" #include #include +#include #include #include @@ -43,6 +44,10 @@ static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig) bdkParameters->memset = (memset_t)&memset; bdkParameters->sharedHeap = &_heap; + // Extra functions. + bdkParameters->extension_magic = IANOS_EXT0; + bdkParameters->reg_voltage_set = (reg_voltage_set_t)&max7762x_regulator_set_voltage; + entrypoint(moduleConfig, bdkParameters); } diff --git a/bdk/input/joycon.c b/bdk/input/joycon.c index 9da1071..825e347 100644 --- a/bdk/input/joycon.c +++ b/bdk/input/joycon.c @@ -1,7 +1,7 @@ /* * Joy-Con UART driver for Nintendo Switch * - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -463,7 +463,7 @@ static void jc_rcv_pkt(joycon_ctxt_t *jc) // Check if device stopped sending data. u32 uart_irq = uart_get_IIR(jc->uart); - if ((uart_irq & 0x8) != 0x8) + if (uart_irq != UART_IIR_REDI) return; u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100); @@ -694,9 +694,15 @@ retry: void jc_deinit() { + // Disable power. + jc_power_supply(UART_B, false); + jc_power_supply(UART_C, false); + + // Turn off Joy-Con detect. gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); + // Send sleep command. u8 data = HCI_STATE_SLEEP; if (jc_r.connected && !(jc_r.type & JC_ID_HORI)) @@ -710,8 +716,9 @@ void jc_deinit() jc_rcv_pkt(&jc_l); } - jc_power_supply(UART_B, false); - jc_power_supply(UART_C, false); + // Disable UART B and C clocks. + clock_disable_uart(UART_B); + clock_disable_uart(UART_C); } static void jc_init_conn(joycon_ctxt_t *jc) @@ -878,14 +885,14 @@ void jc_init_hw() pinmux_config_uart(UART_C); // Ease the stress to APB. - bpmp_clk_rate_set(BPMP_CLK_NORMAL); + bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); // Enable UART B and C clocks. clock_enable_uart(UART_B); clock_enable_uart(UART_C); // Restore OC. - bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST); + bpmp_clk_rate_set(prev_fid); // Turn Joy-Con detect on. gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); diff --git a/bdk/input/touch.c b/bdk/input/touch.c index 11efed0..17d31b3 100644 --- a/bdk/input/touch.c +++ b/bdk/input/touch.c @@ -206,6 +206,7 @@ touch_panel_info_t *touch_get_panel_vendor() { u8 buf[5] = {0}; u8 cmd = STMFTS_VENDOR_GPIO_STATE; + static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""}; if (touch_command(STMFTS_VENDOR, &cmd, 1)) return NULL; @@ -220,13 +221,20 @@ touch_panel_info_t *touch_get_panel_vendor() return panel; } - return NULL; + // Touch panel not found, return current gpios. + panel_info.gpio0 = buf[0]; + panel_info.gpio1 = buf[1]; + panel_info.gpio2 = buf[2]; + + return &panel_info; } int touch_get_fw_info(touch_fw_info_t *fw) { u8 buf[8] = {0}; + memset(fw, 0, sizeof(touch_fw_info_t)); + // Get fw address info. u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 }; int res = touch_read_reg(cmd, 3, buf, 3); @@ -318,7 +326,7 @@ int touch_get_fb_info(u8 *buf) int res = 0; - for (u32 i = 0; i < 0x10000; i+=4) + for (u32 i = 0; i < 0x10000; i += 4) { if (!res) { @@ -392,11 +400,11 @@ static int touch_init() int touch_power_on() { - // Enable LDO6 for touchscreen VDD/AVDD supply. + // Enable LDO6 for touchscreen AVDD supply. max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000); max7762x_regulator_enable(REGULATOR_LDO6, true); - // Configure touchscreen GPIO. + // Configure touchscreen VDD GPIO. PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1; gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO); gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE); @@ -410,7 +418,7 @@ int touch_power_on() // Configure Touscreen and GCAsic shared GPIO. PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2; PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2; - gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); + gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect. // Initialize I2C3. pinmux_config_i2c(I2C_3); diff --git a/bdk/libs/compr/lz4.c b/bdk/libs/compr/lz4.c index ddea3d8..4f6f425 100644 --- a/bdk/libs/compr/lz4.c +++ b/bdk/libs/compr/lz4.c @@ -839,10 +839,12 @@ int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { int result; - LZ4_stream_t ctx; - LZ4_stream_t* const ctxPtr = &ctx; + LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); + LZ4_stream_t* const ctxPtr = ctx; result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); + FREEMEM(ctx); + return result; } @@ -857,13 +859,18 @@ int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxO /* strangely enough, gcc generates faster code when this function is uncommented, even if unused */ int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { - LZ4_stream_t ctx; - LZ4_resetStream(&ctx); + int result; + LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); + LZ4_resetStream(ctx); if (inputSize < LZ4_64Klimit) - return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); else - return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration); + result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration); + + FREEMEM(ctx); + + return result; } @@ -1045,11 +1052,13 @@ static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) { - LZ4_stream_t ctxBody; - LZ4_stream_t* ctx = &ctxBody; + LZ4_stream_t* ctxBody = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));; + LZ4_stream_t* ctx = ctxBody; int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); + FREEMEM(ctxBody); + return result; } diff --git a/bdk/libs/fatfs/diskio.h b/bdk/libs/fatfs/diskio.h index 6959fb4..b5299c6 100644 --- a/bdk/libs/fatfs/diskio.h +++ b/bdk/libs/fatfs/diskio.h @@ -27,7 +27,8 @@ typedef enum { DRIVE_SD = 0, DRIVE_RAM = 1, DRIVE_EMMC = 2, - DRIVE_BIS = 3 + DRIVE_BIS = 3, + DRIVE_EMU = 4 } DDRIVE; @@ -59,6 +60,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff); #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ +#define SET_SECTOR_OFFSET 5 /* Set media logical offset */ /* Generic command (Not used by FatFs) */ #define CTRL_POWER 5 /* Get/Set power status */ diff --git a/bdk/libs/lv_conf.h b/bdk/libs/lv_conf.h index dcc437d..7af36a4 100644 --- a/bdk/libs/lv_conf.h +++ b/bdk/libs/lv_conf.h @@ -155,7 +155,7 @@ /*Log settings*/ -#ifdef DEBUG_UART_PORT +#ifdef DEBUG_UART_LV_LOG # define USE_LV_LOG 1 /*Enable/disable the log module*/ #else # define USE_LV_LOG 0 /*Enable/disable the log module*/ diff --git a/bdk/libs/lvgl/lv_misc/lv_log.c b/bdk/libs/lvgl/lv_misc/lv_log.c index d2db0c7..9cd3d49 100644 --- a/bdk/libs/lvgl/lv_misc/lv_log.c +++ b/bdk/libs/lvgl/lv_misc/lv_log.c @@ -63,7 +63,7 @@ void lv_log_add(lv_log_level_t level, const char * file, int line, const char * if(level >= LV_LOG_LEVEL) { -#if LV_LOG_PRINTF +#if LV_LOG_PRINTF && defined(DEBUG_UART_PORT) static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error"}; char *log = (char *)malloc(0x1000); s_printf(log, "%s: %s \t(%s #%d)\r\n", lvl_prefix[level], dsc, file, line); diff --git a/bdk/mem/minerva.c b/bdk/mem/minerva.c index 6136d73..2560dfe 100644 --- a/bdk/mem/minerva.c +++ b/bdk/mem/minerva.c @@ -104,21 +104,21 @@ u32 minerva_init() } mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz; - mtc_cfg->rate_to = 204000; + mtc_cfg->rate_to = FREQ_204; mtc_cfg->train_mode = OP_TRAIN; minerva_cfg(mtc_cfg, NULL); - mtc_cfg->rate_to = 800000; + mtc_cfg->rate_to = FREQ_800; minerva_cfg(mtc_cfg, NULL); - mtc_cfg->rate_to = 1600000; + mtc_cfg->rate_to = FREQ_1600; minerva_cfg(mtc_cfg, NULL); // FSP WAR. mtc_cfg->train_mode = OP_SWITCH; - mtc_cfg->rate_to = 800000; + mtc_cfg->rate_to = FREQ_800; minerva_cfg(mtc_cfg, NULL); // Switch to max. - mtc_cfg->rate_to = 1600000; + mtc_cfg->rate_to = FREQ_1600; minerva_cfg(mtc_cfg, NULL); return 0; @@ -139,6 +139,23 @@ void minerva_change_freq(minerva_freq_t freq) } } +void minerva_prep_boot_freq() +{ + if (!minerva_cfg) + return; + + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; + + // Check if there's RAM OC. If not exit. + if (mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600) + return; + + // FSP WAR. + minerva_change_freq(FREQ_204); + // Scale down to 800 MHz boot freq. + minerva_change_freq(FREQ_800); +} + void minerva_periodic_training() { if (!minerva_cfg) diff --git a/bdk/mem/minerva.h b/bdk/mem/minerva.h index ed80b95..51cb215 100644 --- a/bdk/mem/minerva.h +++ b/bdk/mem/minerva.h @@ -60,6 +60,7 @@ typedef enum extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *); u32 minerva_init(); void minerva_change_freq(minerva_freq_t freq); +void minerva_prep_boot_freq(); void minerva_periodic_training(); #endif diff --git a/bdk/memory_map.h b/bdk/memory_map.h index 1db19f1..70f1354 100644 --- a/bdk/memory_map.h +++ b/bdk/memory_map.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -19,8 +19,8 @@ //#define IPL_STACK_TOP 0x4003FF00 /* --- BIT/BCT: 0x40000000 - 0x40003000 --- */ -/* --- IPL: 0x40003000 - 0x40028000 --- */ -#define LDR_LOAD_ADDR 0x40003000 +/* --- IPL: 0x40008000 - 0x40028000 --- */ +#define LDR_LOAD_ADDR 0x40007000 #define IPL_LOAD_ADDR 0x40008000 #define IPL_SZ_MAX 0x20000 // 128KB. @@ -49,8 +49,14 @@ // Virtual disk / Chainloader buffers. #define RAM_DISK_ADDR 0xA4000000 -#define NX_BIS_CACHE_ADDR RAM_DISK_ADDR #define RAM_DISK_SZ 0x41000000 // 1040MB. +#define RAM_DISK2_SZ 0x21000000 // 528MB. + +// NX BIS driver sector cache. +#define NX_BIS_CACHE_ADDR 0xC5000000 +#define NX_BIS_CACHE_SZ 0x10020000 // 256MB. +#define NX_BIS_LOOKUP_ADDR 0xD6000000 +#define NX_BIS_LOOKUP_SZ 0xF000000 // 240MB. // L4T Kernel Panic Storage (PSTORE). #define PSTORE_ADDR 0xB0000000 @@ -91,15 +97,10 @@ #define NYX_FB_SZ 0x384000 // 1280 x 720 x 4. #define DRAM_MEM_HOLE_ADR 0xF6A00000 -#define NX_BIS_LOOKUP_ADR DRAM_MEM_HOLE_ADR #define DRAM_MEM_HOLE_SZ 0x8140000 /* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */ #define DRAM_START2 0xFEB40000 -// NX BIS driver sector cache. -// #define NX_BIS_CACHE_ADDR 0xFEE00000 -// #define NX_BIS_CACHE_SZ 0x100000 - // USB buffers. #define USBD_ADDR 0xFEF00000 #define USB_DESCRIPTOR_ADDR 0xFEF40000 diff --git a/bdk/module.h b/bdk/module.h index 6ec303f..acc048c 100644 --- a/bdk/module.h +++ b/bdk/module.h @@ -21,10 +21,13 @@ #include #include +#define IANOS_EXT0 0x304E4149 + // Module Callback typedef void (*cbMainModule_t)(const char *s); typedef void (*memcpy_t)(void *, void *, size_t); typedef void (*memset_t)(void *, int, size_t); +typedef int (*reg_voltage_set_t)(u32, u32); typedef struct _bdkParams_t { @@ -33,6 +36,8 @@ typedef struct _bdkParams_t heap_t *sharedHeap; memcpy_t memcpy; memset_t memset; + u32 extension_magic; + reg_voltage_set_t reg_voltage_set; } *bdkParams_t; // Module Entrypoint diff --git a/bdk/power/max7762x.c b/bdk/power/max7762x.c index 6a41512..a7d30ce 100644 --- a/bdk/power/max7762x.c +++ b/bdk/power/max7762x.c @@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t static const max77620_regulator_t _pmic_regulators[] = { { "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} }, - { "sd1", 12500, 600000, 1125000, 1125000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} }, + { "sd1", 12500, 600000, 1125000, 1250000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} }, { "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} }, { "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} }, { "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} }, @@ -328,6 +328,7 @@ void max77620_config_default() _max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, MAX77620_SD_CNF2_ROVS_EN_SD0); } +// Stock HOS: disabled. void max77620_low_battery_monitor_config(bool enable) { _max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1, diff --git a/bdk/power/max7762x.h b/bdk/power/max7762x.h index 8261336..3478530 100644 --- a/bdk/power/max7762x.h +++ b/bdk/power/max7762x.h @@ -32,11 +32,11 @@ * ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv) * ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 | * ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv) -* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 | +* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 | 0.85V (AO, pcv) * ldo5 | GC Card | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv) -* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V -* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | -* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 | +* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V (pcv) +* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | 1.05V (pcv) +* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv) */ /* @@ -135,10 +135,10 @@ #define MAX77621_CTRL_HOS_CFG 0 #define MAX77621_CTRL_POR_CFG 1 -int max77620_regulator_get_status(u32 id); -int max77620_regulator_config_fps(u32 id); -int max7762x_regulator_set_voltage(u32 id, u32 mv); -int max7762x_regulator_enable(u32 id, bool enable); +int max77620_regulator_get_status(u32 id); +int max77620_regulator_config_fps(u32 id); +int max7762x_regulator_set_voltage(u32 id, u32 mv); +int max7762x_regulator_enable(u32 id, bool enable); void max77620_config_gpio(u32 id, bool enable); void max77620_config_default(); void max77620_low_battery_monitor_config(bool enable); diff --git a/bdk/power/regulator_5v.c b/bdk/power/regulator_5v.c index 31d32f6..64fd7d7 100644 --- a/bdk/power/regulator_5v.c +++ b/bdk/power/regulator_5v.c @@ -81,7 +81,13 @@ bool regulator_5v_get_dev_enabled(u8 dev) void regulator_5v_batt_src_enable(bool enable) { if (enable && !batt_src) + { gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH); + batt_src = true; + } else if (!enable && batt_src) + { gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW); + batt_src = false; + } } diff --git a/bdk/sec/se.c b/bdk/sec/se.c index 2f76985..92767b9 100644 --- a/bdk/sec/se.c +++ b/bdk/sec/se.c @@ -1,8 +1,8 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2021 CTCaer * Copyright (c) 2018 Atmosphère-NX - * Copyright (c) 2019-2020 shchmue + * Copyright (c) 2019-2021 shchmue * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -35,8 +35,8 @@ typedef struct _se_ll_t vu32 size; } se_ll_t; -static u32 _se_rsa_mod_sizes[TEGRA_SE_RSA_KEYSLOT_COUNT]; -static u32 _se_rsa_exp_sizes[TEGRA_SE_RSA_KEYSLOT_COUNT]; +static u32 _se_rsa_mod_sizes[SE_RSA_KEYSLOT_COUNT]; +static u32 _se_rsa_exp_sizes[SE_RSA_KEYSLOT_COUNT]; static void _gf256_mul_x(void *block) { @@ -79,17 +79,17 @@ static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size) static void _se_ll_set(se_ll_t *dst, se_ll_t *src) { - SE(SE_IN_LL_ADDR_REG_OFFSET) = (u32)src; - SE(SE_OUT_LL_ADDR_REG_OFFSET) = (u32)dst; + SE(SE_IN_LL_ADDR_REG) = (u32)src; + SE(SE_OUT_LL_ADDR_REG) = (u32)dst; } static int _se_wait() { - while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET))) + while (!(SE(SE_INT_STATUS_REG) & SE_INT_OP_DONE)) ; - if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) || - SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN || - SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR) + if (SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT || + (SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE || + SE(SE_ERR_STATUS_REG) != 0) return 0; return 1; } @@ -114,12 +114,12 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src _se_ll_set(ll_dst, ll_src); - SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0); - SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET); + SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG); + SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG); bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op); + SE(SE_OPERATION_REG) = op; if (is_oneshot) { @@ -168,13 +168,13 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr if (!src || !dst) return 0; - u8 *block = (u8 *)malloc(0x10); - memset(block, 0, 0x10); + u8 *block = (u8 *)malloc(SE_AES_BLOCK_SIZE); + memset(block, 0, SE_AES_BLOCK_SIZE); - SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; + SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; memcpy(block, src, src_size); - int res = _se_execute_oneshot(op, block, 0x10, block, 0x10); + int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE); memcpy(dst, block, dst_size); free(block); @@ -183,21 +183,21 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr static void _se_aes_ctr_set(void *ctr) { - u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4]; - memcpy(data, ctr, TEGRA_SE_AES_BLOCK_SIZE); + u32 data[SE_AES_IV_SIZE / 4]; + memcpy(data, ctr, SE_AES_IV_SIZE); - for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++) - SE(SE_CRYPTO_CTR_REG_OFFSET + (4 * i)) = data[i]; + for (u32 i = 0; i < SE_CRYPTO_LINEAR_CTR_REG_COUNT; i++) + SE(SE_CRYPTO_LINEAR_CTR_REG + (4 * i)) = data[i]; } void se_rsa_acc_ctrl(u32 rs, u32 flags) { - if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG) - SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = - ((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | - ((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG); - if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG) - SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~BIT(rs); + if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG) + SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) = + (((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |(flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^ + SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG; + if (flags & SE_RSA_KEY_LOCK_FLAG) + SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs); } // se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot @@ -206,15 +206,15 @@ void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 u32 *data = (u32 *)mod; for (u32 i = 0; i < mod_size / 4; i++) { - SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_MOD) | i; - SE(SE_RSA_KEYTABLE_DATA) = byte_swap_32(data[mod_size / 4 - i - 1]); + SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i; + SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[mod_size / 4 - i - 1]); } data = (u32 *)exp; for (u32 i = 0; i < exp_size / 4; i++) { - SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_EXP) | i; - SE(SE_RSA_KEYTABLE_DATA) = byte_swap_32(data[exp_size / 4 - i - 1]); + SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i; + SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[exp_size / 4 - i - 1]); } _se_rsa_mod_sizes[ks] = mod_size; @@ -224,15 +224,15 @@ void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 // se_rsa_key_clear() was derived from Atmosphère's clear_rsa_keyslot void se_rsa_key_clear(u32 ks) { - for (u32 i = 0; i < TEGRA_SE_RSA2048_DIGEST_SIZE / 4; i++) + for (u32 i = 0; i < SE_RSA2048_DIGEST_SIZE / 4; i++) { - SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_MOD) | i; - SE(SE_RSA_KEYTABLE_DATA) = 0; + SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i; + SE(SE_RSA_KEYTABLE_DATA_REG) = 0; } - for (u32 i = 0; i < TEGRA_SE_RSA2048_DIGEST_SIZE / 4; i++) + for (u32 i = 0; i < SE_RSA2048_DIGEST_SIZE / 4; i++) { - SE(SE_RSA_KEYTABLE_ADDR) = RSA_KEY_NUM(ks) | RSA_KEY_TYPE(RSA_KEY_TYPE_EXP) | i; - SE(SE_RSA_KEYTABLE_DATA) = 0; + SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i; + SE(SE_RSA_KEYTABLE_DATA_REG) = 0; } } @@ -240,22 +240,22 @@ void se_rsa_key_clear(u32 ks) int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) { int res; - u8 stack_buf[TEGRA_SE_RSA2048_DIGEST_SIZE]; + u8 stack_buf[SE_RSA2048_DIGEST_SIZE]; for (u32 i = 0; i < src_size; i++) stack_buf[i] = *((u8 *)src + src_size - i - 1); - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_RSA) | SE_CONFIG_DST(DST_RSAREG); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RSA) | SE_CONFIG_DST(DST_RSAREG); SE(SE_RSA_CONFIG) = RSA_KEY_SLOT(ks); - SE(SE_RSA_KEY_SIZE_REG_OFFSET) = (_se_rsa_mod_sizes[ks] >> 6) - 1; - SE(SE_RSA_EXP_SIZE_REG_OFFSET) = _se_rsa_exp_sizes[ks] >> 2; + SE(SE_RSA_KEY_SIZE_REG) = (_se_rsa_mod_sizes[ks] >> 6) - 1; + SE(SE_RSA_EXP_SIZE_REG) = _se_rsa_exp_sizes[ks] >> 2; - res = _se_execute_oneshot(OP_START, NULL, 0, stack_buf, src_size); + res = _se_execute_oneshot(SE_OP_START, NULL, 0, stack_buf, src_size); // Copy output hash. u32 *dst32 = (u32 *)dst; for (u32 i = 0; i < dst_size / 4; i++) - dst32[dst_size / 4 - i - 1] = byte_swap_32(SE(SE_RSA_OUTPUT + (i << 2))); + dst32[dst_size / 4 - i - 1] = byte_swap_32(SE(SE_RSA_OUTPUT_REG + (i << 2))); return res; } @@ -263,54 +263,54 @@ int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_siz void se_key_acc_ctrl(u32 ks, u32 flags) { if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) - SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags; - if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG) - SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~BIT(ks); + SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks) = ~flags; + if (flags & SE_KEY_LOCK_FLAG) + SE(SE_CRYPTO_SECURITY_PERKEY_REG) &= ~BIT(ks); } u32 se_key_acc_ctrl_get(u32 ks) { - return SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks); + return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks); } void se_aes_key_set(u32 ks, const void *key, u32 size) { - u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4]; + u32 data[SE_AES_MAX_KEY_SIZE / 4]; memcpy(data, key, size); for (u32 i = 0; i < (size / 4); i++) { - SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; - SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT. + SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i]; } } void se_aes_key_partial_set(u32 ks, u32 index, u32 data) { - SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | index; - SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data; + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | index; + SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data; } void se_aes_iv_set(u32 ks, const void *iv) { - u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4]; - memcpy(data, iv, TEGRA_SE_AES_BLOCK_SIZE); + u32 data[SE_AES_IV_SIZE / 4]; + memcpy(data, iv, SE_AES_IV_SIZE); - for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++) + for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++) { - SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i; - SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i); + SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i]; } } void se_aes_key_get(u32 ks, void *key, u32 size) { - u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4]; + u32 data[SE_AES_MAX_KEY_SIZE / 4]; for (u32 i = 0; i < (size / 4); i++) { - SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; - data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET); + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT. + data[i] = SE(SE_CRYPTO_KEYTABLE_DATA_REG); } memcpy(key, data, size); @@ -318,77 +318,77 @@ void se_aes_key_get(u32 ks, void *key, u32 size) void se_aes_key_clear(u32 ks) { - for (u32 i = 0; i < (TEGRA_SE_AES_MAX_KEY_SIZE / 4); i++) + for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / 4); i++) { - SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; - SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT. + SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0; } } void se_aes_iv_clear(u32 ks) { - for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++) + for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++) { - SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i; - SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i); + SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0; } } int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input) { - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); - SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; - SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); + SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); + SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; + SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3); - return _se_execute_oneshot(OP_START, NULL, 0, input, 0x10); + return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE); } int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) { if (enc) { - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); } else { - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); + SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); } - SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; - return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size); + SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; + return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size); } int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) { if (enc) { - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP); } else { - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) | + SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM); } - SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; - return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size); + SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; + return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size); } int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src) { - return se_aes_crypt_ecb(ks, enc, dst, 0x10, src, 0x10); + return se_aes_crypt_ecb(ks, enc, dst, SE_AES_BLOCK_SIZE, src, SE_AES_BLOCK_SIZE); } int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr) { - SE(SE_SPARE_0_REG_OFFSET) = 1; - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | - SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1); + SE(SE_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | + SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_CNTN(1); _se_aes_ctr_set(ctr); u32 src_size_aligned = src_size & 0xFFFFFFF0; @@ -396,13 +396,13 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s if (src_size_aligned) { - SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; - if (!_se_execute_oneshot(OP_START, dst, dst_size, src, src_size_aligned)) + SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; + if (!_se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size_aligned)) return 0; } if (src_size - src_size_aligned && src_size_aligned < dst_size) - return _se_execute_one_block(OP_START, dst + src_size_aligned, + return _se_execute_one_block(SE_OP_START, dst + src_size_aligned, MIN(src_size_delta, dst_size - src_size_aligned), src + src_size_aligned, src_size_delta); @@ -419,15 +419,15 @@ int se_initialize_rng() u8 *output_buf = (u8 *)malloc(0x10); - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_INSTANTION) | SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY); - SE(SE_RNG_RESEED_INTERVAL_REG_OFFSET) = 70001; - SE(SE_RNG_SRC_CONFIG_REG_OFFSET) = SE_RNG_SRC_CONFIG_ENT_SRC(RNG_SRC_RO_ENT_ENABLE) | - SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE); - SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); + SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_MODE(MODE_FORCE_INSTANTION) | SE_RNG_CONFIG_SRC(SRC_ENTROPY); + SE(SE_RNG_RESEED_INTERVAL_REG) = 70001; + SE(SE_RNG_SRC_CONFIG_REG) = SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | + SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE); + SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0; - int res =_se_execute_oneshot(OP_START, output_buf, 0x10, NULL, 0); + int res =_se_execute_oneshot(SE_OP_START, output_buf, 0x10, NULL, 0); free(output_buf); if (res) @@ -437,35 +437,35 @@ int se_initialize_rng() int se_generate_random(void *dst, u32 size) { - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL) | SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); + SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_MODE(MODE_NORMAL) | SE_RNG_CONFIG_SRC(SRC_ENTROPY); u32 num_blocks = size >> 4; u32 aligned_size = num_blocks << 4; if (num_blocks) { - SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 1; - if (!_se_execute_oneshot(OP_START, dst, aligned_size, NULL, 0)) + SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 1; + if (!_se_execute_oneshot(SE_OP_START, dst, aligned_size, NULL, 0)) return 0; } if (size > aligned_size) - return _se_execute_one_block(OP_START, dst + aligned_size, size - aligned_size, NULL, 0); + return _se_execute_one_block(SE_OP_START, dst + aligned_size, size - aligned_size, NULL, 0); return 1; } int se_generate_random_key(u32 ks_dst, u32 ks_src) { - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL) | SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY); + SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_MODE(MODE_NORMAL) | SE_RNG_CONFIG_SRC(SRC_ENTROPY); - SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); - if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0)) + SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst); + if (!_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0)) return 0; - SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1; - if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0)) + SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1; + if (!_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0)) return 0; return 1; @@ -544,8 +544,8 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) if (src_size & 0xF) _gf256_mul_x(key); - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) | + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) | SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); se_aes_iv_clear(ks); @@ -553,10 +553,10 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) u32 num_blocks = (src_size + 0xf) >> 4; if (num_blocks > 1) { - SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 2; - if (!_se_execute_oneshot(OP_START, NULL, 0, src, src_size)) + SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2; + if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size)) goto out; - SE(SE_CRYPTO_REG_OFFSET) |= SE_CRYPTO_IV_SEL(IV_UPDATED); + SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED); } if (src_size & 0xf) @@ -572,12 +572,12 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) for (u32 i = 0; i < 0x10; i++) last_block[i] ^= key[i]; - SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; - res = _se_execute_oneshot(OP_START, NULL, 0, last_block, 0x10); + SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0; + res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, 0x10); u32 *dst32 = (u32 *)dst; for (u32 i = 0; i < (dst_size >> 2); i++) - dst32[i] = SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)); + dst32[i] = SE(SE_HASH_RESULT_REG + (i << 2)); out:; free(key); @@ -588,62 +588,62 @@ out:; int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot) { int res; - u32 hash32[TEGRA_SE_SHA_256_SIZE / 4]; + u32 hash32[SE_SHA_256_SIZE / 4]; //! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256. if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer. return 0; // Setup config for SHA256. - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); - SE(SE_SHA_CONFIG_REG_OFFSET) = sha_cfg; - SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); + SE(SE_SHA_CONFIG_REG) = sha_cfg; + SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; // Set total size to current buffer size if empty. if (!total_size) total_size = src_size; // Set total size: BITS(src_size), up to 2 EB. - SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(total_size << 3); - SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29); - SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0; - SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LENGTH_0_REG) = (u32)(total_size << 3); + SE(SE_SHA_MSG_LENGTH_1_REG) = (u32)(total_size >> 29); + SE(SE_SHA_MSG_LENGTH_2_REG) = 0; + SE(SE_SHA_MSG_LENGTH_3_REG) = 0; // Set size left to hash. - SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(total_size << 3); - SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29); - SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0; - SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LEFT_0_REG) = (u32)(total_size << 3); + SE(SE_SHA_MSG_LEFT_1_REG) = (u32)(total_size >> 29); + SE(SE_SHA_MSG_LEFT_2_REG) = 0; + SE(SE_SHA_MSG_LEFT_3_REG) = 0; // If we hash in chunks, copy over the intermediate. if (sha_cfg == SHA_CONTINUE && msg_left) { // Restore message left to process. - SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = msg_left[0]; - SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1]; + SE(SE_SHA_MSG_LEFT_0_REG) = msg_left[0]; + SE(SE_SHA_MSG_LEFT_1_REG) = msg_left[1]; // Restore hash reg. - memcpy(hash32, hash, TEGRA_SE_SHA_256_SIZE); - for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++) - SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]); + memcpy(hash32, hash, SE_SHA_256_SIZE); + for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++) + SE(SE_HASH_RESULT_REG + (i * 4)) = byte_swap_32(hash32[i]); } // Trigger the operation. - res = _se_execute(OP_START, NULL, 0, src, src_size, is_oneshot); + res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot); if (is_oneshot) { // Backup message left. if (msg_left) { - msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET); - msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET); + msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG); + msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG); } // Copy output hash. - for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++) - hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); - memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE); + for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++) + hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4))); + memcpy(hash, hash32, SE_SHA_256_SIZE); } return res; @@ -656,20 +656,20 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size) int se_calc_sha256_finalize(void *hash, u32 *msg_left) { - u32 hash32[TEGRA_SE_SHA_256_SIZE / 4]; + u32 hash32[SE_SHA_256_SIZE / 4]; int res = _se_execute_finalize(); // Backup message left. if (msg_left) { - msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET); - msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET); + msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG); + msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG); } // Copy output hash. - for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++) - hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); - memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE); + for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++) + hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i << 2))); + memcpy(hash, hash32, SE_SHA_256_SIZE); return res; } @@ -793,43 +793,43 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40); // Set Secure Random Key. - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK); - SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); + SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED); SE(SE_CRYPTO_LAST_BLOCK) = 0; - _se_execute_oneshot(OP_START, NULL, 0, NULL, 0); + _se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0); // Save AES keys. - SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - for (u32 i = 0; i < TEGRA_SE_KEYSLOT_COUNT; i++) + for (u32 i = 0; i < SE_AES_KEYSLOT_COUNT; i++) { - SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) | - (i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3); + SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) | + SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3); SE(SE_CRYPTO_LAST_BLOCK) = 0; - _se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0); - memcpy(keys + i * keysize, aligned_buf, 0x10); + _se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0); + memcpy(keys + i * keysize, aligned_buf, SE_AES_BLOCK_SIZE); - if (keysize > 0x10) + if (keysize > SE_KEY_128_SIZE) { - SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) | - (i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7); + SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) | + SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7); SE(SE_CRYPTO_LAST_BLOCK) = 0; - _se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0); - memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10); + _se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0); + memcpy(keys + i * keysize + SE_AES_BLOCK_SIZE, aligned_buf, SE_AES_BLOCK_SIZE); } } // Save SRK to PMC secure scratches. - SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK); - SE(SE_CRYPTO_LAST_BLOCK) = 0; - _se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0); + SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(SRK); + SE(SE_CRYPTO_LAST_BLOCK) = 0; + _se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0); // End context save. - SE(SE_CONFIG_REG_OFFSET) = 0; - _se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0); + SE(SE_CONFIG_REG) = 0; + _se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0); // Get SRK. u32 srk[4]; @@ -840,7 +840,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) // Decrypt context. se_aes_key_clear(3); - se_aes_key_set(3, srk, 0x10); - se_aes_crypt_cbc(3, 0, keys, TEGRA_SE_KEYSLOT_COUNT * keysize, keys, TEGRA_SE_KEYSLOT_COUNT * keysize); + se_aes_key_set(3, srk, SE_KEY_128_SIZE); + se_aes_crypt_cbc(3, 0, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize); se_aes_key_clear(3); } diff --git a/bdk/sec/se.h b/bdk/sec/se.h index 400d865..a52fd53 100644 --- a/bdk/sec/se.h +++ b/bdk/sec/se.h @@ -1,5 +1,7 @@ /* * Copyright (c) 2018 naehrwert +* Copyright (c) 2019-2021 CTCaer +* Copyright (c) 2019-2021 shchmue * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -25,6 +27,7 @@ void se_rsa_key_clear(u32 ks); int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size); void se_key_acc_ctrl(u32 ks, u32 flags); u32 se_key_acc_ctrl_get(u32 ks); +void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize); void se_aes_key_set(u32 ks, const void *key, u32 size); void se_aes_iv_set(u32 ks, const void *iv); void se_aes_key_partial_set(u32 ks, u32 index, u32 data); @@ -35,10 +38,10 @@ int se_initialize_rng(); int se_generate_random(void *dst, u32 size); int se_generate_random_key(u32 ks_dst, u32 ks_src); int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input); +int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src); int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr); -int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size); int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size, u32 num_secs); int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size); @@ -47,6 +50,5 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size); int se_calc_sha256_finalize(void *hash, u32 *msg_left); int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size); u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size); -void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize); #endif diff --git a/bdk/sec/se_t210.h b/bdk/sec/se_t210.h index 6fbf1b0..0233e1d 100644 --- a/bdk/sec/se_t210.h +++ b/bdk/sec/se_t210.h @@ -1,400 +1,323 @@ /* -* Driver for Tegra Security Engine -* -* Copyright (c) 2011-2013, NVIDIA Corporation. All Rights Reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that 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, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ + * Copyright (c) 2018 naehrwert + * Copyright (c) 2018-2021 CTCaer + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ -#ifndef _CRYPTO_TEGRA_SE_H -#define _CRYPTO_TEGRA_SE_H +#ifndef _SE_T210_H +#define _SE_T210_H #include -#define TEGRA_SE_CRA_PRIORITY 300 -#define TEGRA_SE_COMPOSITE_PRIORITY 400 -#define TEGRA_SE_CRYPTO_QUEUE_LENGTH 50 -#define SE_MAX_SRC_SG_COUNT 50 -#define SE_MAX_DST_SG_COUNT 50 +#define SE_CRYPTO_QUEUE_LENGTH 50 +#define SE_MAX_SRC_SG_COUNT 50 +#define SE_MAX_DST_SG_COUNT 50 -#define TEGRA_SE_KEYSLOT_COUNT 16 -#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF +#define SE_AES_KEYSLOT_COUNT 16 +#define SE_RSA_KEYSLOT_COUNT 2 +#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF + +#define SE_AES_BLOCK_SIZE 16 +#define SE_AES_IV_SIZE 16 +#define SE_AES_MIN_KEY_SIZE 16 +#define SE_AES_MAX_KEY_SIZE 32 +#define SE_KEY_128_SIZE 16 +#define SE_KEY_192_SIZE 24 +#define SE_KEY_256_SIZE 32 +#define SE_SHA_192_SIZE 24 +#define SE_SHA_256_SIZE 32 +#define SE_SHA_384_SIZE 48 +#define SE_SHA_512_SIZE 64 +#define SE_RNG_IV_SIZE 16 +#define SE_RNG_DT_SIZE 16 +#define SE_RNG_KEY_SIZE 16 +#define SE_RNG_SEED_SIZE (SE_RNG_IV_SIZE + SE_RNG_KEY_SIZE + SE_RNG_DT_SIZE) + +#define SE_AES_CMAC_DIGEST_SIZE 16 +#define SE_RSA512_DIGEST_SIZE 64 +#define SE_RSA1024_DIGEST_SIZE 128 +#define SE_RSA1536_DIGEST_SIZE 192 +#define SE_RSA2048_DIGEST_SIZE 256 /* SE register definitions */ -#define SE_SECURITY_0 0x000 -#define SE_KEY_SCHED_READ_SHIFT 3 +#define SE_SE_SECURITY_REG 0x000 +#define SE_HARD_SETTING BIT(0) +#define SE_ENG_DIS BIT(1) +#define SE_PERKEY_SETTING BIT(2) +#define SE_SOFT_SETTING BIT(16) -#define SE_TZRAM_SECURITY_0 0x004 +#define SE_TZRAM_SECURITY_REG 0x004 +#define SE_TZRAM_HARD_SETTING BIT(0) +#define SE_TZRAM_ENG_DIS BIT(1) -#define SE_CONFIG_REG_OFFSET 0x014 -#define SE_CONFIG_ENC_ALG_SHIFT 12 -#define SE_CONFIG_DEC_ALG_SHIFT 8 -#define ALG_AES_ENC 1 -#define ALG_RNG 2 -#define ALG_SHA 3 -#define ALG_RSA 4 -#define ALG_NOP 0 -#define ALG_AES_DEC 1 -#define SE_CONFIG_ENC_ALG(x) ((x) << SE_CONFIG_ENC_ALG_SHIFT) -#define SE_CONFIG_DEC_ALG(x) ((x) << SE_CONFIG_DEC_ALG_SHIFT) -#define SE_CONFIG_DST_SHIFT 2 -#define DST_MEMORY 0 -#define DST_HASHREG 1 -#define DST_KEYTAB 2 -#define DST_SRK 3 -#define DST_RSAREG 4 -#define SE_CONFIG_DST(x) ((x) << SE_CONFIG_DST_SHIFT) -#define SE_CONFIG_ENC_MODE_SHIFT 24 -#define SE_CONFIG_DEC_MODE_SHIFT 16 -#define MODE_KEY128 0 -#define MODE_KEY192 1 -#define MODE_KEY256 2 -#define MODE_SHA1 0 -#define MODE_SHA224 4 -#define MODE_SHA256 5 -#define MODE_SHA384 6 -#define MODE_SHA512 7 -#define SE_CONFIG_ENC_MODE(x) ((x) << SE_CONFIG_ENC_MODE_SHIFT) -#define SE_CONFIG_DEC_MODE(x) ((x) << SE_CONFIG_DEC_MODE_SHIFT) +#define SE_OPERATION_REG 0x008 +#define SE_OP_ABORT 0 +#define SE_OP_START 1 +#define SE_OP_RESTART_OUT 2 +#define SE_OP_CTX_SAVE 3 +#define SE_OP_RESTART_IN 4 -#define SE_RNG_CONFIG_REG_OFFSET 0x340 -#define RNG_MODE_SHIFT 0 -#define RNG_MODE_NORMAL 0 -#define RNG_MODE_FORCE_INSTANTION 1 -#define RNG_MODE_FORCE_RESEED 2 -#define SE_RNG_CONFIG_MODE(x) ((x) << RNG_MODE_SHIFT) -#define RNG_SRC_SHIFT 2 -#define RNG_SRC_NONE 0 -#define RNG_SRC_ENTROPY 1 -#define RNG_SRC_LFSR 2 -#define SE_RNG_CONFIG_SRC(x) ((x) << RNG_SRC_SHIFT) +#define SE_INT_ENABLE_REG 0x00C +#define SE_INT_STATUS_REG 0x010 +#define SE_INT_IN_LL_BUF_RD BIT(0) +#define SE_INT_IN_DONE BIT(1) +#define SE_INT_OUT_LL_BUF_WR BIT(2) +#define SE_INT_OUT_DONE BIT(3) +#define SE_INT_OP_DONE BIT(4) +#define SE_INT_RESEED_NEEDED BIT(5) +#define SE_INT_ERR_STAT BIT(16) -#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344 -#define RNG_SRC_RO_ENT_SHIFT 1 -#define RNG_SRC_RO_ENT_ENABLE 1 -#define RNG_SRC_RO_ENT_DISABLE 0 -#define SE_RNG_SRC_CONFIG_ENT_SRC(x) ((x) << RNG_SRC_RO_ENT_SHIFT) -#define RNG_SRC_RO_ENT_LOCK_SHIFT 0 -#define RNG_SRC_RO_ENT_LOCK_ENABLE 1 -#define RNG_SRC_RO_ENT_LOCK_DISABLE 0 -#define SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(x) ((x) << RNG_SRC_RO_ENT_LOCK_SHIFT) +#define SE_CONFIG_REG 0x014 +#define DST_MEMORY 0 +#define DST_HASHREG 1 +#define DST_KEYTABLE 2 +#define DST_SRK 3 +#define DST_RSAREG 4 +#define SE_CONFIG_DST(x) ((x) << 2) +#define ALG_NOP 0 +#define ALG_AES_DEC 1 +#define SE_CONFIG_DEC_ALG(x) ((x) << 8) +#define ALG_NOP 0 +#define ALG_AES_ENC 1 +#define ALG_RNG 2 +#define ALG_SHA 3 +#define ALG_RSA 4 +#define SE_CONFIG_ENC_ALG(x) ((x) << 12) +#define MODE_KEY128 0 +#define MODE_KEY192 1 +#define MODE_KEY256 2 +#define MODE_SHA1 0 +#define MODE_SHA224 4 +#define MODE_SHA256 5 +#define MODE_SHA384 6 +#define MODE_SHA512 7 +#define SE_CONFIG_DEC_MODE(x) ((x) << 16) +#define SE_CONFIG_ENC_MODE(x) ((x) << 24) -#define SE_RNG_RESEED_INTERVAL_REG_OFFSET 0x348 +#define SE_IN_LL_ADDR_REG 0x018 +#define SE_IN_CUR_BYTE_ADDR_REG 0x01C +#define SE_IN_CUR_LL_ID_REG 0x020 +#define SE_OUT_LL_ADDR_REG 0x024 +#define SE_OUT_CUR_BYTE_ADDR_REG 0x028 +#define SE_OUT_CUR_LL_ID_REG 0x02C -#define SE_KEYTABLE_REG_OFFSET 0x31c -#define SE_KEYTABLE_SLOT_SHIFT 4 -#define SE_KEYTABLE_SLOT(x) ((x) << SE_KEYTABLE_SLOT_SHIFT) -#define SE_KEYTABLE_QUAD_SHIFT 2 -#define QUAD_KEYS_128 0 -#define QUAD_KEYS_192 1 -#define QUAD_KEYS_256 1 -#define QUAD_ORG_IV 2 -#define QUAD_UPDTD_IV 3 -#define SE_KEYTABLE_QUAD(x) ((x) << SE_KEYTABLE_QUAD_SHIFT) -#define SE_KEYTABLE_OP_TYPE_SHIFT 9 -#define OP_READ 0 -#define OP_WRITE 1 -#define SE_KEYTABLE_OP_TYPE(x) ((x) << SE_KEYTABLE_OP_TYPE_SHIFT) -#define SE_KEYTABLE_TABLE_SEL_SHIFT 8 -#define TABLE_KEYIV 0 -#define TABLE_SCHEDULE 1 -#define SE_KEYTABLE_TABLE_SEL(x) ((x) << SE_KEYTABLE_TABLE_SEL_SHIFT) -#define SE_KEYTABLE_PKT_SHIFT 0 -#define SE_KEYTABLE_PKT(x) ((x) << SE_KEYTABLE_PKT_SHIFT) +#define SE_HASH_RESULT_REG 0x030 +#define SE_HASH_RESULT_REG_COUNT 16 -#define SE_OP_DONE_SHIFT 4 -#define OP_DONE 1 -#define SE_OP_DONE(x, y) ((x) && ((y) << SE_OP_DONE_SHIFT)) +#define SE_CONTEXT_SAVE_CONFIG_REG 0x070 +#define KEYS_0_3 0 +#define KEYS_4_7 1 +#define ORIGINAL_IV 2 +#define UPDATED_IV 3 +#define SE_CONTEXT_AES_WORD_QUAD(x) ((x) << 0) +#define SE_CONTEXT_AES_KEY_INDEX(x) ((x) << 8) +#define KEYS_0_3 0 +#define KEYS_4_7 1 +#define KEYS_8_11 2 +#define KEYS_12_15 3 +#define SE_CONTEXT_RSA_WORD_QUAD(x) ((x) << 12) +#define SLOT0_EXPONENT 0 +#define SLOT0_MODULUS 1 +#define SLOT1_EXPONENT 2 +#define SLOT1_MODULUS 3 +#define SE_CONTEXT_RSA_KEY_INDEX(x) ((x) << 16) +#define STICKY_0_3 0 +#define STICKY_4_7 1 +#define SE_CONTEXT_STICKY_WORD_QUAD(x) ((x) << 24) +#define STICKY_BITS 0 +#define RSA_KEYTABLE 1 +#define AES_KEYTABLE 2 +#define MEM 4 +#define SRK 6 +#define SE_CONTEXT_SRC(x) ((x) << 29) -#define SE_CRYPTO_LAST_BLOCK 0x080 +#define SE_CTX_SAVE_AUTO_T210B01_REG 0x074 +#define SE_CTX_SAVE_AUTO_ENABLE BIT(0) +#define SE_CTX_SAVE_AUTO_LOCK BIT(8) +#define SE_CTX_SAVE_AUTO_CURR_CNT_MASK (0x3FF << 16) -#define SE_CRYPTO_REG_OFFSET 0x304 -#define SE_CRYPTO_HASH_SHIFT 0 -#define HASH_DISABLE 0 -#define HASH_ENABLE 1 -#define SE_CRYPTO_HASH(x) ((x) << SE_CRYPTO_HASH_SHIFT) -#define SE_CRYPTO_XOR_POS_SHIFT 1 -#define XOR_BYPASS 0 -#define XOR_TOP 2 -#define XOR_BOTTOM 3 -#define SE_CRYPTO_XOR_POS(x) ((x) << SE_CRYPTO_XOR_POS_SHIFT) -#define SE_CRYPTO_INPUT_SEL_SHIFT 3 -#define INPUT_AHB 0 -#define INPUT_RANDOM 1 -#define INPUT_AESOUT 2 -#define INPUT_LNR_CTR 3 -#define SE_CRYPTO_INPUT_SEL(x) ((x) << SE_CRYPTO_INPUT_SEL_SHIFT) -#define SE_CRYPTO_VCTRAM_SEL_SHIFT 5 -#define VCTRAM_AHB 0 -#define VCTRAM_AESOUT 2 -#define VCTRAM_PREVAHB 3 -#define SE_CRYPTO_VCTRAM_SEL(x) ((x) << SE_CRYPTO_VCTRAM_SEL_SHIFT) -#define SE_CRYPTO_IV_SEL_SHIFT 7 -#define IV_ORIGINAL 0 -#define IV_UPDATED 1 -#define SE_CRYPTO_IV_SEL(x) ((x) << SE_CRYPTO_IV_SEL_SHIFT) -#define SE_CRYPTO_CORE_SEL_SHIFT 8 -#define CORE_DECRYPT 0 -#define CORE_ENCRYPT 1 -#define SE_CRYPTO_CORE_SEL(x) ((x) << SE_CRYPTO_CORE_SEL_SHIFT) -#define SE_CRYPTO_CTR_VAL_SHIFT 11 -#define SE_CRYPTO_CTR_VAL(x) ((x) << SE_CRYPTO_CTR_VAL_SHIFT) -#define SE_CRYPTO_KEY_INDEX_SHIFT 24 -#define SE_CRYPTO_KEY_INDEX(x) ((x) << SE_CRYPTO_KEY_INDEX_SHIFT) -#define SE_CRYPTO_CTR_CNTN_SHIFT 11 -#define SE_CRYPTO_CTR_CNTN(x) ((x) << SE_CRYPTO_CTR_CNTN_SHIFT) +#define SE_CRYPTO_LAST_BLOCK 0x080 -#define SE_CRYPTO_CTR_REG_COUNT 4 -#define SE_CRYPTO_CTR_REG_OFFSET 0x308 - -#define SE_OPERATION_REG_OFFSET 0x008 -#define SE_OPERATION_SHIFT 0 -#define OP_ABORT 0 -#define OP_START 1 -#define OP_RESTART 2 -#define OP_CTX_SAVE 3 -#define OP_RESTART_IN 4 -#define SE_OPERATION(x) ((x) << SE_OPERATION_SHIFT) - -#define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET 0x070 -#define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT 0 -#define KEYS_0_3 0 -#define KEYS_4_7 1 -#define ORIG_IV 2 -#define UPD_IV 3 -#define SE_CONTEXT_SAVE_WORD_QUAD(x) ((x) << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT) - -#define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT 8 -#define SE_CONTEXT_SAVE_KEY_INDEX(x) ((x) << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT) - -#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT 24 -#define STICKY_0_3 0 -#define STICKY_4_7 1 -#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x) \ - ((x) << SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT) - -#define SE_CONTEXT_SAVE_SRC_SHIFT 29 -#define STICKY_BITS 0 -#define KEYTABLE 2 -#define MEM 4 -#define SRK 6 - -#define RSA_KEYTABLE 1 -#define AES_KEYTABLE 2 -#define SE_CONTEXT_SAVE_SRC(x) ((x) << SE_CONTEXT_SAVE_SRC_SHIFT) - -#define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT 16 -#define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x) \ - ((x) << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT) - -#define SE_CONTEXT_RSA_WORD_QUAD_SHIFT 12 -#define SE_CONTEXT_RSA_WORD_QUAD(x) \ - ((x) << SE_CONTEXT_RSA_WORD_QUAD_SHIFT) - -#define SE_CTX_SAVE_AUTO 0x074 -#define CTX_SAVE_AUTO_ENABLE BIT(0) -#define CTX_SAVE_AUTO_LOCK BIT(8) -#define CTX_SAVE_AUTO_CURR_CNT_MASK (0x3FF << 16) - -#define SE_INT_ENABLE_REG_OFFSET 0x00c -#define SE_INT_STATUS_REG_OFFSET 0x010 -#define INT_DISABLE 0 -#define INT_ENABLE 1 -#define INT_UNSET 0 -#define INT_SET 1 -#define SE_INT_OP_DONE_SHIFT 4 -#define SE_INT_OP_DONE(x) ((x) << SE_INT_OP_DONE_SHIFT) -#define SE_INT_ERROR_SHIFT 16 -#define SE_INT_ERROR(x) ((x) << SE_INT_ERROR_SHIFT) - -#define SE_STATUS_0 0x800 -#define SE_STATUS_0_STATE_WAIT_IN 3 - -#define SE_ERR_STATUS_0 0x804 -#define SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR 0 - -#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330 -#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0 -#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x) \ - ((x) << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT) - -#define SE_KEY_INDEX_SHIFT 8 -#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x) ((x) << SE_KEY_INDEX_SHIFT) - -#define SE_IN_LL_ADDR_REG_OFFSET 0x018 -#define SE_OUT_LL_ADDR_REG_OFFSET 0x024 - -#define SE_KEYTABLE_DATA0_REG_OFFSET 0x320 -#define SE_KEYTABLE_REG_MAX_DATA 16 - -#define SE_BLOCK_COUNT_REG_OFFSET 0x318 - -#define SE_SPARE_0_REG_OFFSET 0x80c - -#define SE_SHA_CONFIG_REG_OFFSET 0x200 +#define SE_SHA_CONFIG_REG 0x200 #define SHA_CONTINUE 0 #define SHA_INIT_HASH 1 -#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204 -#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208 -#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C -#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210 -#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214 -#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218 -#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C -#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220 +#define SE_SHA_MSG_LENGTH_0_REG 0x204 +#define SE_SHA_MSG_LENGTH_1_REG 0x208 +#define SE_SHA_MSG_LENGTH_2_REG 0x20C +#define SE_SHA_MSG_LENGTH_3_REG 0x210 +#define SE_SHA_MSG_LEFT_0_REG 0x214 +#define SE_SHA_MSG_LEFT_1_REG 0x218 +#define SE_SHA_MSG_LEFT_2_REG 0x21C +#define SE_SHA_MSG_LEFT_3_REG 0x220 -#define SE_HASH_RESULT_REG_COUNT 16 -#define SE_HASH_RESULT_REG_OFFSET 0x030 -#define TEGRA_SE_KEY_256_SIZE 32 -#define TEGRA_SE_KEY_192_SIZE 24 -#define TEGRA_SE_KEY_128_SIZE 16 -#define TEGRA_SE_AES_BLOCK_SIZE 16 -#define TEGRA_SE_AES_MIN_KEY_SIZE 16 -#define TEGRA_SE_AES_MAX_KEY_SIZE 32 -#define TEGRA_SE_AES_IV_SIZE 16 -#define TEGRA_SE_SHA_512_SIZE 64 -#define TEGRA_SE_SHA_384_SIZE 48 -#define TEGRA_SE_SHA_256_SIZE 32 -#define TEGRA_SE_SHA_192_SIZE 24 -#define TEGRA_SE_RNG_IV_SIZE 16 -#define TEGRA_SE_RNG_DT_SIZE 16 -#define TEGRA_SE_RNG_KEY_SIZE 16 -#define TEGRA_SE_RNG_SEED_SIZE (TEGRA_SE_RNG_IV_SIZE + \ - TEGRA_SE_RNG_KEY_SIZE + \ - TEGRA_SE_RNG_DT_SIZE) +#define SE_CRYPTO_SECURITY_PERKEY_REG 0x280 +#define SE_KEY_LOCK_FLAG 0x80 +#define SE_CRYPTO_KEYTABLE_ACCESS_REG 0x284 +#define SE_CRYPTO_KEYTABLE_ACCESS_REG_COUNT 16 +#define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0) +#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1) +#define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2) +#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3) +#define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4) +#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5) +#define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6) +#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F -#define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16 -#define TEGRA_SE_RSA512_DIGEST_SIZE 64 -#define TEGRA_SE_RSA1024_DIGEST_SIZE 128 -#define TEGRA_SE_RSA1536_DIGEST_SIZE 192 -#define TEGRA_SE_RSA2048_DIGEST_SIZE 256 +#define SE_CRYPTO_CONFIG_REG 0x304 +#define HASH_DISABLE 0 +#define HASH_ENABLE 1 +#define SE_CRYPTO_HASH(x) ((x) << 0) +#define XOR_BYPASS 0 +#define XOR_TOP 2 +#define XOR_BOTTOM 3 +#define SE_CRYPTO_XOR_POS(x) ((x) << 1) +#define INPUT_MEMORY 0 +#define INPUT_RANDOM 1 +#define INPUT_AESOUT 2 +#define INPUT_LNR_CTR 3 +#define SE_CRYPTO_INPUT_SEL(x) ((x) << 3) +#define VCTRAM_MEM 0 +#define VCTRAM_AESOUT 2 +#define VCTRAM_PREVMEM 3 +#define SE_CRYPTO_VCTRAM_SEL(x) ((x) << 5) +#define IV_ORIGINAL 0 +#define IV_UPDATED 1 +#define SE_CRYPTO_IV_SEL(x) ((x) << 7) +#define CORE_DECRYPT 0 +#define CORE_ENCRYPT 1 +#define SE_CRYPTO_CORE_SEL(x) ((x) << 8) +#define SE_CRYPTO_KEYSCH_BYPASS BIT(10) +#define SE_CRYPTO_CTR_CNTN(x) ((x) << 11) +#define SE_CRYPTO_KEY_INDEX(x) ((x) << 24) +#define MEMIF_AHB 0 +#define MEMIF_MCCIF 1 +#define SE_CRYPTO_MEMIF(x) ((x) << 31) -#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280 -#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 +#define SE_CRYPTO_LINEAR_CTR_REG 0x308 +#define SE_CRYPTO_LINEAR_CTR_REG_COUNT 4 -#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284 -#define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0) -#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1) -#define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2) -#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3) -#define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4) -#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5) -#define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6) -#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F +#define SE_CRYPTO_BLOCK_COUNT_REG 0x318 -#define SE_KEY_READ_DISABLE_SHIFT 0 -#define SE_KEY_UPDATE_DISABLE_SHIFT 1 +#define SE_CRYPTO_KEYTABLE_ADDR_REG 0x31C +#define SE_KEYTABLE_PKT(x) ((x) << 0) +#define KEYS_0_3 0 +#define KEYS_4_7 1 +#define ORIGINAL_IV 2 +#define UPDATED_IV 3 +#define SE_KEYTABLE_QUAD(x) ((x) << 2) +#define SE_KEYTABLE_SLOT(x) ((x) << 4) -#define SE_CONTEXT_BUFER_SIZE 1072 -#define SE_CONTEXT_DRBG_BUFER_SIZE 2112 +#define SE_CRYPTO_KEYTABLE_DATA_REG 0x320 -#define SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET 0 -#define SE_CONTEXT_SAVE_RANDOM_DATA_SIZE 16 -#define SE_CONTEXT_SAVE_STICKY_BITS_OFFSET \ - (SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET + SE_CONTEXT_SAVE_RANDOM_DATA_SIZE) -#define SE_CONTEXT_SAVE_STICKY_BITS_SIZE 16 +#define SE_CRYPTO_KEYTABLE_DST_REG 0x330 +#define KEYS_0_3 0 +#define KEYS_4_7 1 +#define ORIGINAL_IV 2 +#define UPDATED_IV 3 +#define SE_KEYTABLE_DST_WORD_QUAD(x) ((x) << 0) +#define SE_KEYTABLE_DST_KEY_INDEX(x) ((x) << 8) -#define SE_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \ - SE_CONTEXT_SAVE_STICKY_BITS_SIZE) -#define SE11_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \ - SE_CONTEXT_SAVE_STICKY_BITS_SIZE + \ - SE_CONTEXT_SAVE_STICKY_BITS_SIZE) +#define SE_RNG_CONFIG_REG 0x340 +#define MODE_NORMAL 0 +#define MODE_FORCE_INSTANTION 1 +#define MODE_FORCE_RESEED 2 +#define SE_RNG_CONFIG_MODE(x) ((x) << 0) +#define SRC_NONE 0 +#define SRC_ENTROPY 1 +#define SRC_LFSR 2 +#define SE_RNG_CONFIG_SRC(x) ((x) << 2) -#define SE_CONTEXT_SAVE_KEY_LENGTH 512 -#define SE_CONTEXT_ORIGINAL_IV_OFFSET (SE_CONTEXT_SAVE_KEYS_OFFSET + \ - SE_CONTEXT_SAVE_KEY_LENGTH) -#define SE11_CONTEXT_ORIGINAL_IV_OFFSET (SE11_CONTEXT_SAVE_KEYS_OFFSET + \ - SE_CONTEXT_SAVE_KEY_LENGTH) +#define SE_RNG_SRC_CONFIG_REG 0x344 +#define RO_ENTR_LOCK_DISABLE 0 +#define RO_ENTR_LOCK_ENABLE 1 +#define SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(x) ((x) << 0) +#define RO_ENTR_DISABLE 0 +#define RO_ENTR_ENABLE 1 +#define SE_RNG_SRC_CONFIG_ENTR_SRC(x) ((x) << 1) +#define RO_HW_DIS_CYA_DISABLE 0 +#define RO_HW_DIS_CYA_ENABLE 1 +#define SE_RNG_SRC_CONFIG_HW_DIS_CYA(x) ((x) << 2) +#define SE_RNG_SRC_CONFIG_ENTR_SUBSMPL(x) ((x) << 4) +#define SE_RNG_SRC_CONFIG_ENTR_DATA_FLUSH BIT(8) -#define SE_CONTEXT_ORIGINAL_IV_LENGTH 256 +#define SE_RNG_RESEED_INTERVAL_REG 0x348 -#define SE_CONTEXT_UPDATED_IV_OFFSET (SE_CONTEXT_ORIGINAL_IV_OFFSET + \ - SE_CONTEXT_ORIGINAL_IV_LENGTH) -#define SE11_CONTEXT_UPDATED_IV_OFFSET (SE11_CONTEXT_ORIGINAL_IV_OFFSET + \ - SE_CONTEXT_ORIGINAL_IV_LENGTH) +#define SE_RSA_CONFIG 0x400 +#define RSA_KEY_SLOT_ONE 0 +#define RSA_KEY_SLOT_TW0 1 +#define RSA_KEY_SLOT(x) ((x) << 24) -#define SE_CONTEXT_UPDATED_IV_LENGTH 256 +#define SE_RSA_KEY_SIZE_REG 0x404 +#define RSA_KEY_WIDTH_512 0 +#define RSA_KEY_WIDTH_1024 1 +#define RSA_KEY_WIDTH_1536 2 +#define RSA_KEY_WIDTH_2048 3 -#define SE_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET (SE_CONTEXT_UPDATED_IV_OFFSET + \ - SE_CONTEXT_UPDATED_IV_LENGTH) -#define SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET \ - (SE11_CONTEXT_UPDATED_IV_OFFSET + \ - SE_CONTEXT_UPDATED_IV_LENGTH) +#define SE_RSA_EXP_SIZE_REG 0x408 -#define SE_CONTEXT_SAVE_RSA_KEYS_OFFSET SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET +#define SE_RSA_SECURITY_PERKEY_REG 0x40C +#define SE_RSA_KEY_LOCK_FLAG 0x80 +#define SE_RSA_KEYTABLE_ACCESS_REG 0x410 +#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0) +#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1) +#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG BIT(2) +#define SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F +#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG) +#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG | SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) -#define SE_CONTEXT_SAVE_RSA_KEY_LENGTH 1024 +#define SE_RSA_KEYTABLE_ADDR_REG 0x420 +#define SE_RSA_KEYTABLE_PKT(x) ((x) << 0) +#define RSA_KEY_TYPE_EXP 0 +#define RSA_KEY_TYPE_MOD 1 +#define SE_RSA_KEYTABLE_TYPE(x) ((x) << 6) +#define RSA_KEY_NUM(x) ((x) << 7) +#define RSA_KEY_INPUT_MODE_REG 0 +#define RSA_KEY_INPUT_MODE_DMA 1 +#define SE_RSA_KEYTABLE_INPUT_MODE(x) ((x) << 8) +#define RSA_KEY_READ 0 +#define RSA_KEY_WRITE 1 +#define SE_RSA_KEY_OP(x) ((x) << 10) -#define SE_CONTEXT_SAVE_RSA_KNOWN_PATTERN_OFFSET \ - (SE_CONTEXT_SAVE_RSA_KEYS_OFFSET + SE_CONTEXT_SAVE_RSA_KEY_LENGTH) +#define SE_RSA_KEYTABLE_DATA_REG 0x424 -#define SE_CONTEXT_KNOWN_PATTERN_SIZE 16 +#define SE_RSA_OUTPUT_REG 0x428 +#define SE_RSA_OUTPUT_REG_COUNT 64 -#define TEGRA_SE_RSA_KEYSLOT_COUNT 2 +#define SE_STATUS_REG 0x800 +#define SE_STATUS_STATE_IDLE 0 +#define SE_STATUS_STATE_BUSY 1 +#define SE_STATUS_STATE_WAIT_OUT 2 +#define SE_STATUS_STATE_WAIT_IN 3 +#define SE_STATUS_STATE_MASK 3 -#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C -#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 +#define SE_ERR_STATUS_REG 0x804 +#define SE_ERR_STATUS_SE_NS_ACCESS BIT(0) +#define SE_ERR_STATUS_BUSY_REG_WR BIT(1) +#define SE_ERR_STATUS_DST BIT(2) +#define SE_ERR_STATUS_SRK_USAGE_LIMIT BIT(3) +#define SE_ERR_STATUS_TZRAM_NS_ACCESS BIT(24) +#define SE_ERR_STATUS_TZRAM_ADDRESS BIT(25) -#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410 -#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0) -#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1) -#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG) -#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG BIT(2) -#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT BIT(2) -#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7 -#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F +#define SE_MISC_REG 0x808 +#define SE_ENTROPY_NEXT_192BIT BIT(0) +#define SE_ENTROPY_VN_BYPASS BIT(1) +#define SE_CLK_OVR_ON BIT(2) -#define SE_RSA_KEYTABLE_ADDR 0x420 -#define SE_RSA_KEYTABLE_DATA 0x424 -#define SE_RSA_OUTPUT 0x428 +#define SE_SPARE_REG 0x80C +#define SE_ERRATA_FIX_DISABLE 0 +#define SE_ERRATA_FIX_ENABLE 1 +#define SE_ECO(x) ((x) << 0) -#define RSA_KEY_READ 0 -#define RSA_KEY_WRITE 1 -#define SE_RSA_KEY_OP_SHIFT 10 -#define SE_RSA_KEY_OP(x) ((x) << SE_RSA_KEY_OP_SHIFT) - -#define RSA_KEY_INPUT_MODE_REG 0 -#define RSA_KEY_INPUT_MODE_DMA 1 -#define RSA_KEY_INPUT_MODE_SHIFT 8 -#define RSA_KEY_INPUT_MODE(x) ((x) << RSA_KEY_INPUT_MODE_SHIFT) - -#define RSA_KEY_SLOT_ONE 0 -#define RSA_KEY_SLOT_TW0 1 -#define RSA_KEY_NUM_SHIFT 7 -#define RSA_KEY_NUM(x) ((x) << RSA_KEY_NUM_SHIFT) - -#define RSA_KEY_TYPE_EXP 0 -#define RSA_KEY_TYPE_MOD 1 -#define RSA_KEY_TYPE_SHIFT 6 -#define RSA_KEY_TYPE(x) ((x) << RSA_KEY_TYPE_SHIFT) - -#define SE_RSA_KEY_SIZE_REG_OFFSET 0x404 -#define SE_RSA_EXP_SIZE_REG_OFFSET 0x408 - -#define RSA_KEY_SLOT_SHIFT 24 -#define RSA_KEY_SLOT(x) ((x) << RSA_KEY_SLOT_SHIFT) -#define SE_RSA_CONFIG 0x400 - -#define RSA_KEY_PKT_WORD_ADDR_SHIFT 0 -#define RSA_KEY_PKT_WORD_ADDR(x) ((x) << RSA_KEY_PKT_WORD_ADDR_SHIFT) - -#define RSA_KEY_WORD_ADDR_SHIFT 0 -#define RSA_KEY_WORD_ADDR(x) ((x) << RSA_KEY_WORD_ADDR_SHIFT) - -#define SE_RSA_KEYTABLE_PKT_SHIFT 0 -#define SE_RSA_KEYTABLE_PKT(x) ((x) << SE_RSA_KEYTABLE_PKT_SHIFT) - -#endif /* _CRYPTO_TEGRA_SE_H */ +#endif diff --git a/bdk/sec/tsec.c b/bdk/sec/tsec.c index 3361144..adf5ac2 100644 --- a/bdk/sec/tsec.c +++ b/bdk/sec/tsec.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2019 CTCaer + * Copyright (c) 2018-2021 CTCaer * Copyright (c) 2018 balika011 * * This program is free software; you can redistribute it and/or modify it @@ -70,7 +70,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) u32 *pkg11_magic_off; bpmp_mmu_disable(); - bpmp_clk_rate_set(BPMP_CLK_NORMAL); + bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); // Enable clocks. clock_enable_host1x(); @@ -190,7 +190,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) if (kb == KB_TSEC_FW_EMU_COMPAT) { u32 start = get_tmr_us(); - u32 k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4]; + u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4]; u32 key[16] = {0}; u32 kidx = 0; @@ -198,9 +198,9 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) { smmu_flush_all(); - if (k != se[SE_KEYTABLE_DATA0_REG_OFFSET / 4]) + if (k != se[SE_CRYPTO_KEYTABLE_DATA_REG / 4]) { - k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4]; + k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4]; key[kidx++] = k; } @@ -269,7 +269,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0; SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0; - memcpy(tsec_keys, &buf, 0x10); + memcpy(tsec_keys, &buf, SE_KEY_128_SIZE); } out_free:; @@ -284,7 +284,7 @@ out:; clock_disable_sor_safe(); clock_disable_tsec(); bpmp_mmu_enable(); - bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST); + bpmp_clk_rate_set(prev_fid); return res; } diff --git a/bdk/soc/bpmp.c b/bdk/soc/bpmp.c index 2e1819d..fc0e412 100644 --- a/bdk/soc/bpmp.c +++ b/bdk/soc/bpmp.c @@ -1,7 +1,7 @@ /* * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1 * - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -212,43 +212,45 @@ const u8 pll_divn[] = { //95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB. }; -bpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL; +bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL; void bpmp_clk_rate_get() { bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3; if (clk_src_is_pllp) - bpmp_clock_set = BPMP_CLK_NORMAL; + bpmp_fid_current = BPMP_CLK_NORMAL; else { - bpmp_clock_set = BPMP_CLK_HIGH_BOOST; + bpmp_fid_current = BPMP_CLK_HIGH_BOOST; u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF; for (u32 i = 1; i < sizeof(pll_divn); i++) { if (pll_divn[i] == pll_divn_curr) { - bpmp_clock_set = i; + bpmp_fid_current = i; break; } } } } -void bpmp_clk_rate_set(bpmp_freq_t fid) +bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid) { + bpmp_freq_t prev_fid = bpmp_fid_current; + if (fid > (BPMP_CLK_MAX - 1)) fid = BPMP_CLK_MAX - 1; - if (bpmp_clock_set == fid) - return; + if (prev_fid == fid) + return prev_fid; if (fid) { - if (bpmp_clock_set) + if (prev_fid) { - // Restore to PLLP source during PLLC4 configuration. + // Restore to PLLP source during PLLC configuration. CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // PLLP_OUT. msleep(1); // Wait a bit for clock source change. } @@ -269,7 +271,10 @@ void bpmp_clk_rate_set(bpmp_freq_t fid) // Disable PLLC to save power. clock_disable_pllc(); } - bpmp_clock_set = fid; + bpmp_fid_current = fid; + + // Return old fid in case of temporary swap. + return prev_fid; } // The following functions halt BPMP to reduce power while sleeping. diff --git a/bdk/soc/bpmp.h b/bdk/soc/bpmp.h index 81f000b..0f80150 100644 --- a/bdk/soc/bpmp.h +++ b/bdk/soc/bpmp.h @@ -1,7 +1,7 @@ /* * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1 * - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -53,6 +53,7 @@ typedef enum BPMP_CLK_MAX } bpmp_freq_t; +#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST #define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST void bpmp_mmu_maintenance(u32 op, bool force); @@ -60,7 +61,7 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply); void bpmp_mmu_enable(); void bpmp_mmu_disable(); void bpmp_clk_rate_get(); -void bpmp_clk_rate_set(bpmp_freq_t fid); +bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid); void bpmp_usleep(u32 us); void bpmp_msleep(u32 ms); void bpmp_halt(); diff --git a/bdk/soc/hw_init.c b/bdk/soc/hw_init.c index 5c81b1a..1da102f 100644 --- a/bdk/soc/hw_init.c +++ b/bdk/soc/hw_init.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -42,6 +42,7 @@ #include #include #include +#include #include extern boot_cfg_t b_cfg; @@ -87,6 +88,7 @@ static void _config_oscillators() CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3. } +// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula. static void _config_gpios(bool nx_hoag) { // Clamp inputs when tristated. @@ -263,7 +265,7 @@ static void _config_se_brom() FUSE(FUSE_PRIVATE_KEY3) }; // Set SBK to slot 14. - se_aes_key_set(14, sbk, 0x10); + se_aes_key_set(14, sbk, SE_KEY_128_SIZE); // Lock SBK from being read. se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG); @@ -275,7 +277,7 @@ static void _config_se_brom() // This memset needs to happen here, else TZRAM will behave weirdly later on. memset((void *)TZRAM_BASE, 0, 0x10000); PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE; - SE(SE_INT_STATUS_REG_OFFSET) = 0x1F; + SE(SE_INT_STATUS_REG) = 0x1F; // Clear all SE interrupts. // Clear the boot reason to avoid problems later PMC(APBDEV_PMC_SCRATCH200) = 0x0; @@ -419,19 +421,18 @@ void hw_init() bpmp_mmu_enable(); } -void hw_reinit_workaround(bool coreboot, u32 magic) +void hw_reinit_workaround(bool coreboot, u32 bl_magic) { // Disable BPMP max clock. bpmp_clk_rate_set(BPMP_CLK_NORMAL); #ifdef NYX - // Deinit touchscreen, 5V regulators and Joy-Con. - touch_power_off(); + // Disable temperature sensor, touchscreen, 5V regulators and Joy-Con. + tmp451_end(); set_fan_duty(0); + touch_power_off(); jc_deinit(); regulator_5v_disable(REGULATOR_5V_ALL); - clock_disable_uart(UART_B); - clock_disable_uart(UART_C); #endif // Flush/disable MMU cache and set DRAM clock to 204MHz. @@ -460,11 +461,22 @@ void hw_reinit_workaround(bool coreboot, u32 magic) PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN); } - // Power off display. - display_end(); + // Seamless display or display power off. + switch (bl_magic) + { + case BL_MAGIC_CRBOOT_SLD:; + // Set pwm to 0%, switch to gpio mode and restore pwm duty. + u32 brightness = display_get_backlight_brightness(); + display_backlight_brightness(0, 1000); + gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO); + display_backlight_brightness(brightness, 0); + break; + default: + display_end(); + } // Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits. - if (magic == 0xBAADF00D) + if (bl_magic == BL_MAGIC_BROKEN_HWI) { CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD); sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0); diff --git a/bdk/soc/hw_init.h b/bdk/soc/hw_init.h index 8888824..a1b2dfc 100644 --- a/bdk/soc/hw_init.h +++ b/bdk/soc/hw_init.h @@ -20,6 +20,9 @@ #include +#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0. +#define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit. + void hw_init(); void hw_reinit_workaround(bool coreboot, u32 magic); u32 hw_get_chip_id(); diff --git a/bdk/soc/uart.c b/bdk/soc/uart.c index 75e18b8..582bca1 100644 --- a/bdk/soc/uart.c +++ b/bdk/soc/uart.c @@ -122,7 +122,12 @@ u32 uart_get_IIR(u32 idx) { uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); - return uart->UART_IIR_FCR; + u32 iir = uart->UART_IIR_FCR & UART_IIR_INT_MASK; + + if (iir & UART_IIR_NO_INT) + return 0; + else + return ((iir >> 1) + 1); // Return encoded interrupt. } void uart_set_IIR(u32 idx) diff --git a/bdk/soc/uart.h b/bdk/soc/uart.h index 809192a..6a4c073 100644 --- a/bdk/soc/uart.h +++ b/bdk/soc/uart.h @@ -54,6 +54,17 @@ #define UART_IIR_FCR_RX_CLR 0x2 #define UART_IIR_FCR_EN_FIFO 0x1 +#define UART_IIR_NO_INT BIT(0) +#define UART_IIR_INT_MASK 0xF +/* Custom returned interrupt results. Actual interrupts are -1 */ +#define UART_IIR_NOI 0 // No interrupt. +#define UART_IIR_MSI 1 // Modem status interrupt. +#define UART_IIR_THRI 2 // Transmitter holding register empty. +#define UART_IIR_RDI 3 // Receiver data interrupt. +#define UART_IIR_ERROR 4 // Overrun Error, Parity Error, Framing Error, Break. +#define UART_IIR_REDI 5 // Receiver end of data interrupt. +#define UART_IIR_RDTI 7 // Receiver data timeout interrupt. + #define UART_MCR_RTS 0x2 #define UART_MCR_DTR 0x1 diff --git a/bdk/storage/mmc.h b/bdk/storage/mmc.h index 976ded4..fc6c2f8 100644 --- a/bdk/storage/mmc.h +++ b/bdk/storage/mmc.h @@ -84,6 +84,11 @@ #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ +#define MMC_VENDOR_60_CMD 60 /* Vendor Defined */ +#define MMC_VENDOR_61_CMD 61 /* Vendor Defined */ +#define MMC_VENDOR_62_CMD 62 /* Vendor Defined */ +#define MMC_VENDOR_63_CMD 63 /* Vendor Defined */ + /* class 11 */ #define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */ #define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */ @@ -182,7 +187,10 @@ c : clear by read /* * OCR bits are mostly in host.h */ -#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ +#define MMC_CARD_VDD_18 (1 << 7) /* Card VDD voltage 1.8 */ +#define MMC_CARD_VDD_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */ +#define MMC_CARD_CCS (1 << 30) /* Card Capacity status bit */ +#define MMC_CARD_BUSY (1 << 31) /* Card Power up status bit */ /* * Card Command Classes (CCC) @@ -244,6 +252,7 @@ c : clear by read #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ #define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */ #define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ +#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* RO, 3 bytes */ #define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ #define EXT_CSD_HPI_MGMT 161 /* R/W */ #define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ diff --git a/bdk/storage/nx_sd.h b/bdk/storage/nx_sd.h index bc4c2d4..e2b703f 100644 --- a/bdk/storage/nx_sd.h +++ b/bdk/storage/nx_sd.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2019 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -45,12 +45,15 @@ extern FATFS sd_fs; void sd_error_count_increment(u8 type); u16 *sd_get_error_count(); bool sd_get_card_removed(); +bool sd_get_card_initialized(); +bool sd_get_card_mounted(); u32 sd_get_mode(); int sd_init_retry(bool power_cycle); bool sd_initialize(bool power_cycle); bool sd_mount(); void sd_unmount(); void sd_end(); +bool sd_is_gpt(); void *sd_file_read(const char *path, u32 *fsize); int sd_save_to_file(void *buf, u32 size, const char *filename); diff --git a/bdk/storage/ramdisk.c b/bdk/storage/ramdisk.c index e7b7c01..315075d 100644 --- a/bdk/storage/ramdisk.c +++ b/bdk/storage/ramdisk.c @@ -1,7 +1,7 @@ /* * Ramdisk driver for Tegra X1 * - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -19,23 +19,40 @@ #include #include "ramdisk.h" +#include #include #include #include -int ram_disk_init(FATFS *ram_fs) +static u32 disk_size = 0; + +int ram_disk_init(FATFS *ram_fs, u32 ramdisk_size) { - int res; - u8 *buf = malloc(0x400000); + int res = 0; + disk_size = ramdisk_size; - f_mount(NULL, "ram:", 1); // Unmount ramdisk. + // If ramdisk is not raw, format it. + if (ram_fs) + { + u8 *buf = malloc(0x400000); - res = f_mkfs("ram:", FM_EXFAT, RAMDISK_CLUSTER_SZ, buf, 0x400000); // Format as exFAT w/ 32KB cluster. - if (!res) - res = f_mount(ram_fs, "ram:", 1); // Mount ramdisk. + // Set ramdisk size. + ramdisk_size >>= 9; + disk_set_info(DRIVE_RAM, SET_SECTOR_COUNT, &ramdisk_size); - free(buf); + // Unmount ramdisk. + f_mount(NULL, "ram:", 1); + + // Format as exFAT w/ 32KB cluster with no MBR. + res = f_mkfs("ram:", FM_EXFAT | FM_SFD, RAMDISK_CLUSTER_SZ, buf, 0x400000); + + // Mount ramdisk. + if (!res) + res = f_mount(ram_fs, "ram:", 1); + + free(buf); + } return res; } @@ -45,7 +62,7 @@ int ram_disk_read(u32 sector, u32 sector_count, void *buf) u32 sector_off = RAM_DISK_ADDR + (sector << 9); u32 bytes_count = sector_count << 9; - if ((sector_off - RAM_DISK_ADDR) > RAM_DISK_SZ) + if ((sector_off - RAM_DISK_ADDR) > disk_size) return 1; memcpy(buf, (void *)sector_off, bytes_count); @@ -58,7 +75,7 @@ int ram_disk_write(u32 sector, u32 sector_count, const void *buf) u32 sector_off = RAM_DISK_ADDR + (sector << 9); u32 bytes_count = sector_count << 9; - if ((sector_off - RAM_DISK_ADDR) > RAM_DISK_SZ) + if ((sector_off - RAM_DISK_ADDR) > disk_size) return 1; memcpy((void *)sector_off, buf, bytes_count); diff --git a/bdk/storage/ramdisk.h b/bdk/storage/ramdisk.h index ef43bb5..e625235 100644 --- a/bdk/storage/ramdisk.h +++ b/bdk/storage/ramdisk.h @@ -1,7 +1,7 @@ /* * Ramdisk driver for Tegra X1 * - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -23,7 +23,7 @@ #define RAMDISK_CLUSTER_SZ 32768 -int ram_disk_init(FATFS *ram_fs); +int ram_disk_init(FATFS *ram_fs, u32 ramdisk_size); int ram_disk_read(u32 sector, u32 sector_count, void *buf); int ram_disk_write(u32 sector, u32 sector_count, const void *buf); diff --git a/bdk/storage/sd.h b/bdk/storage/sd.h index 848a679..22d3359 100644 --- a/bdk/storage/sd.h +++ b/bdk/storage/sd.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved. - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,60 +14,79 @@ /* SD commands type argument response */ /* class 0 */ /* This is basically the same command as for MMC with some quirks. */ -#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ -#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ -#define SD_SWITCH_VOLTAGE 11 /* ac R1 */ - +#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ +#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ +#define SD_SWITCH_VOLTAGE 11 /* ac R1 */ /* class 10 */ -#define SD_SWITCH 6 /* adtc [31:0] See below R1 */ - +#define SD_SWITCH 6 /* adtc [31:0] See below R1 */ /* class 5 */ -#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */ -#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */ +#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */ +#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */ /* Application commands */ -#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ -#define SD_APP_SD_STATUS 13 /* adtc R1 */ -#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ -#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ -#define SD_APP_SET_CLR_CARD_DETECT 42 -#define SD_APP_SEND_SCR 51 /* adtc R1 */ +#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ +#define SD_APP_SD_STATUS 13 /* adtc R1 */ +#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ +#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ +#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */ +#define SD_APP_SEND_SCR 51 /* adtc R1 */ + +/* Application secure commands */ +#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */ +#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */ +#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */ +#define SD_APP_SECURE_ERASE 38 /* adtc R1b */ +#define SD_APP_GET_MKB 43 /* adtc [31:0] See below R1 */ +#define SD_APP_GET_MID 44 /* adtc R1 */ +#define SD_APP_SET_CER_RN1 45 /* adtc R1 */ +#define SD_APP_GET_CER_RN2 46 /* adtc R1 */ +#define SD_APP_SET_CER_RES2 47 /* adtc R1 */ +#define SD_APP_GET_CER_RES1 48 /* adtc R1 */ +#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */ /* OCR bit definitions */ -#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */ -#define SD_OCR_XPC (1 << 28) /* SDXC power control */ -#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ -#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ +#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */ +#define SD_VHD_27_36 (1 << 8) /* VDD voltage 2.7 ~ 3.6 */ #define SD_OCR_VDD_27_34 (0x7F << 15) /* VDD voltage 2.7 ~ 3.4 */ #define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */ -#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */ - -#define SD_VHD_27_36 (1 << 8) /* VDD voltage 2.7 ~ 3.6 */ +#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ +#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ +#define SD_OCR_XPC (1 << 28) /* SDXC power control */ +#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */ +#define SD_OCR_BUSY (1 << 31) /* Card Power up Status */ /* -* SD_SWITCH argument format: -* -* [31] Check (0) or switch (1) -* [30:24] Reserved (0) -* [23:20] Function group 6 -* [19:16] Function group 5 -* [15:12] Function group 4 -* [11:8] Function group 3 -* [7:4] Function group 2 -* [3:0] Function group 1 -*/ + * SD_SWITCH argument format: + * + * [31] Check (0) or switch (1) + * [30:24] Reserved (0) + * [23:20] Function group 6 + * [19:16] Function group 5 + * [15:12] Function group 4 + * [11:8] Function group 3 + * [7:4] Function group 2 + * [3:0] Function group 1 + */ /* -* SD_SEND_IF_COND argument format: -* -* [31:12] Reserved (0) -* [11:8] Host Voltage Supply Flags -* [7:0] Check Pattern (0xAA) -*/ + * SD_SEND_IF_COND argument format: + * + * [31:12] Reserved (0) + * [11:8] Host Voltage Supply Flags + * [7:0] Check Pattern (0xAA) + */ /* -* SCR field definitions -*/ + * SD_APP_GET_MKB argument format: + * + * [31:24] Number of blocks to read (512 block size) + * [23:16] MKB ID + * [15:0] Block offset + */ + +/* + * SCR field definitions + */ #define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ #define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ #define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */ @@ -75,14 +94,14 @@ #define SD_SCR_BUS_WIDTH_4 (1<<2) /* -* SD bus widths -*/ + * SD bus widths + */ #define SD_BUS_WIDTH_1 0 #define SD_BUS_WIDTH_4 2 /* -* SD bus speeds -*/ + * SD bus speeds + */ #define UHS_SDR12_BUS_SPEED 0 #define HIGH_SPEED_BUS_SPEED 1 #define UHS_SDR25_BUS_SPEED 1 @@ -112,19 +131,19 @@ #define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800) /* -* SD_SWITCH mode -*/ + * SD_SWITCH mode + */ #define SD_SWITCH_CHECK 0 #define SD_SWITCH_SET 1 /* -* SD_SWITCH function groups -*/ + * SD_SWITCH function groups + */ #define SD_SWITCH_GRP_ACCESS 0 /* -* SD_SWITCH access modes -*/ + * SD_SWITCH access modes + */ #define SD_SWITCH_ACCESS_DEF 0 #define SD_SWITCH_ACCESS_HS 1 diff --git a/bdk/storage/sdmmc.c b/bdk/storage/sdmmc.c index 58e813e..54b19de 100644 --- a/bdk/storage/sdmmc.c +++ b/bdk/storage/sdmmc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -42,8 +42,8 @@ static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size) } /* -* Common functions for SD and MMC. -*/ + * Common functions for SD and MMC. + */ static int _sdmmc_storage_check_card_status(u32 res) { @@ -88,20 +88,20 @@ static int _sdmmc_storage_execute_cmd_type1(sdmmc_storage_t *storage, u32 cmd, u static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage) { - sdmmc_cmd_t cmd; - sdmmc_init_cmd(&cmd, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0); + sdmmc_cmd_t cmdbuf; + sdmmc_init_cmd(&cmdbuf, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0); - return sdmmc_execute_cmd(storage->sdmmc, &cmd, NULL, NULL); + return sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL); } -static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage, void *buf) +static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage) { - sdmmc_cmd_t cmd; - sdmmc_init_cmd(&cmd, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0); - if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, NULL, NULL)) + sdmmc_cmd_t cmdbuf; + sdmmc_init_cmd(&cmdbuf, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0); + if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL)) return 0; - sdmmc_get_rsp(storage->sdmmc, buf, 16, SDMMC_RSP_TYPE_2); + sdmmc_get_rsp(storage->sdmmc, (u32 *)storage->raw_cid, 16, SDMMC_RSP_TYPE_2); return 1; } @@ -111,14 +111,14 @@ static int _sdmmc_storage_select_card(sdmmc_storage_t *storage) return _sdmmc_storage_execute_cmd_type1(storage, MMC_SELECT_CARD, storage->rca << 16, 1, R1_SKIP_STATE_CHECK); } -static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage, void *buf) +static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage) { sdmmc_cmd_t cmdbuf; sdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0); if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL)) return 0; - sdmmc_get_rsp(storage->sdmmc, buf, 16, SDMMC_RSP_TYPE_2); + sdmmc_get_rsp(storage->sdmmc, (u32 *)storage->raw_csd, 16, SDMMC_RSP_TYPE_2); return 1; } @@ -145,6 +145,10 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out sdmmc_cmd_t cmdbuf; sdmmc_req_t reqbuf; + // If SDSC convert block address to byte address. + if (!storage->has_sector_access) + sector <<= 9; + sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0); reqbuf.buf = buf; @@ -152,7 +156,7 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out reqbuf.blksize = 512; reqbuf.is_write = is_write; reqbuf.is_multi_block = 1; - reqbuf.is_auto_cmd12 = 1; + reqbuf.is_auto_stop_trn = 1; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out)) { @@ -288,25 +292,25 @@ int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, v static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u32 power) { - sdmmc_cmd_t cmd; + sdmmc_cmd_t cmdbuf; u32 arg = 0; switch (power) { case SDMMC_POWER_1_8: - arg = SD_OCR_CCS | SD_OCR_VDD_18; + arg = MMC_CARD_CCS | MMC_CARD_VDD_18; break; case SDMMC_POWER_3_3: - arg = SD_OCR_CCS | SD_OCR_VDD_27_34; + arg = MMC_CARD_CCS | MMC_CARD_VDD_27_34; break; default: return 0; } - sdmmc_init_cmd(&cmd, MMC_SEND_OP_COND, arg, SDMMC_RSP_TYPE_3, 0); - if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, NULL, NULL)) + sdmmc_init_cmd(&cmdbuf, MMC_SEND_OP_COND, arg, SDMMC_RSP_TYPE_3, 0); + if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL)) return 0; return sdmmc_get_rsp(storage->sdmmc, pout, 4, SDMMC_RSP_TYPE_3); @@ -316,15 +320,17 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power) { u32 timeout = get_tmr_ms() + 1500; - while (1) + while (true) { u32 cond = 0; if (!_mmc_storage_get_op_cond_inner(storage, &cond, power)) break; + // Check if power up is done. if (cond & MMC_CARD_BUSY) { - if (cond & SD_OCR_CCS) + // Check if card is high capacity. + if (cond & MMC_CARD_CCS) storage->has_sector_access = 1; return 1; @@ -362,7 +368,6 @@ static void _mmc_storage_parse_cid(sdmmc_storage_t *storage) case 3: /* MMC v3.1 - v3.3 */ case 4: /* MMC v4 */ storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); - storage->cid.card_bga = unstuff_bits(raw_cid, 112, 2); storage->cid.oemid = unstuff_bits(raw_cid, 104, 8); storage->cid.prv = unstuff_bits(raw_cid, 48, 8); storage->cid.serial = unstuff_bits(raw_cid, 16, 32); @@ -390,13 +395,14 @@ static void _mmc_storage_parse_cid(sdmmc_storage_t *storage) static void _mmc_storage_parse_csd(sdmmc_storage_t *storage) { - u32 *raw_csd = (u32 *)&(storage->raw_csd); + u32 *raw_csd = (u32 *)storage->raw_csd; storage->csd.mmca_vsn = unstuff_bits(raw_csd, 122, 4); storage->csd.structure = unstuff_bits(raw_csd, 126, 2); storage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12); storage->csd.read_blkbits = unstuff_bits(raw_csd, 80, 4); storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2); + storage->sec_cnt = storage->csd.capacity; } static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf) @@ -407,16 +413,26 @@ static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf) storage->ext_csd.dev_version = *(u16 *)&buf[EXT_CSD_DEVICE_VERSION]; storage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT]; storage->ext_csd.rpmb_mult = buf[EXT_CSD_RPMB_MULT]; - storage->ext_csd.sectors = *(u32 *)&buf[EXT_CSD_SEC_CNT]; - storage->ext_csd.bkops = buf[EXT_CSD_BKOPS_SUPPORT]; - storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN]; - storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS]; + //storage->ext_csd.bkops = buf[EXT_CSD_BKOPS_SUPPORT]; + //storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN]; + //storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS]; storage->ext_csd.pre_eol_info = buf[EXT_CSD_PRE_EOL_INFO]; storage->ext_csd.dev_life_est_a = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]; storage->ext_csd.dev_life_est_b = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]; - storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT]; + storage->ext_csd.cache_size = + buf[EXT_CSD_CACHE_SIZE] | + (buf[EXT_CSD_CACHE_SIZE + 1] << 8) | + (buf[EXT_CSD_CACHE_SIZE + 2] << 16) | + (buf[EXT_CSD_CACHE_SIZE + 3] << 24); + storage->ext_csd.max_enh_mult = + (buf[EXT_CSD_MAX_ENH_SIZE_MULT] | + (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 1] << 8) | + (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 2] << 16)) * + buf[EXT_CSD_HC_WP_GRP_SIZE] * buf[EXT_CSD_HC_ERASE_GRP_SIZE]; + + storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT]; } static int _mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf) @@ -430,7 +446,7 @@ static int _mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf) reqbuf.num_sectors = 1; reqbuf.is_write = 0; reqbuf.is_multi_block = 0; - reqbuf.is_auto_cmd12 = 0; + reqbuf.is_auto_stop_trn = 0; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL)) return 0; @@ -559,19 +575,21 @@ out: return 1; } +/* static int _mmc_storage_enable_bkops(sdmmc_storage_t *storage) { - if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_BKOPS_LEVEL_2))) + if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_AUTO_BKOPS_MASK))) return 0; return _sdmmc_storage_check_status(storage); } +*/ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type) { memset(storage, 0, sizeof(sdmmc_storage_t)); storage->sdmmc = sdmmc; - storage->rca = 2; //TODO: this could be a config item. + storage->rca = 2; // Set default device address. This could be a config item. if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_MMC_ID, SDMMC_POWER_SAVE_DISABLE)) return 0; @@ -587,7 +605,7 @@ DPRINTF("[MMC] went to idle state\n"); return 0; DPRINTF("[MMC] got op cond\n"); - if (!_sdmmc_storage_get_cid(storage, storage->raw_cid)) + if (!_sdmmc_storage_get_cid(storage)) return 0; DPRINTF("[MMC] got cid\n"); @@ -595,7 +613,7 @@ DPRINTF("[MMC] got cid\n"); return 0; DPRINTF("[MMC] set relative addr\n"); - if (!_sdmmc_storage_get_csd(storage, storage->raw_csd)) + if (!_sdmmc_storage_get_csd(storage)) return 0; DPRINTF("[MMC] got csd\n"); _mmc_storage_parse_csd(storage); @@ -612,13 +630,9 @@ DPRINTF("[MMC] card selected\n"); return 0; DPRINTF("[MMC] set blocklen to 512\n"); - u32 *csd = (u32 *)storage->raw_csd; - //Check system specification version, only version 4.0 and later support below features. - if (unstuff_bits(csd, 122, 4) < CSD_SPEC_VER_4) - { - storage->sec_cnt = (1 + unstuff_bits(csd, 62, 12)) << (unstuff_bits(csd, 47, 3) + 2); + // Check system specification version, only version 4.0 and later support below features. + if (storage->csd.mmca_vsn < CSD_SPEC_VER_4) return 1; - } if (!_mmc_storage_switch_buswidth(storage, bus_width)) return 0; @@ -628,21 +642,20 @@ DPRINTF("[MMC] switched buswidth\n"); return 0; DPRINTF("[MMC] got ext_csd\n"); - _mmc_storage_parse_cid(storage); //This needs to be after csd and ext_csd + _mmc_storage_parse_cid(storage); // This needs to be after csd and ext_csd. //gfx_hexdump(0, ext_csd, 512); - /* When auto BKOPS is enabled the mmc device should be powered all the time until we disable this and check status. - Disable it for now until BKOPS disable added to power down sequence at sdmmc_storage_end(). - Additionally this works only when we put the device in idle mode which we don't after enabling it. */ - if (0 && storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_BKOPS_LEVEL_2)) +/* + if (storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_AUTO_BKOPS_MASK)) { _mmc_storage_enable_bkops(storage); DPRINTF("[MMC] BKOPS enabled\n"); } +*/ if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type)) return 0; -DPRINTF("[MMC] succesfully switched to HS mode\n"); +DPRINTF("[MMC] successfully switched to HS mode\n"); sdmmc_card_clock_powersave(storage->sdmmc, SDMMC_POWER_SAVE_ENABLE); @@ -665,16 +678,16 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition) } /* -* SD specific functions. -*/ + * SD specific functions. + */ -static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out) +static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmdbuf, sdmmc_req_t *req, u32 *blkcnt_out) { u32 tmp; if (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask)) return 0; - return sdmmc_execute_cmd(storage->sdmmc, cmd, req, blkcnt_out); + return sdmmc_execute_cmd(storage->sdmmc, cmdbuf, req, blkcnt_out); } static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state) @@ -685,67 +698,70 @@ static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0); } -static int _sd_storage_send_if_cond(sdmmc_storage_t *storage) +static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc) { sdmmc_cmd_t cmdbuf; u16 vhd_pattern = SD_VHD_27_36 | 0xAA; sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0); if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL)) - return 1; // The SD Card is version 1.X + { + *is_sdsc = 1; // The SD Card is version 1.X + return 1; + } - // Card version is >= 2.0, parse results. + // For Card version >= 2.0, parse results. u32 resp = 0; - if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5)) - return 2; // Failed. + sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5); // Check if VHD was accepted and pattern was properly returned. if ((resp & 0xFFF) == vhd_pattern) - return 0; + return 1; - // Failed. - return 2; + return 0; } -static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int bus_uhs_support) +static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, bool is_sdsc, int bus_uhs_support) { sdmmc_cmd_t cmdbuf; // Support for Current > 150mA - u32 arg = !is_version_1 ? SD_OCR_XPC : 0; + u32 arg = !is_sdsc ? SD_OCR_XPC : 0; // Support for handling block-addressed SDHC cards - arg |= !is_version_1 ? SD_OCR_CCS : 0; + arg |= !is_sdsc ? SD_OCR_CCS : 0; // Support for 1.8V - arg |= (bus_uhs_support && !is_version_1) ? SD_OCR_S18R : 0; + arg |= (bus_uhs_support && !is_sdsc) ? SD_OCR_S18R : 0; // This is needed for most cards. Do not set bit7 even if 1.8V is supported. arg |= SD_OCR_VDD_32_33; sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0); - if (!_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_version_1 ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL)) + if (!_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sdsc ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL)) return 0; return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3); } -static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int bus_uhs_support) +static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int bus_uhs_support) { u32 timeout = get_tmr_ms() + 1500; - while (1) + while (true) { u32 cond = 0; - if (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, bus_uhs_support)) + if (!_sd_storage_get_op_cond_once(storage, &cond, is_sdsc, bus_uhs_support)) break; - if (cond & MMC_CARD_BUSY) + + // Check if power up is done. + if (cond & SD_OCR_BUSY) { DPRINTF("[SD] op cond: %08X, lv: %d\n", cond, bus_uhs_support); + // Check if card is high capacity. if (cond & SD_OCR_CCS) storage->has_sector_access = 1; // Check if card supports 1.8V signaling. if (cond & SD_ROCR_S18A && bus_uhs_support) { - //The low voltage regulator configuration is valid for SDMMC1 only. - if (storage->sdmmc->id == SDMMC_1 && - _sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY)) + // Switch to 1.8V signaling. + if (_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY)) { if (!sdmmc_enable_low_voltage(storage->sdmmc)) return 0; @@ -776,7 +792,7 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage) u32 timeout = get_tmr_ms() + 1500; - while (1) + while (true) { if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL)) break; @@ -809,8 +825,9 @@ static void _sd_storage_parse_scr(sdmmc_storage_t *storage) storage->scr.sda_vsn = unstuff_bits(resp, 56, 4); storage->scr.bus_widths = unstuff_bits(resp, 48, 4); + + /* If v2.0 is supported, check if Physical Layer Spec v3.0 is supported */ if (storage->scr.sda_vsn == SCR_SPEC_VER_2) - /* Check if Physical Layer Spec v3.0 is supported */ storage->scr.sda_spec3 = unstuff_bits(resp, 47, 1); if (storage->scr.sda_spec3) storage->scr.cmds = unstuff_bits(resp, 32, 2); @@ -827,7 +844,7 @@ int _sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf) reqbuf.num_sectors = 1; reqbuf.is_write = 0; reqbuf.is_multi_block = 0; - reqbuf.is_auto_cmd12 = 0; + reqbuf.is_auto_stop_trn = 0; if (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL)) return 0; @@ -859,7 +876,7 @@ int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf) reqbuf.num_sectors = 1; reqbuf.is_write = 0; reqbuf.is_multi_block = 0; - reqbuf.is_auto_cmd12 = 0; + reqbuf.is_auto_stop_trn = 0; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL)) return 0; @@ -883,7 +900,7 @@ int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, reqbuf.num_sectors = 1; reqbuf.is_write = 0; reqbuf.is_multi_block = 0; - reqbuf.is_auto_cmd12 = 0; + reqbuf.is_auto_stop_trn = 0; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL)) return 0; @@ -1064,7 +1081,7 @@ int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf) return sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_HS25); } -u32 sd_storage_ssr_get_au(sdmmc_storage_t *storage) +u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage) { u32 au_size = storage->ssr.uhs_au_size; @@ -1104,39 +1121,24 @@ u32 sd_storage_ssr_get_au(sdmmc_storage_t *storage) static void _sd_storage_parse_ssr(sdmmc_storage_t *storage) { - // unstuff_bits supports only 4 u32 so break into 2 x 16byte groups + // unstuff_bits supports only 4 u32 so break into 2 x u32x4 groups. u32 raw_ssr1[4]; u32 raw_ssr2[4]; - raw_ssr1[3] = *(u32 *)&storage->raw_ssr[12]; - raw_ssr1[2] = *(u32 *)&storage->raw_ssr[8]; - raw_ssr1[1] = *(u32 *)&storage->raw_ssr[4]; - raw_ssr1[0] = *(u32 *)&storage->raw_ssr[0]; - - raw_ssr2[3] = *(u32 *)&storage->raw_ssr[28]; - raw_ssr2[2] = *(u32 *)&storage->raw_ssr[24]; - raw_ssr2[1] = *(u32 *)&storage->raw_ssr[20]; - raw_ssr2[0] = *(u32 *)&storage->raw_ssr[16]; + memcpy(raw_ssr1, &storage->raw_ssr[0], 16); + memcpy(raw_ssr2, &storage->raw_ssr[16], 16); storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1; storage->ssr.protected_size = unstuff_bits(raw_ssr1, 448 - 384, 32); - switch(unstuff_bits(raw_ssr1, 440 - 384, 8)) + u32 speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8); + switch(speed_class) { case 0: - storage->ssr.speed_class = 0; - break; - case 1: - storage->ssr.speed_class = 2; - break; - case 2: - storage->ssr.speed_class = 4; - break; - case 3: - storage->ssr.speed_class = 6; + storage->ssr.speed_class = speed_class << 1; break; case 4: @@ -1144,19 +1146,18 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage) break; default: - storage->ssr.speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8); + storage->ssr.speed_class = speed_class; break; } - storage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396 - 384, 4); + storage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396 - 384, 4); storage->ssr.video_class = unstuff_bits(raw_ssr1, 384 - 384, 8); + storage->ssr.app_class = unstuff_bits(raw_ssr2, 336 - 256, 4); - storage->ssr.app_class = unstuff_bits(raw_ssr2, 336 - 256, 4); - - storage->ssr.au_size = unstuff_bits(raw_ssr1, 428 - 384, 4); + storage->ssr.au_size = unstuff_bits(raw_ssr1, 428 - 384, 4); storage->ssr.uhs_au_size = unstuff_bits(raw_ssr1, 392 - 384, 4); } -static int _sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf) +int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf) { sdmmc_cmd_t cmdbuf; sdmmc_init_cmd(&cmdbuf, SD_APP_SD_STATUS, 0, SDMMC_RSP_TYPE_1, 0); @@ -1167,11 +1168,11 @@ static int _sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf) reqbuf.num_sectors = 1; reqbuf.is_write = 0; reqbuf.is_multi_block = 0; - reqbuf.is_auto_cmd12 = 0; + reqbuf.is_auto_stop_trn = 0; if (!(storage->csd.cmdclass & CCC_APP_SPEC)) { -DPRINTF("[SD] ssr: Card lacks mandatory SD Status function\n"); +DPRINTF("[SD] ssr: Not supported\n"); return 0; } @@ -1180,14 +1181,16 @@ DPRINTF("[SD] ssr: Card lacks mandatory SD Status function\n"); u32 tmp = 0; sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1); - //Prepare buffer for unstuff_bits - for (int i = 0; i < 64; i+=4) + + // Convert buffer to LE. + for (int i = 0; i < 64; i += 4) { storage->raw_ssr[i + 3] = buf[i]; storage->raw_ssr[i + 2] = buf[i + 1]; storage->raw_ssr[i + 1] = buf[i + 2]; storage->raw_ssr[i] = buf[i + 3]; } + _sd_storage_parse_ssr(storage); //gfx_hexdump(0, storage->raw_ssr, 64); @@ -1198,18 +1201,18 @@ static void _sd_storage_parse_cid(sdmmc_storage_t *storage) { u32 *raw_cid = (u32 *)&(storage->raw_cid); - storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); - storage->cid.oemid = unstuff_bits(raw_cid, 104, 16); - storage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8); - storage->cid.prod_name[1] = unstuff_bits(raw_cid, 88, 8); - storage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 8); - storage->cid.prod_name[3] = unstuff_bits(raw_cid, 72, 8); - storage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8); - storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4); - storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4); - storage->cid.serial = unstuff_bits(raw_cid, 24, 32); - storage->cid.month = unstuff_bits(raw_cid, 8, 4); - storage->cid.year = unstuff_bits(raw_cid, 12, 8) + 2000; + storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); + storage->cid.oemid = unstuff_bits(raw_cid, 104, 16); + storage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8); + storage->cid.prod_name[1] = unstuff_bits(raw_cid, 88, 8); + storage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 8); + storage->cid.prod_name[3] = unstuff_bits(raw_cid, 72, 8); + storage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8); + storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4); + storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4); + storage->cid.serial = unstuff_bits(raw_cid, 24, 32); + storage->cid.year = unstuff_bits(raw_cid, 12, 8) + 2000; + storage->cid.month = unstuff_bits(raw_cid, 8, 4); } static void _sd_storage_parse_csd(sdmmc_storage_t *storage) @@ -1224,6 +1227,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage) { case 0: storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2); + storage->csd.capacity <<= unstuff_bits(raw_csd, 80, 4) - 9; // Convert native block size to LBA 512B. break; case 1: @@ -1231,7 +1235,13 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage) storage->csd.capacity = storage->csd.c_size << 10; storage->csd.read_blkbits = 9; break; + + default: +DPRINTF("[SD] unknown CSD structure %d\n", storage->csd.structure); + break; } + + storage->sec_cnt = storage->csd.capacity; } static bool _sdmmc_storage_get_bus_uhs_support(u32 bus_width, u32 type) @@ -1261,8 +1271,10 @@ void sdmmc_storage_init_wait_sd() int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type) { - int is_version_1 = 0; - u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; + u32 tmp = 0; + int is_sdsc = 0; + u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; + bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type); DPRINTF("[SD] init: bus: %d, type: %d\n", bus_width, type); @@ -1282,18 +1294,15 @@ DPRINTF("[SD] after init\n"); return 0; DPRINTF("[SD] went to idle state\n"); - is_version_1 = _sd_storage_send_if_cond(storage); - if (is_version_1 == 2) // Failed. + if (!_sd_storage_send_if_cond(storage, &is_sdsc)) return 0; DPRINTF("[SD] after send if cond\n"); - bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type); - - if (!_sd_storage_get_op_cond(storage, is_version_1, bus_uhs_support)) + if (!_sd_storage_get_op_cond(storage, is_sdsc, bus_uhs_support)) return 0; DPRINTF("[SD] got op cond\n"); - if (!_sdmmc_storage_get_cid(storage, storage->raw_cid)) + if (!_sdmmc_storage_get_cid(storage)) return 0; DPRINTF("[SD] got cid\n"); _sd_storage_parse_cid(storage); @@ -1302,30 +1311,16 @@ DPRINTF("[SD] got cid\n"); return 0; DPRINTF("[SD] got rca (= %04X)\n", storage->rca); - if (!_sdmmc_storage_get_csd(storage, storage->raw_csd)) + if (!_sdmmc_storage_get_csd(storage)) return 0; DPRINTF("[SD] got csd\n"); - - //Parse CSD. _sd_storage_parse_csd(storage); - switch (storage->csd.structure) - { - case 0: - storage->sec_cnt = storage->csd.capacity; - break; - case 1: - storage->sec_cnt = storage->csd.c_size << 10; - break; - default: -DPRINTF("[SD] unknown CSD structure %d\n", storage->csd.structure); - break; - } if (!storage->is_low_voltage) { if (!sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_DS12)) return 0; -DPRINTF("[SD] after setup clock\n"); +DPRINTF("[SD] after setup default clock\n"); } if (!_sdmmc_storage_select_card(storage)) @@ -1336,19 +1331,17 @@ DPRINTF("[SD] card selected\n"); return 0; DPRINTF("[SD] set blocklen to 512\n"); - u32 tmp = 0; + // Disconnect Card Detect resistor from DAT3. if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN)) return 0; DPRINTF("[SD] cleared card detect\n"); if (!_sd_storage_get_scr(storage, buf)) return 0; - - //gfx_hexdump(0, storage->raw_scr, 8); DPRINTF("[SD] got scr\n"); - // Check if card supports a wider bus and if it's not SD Version 1.X - if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF)) + // If card supports a wider bus and if it's not SD Version 1.0 switch bus width. + if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & BIT(SD_BUS_WIDTH_4)) && storage->scr.sda_vsn) { if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN)) return 0; @@ -1370,7 +1363,7 @@ DPRINTF("[SD] enabled UHS\n"); sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE); } - else if (type != SDHCI_TIMING_SD_DS12 && (storage->scr.sda_vsn & 0xF)) // Not default speed and not SD Version 1.x + else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default speed and not SD Version 1.0. { if (!_sd_storage_enable_hs_high_volt(storage, buf)) return 0; @@ -1389,7 +1382,7 @@ DPRINTF("[SD] enabled HS\n"); } // Parse additional card info from sd status. - if (_sd_storage_get_ssr(storage, buf)) + if (sd_storage_get_ssr(storage, buf)) { DPRINTF("[SD] got sd status\n"); } @@ -1400,14 +1393,14 @@ DPRINTF("[SD] got sd status\n"); } /* -* Gamecard specific functions. -*/ + * Gamecard specific functions. + */ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf) { u32 resp; sdmmc_cmd_t cmdbuf; - sdmmc_init_cmd(&cmdbuf, 60, 0, SDMMC_RSP_TYPE_1, 1); + sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_60_CMD, 0, SDMMC_RSP_TYPE_1, 1); sdmmc_req_t reqbuf; reqbuf.buf = buf; @@ -1415,7 +1408,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf) reqbuf.num_sectors = 1; reqbuf.is_write = 1; reqbuf.is_multi_block = 0; - reqbuf.is_auto_cmd12 = 0; + reqbuf.is_auto_stop_trn = 0; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL)) { diff --git a/bdk/storage/sdmmc.h b/bdk/storage/sdmmc.h index 481b3a1..2b59f7d 100644 --- a/bdk/storage/sdmmc.h +++ b/bdk/storage/sdmmc.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -30,18 +30,18 @@ typedef enum _sdmmc_type EMMC_GPP = 0, EMMC_BOOT0 = 1, - EMMC_BOOT1 = 2 + EMMC_BOOT1 = 2, + EMMC_RPMB = 3 } sdmmc_type; typedef struct _mmc_cid { u32 manfid; u8 prod_name[8]; - u8 card_bga; - u8 prv; u32 serial; u16 oemid; u16 year; + u8 prv; u8 hwrev; u8 fwrev; u8 month; @@ -65,19 +65,20 @@ typedef struct _mmc_csd typedef struct _mmc_ext_csd { - u32 sectors; - int bkops; /* background support bit */ - int bkops_en; /* manual bkops enable bit */ + //u8 bkops; /* background support bit */ + //u8 bkops_en; /* manual bkops enable bit */ + //u8 bkops_status; /* 246 */ u8 rev; u8 ext_struct; /* 194 */ u8 card_type; /* 196 */ - u8 bkops_status; /* 246 */ u8 pre_eol_info; u8 dev_life_est_a; u8 dev_life_est_b; u8 boot_mult; u8 rpmb_mult; u16 dev_version; + u32 cache_size; + u32 max_enh_mult; } mmc_ext_csd_t; typedef struct _sd_scr @@ -90,13 +91,13 @@ typedef struct _sd_scr typedef struct _sd_ssr { - u8 bus_width; - u8 speed_class; - u8 uhs_grade; - u8 video_class; - u8 app_class; - u8 au_size; - u8 uhs_au_size; + u8 bus_width; + u8 speed_class; + u8 uhs_grade; + u8 video_class; + u8 app_class; + u8 au_size; + u8 uhs_au_size; u32 protected_size; } sd_ssr_t; @@ -130,6 +131,7 @@ void sdmmc_storage_init_wait_sd(); int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type); int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc); -u32 sd_storage_ssr_get_au(sdmmc_storage_t *storage); +int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf); +u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage); #endif diff --git a/bdk/storage/sdmmc_driver.c b/bdk/storage/sdmmc_driver.c index bacb977..5ceb2e7 100644 --- a/bdk/storage/sdmmc_driver.c +++ b/bdk/storage/sdmmc_driver.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -934,12 +934,20 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req) *blkcnt_out = blkcnt; u32 trnmode = SDHCI_TRNS_DMA; + + // Set mulitblock request. if (req->is_multi_block) trnmode = SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_DMA; + + // Set request direction. if (!req->is_write) trnmode |= SDHCI_TRNS_READ; - if (req->is_auto_cmd12) - trnmode = (trnmode & ~(SDHCI_TRNS_AUTO_CMD12 | SDHCI_TRNS_AUTO_CMD23)) | SDHCI_TRNS_AUTO_CMD12; + + // Automatic send of stop transmission or set block count cmd. + if (req->is_auto_stop_trn) + trnmode |= SDHCI_TRNS_AUTO_CMD12; + //else if (req->is_auto_set_blkcnt) + // trnmode |= SDHCI_TRNS_AUTO_CMD23; sdmmc->regs->trnmod = trnmode; @@ -1070,7 +1078,7 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, if (blkcnt_out) *blkcnt_out = blkcnt; - if (req->is_auto_cmd12) + if (req->is_auto_stop_trn) sdmmc->rsp3 = sdmmc->regs->rspreg3; } @@ -1371,12 +1379,12 @@ void sdmmc_end(sdmmc_t *sdmmc) _sdmmc_sd_clock_disable(sdmmc); // Disable SDMMC power. _sdmmc_set_io_power(sdmmc, SDMMC_POWER_OFF); + _sdmmc_commit_changes(sdmmc); // Disable SD card power. if (sdmmc->id == SDMMC_1) sdmmc1_disable_power(); - _sdmmc_commit_changes(sdmmc); clock_sdmmc_disable(sdmmc->id); sdmmc->clock_stopped = 1; } diff --git a/bdk/storage/sdmmc_driver.h b/bdk/storage/sdmmc_driver.h index fb2b1b3..696ce4d 100644 --- a/bdk/storage/sdmmc_driver.h +++ b/bdk/storage/sdmmc_driver.h @@ -242,7 +242,7 @@ typedef struct _sdmmc_req_t u32 num_sectors; int is_write; int is_multi_block; - int is_auto_cmd12; + int is_auto_stop_trn; } sdmmc_req_t; int sdmmc_get_io_power(sdmmc_t *sdmmc); diff --git a/bdk/thermal/fan.c b/bdk/thermal/fan.c index d149b36..14379e3 100644 --- a/bdk/thermal/fan.c +++ b/bdk/thermal/fan.c @@ -26,7 +26,7 @@ void set_fan_duty(u32 duty) { static bool fan_init = false; - static u16 curr_duty = -1; + static u16 curr_duty = -1; if (curr_duty == duty) return; @@ -79,15 +79,14 @@ void get_fan_speed(u32 *duty, u32 *rpm) { if (rpm) { - u32 irq_count = 1; + u32 irq_count = 0; bool should_read = true; - bool irq_val = 0; - // Poll irqs for 2 seconds. - int timer = get_tmr_us() + 1000000; - while (timer - get_tmr_us()) + // Poll irqs for 2 seconds. (5 seconds for accurate count). + int timer = get_tmr_us() + 2000000; + while ((timer - get_tmr_us()) > 0) { - irq_val = gpio_read(GPIO_PORT_S, GPIO_PIN_7); + bool irq_val = gpio_read(GPIO_PORT_S, GPIO_PIN_7); if (irq_val && should_read) { irq_count++; @@ -97,8 +96,11 @@ void get_fan_speed(u32 *duty, u32 *rpm) should_read = true; } + // Halve the irq count. + irq_count /= 2; + // Calculate rpm based on triggered interrupts. - *rpm = 60000000 / ((1000000 * 2) / irq_count); + *rpm = irq_count * (60 / 2); } if (duty) diff --git a/bdk/thermal/tmp451.c b/bdk/thermal/tmp451.c index fb9f9fa..65f2fd2 100644 --- a/bdk/thermal/tmp451.c +++ b/bdk/thermal/tmp451.c @@ -1,7 +1,7 @@ /* * SOC/PCB Temperature driver for Nintendo Switch's TI TMP451 * - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2020 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -16,7 +16,9 @@ * along with this program. If not, see . */ +#include #include +#include #include u16 tmp451_get_soc_temp(bool intenger) @@ -56,6 +58,20 @@ void tmp451_init() // Disable ALARM and Range to 0 - 127 oC. i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CONFIG_REG, 0x80); + // Set remote sensor offsets based on SoC. + if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) + { + // Set offset to 0 oC for Erista. + i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_SOC_TMP_OFH_REG, 0); + i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_SOC_TMP_OFL_REG, 0); + } + else + { + // Set offset to -12.5 oC for Mariko. + i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_SOC_TMP_OFH_REG, 0xF3); // - 13 oC. + i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_SOC_TMP_OFL_REG, 0x80); // + 0.5 oC. + } + // Set conversion rate to 32/s and make a read to update the reg. i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CNV_RATE_REG, 9); tmp451_get_soc_temp(false); @@ -63,3 +79,9 @@ void tmp451_init() // Set rate to every 4 seconds. i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CNV_RATE_REG, 2); } + +void tmp451_end() +{ + // Place into shutdown mode to conserve power. + i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CONFIG_REG, 0xC0); +} diff --git a/bdk/thermal/tmp451.h b/bdk/thermal/tmp451.h index 9549ffa..6258fbd 100644 --- a/bdk/thermal/tmp451.h +++ b/bdk/thermal/tmp451.h @@ -32,11 +32,15 @@ #define TMP451_SOC_TMP_DEC_REG 0x10 #define TMP451_PCB_TMP_DEC_REG 0x15 +#define TMP451_SOC_TMP_OFH_REG 0x11 +#define TMP451_SOC_TMP_OFL_REG 0x12 + // If input is false, the return value is packed. MSByte is the integer in oC // and the LSByte is the decimal point truncated to 2 decimal places. // Otherwise it's an integer oC. u16 tmp451_get_soc_temp(bool integer); u16 tmp451_get_pcb_temp(bool integer); void tmp451_init(); +void tmp451_end(); #endif /* __TMP451_H_ */ diff --git a/bdk/usb/usb_gadget_ums.c b/bdk/usb/usb_gadget_ums.c index 6a9831f..10bd56a 100644 --- a/bdk/usb/usb_gadget_ums.c +++ b/bdk/usb/usb_gadget_ums.c @@ -203,7 +203,7 @@ typedef struct _bulk_ctxt_t { typedef struct _usbd_gadget_ums_t { bulk_ctxt_t bulk_ctxt; - int cmnd_size; + u32 cmnd_size; u8 cmnd[SCSI_MAX_CMD_SZ]; u32 lun_idx; // lun index @@ -583,22 +583,20 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) while (amount_left_to_write > 0) { - /* Queue a request for more data from the host */ - if (amount_left_to_req) + if (amount_left_to_req > 0) { // Limit write to max supported read from EP OUT. amount = MIN(amount_left_to_req, UMS_EP_OUT_MAX_XFER); - if (usb_lba_offset >= ums->lun.num_sectors) //////////Check if it works with concurrency + if (usb_lba_offset >= ums->lun.num_sectors) { ums->set_text(ums->label, "#FFDD00 Error:# Write - Past last sector!"); - amount_left_to_req = 0; ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ums->lun.sense_data_info = usb_lba_offset; ums->lun.info_valid = 1; - continue; + break; } // Get the next buffer. @@ -1114,7 +1112,7 @@ static int _scsi_read_format_capacities(usbd_gadget_ums_t *ums, bulk_ctxt_t *bul // Check whether the command is properly formed and whether its data size // and direction agree with the values we already have. -static int _ums_check_scsi_cmd(usbd_gadget_ums_t *ums, int cmnd_size, +static int _ums_check_scsi_cmd(usbd_gadget_ums_t *ums, u32 cmnd_size, enum data_direction data_dir, u32 mask, int needs_medium) { //const char dirletter[4] = {'u', 'o', 'i', 'n'}; @@ -1608,7 +1606,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) /* Is the CBW meaningful? */ if (cbw->Lun >= UMS_MAX_LUN || cbw->Flags & ~USB_BULK_IN_FLAG || - cbw->Length <= 0 || cbw->Length > SCSI_MAX_CMD_SZ) + cbw->Length == 0 || cbw->Length > SCSI_MAX_CMD_SZ) { gfx_printf("USB: non-meaningful CBW: lun = %X, flags = 0x%X, cmdlen %X\n", cbw->Lun, cbw->Flags, cbw->Length); @@ -1837,6 +1835,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) // Initialize sdmmc. if (usbs->type == MMC_SD) { + sd_end(); sd_mount(); sd_unmount(); ums.lun.sdmmc = &sd_sdmmc; @@ -1907,7 +1906,10 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) send_status(&ums, &ums.bulk_ctxt); } while (ums.state != UMS_STATE_TERMINATED); - ums.set_text(ums.label, "#C7EA46 Status:# Disk ejected"); + if (ums.lun.prevent_medium_removal) + ums.set_text(ums.label, "#FFDD00 Error:# Disk unsafely ejected"); + else + ums.set_text(ums.label, "#C7EA46 Status:# Disk ejected"); goto exit; error: diff --git a/bdk/utils/btn.c b/bdk/utils/btn.c index 9ffe275..cc36573 100644 --- a/bdk/utils/btn.c +++ b/bdk/utils/btn.c @@ -29,7 +29,7 @@ u8 btn_read() res |= BTN_VOL_DOWN; if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6)) res |= BTN_VOL_UP; - if (i2c_recv_byte(4, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFSTAT) & 0x4) + if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFSTAT) & MAX77620_ONOFFSTAT_EN0) res |= BTN_POWER; return res; } diff --git a/bdk/utils/dirlist.c b/bdk/utils/dirlist.c index 5732683..3b09d1d 100644 --- a/bdk/utils/dirlist.c +++ b/bdk/utils/dirlist.c @@ -21,16 +21,16 @@ #include #include +#define MAX_ENTRIES 64 + char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs) { - u8 max_entries = 61; - int res = 0; u32 i = 0, j = 0, k = 0; DIR dir; FILINFO fno; - char *dir_entries = (char *)calloc(max_entries, 256); + char *dir_entries = (char *)calloc(MAX_ENTRIES, 256); char *temp = (char *)calloc(1, 256); if (!pattern && !f_opendir(&dir, directory)) @@ -49,7 +49,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile { strcpy(dir_entries + (k * 256), fno.fname); k++; - if (k > (max_entries - 1)) + if (k > (MAX_ENTRIES - 1)) break; } } @@ -64,7 +64,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile { strcpy(dir_entries + (k * 256), fno.fname); k++; - if (k > (max_entries - 1)) + if (k > (MAX_ENTRIES - 1)) break; } res = f_findnext(&dir, &fno); diff --git a/bdk/utils/ini.c b/bdk/utils/ini.c index ff4d3a3..5088f51 100644 --- a/bdk/utils/ini.c +++ b/bdk/utils/ini.c @@ -66,14 +66,14 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type int ini_parse(link_t *dst, char *ini_path, bool is_dir) { + FIL fp; u32 lblen; u32 pathlen = strlen(ini_path); u32 k = 0; - char lbuf[512]; - char *filelist = NULL; - FIL fp; ini_sec_t *csec = NULL; + char *lbuf = NULL; + char *filelist = NULL; char *filename = (char *)malloc(256); strcpy(filename, ini_path); @@ -114,8 +114,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir) return 0; } - csec = _ini_create_section(dst, csec, "Unknown", INI_CHOICE); - list_init(&csec->kvs); + lbuf = malloc(512); do { @@ -171,6 +170,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir) } } while (is_dir); + free(lbuf); free(filename); free(filelist); diff --git a/bdk/utils/sprintf.c b/bdk/utils/sprintf.c index c27043c..8fa2dec 100644 --- a/bdk/utils/sprintf.c +++ b/bdk/utils/sprintf.c @@ -56,7 +56,7 @@ static u32 _putn(char *buffer, u32 v, int base, char fill, int fcnt) { return _puts(buffer, p); } -u32 sprintf(char *buffer, const char *fmt, ...) { +u32 s_printf(char *buffer, const char *fmt, ...) { va_list ap; int fill, fcnt; u32 count = 0; diff --git a/bdk/utils/sprintf.h b/bdk/utils/sprintf.h index 6094044..35a8218 100644 --- a/bdk/utils/sprintf.h +++ b/bdk/utils/sprintf.h @@ -19,6 +19,6 @@ #include "types.h" -u32 sprintf(char *buffer, const char *fmt, ...); +u32 s_printf(char *buffer, const char *fmt, ...); #endif diff --git a/bdk/utils/types.h b/bdk/utils/types.h index 4e15d89..9e8e716 100644 --- a/bdk/utils/types.h +++ b/bdk/utils/types.h @@ -22,7 +22,7 @@ #define ALWAYS_INLINE inline __attribute__((always_inline)) #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -#define ALIGN_DOWN(x, a) (((x) - ((a) - 1)) & ~((a) - 1)) +#define ALIGN_DOWN(x, a) ((x) & ~((a) - 1)) #define BIT(n) (1U << (n)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -103,14 +103,6 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t }; } boot_cfg_t; -typedef struct __attribute__((__packed__)) _ipl_ver_meta_t -{ - u32 magic; - u32 version; - u16 rsvd0; - u16 rsvd1; -} ipl_ver_meta_t; - typedef struct __attribute__((__packed__)) _reloc_meta_t { u32 start; diff --git a/bdk/utils/util.c b/bdk/utils/util.c index 6f535b2..f267236 100644 --- a/bdk/utils/util.c +++ b/bdk/utils/util.c @@ -167,10 +167,10 @@ void power_set_state(power_state_t state) default: // Enable/Disable soft reset wake event. reg = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2); - if (state == POWER_OFF_RESET) - reg &= ~MAX77620_ONOFFCNFG2_SFT_RST_WK; // Do not wake up after power off. - else // POWER_OFF_REBOOT. - reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK; // Wake up after power off. + if (state == POWER_OFF_RESET) // Do not wake up after power off. + reg &= ~(MAX77620_ONOFFCNFG2_SFT_RST_WK | MAX77620_ONOFFCNFG2_WK_ALARM1 | MAX77620_ONOFFCNFG2_WK_ALARM2); + else // POWER_OFF_REBOOT. Wake up after power off. + reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK; i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg); // Initiate power down sequence and generate a reset (regulators' state resets). diff --git a/bdk/utils/util.h b/bdk/utils/util.h index 9a6d00a..3503e1e 100644 --- a/bdk/utils/util.h +++ b/bdk/utils/util.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -21,8 +21,6 @@ #include #include -#define NYX_NEW_INFO 0x3058594E - typedef enum { REBOOT_RCM, // PMC reset. Enter RCM mode. @@ -53,6 +51,8 @@ typedef enum #define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \ (((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000)) +#define byte_swap_16(num) ((((num) >> 8) & 0xff) | (((num) << 8) & 0xff00)) + typedef struct _cfg_op_t { u32 off; @@ -84,9 +84,9 @@ typedef struct _nyx_storage_t void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); u32 crc32_calc(u32 crc, const u8 *buf, u32 len); -u32 get_tmr_us(); -u32 get_tmr_ms(); -u32 get_tmr_s(); +u32 get_tmr_us(); +u32 get_tmr_ms(); +u32 get_tmr_s(); void usleep(u32 us); void msleep(u32 ms); diff --git a/source/fs/fsutils.c b/source/fs/fsutils.c index c838097..8217e73 100644 --- a/source/fs/fsutils.c +++ b/source/fs/fsutils.c @@ -12,7 +12,7 @@ char *CombinePaths(const char *current, const char *add){ size_t size = strlen(current) + strlen(add) + 2; ret = (char*) malloc (size); - sprintf(ret, (current[strlen(current) - 1] == '/') ? "%s%s" : "%s/%s", current, add); + s_printf(ret, (current[strlen(current) - 1] == '/') ? "%s%s" : "%s/%s", current, add); return ret; } diff --git a/source/fs/menus/filemenu.c b/source/fs/menus/filemenu.c index 063c8f4..8cbcbee 100644 --- a/source/fs/menus/filemenu.c +++ b/source/fs/menus/filemenu.c @@ -180,7 +180,7 @@ void FileMenu(char *path, FSEntry_t entry){ FileMenuEntries[0].sizeUnion = entry.sizeUnion; char attribs[16]; char *attribList = GetFileAttribs(entry); - sprintf(attribs, "Attribs:%s\n", attribList); + s_printf(attribs, "Attribs:%s\n", attribList); free(attribList); FileMenuEntries[2].name = attribs; diff --git a/source/fs/menus/foldermenu.c b/source/fs/menus/foldermenu.c index 0b8405a..1d8b4d3 100644 --- a/source/fs/menus/foldermenu.c +++ b/source/fs/menus/foldermenu.c @@ -114,7 +114,7 @@ int FolderMenu(const char *path){ char attribs[16]; char *attribList = GetFileAttribs(file); - sprintf(attribs, "Attribs:%s\n", attribList); + s_printf(attribs, "Attribs:%s\n", attribList); free(attribList); FolderMenuEntries[2].name = attribs; diff --git a/source/gfx/menu.c b/source/gfx/menu.c index 13634a0..80cd6a6 100644 --- a/source/gfx/menu.c +++ b/source/gfx/menu.c @@ -72,7 +72,7 @@ int newMenu(Vector_t* vec, int startIndex, int screenLenX, int screenLenY, u8 op if (options & ENABLEPAGECOUNT){ SETCOLOR(COLOR_DEFAULT, COLOR_WHITE); char temp[40] = ""; - sprintf(temp, " Page %d / %d | Total %d entries", (selected / screenLenY) + 1, ((vec->count - 1) / screenLenY) + 1, entryCount); + s_printf(temp, " Page %d / %d | Total %d entries", (selected / screenLenY) + 1, ((vec->count - 1) / screenLenY) + 1, entryCount); gfx_con_setpos(YLEFT - strlen(temp) * 18, 0); gfx_printf(temp); } diff --git a/source/storage/nx_emmc_bis.c b/source/storage/nx_emmc_bis.c index e551a13..d68db18 100644 --- a/source/storage/nx_emmc_bis.c +++ b/source/storage/nx_emmc_bis.c @@ -318,8 +318,8 @@ void nx_emmc_bis_cluster_cache_init() free(cluster_lookup_buf); // Check if carveout protected, in case of old hwinit (pre 4.0.0) chainload. - *(vu32 *)NX_BIS_LOOKUP_ADR = 0; - if (*(vu32 *)NX_BIS_LOOKUP_ADR != 0) + *(vu32 *)NX_BIS_LOOKUP_ADDR = 0; + if (*(vu32 *)NX_BIS_LOOKUP_ADDR != 0) { cluster_lookup_buf = (u32 *)malloc(cluster_lookup_size + 0x2000); cluster_lookup = (u32 *)ALIGN((u32)cluster_lookup_buf, 0x1000); @@ -327,7 +327,7 @@ void nx_emmc_bis_cluster_cache_init() else { cluster_lookup_buf = NULL; - cluster_lookup = (u32 *)NX_BIS_LOOKUP_ADR; + cluster_lookup = (u32 *)NX_BIS_LOOKUP_ADDR; } // Clear cluster lookup table and reset end index. diff --git a/source/tegraexplorer/tools.c b/source/tegraexplorer/tools.c index b0676a6..429fdba 100644 --- a/source/tegraexplorer/tools.c +++ b/source/tegraexplorer/tools.c @@ -41,7 +41,7 @@ void DumpSysFw(){ } baseSdPath = malloc(36 + 16); - sprintf(baseSdPath, "sd:/tegraexplorer/Firmware/%d (%s)", TConf.pkg1ver, TConf.pkg1ID); + s_printf(baseSdPath, "sd:/tegraexplorer/Firmware/%d (%s)", TConf.pkg1ver, TConf.pkg1ID); int baseSdPathLen = strlen(baseSdPath); f_mkdir("sd:/tegraexplorer"); @@ -81,7 +81,7 @@ void DumpSysFw(){ int total = 1; vecDefArray(FSEntry_t*, fsEntries, fileVec); for (int i = 0; i < fileVec.count; i++){ - sprintf(sysPath, (fsEntries[i].isDir) ? "%s/%s/00" : "%s/%s", "bis:/Contents/registered", fsEntries[i].name); + s_printf(sysPath, (fsEntries[i].isDir) ? "%s/%s/00" : "%s/%s", "bis:/Contents/registered", fsEntries[i].name); int contentType = GetNcaType(sysPath); if (contentType < 0){ @@ -90,7 +90,7 @@ void DumpSysFw(){ } char *sdPath = malloc(baseSdPathLen + 45); - sprintf(sdPath, "%s/%s", baseSdPath, fsEntries[i].name); + s_printf(sdPath, "%s/%s", baseSdPath, fsEntries[i].name); if (contentType == Meta) memcpy(sdPath + strlen(sdPath) - 4, ".cnmt.nca", 10); @@ -214,7 +214,7 @@ void TakeScreenshot(){ char *name, *path; const char basepath[] = "sd:/tegraexplorer/screenshots"; name = malloc(40); - sprintf(name, "Screenshot_%08X.bmp", get_tmr_us()); + s_printf(name, "Screenshot_%08X.bmp", get_tmr_us()); f_mkdir("sd:/tegraexplorer"); f_mkdir(basepath);