mirror of
https://github.com/suchmememanyskill/TegraExplorer.git
synced 2024-11-25 13:22:04 +00:00
update bdk
This commit is contained in:
parent
fec68fbe45
commit
050e7e9ba2
53 changed files with 1015 additions and 911 deletions
|
@ -507,6 +507,11 @@ void display_backlight_brightness(u32 brightness, u32 step_delay)
|
||||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
|
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)
|
static void _display_panel_and_hw_end(bool no_panel_deinit)
|
||||||
{
|
{
|
||||||
if (no_panel_deinit)
|
if (no_panel_deinit)
|
||||||
|
|
|
@ -650,8 +650,9 @@
|
||||||
* [10] 81 [26]: JDI LPM062M326A
|
* [10] 81 [26]: JDI LPM062M326A
|
||||||
* [10] 96 [09]: JDI LAM062M109A
|
* [10] 96 [09]: JDI LAM062M109A
|
||||||
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
||||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2
|
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
|
||||||
* [20] 96 [0F]: InnoLux P062CCA-AZ3
|
* [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] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
||||||
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
||||||
*
|
*
|
||||||
|
@ -706,6 +707,7 @@ void display_color_screen(u32 color);
|
||||||
/*! Switches screen backlight ON/OFF. */
|
/*! Switches screen backlight ON/OFF. */
|
||||||
void display_backlight(bool enable);
|
void display_backlight(bool enable);
|
||||||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
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). */
|
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
||||||
u32 *display_init_framebuffer_pitch();
|
u32 *display_init_framebuffer_pitch();
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "elfload/elfload.h"
|
#include "elfload/elfload.h"
|
||||||
#include <module.h>
|
#include <module.h>
|
||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
|
#include <power/max7762x.h>
|
||||||
#include <storage/nx_sd.h>
|
#include <storage/nx_sd.h>
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
|
@ -43,6 +44,10 @@ static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
|
||||||
bdkParameters->memset = (memset_t)&memset;
|
bdkParameters->memset = (memset_t)&memset;
|
||||||
bdkParameters->sharedHeap = &_heap;
|
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);
|
entrypoint(moduleConfig, bdkParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Joy-Con UART driver for Nintendo Switch
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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.
|
// Check if device stopped sending data.
|
||||||
u32 uart_irq = uart_get_IIR(jc->uart);
|
u32 uart_irq = uart_get_IIR(jc->uart);
|
||||||
if ((uart_irq & 0x8) != 0x8)
|
if (uart_irq != UART_IIR_REDI)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100);
|
u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100);
|
||||||
|
@ -694,9 +694,15 @@ retry:
|
||||||
|
|
||||||
void jc_deinit()
|
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_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||||
|
|
||||||
|
// Send sleep command.
|
||||||
u8 data = HCI_STATE_SLEEP;
|
u8 data = HCI_STATE_SLEEP;
|
||||||
|
|
||||||
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
||||||
|
@ -710,8 +716,9 @@ void jc_deinit()
|
||||||
jc_rcv_pkt(&jc_l);
|
jc_rcv_pkt(&jc_l);
|
||||||
}
|
}
|
||||||
|
|
||||||
jc_power_supply(UART_B, false);
|
// Disable UART B and C clocks.
|
||||||
jc_power_supply(UART_C, false);
|
clock_disable_uart(UART_B);
|
||||||
|
clock_disable_uart(UART_C);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jc_init_conn(joycon_ctxt_t *jc)
|
static void jc_init_conn(joycon_ctxt_t *jc)
|
||||||
|
@ -878,14 +885,14 @@ void jc_init_hw()
|
||||||
pinmux_config_uart(UART_C);
|
pinmux_config_uart(UART_C);
|
||||||
|
|
||||||
// Ease the stress to APB.
|
// 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.
|
// Enable UART B and C clocks.
|
||||||
clock_enable_uart(UART_B);
|
clock_enable_uart(UART_B);
|
||||||
clock_enable_uart(UART_C);
|
clock_enable_uart(UART_C);
|
||||||
|
|
||||||
// Restore OC.
|
// Restore OC.
|
||||||
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
bpmp_clk_rate_set(prev_fid);
|
||||||
|
|
||||||
// Turn Joy-Con detect on.
|
// Turn Joy-Con detect on.
|
||||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||||
|
|
|
@ -206,6 +206,7 @@ touch_panel_info_t *touch_get_panel_vendor()
|
||||||
{
|
{
|
||||||
u8 buf[5] = {0};
|
u8 buf[5] = {0};
|
||||||
u8 cmd = STMFTS_VENDOR_GPIO_STATE;
|
u8 cmd = STMFTS_VENDOR_GPIO_STATE;
|
||||||
|
static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""};
|
||||||
|
|
||||||
if (touch_command(STMFTS_VENDOR, &cmd, 1))
|
if (touch_command(STMFTS_VENDOR, &cmd, 1))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -220,13 +221,20 @@ touch_panel_info_t *touch_get_panel_vendor()
|
||||||
return panel;
|
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)
|
int touch_get_fw_info(touch_fw_info_t *fw)
|
||||||
{
|
{
|
||||||
u8 buf[8] = {0};
|
u8 buf[8] = {0};
|
||||||
|
|
||||||
|
memset(fw, 0, sizeof(touch_fw_info_t));
|
||||||
|
|
||||||
// Get fw address info.
|
// Get fw address info.
|
||||||
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
|
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
|
||||||
int res = touch_read_reg(cmd, 3, buf, 3);
|
int res = touch_read_reg(cmd, 3, buf, 3);
|
||||||
|
@ -318,7 +326,7 @@ int touch_get_fb_info(u8 *buf)
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
|
|
||||||
for (u32 i = 0; i < 0x10000; i+=4)
|
for (u32 i = 0; i < 0x10000; i += 4)
|
||||||
{
|
{
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
@ -392,11 +400,11 @@ static int touch_init()
|
||||||
|
|
||||||
int touch_power_on()
|
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_set_voltage(REGULATOR_LDO6, 2900000);
|
||||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||||
|
|
||||||
// Configure touchscreen GPIO.
|
// Configure touchscreen VDD GPIO.
|
||||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||||
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
|
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||||
gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);
|
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.
|
// 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_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;
|
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.
|
// Initialize I2C3.
|
||||||
pinmux_config_i2c(I2C_3);
|
pinmux_config_i2c(I2C_3);
|
||||||
|
|
|
@ -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 LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
LZ4_stream_t ctx;
|
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
|
||||||
LZ4_stream_t* const ctxPtr = &ctx;
|
LZ4_stream_t* const ctxPtr = ctx;
|
||||||
result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
|
result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
|
||||||
|
|
||||||
|
FREEMEM(ctx);
|
||||||
|
|
||||||
return result;
|
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 */
|
/* 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)
|
int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||||
{
|
{
|
||||||
LZ4_stream_t ctx;
|
int result;
|
||||||
LZ4_resetStream(&ctx);
|
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
|
||||||
|
LZ4_resetStream(ctx);
|
||||||
|
|
||||||
if (inputSize < LZ4_64Klimit)
|
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
|
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)
|
int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
|
||||||
{
|
{
|
||||||
LZ4_stream_t ctxBody;
|
LZ4_stream_t* ctxBody = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));;
|
||||||
LZ4_stream_t* ctx = &ctxBody;
|
LZ4_stream_t* ctx = ctxBody;
|
||||||
|
|
||||||
int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
|
int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
|
||||||
|
|
||||||
|
FREEMEM(ctxBody);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ typedef enum {
|
||||||
DRIVE_SD = 0,
|
DRIVE_SD = 0,
|
||||||
DRIVE_RAM = 1,
|
DRIVE_RAM = 1,
|
||||||
DRIVE_EMMC = 2,
|
DRIVE_EMMC = 2,
|
||||||
DRIVE_BIS = 3
|
DRIVE_BIS = 3,
|
||||||
|
DRIVE_EMU = 4
|
||||||
} DDRIVE;
|
} 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_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 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 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) */
|
/* Generic command (Not used by FatFs) */
|
||||||
#define CTRL_POWER 5 /* Get/Set power status */
|
#define CTRL_POWER 5 /* Get/Set power status */
|
||||||
|
|
|
@ -155,7 +155,7 @@
|
||||||
|
|
||||||
|
|
||||||
/*Log settings*/
|
/*Log settings*/
|
||||||
#ifdef DEBUG_UART_PORT
|
#ifdef DEBUG_UART_LV_LOG
|
||||||
# define USE_LV_LOG 1 /*Enable/disable the log module*/
|
# define USE_LV_LOG 1 /*Enable/disable the log module*/
|
||||||
#else
|
#else
|
||||||
# define USE_LV_LOG 0 /*Enable/disable the log module*/
|
# define USE_LV_LOG 0 /*Enable/disable the log module*/
|
||||||
|
|
|
@ -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(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"};
|
static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error"};
|
||||||
char *log = (char *)malloc(0x1000);
|
char *log = (char *)malloc(0x1000);
|
||||||
s_printf(log, "%s: %s \t(%s #%d)\r\n", lvl_prefix[level], dsc, file, line);
|
s_printf(log, "%s: %s \t(%s #%d)\r\n", lvl_prefix[level], dsc, file, line);
|
||||||
|
|
|
@ -104,21 +104,21 @@ u32 minerva_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
|
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;
|
mtc_cfg->train_mode = OP_TRAIN;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
mtc_cfg->rate_to = 800000;
|
mtc_cfg->rate_to = FREQ_800;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
mtc_cfg->rate_to = 1600000;
|
mtc_cfg->rate_to = FREQ_1600;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
|
|
||||||
// FSP WAR.
|
// FSP WAR.
|
||||||
mtc_cfg->train_mode = OP_SWITCH;
|
mtc_cfg->train_mode = OP_SWITCH;
|
||||||
mtc_cfg->rate_to = 800000;
|
mtc_cfg->rate_to = FREQ_800;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
|
|
||||||
// Switch to max.
|
// Switch to max.
|
||||||
mtc_cfg->rate_to = 1600000;
|
mtc_cfg->rate_to = FREQ_1600;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
|
|
||||||
return 0;
|
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()
|
void minerva_periodic_training()
|
||||||
{
|
{
|
||||||
if (!minerva_cfg)
|
if (!minerva_cfg)
|
||||||
|
|
|
@ -60,6 +60,7 @@ typedef enum
|
||||||
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||||
u32 minerva_init();
|
u32 minerva_init();
|
||||||
void minerva_change_freq(minerva_freq_t freq);
|
void minerva_change_freq(minerva_freq_t freq);
|
||||||
|
void minerva_prep_boot_freq();
|
||||||
void minerva_periodic_training();
|
void minerva_periodic_training();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
//#define IPL_STACK_TOP 0x4003FF00
|
//#define IPL_STACK_TOP 0x4003FF00
|
||||||
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
|
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
|
||||||
/* --- IPL: 0x40003000 - 0x40028000 --- */
|
/* --- IPL: 0x40008000 - 0x40028000 --- */
|
||||||
#define LDR_LOAD_ADDR 0x40003000
|
#define LDR_LOAD_ADDR 0x40007000
|
||||||
|
|
||||||
#define IPL_LOAD_ADDR 0x40008000
|
#define IPL_LOAD_ADDR 0x40008000
|
||||||
#define IPL_SZ_MAX 0x20000 // 128KB.
|
#define IPL_SZ_MAX 0x20000 // 128KB.
|
||||||
|
@ -49,8 +49,14 @@
|
||||||
|
|
||||||
// Virtual disk / Chainloader buffers.
|
// Virtual disk / Chainloader buffers.
|
||||||
#define RAM_DISK_ADDR 0xA4000000
|
#define RAM_DISK_ADDR 0xA4000000
|
||||||
#define NX_BIS_CACHE_ADDR RAM_DISK_ADDR
|
|
||||||
#define RAM_DISK_SZ 0x41000000 // 1040MB.
|
#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).
|
// L4T Kernel Panic Storage (PSTORE).
|
||||||
#define PSTORE_ADDR 0xB0000000
|
#define PSTORE_ADDR 0xB0000000
|
||||||
|
@ -91,15 +97,10 @@
|
||||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||||
|
|
||||||
#define DRAM_MEM_HOLE_ADR 0xF6A00000
|
#define DRAM_MEM_HOLE_ADR 0xF6A00000
|
||||||
#define NX_BIS_LOOKUP_ADR DRAM_MEM_HOLE_ADR
|
|
||||||
#define DRAM_MEM_HOLE_SZ 0x8140000
|
#define DRAM_MEM_HOLE_SZ 0x8140000
|
||||||
/* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */
|
/* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */
|
||||||
#define DRAM_START2 0xFEB40000
|
#define DRAM_START2 0xFEB40000
|
||||||
|
|
||||||
// NX BIS driver sector cache.
|
|
||||||
// #define NX_BIS_CACHE_ADDR 0xFEE00000
|
|
||||||
// #define NX_BIS_CACHE_SZ 0x100000
|
|
||||||
|
|
||||||
// USB buffers.
|
// USB buffers.
|
||||||
#define USBD_ADDR 0xFEF00000
|
#define USBD_ADDR 0xFEF00000
|
||||||
#define USB_DESCRIPTOR_ADDR 0xFEF40000
|
#define USB_DESCRIPTOR_ADDR 0xFEF40000
|
||||||
|
|
|
@ -21,10 +21,13 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
|
|
||||||
|
#define IANOS_EXT0 0x304E4149
|
||||||
|
|
||||||
// Module Callback
|
// Module Callback
|
||||||
typedef void (*cbMainModule_t)(const char *s);
|
typedef void (*cbMainModule_t)(const char *s);
|
||||||
typedef void (*memcpy_t)(void *, void *, size_t);
|
typedef void (*memcpy_t)(void *, void *, size_t);
|
||||||
typedef void (*memset_t)(void *, int, size_t);
|
typedef void (*memset_t)(void *, int, size_t);
|
||||||
|
typedef int (*reg_voltage_set_t)(u32, u32);
|
||||||
|
|
||||||
typedef struct _bdkParams_t
|
typedef struct _bdkParams_t
|
||||||
{
|
{
|
||||||
|
@ -33,6 +36,8 @@ typedef struct _bdkParams_t
|
||||||
heap_t *sharedHeap;
|
heap_t *sharedHeap;
|
||||||
memcpy_t memcpy;
|
memcpy_t memcpy;
|
||||||
memset_t memset;
|
memset_t memset;
|
||||||
|
u32 extension_magic;
|
||||||
|
reg_voltage_set_t reg_voltage_set;
|
||||||
} *bdkParams_t;
|
} *bdkParams_t;
|
||||||
|
|
||||||
// Module Entrypoint
|
// Module Entrypoint
|
||||||
|
|
|
@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
|
||||||
|
|
||||||
static const max77620_regulator_t _pmic_regulators[] = {
|
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 }} },
|
{ "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 }} },
|
{ "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 }} },
|
{ "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 }} },
|
{ "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);
|
_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)
|
void max77620_low_battery_monitor_config(bool enable)
|
||||||
{
|
{
|
||||||
_max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,
|
_max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,
|
||||||
|
|
|
@ -32,11 +32,11 @@
|
||||||
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
||||||
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
|
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
|
||||||
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
|
* 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)
|
* ldo5 | GC Card | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
|
||||||
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
|
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V (pcv)
|
||||||
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
|
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
||||||
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
|
* 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_HOS_CFG 0
|
||||||
#define MAX77621_CTRL_POR_CFG 1
|
#define MAX77621_CTRL_POR_CFG 1
|
||||||
|
|
||||||
int max77620_regulator_get_status(u32 id);
|
int max77620_regulator_get_status(u32 id);
|
||||||
int max77620_regulator_config_fps(u32 id);
|
int max77620_regulator_config_fps(u32 id);
|
||||||
int max7762x_regulator_set_voltage(u32 id, u32 mv);
|
int max7762x_regulator_set_voltage(u32 id, u32 mv);
|
||||||
int max7762x_regulator_enable(u32 id, bool enable);
|
int max7762x_regulator_enable(u32 id, bool enable);
|
||||||
void max77620_config_gpio(u32 id, bool enable);
|
void max77620_config_gpio(u32 id, bool enable);
|
||||||
void max77620_config_default();
|
void max77620_config_default();
|
||||||
void max77620_low_battery_monitor_config(bool enable);
|
void max77620_low_battery_monitor_config(bool enable);
|
||||||
|
|
|
@ -81,7 +81,13 @@ bool regulator_5v_get_dev_enabled(u8 dev)
|
||||||
void regulator_5v_batt_src_enable(bool enable)
|
void regulator_5v_batt_src_enable(bool enable)
|
||||||
{
|
{
|
||||||
if (enable && !batt_src)
|
if (enable && !batt_src)
|
||||||
|
{
|
||||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||||
|
batt_src = true;
|
||||||
|
}
|
||||||
else if (!enable && batt_src)
|
else if (!enable && batt_src)
|
||||||
|
{
|
||||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
|
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
|
||||||
|
batt_src = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
342
bdk/sec/se.c
342
bdk/sec/se.c
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018 CTCaer
|
* Copyright (c) 2018-2021 CTCaer
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -35,8 +35,8 @@ typedef struct _se_ll_t
|
||||||
vu32 size;
|
vu32 size;
|
||||||
} se_ll_t;
|
} se_ll_t;
|
||||||
|
|
||||||
static u32 _se_rsa_mod_sizes[TEGRA_SE_RSA_KEYSLOT_COUNT];
|
static u32 _se_rsa_mod_sizes[SE_RSA_KEYSLOT_COUNT];
|
||||||
static u32 _se_rsa_exp_sizes[TEGRA_SE_RSA_KEYSLOT_COUNT];
|
static u32 _se_rsa_exp_sizes[SE_RSA_KEYSLOT_COUNT];
|
||||||
|
|
||||||
static void _gf256_mul_x(void *block)
|
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)
|
static void _se_ll_set(se_ll_t *dst, se_ll_t *src)
|
||||||
{
|
{
|
||||||
SE(SE_IN_LL_ADDR_REG_OFFSET) = (u32)src;
|
SE(SE_IN_LL_ADDR_REG) = (u32)src;
|
||||||
SE(SE_OUT_LL_ADDR_REG_OFFSET) = (u32)dst;
|
SE(SE_OUT_LL_ADDR_REG) = (u32)dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _se_wait()
|
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) ||
|
if (SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT ||
|
||||||
SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN ||
|
(SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE ||
|
||||||
SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR)
|
SE(SE_ERR_STATUS_REG) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
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_ll_set(ll_dst, ll_src);
|
||||||
|
|
||||||
SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);
|
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
|
||||||
SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);
|
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
|
||||||
|
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
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)
|
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)
|
if (!src || !dst)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u8 *block = (u8 *)malloc(0x10);
|
u8 *block = (u8 *)malloc(SE_AES_BLOCK_SIZE);
|
||||||
memset(block, 0, 0x10);
|
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);
|
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);
|
memcpy(dst, block, dst_size);
|
||||||
|
|
||||||
free(block);
|
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)
|
static void _se_aes_ctr_set(void *ctr)
|
||||||
{
|
{
|
||||||
u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
|
u32 data[SE_AES_IV_SIZE / 4];
|
||||||
memcpy(data, ctr, TEGRA_SE_AES_BLOCK_SIZE);
|
memcpy(data, ctr, SE_AES_IV_SIZE);
|
||||||
|
|
||||||
for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
|
for (u32 i = 0; i < SE_CRYPTO_LINEAR_CTR_REG_COUNT; i++)
|
||||||
SE(SE_CRYPTO_CTR_REG_OFFSET + (4 * i)) = data[i];
|
SE(SE_CRYPTO_LINEAR_CTR_REG + (4 * i)) = data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
||||||
{
|
{
|
||||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG)
|
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||||
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) =
|
SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) =
|
||||||
((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |
|
(((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |(flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
|
||||||
((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG);
|
SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG;
|
||||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
if (flags & SE_RSA_KEY_LOCK_FLAG)
|
||||||
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~BIT(rs);
|
SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot
|
// 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;
|
u32 *data = (u32 *)mod;
|
||||||
for (u32 i = 0; i < mod_size / 4; i++)
|
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_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i;
|
||||||
SE(SE_RSA_KEYTABLE_DATA) = byte_swap_32(data[mod_size / 4 - i - 1]);
|
SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[mod_size / 4 - i - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (u32 *)exp;
|
data = (u32 *)exp;
|
||||||
for (u32 i = 0; i < exp_size / 4; i++)
|
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_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i;
|
||||||
SE(SE_RSA_KEYTABLE_DATA) = byte_swap_32(data[exp_size / 4 - i - 1]);
|
SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[exp_size / 4 - i - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_se_rsa_mod_sizes[ks] = mod_size;
|
_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
|
// se_rsa_key_clear() was derived from Atmosphère's clear_rsa_keyslot
|
||||||
void se_rsa_key_clear(u32 ks)
|
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_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i;
|
||||||
SE(SE_RSA_KEYTABLE_DATA) = 0;
|
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_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i;
|
||||||
SE(SE_RSA_KEYTABLE_DATA) = 0;
|
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 se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||||
{
|
{
|
||||||
int res;
|
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++)
|
for (u32 i = 0; i < src_size; i++)
|
||||||
stack_buf[i] = *((u8 *)src + src_size - i - 1);
|
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_CONFIG) = RSA_KEY_SLOT(ks);
|
||||||
SE(SE_RSA_KEY_SIZE_REG_OFFSET) = (_se_rsa_mod_sizes[ks] >> 6) - 1;
|
SE(SE_RSA_KEY_SIZE_REG) = (_se_rsa_mod_sizes[ks] >> 6) - 1;
|
||||||
SE(SE_RSA_EXP_SIZE_REG_OFFSET) = _se_rsa_exp_sizes[ks] >> 2;
|
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.
|
// Copy output hash.
|
||||||
u32 *dst32 = (u32 *)dst;
|
u32 *dst32 = (u32 *)dst;
|
||||||
for (u32 i = 0; i < dst_size / 4; i++)
|
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;
|
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)
|
void se_key_acc_ctrl(u32 ks, u32 flags)
|
||||||
{
|
{
|
||||||
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
|
SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks) = ~flags;
|
||||||
if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
if (flags & SE_KEY_LOCK_FLAG)
|
||||||
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~BIT(ks);
|
SE(SE_CRYPTO_SECURITY_PERKEY_REG) &= ~BIT(ks);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 se_key_acc_ctrl_get(u32 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)
|
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);
|
memcpy(data, key, size);
|
||||||
|
|
||||||
for (u32 i = 0; i < (size / 4); i++)
|
for (u32 i = 0; i < (size / 4); i++)
|
||||||
{
|
{
|
||||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
|
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
|
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_aes_key_partial_set(u32 ks, u32 index, u32 data)
|
void se_aes_key_partial_set(u32 ks, u32 index, u32 data)
|
||||||
{
|
{
|
||||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | index;
|
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | index;
|
||||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data;
|
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_aes_iv_set(u32 ks, const void *iv)
|
void se_aes_iv_set(u32 ks, const void *iv)
|
||||||
{
|
{
|
||||||
u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
|
u32 data[SE_AES_IV_SIZE / 4];
|
||||||
memcpy(data, iv, TEGRA_SE_AES_BLOCK_SIZE);
|
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_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
|
||||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
|
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_aes_key_get(u32 ks, void *key, u32 size)
|
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++)
|
for (u32 i = 0; i < (size / 4); i++)
|
||||||
{
|
{
|
||||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
|
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||||
data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET);
|
data[i] = SE(SE_CRYPTO_KEYTABLE_DATA_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(key, data, size);
|
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)
|
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_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
|
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_aes_iv_clear(u32 ks)
|
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_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
|
||||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
|
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
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_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
|
||||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||||
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);
|
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)
|
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||||
{
|
{
|
||||||
if (enc)
|
if (enc)
|
||||||
{
|
{
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
SE(SE_CONFIG_REG) = 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_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
SE(SE_CONFIG_REG) = 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_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||||
}
|
}
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||||
return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
|
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)
|
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||||
{
|
{
|
||||||
if (enc)
|
if (enc)
|
||||||
{
|
{
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
SE(SE_CONFIG_REG) = 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_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);
|
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
SE(SE_CONFIG_REG) = 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_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_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
|
||||||
}
|
}
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||||
return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
|
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)
|
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)
|
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_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE);
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
SE(SE_CONFIG_REG) = 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_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_VAL(1);
|
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_CNTN(1);
|
||||||
_se_aes_ctr_set(ctr);
|
_se_aes_ctr_set(ctr);
|
||||||
|
|
||||||
u32 src_size_aligned = src_size & 0xFFFFFFF0;
|
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)
|
if (src_size_aligned)
|
||||||
{
|
{
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||||
if (!_se_execute_oneshot(OP_START, dst, dst_size, src, src_size_aligned))
|
if (!_se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size_aligned))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_size - src_size_aligned && src_size_aligned < dst_size)
|
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),
|
MIN(src_size_delta, dst_size - src_size_aligned),
|
||||||
src + src_size_aligned, src_size_delta);
|
src + src_size_aligned, src_size_delta);
|
||||||
|
|
||||||
|
@ -419,15 +419,15 @@ int se_initialize_rng()
|
||||||
|
|
||||||
u8 *output_buf = (u8 *)malloc(0x10);
|
u8 *output_buf = (u8 *)malloc(0x10);
|
||||||
|
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
|
SE(SE_CONFIG_REG) = 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_CRYPTO_CONFIG_REG) = 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_CONFIG_REG) = SE_RNG_CONFIG_MODE(MODE_FORCE_INSTANTION) | SE_RNG_CONFIG_SRC(SRC_ENTROPY);
|
||||||
SE(SE_RNG_RESEED_INTERVAL_REG_OFFSET) = 70001;
|
SE(SE_RNG_RESEED_INTERVAL_REG) = 70001;
|
||||||
SE(SE_RNG_SRC_CONFIG_REG_OFFSET) = SE_RNG_SRC_CONFIG_ENT_SRC(RNG_SRC_RO_ENT_ENABLE) |
|
SE(SE_RNG_SRC_CONFIG_REG) = SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) |
|
||||||
SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE);
|
SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE);
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
|
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);
|
free(output_buf);
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -437,35 +437,35 @@ int se_initialize_rng()
|
||||||
|
|
||||||
int se_generate_random(void *dst, u32 size)
|
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_CONFIG_REG) = 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_CRYPTO_CONFIG_REG) = 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);
|
||||||
|
|
||||||
u32 num_blocks = size >> 4;
|
u32 num_blocks = size >> 4;
|
||||||
u32 aligned_size = num_blocks << 4;
|
u32 aligned_size = num_blocks << 4;
|
||||||
if (num_blocks)
|
if (num_blocks)
|
||||||
{
|
{
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 1;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 1;
|
||||||
if (!_se_execute_oneshot(OP_START, dst, aligned_size, NULL, 0))
|
if (!_se_execute_oneshot(SE_OP_START, dst, aligned_size, NULL, 0))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (size > aligned_size)
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int se_generate_random_key(u32 ks_dst, u32 ks_src)
|
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_CONFIG_REG) = 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_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||||
SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
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);
|
SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst);
|
||||||
if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0))
|
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0))
|
||||||
return 0;
|
return 0;
|
||||||
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1;
|
SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1;
|
||||||
if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0))
|
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
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)
|
if (src_size & 0xF)
|
||||||
_gf256_mul_x(key);
|
_gf256_mul_x(key);
|
||||||
|
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
|
SE(SE_CONFIG_REG) = 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_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_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
|
||||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||||
se_aes_iv_clear(ks);
|
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;
|
u32 num_blocks = (src_size + 0xf) >> 4;
|
||||||
if (num_blocks > 1)
|
if (num_blocks > 1)
|
||||||
{
|
{
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 2;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
|
||||||
if (!_se_execute_oneshot(OP_START, NULL, 0, src, src_size))
|
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
|
||||||
goto out;
|
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)
|
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++)
|
for (u32 i = 0; i < 0x10; i++)
|
||||||
last_block[i] ^= key[i];
|
last_block[i] ^= key[i];
|
||||||
|
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
|
||||||
res = _se_execute_oneshot(OP_START, NULL, 0, last_block, 0x10);
|
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, 0x10);
|
||||||
|
|
||||||
u32 *dst32 = (u32 *)dst;
|
u32 *dst32 = (u32 *)dst;
|
||||||
for (u32 i = 0; i < (dst_size >> 2); i++)
|
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:;
|
out:;
|
||||||
free(key);
|
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 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;
|
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.
|
//! 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.
|
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Setup config for SHA256.
|
// 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_CONFIG_REG) = 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_SHA_CONFIG_REG) = sha_cfg;
|
||||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
|
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||||
|
|
||||||
// Set total size to current buffer size if empty.
|
// Set total size to current buffer size if empty.
|
||||||
if (!total_size)
|
if (!total_size)
|
||||||
total_size = src_size;
|
total_size = src_size;
|
||||||
|
|
||||||
// Set total size: BITS(src_size), up to 2 EB.
|
// 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_0_REG) = (u32)(total_size << 3);
|
||||||
SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29);
|
SE(SE_SHA_MSG_LENGTH_1_REG) = (u32)(total_size >> 29);
|
||||||
SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0;
|
SE(SE_SHA_MSG_LENGTH_2_REG) = 0;
|
||||||
SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0;
|
SE(SE_SHA_MSG_LENGTH_3_REG) = 0;
|
||||||
|
|
||||||
// Set size left to hash.
|
// Set size left to hash.
|
||||||
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(total_size << 3);
|
SE(SE_SHA_MSG_LEFT_0_REG) = (u32)(total_size << 3);
|
||||||
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29);
|
SE(SE_SHA_MSG_LEFT_1_REG) = (u32)(total_size >> 29);
|
||||||
SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0;
|
SE(SE_SHA_MSG_LEFT_2_REG) = 0;
|
||||||
SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0;
|
SE(SE_SHA_MSG_LEFT_3_REG) = 0;
|
||||||
|
|
||||||
// If we hash in chunks, copy over the intermediate.
|
// If we hash in chunks, copy over the intermediate.
|
||||||
if (sha_cfg == SHA_CONTINUE && msg_left)
|
if (sha_cfg == SHA_CONTINUE && msg_left)
|
||||||
{
|
{
|
||||||
// Restore message left to process.
|
// Restore message left to process.
|
||||||
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = msg_left[0];
|
SE(SE_SHA_MSG_LEFT_0_REG) = msg_left[0];
|
||||||
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1];
|
SE(SE_SHA_MSG_LEFT_1_REG) = msg_left[1];
|
||||||
|
|
||||||
// Restore hash reg.
|
// Restore hash reg.
|
||||||
memcpy(hash32, hash, TEGRA_SE_SHA_256_SIZE);
|
memcpy(hash32, hash, SE_SHA_256_SIZE);
|
||||||
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
|
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||||
SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]);
|
SE(SE_HASH_RESULT_REG + (i * 4)) = byte_swap_32(hash32[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger the operation.
|
// 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)
|
if (is_oneshot)
|
||||||
{
|
{
|
||||||
// Backup message left.
|
// Backup message left.
|
||||||
if (msg_left)
|
if (msg_left)
|
||||||
{
|
{
|
||||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
|
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
|
||||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
|
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy output hash.
|
// Copy output hash.
|
||||||
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
|
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
|
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
|
||||||
memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
|
memcpy(hash, hash32, SE_SHA_256_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
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)
|
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();
|
int res = _se_execute_finalize();
|
||||||
|
|
||||||
// Backup message left.
|
// Backup message left.
|
||||||
if (msg_left)
|
if (msg_left)
|
||||||
{
|
{
|
||||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
|
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
|
||||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
|
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy output hash.
|
// Copy output hash.
|
||||||
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
|
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
|
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i << 2)));
|
||||||
memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
|
memcpy(hash, hash32, SE_SHA_256_SIZE);
|
||||||
|
|
||||||
return res;
|
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);
|
u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);
|
||||||
|
|
||||||
// Set Secure Random Key.
|
// 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_CONFIG_REG) = 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_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_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED);
|
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(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.
|
// 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) |
|
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||||
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3);
|
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
|
||||||
|
|
||||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||||
_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
|
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||||
memcpy(keys + i * keysize, aligned_buf, 0x10);
|
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) |
|
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||||
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7);
|
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
|
||||||
|
|
||||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||||
_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
|
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||||
memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10);
|
memcpy(keys + i * keysize + SE_AES_BLOCK_SIZE, aligned_buf, SE_AES_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save SRK to PMC secure scratches.
|
// Save SRK to PMC secure scratches.
|
||||||
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK);
|
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(SRK);
|
||||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||||
_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
|
_se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
// End context save.
|
// End context save.
|
||||||
SE(SE_CONFIG_REG_OFFSET) = 0;
|
SE(SE_CONFIG_REG) = 0;
|
||||||
_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
|
_se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
// Get SRK.
|
// Get SRK.
|
||||||
u32 srk[4];
|
u32 srk[4];
|
||||||
|
@ -840,7 +840,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||||
|
|
||||||
// Decrypt context.
|
// Decrypt context.
|
||||||
se_aes_key_clear(3);
|
se_aes_key_clear(3);
|
||||||
se_aes_key_set(3, srk, 0x10);
|
se_aes_key_set(3, srk, SE_KEY_128_SIZE);
|
||||||
se_aes_crypt_cbc(3, 0, keys, TEGRA_SE_KEYSLOT_COUNT * keysize, keys, TEGRA_SE_KEYSLOT_COUNT * keysize);
|
se_aes_crypt_cbc(3, 0, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
|
||||||
se_aes_key_clear(3);
|
se_aes_key_clear(3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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);
|
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);
|
void se_key_acc_ctrl(u32 ks, u32 flags);
|
||||||
u32 se_key_acc_ctrl_get(u32 ks);
|
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_key_set(u32 ks, const void *key, u32 size);
|
||||||
void se_aes_iv_set(u32 ks, const void *iv);
|
void se_aes_iv_set(u32 ks, const void *iv);
|
||||||
void se_aes_key_partial_set(u32 ks, u32 index, u32 data);
|
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(void *dst, u32 size);
|
||||||
int se_generate_random_key(u32 ks_dst, u32 ks_src);
|
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_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_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_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_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_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_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);
|
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_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);
|
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);
|
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
|
#endif
|
||||||
|
|
|
@ -1,400 +1,323 @@
|
||||||
/*
|
/*
|
||||||
* Driver for Tegra Security Engine
|
* Copyright (c) 2018 naehrwert
|
||||||
*
|
* Copyright (c) 2018-2021 CTCaer
|
||||||
* Copyright (c) 2011-2013, NVIDIA Corporation. All Rights Reserved.
|
*
|
||||||
*
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* under the terms and conditions of the GNU General Public License,
|
||||||
* it under the terms of the GNU General Public License as published by
|
* version 2, as published by the Free Software Foundation.
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
*
|
||||||
* (at your option) any later version.
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
*
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* more details.
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
*
|
||||||
* more details.
|
* You should have received a copy of the GNU General Public License
|
||||||
*
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CRYPTO_TEGRA_SE_H
|
#ifndef _SE_T210_H
|
||||||
#define _CRYPTO_TEGRA_SE_H
|
#define _SE_T210_H
|
||||||
|
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
#define TEGRA_SE_CRA_PRIORITY 300
|
#define SE_CRYPTO_QUEUE_LENGTH 50
|
||||||
#define TEGRA_SE_COMPOSITE_PRIORITY 400
|
#define SE_MAX_SRC_SG_COUNT 50
|
||||||
#define TEGRA_SE_CRYPTO_QUEUE_LENGTH 50
|
#define SE_MAX_DST_SG_COUNT 50
|
||||||
#define SE_MAX_SRC_SG_COUNT 50
|
|
||||||
#define SE_MAX_DST_SG_COUNT 50
|
|
||||||
|
|
||||||
#define TEGRA_SE_KEYSLOT_COUNT 16
|
#define SE_AES_KEYSLOT_COUNT 16
|
||||||
#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
|
#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 */
|
/* SE register definitions */
|
||||||
#define SE_SECURITY_0 0x000
|
#define SE_SE_SECURITY_REG 0x000
|
||||||
#define SE_KEY_SCHED_READ_SHIFT 3
|
#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_OPERATION_REG 0x008
|
||||||
#define SE_CONFIG_ENC_ALG_SHIFT 12
|
#define SE_OP_ABORT 0
|
||||||
#define SE_CONFIG_DEC_ALG_SHIFT 8
|
#define SE_OP_START 1
|
||||||
#define ALG_AES_ENC 1
|
#define SE_OP_RESTART_OUT 2
|
||||||
#define ALG_RNG 2
|
#define SE_OP_CTX_SAVE 3
|
||||||
#define ALG_SHA 3
|
#define SE_OP_RESTART_IN 4
|
||||||
#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_RNG_CONFIG_REG_OFFSET 0x340
|
#define SE_INT_ENABLE_REG 0x00C
|
||||||
#define RNG_MODE_SHIFT 0
|
#define SE_INT_STATUS_REG 0x010
|
||||||
#define RNG_MODE_NORMAL 0
|
#define SE_INT_IN_LL_BUF_RD BIT(0)
|
||||||
#define RNG_MODE_FORCE_INSTANTION 1
|
#define SE_INT_IN_DONE BIT(1)
|
||||||
#define RNG_MODE_FORCE_RESEED 2
|
#define SE_INT_OUT_LL_BUF_WR BIT(2)
|
||||||
#define SE_RNG_CONFIG_MODE(x) ((x) << RNG_MODE_SHIFT)
|
#define SE_INT_OUT_DONE BIT(3)
|
||||||
#define RNG_SRC_SHIFT 2
|
#define SE_INT_OP_DONE BIT(4)
|
||||||
#define RNG_SRC_NONE 0
|
#define SE_INT_RESEED_NEEDED BIT(5)
|
||||||
#define RNG_SRC_ENTROPY 1
|
#define SE_INT_ERR_STAT BIT(16)
|
||||||
#define RNG_SRC_LFSR 2
|
|
||||||
#define SE_RNG_CONFIG_SRC(x) ((x) << RNG_SRC_SHIFT)
|
|
||||||
|
|
||||||
#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344
|
#define SE_CONFIG_REG 0x014
|
||||||
#define RNG_SRC_RO_ENT_SHIFT 1
|
#define DST_MEMORY 0
|
||||||
#define RNG_SRC_RO_ENT_ENABLE 1
|
#define DST_HASHREG 1
|
||||||
#define RNG_SRC_RO_ENT_DISABLE 0
|
#define DST_KEYTABLE 2
|
||||||
#define SE_RNG_SRC_CONFIG_ENT_SRC(x) ((x) << RNG_SRC_RO_ENT_SHIFT)
|
#define DST_SRK 3
|
||||||
#define RNG_SRC_RO_ENT_LOCK_SHIFT 0
|
#define DST_RSAREG 4
|
||||||
#define RNG_SRC_RO_ENT_LOCK_ENABLE 1
|
#define SE_CONFIG_DST(x) ((x) << 2)
|
||||||
#define RNG_SRC_RO_ENT_LOCK_DISABLE 0
|
#define ALG_NOP 0
|
||||||
#define SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(x) ((x) << RNG_SRC_RO_ENT_LOCK_SHIFT)
|
#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_HASH_RESULT_REG 0x030
|
||||||
#define SE_KEYTABLE_SLOT_SHIFT 4
|
#define SE_HASH_RESULT_REG_COUNT 16
|
||||||
#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_OP_DONE_SHIFT 4
|
#define SE_CONTEXT_SAVE_CONFIG_REG 0x070
|
||||||
#define OP_DONE 1
|
#define KEYS_0_3 0
|
||||||
#define SE_OP_DONE(x, y) ((x) && ((y) << SE_OP_DONE_SHIFT))
|
#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_LAST_BLOCK 0x080
|
||||||
#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_CTR_REG_COUNT 4
|
#define SE_SHA_CONFIG_REG 0x200
|
||||||
#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 SHA_CONTINUE 0
|
#define SHA_CONTINUE 0
|
||||||
#define SHA_INIT_HASH 1
|
#define SHA_INIT_HASH 1
|
||||||
|
|
||||||
#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204
|
#define SE_SHA_MSG_LENGTH_0_REG 0x204
|
||||||
#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208
|
#define SE_SHA_MSG_LENGTH_1_REG 0x208
|
||||||
#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C
|
#define SE_SHA_MSG_LENGTH_2_REG 0x20C
|
||||||
#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210
|
#define SE_SHA_MSG_LENGTH_3_REG 0x210
|
||||||
#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214
|
#define SE_SHA_MSG_LEFT_0_REG 0x214
|
||||||
#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218
|
#define SE_SHA_MSG_LEFT_1_REG 0x218
|
||||||
#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C
|
#define SE_SHA_MSG_LEFT_2_REG 0x21C
|
||||||
#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220
|
#define SE_SHA_MSG_LEFT_3_REG 0x220
|
||||||
|
|
||||||
#define SE_HASH_RESULT_REG_COUNT 16
|
#define SE_CRYPTO_SECURITY_PERKEY_REG 0x280
|
||||||
#define SE_HASH_RESULT_REG_OFFSET 0x030
|
#define SE_KEY_LOCK_FLAG 0x80
|
||||||
#define TEGRA_SE_KEY_256_SIZE 32
|
#define SE_CRYPTO_KEYTABLE_ACCESS_REG 0x284
|
||||||
#define TEGRA_SE_KEY_192_SIZE 24
|
#define SE_CRYPTO_KEYTABLE_ACCESS_REG_COUNT 16
|
||||||
#define TEGRA_SE_KEY_128_SIZE 16
|
#define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
|
||||||
#define TEGRA_SE_AES_BLOCK_SIZE 16
|
#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
|
||||||
#define TEGRA_SE_AES_MIN_KEY_SIZE 16
|
#define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2)
|
||||||
#define TEGRA_SE_AES_MAX_KEY_SIZE 32
|
#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3)
|
||||||
#define TEGRA_SE_AES_IV_SIZE 16
|
#define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4)
|
||||||
#define TEGRA_SE_SHA_512_SIZE 64
|
#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5)
|
||||||
#define TEGRA_SE_SHA_384_SIZE 48
|
#define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6)
|
||||||
#define TEGRA_SE_SHA_256_SIZE 32
|
#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
|
||||||
#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 TEGRA_SE_AES_CMAC_DIGEST_SIZE 16
|
#define SE_CRYPTO_CONFIG_REG 0x304
|
||||||
#define TEGRA_SE_RSA512_DIGEST_SIZE 64
|
#define HASH_DISABLE 0
|
||||||
#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
|
#define HASH_ENABLE 1
|
||||||
#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
|
#define SE_CRYPTO_HASH(x) ((x) << 0)
|
||||||
#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
|
#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_CRYPTO_LINEAR_CTR_REG 0x308
|
||||||
#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
#define SE_CRYPTO_LINEAR_CTR_REG_COUNT 4
|
||||||
|
|
||||||
#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
|
#define SE_CRYPTO_BLOCK_COUNT_REG 0x318
|
||||||
#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_KEY_READ_DISABLE_SHIFT 0
|
#define SE_CRYPTO_KEYTABLE_ADDR_REG 0x31C
|
||||||
#define SE_KEY_UPDATE_DISABLE_SHIFT 1
|
#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_CRYPTO_KEYTABLE_DATA_REG 0x320
|
||||||
#define SE_CONTEXT_DRBG_BUFER_SIZE 2112
|
|
||||||
|
|
||||||
#define SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET 0
|
#define SE_CRYPTO_KEYTABLE_DST_REG 0x330
|
||||||
#define SE_CONTEXT_SAVE_RANDOM_DATA_SIZE 16
|
#define KEYS_0_3 0
|
||||||
#define SE_CONTEXT_SAVE_STICKY_BITS_OFFSET \
|
#define KEYS_4_7 1
|
||||||
(SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET + SE_CONTEXT_SAVE_RANDOM_DATA_SIZE)
|
#define ORIGINAL_IV 2
|
||||||
#define SE_CONTEXT_SAVE_STICKY_BITS_SIZE 16
|
#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 + \
|
#define SE_RNG_CONFIG_REG 0x340
|
||||||
SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
|
#define MODE_NORMAL 0
|
||||||
#define SE11_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \
|
#define MODE_FORCE_INSTANTION 1
|
||||||
SE_CONTEXT_SAVE_STICKY_BITS_SIZE + \
|
#define MODE_FORCE_RESEED 2
|
||||||
SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
|
#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_RNG_SRC_CONFIG_REG 0x344
|
||||||
#define SE_CONTEXT_ORIGINAL_IV_OFFSET (SE_CONTEXT_SAVE_KEYS_OFFSET + \
|
#define RO_ENTR_LOCK_DISABLE 0
|
||||||
SE_CONTEXT_SAVE_KEY_LENGTH)
|
#define RO_ENTR_LOCK_ENABLE 1
|
||||||
#define SE11_CONTEXT_ORIGINAL_IV_OFFSET (SE11_CONTEXT_SAVE_KEYS_OFFSET + \
|
#define SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(x) ((x) << 0)
|
||||||
SE_CONTEXT_SAVE_KEY_LENGTH)
|
#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 + \
|
#define SE_RSA_CONFIG 0x400
|
||||||
SE_CONTEXT_ORIGINAL_IV_LENGTH)
|
#define RSA_KEY_SLOT_ONE 0
|
||||||
#define SE11_CONTEXT_UPDATED_IV_OFFSET (SE11_CONTEXT_ORIGINAL_IV_OFFSET + \
|
#define RSA_KEY_SLOT_TW0 1
|
||||||
SE_CONTEXT_ORIGINAL_IV_LENGTH)
|
#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 + \
|
#define SE_RSA_EXP_SIZE_REG 0x408
|
||||||
SE_CONTEXT_UPDATED_IV_LENGTH)
|
|
||||||
#define SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET \
|
|
||||||
(SE11_CONTEXT_UPDATED_IV_OFFSET + \
|
|
||||||
SE_CONTEXT_UPDATED_IV_LENGTH)
|
|
||||||
|
|
||||||
#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 \
|
#define SE_RSA_KEYTABLE_DATA_REG 0x424
|
||||||
(SE_CONTEXT_SAVE_RSA_KEYS_OFFSET + SE_CONTEXT_SAVE_RSA_KEY_LENGTH)
|
|
||||||
|
|
||||||
#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_ERR_STATUS_REG 0x804
|
||||||
#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
#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_MISC_REG 0x808
|
||||||
#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
|
#define SE_ENTROPY_NEXT_192BIT BIT(0)
|
||||||
#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
|
#define SE_ENTROPY_VN_BYPASS 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_CLK_OVR_ON BIT(2)
|
||||||
#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_RSA_KEYTABLE_ADDR 0x420
|
#define SE_SPARE_REG 0x80C
|
||||||
#define SE_RSA_KEYTABLE_DATA 0x424
|
#define SE_ERRATA_FIX_DISABLE 0
|
||||||
#define SE_RSA_OUTPUT 0x428
|
#define SE_ERRATA_FIX_ENABLE 1
|
||||||
|
#define SE_ECO(x) ((x) << 0)
|
||||||
|
|
||||||
#define RSA_KEY_READ 0
|
#endif
|
||||||
#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 */
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2019 CTCaer
|
* Copyright (c) 2018-2021 CTCaer
|
||||||
* Copyright (c) 2018 balika011
|
* Copyright (c) 2018 balika011
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* 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;
|
u32 *pkg11_magic_off;
|
||||||
|
|
||||||
bpmp_mmu_disable();
|
bpmp_mmu_disable();
|
||||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||||
|
|
||||||
// Enable clocks.
|
// Enable clocks.
|
||||||
clock_enable_host1x();
|
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)
|
if (kb == KB_TSEC_FW_EMU_COMPAT)
|
||||||
{
|
{
|
||||||
u32 start = get_tmr_us();
|
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 key[16] = {0};
|
||||||
u32 kidx = 0;
|
u32 kidx = 0;
|
||||||
|
|
||||||
|
@ -198,9 +198,9 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
||||||
{
|
{
|
||||||
smmu_flush_all();
|
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;
|
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_MSB) = 0;
|
||||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 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:;
|
out_free:;
|
||||||
|
@ -284,7 +284,7 @@ out:;
|
||||||
clock_disable_sor_safe();
|
clock_disable_sor_safe();
|
||||||
clock_disable_tsec();
|
clock_disable_tsec();
|
||||||
bpmp_mmu_enable();
|
bpmp_mmu_enable();
|
||||||
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
bpmp_clk_rate_set(prev_fid);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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.
|
//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()
|
void bpmp_clk_rate_get()
|
||||||
{
|
{
|
||||||
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
|
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
|
||||||
|
|
||||||
if (clk_src_is_pllp)
|
if (clk_src_is_pllp)
|
||||||
bpmp_clock_set = BPMP_CLK_NORMAL;
|
bpmp_fid_current = BPMP_CLK_NORMAL;
|
||||||
else
|
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;
|
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
|
||||||
for (u32 i = 1; i < sizeof(pll_divn); i++)
|
for (u32 i = 1; i < sizeof(pll_divn); i++)
|
||||||
{
|
{
|
||||||
if (pll_divn[i] == pll_divn_curr)
|
if (pll_divn[i] == pll_divn_curr)
|
||||||
{
|
{
|
||||||
bpmp_clock_set = i;
|
bpmp_fid_current = i;
|
||||||
break;
|
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))
|
if (fid > (BPMP_CLK_MAX - 1))
|
||||||
fid = BPMP_CLK_MAX - 1;
|
fid = BPMP_CLK_MAX - 1;
|
||||||
|
|
||||||
if (bpmp_clock_set == fid)
|
if (prev_fid == fid)
|
||||||
return;
|
return prev_fid;
|
||||||
|
|
||||||
if (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.
|
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // PLLP_OUT.
|
||||||
msleep(1); // Wait a bit for clock source change.
|
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.
|
// Disable PLLC to save power.
|
||||||
clock_disable_pllc();
|
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.
|
// The following functions halt BPMP to reduce power while sleeping.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -53,6 +53,7 @@ typedef enum
|
||||||
BPMP_CLK_MAX
|
BPMP_CLK_MAX
|
||||||
} bpmp_freq_t;
|
} bpmp_freq_t;
|
||||||
|
|
||||||
|
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
||||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||||
|
|
||||||
void bpmp_mmu_maintenance(u32 op, bool force);
|
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_enable();
|
||||||
void bpmp_mmu_disable();
|
void bpmp_mmu_disable();
|
||||||
void bpmp_clk_rate_get();
|
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_usleep(u32 us);
|
||||||
void bpmp_msleep(u32 ms);
|
void bpmp_msleep(u32 ms);
|
||||||
void bpmp_halt();
|
void bpmp_halt();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -42,6 +42,7 @@
|
||||||
#include <storage/nx_sd.h>
|
#include <storage/nx_sd.h>
|
||||||
#include <storage/sdmmc.h>
|
#include <storage/sdmmc.h>
|
||||||
#include <thermal/fan.h>
|
#include <thermal/fan.h>
|
||||||
|
#include <thermal/tmp451.h>
|
||||||
#include <utils/util.h>
|
#include <utils/util.h>
|
||||||
|
|
||||||
extern boot_cfg_t b_cfg;
|
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.
|
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)
|
static void _config_gpios(bool nx_hoag)
|
||||||
{
|
{
|
||||||
// Clamp inputs when tristated.
|
// Clamp inputs when tristated.
|
||||||
|
@ -263,7 +265,7 @@ static void _config_se_brom()
|
||||||
FUSE(FUSE_PRIVATE_KEY3)
|
FUSE(FUSE_PRIVATE_KEY3)
|
||||||
};
|
};
|
||||||
// Set SBK to slot 14.
|
// 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.
|
// Lock SBK from being read.
|
||||||
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
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.
|
// This memset needs to happen here, else TZRAM will behave weirdly later on.
|
||||||
memset((void *)TZRAM_BASE, 0, 0x10000);
|
memset((void *)TZRAM_BASE, 0, 0x10000);
|
||||||
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
|
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
|
// Clear the boot reason to avoid problems later
|
||||||
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
|
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
|
||||||
|
@ -419,19 +421,18 @@ void hw_init()
|
||||||
bpmp_mmu_enable();
|
bpmp_mmu_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hw_reinit_workaround(bool coreboot, u32 magic)
|
void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
||||||
{
|
{
|
||||||
// Disable BPMP max clock.
|
// Disable BPMP max clock.
|
||||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||||
|
|
||||||
#ifdef NYX
|
#ifdef NYX
|
||||||
// Deinit touchscreen, 5V regulators and Joy-Con.
|
// Disable temperature sensor, touchscreen, 5V regulators and Joy-Con.
|
||||||
touch_power_off();
|
tmp451_end();
|
||||||
set_fan_duty(0);
|
set_fan_duty(0);
|
||||||
|
touch_power_off();
|
||||||
jc_deinit();
|
jc_deinit();
|
||||||
regulator_5v_disable(REGULATOR_5V_ALL);
|
regulator_5v_disable(REGULATOR_5V_ALL);
|
||||||
clock_disable_uart(UART_B);
|
|
||||||
clock_disable_uart(UART_C);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Flush/disable MMU cache and set DRAM clock to 204MHz.
|
// 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);
|
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Power off display.
|
// Seamless display or display power off.
|
||||||
display_end();
|
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.
|
// 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);
|
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);
|
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
|
#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0.
|
||||||
|
#define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit.
|
||||||
|
|
||||||
void hw_init();
|
void hw_init();
|
||||||
void hw_reinit_workaround(bool coreboot, u32 magic);
|
void hw_reinit_workaround(bool coreboot, u32 magic);
|
||||||
u32 hw_get_chip_id();
|
u32 hw_get_chip_id();
|
||||||
|
|
|
@ -122,7 +122,12 @@ u32 uart_get_IIR(u32 idx)
|
||||||
{
|
{
|
||||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[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)
|
void uart_set_IIR(u32 idx)
|
||||||
|
|
|
@ -54,6 +54,17 @@
|
||||||
#define UART_IIR_FCR_RX_CLR 0x2
|
#define UART_IIR_FCR_RX_CLR 0x2
|
||||||
#define UART_IIR_FCR_EN_FIFO 0x1
|
#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_RTS 0x2
|
||||||
#define UART_MCR_DTR 0x1
|
#define UART_MCR_DTR 0x1
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,11 @@
|
||||||
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
||||||
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR 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 */
|
/* class 11 */
|
||||||
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
||||||
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr 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
|
* 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)
|
* Card Command Classes (CCC)
|
||||||
|
@ -244,6 +252,7 @@ c : clear by read
|
||||||
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
||||||
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
|
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
|
||||||
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* 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_PARTITION_SUPPORT 160 /* RO */
|
||||||
#define EXT_CSD_HPI_MGMT 161 /* R/W */
|
#define EXT_CSD_HPI_MGMT 161 /* R/W */
|
||||||
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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);
|
void sd_error_count_increment(u8 type);
|
||||||
u16 *sd_get_error_count();
|
u16 *sd_get_error_count();
|
||||||
bool sd_get_card_removed();
|
bool sd_get_card_removed();
|
||||||
|
bool sd_get_card_initialized();
|
||||||
|
bool sd_get_card_mounted();
|
||||||
u32 sd_get_mode();
|
u32 sd_get_mode();
|
||||||
int sd_init_retry(bool power_cycle);
|
int sd_init_retry(bool power_cycle);
|
||||||
bool sd_initialize(bool power_cycle);
|
bool sd_initialize(bool power_cycle);
|
||||||
bool sd_mount();
|
bool sd_mount();
|
||||||
void sd_unmount();
|
void sd_unmount();
|
||||||
void sd_end();
|
void sd_end();
|
||||||
|
bool sd_is_gpt();
|
||||||
void *sd_file_read(const char *path, u32 *fsize);
|
void *sd_file_read(const char *path, u32 *fsize);
|
||||||
int sd_save_to_file(void *buf, u32 size, const char *filename);
|
int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Ramdisk driver for Tegra X1
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -19,23 +19,40 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "ramdisk.h"
|
#include "ramdisk.h"
|
||||||
|
#include <libs/fatfs/diskio.h>
|
||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
#include <memory_map.h>
|
#include <memory_map.h>
|
||||||
|
|
||||||
int ram_disk_init(FATFS *ram_fs)
|
static u32 disk_size = 0;
|
||||||
|
|
||||||
|
int ram_disk_init(FATFS *ram_fs, u32 ramdisk_size)
|
||||||
{
|
{
|
||||||
int res;
|
int res = 0;
|
||||||
u8 *buf = malloc(0x400000);
|
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.
|
// Set ramdisk size.
|
||||||
if (!res)
|
ramdisk_size >>= 9;
|
||||||
res = f_mount(ram_fs, "ram:", 1); // Mount ramdisk.
|
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;
|
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 sector_off = RAM_DISK_ADDR + (sector << 9);
|
||||||
u32 bytes_count = sector_count << 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;
|
return 1;
|
||||||
|
|
||||||
memcpy(buf, (void *)sector_off, bytes_count);
|
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 sector_off = RAM_DISK_ADDR + (sector << 9);
|
||||||
u32 bytes_count = sector_count << 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;
|
return 1;
|
||||||
|
|
||||||
memcpy((void *)sector_off, buf, bytes_count);
|
memcpy((void *)sector_off, buf, bytes_count);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Ramdisk driver for Tegra X1
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#define RAMDISK_CLUSTER_SZ 32768
|
#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_read(u32 sector, u32 sector_count, void *buf);
|
||||||
int ram_disk_write(u32 sector, u32 sector_count, const void *buf);
|
int ram_disk_write(u32 sector, u32 sector_count, const void *buf);
|
||||||
|
|
||||||
|
|
121
bdk/storage/sd.h
121
bdk/storage/sd.h
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -14,60 +14,79 @@
|
||||||
/* SD commands type argument response */
|
/* SD commands type argument response */
|
||||||
/* class 0 */
|
/* class 0 */
|
||||||
/* This is basically the same command as for MMC with some quirks. */
|
/* This is basically the same command as for MMC with some quirks. */
|
||||||
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
||||||
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
|
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
|
||||||
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
|
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
|
||||||
|
|
||||||
/* class 10 */
|
/* class 10 */
|
||||||
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
||||||
|
|
||||||
/* class 5 */
|
/* class 5 */
|
||||||
#define SD_ERASE_WR_BLK_START 32 /* 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 */
|
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
|
||||||
|
|
||||||
/* Application commands */
|
/* Application commands */
|
||||||
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width 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_SD_STATUS 13 /* adtc R1 */
|
||||||
#define SD_APP_SEND_NUM_WR_BLKS 22 /* 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_OP_COND 41 /* bcr [31:0] OCR R3 */
|
||||||
#define SD_APP_SET_CLR_CARD_DETECT 42
|
#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */
|
||||||
#define SD_APP_SEND_SCR 51 /* 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 */
|
/* OCR bit definitions */
|
||||||
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
|
#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */
|
||||||
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
|
#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_VDD_27_34 (0x7F << 15) /* VDD voltage 2.7 ~ 3.4 */
|
#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_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
|
||||||
#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */
|
#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_VHD_27_36 (1 << 8) /* VDD voltage 2.7 ~ 3.6 */
|
#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:
|
* SD_SWITCH argument format:
|
||||||
*
|
*
|
||||||
* [31] Check (0) or switch (1)
|
* [31] Check (0) or switch (1)
|
||||||
* [30:24] Reserved (0)
|
* [30:24] Reserved (0)
|
||||||
* [23:20] Function group 6
|
* [23:20] Function group 6
|
||||||
* [19:16] Function group 5
|
* [19:16] Function group 5
|
||||||
* [15:12] Function group 4
|
* [15:12] Function group 4
|
||||||
* [11:8] Function group 3
|
* [11:8] Function group 3
|
||||||
* [7:4] Function group 2
|
* [7:4] Function group 2
|
||||||
* [3:0] Function group 1
|
* [3:0] Function group 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SD_SEND_IF_COND argument format:
|
* SD_SEND_IF_COND argument format:
|
||||||
*
|
*
|
||||||
* [31:12] Reserved (0)
|
* [31:12] Reserved (0)
|
||||||
* [11:8] Host Voltage Supply Flags
|
* [11:8] Host Voltage Supply Flags
|
||||||
* [7:0] Check Pattern (0xAA)
|
* [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_0 0 /* Implements system specification 1.0 - 1.01 */
|
||||||
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
|
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
|
||||||
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */
|
#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)
|
#define SD_SCR_BUS_WIDTH_4 (1<<2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SD bus widths
|
* SD bus widths
|
||||||
*/
|
*/
|
||||||
#define SD_BUS_WIDTH_1 0
|
#define SD_BUS_WIDTH_1 0
|
||||||
#define SD_BUS_WIDTH_4 2
|
#define SD_BUS_WIDTH_4 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SD bus speeds
|
* SD bus speeds
|
||||||
*/
|
*/
|
||||||
#define UHS_SDR12_BUS_SPEED 0
|
#define UHS_SDR12_BUS_SPEED 0
|
||||||
#define HIGH_SPEED_BUS_SPEED 1
|
#define HIGH_SPEED_BUS_SPEED 1
|
||||||
#define UHS_SDR25_BUS_SPEED 1
|
#define UHS_SDR25_BUS_SPEED 1
|
||||||
|
@ -112,19 +131,19 @@
|
||||||
#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800)
|
#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_CHECK 0
|
||||||
#define SD_SWITCH_SET 1
|
#define SD_SWITCH_SET 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SD_SWITCH function groups
|
* SD_SWITCH function groups
|
||||||
*/
|
*/
|
||||||
#define SD_SWITCH_GRP_ACCESS 0
|
#define SD_SWITCH_GRP_ACCESS 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SD_SWITCH access modes
|
* SD_SWITCH access modes
|
||||||
*/
|
*/
|
||||||
#define SD_SWITCH_ACCESS_DEF 0
|
#define SD_SWITCH_ACCESS_DEF 0
|
||||||
#define SD_SWITCH_ACCESS_HS 1
|
#define SD_SWITCH_ACCESS_HS 1
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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)
|
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)
|
static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmd;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmd, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0);
|
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_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmd, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0);
|
sdmmc_init_cmd(&cmdbuf, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0);
|
||||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, NULL, NULL))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
return 0;
|
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;
|
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);
|
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_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0);
|
sdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0);
|
||||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
return 0;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,10 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_req_t reqbuf;
|
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);
|
sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0);
|
||||||
|
|
||||||
reqbuf.buf = buf;
|
reqbuf.buf = buf;
|
||||||
|
@ -152,7 +156,7 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
|
||||||
reqbuf.blksize = 512;
|
reqbuf.blksize = 512;
|
||||||
reqbuf.is_write = is_write;
|
reqbuf.is_write = is_write;
|
||||||
reqbuf.is_multi_block = 1;
|
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))
|
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)
|
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;
|
u32 arg = 0;
|
||||||
switch (power)
|
switch (power)
|
||||||
{
|
{
|
||||||
case SDMMC_POWER_1_8:
|
case SDMMC_POWER_1_8:
|
||||||
arg = SD_OCR_CCS | SD_OCR_VDD_18;
|
arg = MMC_CARD_CCS | MMC_CARD_VDD_18;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDMMC_POWER_3_3:
|
case SDMMC_POWER_3_3:
|
||||||
arg = SD_OCR_CCS | SD_OCR_VDD_27_34;
|
arg = MMC_CARD_CCS | MMC_CARD_VDD_27_34;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdmmc_init_cmd(&cmd, MMC_SEND_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
|
sdmmc_init_cmd(&cmdbuf, MMC_SEND_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
|
||||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, NULL, NULL))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return sdmmc_get_rsp(storage->sdmmc, pout, 4, SDMMC_RSP_TYPE_3);
|
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;
|
u32 timeout = get_tmr_ms() + 1500;
|
||||||
|
|
||||||
while (1)
|
while (true)
|
||||||
{
|
{
|
||||||
u32 cond = 0;
|
u32 cond = 0;
|
||||||
if (!_mmc_storage_get_op_cond_inner(storage, &cond, power))
|
if (!_mmc_storage_get_op_cond_inner(storage, &cond, power))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Check if power up is done.
|
||||||
if (cond & MMC_CARD_BUSY)
|
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;
|
storage->has_sector_access = 1;
|
||||||
|
|
||||||
return 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 3: /* MMC v3.1 - v3.3 */
|
||||||
case 4: /* MMC v4 */
|
case 4: /* MMC v4 */
|
||||||
storage->cid.manfid = unstuff_bits(raw_cid, 120, 8);
|
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.oemid = unstuff_bits(raw_cid, 104, 8);
|
||||||
storage->cid.prv = unstuff_bits(raw_cid, 48, 8);
|
storage->cid.prv = unstuff_bits(raw_cid, 48, 8);
|
||||||
storage->cid.serial = unstuff_bits(raw_cid, 16, 32);
|
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)
|
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.mmca_vsn = unstuff_bits(raw_csd, 122, 4);
|
||||||
storage->csd.structure = unstuff_bits(raw_csd, 126, 2);
|
storage->csd.structure = unstuff_bits(raw_csd, 126, 2);
|
||||||
storage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12);
|
storage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12);
|
||||||
storage->csd.read_blkbits = unstuff_bits(raw_csd, 80, 4);
|
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->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)
|
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.dev_version = *(u16 *)&buf[EXT_CSD_DEVICE_VERSION];
|
||||||
storage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT];
|
storage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT];
|
||||||
storage->ext_csd.rpmb_mult = buf[EXT_CSD_RPMB_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 = buf[EXT_CSD_BKOPS_SUPPORT];
|
//storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];
|
||||||
storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];
|
//storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS];
|
||||||
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.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_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->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)
|
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.num_sectors = 1;
|
||||||
reqbuf.is_write = 0;
|
reqbuf.is_write = 0;
|
||||||
reqbuf.is_multi_block = 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))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -559,19 +575,21 @@ out:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static int _mmc_storage_enable_bkops(sdmmc_storage_t *storage)
|
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 0;
|
||||||
|
|
||||||
return _sdmmc_storage_check_status(storage);
|
return _sdmmc_storage_check_status(storage);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
||||||
{
|
{
|
||||||
memset(storage, 0, sizeof(sdmmc_storage_t));
|
memset(storage, 0, sizeof(sdmmc_storage_t));
|
||||||
storage->sdmmc = sdmmc;
|
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))
|
if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_MMC_ID, SDMMC_POWER_SAVE_DISABLE))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -587,7 +605,7 @@ DPRINTF("[MMC] went to idle state\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[MMC] got op cond\n");
|
DPRINTF("[MMC] got op cond\n");
|
||||||
|
|
||||||
if (!_sdmmc_storage_get_cid(storage, storage->raw_cid))
|
if (!_sdmmc_storage_get_cid(storage))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[MMC] got cid\n");
|
DPRINTF("[MMC] got cid\n");
|
||||||
|
|
||||||
|
@ -595,7 +613,7 @@ DPRINTF("[MMC] got cid\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[MMC] set relative addr\n");
|
DPRINTF("[MMC] set relative addr\n");
|
||||||
|
|
||||||
if (!_sdmmc_storage_get_csd(storage, storage->raw_csd))
|
if (!_sdmmc_storage_get_csd(storage))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[MMC] got csd\n");
|
DPRINTF("[MMC] got csd\n");
|
||||||
_mmc_storage_parse_csd(storage);
|
_mmc_storage_parse_csd(storage);
|
||||||
|
@ -612,13 +630,9 @@ DPRINTF("[MMC] card selected\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[MMC] set blocklen to 512\n");
|
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.
|
||||||
//Check system specification version, only version 4.0 and later support below features.
|
if (storage->csd.mmca_vsn < CSD_SPEC_VER_4)
|
||||||
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);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (!_mmc_storage_switch_buswidth(storage, bus_width))
|
if (!_mmc_storage_switch_buswidth(storage, bus_width))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -628,21 +642,20 @@ DPRINTF("[MMC] switched buswidth\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[MMC] got ext_csd\n");
|
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);
|
//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().
|
if (storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_AUTO_BKOPS_MASK))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
_mmc_storage_enable_bkops(storage);
|
_mmc_storage_enable_bkops(storage);
|
||||||
DPRINTF("[MMC] BKOPS enabled\n");
|
DPRINTF("[MMC] BKOPS enabled\n");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
|
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
|
||||||
return 0;
|
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);
|
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;
|
u32 tmp;
|
||||||
if (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))
|
if (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))
|
||||||
return 0;
|
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)
|
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);
|
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;
|
sdmmc_cmd_t cmdbuf;
|
||||||
u16 vhd_pattern = SD_VHD_27_36 | 0xAA;
|
u16 vhd_pattern = SD_VHD_27_36 | 0xAA;
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0);
|
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0);
|
||||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
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;
|
u32 resp = 0;
|
||||||
if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5))
|
sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5);
|
||||||
return 2; // Failed.
|
|
||||||
|
|
||||||
// Check if VHD was accepted and pattern was properly returned.
|
// Check if VHD was accepted and pattern was properly returned.
|
||||||
if ((resp & 0xFFF) == vhd_pattern)
|
if ((resp & 0xFFF) == vhd_pattern)
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
// Failed.
|
return 0;
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
sdmmc_cmd_t cmdbuf;
|
||||||
// Support for Current > 150mA
|
// 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
|
// 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
|
// 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.
|
// This is needed for most cards. Do not set bit7 even if 1.8V is supported.
|
||||||
arg |= SD_OCR_VDD_32_33;
|
arg |= SD_OCR_VDD_32_33;
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
|
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 0;
|
||||||
|
|
||||||
return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);
|
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;
|
u32 timeout = get_tmr_ms() + 1500;
|
||||||
|
|
||||||
while (1)
|
while (true)
|
||||||
{
|
{
|
||||||
u32 cond = 0;
|
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;
|
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);
|
DPRINTF("[SD] op cond: %08X, lv: %d\n", cond, bus_uhs_support);
|
||||||
|
|
||||||
|
// Check if card is high capacity.
|
||||||
if (cond & SD_OCR_CCS)
|
if (cond & SD_OCR_CCS)
|
||||||
storage->has_sector_access = 1;
|
storage->has_sector_access = 1;
|
||||||
|
|
||||||
// Check if card supports 1.8V signaling.
|
// Check if card supports 1.8V signaling.
|
||||||
if (cond & SD_ROCR_S18A && bus_uhs_support)
|
if (cond & SD_ROCR_S18A && bus_uhs_support)
|
||||||
{
|
{
|
||||||
//The low voltage regulator configuration is valid for SDMMC1 only.
|
// Switch to 1.8V signaling.
|
||||||
if (storage->sdmmc->id == SDMMC_1 &&
|
if (_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))
|
||||||
_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))
|
|
||||||
{
|
{
|
||||||
if (!sdmmc_enable_low_voltage(storage->sdmmc))
|
if (!sdmmc_enable_low_voltage(storage->sdmmc))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -776,7 +792,7 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
|
||||||
|
|
||||||
u32 timeout = get_tmr_ms() + 1500;
|
u32 timeout = get_tmr_ms() + 1500;
|
||||||
|
|
||||||
while (1)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
break;
|
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.sda_vsn = unstuff_bits(resp, 56, 4);
|
||||||
storage->scr.bus_widths = unstuff_bits(resp, 48, 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)
|
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);
|
storage->scr.sda_spec3 = unstuff_bits(resp, 47, 1);
|
||||||
if (storage->scr.sda_spec3)
|
if (storage->scr.sda_spec3)
|
||||||
storage->scr.cmds = unstuff_bits(resp, 32, 2);
|
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.num_sectors = 1;
|
||||||
reqbuf.is_write = 0;
|
reqbuf.is_write = 0;
|
||||||
reqbuf.is_multi_block = 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))
|
if (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -859,7 +876,7 @@ int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
|
||||||
reqbuf.num_sectors = 1;
|
reqbuf.num_sectors = 1;
|
||||||
reqbuf.is_write = 0;
|
reqbuf.is_write = 0;
|
||||||
reqbuf.is_multi_block = 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))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
return 0;
|
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.num_sectors = 1;
|
||||||
reqbuf.is_write = 0;
|
reqbuf.is_write = 0;
|
||||||
reqbuf.is_multi_block = 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))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
return 0;
|
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);
|
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;
|
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)
|
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_ssr1[4];
|
||||||
u32 raw_ssr2[4];
|
u32 raw_ssr2[4];
|
||||||
|
|
||||||
raw_ssr1[3] = *(u32 *)&storage->raw_ssr[12];
|
memcpy(raw_ssr1, &storage->raw_ssr[0], 16);
|
||||||
raw_ssr1[2] = *(u32 *)&storage->raw_ssr[8];
|
memcpy(raw_ssr2, &storage->raw_ssr[16], 16);
|
||||||
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];
|
|
||||||
|
|
||||||
storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1;
|
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);
|
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:
|
case 0:
|
||||||
storage->ssr.speed_class = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
storage->ssr.speed_class = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
storage->ssr.speed_class = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
storage->ssr.speed_class = 6;
|
storage->ssr.speed_class = speed_class << 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -1144,19 +1146,18 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
storage->ssr.speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8);
|
storage->ssr.speed_class = speed_class;
|
||||||
break;
|
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.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);
|
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_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_APP_SD_STATUS, 0, SDMMC_RSP_TYPE_1, 0);
|
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.num_sectors = 1;
|
||||||
reqbuf.is_write = 0;
|
reqbuf.is_write = 0;
|
||||||
reqbuf.is_multi_block = 0;
|
reqbuf.is_multi_block = 0;
|
||||||
reqbuf.is_auto_cmd12 = 0;
|
reqbuf.is_auto_stop_trn = 0;
|
||||||
|
|
||||||
if (!(storage->csd.cmdclass & CCC_APP_SPEC))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1180,14 +1181,16 @@ DPRINTF("[SD] ssr: Card lacks mandatory SD Status function\n");
|
||||||
|
|
||||||
u32 tmp = 0;
|
u32 tmp = 0;
|
||||||
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
|
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 + 3] = buf[i];
|
||||||
storage->raw_ssr[i + 2] = buf[i + 1];
|
storage->raw_ssr[i + 2] = buf[i + 1];
|
||||||
storage->raw_ssr[i + 1] = buf[i + 2];
|
storage->raw_ssr[i + 1] = buf[i + 2];
|
||||||
storage->raw_ssr[i] = buf[i + 3];
|
storage->raw_ssr[i] = buf[i + 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
_sd_storage_parse_ssr(storage);
|
_sd_storage_parse_ssr(storage);
|
||||||
//gfx_hexdump(0, storage->raw_ssr, 64);
|
//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);
|
u32 *raw_cid = (u32 *)&(storage->raw_cid);
|
||||||
|
|
||||||
storage->cid.manfid = unstuff_bits(raw_cid, 120, 8);
|
storage->cid.manfid = unstuff_bits(raw_cid, 120, 8);
|
||||||
storage->cid.oemid = unstuff_bits(raw_cid, 104, 16);
|
storage->cid.oemid = unstuff_bits(raw_cid, 104, 16);
|
||||||
storage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8);
|
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[1] = unstuff_bits(raw_cid, 88, 8);
|
||||||
storage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 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[3] = unstuff_bits(raw_cid, 72, 8);
|
||||||
storage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8);
|
storage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8);
|
||||||
storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4);
|
storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4);
|
||||||
storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4);
|
storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4);
|
||||||
storage->cid.serial = unstuff_bits(raw_cid, 24, 32);
|
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.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)
|
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:
|
case 0:
|
||||||
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
|
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;
|
break;
|
||||||
|
|
||||||
case 1:
|
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.capacity = storage->csd.c_size << 10;
|
||||||
storage->csd.read_blkbits = 9;
|
storage->csd.read_blkbits = 9;
|
||||||
break;
|
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)
|
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 sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
||||||
{
|
{
|
||||||
int is_version_1 = 0;
|
u32 tmp = 0;
|
||||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
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);
|
DPRINTF("[SD] init: bus: %d, type: %d\n", bus_width, type);
|
||||||
|
|
||||||
|
@ -1282,18 +1294,15 @@ DPRINTF("[SD] after init\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] went to idle state\n");
|
DPRINTF("[SD] went to idle state\n");
|
||||||
|
|
||||||
is_version_1 = _sd_storage_send_if_cond(storage);
|
if (!_sd_storage_send_if_cond(storage, &is_sdsc))
|
||||||
if (is_version_1 == 2) // Failed.
|
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] after send if cond\n");
|
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_sdsc, bus_uhs_support))
|
||||||
|
|
||||||
if (!_sd_storage_get_op_cond(storage, is_version_1, bus_uhs_support))
|
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] got op cond\n");
|
DPRINTF("[SD] got op cond\n");
|
||||||
|
|
||||||
if (!_sdmmc_storage_get_cid(storage, storage->raw_cid))
|
if (!_sdmmc_storage_get_cid(storage))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] got cid\n");
|
DPRINTF("[SD] got cid\n");
|
||||||
_sd_storage_parse_cid(storage);
|
_sd_storage_parse_cid(storage);
|
||||||
|
@ -1302,30 +1311,16 @@ DPRINTF("[SD] got cid\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] got rca (= %04X)\n", storage->rca);
|
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;
|
return 0;
|
||||||
DPRINTF("[SD] got csd\n");
|
DPRINTF("[SD] got csd\n");
|
||||||
|
|
||||||
//Parse CSD.
|
|
||||||
_sd_storage_parse_csd(storage);
|
_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 (!storage->is_low_voltage)
|
||||||
{
|
{
|
||||||
if (!sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_DS12))
|
if (!sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_DS12))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] after setup clock\n");
|
DPRINTF("[SD] after setup default clock\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_sdmmc_storage_select_card(storage))
|
if (!_sdmmc_storage_select_card(storage))
|
||||||
|
@ -1336,19 +1331,17 @@ DPRINTF("[SD] card selected\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] set blocklen to 512\n");
|
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))
|
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] cleared card detect\n");
|
DPRINTF("[SD] cleared card detect\n");
|
||||||
|
|
||||||
if (!_sd_storage_get_scr(storage, buf))
|
if (!_sd_storage_get_scr(storage, buf))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//gfx_hexdump(0, storage->raw_scr, 8);
|
|
||||||
DPRINTF("[SD] got scr\n");
|
DPRINTF("[SD] got scr\n");
|
||||||
|
|
||||||
// Check if card supports a wider bus and if it's not SD Version 1.X
|
// 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 & 4) && (storage->scr.sda_vsn & 0xF))
|
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))
|
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1370,7 +1363,7 @@ DPRINTF("[SD] enabled UHS\n");
|
||||||
|
|
||||||
sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE);
|
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))
|
if (!_sd_storage_enable_hs_high_volt(storage, buf))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1389,7 +1382,7 @@ DPRINTF("[SD] enabled HS\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse additional card info from sd status.
|
// 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");
|
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)
|
int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
|
||||||
{
|
{
|
||||||
u32 resp;
|
u32 resp;
|
||||||
sdmmc_cmd_t cmdbuf;
|
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;
|
sdmmc_req_t reqbuf;
|
||||||
reqbuf.buf = buf;
|
reqbuf.buf = buf;
|
||||||
|
@ -1415,7 +1408,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
|
||||||
reqbuf.num_sectors = 1;
|
reqbuf.num_sectors = 1;
|
||||||
reqbuf.is_write = 1;
|
reqbuf.is_write = 1;
|
||||||
reqbuf.is_multi_block = 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))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -30,18 +30,18 @@ typedef enum _sdmmc_type
|
||||||
|
|
||||||
EMMC_GPP = 0,
|
EMMC_GPP = 0,
|
||||||
EMMC_BOOT0 = 1,
|
EMMC_BOOT0 = 1,
|
||||||
EMMC_BOOT1 = 2
|
EMMC_BOOT1 = 2,
|
||||||
|
EMMC_RPMB = 3
|
||||||
} sdmmc_type;
|
} sdmmc_type;
|
||||||
|
|
||||||
typedef struct _mmc_cid
|
typedef struct _mmc_cid
|
||||||
{
|
{
|
||||||
u32 manfid;
|
u32 manfid;
|
||||||
u8 prod_name[8];
|
u8 prod_name[8];
|
||||||
u8 card_bga;
|
|
||||||
u8 prv;
|
|
||||||
u32 serial;
|
u32 serial;
|
||||||
u16 oemid;
|
u16 oemid;
|
||||||
u16 year;
|
u16 year;
|
||||||
|
u8 prv;
|
||||||
u8 hwrev;
|
u8 hwrev;
|
||||||
u8 fwrev;
|
u8 fwrev;
|
||||||
u8 month;
|
u8 month;
|
||||||
|
@ -65,19 +65,20 @@ typedef struct _mmc_csd
|
||||||
|
|
||||||
typedef struct _mmc_ext_csd
|
typedef struct _mmc_ext_csd
|
||||||
{
|
{
|
||||||
u32 sectors;
|
//u8 bkops; /* background support bit */
|
||||||
int bkops; /* background support bit */
|
//u8 bkops_en; /* manual bkops enable bit */
|
||||||
int bkops_en; /* manual bkops enable bit */
|
//u8 bkops_status; /* 246 */
|
||||||
u8 rev;
|
u8 rev;
|
||||||
u8 ext_struct; /* 194 */
|
u8 ext_struct; /* 194 */
|
||||||
u8 card_type; /* 196 */
|
u8 card_type; /* 196 */
|
||||||
u8 bkops_status; /* 246 */
|
|
||||||
u8 pre_eol_info;
|
u8 pre_eol_info;
|
||||||
u8 dev_life_est_a;
|
u8 dev_life_est_a;
|
||||||
u8 dev_life_est_b;
|
u8 dev_life_est_b;
|
||||||
u8 boot_mult;
|
u8 boot_mult;
|
||||||
u8 rpmb_mult;
|
u8 rpmb_mult;
|
||||||
u16 dev_version;
|
u16 dev_version;
|
||||||
|
u32 cache_size;
|
||||||
|
u32 max_enh_mult;
|
||||||
} mmc_ext_csd_t;
|
} mmc_ext_csd_t;
|
||||||
|
|
||||||
typedef struct _sd_scr
|
typedef struct _sd_scr
|
||||||
|
@ -90,13 +91,13 @@ typedef struct _sd_scr
|
||||||
|
|
||||||
typedef struct _sd_ssr
|
typedef struct _sd_ssr
|
||||||
{
|
{
|
||||||
u8 bus_width;
|
u8 bus_width;
|
||||||
u8 speed_class;
|
u8 speed_class;
|
||||||
u8 uhs_grade;
|
u8 uhs_grade;
|
||||||
u8 video_class;
|
u8 video_class;
|
||||||
u8 app_class;
|
u8 app_class;
|
||||||
u8 au_size;
|
u8 au_size;
|
||||||
u8 uhs_au_size;
|
u8 uhs_au_size;
|
||||||
u32 protected_size;
|
u32 protected_size;
|
||||||
} sd_ssr_t;
|
} 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_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);
|
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
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* 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;
|
*blkcnt_out = blkcnt;
|
||||||
|
|
||||||
u32 trnmode = SDHCI_TRNS_DMA;
|
u32 trnmode = SDHCI_TRNS_DMA;
|
||||||
|
|
||||||
|
// Set mulitblock request.
|
||||||
if (req->is_multi_block)
|
if (req->is_multi_block)
|
||||||
trnmode = SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_DMA;
|
trnmode = SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_DMA;
|
||||||
|
|
||||||
|
// Set request direction.
|
||||||
if (!req->is_write)
|
if (!req->is_write)
|
||||||
trnmode |= SDHCI_TRNS_READ;
|
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;
|
sdmmc->regs->trnmod = trnmode;
|
||||||
|
|
||||||
|
@ -1070,7 +1078,7 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||||
if (blkcnt_out)
|
if (blkcnt_out)
|
||||||
*blkcnt_out = blkcnt;
|
*blkcnt_out = blkcnt;
|
||||||
|
|
||||||
if (req->is_auto_cmd12)
|
if (req->is_auto_stop_trn)
|
||||||
sdmmc->rsp3 = sdmmc->regs->rspreg3;
|
sdmmc->rsp3 = sdmmc->regs->rspreg3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1371,12 +1379,12 @@ void sdmmc_end(sdmmc_t *sdmmc)
|
||||||
_sdmmc_sd_clock_disable(sdmmc);
|
_sdmmc_sd_clock_disable(sdmmc);
|
||||||
// Disable SDMMC power.
|
// Disable SDMMC power.
|
||||||
_sdmmc_set_io_power(sdmmc, SDMMC_POWER_OFF);
|
_sdmmc_set_io_power(sdmmc, SDMMC_POWER_OFF);
|
||||||
|
_sdmmc_commit_changes(sdmmc);
|
||||||
|
|
||||||
// Disable SD card power.
|
// Disable SD card power.
|
||||||
if (sdmmc->id == SDMMC_1)
|
if (sdmmc->id == SDMMC_1)
|
||||||
sdmmc1_disable_power();
|
sdmmc1_disable_power();
|
||||||
|
|
||||||
_sdmmc_commit_changes(sdmmc);
|
|
||||||
clock_sdmmc_disable(sdmmc->id);
|
clock_sdmmc_disable(sdmmc->id);
|
||||||
sdmmc->clock_stopped = 1;
|
sdmmc->clock_stopped = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ typedef struct _sdmmc_req_t
|
||||||
u32 num_sectors;
|
u32 num_sectors;
|
||||||
int is_write;
|
int is_write;
|
||||||
int is_multi_block;
|
int is_multi_block;
|
||||||
int is_auto_cmd12;
|
int is_auto_stop_trn;
|
||||||
} sdmmc_req_t;
|
} sdmmc_req_t;
|
||||||
|
|
||||||
int sdmmc_get_io_power(sdmmc_t *sdmmc);
|
int sdmmc_get_io_power(sdmmc_t *sdmmc);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
void set_fan_duty(u32 duty)
|
void set_fan_duty(u32 duty)
|
||||||
{
|
{
|
||||||
static bool fan_init = false;
|
static bool fan_init = false;
|
||||||
static u16 curr_duty = -1;
|
static u16 curr_duty = -1;
|
||||||
|
|
||||||
if (curr_duty == duty)
|
if (curr_duty == duty)
|
||||||
return;
|
return;
|
||||||
|
@ -79,15 +79,14 @@ void get_fan_speed(u32 *duty, u32 *rpm)
|
||||||
{
|
{
|
||||||
if (rpm)
|
if (rpm)
|
||||||
{
|
{
|
||||||
u32 irq_count = 1;
|
u32 irq_count = 0;
|
||||||
bool should_read = true;
|
bool should_read = true;
|
||||||
bool irq_val = 0;
|
|
||||||
|
|
||||||
// Poll irqs for 2 seconds.
|
// Poll irqs for 2 seconds. (5 seconds for accurate count).
|
||||||
int timer = get_tmr_us() + 1000000;
|
int timer = get_tmr_us() + 2000000;
|
||||||
while (timer - get_tmr_us())
|
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)
|
if (irq_val && should_read)
|
||||||
{
|
{
|
||||||
irq_count++;
|
irq_count++;
|
||||||
|
@ -97,8 +96,11 @@ void get_fan_speed(u32 *duty, u32 *rpm)
|
||||||
should_read = true;
|
should_read = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Halve the irq count.
|
||||||
|
irq_count /= 2;
|
||||||
|
|
||||||
// Calculate rpm based on triggered interrupts.
|
// Calculate rpm based on triggered interrupts.
|
||||||
*rpm = 60000000 / ((1000000 * 2) / irq_count);
|
*rpm = irq_count * (60 / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duty)
|
if (duty)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* SOC/PCB Temperature driver for Nintendo Switch's TI TMP451
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -16,7 +16,9 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <soc/hw_init.h>
|
||||||
#include <soc/i2c.h>
|
#include <soc/i2c.h>
|
||||||
|
#include <soc/t210.h>
|
||||||
#include <thermal/tmp451.h>
|
#include <thermal/tmp451.h>
|
||||||
|
|
||||||
u16 tmp451_get_soc_temp(bool intenger)
|
u16 tmp451_get_soc_temp(bool intenger)
|
||||||
|
@ -56,6 +58,20 @@ void tmp451_init()
|
||||||
// Disable ALARM and Range to 0 - 127 oC.
|
// Disable ALARM and Range to 0 - 127 oC.
|
||||||
i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CONFIG_REG, 0x80);
|
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.
|
// 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);
|
i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CNV_RATE_REG, 9);
|
||||||
tmp451_get_soc_temp(false);
|
tmp451_get_soc_temp(false);
|
||||||
|
@ -63,3 +79,9 @@ void tmp451_init()
|
||||||
// Set rate to every 4 seconds.
|
// Set rate to every 4 seconds.
|
||||||
i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CNV_RATE_REG, 2);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -32,11 +32,15 @@
|
||||||
#define TMP451_SOC_TMP_DEC_REG 0x10
|
#define TMP451_SOC_TMP_DEC_REG 0x10
|
||||||
#define TMP451_PCB_TMP_DEC_REG 0x15
|
#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
|
// 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.
|
// and the LSByte is the decimal point truncated to 2 decimal places.
|
||||||
// Otherwise it's an integer oC.
|
// Otherwise it's an integer oC.
|
||||||
u16 tmp451_get_soc_temp(bool integer);
|
u16 tmp451_get_soc_temp(bool integer);
|
||||||
u16 tmp451_get_pcb_temp(bool integer);
|
u16 tmp451_get_pcb_temp(bool integer);
|
||||||
void tmp451_init();
|
void tmp451_init();
|
||||||
|
void tmp451_end();
|
||||||
|
|
||||||
#endif /* __TMP451_H_ */
|
#endif /* __TMP451_H_ */
|
||||||
|
|
|
@ -203,7 +203,7 @@ typedef struct _bulk_ctxt_t {
|
||||||
typedef struct _usbd_gadget_ums_t {
|
typedef struct _usbd_gadget_ums_t {
|
||||||
bulk_ctxt_t bulk_ctxt;
|
bulk_ctxt_t bulk_ctxt;
|
||||||
|
|
||||||
int cmnd_size;
|
u32 cmnd_size;
|
||||||
u8 cmnd[SCSI_MAX_CMD_SZ];
|
u8 cmnd[SCSI_MAX_CMD_SZ];
|
||||||
|
|
||||||
u32 lun_idx; // lun index
|
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)
|
while (amount_left_to_write > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Queue a request for more data from the host */
|
/* 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.
|
// Limit write to max supported read from EP OUT.
|
||||||
amount = MIN(amount_left_to_req, UMS_EP_OUT_MAX_XFER);
|
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!");
|
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 = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||||
ums->lun.sense_data_info = usb_lba_offset;
|
ums->lun.sense_data_info = usb_lba_offset;
|
||||||
ums->lun.info_valid = 1;
|
ums->lun.info_valid = 1;
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the next buffer.
|
// 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
|
// Check whether the command is properly formed and whether its data size
|
||||||
// and direction agree with the values we already have.
|
// 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)
|
enum data_direction data_dir, u32 mask, int needs_medium)
|
||||||
{
|
{
|
||||||
//const char dirletter[4] = {'u', 'o', 'i', 'n'};
|
//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? */
|
/* Is the CBW meaningful? */
|
||||||
if (cbw->Lun >= UMS_MAX_LUN || cbw->Flags & ~USB_BULK_IN_FLAG ||
|
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",
|
gfx_printf("USB: non-meaningful CBW: lun = %X, flags = 0x%X, cmdlen %X\n",
|
||||||
cbw->Lun, cbw->Flags, cbw->Length);
|
cbw->Lun, cbw->Flags, cbw->Length);
|
||||||
|
@ -1837,6 +1835,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||||
// Initialize sdmmc.
|
// Initialize sdmmc.
|
||||||
if (usbs->type == MMC_SD)
|
if (usbs->type == MMC_SD)
|
||||||
{
|
{
|
||||||
|
sd_end();
|
||||||
sd_mount();
|
sd_mount();
|
||||||
sd_unmount();
|
sd_unmount();
|
||||||
ums.lun.sdmmc = &sd_sdmmc;
|
ums.lun.sdmmc = &sd_sdmmc;
|
||||||
|
@ -1907,7 +1906,10 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||||
send_status(&ums, &ums.bulk_ctxt);
|
send_status(&ums, &ums.bulk_ctxt);
|
||||||
} while (ums.state != UMS_STATE_TERMINATED);
|
} 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;
|
goto exit;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
|
@ -29,7 +29,7 @@ u8 btn_read()
|
||||||
res |= BTN_VOL_DOWN;
|
res |= BTN_VOL_DOWN;
|
||||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
|
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
|
||||||
res |= BTN_VOL_UP;
|
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;
|
res |= BTN_POWER;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,16 +21,16 @@
|
||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
|
|
||||||
|
#define MAX_ENTRIES 64
|
||||||
|
|
||||||
char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs)
|
char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs)
|
||||||
{
|
{
|
||||||
u8 max_entries = 61;
|
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
u32 i = 0, j = 0, k = 0;
|
u32 i = 0, j = 0, k = 0;
|
||||||
DIR dir;
|
DIR dir;
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
|
|
||||||
char *dir_entries = (char *)calloc(max_entries, 256);
|
char *dir_entries = (char *)calloc(MAX_ENTRIES, 256);
|
||||||
char *temp = (char *)calloc(1, 256);
|
char *temp = (char *)calloc(1, 256);
|
||||||
|
|
||||||
if (!pattern && !f_opendir(&dir, directory))
|
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);
|
strcpy(dir_entries + (k * 256), fno.fname);
|
||||||
k++;
|
k++;
|
||||||
if (k > (max_entries - 1))
|
if (k > (MAX_ENTRIES - 1))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
|
||||||
{
|
{
|
||||||
strcpy(dir_entries + (k * 256), fno.fname);
|
strcpy(dir_entries + (k * 256), fno.fname);
|
||||||
k++;
|
k++;
|
||||||
if (k > (max_entries - 1))
|
if (k > (MAX_ENTRIES - 1))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res = f_findnext(&dir, &fno);
|
res = f_findnext(&dir, &fno);
|
||||||
|
|
|
@ -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)
|
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||||
{
|
{
|
||||||
|
FIL fp;
|
||||||
u32 lblen;
|
u32 lblen;
|
||||||
u32 pathlen = strlen(ini_path);
|
u32 pathlen = strlen(ini_path);
|
||||||
u32 k = 0;
|
u32 k = 0;
|
||||||
char lbuf[512];
|
|
||||||
char *filelist = NULL;
|
|
||||||
FIL fp;
|
|
||||||
ini_sec_t *csec = NULL;
|
ini_sec_t *csec = NULL;
|
||||||
|
|
||||||
|
char *lbuf = NULL;
|
||||||
|
char *filelist = NULL;
|
||||||
char *filename = (char *)malloc(256);
|
char *filename = (char *)malloc(256);
|
||||||
|
|
||||||
strcpy(filename, ini_path);
|
strcpy(filename, ini_path);
|
||||||
|
@ -114,8 +114,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
csec = _ini_create_section(dst, csec, "Unknown", INI_CHOICE);
|
lbuf = malloc(512);
|
||||||
list_init(&csec->kvs);
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -171,6 +170,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||||
}
|
}
|
||||||
} while (is_dir);
|
} while (is_dir);
|
||||||
|
|
||||||
|
free(lbuf);
|
||||||
free(filename);
|
free(filename);
|
||||||
free(filelist);
|
free(filelist);
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ static u32 _putn(char *buffer, u32 v, int base, char fill, int fcnt) {
|
||||||
return _puts(buffer, p);
|
return _puts(buffer, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 sprintf(char *buffer, const char *fmt, ...) {
|
u32 s_printf(char *buffer, const char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int fill, fcnt;
|
int fill, fcnt;
|
||||||
u32 count = 0;
|
u32 count = 0;
|
||||||
|
|
|
@ -19,6 +19,6 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
u32 sprintf(char *buffer, const char *fmt, ...);
|
u32 s_printf(char *buffer, const char *fmt, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#define ALWAYS_INLINE inline __attribute__((always_inline))
|
#define ALWAYS_INLINE inline __attribute__((always_inline))
|
||||||
|
|
||||||
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
#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 BIT(n) (1U << (n))
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#define MIN(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;
|
} 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
|
typedef struct __attribute__((__packed__)) _reloc_meta_t
|
||||||
{
|
{
|
||||||
u32 start;
|
u32 start;
|
||||||
|
|
|
@ -167,10 +167,10 @@ void power_set_state(power_state_t state)
|
||||||
default:
|
default:
|
||||||
// Enable/Disable soft reset wake event.
|
// Enable/Disable soft reset wake event.
|
||||||
reg = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2);
|
reg = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2);
|
||||||
if (state == POWER_OFF_RESET)
|
if (state == POWER_OFF_RESET) // Do not wake up after power off.
|
||||||
reg &= ~MAX77620_ONOFFCNFG2_SFT_RST_WK; // 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.
|
else // POWER_OFF_REBOOT. Wake up after power off.
|
||||||
reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK; // Wake up after power off.
|
reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK;
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg);
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg);
|
||||||
|
|
||||||
// Initiate power down sequence and generate a reset (regulators' state resets).
|
// Initiate power down sequence and generate a reset (regulators' state resets).
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -21,8 +21,6 @@
|
||||||
#include <utils/types.h>
|
#include <utils/types.h>
|
||||||
#include <mem/minerva.h>
|
#include <mem/minerva.h>
|
||||||
|
|
||||||
#define NYX_NEW_INFO 0x3058594E
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
REBOOT_RCM, // PMC reset. Enter RCM mode.
|
REBOOT_RCM, // PMC reset. Enter RCM mode.
|
||||||
|
@ -53,6 +51,8 @@ typedef enum
|
||||||
#define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \
|
#define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \
|
||||||
(((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000))
|
(((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000))
|
||||||
|
|
||||||
|
#define byte_swap_16(num) ((((num) >> 8) & 0xff) | (((num) << 8) & 0xff00))
|
||||||
|
|
||||||
typedef struct _cfg_op_t
|
typedef struct _cfg_op_t
|
||||||
{
|
{
|
||||||
u32 off;
|
u32 off;
|
||||||
|
@ -84,9 +84,9 @@ typedef struct _nyx_storage_t
|
||||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||||
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
|
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
|
||||||
|
|
||||||
u32 get_tmr_us();
|
u32 get_tmr_us();
|
||||||
u32 get_tmr_ms();
|
u32 get_tmr_ms();
|
||||||
u32 get_tmr_s();
|
u32 get_tmr_s();
|
||||||
void usleep(u32 us);
|
void usleep(u32 us);
|
||||||
void msleep(u32 ms);
|
void msleep(u32 ms);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ char *CombinePaths(const char *current, const char *add){
|
||||||
size_t size = strlen(current) + strlen(add) + 2;
|
size_t size = strlen(current) + strlen(add) + 2;
|
||||||
ret = (char*) malloc (size);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ void FileMenu(char *path, FSEntry_t entry){
|
||||||
FileMenuEntries[0].sizeUnion = entry.sizeUnion;
|
FileMenuEntries[0].sizeUnion = entry.sizeUnion;
|
||||||
char attribs[16];
|
char attribs[16];
|
||||||
char *attribList = GetFileAttribs(entry);
|
char *attribList = GetFileAttribs(entry);
|
||||||
sprintf(attribs, "Attribs:%s\n", attribList);
|
s_printf(attribs, "Attribs:%s\n", attribList);
|
||||||
free(attribList);
|
free(attribList);
|
||||||
FileMenuEntries[2].name = attribs;
|
FileMenuEntries[2].name = attribs;
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ int FolderMenu(const char *path){
|
||||||
|
|
||||||
char attribs[16];
|
char attribs[16];
|
||||||
char *attribList = GetFileAttribs(file);
|
char *attribList = GetFileAttribs(file);
|
||||||
sprintf(attribs, "Attribs:%s\n", attribList);
|
s_printf(attribs, "Attribs:%s\n", attribList);
|
||||||
free(attribList);
|
free(attribList);
|
||||||
FolderMenuEntries[2].name = attribs;
|
FolderMenuEntries[2].name = attribs;
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ int newMenu(Vector_t* vec, int startIndex, int screenLenX, int screenLenY, u8 op
|
||||||
if (options & ENABLEPAGECOUNT){
|
if (options & ENABLEPAGECOUNT){
|
||||||
SETCOLOR(COLOR_DEFAULT, COLOR_WHITE);
|
SETCOLOR(COLOR_DEFAULT, COLOR_WHITE);
|
||||||
char temp[40] = "";
|
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_con_setpos(YLEFT - strlen(temp) * 18, 0);
|
||||||
gfx_printf(temp);
|
gfx_printf(temp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,8 +318,8 @@ void nx_emmc_bis_cluster_cache_init()
|
||||||
free(cluster_lookup_buf);
|
free(cluster_lookup_buf);
|
||||||
|
|
||||||
// Check if carveout protected, in case of old hwinit (pre 4.0.0) chainload.
|
// Check if carveout protected, in case of old hwinit (pre 4.0.0) chainload.
|
||||||
*(vu32 *)NX_BIS_LOOKUP_ADR = 0;
|
*(vu32 *)NX_BIS_LOOKUP_ADDR = 0;
|
||||||
if (*(vu32 *)NX_BIS_LOOKUP_ADR != 0)
|
if (*(vu32 *)NX_BIS_LOOKUP_ADDR != 0)
|
||||||
{
|
{
|
||||||
cluster_lookup_buf = (u32 *)malloc(cluster_lookup_size + 0x2000);
|
cluster_lookup_buf = (u32 *)malloc(cluster_lookup_size + 0x2000);
|
||||||
cluster_lookup = (u32 *)ALIGN((u32)cluster_lookup_buf, 0x1000);
|
cluster_lookup = (u32 *)ALIGN((u32)cluster_lookup_buf, 0x1000);
|
||||||
|
@ -327,7 +327,7 @@ void nx_emmc_bis_cluster_cache_init()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cluster_lookup_buf = NULL;
|
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.
|
// Clear cluster lookup table and reset end index.
|
||||||
|
|
|
@ -41,7 +41,7 @@ void DumpSysFw(){
|
||||||
}
|
}
|
||||||
|
|
||||||
baseSdPath = malloc(36 + 16);
|
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);
|
int baseSdPathLen = strlen(baseSdPath);
|
||||||
|
|
||||||
f_mkdir("sd:/tegraexplorer");
|
f_mkdir("sd:/tegraexplorer");
|
||||||
|
@ -81,7 +81,7 @@ void DumpSysFw(){
|
||||||
int total = 1;
|
int total = 1;
|
||||||
vecDefArray(FSEntry_t*, fsEntries, fileVec);
|
vecDefArray(FSEntry_t*, fsEntries, fileVec);
|
||||||
for (int i = 0; i < fileVec.count; i++){
|
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);
|
int contentType = GetNcaType(sysPath);
|
||||||
|
|
||||||
if (contentType < 0){
|
if (contentType < 0){
|
||||||
|
@ -90,7 +90,7 @@ void DumpSysFw(){
|
||||||
}
|
}
|
||||||
|
|
||||||
char *sdPath = malloc(baseSdPathLen + 45);
|
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)
|
if (contentType == Meta)
|
||||||
memcpy(sdPath + strlen(sdPath) - 4, ".cnmt.nca", 10);
|
memcpy(sdPath + strlen(sdPath) - 4, ".cnmt.nca", 10);
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ void TakeScreenshot(){
|
||||||
char *name, *path;
|
char *name, *path;
|
||||||
const char basepath[] = "sd:/tegraexplorer/screenshots";
|
const char basepath[] = "sd:/tegraexplorer/screenshots";
|
||||||
name = malloc(40);
|
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("sd:/tegraexplorer");
|
||||||
f_mkdir(basepath);
|
f_mkdir(basepath);
|
||||||
|
|
Loading…
Reference in a new issue