Compare commits

..

45 Commits

Author SHA1 Message Date
CTCaer
5a6608dff4 Bump hekate to v5.3.4 and Nyx to v0.9.5 2020-10-27 21:28:06 +02:00
CTCaer
8f222fd0bd main: Fix update.bin creation on first boot 2020-10-27 21:27:51 +02:00
CTCaer
1f5b371608 Refactor some names
Additionally:
- Do not retry to init sd if all modes failed in Nyx.
- Do not try to read/write if sdmmc controller and card are not initialized.
2020-10-23 06:32:24 +03:00
CTCaer
ce156ab4e7 hos: Automate some eks and bis checks 2020-10-20 11:53:28 +03:00
CTCaer
94235dd005 bm92t30: Add proper info
The driver will now show more charger supported profiles and will also show selected profile.
2020-10-20 10:42:57 +03:00
CTCaer
cb471162d2 i2c: Fix packet mode 2020-10-20 10:37:33 +03:00
CTCaer
9d1c0ce308 Create update.bin if missing
This will allow l4t/Android to always use latest hekate in case of old r2p.
2020-10-20 10:34:33 +03:00
CTCaer
27b1f0e843 Various small fixes 2020-10-20 10:32:32 +03:00
CTCaer
dae7be8ec4 nyx: Allow disabling of Joycon
Setting `jcdisable=1` in nyx.ini disables the usage of Joycon completely.

This also disables the BT pairing data dumping tool.
2020-10-20 10:21:48 +03:00
CTCaer
2f5b52223c config: Add bootloader protection
`bootprotect=1` enables protection of the `bootloader` folder inside HOS.

This disallows any reading/writing of the folder and its contents inside HOS, preventing any corruption of it.

This of course has the side-effect of homebrew that depend on it (e.g. hekate Toolbox) to not work fully.
2020-10-20 10:16:12 +03:00
CTCaer
bf222290b8 hos: Add support for mesosphere
The change adds support for mesosphere loading from fss0 or sd (kernel=).
2020-10-17 23:18:48 +03:00
CTCaer
d825be5eb2 hos: Tiny refactoring 2020-10-17 23:16:16 +03:00
CTCaer
9da0e0358b Merge pull request #500 from AuroraWright/master
hos: Prevent booting emummc with failed emummc patching
2020-10-17 23:02:34 +03:00
Aurora Wright
216d97aada Push changes as requested 2020-10-17 21:11:21 +02:00
Aurora Wright
e3421fd44e hos: Prevent sysmmc boot on emummc patch failure if emummc is forced 2020-10-14 19:37:36 +02:00
CTCaer
85d43147ee Bump hekate to v5.3.3 and Nyx to v0.9.4 2020-09-15 20:24:56 +03:00
CTCaer
e3e5dab0fc nyx: Add USB Charger info 2020-09-15 20:14:56 +03:00
CTCaer
8b837dd81b bm92t30 Add USB-PD driver stub
TODO:
This driver is a stub and relies on incorrect I2C requests.
The I2C driver needs to be updated with proper multi-xfer support.

For now it replies its whole register range, according to request size.
That's because the IC does not support the classic single transfer request-response style.
2020-09-15 20:13:29 +03:00
CTCaer
8f7bdd45b1 hos: Report exFAT compatible if missing FS kip hashes 2020-09-15 19:07:16 +03:00
CTCaer
0142ac1697 Add TUI reload in case of missing bootloader files 2020-09-15 18:57:49 +03:00
CTCaer
e8fb6624c0 Merge pull request #481 from NicholeMattera/master
Added new FS patches for 10.2.0.
2020-09-15 18:39:04 +03:00
Nichole Mattera
bdb21ce3fd Added new FS patches for 10.2.0. 2020-09-15 07:26:27 -04:00
CTCaer
2ca4fb6d8f Correct readme about UMS on boot 2020-09-07 00:10:23 +03:00
CTCaer
e7900b11b4 nyx: Allow L4T last part to be unaligned 2020-09-02 13:11:03 +03:00
CTCaer
d71f6d0b99 sdmmc: Restart xfer on Read/Write error 2020-08-28 09:39:06 +03:00
CTCaer
926bd5d2fb Add SD error report on first boot 2020-08-28 09:37:48 +03:00
CTCaer
461d14c39a di: Correct panel id for AUO A062TAN02 2020-08-28 05:26:18 +03:00
CTCaer
6714cae498 i2c: Add packet mode support (32 bytes) 2020-08-27 10:04:52 +03:00
CTCaer
b20a0e74c2 i2c: Refactor 2020-08-27 10:04:26 +03:00
CTCaer
9686eaf3f1 info: Add better SD error debugging on hekate main
Now the SD Card info function on hekate main will not rely on proper FAT partition, allowing for SDMMC init and FAT mounting to be separate for debugging issues with each one.

Additionally, add SDMMC error counters info.
2020-08-15 13:23:11 +03:00
CTCaer
7b03a24196 sdmmc: Add extra error printing 2020-08-15 13:16:37 +03:00
CTCaer
98555b24f8 l4t: Clear boot mode if user canceled autoboot 2020-08-15 13:12:41 +03:00
CTCaer
3d05b58856 nyx: Add eMMC NAND cells life estimation 2020-08-15 12:33:11 +03:00
CTCaer
15b46ddb27 hos: Hold more devices in Reset for secmon launch 2020-08-15 12:31:44 +03:00
CTCaer
78c4e6510d hos: Add backup bootloader support 2020-08-15 12:30:18 +03:00
CTCaer
cd76d5ac09 nyx: Fix hang on using B button after Launch window 2020-08-15 12:22:01 +03:00
CTCaer
9c2a064817 nyx: Allow SD removal without reloading Nyx 2020-08-15 12:21:25 +03:00
CTCaer
db2da89f69 nyx: Remove delay on JC calibration
This does not help with drifting as the logged values are always changing drastically.
2020-08-15 12:19:43 +03:00
CTCaer
0652d6b3f1 util: sprintf: Fix pointer printing 2020-08-15 12:16:25 +03:00
CTCaer
1111125aab usb: Invalidate cache on ep1_out_reading_finish 2020-08-15 12:15:02 +03:00
CTCaer
4fc420616d nyx: Control UART debug completely via makefile
Also enables LvGL log.
2020-08-13 10:21:00 +03:00
CTCaer
fb7c83a66c exo: Fix exo fatal dump's header 2020-08-02 03:51:36 +03:00
CTCaer
f021665089 Bump hekate to v5.3.2 2020-07-19 23:26:05 +03:00
CTCaer
6c887c15be l4t: Disable kernel panic dumping for now 2020-07-19 23:25:49 +03:00
CTCaer
2b7722da7d hos: Fix hold usbd in reset 2020-07-19 23:10:21 +03:00
46 changed files with 1049 additions and 344 deletions

View File

@@ -55,6 +55,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
| backlight=100 | Screen backlight level. 0-255. |
@@ -67,7 +68,8 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
| umsemmcrw=1 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
| jcdisable=0 | 1: Disables Joycon driver completely. |
### Boot entry key/value combinations:
@@ -120,12 +122,12 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
| Offset / Name | Description |
| ----------------------- | ----------------------------------------------------------------- |
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`, bit6: `Boot to UMS`, bit7: `sept run`. |
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`, bit7: `sept run`. |
| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
| '0x97' extra_cfg | bit7: Force Nyx to run `Dump pkg1/2`. |
| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`, bit7: `Run Dump pkg1/2`. |
| '0x98' xt_str[128] | Depends on the set cfg bits. |
| '0x98' ums[1] | When `Boot to UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
| '0x98' ums[1] | When `Run UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
| '0x98' id[8] | When `Boot from ID` is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
| '0xA0' emummc_path[120] | When `Boot to emuMMC` is set, it will override the current emuMMC (boot entry or emummc.ini). Must be NULL terminated. |

View File

@@ -1,11 +1,11 @@
# IPL Version.
BLVERSION_MAJOR := 5
BLVERSION_MINOR := 3
BLVERSION_HOTFX := 1
BLVERSION_HOTFX := 4
BLVERSION_RSVD := 0
# Nyx Version.
NYXVERSION_MAJOR := 0
NYXVERSION_MINOR := 9
NYXVERSION_HOTFX := 3
NYXVERSION_HOTFX := 5
NYXVERSION_RSVD := 0

View File

@@ -56,7 +56,7 @@ static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
void display_init()
{
// Check if display is already initialized.
if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & 0x18000000)
if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & (BIT(CLK_L_DISP1) | BIT(CLK_L_HOST1X)))
display_end();
// Power on.
@@ -180,14 +180,15 @@ void display_init()
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
// Configure PLLD for DISP1.
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 460.8 MHz.
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 230.4 MHz.
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20;
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN.
// Finalize DSI configuration.
exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 21);
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4; // PCD1 | div3.
// Set pixel clock dividers: 230.4 / 3 / 1 = 76.8 MHz. 60 Hz.
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
usleep(10000);

View File

@@ -503,7 +503,7 @@
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
* [20] 95 [0F]: InnoLux P062CCA-AZ2
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
* [30] XX [0F]: AUO A062TAN02 (59.06A33.002) [UNCONFIRMED ID]
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
*
* 5.5" panels:
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)

View File

@@ -96,7 +96,7 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0},
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
{DC_COM_CRC_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
@@ -253,7 +253,7 @@ static const cfg_op_t _display_dsi_packet_config[21] = {
{DSI_PKT_LEN_2_3, 0x87001A2},
{DSI_PKT_LEN_4_5, 0x190},
{DSI_PKT_LEN_6_7, 0x190},
{DSI_HOST_CONTROL, 0},
{DSI_HOST_CONTROL, 0}
};
//DSI mode config.
@@ -372,16 +372,16 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0},
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
{DC_COM_CRC_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{0x716, 0x10000FF},
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{0x716, 0x10000FF},
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{0x716, 0x10000FF},
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
@@ -394,14 +394,37 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0},
/* Set Display timings */
/* Set Display timings
*
* DC_DISP_REF_TO_SYNC:
* V_REF_TO_SYNC - 1
* H_REF_TO_SYNC - 0
*
* DC_DISP_SYNC_WIDTH:
* V_SYNC_WIDTH - 1
* H_SYNC_WIDTH - 72
*
* DC_DISP_BACK_PORCH:
* V_BACK_PORCH - 9
* H_BACK_PORCH - 72
*
* DC_DISP_ACTIVE:
* V_DISP_ACTIVE - 1280
* H_DISP_ACTIVE - 720
*
* DC_DISP_FRONT_PORCH:
* V_FRONT_PORCH - 10
* H_FRONT_PORCH - 136
*/
{DC_DISP_DISP_TIMING_OPTIONS, 0},
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
{DC_DISP_REF_TO_SYNC, 0x10000},
{DC_DISP_SYNC_WIDTH, 0x10048},
{DC_DISP_BACK_PORCH, 0x90048},
{DC_DISP_ACTIVE, 0x50002D0},
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
/* End of Display timings */
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},

View File

@@ -523,6 +523,9 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos)
u8 retries;
jc_bt_conn_t *bt_conn;
if (!jc_init_done)
return NULL;
bt_conn = &jc_gamepad.bt_conn_l;
memset(bt_conn->host_mac, 0, 6);
memset(bt_conn->ltk, 0, 16);
@@ -812,7 +815,7 @@ void jc_init_hw()
jc_l.uart = UART_C;
jc_r.uart = UART_B;
#if (LV_LOG_PRINTF != 1)
#ifndef DEBUG_UART_PORT
jc_power_supply(UART_C, true);
jc_power_supply(UART_B, true);

View File

@@ -155,7 +155,11 @@
/*Log settings*/
#define USE_LV_LOG 0 /*Enable/disable the log module*/
#ifdef DEBUG_UART_PORT
# define USE_LV_LOG 1 /*Enable/disable the log module*/
#else
# define USE_LV_LOG 0 /*Enable/disable the log module*/
#endif
#if USE_LV_LOG
/* How important log should be added:
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information

View File

@@ -67,7 +67,7 @@ void lv_log_add(lv_log_level_t level, const char * file, int line, const char *
static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error"};
char *log = (char *)malloc(0x1000);
s_printf(log, "%s: %s \t(%s #%d)\r\n", lvl_prefix[level], dsc, file, line);
uart_send(UART_B, (u8 *)log, strlen(log) + 1);
uart_send(DEBUG_UART_PORT, (u8 *)log, strlen(log) + 1);
//gfx_printf("%s: %s \t(%s #%d)\n", lvl_prefix[level], dsc, file, line);
#else
if(print_cb) print_cb(level, file, line, dsc);

99
bdk/power/bm92t36.c Normal file
View File

@@ -0,0 +1,99 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T36
*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "bm92t36.h"
#include <soc/i2c.h>
#include <utils/util.h>
#define ALERT_STATUS_REG 0x2
#define STATUS1_REG 0x3
#define STATUS2_REG 0x4
#define COMMAND_REG 0x5
#define CONFIG1_REG 0x6
#define DEV_CAPS_REG 0x7
#define READ_PDOS_SRC_REG 0x8
#define CONFIG2_REG 0x17
#define DP_STATUS_REG 0x18
#define DP_ALERT_EN_REG 0x19
#define VENDOR_CONFIG_REG 0x1A
#define AUTO_NGT_FIXED_REG 0x20
#define AUTO_NGT_BATT_REG 0x23
#define SYS_CONFIG1_REG 0x26
#define SYS_CONFIG2_REG 0x27
#define CURRENT_PDO_REG 0x28
#define CURRENT_RDO_REG 0x2B
#define ALERT_ENABLE_REG 0x2E
#define SYS_CONFIG3_REG 0x2F
#define SET_RDO_REG 0x30
#define PDOS_SNK_REG 0x33
#define PDOS_SRC_PROV_REG 0x3C
#define FW_TYPE_REG 0x4B
#define FW_REVISION_REG 0x4C
#define MAN_ID_REG 0x4D
#define DEV_ID_REG 0x4E
#define REV_ID_REG 0x4F
#define INCOMING_VDM_REG 0x50
#define OUTGOING_VDM_REG 0x60
#define STATUS1_INSERT BIT(7) // Cable inserted.
typedef struct _pd_object_t {
unsigned int amp:10;
unsigned int volt:10;
unsigned int info:10;
unsigned int type:2;
} __attribute__((packed)) pd_object_t;
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
{
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
}
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
{
u8 buf[32];
pd_object_t pdos[7];
if (inserted)
{
_bm92t36_read_reg(buf, 2, STATUS1_REG);
*inserted = buf[0] & STATUS1_INSERT ? true : false;
}
if (usb_pd)
{
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
memcpy(pdos, &buf[1], 28);
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
usb_pd->pdo_no = buf[0] / sizeof(pd_object_t);
for (u32 i = 0; i < usb_pd->pdo_no; i++)
{
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
usb_pd->pdos[i].voltage = (pdos[i].volt * 50) / 1000;
}
_bm92t36_read_reg(buf, 5, CURRENT_PDO_REG);
memcpy(pdos, &buf[1], 4);
usb_pd->selected_pdo.amperage = pdos[0].amp * 10;
usb_pd->selected_pdo.voltage = (pdos[0].volt * 50) / 1000;
}
}

41
bdk/power/bm92t36.h Normal file
View File

@@ -0,0 +1,41 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T36
*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BM92T36_H_
#define __BM92T36_H_
#include <utils/types.h>
#define BM92T36_I2C_ADDR 0x18
typedef struct _usb_pd_object_t
{
u32 amperage;
u32 voltage;
} usb_pd_object_t;
typedef struct _usb_pd_objects_t
{
u32 pdo_no;
usb_pd_object_t pdos[7];
usb_pd_object_t selected_pdo;
} usb_pd_objects_t;
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
#endif

View File

@@ -56,7 +56,7 @@ extern volatile nyx_storage_t *nyx_str;
* PCLK - 68MHz init (-> 136MHz -> OC/4).
*/
void _config_oscillators()
static void _config_oscillators()
{
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
@@ -79,7 +79,7 @@ void _config_oscillators()
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
}
void _config_gpios()
static void _config_gpios()
{
// Clamp inputs when tristated.
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
@@ -123,14 +123,14 @@ void _config_gpios()
// gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
}
void _config_pmc_scratch()
static void _config_pmc_scratch()
{
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
}
void _mbist_workaround()
static void _mbist_workaround()
{
// Make sure Audio clocks are enabled before accessing I2S.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
@@ -232,13 +232,14 @@ void _mbist_workaround()
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
}
void _config_se_brom()
static void _config_se_brom()
{
// Enable fuse clock.
clock_enable_fuse(true);
// Skip SBK/SSK if sept was run.
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
bool sbk_skip = b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN || FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
if (!sbk_skip)
{
// Bootrom part we skipped.
u32 sbk[4] = {
@@ -268,7 +269,7 @@ void _config_se_brom()
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
}
void _config_regulators()
static void _config_regulators()
{
// Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false);
@@ -384,9 +385,6 @@ void hw_init()
sdram_init();
bpmp_mmu_enable();
// L4T: Clear flags from PMC_SCRATCH0.
PMC(APBDEV_PMC_SCRATCH0) &= ~PMC_SCRATCH0_MODE_PAYLOAD;
}
void hw_reinit_workaround(bool extra_reconfig, u32 magic)

View File

@@ -20,31 +20,98 @@
#include <soc/i2c.h>
#include <utils/util.h>
#define I2C_PACKET_PROT_I2C (1 << 4)
#define I2C_HEADER_CONT_XFER (1 << 15)
#define I2C_HEADER_REP_START (1 << 16)
#define I2C_HEADER_IE_ENABLE (1 << 17)
#define I2C_HEADER_READ (1 << 19)
#define I2C_CNFG (0x00 / 4)
#define CMD1_WRITE (0 << 6)
#define CMD1_READ (1 << 6)
#define NORMAL_MODE_GO (1 << 9)
#define PACKET_MODE_GO (1 << 10)
#define NEW_MASTER_FSM (1 << 11)
#define DEBOUNCE_CNT_4T (2 << 12)
#define I2C_CMD_ADDR0 (0x04 / 4)
#define ADDR0_WRITE 0
#define ADDR0_READ 1
#define I2C_CMD_DATA1 (0x0C / 4)
#define I2C_CMD_DATA2 (0x10 / 4)
#define I2C_STATUS (0x1C / 4)
#define I2C_STATUS_NOACK (0xF << 0)
#define I2C_STATUS_BUSY (1 << 8)
#define I2C_TX_FIFO (0x50 / 4)
#define I2C_RX_FIFO (0x54 / 4)
#define I2C_FIFO_CONTROL (0x5C / 4)
#define RX_FIFO_FLUSH (1 << 0)
#define TX_FIFO_FLUSH (1 << 1)
#define I2C_FIFO_STATUS (0x60 / 4)
#define RX_FIFO_FULL_CNT (0xF << 0)
#define TX_FIFO_EMPTY_CNT (0xF << 4)
#define I2C_INT_EN (0x64 / 4)
#define I2C_INT_STATUS (0x68 / 4)
#define I2C_INT_SOURCE (0x70 / 4)
#define RX_FIFO_DATA_REQ (1 << 0)
#define TX_FIFO_DATA_REQ (1 << 1)
#define ARB_LOST (1 << 2)
#define NO_ACK (1 << 3)
#define RX_FIFO_UNDER (1 << 4)
#define TX_FIFO_OVER (1 << 5)
#define ALL_PACKETS_COMPLETE (1 << 6)
#define PACKET_COMPLETE (1 << 7)
#define BUS_CLEAR_DONE (1 << 11)
#define I2C_CLK_DIVISOR (0x6C / 4)
#define I2C_BUS_CLEAR_CONFIG (0x84 / 4)
#define BC_ENABLE (1 << 0)
#define BC_TERMINATE (1 << 1)
#define I2C_BUS_CLEAR_STATUS (0x88 / 4)
#define I2C_CONFIG_LOAD (0x8C / 4)
#define MSTR_CONFIG_LOAD (1 << 0)
#define TIMEOUT_CONFIG_LOAD (1 << 2)
static const u32 i2c_addrs[] = {
0x7000C000, 0x7000C400, 0x7000C500,
0x7000C700, 0x7000D000, 0x7000D100
0x7000C000, // I2C_1.
0x7000C400, // I2C_2.
0x7000C500, // I2C_3.
0x7000C700, // I2C_4.
0x7000D000, // I2C_5.
0x7000D100 // I2C_6.
};
static void _i2c_wait(vu32 *base)
static void _i2c_load_cfg_wait(vu32 *base)
{
base[I2C_CONFIG_LOAD] = 0x25;
base[I2C_CONFIG_LOAD] = (1 << 5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
for (u32 i = 0; i < 20; i++)
{
usleep(1);
if (!(base[I2C_CONFIG_LOAD] & 1))
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
break;
}
}
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
{
if (size > 8)
return 0;
u32 tmp = 0;
vu32 *base = (vu32 *)i2c_addrs[idx];
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
// Set device address and send mode.
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
if (size > 4)
{
@@ -60,44 +127,55 @@ static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
base[I2C_CMD_DATA1] = tmp; //Set value.
}
base[I2C_CNFG] = ((size - 1) << 1) | 0x2800; //Set size and send mode.
_i2c_wait(base); //Kick transaction.
// Set size and send mode.
base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
// Load configuration.
_i2c_load_cfg_wait(base);
// Initiate transaction on normal mode.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
u32 timeout = get_tmr_ms() + 100; // Actual for max 8 bytes at 100KHz is 0.74ms.
while (base[I2C_STATUS] & 0x100)
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
{
if (get_tmr_ms() > timeout)
return 0;
}
if (base[I2C_STATUS] << 28)
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
return 0;
return 1;
}
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
{
if (size > 8)
return 0;
vu32 *base = (vu32 *)i2c_addrs[idx];
base[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).
base[I2C_CNFG] = ((size - 1) << 1) | 0x2840; // Set size and recv mode.
_i2c_wait(base); // Kick transaction.
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
// Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
// Set size and recv mode.
base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_READ;
// Load configuration.
_i2c_load_cfg_wait(base);
// Initiate transaction on normal mode.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
u32 timeout = get_tmr_ms() + 100; // Actual for max 8 bytes at 100KHz is 0.74ms.
while (base[I2C_STATUS] & 0x100)
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
{
if (get_tmr_ms() > timeout)
return 0;
}
if (base[I2C_STATUS] << 28)
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
return 0;
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
@@ -113,60 +191,234 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
return 1;
}
void i2c_init(u32 idx)
static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
{
vu32 *base = (vu32 *)i2c_addrs[idx];
if (size > 32)
return 0;
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001;
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
_i2c_wait(base);
int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ;
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
// Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
// Set recv mode.
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
// Set and flush FIFO.
base[I2C_FIFO_CONTROL] = RX_FIFO_FLUSH | TX_FIFO_FLUSH;
// Load configuration.
_i2c_load_cfg_wait(base);
// Initiate transaction on packet mode.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
u32 hdr[3];
hdr[0] = I2C_PACKET_PROT_I2C;
hdr[1] = size - 1;
hdr[2] = I2C_HEADER_IE_ENABLE | I2C_HEADER_CONT_XFER | (dev_addr << 1);
// Send header with request.
base[I2C_TX_FIFO] = hdr[0];
base[I2C_TX_FIFO] = hdr[1];
base[I2C_TX_FIFO] = hdr[2];
u32 timeout = get_tmr_ms() + 400;
while (size)
{
if (base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT)
{
u32 tmp = 0;
u32 snd_size = MIN(size, 4);
memcpy(&tmp, buf, snd_size);
base[I2C_TX_FIFO] = tmp;
buf += snd_size;
size -= snd_size;
}
if (get_tmr_ms() > timeout)
{
res = 1;
break;
}
}
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
res = 1;
// Disable packet mode.
usleep(20);
base[I2C_CNFG] &= 0xFFFFF9FF;
// Disable interrupts.
base[I2C_INT_EN] = 0;
return res;
}
static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
{
if (size > 32)
return 0;
int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | RX_FIFO_DATA_REQ;
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
// Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
// Set recv mode.
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_READ;
// Set and flush FIFO.
base[I2C_FIFO_CONTROL] = RX_FIFO_FLUSH | TX_FIFO_FLUSH;
// Load configuration.
_i2c_load_cfg_wait(base);
// Initiate transaction on packet mode.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
// Send reg request.
u32 hdr[3];
hdr[0] = I2C_PACKET_PROT_I2C;
hdr[1] = 1 - 1;
hdr[2] = I2C_HEADER_REP_START | (dev_addr << 1);
// Send header with reg request.
base[I2C_TX_FIFO] = hdr[0];
base[I2C_TX_FIFO] = hdr[1];
base[I2C_TX_FIFO] = hdr[2];
base[I2C_TX_FIFO] = reg;
u32 timeout = get_tmr_ms() + 400;
while (!(base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT))
if (get_tmr_ms() > timeout)
break;
// Send read request.
hdr[1] = size - 1;
hdr[2] = I2C_HEADER_READ | (dev_addr << 1);
// Send header with read request.
base[I2C_TX_FIFO] = hdr[0];
base[I2C_TX_FIFO] = hdr[1];
base[I2C_TX_FIFO] = hdr[2];
timeout = get_tmr_ms() + 400;
while (size)
{
if (base[I2C_FIFO_STATUS] & RX_FIFO_FULL_CNT)
{
u32 rcv_size = MIN(size, 4);
u32 tmp = base[I2C_RX_FIFO];
memcpy(buf, &tmp, rcv_size);
buf += rcv_size;
size -= rcv_size;
}
if (get_tmr_ms() > timeout)
{
res = 1;
break;
}
}
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
res = 1;
// Disable packet mode.
usleep(20);
base[I2C_CNFG] &= 0xFFFFF9FF;
// Disable interrupts.
base[I2C_INT_EN] = 0;
return res;
}
void i2c_init(u32 i2c_idx)
{
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
// Load configuration.
_i2c_load_cfg_wait(base);
for (u32 i = 0; i < 10; i++)
{
usleep(20000);
if (base[INTERRUPT_STATUS_REGISTER] & 0x800)
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
break;
}
(vu32)base[I2C_BUS_CLEAR_STATUS];
base[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER];
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
}
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr)
{
return _i2c_recv_single(i2c_idx, buf, size, dev_addr);
}
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
{
if (size > 32)
return 0;
return _i2c_send_pkt(i2c_idx, buf, size, dev_addr);
}
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
{
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
}
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
{
u8 tmp[4];
if (size > 7)
return 0;
tmp[0] = y;
tmp[0] = reg;
memcpy(tmp + 1, buf, size);
return _i2c_send_pkt(idx, x, tmp, size + 1);
return _i2c_send_single(i2c_idx, dev_addr, tmp, size + 1);
}
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x)
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
{
return _i2c_recv_pkt(idx, buf, size, x);
}
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
{
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
int res = _i2c_send_single(i2c_idx, dev_addr, (u8 *)&reg, 1);
if (res)
res = _i2c_recv_pkt(idx, buf, size, x);
res = _i2c_recv_single(i2c_idx, buf, size, dev_addr);
return res;
}
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val)
{
return i2c_send_buf_small(idx, x, y, &b, 1);
return i2c_send_buf_small(i2c_idx, dev_addr, reg, &val, 1);
}
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg)
{
u8 tmp = 0;
i2c_recv_buf_small(&tmp, 1, idx, x, y);
i2c_recv_buf_small(&tmp, 1, i2c_idx, dev_addr, reg);
return tmp;
}

View File

@@ -27,22 +27,13 @@
#define I2C_5 4
#define I2C_6 5
#define I2C_CNFG 0x00
#define I2C_CMD_ADDR0 0x01
#define I2C_CMD_DATA1 0x03
#define I2C_CMD_DATA2 0x04
#define I2C_STATUS 0x07
#define INTERRUPT_STATUS_REGISTER 0x1A
#define I2C_CLK_DIVISOR_REGISTER 0x1B
#define I2C_BUS_CLEAR_CONFIG 0x21
#define I2C_BUS_CLEAR_STATUS 0x22
#define I2C_CONFIG_LOAD 0x23
void i2c_init(u32 idx);
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
void i2c_init(u32 i2c_idx);
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
#endif

View File

@@ -37,6 +37,7 @@
#define PMC_SCRATCH0_MODE_PAYLOAD (1 << 29)
#define PMC_SCRATCH0_MODE_RCM (1 << 1)
#define PMC_SCRATCH0_MODE_WARMBOOT (1 << 0)
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD)
#define APBDEV_PMC_SCRATCH1 0x54
#define APBDEV_PMC_SCRATCH20 0xA0
#define APBDEV_PMC_PWR_DET_VAL 0xE4

View File

@@ -169,14 +169,23 @@ int sdmmc_storage_end(sdmmc_storage_t *storage)
sdmmc_end(storage->sdmmc);
storage->initialized = 0;
return 1;
}
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
{
u8 *bbuf = (u8 *)buf;
bool first_reinit = false;
while (num_sectors)
u32 sct_off = sector;
u32 sct_total = num_sectors;
bool first_reinit = true;
// Exit if not initialized.
if (!storage->initialized)
return 0;
while (sct_total)
{
u32 blkcnt = 0;
// Retry 5 times if failed.
@@ -184,7 +193,7 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu
do
{
reinit_try:
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write))
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sct_off, MIN(sct_total, 0xFFFF), bbuf, is_write))
goto out;
else
retries--;
@@ -201,7 +210,7 @@ reinit_try:
sd_error_count_increment(SD_ERROR_RW_FAIL);
if (!first_reinit)
if (first_reinit)
res = sd_initialize(true);
else
{
@@ -210,19 +219,29 @@ reinit_try:
sd_error_count_increment(SD_ERROR_INIT_FAIL);
}
// Reset values for a retry.
blkcnt = 0;
retries = 3;
first_reinit = true;
first_reinit = false;
// If succesful reinit, restart xfer.
if (res)
{
bbuf = (u8 *)buf;
sct_off = sector;
sct_total = num_sectors;
goto reinit_try;
}
}
// Failed.
return 0;
out:
DPRINTF("readwrite: %08X\n", blkcnt);
sector += blkcnt;
num_sectors -= blkcnt;
sct_off += blkcnt;
sct_total -= blkcnt;
bbuf += 512 * blkcnt;
}
@@ -387,6 +406,10 @@ static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)
storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];
storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS];
storage->ext_csd.pre_eol_info = buf[EXT_CSD_PRE_EOL_INFO];
storage->ext_csd.dev_life_est_a = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A];
storage->ext_csd.dev_life_est_b = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B];
storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT];
}
@@ -616,6 +639,8 @@ DPRINTF("[MMC] succesfully switched to HS mode\n");
sdmmc_card_clock_ctrl(storage->sdmmc, SDMMC_AUTO_CAL_ENABLE);
storage->initialized = 1;
return 1;
}
@@ -628,6 +653,7 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
return 0;
storage->partition = partition;
return 1;
}
@@ -1291,6 +1317,8 @@ DPRINTF("[SD] enabled HS\n");
DPRINTF("[SD] got sd status\n");
}
storage->initialized = 1;
return 1;
}
@@ -1342,5 +1370,7 @@ DPRINTF("[gc] after tuning\n");
sdmmc_card_clock_ctrl(sdmmc, SDMMC_AUTO_CAL_ENABLE);
storage->initialized = 1;
return 1;
}

View File

@@ -65,16 +65,19 @@ typedef struct _mmc_csd
typedef struct _mmc_ext_csd
{
u8 rev;
u32 sectors;
int bkops; /* background support bit */
int bkops_en; /* manual bkops enable bit */
u8 rev;
u8 ext_struct; /* 194 */
u8 card_type; /* 196 */
u8 bkops_status; /* 246 */
u16 dev_version;
u8 pre_eol_info;
u8 dev_life_est_a;
u8 dev_life_est_b;
u8 boot_mult;
u8 rpmb_mult;
u16 dev_version;
} mmc_ext_csd_t;
typedef struct _sd_scr
@@ -113,6 +116,7 @@ typedef struct _sdmmc_storage_t
mmc_ext_csd_t ext_csd;
sd_scr_t scr;
sd_ssr_t ssr;
int initialized;
} sdmmc_storage_t;
int sdmmc_storage_end(sdmmc_storage_t *storage);

View File

@@ -241,8 +241,9 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
}
#ifdef SDMMC_EMMC_OC
// Add -4 TX_DLY_CODE_OFFSET if HS533.
if (sdmmc->id == SDMMC_4 && overclock)
sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7); // Add -4 TX_DLY_CODE_OFFSET if HS533.
sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7);
#endif
sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
@@ -399,9 +400,8 @@ void sdmmc_card_clock_ctrl(sdmmc_t *sdmmc, int auto_cal_enable)
sdmmc->auto_cal_enabled = auto_cal_enable;
if (auto_cal_enable)
{
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
return;
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
if (sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
return;
}
@@ -725,7 +725,6 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
off_pu = 5;
break;
case SDMMC_1:
case SDMMC_3:
if (power == SDMMC_POWER_1_8)
{
off_pd = 123;
@@ -764,7 +763,7 @@ static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
u16 norintsts = sdmmc->regs->norintsts;
u16 errintsts = sdmmc->regs->errintsts;
DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
if (pout)
*pout = norintsts;
@@ -772,6 +771,9 @@ DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
// Check for error interrupt.
if (norintsts & SDHCI_INT_ERROR)
{
#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC: norintsts %08X, errintsts %08X\n", norintsts, errintsts);
#endif
sdmmc->regs->errintsts = errintsts;
return SDMMC_MASKINT_ERROR;
}
@@ -963,8 +965,6 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
is_data_present = true;
}
else
is_data_present = false;
_sdmmc_enable_interrupts(sdmmc);
@@ -983,7 +983,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
EPRINTF("SDMMC: Transfer timeout!");
#endif
}
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
if (result)
{
@@ -994,7 +994,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (!result)
{
#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC: Unknown response %08X!", sdmmc->rsp[0]);
EPRINTF("SDMMC: Unknown response type!");
#endif
}
}
@@ -1004,7 +1004,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (!result)
{
#ifdef ERROR_EXTRA_PRINTING
EPRINTF("SDMMC: DMA Update failed!");
EPRINTFARGS("SDMMC: DMA Update failed (%08X)!", result);
#endif
}
}
@@ -1116,10 +1116,7 @@ static void _sdmmc_config_emmc(u32 id)
case SDMMC_4:
// Unset park for pads.
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF;
// Set default pad cfg.
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040;
// Enabled schmitt trigger.
// Enable schmitt trigger.
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1; // Enable Schmitt trigger.
break;
}
@@ -1129,7 +1126,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int a
{
const u32 trim_values[] = { 2, 8, 3, 8 };
if (id > SDMMC_4)
if (id > SDMMC_4 || id == SDMMC_3)
return 0;
memset(sdmmc, 0, sizeof(sdmmc_t));

View File

@@ -75,7 +75,7 @@ typedef struct _usb_dev_descr_t
u8 bNumConfigs; // Number of possible configuration.
} __attribute__((packed)) usb_dev_descr_t;
/* Device Qualigier descriptor structure */
/* Device Qualifier descriptor structure */
typedef struct _usb_dev_qual_descr_t
{
u8 bLength; // Size of this descriptor in bytes.

View File

@@ -1523,7 +1523,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
DPRINTF("USB: EP timeout\n");
// In case we disconnected, exit UMS.
// Raise timeout if removable and didn't got a unit ready command inside 4s.
if (bulk_ctxt->bulk_out_status == 28 ||
if (bulk_ctxt->bulk_out_status == 28 ||
(bulk_ctxt->bulk_out_status == 3 && ums->lun.removable && !ums->lun.prevent_medium_removal))
{
if (bulk_ctxt->bulk_out_status == 3)

View File

@@ -1,5 +1,5 @@
/*
* USB driver for Tegra X1
* Enhanced USB (EHCI) device driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
*

View File

@@ -1,5 +1,5 @@
/*
* USB Device driver for Tegra X1
* Enhanced USB (EHCI) Device driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
*
@@ -312,7 +312,7 @@ static void _usb_charger_detect()
gpio_config(GPIO_PORT_V, GPIO_PIN_3, GPIO_MODE_GPIO);
// Configure charger pin.
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) &=
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) &=
~(PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK);
gpio_config(GPIO_PORT_CC, GPIO_PIN_5, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
@@ -335,10 +335,10 @@ int usb_device_init()
return 0;
// Configure PLLU.
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) = CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) | 0x20000000; // Disable reference clock.
u32 pllu_cfg = (((((CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) >> 8 << 8) | 2) & 0xFFFF00FF) | ((0x19 << 8) & 0xFFFF)) & 0xFFE0FFFF) | (1<< 16) | 0x1000000;
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) |= (1 << 29); // Disable reference clock.
u32 pllu_cfg = (((((CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) >> 8 << 8) | 2) & 0xFFFF00FF) | ((0x19 << 8) & 0xFFFF)) & 0xFFE0FFFF) | (1 << 16) | (1 << 24);
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg;
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | 0x40000000; // Enable.
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | (1 << 30); // Enable.
// Wait for PLL to stabilize.
u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300;
@@ -348,7 +348,7 @@ int usb_device_init()
usleep(10);
// Enable PLLU USB/HSIC/ICUSB/48M.
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) | 0x2600000 | 0x800000;
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) |= 0x2E00000;
// Enable USBD clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
@@ -930,10 +930,10 @@ out:
_usbd_mark_ep_complete(endpoint);
else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE)
res = 26;
}
if (direction == USB_XFER_DIR_OUT)
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
if (direction == USB_XFER_DIR_OUT)
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
}
return res;
}
@@ -1175,17 +1175,17 @@ static int _usbd_handle_ep0_control_transfer()
switch (_bmRequestType)
{
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_DEVICE | USB_SETUP_TYPE_STANDARD):
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
ret = _usbd_handle_set_request(&ep_stall);
break;
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_STANDARD):
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
ret = _usbd_ep_ack(USB_EP_CTRL_IN);
if (!ret)
usbd_otg->interface = _wValue;
break;
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_ENDPOINT | USB_SETUP_TYPE_STANDARD):
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
switch (_bRequest)
{
case USB_REQUEST_CLEAR_FEATURE:
@@ -1227,10 +1227,12 @@ static int _usbd_handle_ep0_control_transfer()
break;
}
break;
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_CLASS):
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
break;
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_DEVICE | USB_SETUP_TYPE_STANDARD):
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
switch (_bRequest)
{
case USB_REQUEST_GET_STATUS:
@@ -1253,7 +1255,7 @@ static int _usbd_handle_ep0_control_transfer()
}
break;
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_STANDARD):
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
if (_bRequest == USB_REQUEST_GET_INTERFACE)
{
descriptor = (void *)&usbd_otg->interface;
@@ -1287,7 +1289,7 @@ static int _usbd_handle_ep0_control_transfer()
transmit_data = 1;
break;
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_ENDPOINT | USB_SETUP_TYPE_STANDARD):
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
if (_bRequest == USB_REQUEST_GET_STATUS)
{
int ep_req;
@@ -1324,14 +1326,15 @@ static int _usbd_handle_ep0_control_transfer()
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
break;
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_CLASS):
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
memset(descriptor, 0, _wLength);
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
size = _wLength;
break;
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_INTERFACE | USB_SETUP_TYPE_VENDOR):
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_RECIPIENT_DEVICE | USB_SETUP_TYPE_VENDOR):
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE):
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE):
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
{
switch (_wIndex)
@@ -1565,6 +1568,8 @@ int usb_device_ep1_out_reading_finish(u32 *pending_bytes)
*pending_bytes = _usbd_get_ep1_out_bytes_read();
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
if (ep_status == USB_EP_STATUS_IDLE)
return 0;
else if (ep_status == USB_EP_STATUS_DISABLED)

View File

@@ -1,5 +1,5 @@
/*
* USB Device driver for Tegra X1
* Enhanced USB (EHCI) Device driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
*

View File

@@ -65,11 +65,6 @@ static void _s_putn(u32 v, int base, char fill, int fcnt)
_s_puts(p);
}
static void _s_putp(u32 *v, int base, char fill, int fcnt)
{
_s_putn(*v, base, fill, fcnt);
}
void s_printf(char *out_buf, const char *fmt, ...)
{
va_list ap;
@@ -114,8 +109,6 @@ void s_printf(char *out_buf, const char *fmt, ...)
break;
case 'p':
case 'P':
_s_putp(va_arg(ap, u32*), 16, fill, fcnt);
break;
case 'x':
case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt);

View File

@@ -33,8 +33,9 @@ typedef enum
ERR_LIBSYS_LP0 = (1 << 0),
ERR_SYSOLD_NYX = (1 << 1),
ERR_LIBSYS_MTC = (1 << 2),
ERR_SD_BOOT_EN = (1 << 3),
ERR_L4T_KERNEL = (1 << 24),
ERR_EXCEPT_ENB = (1 << 31),
ERR_EXCEPTION = (1 << 31),
} hekate_errors_t;
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \

View File

@@ -42,8 +42,7 @@ void set_default_configuration()
h_cfg.autohosoff = 0;
h_cfg.autonogc = 1;
h_cfg.updater2p = 0;
h_cfg.brand = NULL;
h_cfg.tagline = NULL;
h_cfg.bootprotect = 0;
h_cfg.errors = 0;
h_cfg.eks = NULL;
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
@@ -107,16 +106,9 @@ int create_config_entry()
f_puts("\nupdater2p=", &fp);
itoa(h_cfg.updater2p, lbuf, 10);
f_puts(lbuf, &fp);
if (h_cfg.brand)
{
f_puts("\nbrand=", &fp);
f_puts(h_cfg.brand, &fp);
}
if (h_cfg.tagline)
{
f_puts("\ntagline=", &fp);
f_puts(h_cfg.tagline, &fp);
}
f_puts("\nbootprotect=", &fp);
itoa(h_cfg.bootprotect, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\n", &fp);
if (mainIniFound)

View File

@@ -30,8 +30,7 @@ typedef struct _hekate_config
u32 autohosoff;
u32 autonogc;
u32 updater2p;
char *brand;
char *tagline;
u32 bootprotect;
// Global temporary config.
bool se_keygen_done;
bool sept_run;

View File

@@ -270,7 +270,7 @@ void print_sdcard_info()
gfx_clear_partial_grey(0x1B, 0, 1256);
gfx_con_setpos(0, 0);
if (sd_mount())
if (sd_initialize(true))
{
gfx_printf("%kCard IDentification:%k\n", 0xFF00DDFF, 0xFFCCCCCC);
gfx_printf(
@@ -287,6 +287,7 @@ void print_sdcard_info()
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
sd_storage.cid.month, sd_storage.cid.year);
u16 *sd_errors = sd_get_error_count();
gfx_printf("%kCard-Specific Data V%d.0:%k\n", 0xFF00DDFF, sd_storage.csd.structure + 1, 0xFFCCCCCC);
gfx_printf(
" Cmd Classes: %02X\n"
@@ -297,18 +298,39 @@ void print_sdcard_info()
" UHS Grade: U%d\n"
" Video Class: V%d\n"
" App perf class: A%d\n"
" Write Protect: %d\n\n",
" Write Protect: %d\n"
" SDMMC Errors: %d %d %d\n\n",
sd_storage.csd.cmdclass, sd_storage.sec_cnt >> 11,
sd_storage.ssr.bus_width, sd_storage.csd.busspeed, sd_storage.csd.busspeed * 2,
sd_storage.ssr.speed_class, sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class,
sd_storage.ssr.app_class, sd_storage.csd.write_protect);
sd_storage.ssr.app_class, sd_storage.csd.write_protect,
sd_errors[0], sd_errors[1], sd_errors[2]); // SD_ERROR_INIT_FAIL, SD_ERROR_RW_FAIL, SD_ERROR_RW_RETRY.
gfx_puts("Acquiring FAT volume info...\n\n");
f_getfree("", &sd_fs.free_clst, NULL);
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
0xFF00DDFF, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", 0xFFCCCCCC,
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
sd_end();
int res = f_mount(&sd_fs, "", 1);
if (!res)
{
gfx_puts("Acquiring FAT volume info...\n\n");
f_getfree("", &sd_fs.free_clst, NULL);
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
0xFF00DDFF, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", 0xFFCCCCCC,
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
f_mount(NULL, "", 1);
}
else
{
EPRINTFARGS("Failed to mount SD card (FatFS Error %d).\n"
"Make sure that a FAT partition exists..", res);
}
sdmmc_storage_end(&sd_storage);
}
else
{
EPRINTF("Failed to init SD card.");
if (!sdmmc_get_sd_inserted())
EPRINTF("Make sure that it is inserted.");
else
EPRINTF("SD Card Reader is not properly seated!");
}
btn_wait();

View File

@@ -165,7 +165,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
continue;
// If content is experimental and experimental flag is not enabled, skip it.
if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_enable_experimental)
if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_experimental)
continue;
// Parse content.
@@ -190,6 +190,10 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
ctxt->warmboot_size = curr_fss_cnt[i].size;
ctxt->warmboot = content;
break;
case CNT_TYPE_KRN:
ctxt->kernel_size = curr_fss_cnt[i].size;
ctxt->kernel = content;
break;
default:
continue;
}

View File

@@ -269,6 +269,10 @@ void hos_eks_save(u32 kb)
u8 *keys = (u8 *)calloc(0x1000, 1);
se_get_aes_keys(keys + 0x800, keys, 0x10);
// Set SBK back.
if (FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF)
se_aes_key_set(14, keys + 14 * 0x10, 0x10);
// Set magic and personalized info.
h_cfg.eks->magic = HOS_EKS_MAGIC;
h_cfg.eks->enabled[key_idx] = kb;
@@ -543,23 +547,41 @@ int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_c
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
{
static const u32 BOOTLOADER_SIZE = 0x40000;
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
static const u32 BOOTLOADER_BACKUP_OFFSET = 0x140000;
static const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
ctxt->pkg1 = (void *)malloc(BOOTLOADER_SIZE);
try_load:
// Read package1.
ctxt->pkg1 = (void *)malloc(0x40000);
emummc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
emummc_storage_read(&emmc_storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
emummc_storage_read(&emmc_storage, bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
if (!ctxt->pkg1_id)
{
_hos_crit_error("Unknown pkg1 version.");
EHPRINTFARGS("HOS version not supported!%s",
EPRINTFARGS("HOS version not supported!%s",
(emu_cfg.enabled && !h_cfg.emummc_force_disable) ? "\nOr emuMMC corrupt!" : "");
// Try backup bootloader.
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
{
EPRINTF("Trying backup bootloader...");
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
goto try_load;
}
return 0;
}
gfx_printf("Identified pkg1 and mkey %d\n\n", ctxt->pkg1_id->kb);
// Read the correct keyblob.
ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
emummc_storage_read(&emmc_storage, 0x180000 / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
emummc_storage_read(&emmc_storage, HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
return 1;
}
@@ -633,20 +655,26 @@ static bool _get_fs_exfat_compatible(link_t *info, bool *fs_is_510)
pkg2_get_ids(&kip_ids, &fs_ids_cnt);
for (fs_idx = 0; fs_idx < fs_ids_cnt; fs_idx++)
{
if (!memcmp(sha_buf, kip_ids[fs_idx].hash, 8))
{
// Check if it's 5.1.0.
if ((fs_idx & ~1) == 16)
*fs_is_510 = true;
// Check if FAT32-only.
if (fs_ids_cnt <= fs_idx && !(fs_idx & 1))
return false;
// FS is FAT32 + exFAT.
break;
// Check if it's 5.1.0.
if ((fs_idx & ~1) == 16)
*fs_is_510 = true;
// Return false if FAT32 only.
if (fs_ids_cnt <= fs_idx && !(fs_idx & 1))
return false;
}
}
break;
}
// Hash didn't match or FAT32 + exFAT.
return true;
}
@@ -830,13 +858,11 @@ int hos_launch(ini_sec_t *cfg)
if (!pkg2_hdr)
{
_hos_crit_error("Pkg2 decryption failed!");
if (kb >= KB_FIRMWARE_VERSION_700)
{
EPRINTF("Is Sept updated?");
EPRINTFARGS("Is hekate%s updated?", kb >= KB_FIRMWARE_VERSION_700 ? " or Sept" : "");
// Clear EKS slot, in case something went wrong with sept keygen.
// Clear EKS slot, in case something went wrong with sept keygen.
if (kb >= KB_FIRMWARE_VERSION_700)
hos_eks_clear(kb);
}
goto error;
}
else if (kb >= KB_FIRMWARE_VERSION_700)
@@ -925,11 +951,14 @@ int hos_launch(ini_sec_t *cfg)
{
EHPRINTFARGS("Failed to apply '%s'!", unappliedPatch);
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
display_backlight_brightness(h_cfg.backlight, 1000);
bool emmc_patch_failed = !strcmp(unappliedPatch, "emummc");
if (!emmc_patch_failed)
{
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
display_backlight_brightness(h_cfg.backlight, 1000);
}
u32 btn = btn_wait();
if (!(btn & BTN_POWER))
if (emmc_patch_failed || !(btn_wait() & BTN_POWER))
{
_free_launch_components(&ctxt);
goto error; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
@@ -937,16 +966,12 @@ int hos_launch(ini_sec_t *cfg)
}
// Rebuild and encrypt package2.
pkg2_build_encrypt((void *)PKG2_LOAD_ADDR, ctxt.kernel, ctxt.kernel_size, &kip1_info, ctxt.new_pkg2, kb);
pkg2_build_encrypt((void *)PKG2_LOAD_ADDR, &ctxt, &kip1_info);
gfx_puts("Rebuilt & loaded pkg2\n");
gfx_printf("\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC);
// Clear pkg1/pkg2 keys.
se_aes_key_clear(8);
se_aes_key_clear(11);
// Set initial mailbox values.
int bootStateDramPkg2 = 0;
int bootStatePkg2Continue = 0;
@@ -957,6 +982,10 @@ int hos_launch(ini_sec_t *cfg)
else if (kb == KB_FIRMWARE_VERSION_301)
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id.
// Clear pkg1/pkg2 keys.
se_aes_key_clear(8);
se_aes_key_clear(11);
// Finalize per firmware key access. Skip access control if new exosphere.
switch (kb | (exo_new << 7))
{
@@ -1039,8 +1068,9 @@ int hos_launch(ini_sec_t *cfg)
// Clear EMC_SCRATCH0.
EMC(EMC_SCRATCH0) = 0;
// Hold USBD in reset for SoC state validation on sleep.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_USBD);
// Hold USBD, USB2, AHBDMA and APBDMA in reset for SoC state validation on sleep.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_AHBDMA) | BIT(CLK_H_APBDMA) | BIT(CLK_H_USB2);
// Flush cache and disable MMU.
bpmp_mmu_disable();

View File

@@ -97,6 +97,7 @@ typedef struct _launch_ctxt_t
void *kernel;
u32 kernel_size;
link_t kip1_list;
char* kip1_patches;
@@ -105,7 +106,7 @@ typedef struct _launch_ctxt_t
bool debugmode;
bool stock;
bool atmosphere;
bool fss0_enable_experimental;
bool fss0_experimental;
bool emummc_forced;
exo_ctxt_t exo_ctx;

View File

@@ -253,7 +253,7 @@ static int _config_fss(launch_ctxt_t *ctxt, const char *value)
{
if (!strcmp("fss0experimental", kv->key))
{
ctxt->fss0_enable_experimental = *kv->val == '1';
ctxt->fss0_experimental = *kv->val == '1';
break;
}
}

View File

@@ -604,6 +604,20 @@ static kip1_patchset_t _fs_patches_1000[] =
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1020[] =
{
{ KPS(KIP_TEXT) | 0x13C2F0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14E268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1020[] =
{
{ "nogc", _fs_nogc_1020 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
// SHA256 hashes.
static kip1_id_t _kip_ids[] =
{
@@ -641,6 +655,8 @@ static kip1_id_t _kip_ids[] =
{ "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exfat
{ "FS", "\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", _fs_patches_1000 }, // FS 10.0.0
{ "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exfat
{ "FS", "\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", _fs_patches_1020 }, // FS 10.2.0
{ "FS", "\x16\x0D\x3E\x10\x4E\xAD\x61\x76", _fs_patches_1020 }, // FS 10.2.0 exfat
};
static kip1_id_t *_kip_id_sets = _kip_ids;
@@ -1394,9 +1410,16 @@ DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->s
return ini1_size;
}
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, bool new_pkg2, u8 kb)
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info)
{
u8 *pdst = (u8 *)dst;
launch_ctxt_t * ctxt = (launch_ctxt_t *)hos_ctxt;
u32 kernel_size = ctxt->kernel_size;
bool is_meso = *(u32 *)(ctxt->kernel + 4) == ATM_MESOSPHERE;
// Force new Package2 if Mesosphere.
if (is_meso)
ctxt->new_pkg2 = true;
// Signature.
memset(pdst, 0, 0x100);
@@ -1411,23 +1434,25 @@ void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_i
hdr->bl_ver = 0;
hdr->pkg2_ver = 0xFF;
if (!new_pkg2)
if (!ctxt->new_pkg2)
hdr->base = 0x10000000;
else
hdr->base = 0x60000;
DPRINTF("kernel @ %08X (%08X)\n", (u32)kernel, kernel_size);
DPRINTF("%s @ %08X (%08X)\n", is_meso ? "Mesosphere": "kernel",(u32)ctxt->kernel, kernel_size);
pdst += sizeof(pkg2_hdr_t);
// Kernel.
memcpy(pdst, kernel, kernel_size);
if (!new_pkg2)
memcpy(pdst, ctxt->kernel, kernel_size);
if (!ctxt->new_pkg2)
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
else
{
// Set new INI1 offset to kernel.
*(u32 *)(pdst + pkg2_newkern_ini1_val) = kernel_size;
kernel_size += _pkg2_ini1_build(pdst + kernel_size, hdr, kips_info, new_pkg2);
*(u32 *)(pdst + (is_meso ? 8 : pkg2_newkern_ini1_val)) = kernel_size;
// Build INI1 for new Package2.
kernel_size += _pkg2_ini1_build(pdst + kernel_size, hdr, kips_info, ctxt->new_pkg2);
hdr->sec_off[PKG2_SEC_KERNEL] = 0x60000;
}
hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
@@ -1435,10 +1460,10 @@ DPRINTF("kernel @ %08X (%08X)\n", (u32)kernel, kernel_size);
pdst += kernel_size;
DPRINTF("kernel encrypted\n");
// INI1.
/// Build INI1 for old Package2.
u32 ini1_size = 0;
if (!new_pkg2)
ini1_size = _pkg2_ini1_build(pdst, hdr, kips_info, new_pkg2);
if (!ctxt->new_pkg2)
ini1_size = _pkg2_ini1_build(pdst, hdr, kips_info, false);
DPRINTF("INI1 encrypted\n");
// Calculate SHA256 over encrypted Kernel and INI1.
@@ -1450,7 +1475,7 @@ DPRINTF("INI1 encrypted\n");
(void *)pk2_hash_data, hdr->sec_size[PKG2_SEC_INI1]);
//Encrypt header.
u8 key_ver = kb ? kb + 1 : 0;
u8 key_ver = ctxt->pkg1_id->kb ? ctxt->pkg1_id->kb + 1 : 0;
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
hdr->ctr[4] = key_ver;
se_aes_crypt_ctr(pkg2_keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);

View File

@@ -30,6 +30,8 @@
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset.
#define PKG2_NEWKERN_START 0x800
#define ATM_MESOSPHERE 0x3053534D
extern u32 pkg2_newkern_ini1_val;
extern u32 pkg2_newkern_ini1_start;
extern u32 pkg2_newkern_ini1_end;
@@ -155,6 +157,6 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames);
const pkg2_kernel_id_t *pkg2_identify(u8 *hash);
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb);
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info, bool new_pkg2, u8 kb);
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info);
#endif

View File

@@ -344,6 +344,8 @@ static const char *get_error_desc(u32 error_desc)
return "SYS"; // System Error.
case 0x301:
return "SVC"; // Bad arguments or unimplemented SVC.
case 0xF00:
return "KRNL"; // Kernel panic.
case 0xFFD:
return "SO"; // Stack Overflow.
case 0xFFE:
@@ -361,9 +363,6 @@ void secmon_exo_check_panic()
if ((rpt->magic & 0xF0FFFFFF) != ATM_FATAL_MAGIC)
return;
// Change magic to invalid, to prevent double-display of error/bootlooping.
rpt->magic = 0;
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
@@ -386,6 +385,9 @@ void secmon_exo_check_panic()
gfx_con.fntsz = 16;
}
// Change magic to invalid, to prevent double-display of error/bootlooping.
rpt->magic = 0;
gfx_printf("\n\nPress POWER to continue.\n");
display_backlight_brightness(100, 1000);

View File

@@ -293,8 +293,15 @@ void auto_launch_update()
EMC(EMC_SCRATCH0) &= ~EMC_HEKA_UPD;
else if (sd_mount())
{
// Check if update.bin exists and is newer and launch it. Otherwise create it.
if (!f_stat("bootloader/update.bin", NULL))
launch_payload("bootloader/update.bin", true);
else
{
u8 *buf = calloc(0x200, 1);
is_ipl_updated(buf, "bootloader/update.bin", true);
free(buf);
}
}
}
@@ -767,6 +774,18 @@ static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomE
return cfg_sec;
}
static void _bootloader_corruption_protect()
{
FILINFO fno;
if (!f_stat("bootloader", &fno))
{
if (!h_cfg.bootprotect && (fno.fattrib & AM_ARC))
f_chmod("bootloader", 0, AM_ARC);
else if (h_cfg.bootprotect && !(fno.fattrib & AM_ARC))
f_chmod("bootloader", AM_ARC, AM_ARC);
}
}
static void _auto_launch_firmware()
{
if(b_cfg.extra_cfg & (EXTRA_CFG_NYX_DUMP | EXTRA_CFG_NYX_BIS))
@@ -775,8 +794,6 @@ static void _auto_launch_firmware()
EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD;
check_sept(NULL);
}
else if (b_cfg.extra_cfg & EXTRA_CFG_NYX_UMS)
EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD;
if (!h_cfg.sept_run)
auto_launch_update();
@@ -845,16 +862,8 @@ static void _auto_launch_firmware()
h_cfg.autonogc = atoi(kv->val);
else if (!strcmp("updater2p", kv->key))
h_cfg.updater2p = atoi(kv->val);
else if (!strcmp("brand", kv->key))
{
h_cfg.brand = malloc(strlen(kv->val) + 1);
strcpy(h_cfg.brand, kv->val);
}
else if (!strcmp("tagline", kv->key))
{
h_cfg.tagline = malloc(strlen(kv->val) + 1);
strcpy(h_cfg.tagline, kv->val);
}
else if (!strcmp("bootprotect", kv->key))
h_cfg.bootprotect = atoi(kv->val);
}
boot_entry_id++;
@@ -870,6 +879,9 @@ static void _auto_launch_firmware()
b_cfg.autoboot_list = h_cfg.autoboot_list;
}
// Apply bootloader protection against corruption.
_bootloader_corruption_protect();
continue;
}
@@ -1080,9 +1092,10 @@ out:
b_cfg.boot_cfg &= BOOT_CFG_SEPT_RUN;
h_cfg.emummc_force_disable = false;
nyx_load_run();
// L4T: Clear custom boot mode flags from PMC_SCRATCH0.
PMC(APBDEV_PMC_SCRATCH0) &= ~PMC_SCRATCH0_MODE_CUSTOM_ALL;
sd_end();
nyx_load_run();
}
static void _patched_rcm_protection()
@@ -1143,9 +1156,10 @@ static void _show_errors()
u32 *excp_lr = (u32 *)EXCP_LR_ADDR;
if (*excp_enabled == EXCP_MAGIC)
h_cfg.errors |= ERR_EXCEPT_ENB;
h_cfg.errors |= ERR_EXCEPTION;
if (PMC(APBDEV_PMC_SCRATCH37) & PMC_SCRATCH37_KERNEL_PANIC_FLAG)
//! FIXME: Find a better way to identify if that scratch has proper data.
if (0 && PMC(APBDEV_PMC_SCRATCH37) & PMC_SCRATCH37_KERNEL_PANIC_FLAG)
{
// Set error and clear flag.
h_cfg.errors |= ERR_L4T_KERNEL;
@@ -1158,23 +1172,24 @@ static void _show_errors()
gfx_con_setpos(0, 0);
display_backlight_brightness(150, 1000);
if (h_cfg.errors & ERR_SD_BOOT_EN)
WPRINTF("Failed to mount SD!\n");
if (h_cfg.errors & ERR_LIBSYS_LP0)
WPRINTF("Missing LP0 (sleep mode) lib!\n");
if (h_cfg.errors & ERR_LIBSYS_MTC)
WPRINTF("Missing or old Minerva lib!\n");
if (h_cfg.errors & ~(ERR_EXCEPT_ENB | ERR_L4T_KERNEL))
{
if (h_cfg.errors & (ERR_LIBSYS_LP0 | ERR_LIBSYS_MTC))
WPRINTF("\nUpdate bootloader folder!\n\n");
}
if (h_cfg.errors & ERR_EXCEPT_ENB)
if (h_cfg.errors & ERR_EXCEPTION)
{
WPRINTFARGS("An exception occurred (LR %08X):\n", *excp_lr);
switch (*excp_type)
{
case EXCP_TYPE_RESET:
WPRINTF("RST");
WPRINTF("RESET");
break;
case EXCP_TYPE_UNDEF:
WPRINTF("UNDEF");
@@ -1192,7 +1207,7 @@ static void _show_errors()
*excp_enabled = 0;
}
if (h_cfg.errors & ERR_L4T_KERNEL)
if (0 && h_cfg.errors & ERR_L4T_KERNEL)
{
WPRINTF("Panic occurred while running L4T.\n");
if (!sd_save_to_file((void *)PSTORE_ADDR, PSTORE_SZ, "L4T_panic.bin"))
@@ -1316,6 +1331,15 @@ out:
max77620_low_battery_monitor_config(true);
}
void ipl_reload()
{
hw_reinit_workaround(false, 0);
// Reload hekate.
void (*ipl_ptr)() = (void *)IPL_LOAD_ADDR;
(*ipl_ptr)();
}
static void _about()
{
static const char credits[] =
@@ -1459,6 +1483,7 @@ ment_t ment_top[] = {
MDEF_MENU("Tools", &menu_tools),
MDEF_MENU("Console info", &menu_cinfo),
MDEF_CAPTION("---------------", 0xFF444444),
MDEF_HANDLER("Reload", ipl_reload),
MDEF_HANDLER("Reboot (Normal)", reboot_normal),
MDEF_HANDLER("Reboot (RCM)", reboot_rcm),
MDEF_HANDLER("Power off", power_off),
@@ -1467,7 +1492,7 @@ ment_t ment_top[] = {
MDEF_END()
};
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.3.1", 0, 0 };
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.3.4", 0, 0 };
extern void pivot_stack(u32 stack_top);
@@ -1493,7 +1518,8 @@ void ipl_main()
// Set bootloader's default configuration.
set_default_configuration();
sd_mount();
// Mount SD Card.
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
// Save sdram lp0 config.
if (!ianos_loader("bootloader/sys/libsys_lp0.bso", DRAM_LIB, (void *)sdram_get_params_patched()))
@@ -1531,6 +1557,9 @@ void ipl_main()
// Load saved configuration and auto boot if enabled.
_auto_launch_firmware();
// Failed to launch Nyx, unmount SD Card.
sd_end();
minerva_change_freq(FREQ_800);
while (true)

View File

@@ -37,7 +37,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
fuse.o kfuse.o \
mc.o sdram.o minerva.o ramdisk.o \
sdmmc.o sdmmc_driver.o nx_emmc.o nx_emmc_bis.o nx_sd.o \
bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
touch.o joycon.o tmp451.o fan.o \
usbd.o usb_gadget_ums.o usb_gadget_hid.o \
hw_init.o \
@@ -80,7 +80,8 @@ CUSTOMDEFINES := -DNYX_LOAD_ADDR=$(NYX_LOAD_ADDR) -DNYX_MAGIC=$(NYX_MAGIC)
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
CUSTOMDEFINES += -DNYX -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
# 0: UART_A, 1: UART_B.
# 0: UART_A, 1: UART_B, 2: UART_C.
# Also enables LV LOG.
#CUSTOMDEFINES += -DDEBUG_UART_PORT=1
#CUSTOMDEFINES += -DDEBUG

View File

@@ -42,13 +42,13 @@ void set_default_configuration()
h_cfg.autohosoff = 0;
h_cfg.autonogc = 1;
h_cfg.updater2p = 0;
h_cfg.brand = NULL;
h_cfg.tagline = NULL;
h_cfg.bootprotect = 0;
h_cfg.errors = 0;
h_cfg.eks = NULL;
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
h_cfg.aes_slots_new = false;
h_cfg.rcm_patched = fuse_check_patched_rcm();
h_cfg.sbk_set = FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
h_cfg.emummc_force_disable = false;
sd_power_cycle_time_start = 0;
@@ -61,6 +61,7 @@ void set_nyx_default_configuration()
n_cfg.home_screen = 0;
n_cfg.verification = 1;
n_cfg.ums_emmc_rw = 0;
n_cfg.jc_disable = 0;
}
int create_config_entry()
@@ -118,16 +119,9 @@ int create_config_entry()
f_puts("\nupdater2p=", &fp);
itoa(h_cfg.updater2p, lbuf, 10);
f_puts(lbuf, &fp);
if (h_cfg.brand)
{
f_puts("\nbrand=", &fp);
f_puts(h_cfg.brand, &fp);
}
if (h_cfg.tagline)
{
f_puts("\ntagline=", &fp);
f_puts(h_cfg.tagline, &fp);
}
f_puts("\nbootprotect=", &fp);
itoa(h_cfg.bootprotect, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\n", &fp);
if (mainIniFound)
@@ -206,6 +200,9 @@ int create_nyx_config_entry()
f_puts("\numsemmcrw=", &fp);
itoa(n_cfg.ums_emmc_rw, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\njcdisable=", &fp);
itoa(n_cfg.jc_disable, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\n", &fp);
f_close(&fp);

View File

@@ -30,14 +30,14 @@ typedef struct _hekate_config
u32 autohosoff;
u32 autonogc;
u32 updater2p;
char *brand;
char *tagline;
u32 bootprotect;
// Global temporary config.
bool se_keygen_done;
bool sept_run;
bool aes_slots_new;
bool emummc_force_disable;
bool rcm_patched;
bool sbk_set;
u32 errors;
hos_eks_mbr_t *eks;
} hekate_config;
@@ -49,6 +49,7 @@ typedef struct _nyx_config
u32 home_screen;
u32 verification;
u32 ums_emmc_rw;
u32 jc_disable;
} nyx_config;
void set_default_configuration();

View File

@@ -386,8 +386,6 @@ static bool _fts_touch_read(lv_indev_data_t *data)
static bool _jc_virt_mouse_read(lv_indev_data_t *data)
{
static u32 calib_timer = 0;
// Poll Joy-Con.
jc_gamepad_rpt_t *jc_pad = joycon_poll();
@@ -409,12 +407,6 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
// Calibrate left stick.
if (!jc_drv_ctx.centering_done)
{
if (!calib_timer)
calib_timer = get_tmr_ms() + LV_INDEV_READ_PERIOD * 4;
if (calib_timer > get_tmr_ms())
return false;
if (jc_pad->conn_l
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
&& jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00)
@@ -435,10 +427,7 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
// Re-calibrate on disconnection.
if (!jc_pad->conn_l)
{
calib_timer = 0;
jc_drv_ctx.centering_done = 0;
}
// Set button presses.
if (jc_pad->a || jc_pad->zl || jc_pad->zr)
@@ -910,6 +899,10 @@ static lv_res_t _removed_sd_action(lv_obj_t *btns, const char *txt)
case 1:
power_off();
break;
case 2:
sd_end();
do_reload = false;
break;
}
return mbox_action(btns, txt);
@@ -926,10 +919,10 @@ static void _check_sd_card_removed(void *params)
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
static const char * mbox_btn_map[] = { "\221Reboot (RCM)", "\221Power Off", "" };
static const char * mbox_btn_map[] = { "\221Reboot (RCM)", "\221Power Off", "\221Do not reload", "" };
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES * 4 / 9);
lv_obj_set_width(mbox, LV_HOR_RES * 6 / 9);
lv_mbox_set_text(mbox, "\n#FF8000 SD card was removed!#\n\n#96FF00 Nyx will reload after inserting it.#\n");
lv_mbox_add_btns(mbox, mbox_btn_map, _removed_sd_action);
@@ -1379,6 +1372,8 @@ static lv_res_t _win_launch_close_action(lv_obj_t * btn)
launch_bg_done = true;
}
close_btn = NULL;
return LV_RES_INV;
}
@@ -2239,8 +2234,11 @@ void nyx_load_and_run()
lv_disp_drv_register(&disp_drv);
// Initialize Joy-Con.
lv_task_t *task_jc_init_hw = lv_task_create(jc_init_hw, LV_TASK_ONESHOT, LV_TASK_PRIO_LOWEST, NULL);
lv_task_once(task_jc_init_hw);
if (!n_cfg.jc_disable)
{
lv_task_t *task_jc_init_hw = lv_task_create(jc_init_hw, LV_TASK_ONESHOT, LV_TASK_PRIO_LOWEST, NULL);
lv_task_once(task_jc_init_hw);
}
lv_indev_drv_t indev_drv_jc;
lv_indev_drv_init(&indev_drv_jc);
indev_drv_jc.type = LV_INDEV_TYPE_POINTER;

View File

@@ -28,6 +28,7 @@
#include <mem/heap.h>
#include <mem/sdram.h>
#include <mem/smmu.h>
#include <power/bm92t36.h>
#include <power/bq24193.h>
#include <power/max17050.h>
#include <sec/se.h>
@@ -264,6 +265,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
lv_mbox_set_text(mbox, "#C7EA46 CAL0 Info#");
char *txt_buf = (char *)malloc(0x4000);
txt_buf[0] = 0;
lv_obj_t * lb_desc = lv_label_create(mbox, NULL);
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
@@ -271,24 +273,39 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
lv_label_set_style(lb_desc, &monospace_text);
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 3);
sd_mount();
// Read package1.
static const u32 BOOTLOADER_SIZE = 0x40000;
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
static const u32 BOOTLOADER_BACKUP_OFFSET = 0x140000;
static const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
u8 kb = 0;
char *build_date = malloc(32);
u8 *pkg1 = (u8 *)malloc(0x40000);
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
u8 *pkg1 = (u8 *)malloc(BOOTLOADER_SIZE);
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
sdmmc_storage_read(&emmc_storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
try_load:
sdmmc_storage_read(&emmc_storage, bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
char *build_date = malloc(32);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n", build_date);
s_printf(txt_buf + strlen(txt_buf), "#00DDFF Found pkg1 ('%s')#\n", build_date);
free(build_date);
sd_mount();
if (!pkg1_id)
{
strcat(txt_buf, "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
strcat(txt_buf, "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#\n");
// Try backup bootloader.
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
{
strcat(txt_buf, "Trying backup bootloader...\n");
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
goto try_load;
}
lv_label_set_text(lb_desc, txt_buf);
goto out;
@@ -328,7 +345,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
// Read the correct keyblob.
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
sdmmc_storage_read(&emmc_storage, 0x180000 / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
sdmmc_storage_read(&emmc_storage, HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
// Generate BIS keys
hos_bis_keygen(keyblob, kb, &tsec_ctxt);
@@ -413,6 +430,9 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
case 0x94:
strcat(txt_buf, "1");
break;
case 0x95:
strcat(txt_buf, "2");
break;
default:
strcat(txt_buf, "X");
break;
@@ -626,32 +646,32 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
switch ((ram_density.dev0_ch0 & 0x3C) >> 2)
{
case 2:
strcat(txt_buf, "4x512MB");
strcat(txt_buf, " x 512MB");
break;
case 3:
strcat(txt_buf, "4x768MB");
strcat(txt_buf, " x 768MB");
break;
case 4:
strcat(txt_buf, "4x1GB");
strcat(txt_buf, " x 1GB");
break;
default:
strcat(txt_buf, "4xUnk");
strcat(txt_buf, " x Unk");
break;
}
s_printf(txt_buf + strlen(txt_buf), " (%d) #FF8000 |# ", (ram_density.dev0_ch0 & 0x3C) >> 2);
switch ((ram_density.dev1_ch0 & 0x3C) >> 2)
{
case 2:
strcat(txt_buf, "4x512MB");
strcat(txt_buf, " x 512MB");
break;
case 3:
strcat(txt_buf, "4x768MB");
strcat(txt_buf, " x 768MB");
break;
case 4:
strcat(txt_buf, "4x1GB");
strcat(txt_buf, " x 1GB");
break;
default:
strcat(txt_buf, "2xUnk");
strcat(txt_buf, " x Unk");
break;
}
s_printf(txt_buf + strlen(txt_buf), " (%d)\n\n", (ram_density.dev1_ch0 & 0x3C) >> 2);
@@ -692,6 +712,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case 0x94:
strcat(txt_buf, "1");
break;
case 0x95:
strcat(txt_buf, "2");
break;
default:
strcat(txt_buf, "X #FFDD00 Contact me!#");
break;
@@ -848,23 +871,40 @@ static lv_res_t _create_window_tsec_keys_status(lv_obj_t *btn)
lv_label_set_recolor(lb_desc, true);
lv_label_set_style(lb_desc, &monospace_text);
// Read package1.
char *build_date = malloc(32);
u8 *pkg1 = (u8 *)malloc(0x40000);
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
sdmmc_storage_read(&emmc_storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
sdmmc_storage_end(&emmc_storage);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
char *txt_buf = (char *)malloc(0x1000);
char *txt_buf2 = (char *)malloc(0x1000);
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n", build_date);
txt_buf[0] = 0;
// Read package1.
static const u32 BOOTLOADER_SIZE = 0x40000;
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
static const u32 BOOTLOADER_BACKUP_OFFSET = 0x140000;
u8 *pkg1 = (u8 *)malloc(0x40000);
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
try_load:
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
sdmmc_storage_read(&emmc_storage, bootloader_offset / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
sdmmc_storage_end(&emmc_storage);
char *build_date = malloc(32);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
s_printf(txt_buf + strlen(txt_buf), "#00DDFF Found pkg1 ('%s')#\n", build_date);
free(build_date);
if (!pkg1_id)
{
strcat(txt_buf, "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
strcat(txt_buf, "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#\n");
// Try backup bootloader.
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
{
strcat(txt_buf, "Trying backup bootloader...\n");
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
goto try_load;
}
lv_label_set_text(lb_desc, txt_buf);
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
@@ -974,7 +1014,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
char *txt_buf = (char *)malloc(0x1000);
s_printf(txt_buf, "#FF8000 %s Benchmark#\n[3 x %s raw reads. Cancel: VOL- & VOL+]\n",
s_printf(txt_buf, "#FF8000 %s Benchmark#\n[3 x %s raw reads] Abort: VOL- & VOL+\n",
sd_bench ? "SD Card" : "eMMC", sd_bench ? "2GB" : "8GB");
lv_mbox_set_text(mbox, txt_buf);
@@ -1111,8 +1151,15 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
}
else
{
u16 card_type;
u32 speed = 0;
char *rsvd_blocks;
char life_a_txt[8];
char life_b_txt[8];
u32 life_a = storage.ext_csd.dev_life_est_a;
u32 life_b = storage.ext_csd.dev_life_est_b;
u16 card_type = storage.ext_csd.card_type;
char card_type_support[96];
card_type_support[0] = 0;
s_printf(txt_buf, "\n%X\n%X\n%02X\n%c%c%c%c%c%c\n%X\n%04X\n%02d/%04d\n\n",
storage.cid.manfid, storage.cid.card_bga, storage.cid.oemid,
@@ -1120,9 +1167,6 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
storage.cid.prod_name[3], storage.cid.prod_name[4], storage.cid.prod_name[5],
storage.cid.prv, storage.cid.serial, storage.cid.month, storage.cid.year);
card_type = storage.ext_csd.card_type;
char card_type_support[96];
card_type_support[0] = 0;
if (card_type & EXT_CSD_CARD_TYPE_HS_26)
{
strcat(card_type_support, "HS26");
@@ -1149,11 +1193,45 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
speed = (200 << 16) | 400;
}
strcpy(life_a_txt, "-");
strcpy(life_b_txt, "-");
// Normalize cells life.
if (life_a)
{
life_a--;
life_a = (10 - life_a) * 10;
s_printf(life_a_txt, "%d%%", life_a);
}
if (life_b) // Toshiba is 0 (undefined).
{
life_b--;
life_b = (10 - life_b) * 10;
s_printf(life_b_txt, "%d%%", life_b);
}
switch (storage.ext_csd.pre_eol_info)
{
case 1:
rsvd_blocks = "Normal (< 80%)";
break;
case 2:
rsvd_blocks = "Warning (> 80%)";
break;
case 3:
rsvd_blocks = "Urgent (> 90%)";
break;
default:
rsvd_blocks = "Unknown";
break;
}
s_printf(txt_buf + strlen(txt_buf),
"#00DDFF V1.%d#\n%02X\n1.%d\n%02X\n%d MB/s (%d MHz)\n%d MB/s\n%s",
storage.ext_csd.ext_struct, storage.csd.mmca_vsn, storage.ext_csd.rev,
"#00DDFF V1.%d (rev 1.%d)#\n%02X\n%d MB/s (%d MHz)\n%d MB/s\n%s\nA: %s, B: %s\n%s",
storage.ext_csd.ext_struct, storage.ext_csd.rev,
storage.csd.cmdclass, speed & 0xFFFF, (speed >> 16) & 0xFFFF,
storage.csd.busspeed, card_type_support);
storage.csd.busspeed, card_type_support, life_a_txt, life_b_txt, rsvd_blocks);
lv_label_set_static_text(lb_desc,
"#00DDFF CID:#\n"
@@ -1165,12 +1243,12 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
"S/N:\n"
"Month/Year:\n\n"
"#00DDFF Ext CSD#\n"
"Spec Version:\n"
"Extended Rev:\n"
"Cmd Classes:\n"
"Max Rate:\n"
"Current Rate:\n"
"Type Support:"
"Type Support:\n\n"
"Estimated Life:\n"
"Reserved Used:"
);
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
@@ -1384,9 +1462,10 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
lv_obj_t * lb_val3 = lv_label_create(val3, lb_desc);
s_printf(txt_buf, "\n%s\n%d KiB\n%d MiB",
s_printf(txt_buf, "\n%s\n%d %s\n%d MiB",
sd_fs.fs_type == FS_EXFAT ? ("exFAT "SYMBOL_SHRK) : ("FAT32"),
(sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512,
(sd_fs.csize > 1) ? "KiB" : "B",
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF);
lv_label_set_text(lb_val3, txt_buf);
@@ -1535,7 +1614,11 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
"Fast charge current limit:\n"
"Charge voltage limit:\n"
"Charge status:\n"
"Temperature status:"
"Temperature status:\n\n"
"#00DDFF USB-PD IC Info:#\n"
"Connection status:\n"
"Input Wattage Limit:\n"
"USB-PD Profiles:"
);
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
@@ -1548,8 +1631,9 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
bq24193_get_property(BQ24193_InputVoltageLimit, &value);
s_printf(txt_buf, "\n%d mV\n", value);
bq24193_get_property(BQ24193_InputCurrentLimit, &value);
s_printf(txt_buf + strlen(txt_buf), "%d mA\n", value);
int iinlim = 0;
bq24193_get_property(BQ24193_InputCurrentLimit, &iinlim);
s_printf(txt_buf + strlen(txt_buf), "%d mA\n", iinlim);
bq24193_get_property(BQ24193_SystemMinimumVoltage, &value);
s_printf(txt_buf + strlen(txt_buf), "%d mV\n", value);
@@ -1603,6 +1687,35 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
break;
}
bool inserted;
u32 wattage = 0;
usb_pd_objects_t usb_pd;
bm92t36_get_sink_info(&inserted, &usb_pd);
strcat(txt_buf, "\n\n\n");
strcat(txt_buf, inserted ? "Connected" : "Disconnected");
// Select 5V is no PD contract.
wattage = iinlim * (usb_pd.pdo_no ? usb_pd.selected_pdo.voltage : 5);
s_printf(txt_buf + strlen(txt_buf), "\n%d.%d W", wattage / 1000, (wattage % 1000) / 100);
if (!usb_pd.pdo_no)
strcat(txt_buf, "\nNon PD");
// Limit to 5 profiles so it can fit.
usb_pd.pdo_no = MIN(usb_pd.pdo_no, 5);
for (u32 i = 0; i < usb_pd.pdo_no; i++)
{
bool selected =
usb_pd.pdos[i].amperage == usb_pd.selected_pdo.amperage &&
usb_pd.pdos[i].voltage == usb_pd.selected_pdo.voltage;
s_printf(txt_buf + strlen(txt_buf), "\n%s%d mA, %2d V%s",
selected ? "#D4FF00 " : "",
usb_pd.pdos[i].amperage, usb_pd.pdos[i].voltage,
selected ? "#" : "");
}
lv_label_set_text(lb_val2, txt_buf);
lv_obj_set_width(lb_val2, lv_obj_get_width(val2));

View File

@@ -740,10 +740,20 @@ void first_time_clock_edit(void *param)
static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
{
FIL fp;
int error;
bool is_l_hos = false;
bool is_r_hos = false;
jc_gamepad_rpt_t *jc_pad = jc_get_bt_pairing_info(&is_l_hos, &is_r_hos);
char *data = (char *)malloc(0x4000);
char *txt_buf = (char *)malloc(0x1000);
if (!jc_pad)
{
error = 255;
goto disabled;
}
// Count valid joycon.
u32 joycon_found = jc_pad->bt_conn_l.type ? 1 : 0;
if (jc_pad->bt_conn_r.type)
@@ -753,10 +763,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
jc_pad->bt_conn_l.type = is_l_hos ? jc_pad->bt_conn_l.type : 0;
jc_pad->bt_conn_r.type = is_r_hos ? jc_pad->bt_conn_r.type : 0;
int error = !sd_mount();
char *data = (char *)malloc(0x4000);
char *txt_buf = (char *)malloc(0x1000);
error = !sd_mount();
if (!error)
{
@@ -798,6 +805,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
sd_unmount();
}
disabled:;
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);

View File

@@ -1105,8 +1105,13 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
// Read package1.
static const u32 BOOTLOADER_SIZE = 0x40000;
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
static const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
char *build_date = malloc(32);
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
sdmmc_storage_read(&storage, BOOTLOADER_MAIN_OFFSET / NX_EMMC_BLOCKSIZE, BOOTLOADER_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n\n", build_date);
@@ -1122,7 +1127,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
manual_system_maintenance(true);
emmcsn_path_impl(path, "/pkg1", "pkg1_enc.bin", &storage);
if (sd_save_to_file(pkg1, 0x40000, path))
if (sd_save_to_file(pkg1, BOOTLOADER_SIZE, path))
goto out_free;
strcat(txt_buf, "\nEncrypted pkg1 dumped to pkg1_enc.bin");
@@ -1167,7 +1172,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Read keyblob.
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
sdmmc_storage_read(&storage, HOS_KEYBLOBS_OFFSET / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
// Decrypt.
hos_keygen(keyblob, kb, &tsec_ctxt);

View File

@@ -676,7 +676,7 @@ static lv_res_t _action_flash_linux_data(lv_obj_t * btns, const char * txt)
if (pct != prevPct)
{
lv_bar_set_value(bar, pct);
s_printf(txt_buf, " "SYMBOL_DOT" %d%%", pct);
s_printf(txt_buf, " #DDDDDD "SYMBOL_DOT"# %d%%", pct);
lv_label_set_text(label_pct, txt_buf);
manual_system_maintenance(true);
prevPct = pct;
@@ -810,8 +810,26 @@ static lv_res_t _action_check_flash_linux(lv_obj_t *btn)
{
if ((u64)fno.fsize % 0x400000)
{
lv_label_set_text(lbl_status, "#FFDD00 Error:# The image is not aligned to 4 MiB!");
goto error;
// Check if last part.
idx++;
if (idx < 10)
{
path[23] = '0';
itoa(idx, &path[23 + 1], 10);
}
else
itoa(idx, &path[23], 10);
// If not the last part, unaligned size is not permitted.
if (!f_stat(path, NULL)) // NULL: Don't override current part fs info.
{
lv_label_set_text(lbl_status, "#FFDD00 Error:# The image is not aligned to 4 MiB!");
goto error;
}
// Last part. Align size to LBA (512 bytes).
fno.fsize = ALIGN((u64)fno.fsize, 512);
idx--;
}
l4t_flash_ctxt.image_size_sct += (u64)fno.fsize >> 9;
}
@@ -894,7 +912,7 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
static const char *mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
static const char *mbox_btn_map2[] = { "\222Continue", "\222Cancel", "" };
static const char *mbox_btn_map2[] = { "\222Continue", "\222No", "" };
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);

View File

@@ -214,6 +214,10 @@ void hos_eks_save(u32 kb)
u8 *keys = (u8 *)calloc(0x1000, 1);
se_get_aes_keys(keys + 0x800, keys, 0x10);
// Set SBK back.
if (h_cfg.sbk_set)
se_aes_key_set(14, keys + 14 * 0x10, 0x10);
// Set magic and personalized info.
h_cfg.eks->magic = HOS_EKS_MAGIC;
h_cfg.eks->enabled[key_idx] = kb;
@@ -659,15 +663,18 @@ void hos_bis_keys_clear()
se_aes_key_clear(i);
// Set SBK back.
u32 sbk[4] = {
if (!h_cfg.sbk_set)
{
u32 sbk[4] = {
FUSE(FUSE_PRIVATE_KEY0),
FUSE(FUSE_PRIVATE_KEY1),
FUSE(FUSE_PRIVATE_KEY2),
FUSE(FUSE_PRIVATE_KEY3)
};
// Set SBK to slot 14.
se_aes_key_set(14, sbk, 0x10);
// Set SBK to slot 14.
se_aes_key_set(14, sbk, 0x10);
// Lock SBK from being read.
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG);
// Lock SBK from being read.
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG);
}
}

View File

@@ -241,10 +241,8 @@ void load_saved_configuration()
h_cfg.autonogc = atoi(kv->val);
else if (!strcmp("updater2p", kv->key))
h_cfg.updater2p = atoi(kv->val);
else if (!strcmp("brand", kv->key))
h_cfg.brand = kv->val;
else if (!strcmp("tagline", kv->key))
h_cfg.tagline = kv->val;
else if (!strcmp("bootprotect", kv->key))
h_cfg.bootprotect = atoi(kv->val);
}
break;
@@ -272,6 +270,8 @@ void load_saved_configuration()
n_cfg.verification = atoi(kv->val);
else if (!strcmp("umsemmcrw", kv->key))
n_cfg.ums_emmc_rw = atoi(kv->val) == 1;
else if (!strcmp("jcdisable", kv->key))
n_cfg.jc_disable = atoi(kv->val) == 1;
}
break;
@@ -307,7 +307,7 @@ static void _show_errors()
switch (*excp_type)
{
case EXCP_TYPE_RESET:
WPRINTF("RST");
WPRINTF("RESET");
break;
case EXCP_TYPE_UNDEF:
WPRINTF("UNDEF");
@@ -402,15 +402,21 @@ void ipl_main()
// Important: Preserve version header!
__asm__ ("" : : "" (ipl_ver));
#if (LV_LOG_PRINTF == 1)
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
pinmux_config_uart(UART_B);
clock_enable_uart(UART_B);
uart_init(UART_B, 115200);
#ifdef DEBUG_UART_PORT
#if DEBUG_UART_PORT == UART_B
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
#endif
#if DEBUG_UART_PORT == UART_C
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
#endif
pinmux_config_uart(DEBUG_UART_PORT);
clock_enable_uart(DEBUG_UART_PORT);
uart_init(DEBUG_UART_PORT, 115200);
uart_send(UART_B, (u8 *)"hekate-NYX: Hello!\r\n", 20);
uart_wait_idle(UART_B, UART_TX_IDLE);
uart_send(DEBUG_UART_PORT, (u8 *)"hekate-NYX: Hello!\r\n", 20);
uart_wait_idle(DEBUG_UART_PORT, UART_TX_IDLE);
#endif
// Initialize the rest of hw and load nyx's resources.

View File

@@ -174,7 +174,7 @@ bool sd_mount()
static void _sd_deinit(bool deinit)
{
if (sd_mode == SD_INIT_FAIL)
if (deinit && sd_mode == SD_INIT_FAIL)
sd_mode = SD_UHS_SDR104;
if (sd_init_done && sd_mounted)