Compare commits

..

30 Commits

Author SHA1 Message Date
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
30 changed files with 743 additions and 191 deletions

View File

@@ -120,12 +120,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 := 3
BLVERSION_RSVD := 0
# Nyx Version.
NYXVERSION_MAJOR := 0
NYXVERSION_MINOR := 9
NYXVERSION_HOTFX := 3
NYXVERSION_HOTFX := 4
NYXVERSION_RSVD := 0

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

@@ -812,7 +812,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);

65
bdk/power/bm92t30_stub.c Normal file
View 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
View 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

View File

@@ -384,9 +384,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,85 @@
#include <soc/i2c.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[] = {
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 +114,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 +178,221 @@ 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, u32 reg)
{
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 | (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++)
{
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, 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 *)&reg, 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];
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, u32 reg, 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

@@ -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)
{
u8 *bbuf = (u8 *)buf;
bool first_reinit = false;
while (num_sectors)
u32 sct_off = sector;
u32 sct_total = num_sectors;
bool first_reinit = true;
while (sct_total)
{
u32 blkcnt = 0;
// Retry 5 times if failed.
@@ -184,7 +187,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 +204,7 @@ reinit_try:
sd_error_count_increment(SD_ERROR_RW_FAIL);
if (!first_reinit)
if (first_reinit)
res = sd_initialize(true);
else
{
@@ -210,19 +213,27 @@ reinit_try:
sd_error_count_increment(SD_ERROR_INIT_FAIL);
}
// Reset retries to a lower number.
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;
}
}
return 0;
out:
DPRINTF("readwrite: %08X\n", blkcnt);
sector += blkcnt;
num_sectors -= blkcnt;
sct_off += blkcnt;
sct_total -= 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_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];
}

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

View File

@@ -764,7 +764,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 +772,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 +966,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 +984,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)
{
@@ -1004,7 +1005,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
}
}

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

@@ -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;
}
@@ -1565,6 +1565,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

@@ -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,6 +33,7 @@ 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),
} hekate_errors_t;

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

@@ -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 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 +651,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;
}
@@ -1039,8 +1063,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

@@ -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;

View File

@@ -361,9 +361,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 +383,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

@@ -1080,9 +1080,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()
@@ -1145,7 +1146,8 @@ static void _show_errors()
if (*excp_enabled == EXCP_MAGIC)
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.
h_cfg.errors |= ERR_L4T_KERNEL;
@@ -1158,15 +1160,16 @@ 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 init 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))
{
WPRINTF("\nUpdate bootloader folder!\n\n");
}
if (h_cfg.errors & ERR_EXCEPT_ENB)
{
@@ -1316,6 +1319,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 +1471,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 +1480,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.3", 0, 0 };
extern void pivot_stack(u32 stack_top);
@@ -1493,7 +1506,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 +1545,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 \
bm92t30_stub.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

@@ -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;
}

View File

@@ -28,6 +28,7 @@
#include <mem/heap.h>
#include <mem/sdram.h>
#include <mem/smmu.h>
#include <power/bm92t30_stub.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;
@@ -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));
@@ -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));
@@ -1535,7 +1613,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 +1630,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 +1686,31 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
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_obj_set_width(lb_val2, lv_obj_get_width(val2));

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;
}

View File

@@ -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.