Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b9bf65071 | ||
|
|
50d4cbbda1 | ||
|
|
f911fab9f2 | ||
|
|
aae7689bf5 | ||
|
|
7d908c9ac5 | ||
|
|
2fb37db707 | ||
|
|
c8052e5b50 | ||
|
|
de830df7e7 | ||
|
|
04907e2823 | ||
|
|
4f5fcf9fbd | ||
|
|
ec890c7c97 |
12
Makefile
12
Makefile
@@ -4,9 +4,11 @@ endif
|
||||
|
||||
include $(DEVKITARM)/base_rules
|
||||
|
||||
TARGET := hekate
|
||||
IPL_LOAD_ADDR := 0x40008000
|
||||
BLVERSION_MAJOR := 4
|
||||
BLVERSION_MINOR := 6
|
||||
BLVERSION_MINOR := 8
|
||||
|
||||
TARGET := hekate
|
||||
BUILD := build
|
||||
OUTPUT := output
|
||||
SOURCEDIR = bootloader
|
||||
@@ -28,6 +30,7 @@ OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
hos.o \
|
||||
hos_config.o \
|
||||
secmon_exo.o \
|
||||
sept.o \
|
||||
i2c.o \
|
||||
kfuse.o \
|
||||
bq24193.o \
|
||||
@@ -62,14 +65,15 @@ OBJS += $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
elfload.o elfreloc_arm.o \
|
||||
)
|
||||
|
||||
CUSTOMDEFINES := -DBLVERSIONMJ=$(BLVERSION_MAJOR) -DBLVERSIONMN=$(BLVERSION_MINOR) -DMENU_LOGO_ENABLE
|
||||
CUSTOMDEFINES := -DBLVERSIONMJ=$(BLVERSION_MAJOR) -DBLVERSIONMN=$(BLVERSION_MINOR) -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
CUSTOMDEFINES += -DMENU_LOGO_ENABLE
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
# 0: UART_A, 1: UART_B.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=0
|
||||
|
||||
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
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
|
||||
|
||||
19
README.md
19
README.md
@@ -29,15 +29,15 @@ The bootloader can be configured via 'bootloader/hekate_ipl.ini' (if it is prese
|
||||
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
|
||||
|
||||
|
||||
### Configuration keys/values when boot entry is **config**:
|
||||
### Global Configuration keys/values when boot entry is **config**:
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
||||
| customlogo=0 | 0: Use default hekate bootlogo, 1: Use bootlogo.bmp. |
|
||||
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
|
||||
|
||||
@@ -51,13 +51,26 @@ 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. |
|
||||
| kip1patch=patchname| Enables a kip1 patch. Specify with multiple lines and/or as CSV. Implemented patches right now are nosigchk,nogc |
|
||||
| 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 |
|
||||
| atmosphere=1 | Enables Atmosphère patching |
|
||||
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
||||
|
||||
|
||||
### Payload storage:
|
||||
|
||||
Hekate now has a new storage in the binary that helps it configure it outside of BPMP enviroment:
|
||||
|
||||
| Offset / Name | Description |
|
||||
| -------------------- | ----------------------------------------------------------------- |
|
||||
| '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. |
|
||||
|
||||
|
||||
You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
|
||||
If the main .ini is not found, it is created on the first hekate boot.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -17,14 +17,15 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../utils/btn.h"
|
||||
#include "config.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "ini.h"
|
||||
#include "../utils/list.h"
|
||||
#include "../gfx/tui.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../gfx/tui.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/btn.h"
|
||||
#include "../utils/list.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
@@ -41,13 +42,14 @@ void set_default_configuration()
|
||||
h_cfg.autoboot = 0;
|
||||
h_cfg.autoboot_list = 0;
|
||||
h_cfg.bootwait = 3;
|
||||
h_cfg.customlogo = 0;
|
||||
h_cfg.verification = 2;
|
||||
h_cfg.se_keygen_done = 0;
|
||||
h_cfg.sbar_time_keeping = 0;
|
||||
h_cfg.backlight = 100;
|
||||
h_cfg.autohosoff = 0;
|
||||
h_cfg.errors = 0;
|
||||
h_cfg.autonogc = 1;
|
||||
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
||||
}
|
||||
|
||||
int create_config_entry()
|
||||
@@ -93,9 +95,6 @@ int create_config_entry()
|
||||
f_puts("\nbootwait=", &fp);
|
||||
itoa(h_cfg.bootwait, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\ncustomlogo=", &fp);
|
||||
itoa(h_cfg.customlogo, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nverification=", &fp);
|
||||
itoa(h_cfg.verification, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
@@ -105,6 +104,9 @@ int create_config_entry()
|
||||
f_puts("\nautohosoff=", &fp);
|
||||
itoa(h_cfg.autohosoff, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nautonogc=", &fp);
|
||||
itoa(h_cfg.autonogc, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\n", &fp);
|
||||
|
||||
if (mainIniFound)
|
||||
@@ -156,6 +158,18 @@ int create_config_entry()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _save_config()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
|
||||
static void _config_autoboot_list(void *ent)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
@@ -216,21 +230,13 @@ static void _config_autoboot_list(void *ent)
|
||||
}
|
||||
|
||||
memset(&ments[i], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Select a list entry to auto boot", 0, 0};
|
||||
menu_t menu = {ments, "Select an entry to auto boot", 0, 0};
|
||||
temp_autoboot = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_autoboot != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||
h_cfg.autoboot_list = 1;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
_save_config();
|
||||
|
||||
ment_t *tmp = (ment_t *)ent;
|
||||
tmp->data = NULL;
|
||||
@@ -240,7 +246,7 @@ static void _config_autoboot_list(void *ent)
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists in SD Card!.");
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists!.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -344,24 +350,16 @@ void config_autoboot()
|
||||
temp_autoboot = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_autoboot != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||
h_cfg.autoboot_list = 0;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
_save_config();
|
||||
}
|
||||
else
|
||||
goto out2;
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists in SD Card!.");
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists!.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -380,6 +378,9 @@ out2:;
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
void config_bootdelay()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
@@ -427,16 +428,8 @@ void config_bootdelay()
|
||||
u32 *temp_bootwait = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_bootwait != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.bootwait = *(u32 *)temp_bootwait;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
@@ -448,64 +441,6 @@ void config_bootdelay()
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_customlogo()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 5);
|
||||
u32 *cb_values = (u32 *)malloc(sizeof(u32) * 2);
|
||||
|
||||
for (u32 j = 0; j < 2; j++)
|
||||
{
|
||||
cb_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &cb_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
if (h_cfg.customlogo)
|
||||
{
|
||||
ments[2].caption = " Disable";
|
||||
ments[3].caption = "*Enable";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ments[2].caption = "*Disable";
|
||||
ments[3].caption = " Enable";
|
||||
}
|
||||
|
||||
memset(&ments[4], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Custom bootlogo", 0, 0};
|
||||
|
||||
u32 *temp_customlogo = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_customlogo != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.customlogo = *(u32 *)temp_customlogo;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(cb_values);
|
||||
|
||||
if (temp_customlogo == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_verification()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
@@ -528,21 +463,16 @@ void config_verification()
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
memcpy(vr_text, " Disable (Fastest)", 19);
|
||||
memcpy(vr_text + 64, " Sparse (Fast - Not reliable)", 32);
|
||||
memcpy(vr_text + 128, " Full (Slow - 100% reliable)", 32);
|
||||
memcpy(vr_text + 64, " Sparse (Fast)", 16);
|
||||
memcpy(vr_text + 128, " Full (Slow)", 16);
|
||||
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (h_cfg.verification != i)
|
||||
{
|
||||
vr_text[64 * i] = ' ';
|
||||
ments[2 + i].caption = vr_text + (i * 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
vr_text[64 * i] = '*';
|
||||
ments[2 + i].caption = vr_text + (i * 64);
|
||||
}
|
||||
ments[2 + i].caption = vr_text + (i * 64);
|
||||
}
|
||||
|
||||
memset(&ments[5], 0, sizeof(ment_t));
|
||||
@@ -551,16 +481,8 @@ void config_verification()
|
||||
u32 *temp_verification = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_verification != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.verification = *(u32 *)temp_verification;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
@@ -604,7 +526,6 @@ void config_backlight()
|
||||
bri_text[i * 32 + 1] = i + '0';
|
||||
memcpy(bri_text + i * 32 + 2, "0%", 3);
|
||||
}
|
||||
|
||||
else
|
||||
memcpy(bri_text + i * 32 + 1, "100%", 5);
|
||||
|
||||
@@ -619,16 +540,8 @@ void config_backlight()
|
||||
u32 *temp_backlight = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_backlight != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.backlight = (*(u32 *)temp_backlight) * 2;
|
||||
//Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
@@ -685,16 +598,8 @@ void config_auto_hos_poweroff()
|
||||
u32 *temp_autohosoff = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_autohosoff != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.autohosoff = *(u32 *)temp_autohosoff;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
@@ -704,3 +609,54 @@ void config_auto_hos_poweroff()
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_nogc()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 5);
|
||||
u32 *cb_values = (u32 *)malloc(sizeof(u32) * 2);
|
||||
|
||||
for (u32 j = 0; j < 2; j++)
|
||||
{
|
||||
cb_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &cb_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
if (h_cfg.autonogc)
|
||||
{
|
||||
ments[2].caption = " Disable";
|
||||
ments[3].caption = "*Auto";
|
||||
}
|
||||
else
|
||||
{
|
||||
ments[2].caption = "*Disable";
|
||||
ments[3].caption = " Auto";
|
||||
}
|
||||
|
||||
memset(&ments[4], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "No Gamecard", 0, 0};
|
||||
|
||||
u32 *temp_nogc = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_nogc != NULL)
|
||||
{
|
||||
h_cfg.autonogc = *(u32 *)temp_nogc;
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(cb_values);
|
||||
|
||||
if (temp_nogc == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -25,14 +25,15 @@ typedef struct _hekate_config
|
||||
u32 autoboot;
|
||||
u32 autoboot_list;
|
||||
u32 bootwait;
|
||||
u32 customlogo;
|
||||
u32 verification;
|
||||
u32 backlight;
|
||||
u32 autohosoff;
|
||||
u32 errors;
|
||||
u32 autonogc;
|
||||
// Global temporary config.
|
||||
int se_keygen_done;
|
||||
u32 sbar_time_keeping;
|
||||
u32 errors;
|
||||
int sept_run;
|
||||
} hekate_config;
|
||||
|
||||
typedef enum
|
||||
@@ -44,9 +45,9 @@ void set_default_configuration();
|
||||
int create_config_entry();
|
||||
void config_autoboot();
|
||||
void config_bootdelay();
|
||||
void config_customlogo();
|
||||
void config_verification();
|
||||
void config_backlight();
|
||||
void config_auto_hos_poweroff();
|
||||
void config_nogc();
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (C) 2018-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,
|
||||
@@ -24,11 +24,39 @@
|
||||
|
||||
static char *_strdup(char *str)
|
||||
{
|
||||
if (!str)
|
||||
return NULL;
|
||||
char *res = (char *)malloc(strlen(str) + 1);
|
||||
strcpy(res, str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 _find_section_name(char *lbuf, u32 lblen, char schar)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type)
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(name);
|
||||
csec->type = type;
|
||||
|
||||
return csec;
|
||||
}
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
{
|
||||
u32 lblen;
|
||||
@@ -43,6 +71,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
|
||||
memcpy(filename, ini_path, pathlen + 1);
|
||||
|
||||
// Get all ini filenames.
|
||||
if (is_dir)
|
||||
{
|
||||
filelist = dirlist(filename, "*.ini", false);
|
||||
@@ -57,6 +86,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
|
||||
do
|
||||
{
|
||||
// Copy ini filename in path string.
|
||||
if (is_dir)
|
||||
{
|
||||
if (filelist[k * 256])
|
||||
@@ -68,6 +98,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
break;
|
||||
}
|
||||
|
||||
// Open ini.
|
||||
if (f_open(&fp, filename, FA_READ) != FR_OK)
|
||||
{
|
||||
free(filelist);
|
||||
@@ -89,75 +120,31 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
|
||||
if (lblen > 2 && lbuf[0] == '[') // Create new section.
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
_find_section_name(lbuf, lblen, ']');
|
||||
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != ']' && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(&lbuf[1]);
|
||||
csec->type = INI_CHOICE;
|
||||
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CHOICE);
|
||||
list_init(&csec->kvs);
|
||||
}
|
||||
else if (lblen > 2 && lbuf[0] == '{') //Create new caption.
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
_find_section_name(lbuf, lblen, '}');
|
||||
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '}' && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(&lbuf[1]);
|
||||
csec->type = INI_CAPTION;
|
||||
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CAPTION);
|
||||
csec->color = 0xFF0AB9E6;
|
||||
}
|
||||
else if (lblen > 2 && lbuf[0] == '#') //Create empty lines and comments.
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
_find_section_name(lbuf, lblen, '\0');
|
||||
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(&lbuf[1]);
|
||||
csec->type = INI_COMMENT;
|
||||
csec = _ini_create_section(dst, csec, &lbuf[1], INI_COMMENT);
|
||||
}
|
||||
else if (lblen < 2)
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = NULL;
|
||||
csec->type = INI_NEWLINE;
|
||||
csec = _ini_create_section(dst, csec, NULL, INI_NEWLINE);
|
||||
}
|
||||
else if (csec && csec->type == INI_CHOICE) //Extract key/value.
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '=' && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
u32 i = _find_section_name(lbuf, lblen, '=');
|
||||
|
||||
ini_kv_t *kv = (ini_kv_t *)malloc(sizeof(ini_kv_t));
|
||||
kv->key = _strdup(&lbuf[0]);
|
||||
@@ -169,8 +156,11 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
f_close(&fp);
|
||||
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
|
||||
if (is_dir)
|
||||
csec = NULL;
|
||||
}
|
||||
} while (is_dir);
|
||||
|
||||
free(filename);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -88,7 +88,7 @@ void print_fuseinfo()
|
||||
gfx_printf(&gfx_con, "%k(Unlocked) fuse cache:\n\n%k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||
gfx_hexdump(&gfx_con, 0x7000F900, (u8 *)0x7000F900, 0x2FC);
|
||||
|
||||
gfx_puts(&gfx_con, "Press POWER to dump them to SD Card.\nPress VOL to go to the menu.\n");
|
||||
gfx_puts(&gfx_con, "\nPress POWER to dump them to SD Card.\nPress VOL to go to the menu.\n");
|
||||
|
||||
u32 btn = btn_wait();
|
||||
if (btn & BTN_POWER)
|
||||
@@ -352,7 +352,6 @@ void print_tsec_key()
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
u32 retries = 0;
|
||||
u32 key_ver_max = 3;
|
||||
|
||||
tsec_ctxt_t tsec_ctxt;
|
||||
sdmmc_storage_t storage;
|
||||
@@ -368,85 +367,70 @@ void print_tsec_key()
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
||||
if (!pkg1_id)
|
||||
{
|
||||
EPRINTFARGS("Unknown package1 version for reading\nTSEC firmware (= '%s').",
|
||||
(char *)pkg1 + 0x10);
|
||||
EPRINTF("Unknown pkg1 version for reading\nTSEC firmware.");
|
||||
goto out_wait;
|
||||
}
|
||||
|
||||
u8 keys[0x10 * 3];
|
||||
u8 keys[0x10 * 2];
|
||||
memset(keys, 0x00, 0x20);
|
||||
|
||||
tsec_ctxt.size = 0xF00;
|
||||
tsec_ctxt.fw = (u8 *)pkg1 + pkg1_id->tsec_off;
|
||||
tsec_ctxt.pkg1 = pkg1;
|
||||
tsec_ctxt.pkg11_off = pkg1_id->pkg11_off;
|
||||
tsec_ctxt.secmon_base = pkg1_id->secmon_base;
|
||||
|
||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
if (pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
||||
tsec_ctxt.size = 0xF00;
|
||||
else if (pkg1_id->kb == KB_FIRMWARE_VERSION_620)
|
||||
tsec_ctxt.size = 0x2900;
|
||||
else
|
||||
{
|
||||
tsec_ctxt.size = 0x3000;
|
||||
// Exit after TSEC key generation.
|
||||
*((vu16 *)((u32)tsec_ctxt.fw + 0x2DB5)) = 0x02F8;
|
||||
}
|
||||
|
||||
if (pkg1_id->kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
u8 *tsec_paged = (u8 *)page_alloc(3);
|
||||
memcpy(tsec_paged, (void *)tsec_ctxt.fw, tsec_ctxt.size);
|
||||
tsec_ctxt.fw = tsec_paged;
|
||||
|
||||
key_ver_max = 1;
|
||||
}
|
||||
|
||||
for (u32 i = 1; i <= key_ver_max; i++)
|
||||
int res = 0;
|
||||
|
||||
while (tsec_query(keys, pkg1_id->kb, &tsec_ctxt) < 0)
|
||||
{
|
||||
tsec_ctxt.key_ver = i;
|
||||
int res = 0;
|
||||
memset(keys, 0x00, 0x20);
|
||||
|
||||
while (tsec_query(keys + ((i - 1) * 0x10), pkg1_id->kb, &tsec_ctxt) < 0)
|
||||
retries++;
|
||||
|
||||
if (retries > 3)
|
||||
{
|
||||
if (pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
||||
memset(keys + ((i - 1) * 0x10), 0x00, 0x10);
|
||||
else
|
||||
memset(keys, 0x00, 0x30);
|
||||
|
||||
retries++;
|
||||
|
||||
if (retries > 3)
|
||||
{
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kTSEC key %d: %k", 0xFF00DDFF, i, 0xFFCCCCCC);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
for (u32 j = 0; j < 0x10; j++)
|
||||
gfx_printf(&gfx_con, "%02X", keys[((i - 1) * 0x10) + j]);
|
||||
}
|
||||
else
|
||||
EPRINTFARGS("ERROR %X", res);
|
||||
gfx_putc(&gfx_con, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kTSEC key: %k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
for (u32 j = 0; j < 0x10; j++)
|
||||
gfx_printf(&gfx_con, "%02X", keys[j]);
|
||||
gfx_putc(&gfx_con, '\n');
|
||||
|
||||
gfx_printf(&gfx_con, "%kTSEC root: %k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||
for (u32 j = 0; j < 0x10; j++)
|
||||
gfx_printf(&gfx_con, "%02X", keys[0x10 + j]);
|
||||
}
|
||||
else
|
||||
EPRINTFARGS("ERROR %X", res);
|
||||
gfx_putc(&gfx_con, '\n');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gfx_puts(&gfx_con, "\nPress POWER to dump them to SD Card.\nPress VOL to go to the menu.\n");
|
||||
gfx_printf(&gfx_con, "%kTSEC key: %k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
for (u32 j = 0; j < 0x10; j++)
|
||||
gfx_printf(&gfx_con, "%02X", keys[j]);
|
||||
|
||||
|
||||
if (pkg1_id->kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
gfx_printf(&gfx_con, "\n%kTSEC root: %k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||
for (u32 j = 0; j < 0x10; j++)
|
||||
gfx_printf(&gfx_con, "%02X", keys[0x10 + j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
EPRINTFARGS("ERROR %X\n", res);
|
||||
|
||||
gfx_puts(&gfx_con, "\n\nPress POWER to dump them to SD Card.\nPress VOL to go to the menu.\n");
|
||||
|
||||
u32 btn = btn_wait();
|
||||
if (btn & BTN_POWER)
|
||||
@@ -455,7 +439,7 @@ void print_tsec_key()
|
||||
{
|
||||
char path[64];
|
||||
emmcsn_path_impl(path, "/dumps", "tsec_keys.bin", NULL);
|
||||
if (!sd_save_to_file(keys, 0x10 * 3, path))
|
||||
if (!sd_save_to_file(keys, 0x10 * 2, path))
|
||||
gfx_puts(&gfx_con, "\nDone!\n");
|
||||
sd_unmount();
|
||||
}
|
||||
@@ -709,4 +693,3 @@ void bootrom_ipatches_info()
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018 Reisyukaku
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "../hos/hos.h"
|
||||
#include "../hos/pkg1.h"
|
||||
#include "../hos/pkg2.h"
|
||||
#include "../hos/sept.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../power/max7762x.h"
|
||||
@@ -35,7 +36,9 @@
|
||||
#include "../utils/btn.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
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;
|
||||
@@ -82,20 +85,34 @@ void dump_packages12()
|
||||
if (!pkg1_id)
|
||||
{
|
||||
gfx_con.fntsz = 8;
|
||||
EPRINTFARGS("Unknown package1 version for reading\nTSEC firmware (= '%s').", (char *)pkg1 + 0x10);
|
||||
EPRINTF("Unknown pkg1 version for reading\nTSEC firmware.");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
kb = pkg1_id->kb;
|
||||
|
||||
if (!h_cfg.se_keygen_done || kb >= KB_FIRMWARE_VERSION_620)
|
||||
if (!h_cfg.se_keygen_done || kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
tsec_ctxt.key_ver = 1;
|
||||
tsec_ctxt.fw = (void *)pkg1 + pkg1_id->tsec_off;
|
||||
tsec_ctxt.pkg1 = (void *)pkg1;
|
||||
tsec_ctxt.pkg11_off = pkg1_id->pkg11_off;
|
||||
tsec_ctxt.secmon_base = pkg1_id->secmon_base;
|
||||
|
||||
if (kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
||||
{
|
||||
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();
|
||||
|
||||
if (!reboot_to_sept((u8 *)tsec_ctxt.fw))
|
||||
{
|
||||
gfx_printf(&gfx_con, "Failed to run sept\n");
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
// Read keyblob.
|
||||
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
||||
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + kb, 1, keyblob);
|
||||
@@ -110,41 +127,45 @@ void dump_packages12()
|
||||
if (kb <= KB_FIRMWARE_VERSION_600)
|
||||
pkg1_decrypt(pkg1_id, pkg1);
|
||||
|
||||
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
|
||||
|
||||
// Display info.
|
||||
gfx_printf(&gfx_con, "%kNX Bootloader size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->ldr_size);
|
||||
|
||||
gfx_printf(&gfx_con, "%kSecure monitor addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->secmon_base);
|
||||
gfx_printf(&gfx_con, "%kSecure monitor size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->sm_size);
|
||||
|
||||
gfx_printf(&gfx_con, "%kWarmboot addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->warmboot_base);
|
||||
gfx_printf(&gfx_con, "%kWarmboot size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->wb_size);
|
||||
|
||||
char path[64];
|
||||
// Dump package1.1.
|
||||
emmcsn_path_impl(path, "/pkg1", "pkg1_decr.bin", &storage);
|
||||
if (sd_save_to_file(pkg1, 0x40000, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "\nFull package1 dumped to pkg1_decr.bin\n");
|
||||
|
||||
// Dump nxbootloader.
|
||||
emmcsn_path_impl(path, "/pkg1", "nxloader.bin", &storage);
|
||||
if (sd_save_to_file(loader, hdr->ldr_size, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "NX Bootloader dumped to nxloader.bin\n");
|
||||
if (kb <= KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
|
||||
|
||||
// Display info.
|
||||
gfx_printf(&gfx_con, "%kNX Bootloader size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->ldr_size);
|
||||
|
||||
gfx_printf(&gfx_con, "%kSecure monitor addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->secmon_base);
|
||||
gfx_printf(&gfx_con, "%kSecure monitor size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->sm_size);
|
||||
|
||||
gfx_printf(&gfx_con, "%kWarmboot addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->warmboot_base);
|
||||
gfx_printf(&gfx_con, "%kWarmboot size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->wb_size);
|
||||
|
||||
// Dump secmon.
|
||||
emmcsn_path_impl(path, "/pkg1", "secmon.bin", &storage);
|
||||
if (sd_save_to_file(secmon, hdr->sm_size, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "Secure Monitor dumped to secmon.bin\n");
|
||||
|
||||
// Dump warmboot.
|
||||
emmcsn_path_impl(path, "/pkg1", "warmboot.bin", &storage);
|
||||
if (sd_save_to_file(warmboot, hdr->wb_size, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "Warmboot dumped to warmboot.bin\n\n\n");
|
||||
// Dump package1.1.
|
||||
emmcsn_path_impl(path, "/pkg1", "pkg1_decr.bin", &storage);
|
||||
if (sd_save_to_file(pkg1, 0x40000, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "\npkg1 dumped to pkg1_decr.bin\n");
|
||||
|
||||
// Dump nxbootloader.
|
||||
emmcsn_path_impl(path, "/pkg1", "nxloader.bin", &storage);
|
||||
if (sd_save_to_file(loader, hdr->ldr_size, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "NX Bootloader dumped to nxloader.bin\n");
|
||||
|
||||
// Dump secmon.
|
||||
emmcsn_path_impl(path, "/pkg1", "secmon.bin", &storage);
|
||||
if (sd_save_to_file(secmon, hdr->sm_size, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "Secure Monitor dumped to secmon.bin\n");
|
||||
|
||||
// Dump warmboot.
|
||||
emmcsn_path_impl(path, "/pkg1", "warmboot.bin", &storage);
|
||||
if (sd_save_to_file(warmboot, hdr->wb_size, path))
|
||||
goto out_free;
|
||||
gfx_puts(&gfx_con, "Warmboot dumped to warmboot.bin\n\n\n");
|
||||
}
|
||||
|
||||
// Dump package2.1.
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
@@ -180,7 +201,7 @@ void dump_packages12()
|
||||
emmcsn_path_impl(path, "/pkg2", "pkg2_decr.bin", &storage);
|
||||
if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
|
||||
goto out;
|
||||
gfx_puts(&gfx_con, "\nFull package2 dumped to pkg2_decr.bin\n");
|
||||
gfx_puts(&gfx_con, "\npkg2 dumped to pkg2_decr.bin\n");
|
||||
|
||||
// Dump kernel.
|
||||
emmcsn_path_impl(path, "/pkg2", "kernel.bin", &storage);
|
||||
@@ -193,7 +214,7 @@ void dump_packages12()
|
||||
if (sd_save_to_file(pkg2_hdr->data + pkg2_hdr->sec_size[PKG2_SEC_KERNEL],
|
||||
pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
|
||||
goto out;
|
||||
gfx_puts(&gfx_con, "INI1 kip1 package dumped to ini1.bin\n");
|
||||
gfx_puts(&gfx_con, "INI1 dumped to ini1.bin\n");
|
||||
|
||||
gfx_puts(&gfx_con, "\nDone. Press any key...\n");
|
||||
|
||||
@@ -430,7 +451,7 @@ void _fix_sd_attr(u32 type)
|
||||
break;
|
||||
}
|
||||
|
||||
gfx_printf(&gfx_con, "Traversing all %s files!\nThis may take some time, please wait...\n\n", label);
|
||||
gfx_printf(&gfx_con, "Traversing all %s files!\nThis may take some time...\n\n", label);
|
||||
_fix_attributes(path, &total, type, type);
|
||||
gfx_printf(&gfx_con, "%kTotal archive bits cleared: %d!%k\n\nDone! Press any key...", 0xFF96FF00, total, 0xFFCCCCCC);
|
||||
sd_unmount();
|
||||
@@ -553,10 +574,10 @@ void fix_battery_desync()
|
||||
}*/
|
||||
|
||||
/*
|
||||
#include "../modules/hekate_libsys_minerva/mtc.h"
|
||||
#include "../../modules/hekate_libsys_minerva/mtc.h"
|
||||
#include "../ianos/ianos.h"
|
||||
#include "../soc/fuse.h"
|
||||
mtc_config_t mtc_cfg;
|
||||
#include "../soc/clock.h"
|
||||
|
||||
void minerva()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 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,
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../power/max7762x.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/clock.h"
|
||||
@@ -42,8 +43,8 @@ static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
||||
void display_init()
|
||||
{
|
||||
// Power on.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO0_CFG, 0xD0); // Configure to 1.2V.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, 0x09);
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL);
|
||||
|
||||
// Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "hos.h"
|
||||
#include "hos_config.h"
|
||||
#include "sept.h"
|
||||
#include "secmon_exo.h"
|
||||
#include "../config/config.h"
|
||||
#include "../gfx/di.h"
|
||||
@@ -43,6 +44,7 @@
|
||||
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();
|
||||
@@ -50,6 +52,19 @@ extern void sd_unmount();
|
||||
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
#define SECMON_MB_ADDR 0x40002EF8
|
||||
#define SECMON7_MB_ADDR 0x400000F8
|
||||
|
||||
// Secmon mailbox.
|
||||
typedef struct _secmon_mailbox_t
|
||||
{
|
||||
// < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
|
||||
// >= 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot.
|
||||
u32 in;
|
||||
// Non-zero: Secmon ready.
|
||||
u32 out;
|
||||
} secmon_mailbox_t;
|
||||
|
||||
static const u8 keyblob_keyseeds[][0x10] = {
|
||||
{ 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, //1.0.0
|
||||
{ 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, //3.0.0
|
||||
@@ -68,7 +83,7 @@ static const u8 master_keyseed_retail[0x10] =
|
||||
static const u8 console_keyseed[0x10] =
|
||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||
|
||||
static const u8 key8_keyseed[] =
|
||||
static const u8 package2_keyseed[] =
|
||||
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
|
||||
|
||||
static const u8 master_keyseed_4xx_5xx_610[0x10] =
|
||||
@@ -129,9 +144,7 @@ void _pmc_scratch_lock(u32 kb)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE7) = 0xFFFFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) = 0xFFAAFFFF;
|
||||
break;
|
||||
case KB_FIRMWARE_VERSION_400:
|
||||
case KB_FIRMWARE_VERSION_500:
|
||||
case KB_FIRMWARE_VERSION_600:
|
||||
default:
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
|
||||
@@ -165,34 +178,44 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
u8 tmp[0x20];
|
||||
u32 retries = 0;
|
||||
|
||||
tsec_ctxt->size = 0xF00;
|
||||
|
||||
if (kb > KB_FIRMWARE_VERSION_MAX)
|
||||
return 0;
|
||||
|
||||
// Get TSEC key.
|
||||
if (kb >= KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
if (kb <= KB_FIRMWARE_VERSION_600)
|
||||
tsec_ctxt->size = 0xF00;
|
||||
else if (kb == KB_FIRMWARE_VERSION_620)
|
||||
tsec_ctxt->size = 0x2900;
|
||||
else
|
||||
tsec_ctxt->size = 0x3000;
|
||||
|
||||
// Prepare smmu tsec page for 6.2.0.
|
||||
if (kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
u8 *tsec_paged = (u8 *)page_alloc(3);
|
||||
memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size);
|
||||
tsec_ctxt->fw = tsec_paged;
|
||||
}
|
||||
|
||||
while (tsec_query(tmp, kb, tsec_ctxt) < 0)
|
||||
// Get TSEC key.
|
||||
if (kb <= KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
memset(tmp, 0x00, 0x20);
|
||||
retries++;
|
||||
|
||||
// We rely on racing conditions, make sure we cover even the unluckiest cases.
|
||||
if (retries > 15)
|
||||
while (tsec_query(tmp, kb, tsec_ctxt) < 0)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%k\nFailed to get TSEC keys. Please try again.%k\n\n", 0xFFFF0000, 0xFFCCCCCC);
|
||||
return 0;
|
||||
memset(tmp, 0x00, 0x20);
|
||||
retries++;
|
||||
|
||||
// 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);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kb >= KB_FIRMWARE_VERSION_620)
|
||||
if (kb >= KB_FIRMWARE_VERSION_700)
|
||||
se_aes_unwrap_key(8, 12, package2_keyseed);
|
||||
else if (kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
// Set TSEC key.
|
||||
se_aes_key_set(12, tmp, 0x10);
|
||||
@@ -203,7 +226,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
se_aes_key_set(8, tmp + 0x10, 0x10);
|
||||
se_aes_unwrap_key(8, 8, master_keyseed_620);
|
||||
se_aes_unwrap_key(8, 8, master_keyseed_retail);
|
||||
se_aes_unwrap_key(8, 8, key8_keyseed);
|
||||
se_aes_unwrap_key(8, 8, package2_keyseed);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -264,7 +287,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
|
||||
// Package2 key.
|
||||
se_key_acc_ctrl(8, 0x15);
|
||||
se_aes_unwrap_key(8, 12, key8_keyseed);
|
||||
se_aes_unwrap_key(8, 12, package2_keyseed);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -285,10 +308,10 @@ 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,\nVersion (= '%s').%k\n", 0xFFFF0000, (char *)ctxt->pkg1 + 0x10, 0xFFCCCCCC);
|
||||
gfx_printf(&gfx_con, "%kUnknown pkg1 version.%k\n", 0xFFFF0000, 0xFFCCCCCC);
|
||||
goto out;
|
||||
}
|
||||
gfx_printf(&gfx_con, "Identified pkg1 ('%s'),\nKeyblob version %d\n\n", (char *)(ctxt->pkg1 + 0x10), ctxt->pkg1_id->kb);
|
||||
gfx_printf(&gfx_con, "Identified pkg1 and Keyblob %d\n\n", ctxt->pkg1_id->kb);
|
||||
|
||||
// Read the correct keyblob.
|
||||
ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
||||
@@ -362,6 +385,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
{
|
||||
launch_ctxt_t ctxt;
|
||||
tsec_ctxt_t tsec_ctxt;
|
||||
volatile secmon_mailbox_t *secmon_mb;
|
||||
|
||||
memset(&ctxt, 0, sizeof(launch_ctxt_t));
|
||||
list_init(&ctxt.kip1_list);
|
||||
@@ -371,7 +395,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
// Try to parse config if present.
|
||||
if (cfg && !_parse_boot_config(&ctxt, cfg))
|
||||
if (cfg && !parse_boot_config(&ctxt, cfg))
|
||||
return 0;
|
||||
|
||||
gfx_printf(&gfx_con, "Initializing...\n\n");
|
||||
@@ -380,17 +404,26 @@ int hos_launch(ini_sec_t *cfg)
|
||||
if (!_read_emmc_pkg1(&ctxt))
|
||||
return 0;
|
||||
|
||||
gfx_printf(&gfx_con, "Loaded pkg1 and keyblob\n");
|
||||
// Check if fuses lower than 4.0.0 and if yes apply NO Gamecard patch.
|
||||
if (h_cfg.autonogc && !(fuse_read_odm(7) & ~0xF) && ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_400)
|
||||
config_kip1patch(&ctxt, "nogc");
|
||||
|
||||
gfx_printf(&gfx_con, "Loaded pkg1 & keyblob\n");
|
||||
|
||||
// Generate keys.
|
||||
if (!h_cfg.se_keygen_done || ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_620)
|
||||
if (!h_cfg.se_keygen_done || ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
tsec_ctxt.key_ver = 1;
|
||||
tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off;
|
||||
tsec_ctxt.pkg1 = ctxt.pkg1;
|
||||
tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off;
|
||||
tsec_ctxt.secmon_base = ctxt.pkg1_id->secmon_base;
|
||||
|
||||
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
||||
{
|
||||
gfx_printf(&gfx_con, "Failed to run sept\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!keygen(ctxt.keyblob, ctxt.pkg1_id->kb, &tsec_ctxt))
|
||||
return 0;
|
||||
DPRINTF("Generated keys\n");
|
||||
@@ -404,9 +437,13 @@ int hos_launch(ini_sec_t *cfg)
|
||||
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
||||
pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1);
|
||||
|
||||
pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, NULL, ctxt.pkg1_id, ctxt.pkg1);
|
||||
|
||||
gfx_printf(&gfx_con, "Decrypted and unpacked pkg1\n");
|
||||
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, NULL, ctxt.pkg1_id, ctxt.pkg1);
|
||||
gfx_printf(&gfx_con, "Decrypted & unpacked pkg1\n");
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Replace 'warmboot.bin' if requested.
|
||||
@@ -414,6 +451,11 @@ int hos_launch(ini_sec_t *cfg)
|
||||
memcpy((void *)ctxt.pkg1_id->warmboot_base, ctxt.warmboot, ctxt.warmboot_size);
|
||||
else
|
||||
{
|
||||
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kNo warmboot provided!%k\n", 0xFFFF0000, 0xFFCCCCCC);
|
||||
return 0;
|
||||
}
|
||||
// Else we patch it to allow downgrading.
|
||||
patch_t *warmboot_patchset = ctxt.pkg1_id->warmboot_patchset;
|
||||
gfx_printf(&gfx_con, "%kPatching Warmboot%k\n", 0xFFFFBA00, 0xFFCCCCCC);
|
||||
@@ -427,7 +469,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
// Replace 'SecureMonitor' if requested.
|
||||
if (ctxt.secmon)
|
||||
memcpy((void *)ctxt.pkg1_id->secmon_base, ctxt.secmon, ctxt.secmon_size);
|
||||
else
|
||||
else if (ctxt.pkg1_id->secmon_patchset)
|
||||
{
|
||||
// Else we patch it to allow for an unsigned package2 and patched kernel.
|
||||
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
|
||||
@@ -436,7 +478,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
|
||||
}
|
||||
|
||||
gfx_printf(&gfx_con, "Loaded warmboot.bin and secmon\n");
|
||||
gfx_printf(&gfx_con, "Loaded warmboot and secmon\n");
|
||||
|
||||
// Read package2.
|
||||
u8 *bootConfigBuf = _read_emmc_pkg2(&ctxt);
|
||||
@@ -495,7 +537,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
}
|
||||
|
||||
// Merge extra KIP1s into loaded ones.
|
||||
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFFFFBA00, 0xFFCCCCCC);
|
||||
gfx_printf(&gfx_con, "%kPatching kips%k\n", 0xFFFFBA00, 0xFFCCCCCC);
|
||||
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
|
||||
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
|
||||
|
||||
@@ -503,7 +545,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, "%kREQUESTED PATCH '%s' NOT APPLIED!%k\n", 0xFFFF0000, unappliedPatch, 0xFFCCCCCC);
|
||||
gfx_printf(&gfx_con, "%kFailed to apply '%s'!%k\n", 0xFFFF0000, unappliedPatch, 0xFFCCCCCC);
|
||||
sd_unmount(); // Just exiting is not enough until pkg2_patch_kips stops modifying the string passed into it.
|
||||
|
||||
_free_launch_components(&ctxt);
|
||||
@@ -513,10 +555,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
// Rebuild and encrypt package2.
|
||||
pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info);
|
||||
|
||||
gfx_printf(&gfx_con, "Rebuilt and loaded pkg2\n");
|
||||
|
||||
// Unmount SD card.
|
||||
sd_unmount();
|
||||
gfx_printf(&gfx_con, "Rebuilt & loaded pkg2\n");
|
||||
|
||||
gfx_printf(&gfx_con, "\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC);
|
||||
|
||||
@@ -547,7 +586,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
case KB_FIRMWARE_VERSION_600:
|
||||
se_key_acc_ctrl(12, 0xFF);
|
||||
se_key_acc_ctrl(15, 0xFF);
|
||||
case KB_FIRMWARE_VERSION_620:
|
||||
default:
|
||||
bootStateDramPkg2 = 2;
|
||||
bootStatePkg2Continue = 4;
|
||||
break;
|
||||
@@ -570,7 +609,10 @@ 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, ctxt.debugmode);
|
||||
config_exosphere(ctxt.pkg1_id->id, ctxt.pkg1_id->kb, (void *)ctxt.pkg1_id->warmboot_base, ctxt.pkg1, ctxt.debugmode);
|
||||
|
||||
// Unmount SD card.
|
||||
sd_unmount();
|
||||
|
||||
// Finalize MC carveout.
|
||||
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_301)
|
||||
@@ -583,39 +625,42 @@ int hos_launch(ini_sec_t *cfg)
|
||||
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_620)
|
||||
_sysctr0_reset();
|
||||
|
||||
// < 4.0.0 pkg1.1 locks PMC scratches.
|
||||
//_pmc_scratch_lock(ctxt.pkg1_id->kb);
|
||||
|
||||
// Set secmon mailbox address.
|
||||
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
||||
secmon_mb = (secmon_mailbox_t *)SECMON7_MB_ADDR;
|
||||
else
|
||||
secmon_mb = (secmon_mailbox_t *)SECMON_MB_ADDR;
|
||||
|
||||
// Start from DRAM ready signal and reset outgoing value.
|
||||
secmon_mb->in = bootStateDramPkg2;
|
||||
secmon_mb->out = 0;
|
||||
|
||||
// Free allocated memory.
|
||||
ini_free_section(cfg);
|
||||
_free_launch_components(&ctxt);
|
||||
|
||||
// < 4.0.0 pkg1.1 locks PMC scratches.
|
||||
//_pmc_scratch_lock(ctxt.pkg1_id->kb);
|
||||
|
||||
// < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
|
||||
// >= 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot.
|
||||
vu32 *mb_in = (vu32 *)0x40002EF8;
|
||||
// Non-zero: Secmon ready.
|
||||
vu32 *mb_out = (vu32 *)0x40002EFC;
|
||||
|
||||
// Start from DRAM ready signal.
|
||||
*mb_in = bootStateDramPkg2;
|
||||
*mb_out = 0;
|
||||
|
||||
// Disable display. This must be executed before secmon to provide support for all fw versions.
|
||||
display_end();
|
||||
|
||||
// Clear EMC_SCRATCH0.
|
||||
EMC(EMC_SCRATCH0) = 0;
|
||||
|
||||
// Wait for secmon to get ready.
|
||||
if (smmu_is_used())
|
||||
smmu_exit();
|
||||
else
|
||||
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
|
||||
while (!*mb_out)
|
||||
while (!secmon_mb->out)
|
||||
usleep(1); // This only works when in IRAM or with a trained DRAM.
|
||||
|
||||
// Signal pkg2 ready and continue boot.
|
||||
*mb_in = bootStatePkg2Continue;
|
||||
secmon_mb->in = bootStatePkg2Continue;
|
||||
|
||||
// Halt ourselves in waitevent state and resume if there's JTAG activity.
|
||||
while (1)
|
||||
while (true)
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = 0x50000000;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
#define KB_FIRMWARE_VERSION_500 4
|
||||
#define KB_FIRMWARE_VERSION_600 5
|
||||
#define KB_FIRMWARE_VERSION_620 6
|
||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_620
|
||||
#define KB_FIRMWARE_VERSION_700 7
|
||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_700
|
||||
|
||||
#define HOS_PKG11_MAGIC 0x31314B50
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -156,7 +156,7 @@ static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_kip1patch(launch_ctxt_t *ctxt, const char *value)
|
||||
int config_kip1patch(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return 0;
|
||||
@@ -197,14 +197,14 @@ static const cfg_handler_t _config_handlers[] = {
|
||||
{ "secmon", _config_secmon },
|
||||
{ "kernel", _config_kernel },
|
||||
{ "kip1", _config_kip1 },
|
||||
{ "kip1patch", _config_kip1patch },
|
||||
{ "kip1patch", config_kip1patch },
|
||||
{ "fullsvcperm", _config_svcperm },
|
||||
{ "debugmode", _config_debugmode },
|
||||
{ "atmosphere", _config_atmosphere },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
int _parse_boot_config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
|
||||
int parse_boot_config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
|
||||
{
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
#include "hos.h"
|
||||
|
||||
int _parse_boot_config(launch_ctxt_t *ctxt, ini_sec_t *cfg);
|
||||
int parse_boot_config(launch_ctxt_t *ctxt, ini_sec_t *cfg);
|
||||
int config_kip1patch(launch_ctxt_t *ctxt, const char *value);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -20,8 +20,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "pkg1.h"
|
||||
#include "../utils/aarch64_util.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../sec/se.h"
|
||||
#include "../utils/aarch64_util.h"
|
||||
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
#define _NOPv7() 0xE320F000
|
||||
|
||||
@@ -116,20 +119,6 @@ PATCHSET_DEF(_warmboot_4_patchset,
|
||||
{ 0x558, _NOPv7() } // Segment id check.
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_warmboot_5_patchset,
|
||||
{ 0x544, _NOPv7() }, // Fuse check.
|
||||
{ 0x558, _NOPv7() } // Segment id check.
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_warmboot_6_patchset,
|
||||
{ 0x544, _NOPv7() }, // Fuse check.
|
||||
{ 0x558, _NOPv7() } // Segment id check.
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_warmboot_620_patchset,
|
||||
{ 0x544, _NOPv7() }, // Fuse check.
|
||||
{ 0x558, _NOPv7() } // Segment id check.
|
||||
);
|
||||
|
||||
/*
|
||||
* package1.1 header: <wb, ldr, sm>
|
||||
@@ -142,23 +131,30 @@ PATCHSET_DEF(_warmboot_620_patchset,
|
||||
* 5.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 6.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 6.2: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 7.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
*/
|
||||
|
||||
static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, _secmon_1_patchset, _warmboot_1_patchset }, //1.0.0 (Patched relocator)
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_2_patchset, _warmboot_2_patchset }, //2.0.0 - 2.3.0
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_5_patchset }, //5.0.0 - 5.1.0
|
||||
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_6_patchset }, //6.0.0 - 6.1.0
|
||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_620_patchset }, //6.2.0
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, _secmon_1_patchset, _warmboot_1_patchset }, //1.0.0 (Patched relocator)
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_2_patchset, _warmboot_2_patchset }, //2.0.0 - 2.3.0
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_4_patchset }, //5.0.0 - 5.1.0
|
||||
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_4_patchset }, //6.0.0 - 6.1.0
|
||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_4_patchset }, //6.2.0
|
||||
{ "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, _warmboot_4_patchset }, //7.0.0
|
||||
{ "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, _warmboot_4_patchset }, //7.0.1
|
||||
{ NULL } //End.
|
||||
};
|
||||
|
||||
|
||||
const pkg1_id_t *pkg1_identify(u8 *pkg1)
|
||||
{
|
||||
char build_date[15];
|
||||
memcpy(build_date, (char *)(pkg1 + 0x10), 14);
|
||||
build_date[14] = 0;
|
||||
gfx_printf(&gfx_con, "Found pkg1 ('%s').\n\n", build_date);
|
||||
|
||||
for (u32 i = 0; _pkg1_ids[i].id; i++)
|
||||
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12))
|
||||
return &_pkg1_ids[i];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
/*#include "util.h"
|
||||
@@ -44,6 +47,7 @@ extern gfx_con_t gfx_con;
|
||||
#define FREE_CODE_OFF_1ST_400 0x52890
|
||||
#define FREE_CODE_OFF_1ST_500 0x5C020
|
||||
#define FREE_CODE_OFF_1ST_600 0x5EE00
|
||||
#define FREE_CODE_OFF_1ST_700 0x5FEC0
|
||||
|
||||
#define ID_SND_OFF_100 0x23CC0
|
||||
#define ID_SND_OFF_200 0x3F134
|
||||
@@ -52,6 +56,7 @@ extern gfx_con_t gfx_con;
|
||||
#define ID_SND_OFF_400 0x2AF64
|
||||
#define ID_SND_OFF_500 0x2AD34
|
||||
#define ID_SND_OFF_600 0x2BB8C
|
||||
#define ID_SND_OFF_700 0x2D044
|
||||
|
||||
#define ID_RCV_OFF_100 0x219F0
|
||||
#define ID_RCV_OFF_200 0x3D1A8
|
||||
@@ -60,13 +65,14 @@ extern gfx_con_t gfx_con;
|
||||
#define ID_RCV_OFF_400 0x28F6C
|
||||
#define ID_RCV_OFF_500 0x28DAC
|
||||
#define ID_RCV_OFF_600 0x29B6C
|
||||
#define ID_RCV_OFF_700 0x2B23C
|
||||
|
||||
static u32 PRC_ID_SND_100[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0E03EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9412948, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_100 (FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100) + 4)
|
||||
#define FREE_CODE_OFF_2ND_100 (FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_100[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A1C03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
|
||||
@@ -78,7 +84,7 @@ static u32 PRC_ID_SND_200[] =
|
||||
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9413148, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_200 (FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200) + 4)
|
||||
#define FREE_CODE_OFF_2ND_200 (FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_200[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
|
||||
@@ -90,7 +96,7 @@ static u32 PRC_ID_SND_300[] =
|
||||
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_300 (FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300) + 4)
|
||||
#define FREE_CODE_OFF_2ND_300 (FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_300[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
|
||||
@@ -102,7 +108,7 @@ static u32 PRC_ID_SND_302[] =
|
||||
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_302 (FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302) + 4)
|
||||
#define FREE_CODE_OFF_2ND_302 (FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_302[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
|
||||
@@ -114,7 +120,7 @@ static u32 PRC_ID_SND_400[] =
|
||||
0x2A1703EA, 0xD37EF54A, 0xF86A6B8A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
|
||||
0xEB09015F, 0x54000060, 0xF94053EA, 0xF9415948, 0xF94053EA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_400 (FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400) + 4)
|
||||
#define FREE_CODE_OFF_2ND_400 (FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_400[] =
|
||||
{
|
||||
0xF9403BED, 0x2A0E03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
|
||||
@@ -126,7 +132,7 @@ static u32 PRC_ID_SND_500[] =
|
||||
0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
|
||||
0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_500 (FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500) + 4)
|
||||
#define FREE_CODE_OFF_2ND_500 (FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_500[] =
|
||||
{
|
||||
0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
|
||||
@@ -139,7 +145,7 @@ static u32 PRC_ID_SND_600[] =
|
||||
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
|
||||
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_600 (FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600) + 4)
|
||||
#define FREE_CODE_OFF_2ND_600 (FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_600[] =
|
||||
{
|
||||
0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
|
||||
@@ -147,6 +153,20 @@ static u32 PRC_ID_RCV_600[] =
|
||||
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
|
||||
};
|
||||
|
||||
static u32 PRC_ID_SND_700[] =
|
||||
{
|
||||
0xA9BF2FEA, 0xF9403BEB, 0x2A1903EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
|
||||
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0,
|
||||
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_700 (FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700) + sizeof(u32))
|
||||
static u32 PRC_ID_RCV_700[] =
|
||||
{
|
||||
0xA9BF2FEA, 0xF9404FEB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
|
||||
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0,
|
||||
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
|
||||
};
|
||||
|
||||
// Include kernel patches here, so we can utilize pkg1 id
|
||||
KERNEL_PATCHSET_DEF(_kernel_1_patchset,
|
||||
{ SVC_VERIFY_DS, 0x3764C, _NOP(), NULL }, // Disable SVC verifications
|
||||
@@ -155,11 +175,11 @@ KERNEL_PATCHSET_DEF(_kernel_1_patchset,
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_100, _B(ID_SND_OFF_100, FREE_CODE_OFF_1ST_100), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_100, sizeof(PRC_ID_SND_100) >> 2, PRC_ID_SND_100}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), ID_SND_OFF_100 + 4), NULL},
|
||||
_B(FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), ID_SND_OFF_100 + sizeof(u32)), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_100, _B(ID_RCV_OFF_100, FREE_CODE_OFF_2ND_100), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_100, sizeof(PRC_ID_RCV_100) >> 2, PRC_ID_RCV_100}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), ID_RCV_OFF_100 + 4), NULL}
|
||||
_B(FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), ID_RCV_OFF_100 + sizeof(u32)), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_2_patchset,
|
||||
@@ -169,11 +189,11 @@ KERNEL_PATCHSET_DEF(_kernel_2_patchset,
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_200, _B(ID_SND_OFF_200, FREE_CODE_OFF_1ST_200), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_200, sizeof(PRC_ID_SND_200) >> 2, PRC_ID_SND_200}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), ID_SND_OFF_200 + 4), NULL},
|
||||
_B(FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), ID_SND_OFF_200 + sizeof(u32)), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_200, _B(ID_RCV_OFF_200, FREE_CODE_OFF_2ND_200), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_200, sizeof(PRC_ID_RCV_200) >> 2, PRC_ID_RCV_200}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), ID_RCV_OFF_200 + 4), NULL}
|
||||
_B(FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), ID_RCV_OFF_200 + sizeof(u32)), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_3_patchset,
|
||||
@@ -183,11 +203,11 @@ KERNEL_PATCHSET_DEF(_kernel_3_patchset,
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_300, _B(ID_SND_OFF_300, FREE_CODE_OFF_1ST_300), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_300, sizeof(PRC_ID_SND_300) >> 2, PRC_ID_SND_300}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), ID_SND_OFF_300 + 4), NULL},
|
||||
_B(FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), ID_SND_OFF_300 + sizeof(u32)), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_300, _B(ID_RCV_OFF_300, FREE_CODE_OFF_2ND_300), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_300, sizeof(PRC_ID_RCV_300) >> 2, PRC_ID_RCV_300}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_300 + 4), NULL}
|
||||
_B(FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_300 + sizeof(u32)), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_302_patchset,
|
||||
@@ -197,11 +217,11 @@ KERNEL_PATCHSET_DEF(_kernel_302_patchset,
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_302, _B(ID_SND_OFF_302, FREE_CODE_OFF_1ST_302), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_302, sizeof(PRC_ID_SND_302) >> 2, PRC_ID_SND_302}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302), ID_SND_OFF_302 + 4), NULL},
|
||||
_B(FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302), ID_SND_OFF_302 + sizeof(u32)), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_302, _B(ID_RCV_OFF_302, FREE_CODE_OFF_2ND_302), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_302, sizeof(PRC_ID_RCV_302) >> 2, PRC_ID_RCV_302}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_302), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_302), ID_RCV_OFF_302 + 4), NULL}
|
||||
_B(FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_302), ID_RCV_OFF_302 + sizeof(u32)), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_4_patchset,
|
||||
@@ -211,11 +231,11 @@ KERNEL_PATCHSET_DEF(_kernel_4_patchset,
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_400, _B(ID_SND_OFF_400, FREE_CODE_OFF_1ST_400), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_400, sizeof(PRC_ID_SND_400) >> 2, PRC_ID_SND_400}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), // Branch back and skip 2 instructions.
|
||||
_B(FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), ID_SND_OFF_400 + 8), NULL},
|
||||
_B(FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), ID_SND_OFF_400 + sizeof(u32) * 2), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_400, _B(ID_RCV_OFF_400, FREE_CODE_OFF_2ND_400), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_400, sizeof(PRC_ID_RCV_400) >> 2, PRC_ID_RCV_400}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), ID_RCV_OFF_400 + 4), NULL}
|
||||
_B(FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), ID_RCV_OFF_400 + sizeof(u32)), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_5_patchset,
|
||||
@@ -226,11 +246,11 @@ KERNEL_PATCHSET_DEF(_kernel_5_patchset,
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_500, _B(ID_SND_OFF_500, FREE_CODE_OFF_1ST_500), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_500, sizeof(PRC_ID_SND_500) >> 2, PRC_ID_SND_500}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), // Branch back and skip 2 instructions.
|
||||
_B(FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), ID_SND_OFF_500 + 8), NULL},
|
||||
_B(FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), ID_SND_OFF_500 + sizeof(u32) * 2), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_500, _B(ID_RCV_OFF_500, FREE_CODE_OFF_2ND_500), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_500, sizeof(PRC_ID_RCV_500) >> 2, PRC_ID_RCV_500}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), // Branch back and skip 2 instructions.
|
||||
_B(FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), ID_RCV_OFF_500 + 8), NULL}
|
||||
_B(FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), ID_RCV_OFF_500 + sizeof(u32) * 2), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_6_patchset,
|
||||
@@ -241,11 +261,26 @@ KERNEL_PATCHSET_DEF(_kernel_6_patchset,
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_600, _B(ID_SND_OFF_600, FREE_CODE_OFF_1ST_600), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_600, sizeof(PRC_ID_SND_600) >> 2, PRC_ID_SND_600}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), // Branch back and skip 4 instructions.
|
||||
_B(FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), ID_SND_OFF_600 + 0x10), NULL},
|
||||
_B(FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), ID_SND_OFF_600 + sizeof(u32) * 4), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_600, _B(ID_RCV_OFF_600, FREE_CODE_OFF_2ND_600), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_600, sizeof(PRC_ID_RCV_600) >> 2, PRC_ID_RCV_600}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), // Branch back and skip 4 instructions.
|
||||
_B(FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), ID_RCV_OFF_600 + 0x10), NULL}
|
||||
_B(FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), ID_RCV_OFF_600 + sizeof(u32) * 4), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_7_patchset,
|
||||
{ SVC_GENERIC, 0x3C6E0, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
|
||||
{ SVC_VERIFY_DS, 0x49E5C, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x581B0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_700, _B(ID_SND_OFF_700, FREE_CODE_OFF_1ST_700), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_700, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
|
||||
_B(FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), ID_SND_OFF_700 + sizeof(u32) * 4), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_700, _B(ID_RCV_OFF_700, FREE_CODE_OFF_2ND_700), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_700, sizeof(PRC_ID_RCV_700) >> 2, PRC_ID_RCV_700}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_700 + sizeof(PRC_ID_RCV_700), // Branch back and skip 4 instructions.
|
||||
_B(FREE_CODE_OFF_2ND_700 + sizeof(PRC_ID_RCV_700), ID_RCV_OFF_700 + sizeof(u32) * 4), NULL}
|
||||
);
|
||||
|
||||
static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
|
||||
@@ -257,6 +292,7 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
|
||||
{ 0x485d0157, _kernel_4_patchset }, //4.0.0 - 4.1.0
|
||||
{ 0xf3c363f2, _kernel_5_patchset }, //5.0.0 - 5.1.0
|
||||
{ 0x64ce1a44, _kernel_6_patchset }, //6.0.0 - 6.2.0
|
||||
{ 0x908175e1, _kernel_7_patchset }, //7.0.0
|
||||
{ 0, 0 } //End.
|
||||
};
|
||||
|
||||
@@ -277,195 +313,238 @@ enum kip_offset_section
|
||||
#define GET_KIP_PATCH_OFFSET(x) (x & KIP_PATCH_OFFSET_MASK)
|
||||
#define KPS(x) ((u32)(x) << KIP_PATCH_SECTION_SHIFT)
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_100[] =
|
||||
static kip1_patch_t _fs_nosigchk_100[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x194A0, 4, "\xBA\x09\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x3A79C, 4, "\xE0\x06\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_100[] =
|
||||
static kip1_patchset_t _fs_patches_100[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_100 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_200[] =
|
||||
static kip1_patch_t _fs_nosigchk_200[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x15DF4, 4, "\xBC\x0A\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x3F720, 4, "\x00\x06\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_200[] =
|
||||
static kip1_patchset_t _fs_patches_200[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_200 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_210[] =
|
||||
static kip1_patch_t _fs_nosigchk_210[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x15F64, 4, "\xDF\x0A\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x3FAF8, 4, "\x00\x06\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_210[] =
|
||||
static kip1_patchset_t _fs_patches_210[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_210 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_300[] =
|
||||
static kip1_patch_t _fs_nosigchk_300[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x18E24, 4, "\x52\x0C\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x49EC8, 4, "\x40\x04\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_300[] =
|
||||
static kip1_patchset_t _fs_patches_300[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_300 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_30x[] =
|
||||
static kip1_patch_t _fs_nosigchk_30x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x18E90, 4, "\x52\x0C\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x49F34, 4, "\xE0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_30x[] =
|
||||
static kip1_patchset_t _fs_patches_30x[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_30x },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_4xx[] =
|
||||
static kip1_patch_t _fs_nosigchk_4xx[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x1C4FC, 4, "\x3C\x2F\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x57934, 4, "\xE0\x02\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_40x[] =
|
||||
static kip1_patch_t _fs_nogc_40x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xA3458, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" },
|
||||
{ KPS(KIP_TEXT) | 0xAAB44, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_40x[] =
|
||||
static kip1_patchset_t _fs_patches_40x[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_4xx },
|
||||
{ "nogc", _fs_nogc_40x },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_410[] =
|
||||
static kip1_patch_t _fs_nogc_410[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xA34BC, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" },
|
||||
{ KPS(KIP_TEXT) | 0xAABA8, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_410[] =
|
||||
static kip1_patchset_t _fs_patches_410[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_4xx },
|
||||
{ "nogc", _fs_nogc_410 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_50x[] =
|
||||
static kip1_patch_t _fs_nosigchk_50x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x22DDC, 4, "\x7D\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x7D490, 4, "\x40\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_50x[] =
|
||||
static kip1_patch_t _fs_nogc_50x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xCF3C4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0xD73A0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_50x[] =
|
||||
static kip1_patchset_t _fs_patches_50x[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_50x },
|
||||
{ "nogc", _fs_nogc_50x },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_510[] =
|
||||
static kip1_patch_t _fs_nosigchk_510[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x22E0C, 4, "\x85\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x7D860, 4, "\x40\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_510[] =
|
||||
static kip1_patch_t _fs_nogc_510[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xCF794, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0xD7770, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_510[] =
|
||||
static kip1_patchset_t _fs_patches_510[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_510 },
|
||||
{ "nogc", _fs_nogc_510 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_600[] =
|
||||
static kip1_patch_t _fs_nosigchk_600[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x712A8, 4, "\x8E\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0xEB08C, 4, "\xC0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_600_exfat[] =
|
||||
static kip1_patch_t _fs_nosigchk_600_exfat[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x7C9A8, 4, "\x8E\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0xF678C, 4, "\xC0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_600[] =
|
||||
static kip1_patch_t _fs_nogc_600[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x12CC20, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1538F4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_600_exfat[] =
|
||||
static kip1_patch_t _fs_nogc_600_exfat[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x138320, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x15EFF4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_600[] =
|
||||
static kip1_patchset_t _fs_patches_600[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_600 },
|
||||
{ "nogc", _fs_nogc_600 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_600_exfat[] =
|
||||
static kip1_patchset_t _fs_patches_600_exfat[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_600_exfat },
|
||||
{ "nogc", _fs_nogc_600_exfat },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_700[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x74A2C, 4, "\x31\x43\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0xF25E4, 4, "\xC0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_700_exfat[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x7FFDC, 4, "\x31\x43\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0xFDB94, 4, "\xC0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_700[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x134160, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x15BF04, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_700_exfat[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x13F710, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1674B4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_700[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_700 },
|
||||
{ "nogc", _fs_nogc_700 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_700_exfat[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_700_exfat },
|
||||
{ "nogc", _fs_nogc_700_exfat },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// SHA256 hashes.
|
||||
static kip1_id_t _kip_ids[] =
|
||||
{
|
||||
{ "FS", "\xde\x9f\xdd\xa4\x08\x5d\xd5\xfe\x68\xdc\xb2\x0b\x41\x09\x5b\xb4", _fs_patches_100 }, // FS 1.0.0
|
||||
@@ -489,7 +568,9 @@ static kip1_id_t _kip_ids[] =
|
||||
{ "FS", "\x1b\x82\xcb\x22\x18\x67\xcb\x52\xc4\x4a\x86\x9e\xa9\x1a\x1a\xdd", _fs_patches_600 }, // FS 6.0.0-4.0
|
||||
{ "FS", "\x96\x6a\xdd\x3d\x20\xb6\x27\x13\x2c\x5a\x8d\xa4\x9a\xc9\xd8\xdd", _fs_patches_600_exfat }, // FS 6.0.0-4.0 exfat
|
||||
{ "FS", "\x3a\x57\x4d\x43\x61\x86\x19\x1d\x17\x88\xeb\x2c\x0f\x07\x6b\x11", _fs_patches_600 }, // FS 6.0.0-5.0
|
||||
{ "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4\xc2\xd7\xb7\x36\x24\x02\x76\xb3", _fs_patches_600_exfat } // FS 6.0.0-5.0 exfat
|
||||
{ "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4\xc2\xd7\xb7\x36\x24\x02\x76\xb3", _fs_patches_600_exfat }, // FS 6.0.0-5.0 exfat
|
||||
{ "FS", "\x2A\xDB\xE9\x7E\x9B\x5F\x41\x77\x9E\xC9\x5F\xFE\x26\x99\xC9\x33", _fs_patches_700 }, // FS 7.0.0
|
||||
{ "FS", "\x2C\xCE\x65\x9C\xEC\x53\x6A\x8E\x4D\x91\xF3\xBE\x4B\x74\xBE\xD3", _fs_patches_700_exfat } // FS 7.0.0 exfat
|
||||
};
|
||||
|
||||
const pkg2_kernel_id_t *pkg2_identify(u32 id)
|
||||
@@ -902,3 +983,4 @@ DPRINTF("INI1 encrypted\n");
|
||||
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
@@ -117,16 +117,16 @@ typedef struct _pkg2_kernel_id_t
|
||||
|
||||
typedef struct _kip1_patch_t
|
||||
{
|
||||
u32 offset; //section+offset of patch to apply
|
||||
u32 length; //in bytes, 0 means last patch
|
||||
const char* srcData; //that must match
|
||||
const char* dstData; //that it gets replaced by
|
||||
u32 offset; // section+offset of patch to apply.
|
||||
u32 length; // In bytes, 0 means last patch.
|
||||
const char* srcData; // That must match.
|
||||
const char* dstData; // That it gets replaced by.
|
||||
} kip1_patch_t;
|
||||
|
||||
typedef struct _kip1_patchset_t
|
||||
{
|
||||
const char* name; //NULL means end
|
||||
kip1_patch_t* patches; //NULL means not necessary
|
||||
const char* name; // NULL means end.
|
||||
kip1_patch_t* patches; // NULL means not necessary.
|
||||
} kip1_patchset_t;
|
||||
|
||||
typedef struct _kip1_id_t
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (C) 2018-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,
|
||||
@@ -17,25 +17,43 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "hos.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
#include "../utils/types.h"
|
||||
|
||||
// Exosphère mailbox defines.
|
||||
#define EXO_MAGIC_ADDR 0x40002E40
|
||||
#define EXO_MAGIC_VAL 0x31434258
|
||||
#define EXO_FWNO_ADDR 0x40002E44
|
||||
#define EXO_FLAGS_ADDR 0x40002E48
|
||||
#define EXO_FLAG_620_KGN (1 << 0)
|
||||
#define EXO_FLAG_DBG_PRIV (1 << 1)
|
||||
#define EXO_FLAG_DBG_USER (1 << 2)
|
||||
typedef struct _exo_cfg_t
|
||||
{
|
||||
vu32 magic;
|
||||
vu32 fwno;
|
||||
vu32 flags;
|
||||
vu32 rsvd;
|
||||
} exo_cfg_t;
|
||||
|
||||
void config_exosphere(const char *id, u32 kb, bool debug)
|
||||
typedef struct _atm_meta_t
|
||||
{
|
||||
uint32_t magic;
|
||||
uint32_t fwno;
|
||||
} wb_cfg_t;
|
||||
|
||||
#define ATM_WB_HEADER_OFF 0x244
|
||||
#define ATM_WB_MAGIC 0x30544257
|
||||
|
||||
// Exosphère mailbox defines.
|
||||
#define EXO_CFG_DEPR_ADDR 0x40002E40 // Deprecated.
|
||||
#define EXO_CFG_ADDR 0x8000F000
|
||||
#define EXO_MAGIC_DEPR_VAL 0x31434258
|
||||
#define EXO_MAGIC_VAL 0x304F5845
|
||||
#define EXO_FLAG_620_KGN (1 << 0)
|
||||
#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)
|
||||
{
|
||||
u32 exoFwNo = 0;
|
||||
u32 exoFlags = 0;
|
||||
|
||||
vu32 *mb_exo_magic = (vu32 *)EXO_MAGIC_ADDR;
|
||||
vu32 *mb_exo_fw_no = (vu32 *)EXO_FWNO_ADDR;
|
||||
vu32 *mb_exo_flags = (vu32 *)EXO_FLAGS_ADDR;
|
||||
volatile exo_cfg_t *exo_cfg_depr = (exo_cfg_t *)EXO_CFG_DEPR_ADDR;
|
||||
volatile exo_cfg_t *exo_cfg = (exo_cfg_t *)EXO_CFG_ADDR;
|
||||
|
||||
switch (kb)
|
||||
{
|
||||
@@ -53,14 +71,42 @@ void config_exosphere(const char *id, u32 kb, bool debug)
|
||||
break;
|
||||
}
|
||||
|
||||
if (kb >= KB_FIRMWARE_VERSION_620)
|
||||
if (kb == KB_FIRMWARE_VERSION_620)
|
||||
exoFlags |= EXO_FLAG_620_KGN;
|
||||
|
||||
if (debug)
|
||||
exoFlags |= EXO_FLAG_DBG_PRIV;
|
||||
|
||||
// Set mailbox values.
|
||||
*mb_exo_magic = EXO_MAGIC_VAL;
|
||||
*mb_exo_fw_no = exoFwNo;
|
||||
*mb_exo_flags = exoFlags;
|
||||
exo_cfg_depr->magic = EXO_MAGIC_VAL;
|
||||
exo_cfg->magic = EXO_MAGIC_VAL;
|
||||
|
||||
exo_cfg_depr->fwno = exoFwNo;
|
||||
exo_cfg->fwno = exoFwNo;
|
||||
|
||||
exo_cfg_depr->flags = exoFlags;
|
||||
exo_cfg->flags = exoFlags;
|
||||
|
||||
volatile wb_cfg_t *wb_cfg = (wb_cfg_t *)(warmboot + ATM_WB_HEADER_OFF);
|
||||
|
||||
if (wb_cfg->magic == ATM_WB_MAGIC)
|
||||
{
|
||||
wb_cfg->fwno = exoFwNo;
|
||||
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sdmmc;
|
||||
|
||||
// Set warmboot binary rsa modulus.
|
||||
u8 *rsa_mod = (u8 *)malloc(512);
|
||||
|
||||
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
|
||||
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||
sdmmc_storage_read(&storage, 1, 1, rsa_mod);
|
||||
sdmmc_storage_end(&storage);
|
||||
|
||||
// Patch AutoRCM.
|
||||
rsa_mod[0x10] = 0xF7;
|
||||
|
||||
memcpy(warmboot + 0x10, rsa_mod + 0x10, 0x100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (C) 2018-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,
|
||||
@@ -19,6 +19,6 @@
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
void config_exosphere(const char *id, u32 kb, bool debug);
|
||||
void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool debug);
|
||||
|
||||
#endif
|
||||
|
||||
184
bootloader/hos/sept.c
Normal file
184
bootloader/hos/sept.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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 "hos.h"
|
||||
#include "sept.h"
|
||||
#include "../config/config.h"
|
||||
#include "../gfx/di.h"
|
||||
#include "../ianos/ianos.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../storage/nx_emmc.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
#include "../utils/btn.h"
|
||||
#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 PATCHED_RELOC_SZ 0x94
|
||||
|
||||
#define WB_RST_ADDR 0x40010ED0
|
||||
#define WB_RST_SIZE 0x30
|
||||
|
||||
u8 warmboot_reboot[] = {
|
||||
0x14, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E450
|
||||
0x01, 0x10, 0xB0, 0xE3, // MOVS R1, #1
|
||||
0x00, 0x10, 0x80, 0xE5, // STR R1, [R0]
|
||||
0x0C, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E400
|
||||
0x10, 0x10, 0xB0, 0xE3, // MOVS R1, #0x10
|
||||
0x00, 0x10, 0x80, 0xE5, // STR R1, [R0]
|
||||
0xFE, 0xFF, 0xFF, 0xEA, // LOOP
|
||||
0x50, 0xE4, 0x00, 0x70, // #0x7000E450
|
||||
0x00, 0xE4, 0x00, 0x70 // #0x7000E400
|
||||
};
|
||||
|
||||
#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 hekate_config h_cfg;
|
||||
extern void *sd_file_read(char *path);
|
||||
extern void sd_mount();
|
||||
extern void sd_unmount();
|
||||
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
||||
|
||||
void check_sept()
|
||||
{
|
||||
u8 *pkg1 = (u8 *)calloc(1, 0x40000);
|
||||
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sdmmc;
|
||||
if (!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
|
||||
{
|
||||
EPRINTF("Failed to init eMMC.");
|
||||
goto out_free;
|
||||
}
|
||||
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||
|
||||
// Read package1.
|
||||
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
||||
if (!pkg1_id)
|
||||
{
|
||||
gfx_con.fntsz = 16;
|
||||
EPRINTF("Unknown pkg1 version.");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
||||
{
|
||||
sdmmc_storage_end(&storage);
|
||||
reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off);
|
||||
}
|
||||
|
||||
out_free:
|
||||
free(pkg1);
|
||||
sdmmc_storage_end(&storage);
|
||||
}
|
||||
|
||||
int reboot_to_sept(const u8 *tsec_fw)
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
// Copy warmboot reboot code and TSEC fw.
|
||||
memcpy((u8 *)(SEPT_PK1T_ADDR - WB_RST_SIZE), (u8 *)warmboot_reboot, sizeof(warmboot_reboot));
|
||||
memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, 0x3000);
|
||||
*(vu32 *)SEPT_TCSZ_ADDR = 0x3000;
|
||||
|
||||
// Copy sept-primary.
|
||||
if (f_open(&fp, "sept/sept-primary.bin", FA_READ))
|
||||
goto error;
|
||||
|
||||
if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL))
|
||||
{
|
||||
f_close(&fp);
|
||||
goto error;
|
||||
}
|
||||
f_close(&fp);
|
||||
|
||||
// Copy sept-secondary.
|
||||
if (f_open(&fp, "sept/sept-secondary.enc", FA_READ))
|
||||
goto error;
|
||||
|
||||
if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL))
|
||||
{
|
||||
f_close(&fp);
|
||||
goto error;
|
||||
}
|
||||
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));
|
||||
|
||||
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)
|
||||
{
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ);
|
||||
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
sd_unmount();
|
||||
|
||||
u32 pk1t_sept = SEPT_PK1T_ADDR - (ALIGN(PATCHED_RELOC_SZ, 0x10) + WB_RST_SIZE);
|
||||
|
||||
void (*sept)() = (void *)pk1t_sept;
|
||||
|
||||
reloc_patcher(WB_RST_ADDR, pk1t_sept, SEPT_PKG_SZ);
|
||||
|
||||
// Patch SDRAM init to perform an SVC immediately after second write.
|
||||
PMC(APBDEV_PMC_SCRATCH45) = 0x2E38DFFF;
|
||||
PMC(APBDEV_PMC_SCRATCH46) = 0x6001DC28;
|
||||
// Set SVC handler to jump to sept-primary in IRAM.
|
||||
PMC(APBDEV_PMC_SCRATCH33) = SEPT_PRI_ADDR;
|
||||
PMC(APBDEV_PMC_SCRATCH40) = 0x6000F208;
|
||||
|
||||
display_end();
|
||||
|
||||
(*sept)();
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
EPRINTF("Failed to run sept\n");
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
||||
btn_wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
25
bootloader/hos/sept.h
Normal file
25
bootloader/hos/sept.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 _SEPT_H_
|
||||
#define _SEPT_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
void check_sept();
|
||||
int reboot_to_sept(const u8 *tsec_fw);
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,11 @@
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS {
|
||||
PROVIDE(__ipl_start = 0x40008000);
|
||||
PROVIDE(__ipl_start = IPL_LOAD_ADDR);
|
||||
. = __ipl_start;
|
||||
.text : {
|
||||
*(.text._start);
|
||||
. = . + 36;
|
||||
*(.text*);
|
||||
}
|
||||
.data : {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "gfx/logos.h"
|
||||
#include "gfx/tui.h"
|
||||
#include "hos/hos.h"
|
||||
#include "hos/sept.h"
|
||||
#include "ianos/ianos.h"
|
||||
#include "libs/compr/blz.h"
|
||||
#include "libs/fatfs/ff.h"
|
||||
@@ -67,6 +68,7 @@ static bool sd_mounted;
|
||||
u8 *Kc_MENU_LOGO;
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
boot_cfg_t *b_cfg;
|
||||
hekate_config h_cfg;
|
||||
|
||||
bool sd_mount()
|
||||
@@ -269,7 +271,7 @@ void check_power_off_from_hos()
|
||||
}
|
||||
|
||||
// This is a safe and unused DRAM region for our payloads.
|
||||
#define IPL_LOAD_ADDR 0x40008000
|
||||
// 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))
|
||||
@@ -280,21 +282,23 @@ void check_power_off_from_hos()
|
||||
void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;
|
||||
void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR;
|
||||
|
||||
void reloc_patcher(u32 payload_size)
|
||||
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 *)EXT_PAYLOAD_ADDR, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);
|
||||
memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);
|
||||
|
||||
*(vu32 *)(EXT_PAYLOAD_ADDR + START_OFF) = PAYLOAD_ENTRY - ALIGN(PATCHED_RELOC_SZ, 0x10);
|
||||
*(vu32 *)(EXT_PAYLOAD_ADDR + PAYLOAD_END_OFF) = PAYLOAD_ENTRY + payload_size;
|
||||
*(vu32 *)(EXT_PAYLOAD_ADDR + IPL_START_OFF) = PAYLOAD_ENTRY;
|
||||
*(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;
|
||||
|
||||
if (payload_size == 0x7000)
|
||||
{
|
||||
memcpy((u8 *)(EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
|
||||
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
|
||||
*(vu32 *)CBFS_SDRAM_EN_ADDR = 0x4452414D;
|
||||
}
|
||||
}
|
||||
@@ -338,16 +342,40 @@ int launch_payload(char *path, bool update)
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
if (!update)
|
||||
{
|
||||
free(path);
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
free(path);
|
||||
|
||||
// Check for updated version.
|
||||
if (update)
|
||||
{
|
||||
u8 *update_ft = calloc(1, 6);
|
||||
|
||||
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';
|
||||
@@ -373,12 +401,15 @@ int launch_payload(char *path, bool update)
|
||||
if (size < 0x30000)
|
||||
{
|
||||
if (!update)
|
||||
reloc_patcher(ALIGN(size, 0x10));
|
||||
reloc_patcher(PAYLOAD_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
|
||||
else
|
||||
memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), (u8 *)(IPL_LOAD_ADDR + PATCHED_RELOC_SZ), sizeof(boot_cfg_t));
|
||||
|
||||
reconfig_hw_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
|
||||
}
|
||||
else
|
||||
{
|
||||
reloc_patcher(0x7000);
|
||||
reloc_patcher(PAYLOAD_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
|
||||
if (*(vu32 *)CBFS_SDRAM_EN_ADDR != 0x4452414D)
|
||||
return 1;
|
||||
reconfig_hw_workaround(true, 0);
|
||||
@@ -397,6 +428,7 @@ 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
|
||||
@@ -530,6 +562,7 @@ void ini_list_launcher()
|
||||
u8 max_entries = 61;
|
||||
char *payload_path = NULL;
|
||||
|
||||
ini_sec_t *cfg_tmp = NULL;
|
||||
ini_sec_t *cfg_sec = NULL;
|
||||
LIST_INIT(ini_list_sections);
|
||||
|
||||
@@ -568,7 +601,35 @@ void ini_list_launcher()
|
||||
menu_t menu = {
|
||||
ments, "Launch ini configurations", 0, 0
|
||||
};
|
||||
cfg_sec = ini_clone_section((ini_sec_t *)tui_do_menu(&gfx_con, &menu));
|
||||
|
||||
cfg_tmp = (ini_sec_t *)tui_do_menu(&gfx_con, &menu);
|
||||
|
||||
if (cfg_tmp)
|
||||
{
|
||||
u32 non_cfg = 1;
|
||||
for (int j = 2; j < i; j++)
|
||||
{
|
||||
if (ments[j].type != INI_CHOICE)
|
||||
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 = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payload_path = ini_check_payload_section(cfg_tmp);
|
||||
|
||||
if (cfg_tmp && !payload_path)
|
||||
check_sept();
|
||||
|
||||
cfg_sec = ini_clone_section(cfg_tmp);
|
||||
|
||||
if (!cfg_sec)
|
||||
{
|
||||
free(ments);
|
||||
@@ -578,12 +639,12 @@ void ini_list_launcher()
|
||||
}
|
||||
}
|
||||
else
|
||||
EPRINTF("No ini configurations found.");
|
||||
EPRINTF("No ini configs found.");
|
||||
free(ments);
|
||||
ini_free(&ini_list_sections);
|
||||
}
|
||||
else
|
||||
EPRINTF("Could not find any ini\nin bootloader/ini folder!");
|
||||
EPRINTF("Could not find any ini\nin bootloader/ini!");
|
||||
}
|
||||
|
||||
if (!cfg_sec)
|
||||
@@ -593,8 +654,6 @@ void ini_list_launcher()
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
payload_path = ini_check_payload_section(cfg_sec);
|
||||
|
||||
if (payload_path)
|
||||
{
|
||||
ini_free_section(cfg_sec);
|
||||
@@ -626,6 +685,7 @@ void launch_firmware()
|
||||
u8 max_entries = 61;
|
||||
char *payload_path = NULL;
|
||||
|
||||
ini_sec_t *cfg_tmp = NULL;
|
||||
ini_sec_t *cfg_sec = NULL;
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
@@ -678,7 +738,33 @@ void launch_firmware()
|
||||
menu_t menu = {
|
||||
ments, "Launch configurations", 0, 0
|
||||
};
|
||||
cfg_sec = ini_clone_section((ini_sec_t *)tui_do_menu(&gfx_con, &menu));
|
||||
|
||||
cfg_tmp = (ini_sec_t *)tui_do_menu(&gfx_con, &menu);
|
||||
|
||||
if (cfg_tmp)
|
||||
{
|
||||
u8 non_cfg = 4;
|
||||
for (int j = 5; j < i; j++)
|
||||
{
|
||||
if (ments[j].type != INI_CHOICE)
|
||||
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;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payload_path = ini_check_payload_section(cfg_tmp);
|
||||
|
||||
if (cfg_tmp && !payload_path)
|
||||
check_sept();
|
||||
|
||||
cfg_sec = ini_clone_section(cfg_tmp);
|
||||
if (!cfg_sec)
|
||||
{
|
||||
free(ments);
|
||||
@@ -691,7 +777,7 @@ void launch_firmware()
|
||||
ini_free(&ini_sections);
|
||||
}
|
||||
else
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists in SD Card!");
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists!");
|
||||
}
|
||||
|
||||
if (!cfg_sec)
|
||||
@@ -707,8 +793,6 @@ void launch_firmware()
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
payload_path = ini_check_payload_section(cfg_sec);
|
||||
|
||||
if (payload_path)
|
||||
{
|
||||
ini_free_section(cfg_sec);
|
||||
@@ -735,11 +819,16 @@ out:
|
||||
|
||||
void auto_launch_firmware()
|
||||
{
|
||||
auto_launch_update();
|
||||
if (!(b_cfg->boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||
{
|
||||
auto_launch_update();
|
||||
gfx_con.mute = true;
|
||||
}
|
||||
|
||||
u8 *BOOTLOGO = NULL;
|
||||
char *payload_path = NULL;
|
||||
FIL fp;
|
||||
u32 btn = 0;
|
||||
|
||||
struct _bmp_data
|
||||
{
|
||||
@@ -759,8 +848,6 @@ void auto_launch_firmware()
|
||||
LIST_INIT(ini_sections);
|
||||
LIST_INIT(ini_list_sections);
|
||||
|
||||
gfx_con.mute = true;
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
if (f_open(&fp, "bootloader/hekate_ipl.ini", FA_READ))
|
||||
@@ -790,16 +877,29 @@ void auto_launch_firmware()
|
||||
h_cfg.autoboot_list = atoi(kv->val);
|
||||
else if (!strcmp("bootwait", kv->key))
|
||||
h_cfg.bootwait = atoi(kv->val);
|
||||
else if (!strcmp("customlogo", kv->key))
|
||||
h_cfg.customlogo = atoi(kv->val);
|
||||
else if (!strcmp("verification", kv->key))
|
||||
h_cfg.verification = atoi(kv->val);
|
||||
else if (!strcmp("backlight", kv->key))
|
||||
h_cfg.backlight = atoi(kv->val);
|
||||
else if (!strcmp("autohosoff", kv->key))
|
||||
h_cfg.autohosoff = atoi(kv->val);
|
||||
else if (!strcmp("autonogc", kv->key))
|
||||
h_cfg.autonogc = atoi(kv->val);
|
||||
}
|
||||
boot_entry_id++;
|
||||
|
||||
// Override autoboot, otherwise save it for a possbile sept run.
|
||||
if (b_cfg->boot_cfg & BOOT_CFG_AUTOBOOT_EN)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -810,7 +910,6 @@ void auto_launch_firmware()
|
||||
{
|
||||
if (!strcmp("logopath", kv->key))
|
||||
bootlogoCustomEntry = kv->val;
|
||||
gfx_printf(&gfx_con, "\n%s=%s\n\n", kv->key, kv->val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -818,7 +917,7 @@ void auto_launch_firmware()
|
||||
}
|
||||
}
|
||||
|
||||
if (h_cfg.autohosoff)
|
||||
if (h_cfg.autohosoff && !(b_cfg->boot_cfg & BOOT_CFG_AUTOBOOT_EN))
|
||||
check_power_off_from_hos();
|
||||
|
||||
if (h_cfg.autoboot_list)
|
||||
@@ -844,7 +943,6 @@ void auto_launch_firmware()
|
||||
{
|
||||
if (!strcmp("logopath", kv->key))
|
||||
bootlogoCustomEntry = kv->val;
|
||||
gfx_printf(&gfx_con, "\n%s=%s\n\n", kv->key, kv->val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -873,9 +971,14 @@ void auto_launch_firmware()
|
||||
else
|
||||
goto out;
|
||||
|
||||
if (h_cfg.customlogo)
|
||||
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))
|
||||
{
|
||||
u8 *bitmap = NULL;
|
||||
if (bootlogoCustomEntry != NULL) // Check if user set custom logo path at the boot entry.
|
||||
{
|
||||
bitmap = (u8 *)sd_file_read(bootlogoCustomEntry);
|
||||
@@ -922,31 +1025,23 @@ void auto_launch_firmware()
|
||||
else
|
||||
free(bitmap);
|
||||
}
|
||||
|
||||
// Render boot logo.
|
||||
if (bootlogoFound)
|
||||
{
|
||||
gfx_render_bmp_argb(&gfx_ctxt, (u32 *)BOOTLOGO, bmpData.size_x, bmpData.size_y,
|
||||
bmpData.pos_x, bmpData.pos_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
BOOTLOGO = (void *)malloc(0x4000);
|
||||
blz_uncompress_srcdest(BOOTLOGO_BLZ, SZ_BOOTLOGO_BLZ, BOOTLOGO, SZ_BOOTLOGO);
|
||||
gfx_set_rect_grey(&gfx_ctxt, BOOTLOGO, X_BOOTLOGO, Y_BOOTLOGO, 326, 544);
|
||||
}
|
||||
free(BOOTLOGO);
|
||||
}
|
||||
|
||||
// Render boot logo.
|
||||
if (bootlogoFound)
|
||||
{
|
||||
gfx_render_bmp_argb(&gfx_ctxt, (u32 *)BOOTLOGO, bmpData.size_x, bmpData.size_y,
|
||||
bmpData.pos_x, bmpData.pos_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
BOOTLOGO = (void *)malloc(0x4000);
|
||||
blz_uncompress_srcdest(BOOTLOGO_BLZ, SZ_BOOTLOGO_BLZ, BOOTLOGO, SZ_BOOTLOGO);
|
||||
gfx_set_rect_grey(&gfx_ctxt, BOOTLOGO, X_BOOTLOGO, Y_BOOTLOGO, 326, 544);
|
||||
}
|
||||
free(BOOTLOGO);
|
||||
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
||||
// Wait before booting. If VOL- is pressed go into bootloader menu.
|
||||
u32 btn = btn_wait_timeout(h_cfg.bootwait * 1000, BTN_VOL_DOWN);
|
||||
|
||||
if (btn & BTN_VOL_DOWN)
|
||||
goto out;
|
||||
|
||||
ini_free(&ini_sections);
|
||||
if (h_cfg.autoboot_list)
|
||||
ini_free(&ini_list_sections);
|
||||
@@ -955,7 +1050,19 @@ void auto_launch_firmware()
|
||||
free(Kc_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
payload_path = ini_check_payload_section(cfg_sec);
|
||||
if (b_cfg->boot_cfg & BOOT_CFG_FROM_LAUNCH)
|
||||
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))
|
||||
{
|
||||
btn = btn_wait_timeout(h_cfg.bootwait * 1000, BTN_VOL_DOWN);
|
||||
|
||||
if (btn & BTN_VOL_DOWN)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (payload_path)
|
||||
{
|
||||
@@ -979,13 +1086,15 @@ out:
|
||||
|
||||
sd_unmount();
|
||||
gfx_con.mute = false;
|
||||
|
||||
b_cfg->boot_cfg &= ~(BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_LAUNCH);
|
||||
}
|
||||
|
||||
void about()
|
||||
{
|
||||
static const char credits[] =
|
||||
"\nhekate (C) 2018 naehrwert, st4rk\n\n"
|
||||
"CTCaer mod (C) 2018 CTCaer\n"
|
||||
"\nhekate (c) 2018 naehrwert, st4rk\n\n"
|
||||
"CTCaer mod (c) 2018 CTCaer\n"
|
||||
" ___________________________________________\n\n"
|
||||
"Thanks to: %kderrek, nedwill, plutoo,\n"
|
||||
" shuffle2, smea, thexyz, yellows8%k\n"
|
||||
@@ -995,14 +1104,14 @@ void about()
|
||||
" ___________________________________________\n\n"
|
||||
"Open source and free packages used:\n\n"
|
||||
" - FatFs R0.13b,\n"
|
||||
" Copyright (C) 2018, ChaN\n\n"
|
||||
" Copyright (c) 2018, ChaN\n\n"
|
||||
" - bcl-1.2.0,\n"
|
||||
" Copyright (C) 2003-2006, Marcus Geelnard\n\n"
|
||||
" Copyright (c) 2003-2006, Marcus Geelnard\n\n"
|
||||
" - Atmosphere (SE sha256, prc id patches),\n"
|
||||
" Copyright (C) 2018, Atmosphere-NX\n\n"
|
||||
" Copyright (c) 2018, Atmosphere-NX\n\n"
|
||||
" - elfload,\n"
|
||||
" Copyright (C) 2014, Owen Shepherd\n"
|
||||
" Copyright (C) 2018, M4xw\n"
|
||||
" Copyright (c) 2014, Owen Shepherd\n"
|
||||
" Copyright (c) 2018, M4xw\n"
|
||||
" ___________________________________________\n\n";
|
||||
static const char octopus[] =
|
||||
" %k___\n"
|
||||
@@ -1039,7 +1148,7 @@ ment_t ment_options[] = {
|
||||
MDEF_CHGLINE(),
|
||||
MDEF_HANDLER("Auto boot", config_autoboot),
|
||||
MDEF_HANDLER("Boot time delay", config_bootdelay),
|
||||
MDEF_HANDLER("Custom boot logo", config_customlogo),
|
||||
MDEF_HANDLER("Auto NoGC", config_nogc),
|
||||
MDEF_HANDLER("Auto HOS power off", config_auto_hos_poweroff),
|
||||
MDEF_HANDLER("Backlight", config_backlight),
|
||||
MDEF_END()
|
||||
@@ -1118,8 +1227,8 @@ ment_t ment_tools[] = {
|
||||
MDEF_CAPTION("-------- Misc --------", 0xFF0AB9E6),
|
||||
MDEF_HANDLER("Dump package1/2", dump_packages12),
|
||||
MDEF_HANDLER("Fix battery de-sync", fix_battery_desync),
|
||||
MDEF_HANDLER("Fix archive bit (except Nintendo folder)", fix_sd_all_attr),
|
||||
MDEF_HANDLER("Fix archive bit (Nintendo folder)", fix_sd_nin_attr),
|
||||
MDEF_HANDLER("Fix archive bit (except Nintendo)", fix_sd_all_attr),
|
||||
MDEF_HANDLER("Fix archive bit (Nintendo only)", fix_sd_nin_attr),
|
||||
//MDEF_HANDLER("Fix fuel gauge configuration", fix_fuel_gauge_configuration),
|
||||
//MDEF_HANDLER("Reset all battery cfg", reset_pmic_fuel_gauge_charger_config),
|
||||
//MDEF_HANDLER("Minerva", minerva), // Uncomment for testing Minerva Training Cell
|
||||
@@ -1150,13 +1259,16 @@ ment_t ment_top[] = {
|
||||
};
|
||||
menu_t menu_top = {
|
||||
ment_top,
|
||||
"hekate - CTCaer mod v4.6", 0, 0
|
||||
"hekate - CTCaer mod v4.8", 0, 0
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 balika011
|
||||
* 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,
|
||||
@@ -23,6 +25,7 @@
|
||||
#include "../utils/util.h"
|
||||
#include "../soc/fuse.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../power/max7762x.h"
|
||||
#include "../soc/clock.h"
|
||||
|
||||
#define CONFIG_SDRAM_COMPRESS_CFG
|
||||
@@ -536,7 +539,7 @@ void sdram_init()
|
||||
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD1, 40); //40 = (1000 * 1100 - 600000) / 12500 -> 1.1V
|
||||
max77620_regulator_set_voltage(REGULATOR_SD1, 1100000);
|
||||
|
||||
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
||||
usleep(params->pmc_vddp_sel_wait);
|
||||
|
||||
@@ -148,7 +148,7 @@ int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
||||
|
||||
void bq24193_fake_battery_removal()
|
||||
{
|
||||
u8 value;
|
||||
u8 value;
|
||||
|
||||
// Disable watchdog to keep BATFET disabled.
|
||||
value = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Defining registers address and its bit definitions of MAX77620 and MAX20024
|
||||
*
|
||||
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||
* 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,
|
||||
@@ -14,275 +15,277 @@
|
||||
#define MAX77620_I2C_ADDR 0x3C
|
||||
|
||||
/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
|
||||
#define MAX77620_REG_CNFGGLBL1 0x00
|
||||
#define MAX77620_REG_CNFGGLBL2 0x01
|
||||
#define MAX77620_REG_CNFGGLBL3 0x02
|
||||
#define MAX77620_REG_CNFG1_32K 0x03
|
||||
#define MAX77620_REG_CNFGBBC 0x04
|
||||
#define MAX77620_REG_IRQTOP 0x05
|
||||
#define MAX77620_REG_INTLBT 0x06
|
||||
#define MAX77620_REG_IRQSD 0x07
|
||||
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
|
||||
#define MAX77620_REG_IRQ_LVL2_L8 0x09
|
||||
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
|
||||
#define MAX77620_REG_ONOFFIRQ 0x0B
|
||||
#define MAX77620_REG_NVERC 0x0C
|
||||
#define MAX77620_REG_IRQTOPM 0x0D
|
||||
#define MAX77620_REG_INTENLBT 0x0E
|
||||
#define MAX77620_REG_IRQMASKSD 0x0F
|
||||
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
|
||||
#define MAX77620_REG_IRQ_MSK_L8 0x11
|
||||
#define MAX77620_REG_ONOFFIRQM 0x12
|
||||
#define MAX77620_REG_STATLBT 0x13
|
||||
#define MAX77620_REG_STATSD 0x14
|
||||
#define MAX77620_REG_ONOFFSTAT 0x15
|
||||
#define MAX77620_REG_CNFGGLBL1 0x00
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
|
||||
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
|
||||
|
||||
#define MAX77620_REG_CNFGGLBL2 0x01
|
||||
#define MAX77620_REG_CNFGGLBL3 0x02
|
||||
#define MAX77620_WDTC_MASK 0x3
|
||||
#define MAX77620_WDTOFFC (1 << 4)
|
||||
#define MAX77620_WDTSLPC (1 << 3)
|
||||
#define MAX77620_WDTEN (1 << 2)
|
||||
#define MAX77620_TWD_MASK 0x3
|
||||
#define MAX77620_TWD_2s 0x0
|
||||
#define MAX77620_TWD_16s 0x1
|
||||
#define MAX77620_TWD_64s 0x2
|
||||
#define MAX77620_TWD_128s 0x3
|
||||
|
||||
#define MAX77620_REG_CNFG1_32K 0x03
|
||||
#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
|
||||
|
||||
#define MAX77620_REG_CNFGBBC 0x04
|
||||
#define MAX77620_CNFGBBC_ENABLE (1 << 0)
|
||||
#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
|
||||
#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
|
||||
#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
|
||||
#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
|
||||
#define MAX77620_CNFGBBC_RESISTOR_100 (0 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_1K (1 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_3K (2 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_6K (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
|
||||
#define MAX77620_REG_IRQTOP 0x05
|
||||
#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
|
||||
#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
|
||||
#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
|
||||
#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
|
||||
#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
|
||||
#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
|
||||
#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
|
||||
|
||||
#define MAX77620_REG_INTLBT 0x06
|
||||
#define MAX77620_REG_IRQTOPM 0x0D
|
||||
#define MAX77620_IRQ_LBM_MASK (1 << 3)
|
||||
#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
|
||||
#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
|
||||
|
||||
#define MAX77620_REG_IRQSD 0x07
|
||||
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
|
||||
#define MAX77620_REG_IRQ_LVL2_L8 0x09
|
||||
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
|
||||
#define MAX77620_REG_ONOFFIRQ 0x0B
|
||||
#define MAX77620_REG_NVERC 0x0C
|
||||
|
||||
#define MAX77620_REG_INTENLBT 0x0E
|
||||
#define MAX77620_GLBLM_MASK (1 << 0)
|
||||
|
||||
#define MAX77620_REG_IRQMASKSD 0x0F
|
||||
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
|
||||
#define MAX77620_REG_IRQ_MSK_L8 0x11
|
||||
#define MAX77620_REG_ONOFFIRQM 0x12
|
||||
#define MAX77620_REG_STATLBT 0x13
|
||||
#define MAX77620_REG_STATSD 0x14
|
||||
#define MAX77620_REG_ONOFFSTAT 0x15
|
||||
|
||||
/* SD and LDO Registers */
|
||||
#define MAX77620_REG_SD0 0x16
|
||||
#define MAX77620_REG_SD1 0x17
|
||||
#define MAX77620_REG_SD2 0x18
|
||||
#define MAX77620_REG_SD3 0x19
|
||||
#define MAX77620_REG_SD4 0x1A
|
||||
#define MAX77620_REG_DVSSD0 0x1B
|
||||
#define MAX77620_REG_DVSSD1 0x1C
|
||||
#define MAX77620_REG_SD0_CFG 0x1D
|
||||
#define MAX77620_REG_SD1_CFG 0x1E
|
||||
#define MAX77620_REG_SD2_CFG 0x1F
|
||||
#define MAX77620_REG_SD3_CFG 0x20
|
||||
#define MAX77620_REG_SD4_CFG 0x21
|
||||
#define MAX77620_REG_SD_CFG2 0x22
|
||||
#define MAX77620_REG_LDO0_CFG 0x23
|
||||
#define MAX77620_REG_LDO0_CFG2 0x24
|
||||
#define MAX77620_REG_LDO1_CFG 0x25
|
||||
#define MAX77620_REG_LDO1_CFG2 0x26
|
||||
#define MAX77620_REG_LDO2_CFG 0x27
|
||||
#define MAX77620_REG_LDO2_CFG2 0x28
|
||||
#define MAX77620_REG_LDO3_CFG 0x29
|
||||
#define MAX77620_REG_LDO3_CFG2 0x2A
|
||||
#define MAX77620_REG_LDO4_CFG 0x2B
|
||||
#define MAX77620_REG_LDO4_CFG2 0x2C
|
||||
#define MAX77620_REG_LDO5_CFG 0x2D
|
||||
#define MAX77620_REG_LDO5_CFG2 0x2E
|
||||
#define MAX77620_REG_LDO6_CFG 0x2F
|
||||
#define MAX77620_REG_LDO6_CFG2 0x30
|
||||
#define MAX77620_REG_LDO7_CFG 0x31
|
||||
#define MAX77620_REG_LDO7_CFG2 0x32
|
||||
#define MAX77620_REG_LDO8_CFG 0x33
|
||||
#define MAX77620_REG_LDO8_CFG2 0x34
|
||||
#define MAX77620_REG_LDO_CFG3 0x35
|
||||
#define MAX77620_REG_SD0 0x16
|
||||
#define MAX77620_REG_SD1 0x17
|
||||
#define MAX77620_REG_SD2 0x18
|
||||
#define MAX77620_REG_SD3 0x19
|
||||
#define MAX77620_REG_SD4 0x1A
|
||||
#define MAX77620_SDX_VOLT_MASK 0xFF
|
||||
#define MAX77620_SD0_VOLT_MASK 0x3F
|
||||
#define MAX77620_SD1_VOLT_MASK 0x7F
|
||||
#define MAX77620_LDO_VOLT_MASK 0x3F
|
||||
#define MAX77620_REG_DVSSD0 0x1B
|
||||
#define MAX77620_REG_DVSSD1 0x1C
|
||||
#define MAX77620_REG_SD0_CFG 0x1D
|
||||
#define MAX77620_REG_SD1_CFG 0x1E
|
||||
#define MAX77620_REG_SD2_CFG 0x1F
|
||||
#define MAX77620_REG_SD3_CFG 0x20
|
||||
#define MAX77620_REG_SD4_CFG 0x21
|
||||
#define MAX77620_REG_SD_CFG2 0x22
|
||||
#define MAX77620_REG_LDO0_CFG 0x23
|
||||
#define MAX77620_REG_LDO0_CFG2 0x24
|
||||
#define MAX77620_REG_LDO1_CFG 0x25
|
||||
#define MAX77620_REG_LDO1_CFG2 0x26
|
||||
#define MAX77620_REG_LDO2_CFG 0x27
|
||||
#define MAX77620_REG_LDO2_CFG2 0x28
|
||||
#define MAX77620_REG_LDO3_CFG 0x29
|
||||
#define MAX77620_REG_LDO3_CFG2 0x2A
|
||||
#define MAX77620_REG_LDO4_CFG 0x2B
|
||||
#define MAX77620_REG_LDO4_CFG2 0x2C
|
||||
#define MAX77620_REG_LDO5_CFG 0x2D
|
||||
#define MAX77620_REG_LDO5_CFG2 0x2E
|
||||
#define MAX77620_REG_LDO6_CFG 0x2F
|
||||
#define MAX77620_REG_LDO6_CFG2 0x30
|
||||
#define MAX77620_REG_LDO7_CFG 0x31
|
||||
#define MAX77620_REG_LDO7_CFG2 0x32
|
||||
#define MAX77620_REG_LDO8_CFG 0x33
|
||||
#define MAX77620_REG_LDO8_CFG2 0x34
|
||||
#define MAX77620_LDO_POWER_MODE_MASK 0xC0
|
||||
#define MAX77620_LDO_POWER_MODE_SHIFT 6
|
||||
#define MAX77620_POWER_MODE_NORMAL 3
|
||||
#define MAX77620_POWER_MODE_LPM 2
|
||||
#define MAX77620_POWER_MODE_GLPM 1
|
||||
#define MAX77620_POWER_MODE_DISABLE 0
|
||||
#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
|
||||
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_ADE_DISABLE 0
|
||||
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_SLOW 0
|
||||
|
||||
#define MAX77620_LDO_SLEW_RATE_MASK 0x1
|
||||
#define MAX77620_REG_LDO_CFG3 0x35
|
||||
#define MAX77620_TRACK4_MASK (1 << 5)
|
||||
#define MAX77620_TRACK4_SHIFT 5
|
||||
|
||||
/* LDO Configuration 3 */
|
||||
#define MAX77620_TRACK4_MASK (1 << 5)
|
||||
#define MAX77620_TRACK4_SHIFT 5
|
||||
#define MAX77620_LDO_SLEW_RATE_MASK 0x1
|
||||
|
||||
/* Voltage */
|
||||
#define MAX77620_SDX_VOLT_MASK 0xFF
|
||||
#define MAX77620_SD0_VOLT_MASK 0x3F
|
||||
#define MAX77620_SD1_VOLT_MASK 0x7F
|
||||
#define MAX77620_LDO_VOLT_MASK 0x3F
|
||||
#define MAX77620_REG_GPIO0 0x36
|
||||
#define MAX77620_REG_GPIO1 0x37
|
||||
#define MAX77620_REG_GPIO2 0x38
|
||||
#define MAX77620_REG_GPIO3 0x39
|
||||
#define MAX77620_REG_GPIO4 0x3A
|
||||
#define MAX77620_REG_GPIO5 0x3B
|
||||
#define MAX77620_REG_GPIO6 0x3C
|
||||
#define MAX77620_REG_GPIO7 0x3D
|
||||
#define MAX77620_REG_PUE_GPIO 0x3E
|
||||
#define MAX77620_REG_PDE_GPIO 0x3F
|
||||
#define MAX77620_REG_AME_GPIO 0x40
|
||||
|
||||
#define MAX77620_REG_GPIO0 0x36
|
||||
#define MAX77620_REG_GPIO1 0x37
|
||||
#define MAX77620_REG_GPIO2 0x38
|
||||
#define MAX77620_REG_GPIO3 0x39
|
||||
#define MAX77620_REG_GPIO4 0x3A
|
||||
#define MAX77620_REG_GPIO5 0x3B
|
||||
#define MAX77620_REG_GPIO6 0x3C
|
||||
#define MAX77620_REG_GPIO7 0x3D
|
||||
#define MAX77620_REG_PUE_GPIO 0x3E
|
||||
#define MAX77620_REG_PDE_GPIO 0x3F
|
||||
#define MAX77620_REG_AME_GPIO 0x40
|
||||
#define MAX77620_REG_ONOFFCNFG1 0x41
|
||||
#define MAX77620_REG_ONOFFCNFG2 0x42
|
||||
#define MAX77620_REG_ONOFFCNFG1 0x41
|
||||
#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
|
||||
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
|
||||
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
|
||||
#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
|
||||
#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
|
||||
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
|
||||
|
||||
#define MAX77620_REG_ONOFFCNFG2 0x42
|
||||
#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
|
||||
#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
|
||||
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
|
||||
#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
|
||||
#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
|
||||
|
||||
/* FPS Registers */
|
||||
#define MAX77620_REG_FPS_CFG0 0x43
|
||||
#define MAX77620_REG_FPS_CFG1 0x44
|
||||
#define MAX77620_REG_FPS_CFG2 0x45
|
||||
#define MAX77620_REG_FPS_LDO0 0x46
|
||||
#define MAX77620_REG_FPS_LDO1 0x47
|
||||
#define MAX77620_REG_FPS_LDO2 0x48
|
||||
#define MAX77620_REG_FPS_LDO3 0x49
|
||||
#define MAX77620_REG_FPS_LDO4 0x4A
|
||||
#define MAX77620_REG_FPS_LDO5 0x4B
|
||||
#define MAX77620_REG_FPS_LDO6 0x4C
|
||||
#define MAX77620_REG_FPS_LDO7 0x4D
|
||||
#define MAX77620_REG_FPS_LDO8 0x4E
|
||||
#define MAX77620_REG_FPS_SD0 0x4F
|
||||
#define MAX77620_REG_FPS_SD1 0x50
|
||||
#define MAX77620_REG_FPS_SD2 0x51
|
||||
#define MAX77620_REG_FPS_SD3 0x52
|
||||
#define MAX77620_REG_FPS_SD4 0x53
|
||||
#define MAX77620_REG_FPS_NONE 0
|
||||
|
||||
#define MAX77620_FPS_SRC_MASK 0xC0
|
||||
#define MAX77620_FPS_SRC_SHIFT 6
|
||||
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
|
||||
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
|
||||
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_EN_SRC_MASK 0x06
|
||||
#define MAX77620_FPS_EN_SRC_SHIFT 1
|
||||
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
|
||||
#define MAX77620_FPS_ENFPS_SW 0x01
|
||||
#define MAX77620_REG_FPS_CFG0 0x43
|
||||
#define MAX77620_REG_FPS_CFG1 0x44
|
||||
#define MAX77620_REG_FPS_CFG2 0x45
|
||||
#define MAX77620_REG_FPS_LDO0 0x46
|
||||
#define MAX77620_REG_FPS_LDO1 0x47
|
||||
#define MAX77620_REG_FPS_LDO2 0x48
|
||||
#define MAX77620_REG_FPS_LDO3 0x49
|
||||
#define MAX77620_REG_FPS_LDO4 0x4A
|
||||
#define MAX77620_REG_FPS_LDO5 0x4B
|
||||
#define MAX77620_REG_FPS_LDO6 0x4C
|
||||
#define MAX77620_REG_FPS_LDO7 0x4D
|
||||
#define MAX77620_REG_FPS_LDO8 0x4E
|
||||
#define MAX77620_REG_FPS_SD0 0x4F
|
||||
#define MAX77620_REG_FPS_SD1 0x50
|
||||
#define MAX77620_REG_FPS_SD2 0x51
|
||||
#define MAX77620_REG_FPS_SD3 0x52
|
||||
#define MAX77620_REG_FPS_SD4 0x53
|
||||
#define MAX77620_REG_FPS_NONE 0
|
||||
#define MAX77620_FPS_SRC_MASK 0xC0
|
||||
#define MAX77620_FPS_SRC_SHIFT 6
|
||||
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
|
||||
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
|
||||
|
||||
/* Minimum and maximum FPS period time (in microseconds) are
|
||||
* different for MAX77620 and Max20024.
|
||||
*/
|
||||
#define MAX77620_FPS_PERIOD_MIN_US 40
|
||||
#define MAX20024_FPS_PERIOD_MIN_US 20
|
||||
#define MAX77620_FPS_COUNT 3
|
||||
|
||||
#define MAX77620_FPS_PERIOD_MAX_US 2560
|
||||
#define MAX20024_FPS_PERIOD_MAX_US 5120
|
||||
#define MAX77620_FPS_PERIOD_MIN_US 40
|
||||
#define MAX20024_FPS_PERIOD_MIN_US 20
|
||||
|
||||
#define MAX77620_REG_FPS_GPIO1 0x54
|
||||
#define MAX77620_REG_FPS_GPIO2 0x55
|
||||
#define MAX77620_REG_FPS_GPIO3 0x56
|
||||
#define MAX77620_REG_FPS_RSO 0x57
|
||||
#define MAX77620_REG_CID0 0x58
|
||||
#define MAX77620_REG_CID1 0x59
|
||||
#define MAX77620_REG_CID2 0x5A
|
||||
#define MAX77620_REG_CID3 0x5B
|
||||
#define MAX77620_REG_CID4 0x5C
|
||||
#define MAX77620_REG_CID5 0x5D
|
||||
#define MAX77620_FPS_PERIOD_MAX_US 2560
|
||||
#define MAX20024_FPS_PERIOD_MAX_US 5120
|
||||
|
||||
#define MAX77620_REG_DVSSD4 0x5E
|
||||
#define MAX20024_REG_MAX_ADD 0x70
|
||||
#define MAX77620_REG_FPS_GPIO1 0x54
|
||||
#define MAX77620_REG_FPS_GPIO2 0x55
|
||||
#define MAX77620_REG_FPS_GPIO3 0x56
|
||||
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_EN_SRC_MASK 0x06
|
||||
#define MAX77620_FPS_EN_SRC_SHIFT 1
|
||||
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
|
||||
#define MAX77620_FPS_ENFPS_SW 0x01
|
||||
|
||||
#define MAX77620_CID_DIDM_MASK 0xF0
|
||||
#define MAX77620_CID_DIDM_SHIFT 4
|
||||
#define MAX77620_REG_FPS_RSO 0x57
|
||||
#define MAX77620_REG_CID0 0x58
|
||||
#define MAX77620_REG_CID1 0x59
|
||||
#define MAX77620_REG_CID2 0x5A
|
||||
#define MAX77620_REG_CID3 0x5B
|
||||
#define MAX77620_REG_CID4 0x5C
|
||||
#define MAX77620_REG_CID5 0x5D
|
||||
|
||||
#define MAX77620_REG_DVSSD4 0x5E
|
||||
#define MAX20024_REG_MAX_ADD 0x70
|
||||
|
||||
#define MAX77620_CID_DIDM_MASK 0xF0
|
||||
#define MAX77620_CID_DIDM_SHIFT 4
|
||||
|
||||
/* CNCG2SD */
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
|
||||
|
||||
/* Device Identification Metal */
|
||||
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
|
||||
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
|
||||
/* Device Indentification OTP */
|
||||
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
|
||||
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
|
||||
|
||||
/* SD CNFG1 */
|
||||
#define MAX77620_SD_SR_MASK 0xC0
|
||||
#define MAX77620_SD_SR_SHIFT 6
|
||||
#define MAX77620_SD_POWER_MODE_MASK 0x30
|
||||
#define MAX77620_SD_POWER_MODE_SHIFT 4
|
||||
#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
|
||||
#define MAX77620_SD_CFG1_ADE_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
|
||||
#define MAX77620_SD_FPWM_MASK 0x04
|
||||
#define MAX77620_SD_FPWM_SHIFT 2
|
||||
#define MAX77620_SD_FSRADE_MASK 0x01
|
||||
#define MAX77620_SD_FSRADE_SHIFT 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
|
||||
#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
|
||||
#define MAX77620_SD_SR_MASK 0xC0
|
||||
#define MAX77620_SD_SR_SHIFT 6
|
||||
#define MAX77620_SD_POWER_MODE_MASK 0x30
|
||||
#define MAX77620_SD_POWER_MODE_SHIFT 4
|
||||
#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
|
||||
#define MAX77620_SD_CFG1_ADE_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
|
||||
#define MAX77620_SD_FPWM_MASK 0x04
|
||||
#define MAX77620_SD_FPWM_SHIFT 2
|
||||
#define MAX77620_SD_FSRADE_MASK 0x01
|
||||
#define MAX77620_SD_FSRADE_SHIFT 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
|
||||
#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
|
||||
|
||||
/* LDO_CNFG2 */
|
||||
#define MAX77620_LDO_POWER_MODE_MASK 0xC0
|
||||
#define MAX77620_LDO_POWER_MODE_SHIFT 6
|
||||
#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
|
||||
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_ADE_DISABLE 0
|
||||
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_SLOW 0
|
||||
#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
|
||||
#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
|
||||
#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
|
||||
#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
|
||||
#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
|
||||
#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
|
||||
|
||||
#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
|
||||
#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
|
||||
#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
|
||||
#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
|
||||
#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
|
||||
#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
|
||||
#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
|
||||
|
||||
#define MAX77620_IRQ_LBM_MASK (1 << 3)
|
||||
#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
|
||||
#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
|
||||
|
||||
#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
|
||||
#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
|
||||
#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
|
||||
#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
|
||||
#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
|
||||
#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
|
||||
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
|
||||
|
||||
#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
|
||||
|
||||
#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
|
||||
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
|
||||
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
|
||||
#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
|
||||
#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
|
||||
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
|
||||
|
||||
#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
|
||||
#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
|
||||
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
|
||||
#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
|
||||
#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
|
||||
|
||||
#define MAX77620_GLBLM_MASK (1 << 0)
|
||||
|
||||
#define MAX77620_WDTC_MASK 0x3
|
||||
#define MAX77620_WDTOFFC (1 << 4)
|
||||
#define MAX77620_WDTSLPC (1 << 3)
|
||||
#define MAX77620_WDTEN (1 << 2)
|
||||
|
||||
#define MAX77620_TWD_MASK 0x3
|
||||
#define MAX77620_TWD_2s 0x0
|
||||
#define MAX77620_TWD_16s 0x1
|
||||
#define MAX77620_TWD_64s 0x2
|
||||
#define MAX77620_TWD_128s 0x3
|
||||
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
|
||||
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
|
||||
|
||||
/* CNFG BBC registers */
|
||||
#define MAX77620_CNFGBBC_ENABLE (1 << 0)
|
||||
#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
|
||||
#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
|
||||
#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
|
||||
#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
|
||||
|
||||
#define MAX77620_FPS_COUNT 3
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
|
||||
|
||||
/* Interrupts */
|
||||
enum {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* 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,
|
||||
@@ -27,12 +28,15 @@ typedef struct _max77620_regulator_t
|
||||
u8 type;
|
||||
const char *name;
|
||||
u8 reg_sd;
|
||||
|
||||
u32 mv_step;
|
||||
u32 mv_min;
|
||||
u32 mv_default;
|
||||
u32 mv_max;
|
||||
|
||||
u8 volt_addr;
|
||||
u8 cfg_addr;
|
||||
|
||||
u8 volt_mask;
|
||||
u8 enable_mask;
|
||||
u8 enable_shift;
|
||||
@@ -45,19 +49,19 @@ typedef struct _max77620_regulator_t
|
||||
} max77620_regulator_t;
|
||||
|
||||
static const max77620_regulator_t _pmic_regulators[] = {
|
||||
{ REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, 0x3F, 0x30, 4, 0x80, 0x4F, 1, 7, 1 },
|
||||
{ REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, 0x3F, 0x30, 4, 0x40, 0x50, 0, 1, 5 },
|
||||
{ REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, 0xFF, 0x30, 4, 0x20, 0x51, 1, 5, 2 },
|
||||
{ REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, 0xFF, 0x30, 4, 0x10, 0x52, 0, 3, 3 },
|
||||
{ REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, 0x3F, 0xC0, 6, 0x00, 0x46, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, 0x3F, 0xC0, 6, 0x00, 0x47, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, 0x3F, 0xC0, 6, 0x00, 0x48, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, 0x3F, 0xC0, 6, 0x00, 0x49, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4A, 0, 7, 1 },
|
||||
{ REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4B, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4C, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4D, 1, 4, 3 },
|
||||
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4E, 3, 7, 0 }
|
||||
{ REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x80, MAX77620_REG_FPS_SD0, 1, 7, 1 },
|
||||
{ REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x40, MAX77620_REG_FPS_SD1, 0, 1, 5 },
|
||||
{ REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x20, MAX77620_REG_FPS_SD2, 1, 5, 2 },
|
||||
{ REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x10, MAX77620_REG_FPS_SD3, 0, 3, 3 },
|
||||
{ REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO0, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO1, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO2, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO3, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO4, 0, 7, 1 },
|
||||
{ REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO5, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO6, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO7, 1, 4, 3 },
|
||||
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
|
||||
};
|
||||
|
||||
int max77620_regulator_get_status(u32 id)
|
||||
@@ -79,7 +83,8 @@ int max77620_regulator_config_fps(u32 id)
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->fps_addr, (reg->fps_src << 6) | (reg->pu_period << 3) | (reg->pd_period));
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->fps_addr,
|
||||
(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -91,7 +96,7 @@ int max77620_regulator_set_voltage(u32 id, u32 mv)
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (mv < reg->mv_default || mv > reg->mv_max)
|
||||
if (mv < reg->mv_min || mv > reg->mv_max)
|
||||
return 0;
|
||||
|
||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
@@ -113,7 +118,7 @@ int max77620_regulator_enable(u32 id, int enable)
|
||||
u32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;
|
||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, addr);
|
||||
if (enable)
|
||||
val = (val & ~reg->enable_mask) | ((3 << reg->enable_shift) & reg->enable_mask);
|
||||
val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
|
||||
else
|
||||
val &= ~reg->enable_mask;
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, addr, val);
|
||||
@@ -122,6 +127,24 @@ int max77620_regulator_enable(u32 id, int enable)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (mv < reg->mv_min || mv > reg->mv_max)
|
||||
return 0;
|
||||
|
||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void max77620_config_default()
|
||||
{
|
||||
for (u32 i = 1; i <= REGULATOR_MAX; i++)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* 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,
|
||||
@@ -30,10 +31,10 @@
|
||||
* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
|
||||
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
||||
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
|
||||
* ldo3 | | 50000 | 800000 | 3100000 | 3100000 |
|
||||
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
|
||||
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
|
||||
* ldo5 | | 50000 | 800000 | 1800000 | 1800000 |
|
||||
* ldo6 | | 50000 | 800000 | 2900000 | 2900000 |
|
||||
* ldo5 | GC ASIC | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
|
||||
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
|
||||
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
|
||||
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
|
||||
*/
|
||||
@@ -108,6 +109,7 @@ int max77620_regulator_get_status(u32 id);
|
||||
int max77620_regulator_config_fps(u32 id);
|
||||
int max77620_regulator_set_voltage(u32 id, u32 mv);
|
||||
int max77620_regulator_enable(u32 id, int enable);
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
|
||||
void max77620_config_default();
|
||||
void max77620_low_battery_monitor_config();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -97,15 +97,15 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
}
|
||||
|
||||
//Load firmware or emulate memio environment for newer TSEC fw.
|
||||
if (kb <= KB_FIRMWARE_VERSION_600)
|
||||
if (kb == KB_FIRMWARE_VERSION_620)
|
||||
TSEC(TSEC_DMATRFBASE) = (u32)tsec_ctxt->fw >> 8;
|
||||
else
|
||||
{
|
||||
fwbuf = (u8 *)malloc(0x2000);
|
||||
u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf + 0x1000, 0x100);
|
||||
fwbuf = (u8 *)malloc(0x4000);
|
||||
u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf, 0x100);
|
||||
memcpy(fwbuf_aligned, tsec_ctxt->fw, tsec_ctxt->size);
|
||||
TSEC(TSEC_DMATRFBASE) = (u32)fwbuf_aligned >> 8;
|
||||
}
|
||||
else
|
||||
TSEC(TSEC_DMATRFBASE) = (u32)tsec_ctxt->fw >> 8;
|
||||
|
||||
for (u32 addr = 0; addr < tsec_ctxt->size; addr += 0x100)
|
||||
{
|
||||
@@ -116,7 +116,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
}
|
||||
}
|
||||
|
||||
if (kb >= KB_FIRMWARE_VERSION_620)
|
||||
if (kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
// Init SMMU translation for TSEC.
|
||||
pdir = smmu_init_for_tsec();
|
||||
@@ -174,45 +174,11 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
//Execute firmware.
|
||||
HOST1X(0x3300) = 0x34C2E1DA;
|
||||
TSEC(TSEC_STATUS) = 0;
|
||||
TSEC(TSEC_BOOTKEYVER) = tsec_ctxt->key_ver;
|
||||
TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1.
|
||||
TSEC(TSEC_BOOTVEC) = 0;
|
||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||
|
||||
if (kb <= KB_FIRMWARE_VERSION_600)
|
||||
{
|
||||
if (!_tsec_dma_wait_idle())
|
||||
{
|
||||
res = -3;
|
||||
goto out_free;
|
||||
}
|
||||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while (!TSEC(TSEC_STATUS))
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = -4;
|
||||
goto out_free;
|
||||
}
|
||||
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
|
||||
{
|
||||
res = -5;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
//Fetch result.
|
||||
HOST1X(0x3300) = 0;
|
||||
u32 buf[4];
|
||||
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
|
||||
memcpy(tsec_keys, &buf, 0x10);
|
||||
}
|
||||
else
|
||||
if (kb == KB_FIRMWARE_VERSION_620)
|
||||
{
|
||||
u32 start = get_tmr_us();
|
||||
u32 k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
|
||||
@@ -261,6 +227,40 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
// gfx_printf(&gfx_con, " dir: %s\n", (errst >> 16) & 1 ? "W" : "R");
|
||||
// gfx_printf(&gfx_con, " cid: %02x\n", errst & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_tsec_dma_wait_idle())
|
||||
{
|
||||
res = -3;
|
||||
goto out_free;
|
||||
}
|
||||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while (!TSEC(TSEC_STATUS))
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = -4;
|
||||
goto out_free;
|
||||
}
|
||||
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
|
||||
{
|
||||
res = -5;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
//Fetch result.
|
||||
HOST1X(0x3300) = 0;
|
||||
u32 buf[4];
|
||||
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
|
||||
memcpy(tsec_keys, &buf, 0x10);
|
||||
}
|
||||
|
||||
out_free:;
|
||||
free(fwbuf);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
typedef struct _tsec_ctxt_t
|
||||
{
|
||||
u32 key_ver;
|
||||
void *fw;
|
||||
u32 size;
|
||||
void *pkg1;
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
void _cluster_enable_power()
|
||||
{
|
||||
u8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & 0xDF);
|
||||
u8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO); // Get current pinmuxing
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & ~(1 << 5)); // Disable GPIO5 pinmuxing.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);
|
||||
|
||||
// Enable cores power.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "../utils/util.h"
|
||||
|
||||
extern sdmmc_t sd_sdmmc;
|
||||
extern boot_cfg_t *b_cfg;
|
||||
|
||||
void _config_oscillators()
|
||||
{
|
||||
@@ -97,6 +98,9 @@ void _config_pmc_scratch()
|
||||
|
||||
void _mbist_workaround()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000u;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = 0x40;
|
||||
@@ -142,27 +146,31 @@ void _mbist_workaround()
|
||||
|
||||
void _config_se_brom()
|
||||
{
|
||||
// Bootrom part we skipped.
|
||||
u32 sbk[4] = {
|
||||
FUSE(FUSE_PRIVATE_KEY0),
|
||||
FUSE(FUSE_PRIVATE_KEY1),
|
||||
FUSE(FUSE_PRIVATE_KEY2),
|
||||
FUSE(FUSE_PRIVATE_KEY3)
|
||||
};
|
||||
// Set SBK to slot 14.
|
||||
se_aes_key_set(14, sbk, 0x10);
|
||||
// Skip SBK/SSK if sept was run.
|
||||
if (!(b_cfg->boot_cfg & BOOT_CFG_SEPT_RUN))
|
||||
{
|
||||
// Bootrom part we skipped.
|
||||
u32 sbk[4] = {
|
||||
FUSE(FUSE_PRIVATE_KEY0),
|
||||
FUSE(FUSE_PRIVATE_KEY1),
|
||||
FUSE(FUSE_PRIVATE_KEY2),
|
||||
FUSE(FUSE_PRIVATE_KEY3)
|
||||
};
|
||||
// Set SBK to slot 14.
|
||||
se_aes_key_set(14, sbk, 0x10);
|
||||
|
||||
// Lock SBK from being read.
|
||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 14 * 4) = 0x7E;
|
||||
// Lock SBK from being read.
|
||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 14 * 4) = 0x7E;
|
||||
|
||||
// Lock SSK (although it's not set and unused anyways).
|
||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 15 * 4) = 0x7E;
|
||||
}
|
||||
|
||||
// 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;
|
||||
SE(SE_INT_STATUS_REG_OFFSET) = 0x1F;
|
||||
|
||||
// Lock SSK (although it's not set and unused anyways).
|
||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 15 * 4) = 0x7E;
|
||||
|
||||
// Clear the boot reason to avoid problems later
|
||||
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
|
||||
PMC(APBDEV_PMC_RST_STATUS) = 0x0;
|
||||
@@ -206,21 +214,30 @@ void config_hw()
|
||||
i2c_init(I2C_1);
|
||||
i2c_init(I2C_5);
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, 0x40);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, 0x78); // PWR delay for forced shutdown off.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
|
||||
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, 0x38);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, 0x3A);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, 0x38);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_LDO4, 0xF);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_LDO8, 0xC7);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_SD0, 0x4F);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_SD1, 0x29);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_SD3, 0x1B);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
|
||||
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1,
|
||||
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2,
|
||||
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||
max77620_regulator_config_fps(REGULATOR_LDO4);
|
||||
max77620_regulator_config_fps(REGULATOR_LDO8);
|
||||
max77620_regulator_config_fps(REGULATOR_SD0);
|
||||
max77620_regulator_config_fps(REGULATOR_SD1);
|
||||
max77620_regulator_config_fps(REGULATOR_SD3);
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, 0x22); // 3.x+
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,
|
||||
(4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD0, 42); //42 = (1125000uV - 600000) / 12500 -> 1.125V
|
||||
max77620_regulator_set_voltage(REGULATOR_SD0, 1125000);
|
||||
|
||||
// Fix GPU after warmboot for Linux.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);
|
||||
|
||||
_config_pmc_scratch(); // Missing from 4.x+
|
||||
|
||||
@@ -247,10 +264,6 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
|
||||
// Fix GPU after warmboot for Linux.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);
|
||||
}
|
||||
|
||||
// Power off display.
|
||||
|
||||
@@ -32,12 +32,16 @@
|
||||
#define PMC_PWR_DET_SDMMC1_IO_EN (1 << 12)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_DDR_CFG 0x1D0
|
||||
#define APBDEV_PMC_SCRATCH45 0x234
|
||||
#define APBDEV_PMC_SCRATCH46 0x238
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
|
||||
@@ -179,4 +179,8 @@
|
||||
#define I2S_CG_SLCG_ENABLE (1 << 0)
|
||||
#define I2S_CTRL_MASTER_EN (1 << 10)
|
||||
|
||||
/*! Special registers. */
|
||||
#define EMC_SCRATCH0 0x324
|
||||
#define EMC_SEPT_RUN (1 << 31)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -51,4 +51,17 @@ typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define BOOT_CFG_AUTOBOOT_EN (1 << 0)
|
||||
#define BOOT_CFG_FROM_LAUNCH (1 << 1)
|
||||
#define BOOT_CFG_SEPT_RUN (1 << 7)
|
||||
|
||||
typedef struct __attribute__((__packed__)) _boot_cfg_t
|
||||
{
|
||||
u8 boot_cfg;
|
||||
u8 autoboot;
|
||||
u8 autoboot_list;
|
||||
u8 rsvd_cfg;
|
||||
u8 rsvd[32];
|
||||
} boot_cfg_t;
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user