Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85d43147ee | ||
|
|
e3e5dab0fc | ||
|
|
8b837dd81b | ||
|
|
8f7bdd45b1 | ||
|
|
0142ac1697 | ||
|
|
e8fb6624c0 | ||
|
|
bdb21ce3fd | ||
|
|
2ca4fb6d8f | ||
|
|
e7900b11b4 | ||
|
|
d71f6d0b99 | ||
|
|
926bd5d2fb | ||
|
|
461d14c39a | ||
|
|
6714cae498 | ||
|
|
b20a0e74c2 | ||
|
|
9686eaf3f1 | ||
|
|
7b03a24196 | ||
|
|
98555b24f8 | ||
|
|
3d05b58856 | ||
|
|
15b46ddb27 | ||
|
|
78c4e6510d | ||
|
|
cd76d5ac09 | ||
|
|
9c2a064817 | ||
|
|
db2da89f69 | ||
|
|
0652d6b3f1 | ||
|
|
1111125aab | ||
|
|
4fc420616d | ||
|
|
fb7c83a66c | ||
|
|
f021665089 | ||
|
|
6c887c15be | ||
|
|
2b7722da7d |
@@ -120,12 +120,12 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
|
|||||||
|
|
||||||
| Offset / Name | Description |
|
| 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. |
|
| '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. |
|
| '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' 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. |
|
| '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. |
|
| '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. |
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# IPL Version.
|
# IPL Version.
|
||||||
BLVERSION_MAJOR := 5
|
BLVERSION_MAJOR := 5
|
||||||
BLVERSION_MINOR := 3
|
BLVERSION_MINOR := 3
|
||||||
BLVERSION_HOTFX := 1
|
BLVERSION_HOTFX := 3
|
||||||
BLVERSION_RSVD := 0
|
BLVERSION_RSVD := 0
|
||||||
|
|
||||||
# Nyx Version.
|
# Nyx Version.
|
||||||
NYXVERSION_MAJOR := 0
|
NYXVERSION_MAJOR := 0
|
||||||
NYXVERSION_MINOR := 9
|
NYXVERSION_MINOR := 9
|
||||||
NYXVERSION_HOTFX := 3
|
NYXVERSION_HOTFX := 4
|
||||||
NYXVERSION_RSVD := 0
|
NYXVERSION_RSVD := 0
|
||||||
|
|||||||
@@ -503,7 +503,7 @@
|
|||||||
* [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
|
||||||
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
* [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:
|
* 5.5" panels:
|
||||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
|
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
|
||||||
|
|||||||
@@ -812,7 +812,7 @@ void jc_init_hw()
|
|||||||
jc_l.uart = UART_C;
|
jc_l.uart = UART_C;
|
||||||
jc_r.uart = UART_B;
|
jc_r.uart = UART_B;
|
||||||
|
|
||||||
#if (LV_LOG_PRINTF != 1)
|
#ifndef DEBUG_UART_PORT
|
||||||
jc_power_supply(UART_C, true);
|
jc_power_supply(UART_C, true);
|
||||||
jc_power_supply(UART_B, true);
|
jc_power_supply(UART_B, true);
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,11 @@
|
|||||||
|
|
||||||
|
|
||||||
/*Log settings*/
|
/*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
|
#if USE_LV_LOG
|
||||||
/* How important log should be added:
|
/* How important log should be added:
|
||||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||||
|
|||||||
@@ -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"};
|
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);
|
||||||
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);
|
//gfx_printf("%s: %s \t(%s #%d)\n", lvl_prefix[level], dsc, file, line);
|
||||||
#else
|
#else
|
||||||
if(print_cb) print_cb(level, file, line, dsc);
|
if(print_cb) print_cb(level, file, line, dsc);
|
||||||
|
|||||||
65
bdk/power/bm92t30_stub.c
Normal file
65
bdk/power/bm92t30_stub.c
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* USB-PD driver for Nintendo Switch's TI BM92T30
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bm92t30_stub.h"
|
||||||
|
#include <soc/i2c.h>
|
||||||
|
#include <utils/util.h>
|
||||||
|
|
||||||
|
#define STATUS1_INSERT 0x80
|
||||||
|
|
||||||
|
typedef struct _pdo_t{
|
||||||
|
u32 amp:10;
|
||||||
|
u32 volt:10;
|
||||||
|
u32 info:10;
|
||||||
|
u32 type:2;
|
||||||
|
} pdo_t;
|
||||||
|
|
||||||
|
void bm92t30_get_charger_type(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||||
|
{
|
||||||
|
u8 buf[32];
|
||||||
|
pdo_t pdos[7];
|
||||||
|
i2c_recv_buf_big(buf, 32, I2C_1, BM92T30_I2C_ADDR, 0);
|
||||||
|
|
||||||
|
if (inserted)
|
||||||
|
*inserted = buf[6] & STATUS1_INSERT ? true : false;
|
||||||
|
memcpy(pdos, &buf[17], 15); // We can only get max 4 objects.
|
||||||
|
|
||||||
|
if (usb_pd)
|
||||||
|
{
|
||||||
|
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
|
||||||
|
usb_pd->pdo_no = MIN(buf[16] / sizeof(pdo_t), 4); // We can only get max 4 objects.
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
bdk/power/bm92t30_stub.h
Normal file
40
bdk/power/bm92t30_stub.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* USB-PD driver for Nintendo Switch's TI BM92T30
|
||||||
|
*
|
||||||
|
* 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 __BM92T30_H_
|
||||||
|
#define __BM92T30_H_
|
||||||
|
|
||||||
|
#include <utils/types.h>
|
||||||
|
|
||||||
|
#define BM92T30_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_objects_t;
|
||||||
|
|
||||||
|
void bm92t30_get_charger_type(bool *inserted, usb_pd_objects_t *usb_pd);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -384,9 +384,6 @@ void hw_init()
|
|||||||
sdram_init();
|
sdram_init();
|
||||||
|
|
||||||
bpmp_mmu_enable();
|
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)
|
void hw_reinit_workaround(bool extra_reconfig, u32 magic)
|
||||||
|
|||||||
312
bdk/soc/i2c.c
312
bdk/soc/i2c.c
@@ -20,31 +20,85 @@
|
|||||||
#include <soc/i2c.h>
|
#include <soc/i2c.h>
|
||||||
#include <utils/util.h>
|
#include <utils/util.h>
|
||||||
|
|
||||||
|
#define I2C_PACKET_PROT_I2C (1 << 4)
|
||||||
|
#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[] = {
|
static const u32 i2c_addrs[] = {
|
||||||
0x7000C000, 0x7000C400, 0x7000C500,
|
0x7000C000, // I2C_1.
|
||||||
0x7000C700, 0x7000D000, 0x7000D100
|
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++)
|
for (u32 i = 0; i < 20; i++)
|
||||||
{
|
{
|
||||||
usleep(1);
|
usleep(1);
|
||||||
if (!(base[I2C_CONFIG_LOAD] & 1))
|
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
|
||||||
break;
|
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)
|
if (size > 8)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u32 tmp = 0;
|
u32 tmp = 0;
|
||||||
|
|
||||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||||
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
|
|
||||||
|
// Set device address and send mode.
|
||||||
|
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
|
||||||
|
|
||||||
if (size > 4)
|
if (size > 4)
|
||||||
{
|
{
|
||||||
@@ -60,44 +114,55 @@ static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
|||||||
base[I2C_CMD_DATA1] = tmp; //Set value.
|
base[I2C_CMD_DATA1] = tmp; //Set value.
|
||||||
}
|
}
|
||||||
|
|
||||||
base[I2C_CNFG] = ((size - 1) << 1) | 0x2800; //Set size and send mode.
|
// Set size and send mode.
|
||||||
_i2c_wait(base); //Kick transaction.
|
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.
|
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)
|
if (get_tmr_ms() > timeout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base[I2C_STATUS] << 28)
|
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
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)
|
if (size > 8)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
vu32 *base = (vu32 *)i2c_addrs[i2c_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.
|
|
||||||
|
|
||||||
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.
|
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)
|
if (get_tmr_ms() > timeout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base[I2C_STATUS] << 28)
|
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
|
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
|
||||||
@@ -113,60 +178,221 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2c_init(u32 idx)
|
static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
||||||
{
|
{
|
||||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
if (size > 32)
|
||||||
|
return 0;
|
||||||
|
|
||||||
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001;
|
int res = 0;
|
||||||
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
|
|
||||||
_i2c_wait(base);
|
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 | (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;
|
||||||
|
|
||||||
|
u32 hdr[3];
|
||||||
|
hdr[0] = I2C_PACKET_PROT_I2C;
|
||||||
|
hdr[1] = size - 1;
|
||||||
|
hdr[2] = I2C_HEADER_READ | I2C_HEADER_IE_ENABLE | (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] & 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++)
|
for (u32 i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
usleep(20000);
|
usleep(20000);
|
||||||
if (base[INTERRUPT_STATUS_REGISTER] & 0x800)
|
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
(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, u32 reg, u8 *buf, u32 size)
|
||||||
|
{
|
||||||
|
if (size > 32)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return _i2c_send_pkt(i2c_idx, buf, size, dev_addr, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||||
|
{
|
||||||
|
int res = _i2c_send_single(i2c_idx, dev_addr, (u8 *)®, 1);
|
||||||
|
if (res)
|
||||||
|
res = _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
|
||||||
{
|
{
|
||||||
u8 tmp[4];
|
u8 tmp[4];
|
||||||
|
|
||||||
if (size > 7)
|
if (size > 7)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tmp[0] = y;
|
tmp[0] = reg;
|
||||||
memcpy(tmp + 1, buf, size);
|
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 res = _i2c_send_single(i2c_idx, dev_addr, (u8 *)®, 1);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (res)
|
if (res)
|
||||||
res = _i2c_recv_pkt(idx, buf, size, x);
|
res = _i2c_recv_single(i2c_idx, buf, size, dev_addr);
|
||||||
return res;
|
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;
|
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;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,22 +27,13 @@
|
|||||||
#define I2C_5 4
|
#define I2C_5 4
|
||||||
#define I2C_6 5
|
#define I2C_6 5
|
||||||
|
|
||||||
#define I2C_CNFG 0x00
|
void i2c_init(u32 i2c_idx);
|
||||||
#define I2C_CMD_ADDR0 0x01
|
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
|
||||||
#define I2C_CMD_DATA1 0x03
|
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
|
||||||
#define I2C_CMD_DATA2 0x04
|
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||||
#define I2C_STATUS 0x07
|
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
|
||||||
#define INTERRUPT_STATUS_REGISTER 0x1A
|
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||||
#define I2C_CLK_DIVISOR_REGISTER 0x1B
|
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
|
||||||
#define I2C_BUS_CLEAR_CONFIG 0x21
|
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||||
#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);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#define PMC_SCRATCH0_MODE_PAYLOAD (1 << 29)
|
#define PMC_SCRATCH0_MODE_PAYLOAD (1 << 29)
|
||||||
#define PMC_SCRATCH0_MODE_RCM (1 << 1)
|
#define PMC_SCRATCH0_MODE_RCM (1 << 1)
|
||||||
#define PMC_SCRATCH0_MODE_WARMBOOT (1 << 0)
|
#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_SCRATCH1 0x54
|
||||||
#define APBDEV_PMC_SCRATCH20 0xA0
|
#define APBDEV_PMC_SCRATCH20 0xA0
|
||||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||||
|
|||||||
@@ -175,8 +175,11 @@ int sdmmc_storage_end(sdmmc_storage_t *storage)
|
|||||||
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
||||||
{
|
{
|
||||||
u8 *bbuf = (u8 *)buf;
|
u8 *bbuf = (u8 *)buf;
|
||||||
bool first_reinit = false;
|
u32 sct_off = sector;
|
||||||
while (num_sectors)
|
u32 sct_total = num_sectors;
|
||||||
|
bool first_reinit = true;
|
||||||
|
|
||||||
|
while (sct_total)
|
||||||
{
|
{
|
||||||
u32 blkcnt = 0;
|
u32 blkcnt = 0;
|
||||||
// Retry 5 times if failed.
|
// Retry 5 times if failed.
|
||||||
@@ -184,7 +187,7 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
reinit_try:
|
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;
|
goto out;
|
||||||
else
|
else
|
||||||
retries--;
|
retries--;
|
||||||
@@ -201,7 +204,7 @@ reinit_try:
|
|||||||
|
|
||||||
sd_error_count_increment(SD_ERROR_RW_FAIL);
|
sd_error_count_increment(SD_ERROR_RW_FAIL);
|
||||||
|
|
||||||
if (!first_reinit)
|
if (first_reinit)
|
||||||
res = sd_initialize(true);
|
res = sd_initialize(true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -210,19 +213,27 @@ reinit_try:
|
|||||||
sd_error_count_increment(SD_ERROR_INIT_FAIL);
|
sd_error_count_increment(SD_ERROR_INIT_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset retries to a lower number.
|
||||||
retries = 3;
|
retries = 3;
|
||||||
first_reinit = true;
|
first_reinit = false;
|
||||||
|
|
||||||
|
// If succesful reinit, restart xfer.
|
||||||
if (res)
|
if (res)
|
||||||
|
{
|
||||||
|
bbuf = (u8 *)buf;
|
||||||
|
sct_off = sector;
|
||||||
|
sct_total = num_sectors;
|
||||||
|
|
||||||
goto reinit_try;
|
goto reinit_try;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
DPRINTF("readwrite: %08X\n", blkcnt);
|
DPRINTF("readwrite: %08X\n", blkcnt);
|
||||||
sector += blkcnt;
|
sct_off += blkcnt;
|
||||||
num_sectors -= blkcnt;
|
sct_total -= blkcnt;
|
||||||
bbuf += 512 * blkcnt;
|
bbuf += 512 * blkcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +398,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_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.dev_life_est_a = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A];
|
||||||
|
storage->ext_csd.dev_life_est_b = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B];
|
||||||
|
|
||||||
storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT];
|
storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,16 +65,19 @@ typedef struct _mmc_csd
|
|||||||
|
|
||||||
typedef struct _mmc_ext_csd
|
typedef struct _mmc_ext_csd
|
||||||
{
|
{
|
||||||
u8 rev;
|
|
||||||
u32 sectors;
|
u32 sectors;
|
||||||
int bkops; /* background support bit */
|
int bkops; /* background support bit */
|
||||||
int bkops_en; /* manual bkops enable bit */
|
int bkops_en; /* manual bkops enable bit */
|
||||||
|
u8 rev;
|
||||||
u8 ext_struct; /* 194 */
|
u8 ext_struct; /* 194 */
|
||||||
u8 card_type; /* 196 */
|
u8 card_type; /* 196 */
|
||||||
u8 bkops_status; /* 246 */
|
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 boot_mult;
|
||||||
u8 rpmb_mult;
|
u8 rpmb_mult;
|
||||||
|
u16 dev_version;
|
||||||
} mmc_ext_csd_t;
|
} mmc_ext_csd_t;
|
||||||
|
|
||||||
typedef struct _sd_scr
|
typedef struct _sd_scr
|
||||||
|
|||||||
@@ -764,7 +764,7 @@ static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
|||||||
u16 norintsts = sdmmc->regs->norintsts;
|
u16 norintsts = sdmmc->regs->norintsts;
|
||||||
u16 errintsts = sdmmc->regs->errintsts;
|
u16 errintsts = sdmmc->regs->errintsts;
|
||||||
|
|
||||||
DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
|
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||||
|
|
||||||
if (pout)
|
if (pout)
|
||||||
*pout = norintsts;
|
*pout = norintsts;
|
||||||
@@ -772,6 +772,9 @@ DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
|
|||||||
// Check for error interrupt.
|
// Check for error interrupt.
|
||||||
if (norintsts & SDHCI_INT_ERROR)
|
if (norintsts & SDHCI_INT_ERROR)
|
||||||
{
|
{
|
||||||
|
#ifdef ERROR_EXTRA_PRINTING
|
||||||
|
EPRINTFARGS("SDMMC: norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||||
|
#endif
|
||||||
sdmmc->regs->errintsts = errintsts;
|
sdmmc->regs->errintsts = errintsts;
|
||||||
return SDMMC_MASKINT_ERROR;
|
return SDMMC_MASKINT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -963,8 +966,6 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||||||
|
|
||||||
is_data_present = true;
|
is_data_present = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
is_data_present = false;
|
|
||||||
|
|
||||||
_sdmmc_enable_interrupts(sdmmc);
|
_sdmmc_enable_interrupts(sdmmc);
|
||||||
|
|
||||||
@@ -983,7 +984,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||||||
EPRINTF("SDMMC: Transfer timeout!");
|
EPRINTF("SDMMC: Transfer timeout!");
|
||||||
#endif
|
#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);
|
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@@ -1004,7 +1005,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
#ifdef ERROR_EXTRA_PRINTING
|
#ifdef ERROR_EXTRA_PRINTING
|
||||||
EPRINTF("SDMMC: DMA Update failed!");
|
EPRINTFARGS("SDMMC: DMA Update failed (%08X)!", result);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1523,7 +1523,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||||||
DPRINTF("USB: EP timeout\n");
|
DPRINTF("USB: EP timeout\n");
|
||||||
// In case we disconnected, exit UMS.
|
// In case we disconnected, exit UMS.
|
||||||
// Raise timeout if removable and didn't got a unit ready command inside 4s.
|
// 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))
|
(bulk_ctxt->bulk_out_status == 3 && ums->lun.removable && !ums->lun.prevent_medium_removal))
|
||||||
{
|
{
|
||||||
if (bulk_ctxt->bulk_out_status == 3)
|
if (bulk_ctxt->bulk_out_status == 3)
|
||||||
|
|||||||
@@ -930,10 +930,10 @@ out:
|
|||||||
_usbd_mark_ep_complete(endpoint);
|
_usbd_mark_ep_complete(endpoint);
|
||||||
else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE)
|
else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE)
|
||||||
res = 26;
|
res = 26;
|
||||||
}
|
|
||||||
|
|
||||||
if (direction == USB_XFER_DIR_OUT)
|
if (direction == USB_XFER_DIR_OUT)
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1565,6 +1565,8 @@ int usb_device_ep1_out_reading_finish(u32 *pending_bytes)
|
|||||||
|
|
||||||
*pending_bytes = _usbd_get_ep1_out_bytes_read();
|
*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)
|
if (ep_status == USB_EP_STATUS_IDLE)
|
||||||
return 0;
|
return 0;
|
||||||
else if (ep_status == USB_EP_STATUS_DISABLED)
|
else if (ep_status == USB_EP_STATUS_DISABLED)
|
||||||
|
|||||||
@@ -65,11 +65,6 @@ static void _s_putn(u32 v, int base, char fill, int fcnt)
|
|||||||
_s_puts(p);
|
_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, ...)
|
void s_printf(char *out_buf, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -114,8 +109,6 @@ void s_printf(char *out_buf, const char *fmt, ...)
|
|||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'P':
|
case 'P':
|
||||||
_s_putp(va_arg(ap, u32*), 16, fill, fcnt);
|
|
||||||
break;
|
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
|
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ typedef enum
|
|||||||
ERR_LIBSYS_LP0 = (1 << 0),
|
ERR_LIBSYS_LP0 = (1 << 0),
|
||||||
ERR_SYSOLD_NYX = (1 << 1),
|
ERR_SYSOLD_NYX = (1 << 1),
|
||||||
ERR_LIBSYS_MTC = (1 << 2),
|
ERR_LIBSYS_MTC = (1 << 2),
|
||||||
|
ERR_SD_BOOT_EN = (1 << 3),
|
||||||
ERR_L4T_KERNEL = (1 << 24),
|
ERR_L4T_KERNEL = (1 << 24),
|
||||||
ERR_EXCEPT_ENB = (1 << 31),
|
ERR_EXCEPT_ENB = (1 << 31),
|
||||||
} hekate_errors_t;
|
} hekate_errors_t;
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ void print_sdcard_info()
|
|||||||
gfx_clear_partial_grey(0x1B, 0, 1256);
|
gfx_clear_partial_grey(0x1B, 0, 1256);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
|
|
||||||
if (sd_mount())
|
if (sd_initialize(true))
|
||||||
{
|
{
|
||||||
gfx_printf("%kCard IDentification:%k\n", 0xFF00DDFF, 0xFFCCCCCC);
|
gfx_printf("%kCard IDentification:%k\n", 0xFF00DDFF, 0xFFCCCCCC);
|
||||||
gfx_printf(
|
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.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
|
||||||
sd_storage.cid.month, sd_storage.cid.year);
|
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("%kCard-Specific Data V%d.0:%k\n", 0xFF00DDFF, sd_storage.csd.structure + 1, 0xFFCCCCCC);
|
||||||
gfx_printf(
|
gfx_printf(
|
||||||
" Cmd Classes: %02X\n"
|
" Cmd Classes: %02X\n"
|
||||||
@@ -297,18 +298,39 @@ void print_sdcard_info()
|
|||||||
" UHS Grade: U%d\n"
|
" UHS Grade: U%d\n"
|
||||||
" Video Class: V%d\n"
|
" Video Class: V%d\n"
|
||||||
" App perf class: A%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.csd.cmdclass, sd_storage.sec_cnt >> 11,
|
||||||
sd_storage.ssr.bus_width, sd_storage.csd.busspeed, sd_storage.csd.busspeed * 2,
|
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.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");
|
int res = f_mount(&sd_fs, "", 1);
|
||||||
f_getfree("", &sd_fs.free_clst, NULL);
|
if (!res)
|
||||||
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,
|
gfx_puts("Acquiring FAT volume info...\n\n");
|
||||||
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
|
f_getfree("", &sd_fs.free_clst, NULL);
|
||||||
sd_end();
|
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();
|
btn_wait();
|
||||||
|
|||||||
@@ -543,23 +543,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 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.
|
// Read package1.
|
||||||
ctxt->pkg1 = (void *)malloc(0x40000);
|
|
||||||
emummc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0);
|
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);
|
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
|
||||||
if (!ctxt->pkg1_id)
|
if (!ctxt->pkg1_id)
|
||||||
{
|
{
|
||||||
_hos_crit_error("Unknown pkg1 version.");
|
_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!" : "");
|
(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;
|
return 0;
|
||||||
}
|
}
|
||||||
gfx_printf("Identified pkg1 and mkey %d\n\n", ctxt->pkg1_id->kb);
|
gfx_printf("Identified pkg1 and mkey %d\n\n", ctxt->pkg1_id->kb);
|
||||||
|
|
||||||
// Read the correct keyblob.
|
// Read the correct keyblob.
|
||||||
ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -633,20 +651,26 @@ static bool _get_fs_exfat_compatible(link_t *info, bool *fs_is_510)
|
|||||||
pkg2_get_ids(&kip_ids, &fs_ids_cnt);
|
pkg2_get_ids(&kip_ids, &fs_ids_cnt);
|
||||||
|
|
||||||
for (fs_idx = 0; fs_idx < fs_ids_cnt; fs_idx++)
|
for (fs_idx = 0; fs_idx < fs_ids_cnt; fs_idx++)
|
||||||
|
{
|
||||||
if (!memcmp(sha_buf, kip_ids[fs_idx].hash, 8))
|
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;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hash didn't match or FAT32 + exFAT.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1039,8 +1063,9 @@ int hos_launch(ini_sec_t *cfg)
|
|||||||
// Clear EMC_SCRATCH0.
|
// Clear EMC_SCRATCH0.
|
||||||
EMC(EMC_SCRATCH0) = 0;
|
EMC(EMC_SCRATCH0) = 0;
|
||||||
|
|
||||||
// Hold USBD in reset for SoC state validation on sleep.
|
// Hold USBD, USB2, AHBDMA and APBDMA in reset for SoC state validation on sleep.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_USBD);
|
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.
|
// Flush cache and disable MMU.
|
||||||
bpmp_mmu_disable();
|
bpmp_mmu_disable();
|
||||||
|
|||||||
@@ -604,6 +604,20 @@ static kip1_patchset_t _fs_patches_1000[] =
|
|||||||
{ NULL, NULL }
|
{ 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.
|
// SHA256 hashes.
|
||||||
static kip1_id_t _kip_ids[] =
|
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", "\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", "\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", "\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;
|
static kip1_id_t *_kip_id_sets = _kip_ids;
|
||||||
|
|||||||
@@ -361,9 +361,6 @@ void secmon_exo_check_panic()
|
|||||||
if ((rpt->magic & 0xF0FFFFFF) != ATM_FATAL_MAGIC)
|
if ((rpt->magic & 0xF0FFFFFF) != ATM_FATAL_MAGIC)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Change magic to invalid, to prevent double-display of error/bootlooping.
|
|
||||||
rpt->magic = 0;
|
|
||||||
|
|
||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
|
|
||||||
@@ -386,6 +383,9 @@ void secmon_exo_check_panic()
|
|||||||
gfx_con.fntsz = 16;
|
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");
|
gfx_printf("\n\nPress POWER to continue.\n");
|
||||||
|
|
||||||
display_backlight_brightness(100, 1000);
|
display_backlight_brightness(100, 1000);
|
||||||
|
|||||||
@@ -1080,9 +1080,10 @@ out:
|
|||||||
b_cfg.boot_cfg &= BOOT_CFG_SEPT_RUN;
|
b_cfg.boot_cfg &= BOOT_CFG_SEPT_RUN;
|
||||||
h_cfg.emummc_force_disable = false;
|
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()
|
static void _patched_rcm_protection()
|
||||||
@@ -1145,7 +1146,8 @@ static void _show_errors()
|
|||||||
if (*excp_enabled == EXCP_MAGIC)
|
if (*excp_enabled == EXCP_MAGIC)
|
||||||
h_cfg.errors |= ERR_EXCEPT_ENB;
|
h_cfg.errors |= ERR_EXCEPT_ENB;
|
||||||
|
|
||||||
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.
|
// Set error and clear flag.
|
||||||
h_cfg.errors |= ERR_L4T_KERNEL;
|
h_cfg.errors |= ERR_L4T_KERNEL;
|
||||||
@@ -1158,15 +1160,16 @@ static void _show_errors()
|
|||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
display_backlight_brightness(150, 1000);
|
display_backlight_brightness(150, 1000);
|
||||||
|
|
||||||
|
if (h_cfg.errors & ERR_SD_BOOT_EN)
|
||||||
|
WPRINTF("Failed to init SD!\n");
|
||||||
|
|
||||||
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
||||||
WPRINTF("Missing LP0 (sleep mode) lib!\n");
|
WPRINTF("Missing LP0 (sleep mode) lib!\n");
|
||||||
if (h_cfg.errors & ERR_LIBSYS_MTC)
|
if (h_cfg.errors & ERR_LIBSYS_MTC)
|
||||||
WPRINTF("Missing or old Minerva lib!\n");
|
WPRINTF("Missing or old Minerva lib!\n");
|
||||||
|
|
||||||
if (h_cfg.errors & ~(ERR_EXCEPT_ENB | ERR_L4T_KERNEL))
|
if (h_cfg.errors & ~(ERR_EXCEPT_ENB | ERR_L4T_KERNEL))
|
||||||
{
|
|
||||||
WPRINTF("\nUpdate bootloader folder!\n\n");
|
WPRINTF("\nUpdate bootloader folder!\n\n");
|
||||||
}
|
|
||||||
|
|
||||||
if (h_cfg.errors & ERR_EXCEPT_ENB)
|
if (h_cfg.errors & ERR_EXCEPT_ENB)
|
||||||
{
|
{
|
||||||
@@ -1316,6 +1319,15 @@ out:
|
|||||||
max77620_low_battery_monitor_config(true);
|
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 void _about()
|
||||||
{
|
{
|
||||||
static const char credits[] =
|
static const char credits[] =
|
||||||
@@ -1459,6 +1471,7 @@ ment_t ment_top[] = {
|
|||||||
MDEF_MENU("Tools", &menu_tools),
|
MDEF_MENU("Tools", &menu_tools),
|
||||||
MDEF_MENU("Console info", &menu_cinfo),
|
MDEF_MENU("Console info", &menu_cinfo),
|
||||||
MDEF_CAPTION("---------------", 0xFF444444),
|
MDEF_CAPTION("---------------", 0xFF444444),
|
||||||
|
MDEF_HANDLER("Reload", ipl_reload),
|
||||||
MDEF_HANDLER("Reboot (Normal)", reboot_normal),
|
MDEF_HANDLER("Reboot (Normal)", reboot_normal),
|
||||||
MDEF_HANDLER("Reboot (RCM)", reboot_rcm),
|
MDEF_HANDLER("Reboot (RCM)", reboot_rcm),
|
||||||
MDEF_HANDLER("Power off", power_off),
|
MDEF_HANDLER("Power off", power_off),
|
||||||
@@ -1467,7 +1480,7 @@ ment_t ment_top[] = {
|
|||||||
MDEF_END()
|
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.3", 0, 0 };
|
||||||
|
|
||||||
extern void pivot_stack(u32 stack_top);
|
extern void pivot_stack(u32 stack_top);
|
||||||
|
|
||||||
@@ -1493,7 +1506,8 @@ void ipl_main()
|
|||||||
// Set bootloader's default configuration.
|
// Set bootloader's default configuration.
|
||||||
set_default_configuration();
|
set_default_configuration();
|
||||||
|
|
||||||
sd_mount();
|
// Mount SD Card.
|
||||||
|
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
|
||||||
|
|
||||||
// Save sdram lp0 config.
|
// Save sdram lp0 config.
|
||||||
if (!ianos_loader("bootloader/sys/libsys_lp0.bso", DRAM_LIB, (void *)sdram_get_params_patched()))
|
if (!ianos_loader("bootloader/sys/libsys_lp0.bso", DRAM_LIB, (void *)sdram_get_params_patched()))
|
||||||
@@ -1531,6 +1545,9 @@ void ipl_main()
|
|||||||
// Load saved configuration and auto boot if enabled.
|
// Load saved configuration and auto boot if enabled.
|
||||||
_auto_launch_firmware();
|
_auto_launch_firmware();
|
||||||
|
|
||||||
|
// Failed to launch Nyx, unmount SD Card.
|
||||||
|
sd_end();
|
||||||
|
|
||||||
minerva_change_freq(FREQ_800);
|
minerva_change_freq(FREQ_800);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||||||
fuse.o kfuse.o \
|
fuse.o kfuse.o \
|
||||||
mc.o sdram.o minerva.o ramdisk.o \
|
mc.o sdram.o minerva.o ramdisk.o \
|
||||||
sdmmc.o sdmmc_driver.o nx_emmc.o nx_emmc_bis.o nx_sd.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 \
|
bm92t30_stub.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
|
||||||
touch.o joycon.o tmp451.o fan.o \
|
touch.o joycon.o tmp451.o fan.o \
|
||||||
usbd.o usb_gadget_ums.o usb_gadget_hid.o \
|
usbd.o usb_gadget_ums.o usb_gadget_hid.o \
|
||||||
hw_init.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_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)
|
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_UART_PORT=1
|
||||||
|
|
||||||
#CUSTOMDEFINES += -DDEBUG
|
#CUSTOMDEFINES += -DDEBUG
|
||||||
|
|||||||
@@ -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 bool _jc_virt_mouse_read(lv_indev_data_t *data)
|
||||||
{
|
{
|
||||||
static u32 calib_timer = 0;
|
|
||||||
|
|
||||||
// Poll Joy-Con.
|
// Poll Joy-Con.
|
||||||
jc_gamepad_rpt_t *jc_pad = joycon_poll();
|
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.
|
// Calibrate left stick.
|
||||||
if (!jc_drv_ctx.centering_done)
|
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
|
if (jc_pad->conn_l
|
||||||
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
|
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
|
||||||
&& jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00)
|
&& 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.
|
// Re-calibrate on disconnection.
|
||||||
if (!jc_pad->conn_l)
|
if (!jc_pad->conn_l)
|
||||||
{
|
|
||||||
calib_timer = 0;
|
|
||||||
jc_drv_ctx.centering_done = 0;
|
jc_drv_ctx.centering_done = 0;
|
||||||
}
|
|
||||||
|
|
||||||
// Set button presses.
|
// Set button presses.
|
||||||
if (jc_pad->a || jc_pad->zl || jc_pad->zr)
|
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:
|
case 1:
|
||||||
power_off();
|
power_off();
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
sd_end();
|
||||||
|
do_reload = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mbox_action(btns, txt);
|
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_style(dark_bg, &mbox_darken);
|
||||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
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_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
|
||||||
lv_mbox_set_recolor_text(mbox, true);
|
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_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);
|
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;
|
launch_bg_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close_btn = NULL;
|
||||||
|
|
||||||
return LV_RES_INV;
|
return LV_RES_INV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <mem/heap.h>
|
#include <mem/heap.h>
|
||||||
#include <mem/sdram.h>
|
#include <mem/sdram.h>
|
||||||
#include <mem/smmu.h>
|
#include <mem/smmu.h>
|
||||||
|
#include <power/bm92t30_stub.h>
|
||||||
#include <power/bq24193.h>
|
#include <power/bq24193.h>
|
||||||
#include <power/max17050.h>
|
#include <power/max17050.h>
|
||||||
#include <sec/se.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#");
|
lv_mbox_set_text(mbox, "#C7EA46 CAL0 Info#");
|
||||||
|
|
||||||
char *txt_buf = (char *)malloc(0x4000);
|
char *txt_buf = (char *)malloc(0x4000);
|
||||||
|
txt_buf[0] = 0;
|
||||||
|
|
||||||
lv_obj_t * lb_desc = lv_label_create(mbox, NULL);
|
lv_obj_t * lb_desc = lv_label_create(mbox, NULL);
|
||||||
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
|
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_label_set_style(lb_desc, &monospace_text);
|
||||||
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 3);
|
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 3);
|
||||||
|
|
||||||
|
sd_mount();
|
||||||
|
|
||||||
// Read package1.
|
// 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;
|
u8 kb = 0;
|
||||||
char *build_date = malloc(32);
|
u32 bootloader_offset = BOOTLOADER_MAIN_OFFSET;
|
||||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
u8 *pkg1 = (u8 *)malloc(BOOTLOADER_SIZE);
|
||||||
sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
|
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_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);
|
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);
|
free(build_date);
|
||||||
|
|
||||||
sd_mount();
|
|
||||||
|
|
||||||
if (!pkg1_id)
|
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_label_set_text(lb_desc, txt_buf);
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
@@ -328,7 +345,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
|||||||
|
|
||||||
// Read the correct keyblob.
|
// Read the correct keyblob.
|
||||||
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
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
|
// Generate BIS keys
|
||||||
hos_bis_keygen(keyblob, kb, &tsec_ctxt);
|
hos_bis_keygen(keyblob, kb, &tsec_ctxt);
|
||||||
@@ -413,6 +430,9 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
|
|||||||
case 0x94:
|
case 0x94:
|
||||||
strcat(txt_buf, "1");
|
strcat(txt_buf, "1");
|
||||||
break;
|
break;
|
||||||
|
case 0x95:
|
||||||
|
strcat(txt_buf, "2");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
strcat(txt_buf, "X");
|
strcat(txt_buf, "X");
|
||||||
break;
|
break;
|
||||||
@@ -692,6 +712,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
|||||||
case 0x94:
|
case 0x94:
|
||||||
strcat(txt_buf, "1");
|
strcat(txt_buf, "1");
|
||||||
break;
|
break;
|
||||||
|
case 0x95:
|
||||||
|
strcat(txt_buf, "2");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
strcat(txt_buf, "X #FFDD00 Contact me!#");
|
strcat(txt_buf, "X #FFDD00 Contact me!#");
|
||||||
break;
|
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_recolor(lb_desc, true);
|
||||||
lv_label_set_style(lb_desc, &monospace_text);
|
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_buf = (char *)malloc(0x1000);
|
||||||
char *txt_buf2 = (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);
|
free(build_date);
|
||||||
|
|
||||||
if (!pkg1_id)
|
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_label_set_text(lb_desc, txt_buf);
|
||||||
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
|
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
|
||||||
|
|
||||||
@@ -1111,8 +1151,15 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u16 card_type;
|
|
||||||
u32 speed = 0;
|
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",
|
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,
|
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.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);
|
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)
|
if (card_type & EXT_CSD_CARD_TYPE_HS_26)
|
||||||
{
|
{
|
||||||
strcat(card_type_support, "HS26");
|
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;
|
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),
|
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",
|
"#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.csd.mmca_vsn, storage.ext_csd.rev,
|
storage.ext_csd.ext_struct, storage.ext_csd.rev,
|
||||||
storage.csd.cmdclass, speed & 0xFFFF, (speed >> 16) & 0xFFFF,
|
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,
|
lv_label_set_static_text(lb_desc,
|
||||||
"#00DDFF CID:#\n"
|
"#00DDFF CID:#\n"
|
||||||
@@ -1165,12 +1243,12 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
|||||||
"S/N:\n"
|
"S/N:\n"
|
||||||
"Month/Year:\n\n"
|
"Month/Year:\n\n"
|
||||||
"#00DDFF Ext CSD#\n"
|
"#00DDFF Ext CSD#\n"
|
||||||
"Spec Version:\n"
|
|
||||||
"Extended Rev:\n"
|
|
||||||
"Cmd Classes:\n"
|
"Cmd Classes:\n"
|
||||||
"Max Rate:\n"
|
"Max Rate:\n"
|
||||||
"Current 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));
|
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
|
||||||
|
|
||||||
@@ -1535,7 +1613,11 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||||||
"Fast charge current limit:\n"
|
"Fast charge current limit:\n"
|
||||||
"Charge voltage limit:\n"
|
"Charge voltage limit:\n"
|
||||||
"Charge status:\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_set_width(lb_desc2, lv_obj_get_width(desc2));
|
||||||
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
|
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
|
||||||
@@ -1548,8 +1630,9 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||||||
bq24193_get_property(BQ24193_InputVoltageLimit, &value);
|
bq24193_get_property(BQ24193_InputVoltageLimit, &value);
|
||||||
s_printf(txt_buf, "\n%d mV\n", value);
|
s_printf(txt_buf, "\n%d mV\n", value);
|
||||||
|
|
||||||
bq24193_get_property(BQ24193_InputCurrentLimit, &value);
|
int iinlim = 0;
|
||||||
s_printf(txt_buf + strlen(txt_buf), "%d mA\n", value);
|
bq24193_get_property(BQ24193_InputCurrentLimit, &iinlim);
|
||||||
|
s_printf(txt_buf + strlen(txt_buf), "%d mA\n", iinlim);
|
||||||
|
|
||||||
bq24193_get_property(BQ24193_SystemMinimumVoltage, &value);
|
bq24193_get_property(BQ24193_SystemMinimumVoltage, &value);
|
||||||
s_printf(txt_buf + strlen(txt_buf), "%d mV\n", value);
|
s_printf(txt_buf + strlen(txt_buf), "%d mV\n", value);
|
||||||
@@ -1603,6 +1686,31 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool inserted;
|
||||||
|
u32 wattage = 0;
|
||||||
|
u32 max_voltage = 5;
|
||||||
|
usb_pd_objects_t usb_pd;
|
||||||
|
bm92t30_get_charger_type(&inserted, &usb_pd);
|
||||||
|
strcat(txt_buf, "\n\n\n");
|
||||||
|
strcat(txt_buf, inserted ? "Connected" : "Disconnected");
|
||||||
|
|
||||||
|
for (u32 i = 0; i < usb_pd.pdo_no; i++)
|
||||||
|
if (usb_pd.pdos[i].voltage <= 15)
|
||||||
|
max_voltage = usb_pd.pdos[i].voltage;
|
||||||
|
|
||||||
|
wattage = iinlim * max_voltage;
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
for (u32 i = 0; i < usb_pd.pdo_no; i++)
|
||||||
|
{
|
||||||
|
s_printf(txt_buf + strlen(txt_buf), "\n%d mA, %2d V",
|
||||||
|
usb_pd.pdos[i].amperage, usb_pd.pdos[i].voltage);
|
||||||
|
}
|
||||||
|
|
||||||
lv_label_set_text(lb_val2, txt_buf);
|
lv_label_set_text(lb_val2, txt_buf);
|
||||||
|
|
||||||
lv_obj_set_width(lb_val2, lv_obj_get_width(val2));
|
lv_obj_set_width(lb_val2, lv_obj_get_width(val2));
|
||||||
|
|||||||
@@ -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);
|
sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
|
||||||
|
|
||||||
// Read package1.
|
// 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);
|
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);
|
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1, build_date);
|
||||||
|
|
||||||
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n\n", 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);
|
manual_system_maintenance(true);
|
||||||
|
|
||||||
emmcsn_path_impl(path, "/pkg1", "pkg1_enc.bin", &storage);
|
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;
|
goto out_free;
|
||||||
|
|
||||||
strcat(txt_buf, "\nEncrypted pkg1 dumped to pkg1_enc.bin");
|
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.
|
// Read keyblob.
|
||||||
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
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.
|
// Decrypt.
|
||||||
hos_keygen(keyblob, kb, &tsec_ctxt);
|
hos_keygen(keyblob, kb, &tsec_ctxt);
|
||||||
|
|||||||
@@ -676,7 +676,7 @@ static lv_res_t _action_flash_linux_data(lv_obj_t * btns, const char * txt)
|
|||||||
if (pct != prevPct)
|
if (pct != prevPct)
|
||||||
{
|
{
|
||||||
lv_bar_set_value(bar, pct);
|
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);
|
lv_label_set_text(label_pct, txt_buf);
|
||||||
manual_system_maintenance(true);
|
manual_system_maintenance(true);
|
||||||
prevPct = pct;
|
prevPct = pct;
|
||||||
@@ -810,8 +810,26 @@ static lv_res_t _action_check_flash_linux(lv_obj_t *btn)
|
|||||||
{
|
{
|
||||||
if ((u64)fno.fsize % 0x400000)
|
if ((u64)fno.fsize % 0x400000)
|
||||||
{
|
{
|
||||||
lv_label_set_text(lbl_status, "#FFDD00 Error:# The image is not aligned to 4 MiB!");
|
// Check if last part.
|
||||||
goto error;
|
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;
|
l4t_flash_ctxt.image_size_sct += (u64)fno.fsize >> 9;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,15 +402,21 @@ void ipl_main()
|
|||||||
// Important: Preserve version header!
|
// Important: Preserve version header!
|
||||||
__asm__ ("" : : "" (ipl_ver));
|
__asm__ ("" : : "" (ipl_ver));
|
||||||
|
|
||||||
#if (LV_LOG_PRINTF == 1)
|
#ifdef DEBUG_UART_PORT
|
||||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
#if DEBUG_UART_PORT == UART_B
|
||||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||||
pinmux_config_uart(UART_B);
|
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||||
clock_enable_uart(UART_B);
|
#endif
|
||||||
uart_init(UART_B, 115200);
|
#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_send(DEBUG_UART_PORT, (u8 *)"hekate-NYX: Hello!\r\n", 20);
|
||||||
uart_wait_idle(UART_B, UART_TX_IDLE);
|
uart_wait_idle(DEBUG_UART_PORT, UART_TX_IDLE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize the rest of hw and load nyx's resources.
|
// Initialize the rest of hw and load nyx's resources.
|
||||||
|
|||||||
Reference in New Issue
Block a user