Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be09b68532 | ||
|
|
50eff41351 | ||
|
|
4b78198f33 | ||
|
|
dfb5640bfe | ||
|
|
f139f9c56f | ||
|
|
4f4df9ccd1 | ||
|
|
bafc6f4a1d | ||
|
|
b1110caed1 | ||
|
|
e7f72b711a | ||
|
|
0ddc1c71a8 | ||
|
|
4e7c39d6a0 | ||
|
|
72a81e7c2a | ||
|
|
2e9a89aa20 | ||
|
|
ca68818efe |
120
Makefile
120
Makefile
@@ -4,106 +4,106 @@ endif
|
||||
|
||||
include $(DEVKITARM)/base_rules
|
||||
|
||||
################################################################################
|
||||
|
||||
IPL_LOAD_ADDR := 0x40008000
|
||||
IPL_MAGIC := 0x43544349 #"ICTC"
|
||||
BLVERSION_MAJOR := 4
|
||||
BLVERSION_MINOR := 8
|
||||
BLVERSION_MINOR := 9
|
||||
BLVERSION_HOTFX := 0
|
||||
|
||||
BL_RESERVED := 0
|
||||
|
||||
################################################################################
|
||||
|
||||
TARGET := hekate
|
||||
BUILD := build
|
||||
OUTPUT := output
|
||||
BUILDDIR := build
|
||||
OUTPUTDIR := output
|
||||
SOURCEDIR = bootloader
|
||||
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
|
||||
OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
# Main and graphics.
|
||||
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
start.o \
|
||||
main.o \
|
||||
fe_emmc_tools.o \
|
||||
fe_info.o \
|
||||
fe_tools.o \
|
||||
config.o \
|
||||
btn.o \
|
||||
clock.o \
|
||||
cluster.o \
|
||||
fuse.o \
|
||||
gpio.o \
|
||||
heap.o \
|
||||
hos.o \
|
||||
hos_config.o \
|
||||
secmon_exo.o \
|
||||
sept.o \
|
||||
i2c.o \
|
||||
kfuse.o \
|
||||
bq24193.o \
|
||||
max7762x.o \
|
||||
max17050.o \
|
||||
mc.o \
|
||||
nx_emmc.o \
|
||||
sdmmc.o \
|
||||
sdmmc_driver.o \
|
||||
sdram.o \
|
||||
tui.o \
|
||||
util.o \
|
||||
di.o \
|
||||
gfx.o \
|
||||
pinmux.o \
|
||||
pkg1.o \
|
||||
pkg2.o \
|
||||
se.o \
|
||||
tsec.o \
|
||||
uart.o \
|
||||
hw_init.o \
|
||||
dirlist.o \
|
||||
ini.o \
|
||||
ianos.o \
|
||||
smmu.o \
|
||||
max77620-rtc.o \
|
||||
main.o heap.o \
|
||||
gfx.o tui.o \
|
||||
fe_emmc_tools.o fe_info.o fe_tools.o \
|
||||
)
|
||||
|
||||
OBJS += $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
# Hardware.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
clock.o cluster.o di.o gpio.o i2c.o mc.o sdram.o pinmux.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o \
|
||||
sdmmc.o sdmmc_driver.o \
|
||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||
hw_init.o \
|
||||
)
|
||||
|
||||
# Utilities.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
btn.o dirlist.o ianos.o util.o \
|
||||
config.o ini.o \
|
||||
)
|
||||
|
||||
# Horizon.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
nx_emmc.o \
|
||||
hos.o hos_config.o pkg1.o pkg2.o fss.o secmon_exo.o sept.o \
|
||||
)
|
||||
|
||||
# Libraries.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
lz.o blz.o \
|
||||
diskio.o ff.o ffunicode.o ffsystem.o \
|
||||
elfload.o elfreloc_arm.o \
|
||||
)
|
||||
|
||||
CUSTOMDEFINES := -DBLVERSIONMJ=$(BLVERSION_MAJOR) -DBLVERSIONMN=$(BLVERSION_MINOR) -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
################################################################################
|
||||
|
||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BL_RESERVED)
|
||||
CUSTOMDEFINES += -DMENU_LOGO_ENABLE
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
||||
# 0: UART_A, 1: UART_B.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=0
|
||||
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
|
||||
################################################################################
|
||||
|
||||
.PHONY: all clean $(MODULEDIRS)
|
||||
|
||||
all: $(TARGET).bin
|
||||
@echo -n "Payload size is "
|
||||
@wc -c < $(OUTPUT)/$(TARGET).bin
|
||||
@wc -c < $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "Max size is 126296 Bytes."
|
||||
|
||||
clean:
|
||||
@rm -rf $(OBJS)
|
||||
@rm -rf $(BUILD)
|
||||
@rm -rf $(OUTPUT)
|
||||
@rm -rf $(BUILDDIR)
|
||||
@rm -rf $(OUTPUTDIR)
|
||||
|
||||
$(MODULEDIRS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
||||
$(TARGET).bin: $(BUILD)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUT)/$@
|
||||
@printf ICTC$(BLVERSION_MAJOR)$(BLVERSION_MINOR) >> $(OUTPUT)/$@
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
@printf ICTC$(BLVERSION_MAJOR)$(BLVERSION_MINOR) >> $(OUTPUTDIR)/$@
|
||||
|
||||
$(BUILD)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
|
||||
$(BUILD)/$(TARGET)/%.o: %.c
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILD)/$(TARGET)/%.o: %.S
|
||||
@mkdir -p "$(BUILD)"
|
||||
@mkdir -p "$(BUILD)/$(TARGET)"
|
||||
@mkdir -p "$(OUTPUT)"
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.S
|
||||
@mkdir -p "$(BUILDDIR)"
|
||||
@mkdir -p "$(BUILDDIR)/$(TARGET)"
|
||||
@mkdir -p "$(OUTPUTDIR)"
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
16
README.md
16
README.md
@@ -20,6 +20,8 @@ Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||
| bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
|
||||
| bootloader/libtools/ | Future reserved |
|
||||
|
||||
**Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card.
|
||||
|
||||
|
||||
## Bootloader configuration
|
||||
|
||||
@@ -51,12 +53,20 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
||||
| kernel={SD path} | Replaces the kernel binary |
|
||||
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| fss0={SD path} | Takes a fusee-secondary binary and extracts all needed parts from it. |
|
||||
| kip1patch=patchname| Enables a kip1 patch. Specify with multiple lines and/or as CSV. Current available patches nosigchk. |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||
| debugmode=1 | Enables Debug mode |
|
||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||
| atmosphere=1 | Enables Atmosphère patching |
|
||||
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra signle kips.
|
||||
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Never define core kips when using `fss0` and make sure that the folder (when using `/*`), does not include them.
|
||||
|
||||
|
||||
### Payload storage:
|
||||
|
||||
@@ -67,8 +77,8 @@ Hekate now has a new storage in the binary that helps it configure it outside of
|
||||
| '0x94' boot_cfg | bit0: Force AutoBoot, bit1: Show launch log, bit2: sept run. |
|
||||
| '0x98' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
|
||||
| '0x9C' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||
| '0xA0' rsvd_cfg | Reserved. |
|
||||
| '0xA4' rsvd[32] | Reserved. |
|
||||
| '0xA0' extra_cfg | Reserved. |
|
||||
| '0xA4' rsvd[128] | Reserved. |
|
||||
|
||||
|
||||
You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
|
||||
@@ -27,12 +27,6 @@
|
||||
#include "../utils/list.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
//TODO: Create more macros (info, header, debug, etc) with different colors and utilize them for consistency.
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
extern int sd_mount();
|
||||
extern int sd_unmount();
|
||||
@@ -42,7 +36,7 @@ void set_default_configuration()
|
||||
h_cfg.autoboot = 0;
|
||||
h_cfg.autoboot_list = 0;
|
||||
h_cfg.bootwait = 3;
|
||||
h_cfg.verification = 2;
|
||||
h_cfg.verification = 1;
|
||||
h_cfg.se_keygen_done = 0;
|
||||
h_cfg.sbar_time_keeping = 0;
|
||||
h_cfg.backlight = 100;
|
||||
@@ -378,9 +372,6 @@ out2:;
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
void config_bootdelay()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
@@ -462,9 +453,9 @@ void config_verification()
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
memcpy(vr_text, " Disable (Fastest)", 19);
|
||||
memcpy(vr_text + 64, " Sparse (Fast)", 16);
|
||||
memcpy(vr_text + 128, " Full (Slow)", 16);
|
||||
memcpy(vr_text, " Disable (Fastest - Unsafe)", 28);
|
||||
memcpy(vr_text + 64, " Sparse (Fast - Safe)", 23);
|
||||
memcpy(vr_text + 128, " Full (Slow - Safe)", 23);
|
||||
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
@@ -658,5 +649,3 @@ void config_nogc()
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
@@ -31,29 +31,27 @@
|
||||
#include "../utils/btn.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
#define EMMC_BUF_ALIGNED 0xB5000000
|
||||
#define SDXC_BUF_ALIGNED 0xB6000000
|
||||
#define MIXD_BUF_ALIGNED 0xB7000000
|
||||
|
||||
extern sdmmc_t sd_sdmmc;
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
extern FATFS sd_fs;
|
||||
extern hekate_config h_cfg;
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
extern bool sd_mount();
|
||||
extern void sd_unmount();
|
||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||
|
||||
//TODO: Create more macros (info, header, debug, etc) with different colors and utilize them for consistency.
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
#define WPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, 0xFFCCCCCC)
|
||||
#define WPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, args, 0xFFCCCCCC)
|
||||
|
||||
static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFilename, emmc_part_t *part)
|
||||
{
|
||||
FIL fp;
|
||||
u8 sparseShouldVerify = 0;
|
||||
u32 btn = 0;
|
||||
u32 prevPct = 200;
|
||||
int res = 0;
|
||||
u32 sdFileSector = 0;
|
||||
|
||||
u8 hashEm[0x20];
|
||||
u8 hashSd[0x20];
|
||||
@@ -62,14 +60,10 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi
|
||||
{
|
||||
u32 totalSectorsVer = (u32)((u64)f_size(&fp) >> (u64)9);
|
||||
|
||||
u32 numSectorsPerIter = 0;
|
||||
if (totalSectorsVer > 0x200000)
|
||||
numSectorsPerIter = 8192; //4MB Cache
|
||||
else
|
||||
numSectorsPerIter = 512; //256KB Cache
|
||||
const u32 NUM_SECTORS_PER_ITER = 8192; // 4MB Cache.
|
||||
|
||||
u8 *bufEm = (u8 *)calloc(numSectorsPerIter, NX_EMMC_BLOCKSIZE);
|
||||
u8 *bufSd = (u8 *)calloc(numSectorsPerIter, NX_EMMC_BLOCKSIZE);
|
||||
u8 *bufEm = (u8 *)EMMC_BUF_ALIGNED;
|
||||
u8 *bufSd = (u8 *)SDXC_BUF_ALIGNED;
|
||||
|
||||
u32 pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
|
||||
tui_pbar(&gfx_con, 0, gfx_con.y, pct, 0xFF96FF00, 0xFF155500);
|
||||
@@ -77,53 +71,49 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi
|
||||
u32 num = 0;
|
||||
while (totalSectorsVer > 0)
|
||||
{
|
||||
num = MIN(totalSectorsVer, numSectorsPerIter);
|
||||
|
||||
if (!sdmmc_storage_read(storage, lba_curr, num, bufEm))
|
||||
num = MIN(totalSectorsVer, NUM_SECTORS_PER_ITER);
|
||||
|
||||
// Check every time or every 4.
|
||||
// Every 4 protects from fake sd, sector corruption and frequent I/O corruption.
|
||||
// Full provides all that, plus protection from extremely rare I/O corruption.
|
||||
if ((h_cfg.verification & 2) || !(sparseShouldVerify % 4))
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("\nFailed to read %d blocks (@LBA %08X),\nfrom eMMC!\n\nVerification failed..\n",
|
||||
num, lba_curr);
|
||||
if (!sdmmc_storage_read(storage, lba_curr, num, bufEm))
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("\nFailed to read %d blocks (@LBA %08X),\nfrom eMMC!\n\nVerification failed..\n",
|
||||
num, lba_curr);
|
||||
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
f_lseek(&fp, sdFileSector);
|
||||
if (f_read(&fp, bufSd, num << 9, NULL))
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("\nFailed to read %d blocks (@LBA %08X),\nfrom sd card!\n\nVerification failed..\n", num, lba_curr);
|
||||
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(bufEm);
|
||||
free(bufSd);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
if (f_read(&fp, bufSd, num << 9, NULL))
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("\nFailed to read %d blocks (@LBA %08X),\nfrom sd card!\n\nVerification failed..\n", num, lba_curr);
|
||||
|
||||
free(bufEm);
|
||||
free(bufSd);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (h_cfg.verification)
|
||||
{
|
||||
case 1:
|
||||
res = memcmp32sparse((u32 *)bufEm, (u32 *)bufSd, num << 9);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
se_calc_sha256(&hashEm, bufEm, num << 9);
|
||||
se_calc_sha256(&hashSd, bufSd, num << 9);
|
||||
se_calc_sha256(hashEm, bufEm, num << 9);
|
||||
se_calc_sha256(hashSd, bufSd, num << 9);
|
||||
res = memcmp(hashEm, hashSd, 0x10);
|
||||
break;
|
||||
}
|
||||
if (res)
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("\nSD card and eMMC data (@LBA %08X),\ndo not match!\n\nVerification failed..\n", lba_curr);
|
||||
|
||||
free(bufEm);
|
||||
free(bufSd);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
if (res)
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("\nSD and eMMC data (@LBA %08X),\ndo not match!\n\nVerification failed..\n", lba_curr);
|
||||
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
sparseShouldVerify++;
|
||||
sdFileSector += NUM_SECTORS_PER_ITER << 9;
|
||||
|
||||
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
|
||||
if (pct != prevPct)
|
||||
{
|
||||
@@ -138,19 +128,15 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi
|
||||
if ((btn & BTN_VOL_DOWN) && (btn & BTN_VOL_UP))
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
WPRINTF("\n\nThe verification was cancelled!");
|
||||
WPRINTF("\n\nVerification was cancelled!");
|
||||
EPRINTF("\nPress any key...\n");
|
||||
msleep(1500);
|
||||
msleep(1000);
|
||||
|
||||
free(bufEm);
|
||||
free(bufSd);
|
||||
f_close(&fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
free(bufEm);
|
||||
free(bufSd);
|
||||
f_close(&fp);
|
||||
|
||||
tui_pbar(&gfx_con, 0, gfx_con.y, pct, 0xFFCCCCCC, 0xFF555555);
|
||||
@@ -165,6 +151,17 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi
|
||||
}
|
||||
}
|
||||
|
||||
void _update_filename(char *outFilename, u32 sdPathLen, u32 numSplitParts, u32 currPartIdx)
|
||||
{
|
||||
if (numSplitParts >= 10 && currPartIdx < 10)
|
||||
{
|
||||
outFilename[sdPathLen] = '0';
|
||||
itoa(currPartIdx, &outFilename[sdPathLen + 1], 10);
|
||||
}
|
||||
else
|
||||
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||
}
|
||||
|
||||
static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||
{
|
||||
static const u32 FAT32_FILESIZE_LIMIT = 0xFFFFFFFF;
|
||||
@@ -195,7 +192,7 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
if ((sd_storage.csd.capacity >> (20 - sd_storage.csd.read_blkbits)) <= 8192)
|
||||
multipartSplitSize = (1u << 30);
|
||||
// Maximum parts fitting the free space available.
|
||||
maxSplitParts = (sd_fs.free_clst * sd_fs.csize) / (multipartSplitSize / 512);
|
||||
maxSplitParts = (sd_fs.free_clst * sd_fs.csize) / (multipartSplitSize / NX_EMMC_BLOCKSIZE);
|
||||
|
||||
// Check if the USER partition or the RAW eMMC fits the sd card free space.
|
||||
if (totalSectors > (sd_fs.free_clst * sd_fs.csize))
|
||||
@@ -246,28 +243,8 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
|
||||
outFilename[sdPathLen++] = '.';
|
||||
|
||||
if (!partialDumpInProgress)
|
||||
{
|
||||
outFilename[sdPathLen] = '0';
|
||||
if (numSplitParts >= 10)
|
||||
{
|
||||
outFilename[sdPathLen + 1] = '0';
|
||||
outFilename[sdPathLen + 2] = 0;
|
||||
}
|
||||
else
|
||||
outFilename[sdPathLen + 1] = 0;
|
||||
}
|
||||
// Continue from where we left, if Partial Backup in progress.
|
||||
else
|
||||
{
|
||||
if (numSplitParts >= 10 && currPartIdx < 10)
|
||||
{
|
||||
outFilename[sdPathLen] = '0';
|
||||
itoa(currPartIdx, &outFilename[sdPathLen + 1], 10);
|
||||
}
|
||||
else
|
||||
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||
}
|
||||
_update_filename(outFilename, sdPathLen, numSplitParts, partialDumpInProgress ? currPartIdx : 0);
|
||||
}
|
||||
|
||||
FIL fp;
|
||||
@@ -276,7 +253,7 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
{
|
||||
f_close(&fp);
|
||||
gfx_con.fntsz = 16;
|
||||
|
||||
|
||||
WPRINTF("An existing backup has been detected!");
|
||||
WPRINTF("Press POWER to Continue.\nPress VOL to go to the menu.\n");
|
||||
msleep(500);
|
||||
@@ -297,12 +274,9 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 numSectorsPerIter = 0;
|
||||
if (totalSectors > 0x200000)
|
||||
numSectorsPerIter = 8192;
|
||||
else
|
||||
numSectorsPerIter = 512;
|
||||
u8 *buf = (u8 *)calloc(numSectorsPerIter, NX_EMMC_BLOCKSIZE);
|
||||
const u32 NUM_SECTORS_PER_ITER = 8192;
|
||||
|
||||
u8 *buf = (u8 *)MIXD_BUF_ALIGNED;
|
||||
|
||||
u32 lba_curr = part->lba_start;
|
||||
u32 lbaStartPart = part->lba_start;
|
||||
@@ -341,18 +315,11 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
{
|
||||
EPRINTF("\nPress any key and try again...\n");
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (numSplitParts >= 10 && currPartIdx < 10)
|
||||
{
|
||||
outFilename[sdPathLen] = '0';
|
||||
itoa(currPartIdx, &outFilename[sdPathLen + 1], 10);
|
||||
}
|
||||
else
|
||||
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||
_update_filename(outFilename, sdPathLen, numSplitParts, currPartIdx);
|
||||
|
||||
// Always create partial.idx before next part, in case a fatal error occurs.
|
||||
if (isSmallSdCard)
|
||||
@@ -368,7 +335,6 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTF("\nError creating partial.idx file.\n");
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -382,7 +348,6 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
4. Select the SAME option again to continue.\n");
|
||||
gfx_con.fntsz = 16;
|
||||
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -397,7 +362,6 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("Error (%d) creating file %s.\n", res, outFilename);
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
bytesWritten = 0;
|
||||
@@ -408,7 +372,7 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
}
|
||||
|
||||
retryCount = 0;
|
||||
num = MIN(totalSectors, numSectorsPerIter);
|
||||
num = MIN(totalSectors, NUM_SECTORS_PER_ITER);
|
||||
while (!sdmmc_storage_read(storage, lba_curr, num, buf))
|
||||
{
|
||||
EPRINTFARGS("Error reading %d blocks @ LBA %08X,\nfrom eMMC (try %d), retrying...",
|
||||
@@ -422,7 +386,6 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
num, lba_curr);
|
||||
EPRINTF("\nPress any key and try again...\n");
|
||||
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
f_unlink(outFilename);
|
||||
|
||||
@@ -436,7 +399,6 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
EPRINTFARGS("\nFatal error (%d) when writing to SD Card", res);
|
||||
EPRINTF("\nPress any key and try again...\n");
|
||||
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
f_unlink(outFilename);
|
||||
|
||||
@@ -468,7 +430,6 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
EPRINTF("\nPress any key...\n");
|
||||
msleep(1500);
|
||||
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
f_unlink(outFilename);
|
||||
|
||||
@@ -478,7 +439,6 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
||||
tui_pbar(&gfx_con, 0, gfx_con.y, 100, 0xFFCCCCCC, 0xFF555555);
|
||||
|
||||
// Backup operation ended successfully.
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
|
||||
if (h_cfg.verification)
|
||||
@@ -635,20 +595,78 @@ void dump_emmc_user() { _dump_emmc_selected(PART_USER); }
|
||||
void dump_emmc_boot() { _dump_emmc_selected(PART_BOOT); }
|
||||
void dump_emmc_rawnand() { _dump_emmc_selected(PART_RAW); }
|
||||
|
||||
static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||
static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part, bool allow_multi_part)
|
||||
{
|
||||
static const u32 SECTORS_TO_MIB_COEFF = 11;
|
||||
|
||||
u32 totalSectors = part->lba_end - part->lba_start + 1;
|
||||
u32 currPartIdx = 0;
|
||||
u32 numSplitParts = 0;
|
||||
u32 lbaStartPart = part->lba_start;
|
||||
int res = 0;
|
||||
char *outFilename = sd_path;
|
||||
|
||||
u32 sdPathLen = strlen(sd_path);
|
||||
u64 fileSize = 0;
|
||||
u64 totalCheckFileSize = 0;
|
||||
gfx_con.fntsz = 8;
|
||||
|
||||
FIL fp;
|
||||
FILINFO fno;
|
||||
gfx_printf(&gfx_con, "\nFilename: %s\n", outFilename);
|
||||
|
||||
bool use_multipart = false;
|
||||
|
||||
if (allow_multi_part)
|
||||
{
|
||||
// Check to see if there is a combined file and if so then use that.
|
||||
if (f_stat(outFilename, &fno))
|
||||
{
|
||||
// If not, check if there are partial files and the total size matches.
|
||||
gfx_printf(&gfx_con, "\nFile not found, checking for part files.\n");
|
||||
|
||||
// Store console pos, so we dont take too much room.
|
||||
gfx_con_getpos(&gfx_con, &gfx_con.savedx, &gfx_con.savedy);
|
||||
|
||||
outFilename[sdPathLen++] = '.';
|
||||
|
||||
// Stat total size of the part files.
|
||||
while ((u32)((u64)totalCheckFileSize >> (u64)9) != totalSectors)
|
||||
{
|
||||
_update_filename(outFilename, sdPathLen, 99, numSplitParts);
|
||||
|
||||
gfx_con_setpos(&gfx_con, gfx_con.savedx, gfx_con.savedy);
|
||||
gfx_printf(&gfx_con, "\nFilename: %s\n", outFilename);
|
||||
|
||||
if (f_stat(outFilename, &fno))
|
||||
{
|
||||
WPRINTFARGS("Error (%d) file not found '%s'. Aborting...\n", res, outFilename);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
totalCheckFileSize += (u64)fno.fsize;
|
||||
|
||||
numSplitParts++;
|
||||
}
|
||||
|
||||
gfx_printf(&gfx_con, "\n%X sectors total.\n", (u32)((u64)totalCheckFileSize >> (u64)9));
|
||||
|
||||
if ((u32)((u64)totalCheckFileSize >> (u64)9) != totalSectors)
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTF("Size of SD Card split backups does not match,\neMMC's selected part size.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
use_multipart = true;
|
||||
_update_filename(outFilename, sdPathLen, numSplitParts, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx_con_setpos(&gfx_con, gfx_con.savedx, gfx_con.savedy);
|
||||
|
||||
res = f_open(&fp, outFilename, FA_READ);
|
||||
if (res)
|
||||
{
|
||||
@@ -660,8 +678,7 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
|
||||
|
||||
return 0;
|
||||
}
|
||||
//TODO: Should we keep this check?
|
||||
else if (((u32)((u64)f_size(&fp) >> (u64)9)) != totalSectors)
|
||||
else if (!use_multipart && (((u32)((u64)f_size(&fp) >> (u64)9)) != totalSectors)) // Check total restore size vs emmc size.
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTF("Size of the SD Card backup does not match,\neMMC's selected part size.\n");
|
||||
@@ -670,15 +687,15 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
gfx_printf(&gfx_con, "\nTotal restore size: %d MiB.\n\n", ((u32)((u64)f_size(&fp) >> (u64)9)) >> SECTORS_TO_MIB_COEFF);
|
||||
{
|
||||
fileSize = (u64)f_size(&fp);
|
||||
gfx_printf(&gfx_con, "\nTotal restore size: %d MiB.\n\n",
|
||||
((u32)((use_multipart ? ((u64)totalCheckFileSize >> (u64)9) : fileSize) >> (u64)9)) >> SECTORS_TO_MIB_COEFF);
|
||||
}
|
||||
|
||||
u32 numSectorsPerIter = 0;
|
||||
if (totalSectors > 0x200000)
|
||||
numSectorsPerIter = 8192; //4MB Cache
|
||||
else
|
||||
numSectorsPerIter = 512; //256KB Cache
|
||||
const u32 NUM_SECTORS_PER_ITER = 8192; // 4MB Cache.
|
||||
|
||||
u8 *buf = (u8 *)calloc(numSectorsPerIter, NX_EMMC_BLOCKSIZE);
|
||||
u8 *buf = (u8 *)MIXD_BUF_ALIGNED;
|
||||
|
||||
u32 lba_curr = part->lba_start;
|
||||
u32 bytesWritten = 0;
|
||||
@@ -687,10 +704,53 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
|
||||
|
||||
u32 num = 0;
|
||||
u32 pct = 0;
|
||||
|
||||
gfx_con_getpos(&gfx_con, &gfx_con.savedx, &gfx_con.savedy);
|
||||
|
||||
while (totalSectors > 0)
|
||||
{
|
||||
// If we have more than one part, check the size for the split parts and make sure that the bytes written is not more than that.
|
||||
if (numSplitParts != 0 && bytesWritten >= fileSize)
|
||||
{
|
||||
// If we have more bytes written then close the file pointer and increase the part index we are using
|
||||
f_close(&fp);
|
||||
memset(&fp, 0, sizeof(fp));
|
||||
currPartIdx++;
|
||||
|
||||
if (h_cfg.verification)
|
||||
{
|
||||
// Verify part.
|
||||
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
|
||||
{
|
||||
EPRINTF("\nPress any key and try again...\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
_update_filename(outFilename, sdPathLen, numSplitParts, currPartIdx);
|
||||
|
||||
// Read from next part.
|
||||
gfx_con_setpos(&gfx_con, gfx_con.savedx, gfx_con.savedy);
|
||||
gfx_printf(&gfx_con, "Filename: %s\n\n", outFilename);
|
||||
|
||||
lbaStartPart = lba_curr;
|
||||
|
||||
// Try to open the next file part
|
||||
res = f_open(&fp, outFilename, FA_READ);
|
||||
if (res)
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTFARGS("Error (%d) opening file %s.\n", res, outFilename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
fileSize = (u64)f_size(&fp);
|
||||
bytesWritten = 0;
|
||||
}
|
||||
|
||||
retryCount = 0;
|
||||
num = MIN(totalSectors, numSectorsPerIter);
|
||||
num = MIN(totalSectors, NUM_SECTORS_PER_ITER);
|
||||
|
||||
res = f_read(&fp, buf, NX_EMMC_BLOCKSIZE * num, NULL);
|
||||
if (res)
|
||||
@@ -699,7 +759,6 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
|
||||
EPRINTFARGS("\nFatal error (%d) when reading from SD Card", res);
|
||||
EPRINTF("\nYour device may be in an inoperative state!\n\nPress any key and try again now...\n");
|
||||
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
return 0;
|
||||
}
|
||||
@@ -716,7 +775,6 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
|
||||
num, lba_curr);
|
||||
EPRINTF("\nYour device may be in an inoperative state!\n\nPress any key and try again...\n");
|
||||
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
return 0;
|
||||
}
|
||||
@@ -735,7 +793,6 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
|
||||
tui_pbar(&gfx_con, 0, gfx_con.y, 100, 0xFFCCCCCC, 0xFF555555);
|
||||
|
||||
// Restore operation ended successfully.
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
|
||||
if (h_cfg.verification)
|
||||
@@ -765,7 +822,7 @@ static void _restore_emmc_selected(emmcPartType_t restoreType)
|
||||
tui_sbar(&gfx_con, true);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
gfx_printf(&gfx_con, "%kThis is a dangerous operation\nand may render your device inoperative!\n\n", 0xFFFFDD00);
|
||||
gfx_printf(&gfx_con, "%kThis may render your device inoperative!\n\n", 0xFFFFDD00);
|
||||
gfx_printf(&gfx_con, "Are you really sure?\n\n%k", 0xFFCCCCCC);
|
||||
if ((restoreType & PART_BOOT) || (restoreType & PART_GP_ALL))
|
||||
{
|
||||
@@ -777,13 +834,13 @@ static void _restore_emmc_selected(emmcPartType_t restoreType)
|
||||
}
|
||||
gfx_con_getpos(&gfx_con, &gfx_con.savedx, &gfx_con.savedy);
|
||||
|
||||
u8 value = 10;
|
||||
while (value > 0)
|
||||
u8 failsafe_wait = 10;
|
||||
while (failsafe_wait > 0)
|
||||
{
|
||||
gfx_con_setpos(&gfx_con, gfx_con.savedx, gfx_con.savedy);
|
||||
gfx_printf(&gfx_con, "%kWait... (%ds) %k", 0xFF888888, value, 0xFFCCCCCC);
|
||||
gfx_printf(&gfx_con, "%kWait... (%ds) %k", 0xFF888888, failsafe_wait, 0xFFCCCCCC);
|
||||
msleep(1000);
|
||||
value--;
|
||||
failsafe_wait--;
|
||||
}
|
||||
gfx_con_setpos(&gfx_con, gfx_con.savedx, gfx_con.savedy);
|
||||
|
||||
@@ -828,7 +885,7 @@ static void _restore_emmc_selected(emmcPartType_t restoreType)
|
||||
sdmmc_storage_set_mmc_partition(&storage, i + 1);
|
||||
|
||||
emmcsn_path_impl(sdPath, "/restore", bootPart.name, &storage);
|
||||
res = _restore_emmc_part(sdPath, &storage, &bootPart);
|
||||
res = _restore_emmc_part(sdPath, &storage, &bootPart, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,7 +901,7 @@ static void _restore_emmc_selected(emmcPartType_t restoreType)
|
||||
part->name, part->lba_start, part->lba_end, 0xFFCCCCCC);
|
||||
|
||||
emmcsn_path_impl(sdPath, "/restore/partitions/", part->name, &storage);
|
||||
res = _restore_emmc_part(sdPath, &storage, part);
|
||||
res = _restore_emmc_part(sdPath, &storage, part, false);
|
||||
}
|
||||
nx_emmc_gpt_free(&gpt);
|
||||
}
|
||||
@@ -864,7 +921,7 @@ static void _restore_emmc_selected(emmcPartType_t restoreType)
|
||||
rawPart.name, rawPart.lba_start, rawPart.lba_end, 0xFFCCCCCC);
|
||||
|
||||
emmcsn_path_impl(sdPath, "/restore", rawPart.name, &storage);
|
||||
res = _restore_emmc_part(sdPath, &storage, &rawPart);
|
||||
res = _restore_emmc_part(sdPath, &storage, &rawPart, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
#include "../utils/btn.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
extern FATFS sd_fs;
|
||||
|
||||
@@ -48,15 +46,6 @@ extern void sd_unmount();
|
||||
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||
|
||||
//TODO: Create more macros (info, header, debug, etc) with different colors and utilize them for consistency.
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
#define WPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, 0xFFCCCCCC)
|
||||
#define WPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, args, 0xFFCCCCCC)
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
void print_fuseinfo()
|
||||
{
|
||||
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
|
||||
@@ -691,5 +680,3 @@ void bootrom_ipatches_info()
|
||||
btn_wait();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
@@ -36,22 +36,14 @@
|
||||
#include "../utils/btn.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
extern boot_cfg_t *b_cfg;
|
||||
extern boot_cfg_t b_cfg;
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
|
||||
extern bool sd_mount();
|
||||
extern void sd_unmount();
|
||||
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||
|
||||
//TODO: Create more macros (info, header, debug, etc) with different colors and utilize them for consistency.
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
|
||||
void dump_packages12()
|
||||
{
|
||||
if (!sd_mount())
|
||||
@@ -100,8 +92,8 @@ void dump_packages12()
|
||||
|
||||
if (kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
||||
{
|
||||
b_cfg->autoboot = 0;
|
||||
b_cfg->autoboot_list = 0;
|
||||
b_cfg.autoboot = 0;
|
||||
b_cfg.autoboot_list = 0;
|
||||
|
||||
gfx_printf(&gfx_con, "sept will run to get the keys.\nThen rerun this option.");
|
||||
btn_wait();
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
|
||||
#include "../../common/common_gfx.h"
|
||||
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
#define WPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, 0xFFCCCCCC)
|
||||
#define WPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, args, 0xFFCCCCCC)
|
||||
|
||||
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride);
|
||||
void gfx_clear_grey(gfx_ctxt_t *ctxt, u8 color);
|
||||
void gfx_clear_partial_grey(gfx_ctxt_t *ctxt, u8 color, u32 pos_x, u32 height);
|
||||
@@ -43,4 +48,8 @@ void gfx_set_rect_rgb(gfx_ctxt_t *ctxt, const u8 *buf, u32 size_x, u32 size_y, u
|
||||
void gfx_set_rect_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
void gfx_render_bmp_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
|
||||
// Global gfx console and context.
|
||||
gfx_ctxt_t gfx_ctxt;
|
||||
gfx_con_t gfx_con;
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
127
bootloader/hos/fss.c
Normal file
127
bootloader/hos/fss.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Atmosphère Fusée Secondary Storage parser.
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "fss.h"
|
||||
#include "hos.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../mem/heap.h"
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
#define DPRINTF(...)
|
||||
|
||||
#define FSS0_MAGIC 0x30535346
|
||||
#define CNT_TYPE_FSP 0
|
||||
#define CNT_TYPE_EXO 1
|
||||
#define CNT_TYPE_WBT 2
|
||||
#define CNT_TYPE_RBT 3
|
||||
#define CNT_TYPE_SP1 4
|
||||
#define CNT_TYPE_SP2 5
|
||||
#define CNT_TYPE_KIP 6
|
||||
#define CNT_TYPE_BMP 7
|
||||
|
||||
typedef struct _fss_t
|
||||
{
|
||||
u32 magic;
|
||||
u32 size;
|
||||
u32 crt0_off;
|
||||
u32 cnt_off;
|
||||
u32 cnt_count;
|
||||
u32 hos_ver;
|
||||
u32 version;
|
||||
u32 git_rev;
|
||||
} fss_t;
|
||||
|
||||
typedef struct _fss_content_t
|
||||
{
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u32 type;
|
||||
u32 rsvd1;
|
||||
char name[0x10];
|
||||
} fss_content_t;
|
||||
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
|
||||
void *fss = malloc(f_size(&fp));
|
||||
// Read header.
|
||||
f_read(&fp, fss, 0x400, NULL);
|
||||
|
||||
u32 fss_entry = *(u32 *)(fss + 4);
|
||||
fss_t *fss_meta = (fss_t *)(fss + fss_entry);
|
||||
|
||||
if (fss_meta->magic == FSS0_MAGIC)
|
||||
{
|
||||
gfx_printf(&gfx_con, "Found FSS0, Atmosphere %d.%d.%d-%08x\n"
|
||||
"Max HOS supported: %d.%d.%d\n"
|
||||
"Unpacking and loading components.. ",
|
||||
fss_meta->version >> 24, (fss_meta->version >> 16) & 0xFF, (fss_meta->version >> 8) & 0xFF, fss_meta->git_rev,
|
||||
fss_meta->hos_ver >> 24, (fss_meta->hos_ver >> 16) & 0xFF, (fss_meta->hos_ver >> 8) & 0xFF);
|
||||
|
||||
fss_content_t *curr_fss_cnt = (fss_content_t *)(fss + fss_meta->cnt_off);
|
||||
void *content;
|
||||
for (int i = 0; i < fss_meta->cnt_count; i++)
|
||||
{
|
||||
content = (void *)(fss + curr_fss_cnt[i].offset);
|
||||
if ((curr_fss_cnt[i].offset + curr_fss_cnt[i].size) > fss_meta->size)
|
||||
continue;
|
||||
|
||||
// Load content to launch context.
|
||||
switch (curr_fss_cnt[i].type)
|
||||
{
|
||||
case CNT_TYPE_KIP:;
|
||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||
mkip1->kip1 = content;
|
||||
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||
DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size);
|
||||
break;
|
||||
case CNT_TYPE_EXO:
|
||||
ctxt->secmon_size = curr_fss_cnt[i].size;
|
||||
ctxt->secmon = content;
|
||||
break;
|
||||
case CNT_TYPE_WBT:
|
||||
ctxt->warmboot_size = curr_fss_cnt[i].size;
|
||||
ctxt->warmboot = content;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
// TODO: add more types?
|
||||
// case CNT_TYPE_SP1:
|
||||
// case CNT_TYPE_SP2:
|
||||
}
|
||||
|
||||
f_lseek(&fp, curr_fss_cnt[i].offset);
|
||||
f_read(&fp, content, curr_fss_cnt[i].size, NULL);
|
||||
}
|
||||
|
||||
gfx_printf(&gfx_con, "Done!\n");
|
||||
f_close(&fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
free(fss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
24
bootloader/hos/fss.h
Normal file
24
bootloader/hos/fss.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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 _FSS_H_
|
||||
#define _FSS_H_
|
||||
|
||||
#include "hos.h"
|
||||
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *value);
|
||||
|
||||
#endif
|
||||
@@ -39,12 +39,8 @@
|
||||
#include "../storage/nx_emmc.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
extern boot_cfg_t *b_cfg;
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
extern void sd_unmount();
|
||||
@@ -52,10 +48,11 @@ extern void sd_unmount();
|
||||
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
#define SECMON_MB_ADDR 0x40002EF8
|
||||
#define SECMON7_MB_ADDR 0x400000F8
|
||||
#define PKG2_LOAD_ADDR 0xA9800000
|
||||
|
||||
// Secmon mailbox.
|
||||
#define SECMON_MB_ADDR 0x40002EF8
|
||||
#define SECMON7_MB_ADDR 0x400000F8
|
||||
typedef struct _secmon_mailbox_t
|
||||
{
|
||||
// < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
|
||||
@@ -207,7 +204,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
// We rely on racing conditions, make sure we cover even the unluckiest cases.
|
||||
if (retries > 15)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%k\nFailed to get TSEC keys. Please try again.%k\n\n", 0xFFFF0000, 0xFFCCCCCC);
|
||||
EPRINTF("\nFailed to get TSEC keys. Please try again.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -308,7 +305,7 @@ static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
|
||||
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
|
||||
if (!ctxt->pkg1_id)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kUnknown pkg1 version.%k\n", 0xFFFF0000, 0xFFCCCCCC);
|
||||
EPRINTF("Unknown pkg1 version.");
|
||||
goto out;
|
||||
}
|
||||
gfx_printf(&gfx_con, "Identified pkg1 and Keyblob %d\n\n", ctxt->pkg1_id->kb);
|
||||
@@ -388,6 +385,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
volatile secmon_mailbox_t *secmon_mb;
|
||||
|
||||
memset(&ctxt, 0, sizeof(launch_ctxt_t));
|
||||
memset(&tsec_ctxt, 0, sizeof(tsec_ctxt_t));
|
||||
list_init(&ctxt.kip1_list);
|
||||
|
||||
if (!gfx_con.mute)
|
||||
@@ -443,7 +441,10 @@ int hos_launch(ini_sec_t *cfg)
|
||||
gfx_printf(&gfx_con, "Decrypted & unpacked pkg1\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("No mandatory secmon or warmboot provided!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace 'warmboot.bin' if requested.
|
||||
@@ -453,7 +454,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
{
|
||||
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kNo warmboot provided!%k\n", 0xFFFF0000, 0xFFCCCCCC);
|
||||
EPRINTF("No warmboot provided!");
|
||||
return 0;
|
||||
}
|
||||
// Else we patch it to allow downgrading.
|
||||
@@ -545,7 +546,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
const char* unappliedPatch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
|
||||
if (unappliedPatch != NULL)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kFailed to apply '%s'!%k\n", 0xFFFF0000, unappliedPatch, 0xFFCCCCCC);
|
||||
EPRINTFARGS("Failed to apply '%s'!", unappliedPatch);
|
||||
sd_unmount(); // Just exiting is not enough until pkg2_patch_kips stops modifying the string passed into it.
|
||||
|
||||
_free_launch_components(&ctxt);
|
||||
@@ -553,7 +554,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
}
|
||||
|
||||
// Rebuild and encrypt package2.
|
||||
pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info);
|
||||
pkg2_build_encrypt((void *)PKG2_LOAD_ADDR, ctxt.kernel, ctxt.kernel_size, &kip1_info);
|
||||
|
||||
gfx_printf(&gfx_con, "Rebuilt & loaded pkg2\n");
|
||||
|
||||
@@ -609,7 +610,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
|
||||
// Config Exosphère if booting full Atmosphère.
|
||||
if (ctxt.atmosphere && ctxt.secmon)
|
||||
config_exosphere(ctxt.pkg1_id->id, ctxt.pkg1_id->kb, (void *)ctxt.pkg1_id->warmboot_base, ctxt.pkg1, ctxt.debugmode);
|
||||
config_exosphere(ctxt.pkg1_id->id, ctxt.pkg1_id->kb, (void *)ctxt.pkg1_id->warmboot_base, ctxt.pkg1);
|
||||
|
||||
// Unmount SD card.
|
||||
sd_unmount();
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
#include "hos.h"
|
||||
#include "hos_config.h"
|
||||
#include "fss.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../utils/dirlist.h"
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
@@ -126,36 +126,6 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_svcperm(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Disabled SVC verification\n");
|
||||
ctxt->svcperm = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_debugmode(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Enabled Debug mode\n");
|
||||
ctxt->debugmode = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Enabled atmosphere patching\n");
|
||||
ctxt->atmosphere = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int config_kip1patch(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
@@ -186,6 +156,41 @@ int config_kip1patch(launch_ctxt_t *ctxt, const char *value)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_svcperm(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Disabled SVC verification\n");
|
||||
ctxt->svcperm = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_debugmode(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Enabled Debug mode\n");
|
||||
ctxt->debugmode = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Enabled atmosphere patching\n");
|
||||
ctxt->atmosphere = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_fss(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
return parse_fss(ctxt, value);
|
||||
}
|
||||
|
||||
typedef struct _cfg_handler_t
|
||||
{
|
||||
const char *key;
|
||||
@@ -201,6 +206,7 @@ static const cfg_handler_t _config_handlers[] = {
|
||||
{ "fullsvcperm", _config_svcperm },
|
||||
{ "debugmode", _config_debugmode },
|
||||
{ "atmosphere", _config_atmosphere },
|
||||
{ "fss0", _config_fss },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#include "../sec/se.h"
|
||||
#include "../utils/aarch64_util.h"
|
||||
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
#define _NOPv7() 0xE320F000
|
||||
|
||||
#define SM_100_ADR 0x4002B020
|
||||
|
||||
@@ -26,11 +26,6 @@
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
/*#include "util.h"
|
||||
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DEBUG_PRINTING*/
|
||||
@@ -982,5 +977,3 @@ DPRINTF("INI1 encrypted\n");
|
||||
memset(hdr->ctr, 0 , 0x10);
|
||||
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "hos.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../soc/fuse.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
#include "../utils/types.h"
|
||||
|
||||
@@ -47,7 +48,7 @@ typedef struct _atm_meta_t
|
||||
#define EXO_FLAG_DBG_PRIV (1 << 1)
|
||||
#define EXO_FLAG_DBG_USER (1 << 2)
|
||||
|
||||
void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool debug)
|
||||
void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1)
|
||||
{
|
||||
u32 exoFwNo = 0;
|
||||
u32 exoFlags = 0;
|
||||
@@ -74,8 +75,8 @@ void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool d
|
||||
if (kb == KB_FIRMWARE_VERSION_620)
|
||||
exoFlags |= EXO_FLAG_620_KGN;
|
||||
|
||||
if (debug)
|
||||
exoFlags |= EXO_FLAG_DBG_PRIV;
|
||||
// To avoid problems, make private debug mode always on.
|
||||
exoFlags |= EXO_FLAG_DBG_PRIV;
|
||||
|
||||
// Set mailbox values.
|
||||
exo_cfg_depr->magic = EXO_MAGIC_VAL;
|
||||
@@ -87,6 +88,7 @@ void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool d
|
||||
exo_cfg_depr->flags = exoFlags;
|
||||
exo_cfg->flags = exoFlags;
|
||||
|
||||
// If warmboot is lp0fw, add in RSA modulus.
|
||||
volatile wb_cfg_t *wb_cfg = (wb_cfg_t *)(warmboot + ATM_WB_HEADER_OFF);
|
||||
|
||||
if (wb_cfg->magic == ATM_WB_MAGIC)
|
||||
@@ -104,8 +106,11 @@ void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool d
|
||||
sdmmc_storage_read(&storage, 1, 1, rsa_mod);
|
||||
sdmmc_storage_end(&storage);
|
||||
|
||||
// Patch AutoRCM.
|
||||
rsa_mod[0x10] = 0xF7;
|
||||
// Patch AutoRCM out.
|
||||
if ((fuse_read_odm(4) & 3) != 3)
|
||||
rsa_mod[0x10] = 0xF7;
|
||||
else
|
||||
rsa_mod[0x10] = 0x37;
|
||||
|
||||
memcpy(warmboot + 0x10, rsa_mod + 0x10, 0x100);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool debug);
|
||||
void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,10 +31,8 @@
|
||||
#include "../utils/types.h"
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
extern gfx_con_t gfx_con;
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
|
||||
#define RELOC_META_OFF 0x7C
|
||||
#define PATCHED_RELOC_SZ 0x94
|
||||
|
||||
#define WB_RST_ADDR 0x40010ED0
|
||||
@@ -55,21 +53,31 @@ u8 warmboot_reboot[] = {
|
||||
#define SEPT_PRI_ADDR 0x4003F000
|
||||
|
||||
#define SEPT_PK1T_ADDR 0xC0400000
|
||||
#define SEPT_PK1T_STACK 0x40008000
|
||||
#define SEPT_TCSZ_ADDR (SEPT_PK1T_ADDR - 0x4)
|
||||
#define SEPT_STG1_ADDR (SEPT_PK1T_ADDR + 0x2E100)
|
||||
#define SEPT_STG2_ADDR (SEPT_PK1T_ADDR + 0x60E0)
|
||||
#define SEPT_PKG_SZ (0x2F100 + WB_RST_SIZE)
|
||||
|
||||
extern boot_cfg_t *b_cfg;
|
||||
extern boot_cfg_t b_cfg;
|
||||
extern hekate_config h_cfg;
|
||||
extern const volatile ipl_ver_meta_t ipl_ver;
|
||||
|
||||
extern void *sd_file_read(char *path);
|
||||
extern void sd_mount();
|
||||
extern void sd_unmount();
|
||||
extern bool is_ipl_updated(void *buf);
|
||||
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
||||
|
||||
void check_sept()
|
||||
{
|
||||
// Check if non-hekate payload is used for sept and restore it.
|
||||
if (h_cfg.sept_run && !f_stat("sept/payload.bak", NULL))
|
||||
{
|
||||
f_unlink("sept/payload.bin");
|
||||
f_rename("sept/payload.bak", "sept/payload.bin");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *pkg1 = (u8 *)calloc(1, 0x40000);
|
||||
|
||||
sdmmc_storage_t storage;
|
||||
@@ -133,25 +141,41 @@ int reboot_to_sept(const u8 *tsec_fw)
|
||||
}
|
||||
f_close(&fp);
|
||||
|
||||
// Save auto boot config to payload, if any.
|
||||
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
||||
memcpy(tmp_cfg, b_cfg, sizeof(boot_cfg_t));
|
||||
b_cfg.boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN);
|
||||
|
||||
tmp_cfg->boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN);
|
||||
|
||||
if (f_open(&fp, "sept/payload.bin", FA_READ | FA_WRITE))
|
||||
goto error;
|
||||
|
||||
u32 magic;
|
||||
f_lseek(&fp, f_size(&fp) - 6);
|
||||
f_read(&fp, &magic, 4, NULL);
|
||||
if (magic == 0x43544349)
|
||||
bool update_sept_payload = true;
|
||||
if (!f_open(&fp, "sept/payload.bin", FA_READ | FA_WRITE))
|
||||
{
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ);
|
||||
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
|
||||
ipl_ver_meta_t tmp_ver;
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
||||
f_read(&fp, &tmp_ver, sizeof(ipl_ver_meta_t), NULL);
|
||||
|
||||
if (tmp_ver.magic == ipl_ver.magic)
|
||||
{
|
||||
if (tmp_ver.version == ipl_ver.version)
|
||||
{
|
||||
// Save auto boot config to sept payload, if any.
|
||||
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
||||
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ);
|
||||
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
|
||||
f_close(&fp);
|
||||
update_sept_payload = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
f_rename("sept/payload.bin", "sept/payload.bak"); // Backup foreign payload.
|
||||
|
||||
f_close(&fp);
|
||||
}
|
||||
|
||||
if (update_sept_payload)
|
||||
{
|
||||
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
|
||||
f_open(&fp, "sept/payload.bin", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_write(&fp, (u8 *)reloc->start, reloc->end - reloc->start, NULL);
|
||||
f_close(&fp);
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
sd_unmount();
|
||||
|
||||
@@ -172,8 +196,6 @@ int reboot_to_sept(const u8 *tsec_fw)
|
||||
|
||||
(*sept)();
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
EPRINTF("Failed to run sept\n");
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#define IRAM_LIB_ADDR 0x4002B000
|
||||
#define DRAM_LIB_ADDR 0xE0000000
|
||||
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
extern heap_t _heap;
|
||||
|
||||
extern void *sd_file_read(char *path);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "../../gfx/gfx.h"
|
||||
extern gfx_con_t gfx_con;
|
||||
#define EL_DEBUG(format, ...) \
|
||||
gfx_printf(&gfx_con, format __VA_OPT__(, ) __VA_ARGS__)
|
||||
#else
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "../../storage/sdmmc.h"
|
||||
|
||||
#define SDMMC_UPPER_BUFFER 0xB8000000
|
||||
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
|
||||
DSTATUS disk_status (
|
||||
@@ -36,7 +38,7 @@ DRESULT disk_read (
|
||||
{
|
||||
if ((u32)buff >= 0x90000000)
|
||||
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
|
||||
u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere.
|
||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere.
|
||||
if (sdmmc_storage_read(&sd_storage, sector, count, buf))
|
||||
{
|
||||
memcpy(buff, buf, 512 * count);
|
||||
@@ -54,7 +56,7 @@ DRESULT disk_write (
|
||||
{
|
||||
if ((u32)buff >= 0x90000000)
|
||||
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||
u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere.
|
||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere.
|
||||
memcpy(buf, buff, 512 * count);
|
||||
if (sdmmc_storage_write(&sd_storage, sector, count, buf))
|
||||
return RES_OK;
|
||||
|
||||
@@ -23,10 +23,8 @@
|
||||
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#include "diskio.h" /* Declarations of device I/O functions */
|
||||
|
||||
#include "../../gfx/gfx.h"
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||
//#define EFSPRINTF(...)
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ SECTIONS {
|
||||
. = __ipl_start;
|
||||
.text : {
|
||||
*(.text._start);
|
||||
. = . + 36;
|
||||
*(._boot_cfg);
|
||||
*(._ipl_version);
|
||||
*(.text*);
|
||||
}
|
||||
.data : {
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "rtc/max77620-rtc.h"
|
||||
#include "soc/hw_init.h"
|
||||
#include "soc/i2c.h"
|
||||
#include "soc/pmc.h"
|
||||
#include "soc/t210.h"
|
||||
#include "soc/uart.h"
|
||||
#include "storage/sdmmc.h"
|
||||
@@ -48,16 +47,6 @@
|
||||
#include "frontend/fe_tools.h"
|
||||
#include "frontend/fe_info.h"
|
||||
|
||||
//TODO: ugly.
|
||||
gfx_ctxt_t gfx_ctxt;
|
||||
gfx_con_t gfx_con;
|
||||
|
||||
//TODO: Create more macros (info, header, debug, etc) with different colors and utilize them for consistency.
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
#define WPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, 0xFFCCCCCC)
|
||||
#define WPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFFDD00, args, 0xFFCCCCCC)
|
||||
|
||||
//TODO: ugly.
|
||||
sdmmc_t sd_sdmmc;
|
||||
sdmmc_storage_t sd_storage;
|
||||
@@ -68,8 +57,14 @@ static bool sd_mounted;
|
||||
u8 *Kc_MENU_LOGO;
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
boot_cfg_t *b_cfg;
|
||||
hekate_config h_cfg;
|
||||
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;
|
||||
const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver = {
|
||||
.magic = BL_MAGIC,
|
||||
.version = (BL_VER_MJ + '0') | ((BL_VER_MN + '0') << 8) | ((BL_VER_HF + '0') << 16),
|
||||
.rsvd0 = 0,
|
||||
.rsvd1 = 0
|
||||
};
|
||||
|
||||
bool sd_mount()
|
||||
{
|
||||
@@ -120,10 +115,12 @@ void *sd_file_read(char *path)
|
||||
u8 *ptr = buf;
|
||||
while (size > 0)
|
||||
{
|
||||
u32 rsize = MIN(size, 512 * 512);
|
||||
u32 rsize = MIN(size, 512 * 8192);
|
||||
if (f_read(&fp, ptr, rsize, NULL) != FR_OK)
|
||||
{
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -193,56 +190,6 @@ void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t
|
||||
sdmmc_storage_end(&storage2);
|
||||
}
|
||||
|
||||
void panic(u32 val)
|
||||
{
|
||||
// Set panic code.
|
||||
PMC(APBDEV_PMC_SCRATCH200) = val;
|
||||
//PMC(APBDEV_PMC_CRYPTO_OP) = 1; // Disable SE.
|
||||
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
|
||||
TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN;
|
||||
TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN;
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void reboot_normal()
|
||||
{
|
||||
sd_unmount();
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
display_end();
|
||||
panic(0x21); // Bypass fuse programming in package1.
|
||||
}
|
||||
|
||||
void reboot_rcm()
|
||||
{
|
||||
sd_unmount();
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
display_end();
|
||||
PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm.
|
||||
PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;
|
||||
while (true)
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
void power_off()
|
||||
{
|
||||
sd_unmount();
|
||||
|
||||
// Stop the alarm, in case we injected and powered off too fast.
|
||||
max77620_rtc_stop_alarm();
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
//TODO: we should probably make sure all regulators are powered off properly.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
|
||||
}
|
||||
|
||||
void check_power_off_from_hos()
|
||||
{
|
||||
// Power off on AutoRCM wakeup from HOS shutdown. For modchips/dongles.
|
||||
@@ -263,7 +210,7 @@ void check_power_off_from_hos()
|
||||
|
||||
display_backlight_brightness(10, 5000);
|
||||
display_backlight_brightness(100, 25000);
|
||||
usleep(600000);
|
||||
msleep(600);
|
||||
display_backlight_brightness(0, 20000);
|
||||
}
|
||||
power_off();
|
||||
@@ -271,44 +218,53 @@ void check_power_off_from_hos()
|
||||
}
|
||||
|
||||
// This is a safe and unused DRAM region for our payloads.
|
||||
// IPL_LOAD_ADDR is defined in makefile.
|
||||
#define EXT_PAYLOAD_ADDR 0xC03C0000
|
||||
#define PATCHED_RELOC_SZ 0x94
|
||||
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
#define PAYLOAD_ENTRY 0x40010000
|
||||
#define CBFS_SDRAM_EN_ADDR 0x4003e000
|
||||
#define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
||||
|
||||
void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;
|
||||
void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR;
|
||||
#define RELOC_META_OFF 0x7C
|
||||
#define PATCHED_RELOC_SZ 0x94
|
||||
#define PATCHED_RELOC_STACK 0x40007000
|
||||
#define PATCHED_RELOC_ENTRY 0x40010000
|
||||
#define EXT_PAYLOAD_ADDR 0xC03C0000
|
||||
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
#define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
||||
#define CBFS_DRAM_EN_ADDR 0x4003e000
|
||||
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
|
||||
|
||||
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
||||
{
|
||||
static const u32 START_OFF = 0x7C;
|
||||
static const u32 STACK_OFF = 0x80;
|
||||
static const u32 PAYLOAD_END_OFF = 0x84;
|
||||
static const u32 IPL_START_OFF = 0x88;
|
||||
|
||||
memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);
|
||||
|
||||
*(vu32 *)(payload_src + START_OFF) = payload_dst - ALIGN(PATCHED_RELOC_SZ, 0x10);
|
||||
*(vu32 *)(payload_src + PAYLOAD_END_OFF) = payload_dst + payload_size;
|
||||
*(vu32 *)(payload_src + STACK_OFF) = 0x40008000;
|
||||
*(vu32 *)(payload_src + IPL_START_OFF) = payload_dst;
|
||||
volatile reloc_meta_t *relocator = (reloc_meta_t *)(payload_src + RELOC_META_OFF);
|
||||
|
||||
relocator->start = payload_dst - ALIGN(PATCHED_RELOC_SZ, 0x10);
|
||||
relocator->stack = PATCHED_RELOC_STACK;
|
||||
relocator->end = payload_dst + payload_size;
|
||||
relocator->ep = payload_dst;
|
||||
|
||||
if (payload_size == 0x7000)
|
||||
{
|
||||
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
|
||||
*(vu32 *)CBFS_SDRAM_EN_ADDR = 0x4452414D;
|
||||
*(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC;
|
||||
}
|
||||
}
|
||||
|
||||
#define BOOTLOADER_UPDATED_MAGIC 0x424F4F54 // "BOOT".
|
||||
#define BOOTLOADER_UPDATED_MAGIC_ADDR 0x4003E000
|
||||
bool is_ipl_updated(void *buf)
|
||||
{
|
||||
ipl_ver_meta_t *update_ft = (ipl_ver_meta_t *)(buf + PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
||||
|
||||
if (update_ft->magic == ipl_ver.magic)
|
||||
{
|
||||
if (byte_swap_32(update_ft->version) <= byte_swap_32(ipl_ver.version))
|
||||
return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
int launch_payload(char *path, bool update)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
if (!update)
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
if (!path)
|
||||
return 1;
|
||||
@@ -344,82 +300,37 @@ int launch_payload(char *path, bool update)
|
||||
f_close(&fp);
|
||||
free(path);
|
||||
|
||||
// Check for updated version.
|
||||
if (update)
|
||||
{
|
||||
u8 *update_ft = calloc(1, 6);
|
||||
if (update && is_ipl_updated(buf))
|
||||
return 1;
|
||||
|
||||
bool update_sept = true;
|
||||
if (!f_open(&fp, "sept/payload.bin", FA_READ | FA_WRITE))
|
||||
{
|
||||
memset(update_ft, 0, 6);
|
||||
f_lseek(&fp, f_size(&fp) - 6);
|
||||
f_read(&fp, update_ft, 6, NULL);
|
||||
f_close(&fp);
|
||||
update_ft[4] -= '0';
|
||||
update_ft[5] -= '0';
|
||||
if (*(u32 *)update_ft == 0x43544349)
|
||||
{
|
||||
if (update_ft[4] == BLVERSIONMJ && update_ft[5] == BLVERSIONMN)
|
||||
update_sept = false;
|
||||
}
|
||||
else
|
||||
update_sept = false;
|
||||
}
|
||||
|
||||
if (update_sept)
|
||||
{
|
||||
if (!f_open(&fp, "sept/payload.bin", FA_CREATE_ALWAYS | FA_WRITE))
|
||||
{
|
||||
f_write(&fp, buf, size, NULL);
|
||||
f_close(&fp);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(update_ft, buf + size - 6, 6);
|
||||
update_ft[4] -= '0';
|
||||
update_ft[5] -= '0';
|
||||
if (*(u32 *)update_ft == 0x43544349)
|
||||
{
|
||||
if (update_ft[4] < BLVERSIONMJ || (update_ft[4] == BLVERSIONMJ && update_ft[5] <= BLVERSIONMN))
|
||||
{
|
||||
free(update_ft);
|
||||
return 1;
|
||||
}
|
||||
*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR = BOOTLOADER_UPDATED_MAGIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(update_ft);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(update_ft);
|
||||
}
|
||||
sd_unmount();
|
||||
|
||||
if (size < 0x30000)
|
||||
{
|
||||
if (!update)
|
||||
reloc_patcher(PAYLOAD_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
|
||||
if (update)
|
||||
memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), &b_cfg, sizeof(boot_cfg_t)); // Transfer boot cfg.
|
||||
else
|
||||
memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), (u8 *)(IPL_LOAD_ADDR + PATCHED_RELOC_SZ), sizeof(boot_cfg_t));
|
||||
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
|
||||
|
||||
reconfig_hw_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
|
||||
}
|
||||
else
|
||||
{
|
||||
reloc_patcher(PAYLOAD_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
|
||||
if (*(vu32 *)CBFS_SDRAM_EN_ADDR != 0x4452414D)
|
||||
return 1;
|
||||
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
|
||||
reconfig_hw_workaround(true, 0);
|
||||
}
|
||||
|
||||
void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;
|
||||
void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR;
|
||||
|
||||
// Launch our payload.
|
||||
if (!update)
|
||||
(*ext_payload_ptr)();
|
||||
else
|
||||
{
|
||||
EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD;
|
||||
(*update_ptr)();
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -427,23 +338,12 @@ int launch_payload(char *path, bool update)
|
||||
|
||||
void auto_launch_update()
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
if (*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR == BOOTLOADER_UPDATED_MAGIC)
|
||||
*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR = 0;
|
||||
else
|
||||
if (EMC(EMC_SCRATCH0) & EMC_HEKA_UPD)
|
||||
EMC(EMC_SCRATCH0) &= ~EMC_HEKA_UPD;
|
||||
else if (sd_mount())
|
||||
{
|
||||
if (sd_mount())
|
||||
{
|
||||
if (f_open(&fp, "bootloader/update.bin", FA_READ))
|
||||
return;
|
||||
else
|
||||
{
|
||||
f_close(&fp);
|
||||
launch_payload("bootloader/update.bin", true);
|
||||
}
|
||||
|
||||
}
|
||||
if (!f_stat("bootloader/update.bin", NULL))
|
||||
launch_payload("bootloader/update.bin", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +366,7 @@ void launch_tools(u8 type)
|
||||
if (!type)
|
||||
memcpy(dir, "bootloader/payloads", 20);
|
||||
else
|
||||
memcpy(dir, "bootloader/libtools", 20);
|
||||
memcpy(dir, "bootloader/modules", 19);
|
||||
|
||||
filelist = dirlist(dir, NULL, false);
|
||||
|
||||
@@ -511,7 +411,7 @@ void launch_tools(u8 type)
|
||||
}
|
||||
}
|
||||
else
|
||||
EPRINTF("No payloads or libraries found.");
|
||||
EPRINTF("No payloads or modules found.");
|
||||
|
||||
free(ments);
|
||||
free(filelist);
|
||||
@@ -525,9 +425,6 @@ void launch_tools(u8 type)
|
||||
|
||||
if (file_sec)
|
||||
{
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
memcpy(dir + strlen(dir), "/", 2);
|
||||
memcpy(dir + strlen(dir), file_sec, strlen(file_sec) + 1);
|
||||
|
||||
@@ -541,10 +438,6 @@ void launch_tools(u8 type)
|
||||
}
|
||||
else
|
||||
ianos_loader(true, dir, DRAM_LIB, NULL);
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
Kc_MENU_LOGO = (u8 *)malloc(0x6000);
|
||||
blz_uncompress_srcdest(Kc_MENU_LOGO_blz, SZ_MENU_LOGO_BLZ, Kc_MENU_LOGO, SZ_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -555,7 +448,7 @@ out:
|
||||
}
|
||||
|
||||
void launch_tools_payload() { launch_tools(0); }
|
||||
void launch_tools_library() { launch_tools(1); }
|
||||
void launch_tools_module() { launch_tools(1); }
|
||||
|
||||
void ini_list_launcher()
|
||||
{
|
||||
@@ -614,9 +507,9 @@ void ini_list_launcher()
|
||||
|
||||
if (ments[j].data == cfg_tmp)
|
||||
{
|
||||
b_cfg->boot_cfg = BOOT_CFG_FROM_LAUNCH;
|
||||
b_cfg->autoboot = j - non_cfg;
|
||||
b_cfg->autoboot_list = 1;
|
||||
b_cfg.boot_cfg = BOOT_CFG_FROM_LAUNCH;
|
||||
b_cfg.autoboot = j - non_cfg;
|
||||
b_cfg.autoboot_list = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -639,7 +532,7 @@ void ini_list_launcher()
|
||||
}
|
||||
}
|
||||
else
|
||||
EPRINTF("No ini configs found.");
|
||||
EPRINTF("No extra configs found.");
|
||||
free(ments);
|
||||
ini_free(&ini_list_sections);
|
||||
}
|
||||
@@ -650,10 +543,6 @@ void ini_list_launcher()
|
||||
if (!cfg_sec)
|
||||
goto out;
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
if (payload_path)
|
||||
{
|
||||
ini_free_section(cfg_sec);
|
||||
@@ -669,11 +558,6 @@ void ini_list_launcher()
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
Kc_MENU_LOGO = (u8 *)malloc(0x6000);
|
||||
blz_uncompress_srcdest(Kc_MENU_LOGO_blz, SZ_MENU_LOGO_BLZ, Kc_MENU_LOGO, SZ_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
out:
|
||||
ini_free_section(cfg_sec);
|
||||
|
||||
@@ -730,7 +614,7 @@ void launch_firmware()
|
||||
if (i < 6)
|
||||
{
|
||||
ments[i].type = MENT_CAPTION;
|
||||
ments[i].caption = "No main configurations found...";
|
||||
ments[i].caption = "No main configs found...";
|
||||
ments[i].color = 0xFFFFDD00;
|
||||
i++;
|
||||
}
|
||||
@@ -750,9 +634,9 @@ void launch_firmware()
|
||||
non_cfg++;
|
||||
if (ments[j].data == cfg_tmp)
|
||||
{
|
||||
b_cfg->boot_cfg = BOOT_CFG_FROM_LAUNCH;
|
||||
b_cfg->autoboot = j - non_cfg;
|
||||
b_cfg->autoboot_list = 0;
|
||||
b_cfg.boot_cfg = BOOT_CFG_FROM_LAUNCH;
|
||||
b_cfg.autoboot = j - non_cfg;
|
||||
b_cfg.autoboot_list = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -789,9 +673,6 @@ void launch_firmware()
|
||||
if (!(btn & BTN_POWER))
|
||||
goto out;
|
||||
}
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
if (payload_path)
|
||||
{
|
||||
@@ -805,11 +686,6 @@ void launch_firmware()
|
||||
else if (!hos_launch(cfg_sec))
|
||||
EPRINTF("Failed to launch firmware.");
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
Kc_MENU_LOGO = (u8 *)malloc(0x6000);
|
||||
blz_uncompress_srcdest(Kc_MENU_LOGO_blz, SZ_MENU_LOGO_BLZ, Kc_MENU_LOGO, SZ_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
out:
|
||||
ini_free_section(cfg_sec);
|
||||
sd_unmount();
|
||||
@@ -819,15 +695,11 @@ out:
|
||||
|
||||
void auto_launch_firmware()
|
||||
{
|
||||
if (!(b_cfg->boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||
{
|
||||
if (!h_cfg.sept_run)
|
||||
auto_launch_update();
|
||||
gfx_con.mute = true;
|
||||
}
|
||||
|
||||
u8 *BOOTLOGO = NULL;
|
||||
char *payload_path = NULL;
|
||||
FIL fp;
|
||||
u32 btn = 0;
|
||||
|
||||
struct _bmp_data
|
||||
@@ -844,16 +716,17 @@ void auto_launch_firmware()
|
||||
bool bootlogoFound = false;
|
||||
char *bootlogoCustomEntry = NULL;
|
||||
|
||||
if (!(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||
gfx_con.mute = true;
|
||||
|
||||
ini_sec_t *cfg_sec = NULL;
|
||||
LIST_INIT(ini_sections);
|
||||
LIST_INIT(ini_list_sections);
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
if (f_open(&fp, "bootloader/hekate_ipl.ini", FA_READ))
|
||||
if (f_stat("bootloader/hekate_ipl.ini", NULL))
|
||||
create_config_entry();
|
||||
else
|
||||
f_close(&fp);
|
||||
|
||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||
{
|
||||
@@ -889,15 +762,15 @@ void auto_launch_firmware()
|
||||
boot_entry_id++;
|
||||
|
||||
// Override autoboot, otherwise save it for a possbile sept run.
|
||||
if (b_cfg->boot_cfg & BOOT_CFG_AUTOBOOT_EN)
|
||||
if (b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN)
|
||||
{
|
||||
h_cfg.autoboot = b_cfg->autoboot;
|
||||
h_cfg.autoboot_list = b_cfg->autoboot_list;
|
||||
h_cfg.autoboot = b_cfg.autoboot;
|
||||
h_cfg.autoboot_list = b_cfg.autoboot_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_cfg->autoboot = h_cfg.autoboot;
|
||||
b_cfg->autoboot_list = h_cfg.autoboot_list;
|
||||
b_cfg.autoboot = h_cfg.autoboot;
|
||||
b_cfg.autoboot_list = h_cfg.autoboot_list;
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -917,12 +790,11 @@ void auto_launch_firmware()
|
||||
}
|
||||
}
|
||||
|
||||
if (h_cfg.autohosoff && !(b_cfg->boot_cfg & BOOT_CFG_AUTOBOOT_EN))
|
||||
if (h_cfg.autohosoff && !(b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN))
|
||||
check_power_off_from_hos();
|
||||
|
||||
if (h_cfg.autoboot_list)
|
||||
{
|
||||
ini_free(&ini_sections);
|
||||
ini_free_section(cfg_sec);
|
||||
boot_entry_id = 1;
|
||||
bootlogoCustomEntry = NULL;
|
||||
@@ -971,24 +843,16 @@ void auto_launch_firmware()
|
||||
else
|
||||
goto out;
|
||||
|
||||
payload_path = ini_check_payload_section(cfg_sec);
|
||||
|
||||
if (!payload_path)
|
||||
check_sept();
|
||||
|
||||
u8 *bitmap = NULL;
|
||||
if (!(b_cfg->boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||
if (!(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH) && h_cfg.bootwait)
|
||||
{
|
||||
if (bootlogoCustomEntry != NULL) // Check if user set custom logo path at the boot entry.
|
||||
{
|
||||
if (bootlogoCustomEntry) // Check if user set custom logo path at the boot entry.
|
||||
bitmap = (u8 *)sd_file_read(bootlogoCustomEntry);
|
||||
if (bitmap == NULL) // Custom entry bootlogo not found, trying default custom one.
|
||||
bitmap = (u8 *)sd_file_read("bootloader/bootlogo.bmp");
|
||||
}
|
||||
else // User has not set a custom logo path.
|
||||
|
||||
if (!bitmap) // Custom entry bootlogo not found, trying default custom one.
|
||||
bitmap = (u8 *)sd_file_read("bootloader/bootlogo.bmp");
|
||||
|
||||
if (bitmap != NULL)
|
||||
if (bitmap)
|
||||
{
|
||||
// Get values manually to avoid unaligned access.
|
||||
bmpData.size = bitmap[2] | bitmap[3] << 8 |
|
||||
@@ -1002,7 +866,7 @@ void auto_launch_firmware()
|
||||
// Sanity check.
|
||||
if (bitmap[0] == 'B' &&
|
||||
bitmap[1] == 'M' &&
|
||||
bitmap[28] == 32 && //
|
||||
bitmap[28] == 32 && // Only 32 bit BMPs allowed.
|
||||
bmpData.size_x <= 720 &&
|
||||
bmpData.size_y <= 1280)
|
||||
{
|
||||
@@ -1046,17 +910,13 @@ void auto_launch_firmware()
|
||||
if (h_cfg.autoboot_list)
|
||||
ini_free(&ini_list_sections);
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
if (b_cfg->boot_cfg & BOOT_CFG_FROM_LAUNCH)
|
||||
if (h_cfg.sept_run)
|
||||
display_backlight_brightness(h_cfg.backlight, 0);
|
||||
else if (h_cfg.bootwait)
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
||||
// Wait before booting. If VOL- is pressed go into bootloader menu.
|
||||
if (!(b_cfg->boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||
if (!h_cfg.sept_run)
|
||||
{
|
||||
btn = btn_wait_timeout(h_cfg.bootwait * 1000, BTN_VOL_DOWN);
|
||||
|
||||
@@ -1064,6 +924,8 @@ void auto_launch_firmware()
|
||||
goto out;
|
||||
}
|
||||
|
||||
payload_path = ini_check_payload_section(cfg_sec);
|
||||
|
||||
if (payload_path)
|
||||
{
|
||||
ini_free_section(cfg_sec);
|
||||
@@ -1071,12 +933,10 @@ void auto_launch_firmware()
|
||||
free(payload_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_sept();
|
||||
hos_launch(cfg_sec);
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
Kc_MENU_LOGO = (u8 *)malloc(ALIGN(SZ_MENU_LOGO, 0x10));
|
||||
blz_uncompress_srcdest(Kc_MENU_LOGO_blz, SZ_MENU_LOGO_BLZ, Kc_MENU_LOGO, SZ_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
}
|
||||
|
||||
out:
|
||||
ini_free(&ini_sections);
|
||||
@@ -1087,7 +947,7 @@ out:
|
||||
sd_unmount();
|
||||
gfx_con.mute = false;
|
||||
|
||||
b_cfg->boot_cfg &= ~(BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_LAUNCH);
|
||||
b_cfg.boot_cfg &= ~(BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_LAUNCH);
|
||||
}
|
||||
|
||||
void about()
|
||||
@@ -1186,7 +1046,7 @@ ment_t ment_restore[] = {
|
||||
MDEF_CHGLINE(),
|
||||
MDEF_CAPTION("------ Full --------", 0xFF0AB9E6),
|
||||
MDEF_HANDLER("Restore eMMC BOOT0/1", restore_emmc_boot),
|
||||
MDEF_HANDLER("Restore eMMC RAW GPP (exFAT only)", restore_emmc_rawnand),
|
||||
MDEF_HANDLER("Restore eMMC RAW GPP", restore_emmc_rawnand),
|
||||
MDEF_CHGLINE(),
|
||||
MDEF_CAPTION("-- GPP Partitions --", 0xFF0AB9E6),
|
||||
MDEF_HANDLER("Restore GPP partitions", restore_emmc_gpp_parts),
|
||||
@@ -1259,27 +1119,28 @@ ment_t ment_top[] = {
|
||||
};
|
||||
menu_t menu_top = {
|
||||
ment_top,
|
||||
"hekate - CTCaer mod v4.8", 0, 0
|
||||
"hekate - CTCaer mod v4.9", 0, 0
|
||||
};
|
||||
|
||||
#define IPL_STACK_TOP 0x90010000
|
||||
#define IPL_HEAP_START 0x90020000
|
||||
#define IPL_HEAP_END 0xB5000000
|
||||
|
||||
extern void pivot_stack(u32 stack_top);
|
||||
|
||||
void ipl_main()
|
||||
{
|
||||
// Set boot config address.
|
||||
b_cfg = (boot_cfg_t *)(IPL_LOAD_ADDR + PATCHED_RELOC_SZ);
|
||||
|
||||
// Do initial HW configuration. This is compatible with consecutive reruns without a reset.
|
||||
config_hw();
|
||||
|
||||
//Pivot the stack so we have enough space.
|
||||
pivot_stack(0x90010000);
|
||||
pivot_stack(IPL_STACK_TOP);
|
||||
|
||||
//Tegra/Horizon configuration goes to 0x80000000+, package2 goes to 0xA9800000, we place our heap in between.
|
||||
heap_init(0x90020000);
|
||||
heap_init(IPL_HEAP_START);
|
||||
|
||||
#ifdef DEBUG_UART_PORT
|
||||
uart_send(DEBUG_UART_PORT, (u8 *)"Hekate: Hello!\r\n", 18);
|
||||
uart_send(DEBUG_UART_PORT, (u8 *)"Hekate: Hello!\r\n", 16);
|
||||
uart_wait_idle(DEBUG_UART_PORT, UART_TX_IDLE);
|
||||
#endif
|
||||
|
||||
@@ -1296,9 +1157,9 @@ void ipl_main()
|
||||
gfx_init_ctxt(&gfx_ctxt, fb, 720, 1280, 720);
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
Kc_MENU_LOGO = (u8 *)malloc(0x6000);
|
||||
Kc_MENU_LOGO = (u8 *)malloc(ALIGN(SZ_MENU_LOGO, 0x1000));
|
||||
blz_uncompress_srcdest(Kc_MENU_LOGO_blz, SZ_MENU_LOGO_BLZ, Kc_MENU_LOGO, SZ_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
#endif
|
||||
|
||||
gfx_con_init(&gfx_con, &gfx_ctxt);
|
||||
|
||||
|
||||
@@ -124,6 +124,6 @@ void *calloc(u32 num, u32 size)
|
||||
|
||||
void free(void *buf)
|
||||
{
|
||||
if ((buf != NULL) || ((u32)buf > (_heap.start - 1)))
|
||||
if ((u32)buf >= _heap.start)
|
||||
_heap_free(&_heap, (u32)buf);
|
||||
}
|
||||
|
||||
@@ -270,15 +270,15 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size)
|
||||
int res;
|
||||
// Setup config for SHA256, size = BITS(src_size).
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_SHA_CONFIG_REG_OFFSET) = 1;
|
||||
SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_ENABLE;
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3);
|
||||
SE(0x208) = 0;
|
||||
SE(0x20C) = 0;
|
||||
SE(0x210) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 1) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 2) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 3) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3);
|
||||
SE(0x218) = 0;
|
||||
SE(0x21C) = 0;
|
||||
SE(0x220) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 1) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 2) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 3) = 0;
|
||||
|
||||
// Trigger the operation.
|
||||
res = _se_execute(OP_START, NULL, 0, src, src_size);
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
#include "../utils/util.h"
|
||||
#include "../hos/hos.h"
|
||||
|
||||
/* #include "../gfx/gfx.h"
|
||||
extern gfx_con_t gfx_con; */
|
||||
// #include "../gfx/gfx.h"
|
||||
|
||||
static int _tsec_dma_wait_idle()
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "../utils/util.h"
|
||||
|
||||
extern sdmmc_t sd_sdmmc;
|
||||
extern boot_cfg_t *b_cfg;
|
||||
extern boot_cfg_t b_cfg;
|
||||
|
||||
void _config_oscillators()
|
||||
{
|
||||
@@ -147,7 +147,7 @@ void _mbist_workaround()
|
||||
void _config_se_brom()
|
||||
{
|
||||
// Skip SBK/SSK if sept was run.
|
||||
if (!(b_cfg->boot_cfg & BOOT_CFG_SEPT_RUN))
|
||||
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
|
||||
{
|
||||
// Bootrom part we skipped.
|
||||
u32 sbk[4] = {
|
||||
@@ -168,7 +168,7 @@ void _config_se_brom()
|
||||
|
||||
// This memset needs to happen here, else TZRAM will behave weirdly later on.
|
||||
memset((void *)TZRAM_BASE, 0, 0x10000);
|
||||
PMC(APBDEV_PMC_CRYPTO_OP) = 0;
|
||||
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
|
||||
SE(SE_INT_STATUS_REG_OFFSET) = 0x1F;
|
||||
|
||||
// Clear the boot reason to avoid problems later
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#define PMC_PWR_DET_SDMMC1_IO_EN (1 << 12)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
|
||||
/*! Special registers. */
|
||||
#define EMC_SCRATCH0 0x324
|
||||
#define EMC_HEKA_UPD (1 << 30)
|
||||
#define EMC_SEPT_RUN (1 << 31)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,13 +19,11 @@
|
||||
#include "sdmmc.h"
|
||||
#include "mmc.h"
|
||||
#include "sd.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
/*#include "gfx.h"
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
|
||||
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
|
||||
|
||||
@@ -17,20 +17,18 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "sdmmc.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "mmc.h"
|
||||
#include "sdmmc.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../power/max7762x.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
/*#include "gfx.h"
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
|
||||
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
/*! SCMMC controller base addresses. */
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#include "util.h"
|
||||
#include "../power/max77620.h"
|
||||
|
||||
u32 btn_read()
|
||||
u8 btn_read()
|
||||
{
|
||||
u32 res = 0;
|
||||
u8 res = 0;
|
||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))
|
||||
res |= BTN_VOL_DOWN;
|
||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
|
||||
@@ -34,9 +34,9 @@ u32 btn_read()
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 btn_wait()
|
||||
u8 btn_wait()
|
||||
{
|
||||
u32 res = 0, btn = btn_read();
|
||||
u8 res = 0, btn = btn_read();
|
||||
bool pwr = false;
|
||||
|
||||
//Power button down, raise a filter.
|
||||
@@ -59,16 +59,18 @@ u32 btn_wait()
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 btn_wait_timeout(u32 time_ms, u32 mask)
|
||||
u8 btn_wait_timeout(u32 time_ms, u8 mask)
|
||||
{
|
||||
u32 timeout = get_tmr_ms() + time_ms;
|
||||
u32 res = btn_read() & mask;
|
||||
u8 res = btn_read() & mask;
|
||||
|
||||
do
|
||||
while (get_tmr_ms() < timeout)
|
||||
{
|
||||
if (!(res & mask))
|
||||
if (res == mask)
|
||||
break;
|
||||
else
|
||||
res = btn_read() & mask;
|
||||
} while (get_tmr_ms() < timeout);
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define BTN_POWER 0x1
|
||||
#define BTN_VOL_DOWN 0x2
|
||||
#define BTN_VOL_UP 0x4
|
||||
#define BTN_POWER (1 << 0)
|
||||
#define BTN_VOL_DOWN (1 << 1)
|
||||
#define BTN_VOL_UP (1 << 2)
|
||||
|
||||
u32 btn_read();
|
||||
u32 btn_wait();
|
||||
u32 btn_wait_timeout(u32 time_ms, u32 mask);
|
||||
u8 btn_read();
|
||||
u8 btn_wait();
|
||||
u8 btn_wait_timeout(u32 time_ms, u8 mask);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -55,13 +55,33 @@ typedef int bool;
|
||||
#define BOOT_CFG_FROM_LAUNCH (1 << 1)
|
||||
#define BOOT_CFG_SEPT_RUN (1 << 7)
|
||||
|
||||
#define EXTRA_CFG_KEYS (1 << 0)
|
||||
#define EXTRA_CFG_PAYLOAD (1 << 1)
|
||||
#define EXTRA_CFG_MODULE (1 << 2)
|
||||
|
||||
typedef struct __attribute__((__packed__)) _boot_cfg_t
|
||||
{
|
||||
u8 boot_cfg;
|
||||
u8 autoboot;
|
||||
u8 autoboot_list;
|
||||
u8 rsvd_cfg;
|
||||
u8 rsvd[32];
|
||||
u8 extra_cfg;
|
||||
u8 rsvd[128];
|
||||
} boot_cfg_t;
|
||||
|
||||
typedef struct __attribute__((__packed__)) _ipl_ver_meta_t
|
||||
{
|
||||
u32 magic;
|
||||
u32 version;
|
||||
u16 rsvd0;
|
||||
u16 rsvd1;
|
||||
} ipl_ver_meta_t;
|
||||
|
||||
typedef struct __attribute__((__packed__)) _reloc_meta_t
|
||||
{
|
||||
u32 start;
|
||||
u32 stack;
|
||||
u32 end;
|
||||
u32 ep;
|
||||
} reloc_meta_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,15 @@
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
#include "../gfx/di.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../rtc/max77620-rtc.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
extern void sd_unmount();
|
||||
|
||||
u32 get_tmr_s()
|
||||
{
|
||||
return RTC(APBDEV_RTC_SECONDS);
|
||||
@@ -26,7 +33,7 @@ u32 get_tmr_s()
|
||||
u32 get_tmr_ms()
|
||||
{
|
||||
// The registers must be read with the following order:
|
||||
// -> RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
|
||||
// RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
|
||||
return (RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10));
|
||||
}
|
||||
|
||||
@@ -56,6 +63,50 @@ void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
|
||||
base[ops[i].off] = ops[i].val;
|
||||
}
|
||||
|
||||
void panic(u32 val)
|
||||
{
|
||||
// Set panic code.
|
||||
PMC(APBDEV_PMC_SCRATCH200) = val;
|
||||
//PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_DISABLE;
|
||||
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
|
||||
TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN;
|
||||
TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN;
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void reboot_normal()
|
||||
{
|
||||
sd_unmount();
|
||||
display_end();
|
||||
|
||||
panic(0x21); // Bypass fuse programming in package1.
|
||||
}
|
||||
|
||||
void reboot_rcm()
|
||||
{
|
||||
sd_unmount();
|
||||
display_end();
|
||||
|
||||
PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm.
|
||||
PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;
|
||||
|
||||
while (true)
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
void power_off()
|
||||
{
|
||||
sd_unmount();
|
||||
|
||||
// Stop the alarm, in case we injected and powered off too fast.
|
||||
max77620_rtc_stop_alarm();
|
||||
|
||||
//TODO: we should probably make sure all regulators are powered off properly.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
|
||||
}
|
||||
|
||||
#define CRC32C_POLY 0x82F63B78
|
||||
u32 crc32c(const void *buf, u32 len)
|
||||
{
|
||||
@@ -69,31 +120,3 @@ u32 crc32c(const void *buf, u32 len)
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len)
|
||||
{
|
||||
u32 len32 = len / 4;
|
||||
|
||||
if (!(len32 % 32))
|
||||
{
|
||||
while (len32)
|
||||
{
|
||||
len32 -= 32;
|
||||
if(buf1[len32] != buf2[len32])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (len32)
|
||||
{
|
||||
len32 -= 32;
|
||||
if(buf1[len32] != buf2[len32])
|
||||
return 1;
|
||||
if (len32 < 32)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000)
|
||||
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000))
|
||||
|
||||
typedef struct _cfg_op_t
|
||||
{
|
||||
@@ -34,11 +34,11 @@ u32 get_tmr_ms();
|
||||
u32 get_tmr_s();
|
||||
void usleep(u32 ticks);
|
||||
void msleep(u32 milliseconds);
|
||||
void panic(u32 val);
|
||||
void reboot_normal();
|
||||
void reboot_rcm();
|
||||
void power_off();
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||
u32 crc32c(const void *buf, u32 len);
|
||||
|
||||
/* This is a faster implementation of memcmp that checks two u32 values */
|
||||
/* every 128 Bytes block. Intented only for Backup and Restore */
|
||||
u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user