Compare commits

...

50 Commits

Author SHA1 Message Date
CTCaer
3f22601022 Bump hekate to v5.5.6 and Nyx to v1.0.3 2021-05-12 12:55:03 +03:00
CTCaer
a80a7ecba9 hos: nogc detection support for 12.0.2
12.0.2 burnt a fuse so we can now automatically detect if NoGC is needed for LAFW v5
2021-05-12 12:04:46 +03:00
CTCaer
7c450f4a5f hos: 12.0.2 support 2021-05-12 11:47:39 +03:00
CTCaer
6316d3076d nyx: fix restore logic when backup does not match emmc
- If sd backup size exceeds eMMC size, bail out.
- If partial files backup is smaller allow restoring in case user has an eMMC upgrade.
 Following the same behavior that single file backup has when it's smaller.
2021-05-12 11:47:25 +03:00
CTCaer
7181683d8e ums: various fixes
- Immediately exit if offset exceeds num of sectors.
- Correct cmnd type and checks.
- Inform user if ejected unsafely (while medium removal prevention is enabled).
2021-05-11 10:45:17 +03:00
CTCaer
7d7134dd9e utils: correct align down 2021-05-11 10:34:10 +03:00
CTCaer
c29db97f73 hwinit/joycon: move uart clock deinits to joycon driver 2021-05-11 10:24:48 +03:00
CTCaer
05833bb38c minerva: update to v1.4
- Correct Zqlatch period checks
- Update periodic training
- Simplify some logic
- Fix some mr13 values
- Separate EMC channel enums from macros
- Add extra reg flushes
- Fix tree margin comparison signedness
 By using incorrect signedness on tree margins the delta taps would always apply.
 By casting margins to integer it now properly checks if it should apply delta taps on the new trimmers.
 This fixes a bug that exists in every Nvidia emc dvfs code.
2021-05-11 10:23:08 +03:00
CTCaer
253de81a6b Further reduce hekate size by streamlining about screen 2021-05-11 10:11:31 +03:00
CTCaer
21e6a0cf7e pkg1: reduce struct sizes 2021-05-11 10:08:43 +03:00
CTCaer
d0fefabad7 nyx: return unknown if SD vendor is not known
TODO: Investigate which OEM/ODM makes the new Lexar SD cards.
2021-05-11 10:07:08 +03:00
CTCaer
44db160ab1 nyx: add info about new InnoLux panel revision 2021-05-11 10:04:31 +03:00
CTCaer
cb633a8f32 display: add info about new InnoLux panel revision 2021-05-11 10:04:24 +03:00
CTCaer
66b7130641 nyx: align total sectors to guarantee alignment
Helps on some sd cards with weird total sectors number.
2021-05-11 09:57:29 +03:00
CTCaer
80d9718770 GCC 11 fixes
The array/stringop warning removals are undesirable.
Consider removing them when a new GCC version moves back to saner checks for pointers.
2021-05-11 09:51:08 +03:00
CTCaer
dfbbca4c9f pkg2: isolate kernel/kip patches structs from code 2021-05-11 09:45:12 +03:00
CTCaer
f4d08b2d9b pkg2: refactor defines for kernel patches 2021-05-11 09:38:20 +03:00
CTCaer
588a834ae4 nyx: allow backing up resized emummc 2021-05-11 09:34:19 +03:00
CTCaer
833dda7e7c nyx: bpmp: automatically find best clock for t210
There were 4 reports of Nyx hanging or UMS and backup verification failing because of low binned Erista SoC.

This change reduces clock for hekate main and Nyx will now automatically try and find a working one.
In case Nyx hangs it will reduce it on next inject.

If Nyx works and user still has issues with UMS/Verification, manually editing nyx.ini and setting `bpmpclock=2` will fix that.
2021-05-11 09:32:38 +03:00
CTCaer
6a4ab55930 storage: add sd_get_card_mounted declaration 2021-05-11 09:22:39 +03:00
CTCaer
d7ce2a81db bpmp: return previous fid when setting a new one 2021-05-11 09:21:12 +03:00
CTCaer
4d90fa4830 hos: set applied bits on double defined kip patches
The loop would break before and if a patch was double defined, would not set its applied bit and thus throw an error.
2021-04-12 04:28:14 +03:00
CTCaer
501fdda138 main: do not clear screen on payload launch 2021-04-12 04:26:16 +03:00
CTCaer
678e8d34e3 Bump hekate to v5.5.5 and Nyx to v1.0.2 2021-04-11 15:02:35 +03:00
CTCaer
07d1982abf minerva: add compile time sdram voltage change 2021-04-11 10:31:57 +03:00
CTCaer
fd05f83636 ianos: add extensions magic
Useful to avoid using extensions if bootloader does not support them.
2021-04-11 10:30:24 +03:00
CTCaer
94e119fb51 max77620: allow max sdram voltage of 1.25V 2021-04-11 10:20:54 +03:00
CTCaer
c2ff4bf623 ianos: add regulator voltage set 2021-04-11 10:18:47 +03:00
CTCaer
faf5651607 minerva: more accurate clock tree delays
Additionally, do not restore source DPD ctrl when switching frequencies or training is not needed.
2021-04-11 09:50:06 +03:00
CTCaer
978e8344cf nyx: check for errors in benchmark 2021-04-11 09:28:28 +03:00
CTCaer
160d6eacc0 nyx: add new touch panel id 2021-04-11 09:27:47 +03:00
CTCaer
075d8e6393 gfx: change line if max width is reached 2021-04-11 09:25:53 +03:00
CTCaer
28008ac7ac hwinit: add seamless display (L4T Linux/Android)
Initial support is for coreboot based preloading.
2021-04-11 09:18:55 +03:00
CTCaer
345d36287e display: add pwm duty getter 2021-04-11 09:16:55 +03:00
CTCaer
edff6c551d hos: Add 12.0.0 support 2021-04-09 19:49:44 +03:00
CTCaer
d42a94f148 minerva: Scale down RAM OC if stock boot 2021-04-09 19:28:04 +03:00
CTCaer
c01b8aa89c exo: add usb3 force enable support
Like the other configs, it can be read from system_settings.ini and be set.

Additionally a new `usb3force` key was added to allow user to override and enable/disable that setting via a boot entry.
This allows for fast (re)boot into an entry that disables that (important because of the huge interference that USB3 creates to Bluetooth and WiFi 2.4GHz).
2021-03-17 09:31:06 +02:00
CTCaer
4958bd6a52 fatfs: utilize fatfs buffers for parsing gpt 2021-03-17 09:23:51 +02:00
CTCaer
46038032a4 bdk: make sure that boot storage has the correct size 2021-03-17 09:23:13 +02:00
CTCaer
f66ddca100 nyx: make hybrid mbr fixer smarter
Allow usage of FatFS simple gpt parsing for setting the fat partition in case its label is not hos_data.
Additionally allow hos_data partition to not be the first one.
2021-03-17 09:20:01 +02:00
CTCaer
6981c59de3 gpt: properly check that GPT is valid 2021-03-17 09:14:50 +02:00
CTCaer
f21f13b15d ums/nyx: reinit sd to update cal trimmers for max perf 2021-03-17 09:12:30 +02:00
CTCaer
ef5a01433d nyx: inform user that Fix RAW also fixes partition type 2021-03-17 09:09:59 +02:00
CTCaer
0e12d8545b Decrease stack usage on various functions 2021-03-17 09:08:34 +02:00
CTCaer
9dbf745649 regulator 5V: fix battery/usb source swap 2021-03-17 08:56:46 +02:00
CTCaer
e8f73a42b8 fan: increase irq polling to get more accurate rpm 2021-03-17 08:55:54 +02:00
CTCaer
dbe431095a touch: report gpio info in case of unknown panel 2021-03-17 08:53:23 +02:00
CTCaer
513f77a2ad uart: use proper interrupt decoding 2021-03-17 08:51:49 +02:00
CTCaer
e8cf85bd65 Merge pull request #575 from DarkMatterCore/master
Fix bin2c behaviour under Windows if compiled with MinGW / TDM-GCC.
2021-02-08 23:32:51 +02:00
Pablo Curiel
be23d1fa15 Update bin2c.c
Fix behaviour under Windows if compiled with MinGW / TDM-GCC.
2021-02-08 14:10:38 -04:00
69 changed files with 1811 additions and 1387 deletions

View File

@@ -73,8 +73,11 @@ CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
# DEBUG_UART_PORT - 0: UART_A, 1: UART_B, 2: UART_C.
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=0
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
WARNINGS := -Wall -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
MODULEDIRS := $(wildcard modules/*)

View File

@@ -70,7 +70,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
| jcdisable=0 | 1: Disables Joycon driver completely. |
| newpowersave=1 | 0: Timer based, 1: DRAM frequency based (Better). Use 0 if Nyx hangs. |
| bpmpclock=1 | 0: Auto, 1: Faster, 2: Fast. Use 2 if Nyx hangs or some functions like UMS/Backup Verification fail. |
### Boot entry key/value combinations:
@@ -88,7 +88,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
| fullsvcperm=1 | Disables SVC verification (full services permission) |
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
| atmosphere=1 | Enables Atmosphère patching. |
| atmosphere=1 | Enables Atmosphère patching. Not needed when `fss0` is used. |
| emupath={SD folder} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
| emummcforce=1 | Forces the use of emuMMC. If emummc.ini is disabled or not found, then it causes an error. |
| emummc_force_disable=1 | Disables emuMMC, if it's enabled. |
@@ -139,9 +139,9 @@ If the main .ini is not found, it is created on the first hekate boot.
```
hekate (c) 2018, naehrwert, st4rk.
(c) 2018-2020, CTCaer.
(c) 2018-2021, CTCaer.
Nyx GUI (c) 2019-2020, CTCaer.
Nyx GUI (c) 2019-2021, CTCaer.
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.

View File

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

View File

@@ -507,6 +507,11 @@ void display_backlight_brightness(u32 brightness, u32 step_delay)
PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
}
u32 display_get_backlight_brightness()
{
return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
}
static void _display_panel_and_hw_end(bool no_panel_deinit)
{
if (no_panel_deinit)

View File

@@ -650,8 +650,9 @@
* [10] 81 [26]: JDI LPM062M326A
* [10] 96 [09]: JDI LAM062M109A
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
* [20] 95 [0F]: InnoLux P062CCA-AZ2
* [20] 96 [0F]: InnoLux P062CCA-AZ3
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
* [20] 96 [0F]: InnoLux P062CCA-AZ3 [UNCONFIRMED MODEL REV]
* [20] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV]
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
*
@@ -706,6 +707,7 @@ void display_color_screen(u32 color);
/*! Switches screen backlight ON/OFF. */
void display_backlight(bool enable);
void display_backlight_brightness(u32 brightness, u32 step_delay);
u32 display_get_backlight_brightness();
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
u32 *display_init_framebuffer_pitch();

View File

@@ -21,6 +21,7 @@
#include "elfload/elfload.h"
#include <module.h>
#include <mem/heap.h>
#include <power/max7762x.h>
#include <storage/nx_sd.h>
#include <utils/types.h>
@@ -43,6 +44,10 @@ static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
bdkParameters->memset = (memset_t)&memset;
bdkParameters->sharedHeap = &_heap;
// Extra functions.
bdkParameters->extension_magic = IANOS_EXT0;
bdkParameters->reg_voltage_set = (reg_voltage_set_t)&max7762x_regulator_set_voltage;
entrypoint(moduleConfig, bdkParameters);
}

View File

@@ -1,7 +1,7 @@
/*
* Joy-Con UART driver for Nintendo Switch
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2021 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,
@@ -463,7 +463,7 @@ static void jc_rcv_pkt(joycon_ctxt_t *jc)
// Check if device stopped sending data.
u32 uart_irq = uart_get_IIR(jc->uart);
if ((uart_irq & 0x8) != 0x8)
if (uart_irq != UART_IIR_REDI)
return;
u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100);
@@ -715,6 +715,10 @@ void jc_deinit()
jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1);
jc_rcv_pkt(&jc_l);
}
// Disable UART B and C clocks.
clock_disable_uart(UART_B);
clock_disable_uart(UART_C);
}
static void jc_init_conn(joycon_ctxt_t *jc)
@@ -881,14 +885,14 @@ void jc_init_hw()
pinmux_config_uart(UART_C);
// Ease the stress to APB.
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
// Enable UART B and C clocks.
clock_enable_uart(UART_B);
clock_enable_uart(UART_C);
// Restore OC.
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(prev_fid);
// Turn Joy-Con detect on.
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);

View File

@@ -206,6 +206,7 @@ touch_panel_info_t *touch_get_panel_vendor()
{
u8 buf[5] = {0};
u8 cmd = STMFTS_VENDOR_GPIO_STATE;
static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""};
if (touch_command(STMFTS_VENDOR, &cmd, 1))
return NULL;
@@ -220,13 +221,20 @@ touch_panel_info_t *touch_get_panel_vendor()
return panel;
}
return NULL;
// Touch panel not found, return current gpios.
panel_info.gpio0 = buf[0];
panel_info.gpio1 = buf[1];
panel_info.gpio2 = buf[2];
return &panel_info;
}
int touch_get_fw_info(touch_fw_info_t *fw)
{
u8 buf[8] = {0};
memset(fw, 0, sizeof(touch_fw_info_t));
// Get fw address info.
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
int res = touch_read_reg(cmd, 3, buf, 3);
@@ -318,7 +326,7 @@ int touch_get_fb_info(u8 *buf)
int res = 0;
for (u32 i = 0; i < 0x10000; i+=4)
for (u32 i = 0; i < 0x10000; i += 4)
{
if (!res)
{
@@ -392,11 +400,11 @@ static int touch_init()
int touch_power_on()
{
// Enable LDO6 for touchscreen VDD/AVDD supply.
// Enable LDO6 for touchscreen AVDD supply.
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
max7762x_regulator_enable(REGULATOR_LDO6, true);
// Configure touchscreen GPIO.
// Configure touchscreen VDD GPIO.
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);
@@ -410,7 +418,7 @@ int touch_power_on()
// Configure Touscreen and GCAsic shared GPIO.
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2;
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
// Initialize I2C3.
pinmux_config_i2c(I2C_3);

View File

@@ -839,10 +839,12 @@ int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst
int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
{
int result;
LZ4_stream_t ctx;
LZ4_stream_t* const ctxPtr = &ctx;
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
LZ4_stream_t* const ctxPtr = ctx;
result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
FREEMEM(ctx);
return result;
}
@@ -857,13 +859,18 @@ int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxO
/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */
int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
{
LZ4_stream_t ctx;
LZ4_resetStream(&ctx);
int result;
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
LZ4_resetStream(ctx);
if (inputSize < LZ4_64Klimit)
return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
else
return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
FREEMEM(ctx);
return result;
}
@@ -1045,11 +1052,13 @@ static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src,
int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
{
LZ4_stream_t ctxBody;
LZ4_stream_t* ctx = &ctxBody;
LZ4_stream_t* ctxBody = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));;
LZ4_stream_t* ctx = ctxBody;
int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
FREEMEM(ctxBody);
return result;
}

View File

@@ -3323,11 +3323,13 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
#if FF_SIMPLE_GPT
if (fmt >= 2) {
/* If GPT Check the first partition */
gpt_t gpt;
if (disk_read(fs->pdrv, (BYTE *)&gpt, 1, sizeof(gpt_t) / SS(fs))) return FR_DISK_ERR;
if (!mem_cmp(&gpt.header.signature, "EFI PART", 8)) {
gpt_header_t *gpt_header = (gpt_header_t *)fs->win;
if (move_window(fs, 1) != FR_OK) return FR_DISK_ERR;
if (!mem_cmp(&gpt_header->signature, "EFI PART", 8)) {
if (move_window(fs, gpt_header->part_ent_lba) != FR_OK) return FR_DISK_ERR;
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win;
fs->part_type = 1;
bsect = gpt.entries[0].lba_start;
bsect = gpt_entry->lba_start;
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
}
}

View File

@@ -104,21 +104,21 @@ u32 minerva_init()
}
mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
mtc_cfg->rate_to = 204000;
mtc_cfg->rate_to = FREQ_204;
mtc_cfg->train_mode = OP_TRAIN;
minerva_cfg(mtc_cfg, NULL);
mtc_cfg->rate_to = 800000;
mtc_cfg->rate_to = FREQ_800;
minerva_cfg(mtc_cfg, NULL);
mtc_cfg->rate_to = 1600000;
mtc_cfg->rate_to = FREQ_1600;
minerva_cfg(mtc_cfg, NULL);
// FSP WAR.
mtc_cfg->train_mode = OP_SWITCH;
mtc_cfg->rate_to = 800000;
mtc_cfg->rate_to = FREQ_800;
minerva_cfg(mtc_cfg, NULL);
// Switch to max.
mtc_cfg->rate_to = 1600000;
mtc_cfg->rate_to = FREQ_1600;
minerva_cfg(mtc_cfg, NULL);
return 0;
@@ -139,6 +139,23 @@ void minerva_change_freq(minerva_freq_t freq)
}
}
void minerva_prep_boot_freq()
{
if (!minerva_cfg)
return;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
// Check if there's RAM OC. If not exit.
if (mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
return;
// FSP WAR.
minerva_change_freq(FREQ_204);
// Scale down to 800 MHz boot freq.
minerva_change_freq(FREQ_800);
}
void minerva_periodic_training()
{
if (!minerva_cfg)

View File

@@ -60,6 +60,7 @@ typedef enum
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init();
void minerva_change_freq(minerva_freq_t freq);
void minerva_prep_boot_freq();
void minerva_periodic_training();
#endif

View File

@@ -21,10 +21,13 @@
#include <stddef.h>
#include <mem/heap.h>
#define IANOS_EXT0 0x304E4149
// Module Callback
typedef void (*cbMainModule_t)(const char *s);
typedef void (*memcpy_t)(void *, void *, size_t);
typedef void (*memset_t)(void *, int, size_t);
typedef int (*reg_voltage_set_t)(u32, u32);
typedef struct _bdkParams_t
{
@@ -33,6 +36,8 @@ typedef struct _bdkParams_t
heap_t *sharedHeap;
memcpy_t memcpy;
memset_t memset;
u32 extension_magic;
reg_voltage_set_t reg_voltage_set;
} *bdkParams_t;
// Module Entrypoint

View File

@@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
static const max77620_regulator_t _pmic_regulators[] = {
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
{ "sd1", 12500, 600000, 1125000, 1125000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
{ "sd1", 12500, 600000, 1125000, 1250000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },
@@ -328,6 +328,7 @@ void max77620_config_default()
_max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, MAX77620_SD_CNF2_ROVS_EN_SD0);
}
// Stock HOS: disabled.
void max77620_low_battery_monitor_config(bool enable)
{
_max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,

View File

@@ -32,11 +32,11 @@
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 | 0.85V (AO, pcv)
* ldo5 | GC Card | 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 |
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V (pcv)
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
*/
/*
@@ -135,10 +135,10 @@
#define MAX77621_CTRL_HOS_CFG 0
#define MAX77621_CTRL_POR_CFG 1
int max77620_regulator_get_status(u32 id);
int max77620_regulator_config_fps(u32 id);
int max7762x_regulator_set_voltage(u32 id, u32 mv);
int max7762x_regulator_enable(u32 id, bool enable);
int max77620_regulator_get_status(u32 id);
int max77620_regulator_config_fps(u32 id);
int max7762x_regulator_set_voltage(u32 id, u32 mv);
int max7762x_regulator_enable(u32 id, bool enable);
void max77620_config_gpio(u32 id, bool enable);
void max77620_config_default();
void max77620_low_battery_monitor_config(bool enable);

View File

@@ -81,7 +81,13 @@ bool regulator_5v_get_dev_enabled(u8 dev)
void regulator_5v_batt_src_enable(bool enable)
{
if (enable && !batt_src)
{
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
batt_src = true;
}
else if (!enable && batt_src)
{
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
batt_src = false;
}
}

View File

@@ -70,7 +70,7 @@ int tsec_query(void *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
u32 *pkg11_magic_off;
bpmp_mmu_disable();
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
// Enable clocks.
clock_enable_host1x();
@@ -284,7 +284,7 @@ out:;
clock_disable_sor_safe();
clock_disable_tsec();
bpmp_mmu_enable();
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(prev_fid);
return res;
}

View File

@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019-2020 CTCaer
* Copyright (c) 2019-2021 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,
@@ -212,43 +212,45 @@ const u8 pll_divn[] = {
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
};
bpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;
bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
void bpmp_clk_rate_get()
{
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
if (clk_src_is_pllp)
bpmp_clock_set = BPMP_CLK_NORMAL;
bpmp_fid_current = BPMP_CLK_NORMAL;
else
{
bpmp_clock_set = BPMP_CLK_HIGH_BOOST;
bpmp_fid_current = BPMP_CLK_HIGH_BOOST;
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
for (u32 i = 1; i < sizeof(pll_divn); i++)
{
if (pll_divn[i] == pll_divn_curr)
{
bpmp_clock_set = i;
bpmp_fid_current = i;
break;
}
}
}
}
void bpmp_clk_rate_set(bpmp_freq_t fid)
bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid)
{
bpmp_freq_t prev_fid = bpmp_fid_current;
if (fid > (BPMP_CLK_MAX - 1))
fid = BPMP_CLK_MAX - 1;
if (bpmp_clock_set == fid)
return;
if (prev_fid == fid)
return prev_fid;
if (fid)
{
if (bpmp_clock_set)
if (prev_fid)
{
// Restore to PLLP source during PLLC4 configuration.
// Restore to PLLP source during PLLC configuration.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // PLLP_OUT.
msleep(1); // Wait a bit for clock source change.
}
@@ -269,7 +271,10 @@ void bpmp_clk_rate_set(bpmp_freq_t fid)
// Disable PLLC to save power.
clock_disable_pllc();
}
bpmp_clock_set = fid;
bpmp_fid_current = fid;
// Return old fid in case of temporary swap.
return prev_fid;
}
// The following functions halt BPMP to reduce power while sleeping.

View File

@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019-2020 CTCaer
* Copyright (c) 2019-2021 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,
@@ -53,6 +53,7 @@ typedef enum
BPMP_CLK_MAX
} bpmp_freq_t;
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
void bpmp_mmu_maintenance(u32 op, bool force);
@@ -60,7 +61,7 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
void bpmp_mmu_enable();
void bpmp_mmu_disable();
void bpmp_clk_rate_get();
void bpmp_clk_rate_set(bpmp_freq_t fid);
bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid);
void bpmp_usleep(u32 us);
void bpmp_msleep(u32 ms);
void bpmp_halt();

View File

@@ -88,6 +88,7 @@ static void _config_oscillators()
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
}
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
static void _config_gpios(bool nx_hoag)
{
// Clamp inputs when tristated.
@@ -420,7 +421,7 @@ void hw_init()
bpmp_mmu_enable();
}
void hw_reinit_workaround(bool coreboot, u32 magic)
void hw_reinit_workaround(bool coreboot, u32 bl_magic)
{
// Disable BPMP max clock.
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
@@ -432,8 +433,6 @@ void hw_reinit_workaround(bool coreboot, u32 magic)
touch_power_off();
jc_deinit();
regulator_5v_disable(REGULATOR_5V_ALL);
clock_disable_uart(UART_B);
clock_disable_uart(UART_C);
#endif
// Flush/disable MMU cache and set DRAM clock to 204MHz.
@@ -462,11 +461,22 @@ void hw_reinit_workaround(bool coreboot, u32 magic)
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
}
// Power off display.
display_end();
// Seamless display or display power off.
switch (bl_magic)
{
case BL_MAGIC_CRBOOT_SLD:;
// Set pwm to 0%, switch to gpio mode and restore pwm duty.
u32 brightness = display_get_backlight_brightness();
display_backlight_brightness(0, 1000);
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO);
display_backlight_brightness(brightness, 0);
break;
default:
display_end();
}
// Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.
if (magic == 0xBAADF00D)
if (bl_magic == BL_MAGIC_BROKEN_HWI)
{
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);

View File

@@ -20,6 +20,9 @@
#include <utils/types.h>
#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0.
#define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit.
void hw_init();
void hw_reinit_workaround(bool coreboot, u32 magic);
u32 hw_get_chip_id();

View File

@@ -122,7 +122,12 @@ u32 uart_get_IIR(u32 idx)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
return uart->UART_IIR_FCR;
u32 iir = uart->UART_IIR_FCR & UART_IIR_INT_MASK;
if (iir & UART_IIR_NO_INT)
return 0;
else
return ((iir >> 1) + 1); // Return encoded interrupt.
}
void uart_set_IIR(u32 idx)

View File

@@ -54,6 +54,17 @@
#define UART_IIR_FCR_RX_CLR 0x2
#define UART_IIR_FCR_EN_FIFO 0x1
#define UART_IIR_NO_INT BIT(0)
#define UART_IIR_INT_MASK 0xF
/* Custom returned interrupt results. Actual interrupts are -1 */
#define UART_IIR_NOI 0 // No interrupt.
#define UART_IIR_MSI 1 // Modem status interrupt.
#define UART_IIR_THRI 2 // Transmitter holding register empty.
#define UART_IIR_RDI 3 // Receiver data interrupt.
#define UART_IIR_ERROR 4 // Overrun Error, Parity Error, Framing Error, Break.
#define UART_IIR_REDI 5 // Receiver end of data interrupt.
#define UART_IIR_RDTI 7 // Receiver data timeout interrupt.
#define UART_MCR_RTS 0x2
#define UART_MCR_DTR 0x1

View File

@@ -46,6 +46,7 @@ void sd_error_count_increment(u8 type);
u16 *sd_get_error_count();
bool sd_get_card_removed();
bool sd_get_card_initialized();
bool sd_get_card_mounted();
u32 sd_get_mode();
int sd_init_retry(bool power_cycle);
bool sd_initialize(bool power_cycle);

View File

@@ -26,7 +26,7 @@
void set_fan_duty(u32 duty)
{
static bool fan_init = false;
static u16 curr_duty = -1;
static u16 curr_duty = -1;
if (curr_duty == duty)
return;
@@ -79,15 +79,14 @@ void get_fan_speed(u32 *duty, u32 *rpm)
{
if (rpm)
{
u32 irq_count = 1;
u32 irq_count = 0;
bool should_read = true;
bool irq_val = 0;
// Poll irqs for 2 seconds.
int timer = get_tmr_us() + 1000000;
while (timer - get_tmr_us())
// Poll irqs for 2 seconds. (5 seconds for accurate count).
int timer = get_tmr_us() + 2000000;
while ((timer - get_tmr_us()) > 0)
{
irq_val = gpio_read(GPIO_PORT_S, GPIO_PIN_7);
bool irq_val = gpio_read(GPIO_PORT_S, GPIO_PIN_7);
if (irq_val && should_read)
{
irq_count++;
@@ -97,8 +96,11 @@ void get_fan_speed(u32 *duty, u32 *rpm)
should_read = true;
}
// Halve the irq count.
irq_count /= 2;
// Calculate rpm based on triggered interrupts.
*rpm = 60000000 / ((1000000 * 2) / irq_count);
*rpm = irq_count * (60 / 2);
}
if (duty)

View File

@@ -203,7 +203,7 @@ typedef struct _bulk_ctxt_t {
typedef struct _usbd_gadget_ums_t {
bulk_ctxt_t bulk_ctxt;
int cmnd_size;
u32 cmnd_size;
u8 cmnd[SCSI_MAX_CMD_SZ];
u32 lun_idx; // lun index
@@ -583,22 +583,20 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
while (amount_left_to_write > 0)
{
/* Queue a request for more data from the host */
if (amount_left_to_req)
if (amount_left_to_req > 0)
{
// Limit write to max supported read from EP OUT.
amount = MIN(amount_left_to_req, UMS_EP_OUT_MAX_XFER);
if (usb_lba_offset >= ums->lun.num_sectors) //////////Check if it works with concurrency
if (usb_lba_offset >= ums->lun.num_sectors)
{
ums->set_text(ums->label, "#FFDD00 Error:# Write - Past last sector!");
amount_left_to_req = 0;
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
ums->lun.sense_data_info = usb_lba_offset;
ums->lun.info_valid = 1;
continue;
break;
}
// Get the next buffer.
@@ -1114,7 +1112,7 @@ static int _scsi_read_format_capacities(usbd_gadget_ums_t *ums, bulk_ctxt_t *bul
// Check whether the command is properly formed and whether its data size
// and direction agree with the values we already have.
static int _ums_check_scsi_cmd(usbd_gadget_ums_t *ums, int cmnd_size,
static int _ums_check_scsi_cmd(usbd_gadget_ums_t *ums, u32 cmnd_size,
enum data_direction data_dir, u32 mask, int needs_medium)
{
//const char dirletter[4] = {'u', 'o', 'i', 'n'};
@@ -1608,7 +1606,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
/* Is the CBW meaningful? */
if (cbw->Lun >= UMS_MAX_LUN || cbw->Flags & ~USB_BULK_IN_FLAG ||
cbw->Length <= 0 || cbw->Length > SCSI_MAX_CMD_SZ)
cbw->Length == 0 || cbw->Length > SCSI_MAX_CMD_SZ)
{
gfx_printf("USB: non-meaningful CBW: lun = %X, flags = 0x%X, cmdlen %X\n",
cbw->Lun, cbw->Flags, cbw->Length);
@@ -1837,6 +1835,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
// Initialize sdmmc.
if (usbs->type == MMC_SD)
{
sd_end();
sd_mount();
sd_unmount();
ums.lun.sdmmc = &sd_sdmmc;
@@ -1907,7 +1906,10 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
send_status(&ums, &ums.bulk_ctxt);
} while (ums.state != UMS_STATE_TERMINATED);
ums.set_text(ums.label, "#C7EA46 Status:# Disk ejected");
if (ums.lun.prevent_medium_removal)
ums.set_text(ums.label, "#FFDD00 Error:# Disk unsafely ejected");
else
ums.set_text(ums.label, "#C7EA46 Status:# Disk ejected");
goto exit;
error:

View File

@@ -21,16 +21,16 @@
#include <mem/heap.h>
#include <utils/types.h>
#define MAX_ENTRIES 64
char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs)
{
u8 max_entries = 61;
int res = 0;
u32 i = 0, j = 0, k = 0;
DIR dir;
FILINFO fno;
char *dir_entries = (char *)calloc(max_entries, 256);
char *dir_entries = (char *)calloc(MAX_ENTRIES, 256);
char *temp = (char *)calloc(1, 256);
if (!pattern && !f_opendir(&dir, directory))
@@ -49,7 +49,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
{
strcpy(dir_entries + (k * 256), fno.fname);
k++;
if (k > (max_entries - 1))
if (k > (MAX_ENTRIES - 1))
break;
}
}
@@ -64,7 +64,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
{
strcpy(dir_entries + (k * 256), fno.fname);
k++;
if (k > (max_entries - 1))
if (k > (MAX_ENTRIES - 1))
break;
}
res = f_findnext(&dir, &fno);

View File

@@ -66,14 +66,14 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
{
FIL fp;
u32 lblen;
u32 pathlen = strlen(ini_path);
u32 k = 0;
char lbuf[512];
char *filelist = NULL;
FIL fp;
ini_sec_t *csec = NULL;
char *lbuf = NULL;
char *filelist = NULL;
char *filename = (char *)malloc(256);
strcpy(filename, ini_path);
@@ -114,6 +114,8 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
return 0;
}
lbuf = malloc(512);
do
{
// Fetch one line.
@@ -168,6 +170,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
}
} while (is_dir);
free(lbuf);
free(filename);
free(filelist);

View File

@@ -18,10 +18,12 @@
#ifndef _TYPES_H_
#define _TYPES_H_
#include <assert.h>
#define NULL ((void *)0)
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define ALIGN_DOWN(x, a) (((x) - ((a) - 1)) & ~((a) - 1))
#define ALIGN_DOWN(x, a) ((x) & ~((a) - 1))
#define BIT(n) (1U << (n))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -116,6 +118,8 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t
};
} boot_cfg_t;
static_assert(sizeof(boot_cfg_t) == 0x84, "Boot CFG size is wrong!");
typedef struct __attribute__((__packed__)) _ipl_ver_meta_t
{
u32 magic;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2021 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,
@@ -58,7 +58,7 @@ int create_config_entry()
if (!sd_mount())
return 1;
char lbuf[32];
char lbuf[64];
FIL fp;
bool mainIniFound = false;

View File

@@ -77,7 +77,7 @@ void tui_pbar(int x, int y, u32 val, u32 fgcol, u32 bgcol)
x += 7 * gfx_con.fntsz;
for (int i = 0; i < (gfx_con.fntsz >> 3) * 6; i++)
for (u32 i = 0; i < (gfx_con.fntsz >> 3) * 6; i++)
{
gfx_line(x, y + i + 1, x + 3 * val, y + i + 1, fgcol);
gfx_line(x + 3 * val, y + i + 1, x + 3 * 100, y + i + 1, bgcol);

View File

@@ -81,15 +81,16 @@ typedef struct _fss_content_t
char name[0x10];
} fss_content_t;
static void _update_r2p(const char *path)
static void _update_r2p(launch_ctxt_t *ctxt, const char *path)
{
char *r2p_path = malloc(256);
char *r2p_path = malloc(512);
u32 path_len = strlen(path);
strcpy(r2p_path, path);
while(path_len)
{
if ((r2p_path[path_len - 1] == '/') || (r2p_path[path_len - 1] == 0x5C))
if ((r2p_path[path_len - 1] == '/') || (r2p_path[path_len - 1] == '\\'))
{
r2p_path[path_len] = 0;
strcat(r2p_path, "reboot_payload.bin");
@@ -98,6 +99,15 @@ static void _update_r2p(const char *path)
is_ipl_updated(r2p_payload, r2p_path, h_cfg.updater2p ? true : false);
free(r2p_payload);
// Save fss0 parrent path.
if (ctxt)
{
r2p_path[path_len] = 0;
ctxt->fss0_main_path = r2p_path;
return;
}
break;
}
path_len--;
@@ -264,7 +274,7 @@ out:
gfx_printf("Done!\n");
f_close(&fp);
_update_r2p(path);
_update_r2p(ctxt, path);
return (!sept_ctxt ? 1 : sept_used);
}

View File

@@ -684,7 +684,7 @@ static bool _get_fs_exfat_compatible(link_t *info, bool *fs_is_510)
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
{
if (strncmp((const char*)ki->kip1->name, "FS", 2))
if (strncmp((const char*)ki->kip1->name, "FS", sizeof(ki->kip1->name)))
continue;
if (!se_calc_sha256_oneshot(sha_buf, ki->kip1, ki->size))
@@ -797,13 +797,17 @@ int hos_launch(ini_sec_t *cfg)
(
(!(fuses & ~0xF) && (ctxt.pkg1_id->fuses >= 5)) || // LAFW v2, 4.0.0+
(!(fuses & ~0x3FF) && (ctxt.pkg1_id->fuses >= 11)) || // LAFW v3, 9.0.0+
(!(fuses & ~0x1FFF) && (ctxt.pkg1_id->fuses >= 14)) // LAFW v4, 11.0.0+
(!(fuses & ~0x1FFF) && (ctxt.pkg1_id->fuses >= 14)) || // LAFW v4, 11.0.0+
// Detection broken! Use kip1patch=nogc // LAFW v5, 12.0.0+
(!(fuses & ~0x3FFF) && (ctxt.pkg1_id->fuses >= 15)) // LAFW v5, 12.0.2+
)
)
|| ((emummc_enabled) &&
(
((fuses & 0x400) && (ctxt.pkg1_id->fuses <= 10)) || // HOS 9.0.0+ fuses burnt.
((fuses & 0x2000) && (ctxt.pkg1_id->fuses <= 13)) // HOS 11.0.0+ fuses burnt.
((fuses & 0x400) && (ctxt.pkg1_id->fuses <= 10)) || // HOS 9.0.0+ fuses burnt.
((fuses & 0x2000) && (ctxt.pkg1_id->fuses <= 13)) || // HOS 11.0.0+ fuses burnt.
// Detection broken! Use kip1patch=nogc // HOS 12.0.0+
((fuses & 0x4000) && (ctxt.pkg1_id->fuses <= 14)) // HOS 11.0.2+ fuses burnt.
)
))
config_kip1patch(&ctxt, "nogc");
@@ -1140,6 +1144,10 @@ int hos_launch(ini_sec_t *cfg)
bpmp_mmu_disable();
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
// Scale down RAM OC if enabled.
if (ctxt.stock)
minerva_prep_boot_freq();
// emuMMC: Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
sdmmc_storage_init_wait_sd();

View File

@@ -51,6 +51,7 @@ typedef struct _exo_ctxt_t
bool fs_is_510;
bool no_user_exceptions;
bool user_pmu;
bool *usb3_force;
bool *cal0_blank;
bool *cal0_allow_writes_sys;
} exo_ctxt_t;
@@ -107,14 +108,16 @@ typedef struct _launch_ctxt_t
link_t kip1_list;
char* kip1_patches;
u32 fss0_hosver;
bool svcperm;
bool debugmode;
bool stock;
bool atmosphere;
bool fss0_experimental;
bool emummc_forced;
char *fss0_main_path;
u32 fss0_hosver;
bool fss0_experimental;
bool atmosphere;
exo_ctxt_t exo_ctx;
ini_sec_t *cfg;

View File

@@ -220,6 +220,19 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value)
return 1;
}
static int _config_exo_usb3_force(launch_ctxt_t *ctxt, const char *value)
{
// Override key found.
ctxt->exo_ctx.usb3_force = calloc(sizeof(bool), 1);
if (*value == '1')
{
DPRINTF("Enabled USB 3.0\n");
*ctxt->exo_ctx.usb3_force = true;
}
return 1;
}
static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value)
{
// Override key found.
@@ -291,6 +304,7 @@ static const cfg_handler_t _config_handlers[] = {
{ "emummcforce", _config_emummc_forced },
{ "nouserexceptions", _config_dis_exo_user_exceptions },
{ "userpmu", _config_exo_user_pmu_access },
{ "usb3force", _config_exo_usb3_force },
{ "cal0blank", _config_exo_cal0_blanking },
{ "cal0writesys", _config_exo_cal0_writes_enable },
{ NULL, NULL },

View File

@@ -127,10 +127,6 @@ PATCHSET_DEF(_warmboot_1_patchset,
{ 0x4DC, _NOPv7() } // Fuse check.
);
PATCHSET_DEF(_warmboot_2_patchset,
{ 0x4DC, _NOPv7() } // Fuse check.
);
PATCHSET_DEF(_warmboot_3_patchset,
{ 0x4DC, _NOPv7() }, // Fuse check.
{ 0x4F0, _NOPv7() } // Segment id check.
@@ -155,28 +151,29 @@ static const u8 sec_map_4xx[3] = { PK11_SECTION_LD, PK11_SECTION_SM, PK11_SECTIO
// ID (Timestamp), KB, Fuses, TSEC, PK11, SECMON, Warmboot.
static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0, 1, 0x1900, 0x3FE0, SM_100_ADR, 0x8000D000, _secmon_1_patchset, _warmboot_1_patchset }, // 1.0.0 (Patched relocator).
{ "20170210155124", 0, 2, 0x1900, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_2_patchset, _warmboot_2_patchset }, // 2.0.0 - 2.3.0.
{ "20170519101410", 1, 3, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_3_patchset, _warmboot_3_patchset }, // 3.0.0.
{ "20170710161758", 2, 4, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_3_patchset, _warmboot_3_patchset }, // 3.0.1 - 3.0.2.
{ "20170921172629", 3, 5, 0x1800, 0x3FE0, 0x4002B000, 0x4003B000, _secmon_4_patchset, _warmboot_4_patchset }, // 4.0.0 - 4.1.0.
{ "20180220163747", 4, 6, 0x1900, 0x3FE0, 0x4002B000, 0x4003B000, _secmon_5_patchset, _warmboot_4_patchset }, // 5.0.0 - 5.1.0.
{ "20180802162753", 5, 7, 0x1900, 0x3FE0, 0x4002B000, 0x4003D800, _secmon_6_patchset, _warmboot_4_patchset }, // 6.0.0 - 6.1.0.
{ "20181107105733", 6, 8, 0x0E00, 0x6FE0, 0x4002B000, 0x4003D800, _secmon_62_patchset, _warmboot_4_patchset }, // 6.2.0.
{ "20181218175730", 7, 9, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 7.0.0.
{ "20190208150037", 7, 9, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 7.0.1.
{ "20190314172056", 7, 9, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 8.0.0 - 8.0.1.
{ "20190531152432", 8, 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 8.1.0 - 8.1.1.
{ "20190809135709", 9, 11, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 9.0.0 - 9.0.1.
{ "20191021113848", 10, 12, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 9.1.0 - 9.2.0.
{ "20200303104606", 10, 13, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 10.0.0 - 10.2.0.
{ "20201030110855", 10, 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL, NULL }, // 11.0.0+
{ NULL } // End.
{ "20161121183008", 0, 1, 0x1900, 0x3FE0, SM_100_ADR, 0x8000D000, _secmon_1_patchset }, // 1.0.0 (Patched relocator).
{ "20170210155124", 0, 2, 0x1900, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_2_patchset }, // 2.0.0 - 2.3.0.
{ "20170519101410", 1, 3, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_3_patchset }, // 3.0.0.
{ "20170710161758", 2, 4, 0x1A00, 0x3FE0, 0x4002D000, 0x8000D000, _secmon_3_patchset }, // 3.0.1 - 3.0.2.
{ "20170921172629", 3, 5, 0x1800, 0x3FE0, 0x4002B000, 0x4003B000, _secmon_4_patchset }, // 4.0.0 - 4.1.0.
{ "20180220163747", 4, 6, 0x1900, 0x3FE0, 0x4002B000, 0x4003B000, _secmon_5_patchset }, // 5.0.0 - 5.1.0.
{ "20180802162753", 5, 7, 0x1900, 0x3FE0, 0x4002B000, 0x4003D800, _secmon_6_patchset }, // 6.0.0 - 6.1.0.
{ "20181107105733", 6, 8, 0x0E00, 0x6FE0, 0x4002B000, 0x4003D800, _secmon_62_patchset}, // 6.2.0.
{ "20181218175730", 7, 9, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 7.0.0.
{ "20190208150037", 7, 9, 0x0F00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 7.0.1.
{ "20190314172056", 7, 9, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 8.0.0 - 8.0.1.
{ "20190531152432", 8, 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 8.1.0 - 8.1.1.
{ "20190809135709", 9, 11, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 9.0.0 - 9.0.1.
{ "20191021113848", 10, 12, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 9.1.0 - 9.2.0.
{ "20200303104606", 10, 13, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 10.0.0 - 10.2.0.
{ "20201030110855", 10, 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 11.0.0 - 11.0.1.
{ "20210129111626", 10, 14, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 12.0.0 - 12.0.1.
{ "20210422145837", 10, 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 12.0.2+
};
const pkg1_id_t *pkg1_get_latest()
{
return &_pkg1_ids[ARRAY_SIZE(_pkg1_ids) - 2];
return &_pkg1_ids[ARRAY_SIZE(_pkg1_ids) - 1];
}
const pkg1_id_t *pkg1_identify(u8 *pkg1)
@@ -186,7 +183,7 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1)
build_date[14] = 0;
gfx_printf("Found pkg1 ('%s').\n\n", build_date);
for (u32 i = 0; _pkg1_ids[i].id; i++)
for (u32 i = 0; i < ARRAY_SIZE(_pkg1_ids); i++)
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 8))
return &_pkg1_ids[i];
return NULL;
@@ -194,13 +191,13 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1)
int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
{
// Decrypt package1.
pk11_hdr_t *hdr;
u8 *pkg11 = pkg1 + id->pkg11_off;
u32 pkg11_size = *(u32 *)pkg11;
// Decrypt package1.
if (!h_cfg.t210b01)
{
u8 *pkg11 = pkg1 + id->pkg11_off;
u32 pkg11_size = *(u32 *)pkg11;
hdr = (pk11_hdr_t *)(pkg11 + 0x20);
se_aes_crypt_ctr(11, hdr, pkg11_size, hdr, pkg11_size, pkg11 + 0x10);
}
@@ -311,9 +308,21 @@ void pkg1_secmon_patch(void *hos_ctxt, u32 secmon_base, bool t210b01)
void pkg1_warmboot_patch(void *hos_ctxt)
{
launch_ctxt_t *ctxt = (launch_ctxt_t *)hos_ctxt;
patch_t *warmboot_patchset;
// Patch warmboot on T210 to allow downgrading.
patch_t *warmboot_patchset = ctxt->pkg1_id->warmboot_patchset;
switch (ctxt->pkg1_id->kb)
{
case 0:
warmboot_patchset = _warmboot_1_patchset;
break;
case 1 ... 2:
warmboot_patchset = _warmboot_3_patchset;
break;
default: // 4.0.0 - 6.2.0.
warmboot_patchset = _warmboot_4_patchset;
break;
}
gfx_printf("%kPatching Warmboot%k\n", 0xFFFFBA00, 0xFFCCCCCC);
for (u32 i = 0; warmboot_patchset[i].off != 0xFFFFFFFF; i++)
*(vu32 *)(ctxt->pkg1_id->warmboot_base + warmboot_patchset[i].off) = warmboot_patchset[i].val;

View File

@@ -60,7 +60,6 @@ typedef struct _pkg1_id_t
u32 secmon_base;
u32 warmboot_base;
patch_t *secmon_patchset;
patch_t *warmboot_patchset;
} pkg1_id_t;
typedef struct _pk11_hdr_t

View File

@@ -1,7 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -49,403 +48,6 @@ u32 pkg2_newkern_ini1_end;
#define DPRINTF(...)
#endif
//TODO: Replace hardcoded AArch64 instructions with instruction macros.
//TODO: Reduce hardcoded values without searching kernel for patterns?
// The process ID send/receive kernel patches were taken from Atmosphère's kernel patches.
// They should only be used when running Atmosphère.
#define FREE_CODE_OFF_1ST_100 0x4797C
#define FREE_CODE_OFF_1ST_200 0x6486C
#define FREE_CODE_OFF_1ST_300 0x494A4
#define FREE_CODE_OFF_1ST_302 0x494BC
#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 FREE_CODE_OFF_1ST_800 0x607F0
#define FREE_CODE_OFF_1ST_900 0x65780
#define FREE_CODE_OFF_1ST_1000 0x67790
#define FREE_CODE_OFF_1ST_1100 0x49EE8
#define ID_SND_OFF_100 0x23CC0
#define ID_SND_OFF_200 0x3F134
#define ID_SND_OFF_300 0x26080
#define ID_SND_OFF_302 0x26080
#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_SND_OFF_800 0x2F1FC
#define ID_SND_OFF_900 0x329A0
#define ID_SND_OFF_1000 0x34404
#define ID_SND_OFF_1100 0x245B4
#define ID_SND_OFF_1101 0x245B8
#define ID_RCV_OFF_100 0x219F0
#define ID_RCV_OFF_200 0x3D1A8
#define ID_RCV_OFF_300 0x240F0
#define ID_RCV_OFF_302 0x240F0
#define ID_RCV_OFF_400 0x28F6C
#define ID_RCV_OFF_500 0x28DAC
#define ID_RCV_OFF_600 0x29B6C
#define ID_RCV_OFF_700 0x2B23C
#define ID_RCV_OFF_800 0x2D424
#define ID_RCV_OFF_900 0x309B4
#define ID_RCV_OFF_1000 0x322F8
#define ID_RCV_OFF_1100 0x22B24
#define ID_RCV_OFF_1101 0x22B28
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) + sizeof(u32))
static u32 PRC_ID_RCV_100[] =
{
0xA9BF2FEA, 0x2A1C03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9412968, 0xA8C12FEA
};
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) + sizeof(u32))
static u32 PRC_ID_RCV_200[] =
{
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9413168, 0xA8C12FEA
};
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) + sizeof(u32))
static u32 PRC_ID_RCV_300[] =
{
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA
};
#define FREE_CODE_OFF_2ND_302 (FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300) + sizeof(u32))
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) + sizeof(u32))
static u32 PRC_ID_RCV_400[] =
{
0xF9403BED, 0x2A0E03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B28, 0xD503201F
};
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) + sizeof(u32))
static u32 PRC_ID_RCV_500[] =
{
0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA
};
static u32 PRC_ID_SND_600[] =
{
0xA9BF2FEA, 0xF94037EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
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) + sizeof(u32))
static u32 PRC_ID_RCV_600[] =
{
0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
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
};
#define FREE_CODE_OFF_2ND_800 (FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700) + sizeof(u32))
static u32 PRC_ID_SND_900[] =
{
0xA9BF2FEA, 0xF94037EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define FREE_CODE_OFF_2ND_900 (FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900) + sizeof(u32))
static u32 PRC_ID_RCV_900[] =
{
0xA9BF2FEA, 0xF9404BEB, 0x2A1703EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1000[] =
{
0xA9BF2FEA, 0xF94063EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define FREE_CODE_OFF_2ND_1000 (FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000) + sizeof(u32))
static u32 PRC_ID_RCV_1000[] =
{
0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1100[] =
{
0xA9BF2FEA, 0xF94043EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define FREE_CODE_OFF_2ND_1100 (FREE_CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100) + sizeof(u32))
static u32 PRC_ID_RCV_1100[] =
{
0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
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
{ DEBUG_MODE_EN, 0x44074, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ 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 + 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 + sizeof(u32)), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_2_patchset,
{ SVC_VERIFY_DS, 0x54834, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x6086C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ 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 + 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 + sizeof(u32)), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_3_patchset,
{ SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x483FC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ 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 + 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 + sizeof(u32)), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_302_patchset,
{ SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x48414, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ 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_300) >> 2, PRC_ID_SND_300}, // Send process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction.
_B(FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300), 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_300) >> 2, PRC_ID_RCV_300}, // Receive process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction.
_B(FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_302 + sizeof(u32)), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_4_patchset,
{ SVC_VERIFY_DS, 0x41EB4, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x4EBFC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ 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 + 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 + sizeof(u32)), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_5_patchset,
{ SVC_GENERIC, 0x38C2C, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x54E30, _MOVZW(8, 0x1E00, LSL16), NULL }, // System memory pool increase.
{ 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 + 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 + sizeof(u32) * 2), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_6_patchset,
{ SVC_GENERIC, 0x3A8CC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x57330, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ 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 + 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 + 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_SYSM_INCR, 0x57F98, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ 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}
);
KERNEL_PATCHSET_DEF(_kernel_8_patchset,
{ SVC_GENERIC, 0x3FAD0, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x4D15C, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x5BFAC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x5F9A4, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_800, _B(ID_SND_OFF_800, FREE_CODE_OFF_1ST_800), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_800, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700}, // Send process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), ID_SND_OFF_800 + sizeof(u32) * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_800, _B(ID_RCV_OFF_800, FREE_CODE_OFF_2ND_800), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_800, sizeof(PRC_ID_RCV_700) >> 2, PRC_ID_RCV_700}, // Receive process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_800 + sizeof(PRC_ID_RCV_700), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_2ND_800 + sizeof(PRC_ID_RCV_700), ID_RCV_OFF_800 + sizeof(u32) * 4), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_9_patchset,
{ SVC_GENERIC, 0x43DFC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x50628, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x609E8, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x6493C, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_900, _B(ID_SND_OFF_900, FREE_CODE_OFF_1ST_900), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_900, sizeof(PRC_ID_SND_900) >> 2, PRC_ID_SND_900}, // Send process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), ID_SND_OFF_900 + sizeof(u32) * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_900, _B(ID_RCV_OFF_900, FREE_CODE_OFF_2ND_900), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_900, sizeof(PRC_ID_RCV_900) >> 2, PRC_ID_RCV_900}, // Receive process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_900 + sizeof(PRC_ID_RCV_900), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_2ND_900 + sizeof(PRC_ID_RCV_900), ID_RCV_OFF_900 + sizeof(u32) * 4), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_10_patchset,
{ SVC_GENERIC, 0x45DAC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x523E4, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x62B14, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x66950, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1000, _B(ID_SND_OFF_1000, FREE_CODE_OFF_1ST_1000), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_1000, sizeof(PRC_ID_SND_1000) >> 2, PRC_ID_SND_1000}, // Send process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), ID_SND_OFF_1000 + sizeof(u32) * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_1000, _B(ID_RCV_OFF_1000, FREE_CODE_OFF_2ND_1000), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_1000, sizeof(PRC_ID_RCV_1000) >> 2, PRC_ID_RCV_1000}, // Receive process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), ID_RCV_OFF_1000 + sizeof(u32) * 4), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_11_patchset,
{ SVC_GENERIC, 0x2FCE0, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x39194, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x460C0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x490C4, _MOVZW(21, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1100, _B(ID_SND_OFF_1100, FREE_CODE_OFF_1ST_1100), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_1100, sizeof(PRC_ID_SND_1100) >> 2, PRC_ID_SND_1100}, // Send process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), ID_SND_OFF_1100 + sizeof(u32) * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_1100, _B(ID_RCV_OFF_1100, FREE_CODE_OFF_2ND_1100), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_1100, sizeof(PRC_ID_RCV_1100) >> 2, PRC_ID_RCV_1100}, // Receive process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), ID_RCV_OFF_1100 + sizeof(u32) * 4), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_1101_patchset,
{ SVC_GENERIC, 0x2FD04, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x39194, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x460C0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x490C4, _MOVZW(21, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1101, _B(ID_SND_OFF_1101, FREE_CODE_OFF_1ST_1100), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_1100, sizeof(PRC_ID_SND_1100) >> 2, PRC_ID_SND_1100}, // Send process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), ID_SND_OFF_1101 + sizeof(u32) * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_1101, _B(ID_RCV_OFF_1101, FREE_CODE_OFF_2ND_1100), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_1100, sizeof(PRC_ID_RCV_1100) >> 2, PRC_ID_RCV_1100}, // Receive process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), ID_RCV_OFF_1101 + sizeof(u32) * 4), NULL}
);
// Kernel sha256 hashes.
static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
{
{ "\xb8\xc5\x0c\x68\x25\xa9\xb9\x5b", _kernel_1_patchset }, // 1.0.0
{ "\x64\x0b\x51\xff\x28\x01\xb8\x30", _kernel_2_patchset }, // 2.0.0 - 2.3.0
{ "\x50\x84\x23\xac\x6f\xa1\x5d\x3b", _kernel_3_patchset }, // 3.0.0 - 3.0.1
{ "\x81\x9d\x08\xbe\xe4\x5e\x1f\xbb", _kernel_302_patchset }, // 3.0.2
{ "\xe6\xc0\xb7\xe3\x2f\xf9\x44\x51", _kernel_4_patchset }, // 4.0.0 - 4.1.0
{ "\xb2\x38\x61\xa8\xe1\xe2\xe4\xe4", _kernel_5_patchset }, // 5.0.0 - 5.1.0
{ "\x85\x97\x40\xf6\xc0\x3e\x3d\x44", _kernel_6_patchset }, // 6.0.0 - 6.2.0
{ "\xa2\x5e\x47\x0c\x8e\x6d\x2f\xd7", _kernel_7_patchset }, // 7.0.0 - 7.0.1
{ "\xf1\x5e\xc8\x34\xfd\x68\xf0\xf0", _kernel_8_patchset }, // 8.0.0 - 8.1.0. Kernel only.
{ "\x69\x00\x39\xdf\x21\x56\x70\x6b", _kernel_9_patchset }, // 9.0.0 - 9.1.0. Kernel only.
{ "\xa2\xe3\xad\x1c\x98\xd8\x7a\x62", _kernel_9_patchset }, // 9.2.0. Kernel only.
{ "\x21\xc1\xd7\x24\x8e\xcd\xbd\xa8", _kernel_10_patchset }, // 10.0.0. Kernel only.
{ "\xD5\xD0\xBA\x5D\x52\xB9\x77\x85", _kernel_11_patchset }, // 11.0.0. Kernel only.
{ "\xF8\x1E\xE0\x30\x3C\x7A\x08\x04", _kernel_1101_patchset },// 11.0.1. Kernel only.
};
enum kip_offset_section
{
KIP_TEXT = 0,
@@ -463,272 +65,7 @@ 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_emummc[] =
{
{ KPS(KIP_TEXT) | 1, 0, "", "" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_100[] =
{
{ "nogc", NULL },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_40x },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_410 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_50x },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_510 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ 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[] =
{
{ "nogc", _fs_nogc_600 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_600_exfat[] =
{
{ "nogc", _fs_nogc_600_exfat },
{ "emummc", _fs_emummc },
{ 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[] =
{
{ "nogc", _fs_nogc_700 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_700_exfat[] =
{
{ "nogc", _fs_nogc_700_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_800[] =
{
{ KPS(KIP_TEXT) | 0x136800, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15EB94, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patch_t _fs_nogc_800_exfat[] =
{
{ KPS(KIP_TEXT) | 0x141DB0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x16A144, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_800[] =
{
{ "nogc", _fs_nogc_800 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_800_exfat[] =
{
{ "nogc", _fs_nogc_800_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_900[] =
{
{ KPS(KIP_TEXT) | 0x129420, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_900[] =
{
{ "nogc", _fs_nogc_900 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_910[] =
{
{ KPS(KIP_TEXT) | 0x129430, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143278, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_910[] =
{
{ "nogc", _fs_nogc_910 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1000[] =
{
{ KPS(KIP_TEXT) | 0x13BE90, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14DE08, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1000[] =
{
{ "nogc", _fs_nogc_1000 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1020[] =
{
{ KPS(KIP_TEXT) | 0x13C2F0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14E268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1020[] =
{
{ "nogc", _fs_nogc_1020 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1100[] =
{
{ KPS(KIP_TEXT) | 0x1398B4, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x156EB8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1100[] =
{
{ "nogc", _fs_nogc_1100 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
// SHA256 hashes.
static kip1_id_t _kip_ids[] =
{
{ "FS", "\xde\x9f\xdd\xa4\x08\x5d\xd5\xfe", _fs_patches_100 }, // FS 1.0.0
{ "FS", "\xfc\x3e\x80\x99\x1d\xca\x17\x96", _fs_patches_100 }, // FS 1.0.0 exfat
{ "FS", "\xcd\x7b\xbe\x18\xd6\x13\x0b\x28", _fs_patches_100 }, // FS 2.0.0
{ "FS", "\xe7\x66\x92\xdf\xaa\x04\x20\xe9", _fs_patches_100 }, // FS 2.0.0 exfat
{ "FS", "\x0d\x70\x05\x62\x7b\x07\x76\x7c", _fs_patches_100 }, // FS 2.1.0
{ "FS", "\xdb\xd8\x5f\xca\xcc\x19\x3d\xa8", _fs_patches_100 }, // FS 2.1.0 exfat
{ "FS", "\xa8\x6d\xa5\xe8\x7e\xf1\x09\x7b", _fs_patches_100 }, // FS 3.0.0
{ "FS", "\x98\x1c\x57\xe7\xf0\x2f\x70\xf7", _fs_patches_100 }, // FS 3.0.0 exfat
{ "FS", "\x57\x39\x7c\x06\x3f\x10\xb6\x31", _fs_patches_100 }, // FS 3.0.1
{ "FS", "\x07\x30\x99\xd7\xc6\xad\x7d\x89", _fs_patches_100 }, // FS 3.0.1 exfat
{ "FS", "\x06\xe9\x07\x19\x59\x5a\x01\x0c", _fs_patches_40x }, // FS 4.0.1
{ "FS", "\x54\x9b\x0f\x8d\x6f\x72\xc4\xe9", _fs_patches_40x }, // FS 4.0.1 exfat
{ "FS", "\x80\x96\xaf\x7c\x6a\x35\xaa\x82", _fs_patches_410 }, // FS 4.1.0
{ "FS", "\x02\xd5\xab\xaa\xfd\x20\xc8\xb0", _fs_patches_410 }, // FS 4.1.0 exfat
{ "FS", "\xa6\xf2\x7a\xd9\xac\x7c\x73\xad", _fs_patches_50x }, // FS 5.0.0
{ "FS", "\xce\x3e\xcb\xa2\xf2\xf0\x62\xf5", _fs_patches_50x }, // FS 5.0.0 exfat
{ "FS", "\x76\xf8\x74\x02\xc9\x38\x7c\x0f", _fs_patches_510 }, // FS 5.1.0
{ "FS", "\x10\xb2\xd8\x16\x05\x48\x85\x99", _fs_patches_510 }, // FS 5.1.0 exfat
{ "FS", "\x1b\x82\xcb\x22\x18\x67\xcb\x52", _fs_patches_600 }, // FS 6.0.0-4.0
{ "FS", "\x96\x6a\xdd\x3d\x20\xb6\x27\x13", _fs_patches_600_exfat }, // FS 6.0.0-4.0 exfat
{ "FS", "\x3a\x57\x4d\x43\x61\x86\x19\x1d", _fs_patches_600 }, // FS 6.0.0-5.0
{ "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4", _fs_patches_600_exfat }, // FS 6.0.0-5.0 exfat
{ "FS", "\x2A\xDB\xE9\x7E\x9B\x5F\x41\x77", _fs_patches_700 }, // FS 7.0.0
{ "FS", "\x2C\xCE\x65\x9C\xEC\x53\x6A\x8E", _fs_patches_700_exfat }, // FS 7.0.0 exfat
{ "FS", "\xB2\xF5\x17\x6B\x35\x48\x36\x4D", _fs_patches_800 }, // FS 8.0.0
{ "FS", "\xDB\xD9\x41\xC0\xC5\x3C\x52\xCC", _fs_patches_800_exfat }, // FS 8.0.0 exfat
{ "FS", "\x6B\x09\xB6\x7B\x29\xC0\x20\x24", _fs_patches_800 }, // FS 8.1.0
{ "FS", "\xB4\xCA\xE1\xF2\x49\x65\xD9\x2E", _fs_patches_800_exfat }, // FS 8.1.0 exfat
{ "FS", "\x46\x87\x40\x76\x1E\x19\x3E\xB7", _fs_patches_900 }, // FS 9.0.0
{ "FS", "\x7C\x95\x13\x76\xE5\xC1\x2D\xF8", _fs_patches_900 }, // FS 9.0.0 exfat
{ "FS", "\xB5\xE7\xA6\x4C\x6F\x5C\x4F\xE3", _fs_patches_910 }, // FS 9.1.0
{ "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exfat
{ "FS", "\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", _fs_patches_1000 }, // FS 10.0.0
{ "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exfat
{ "FS", "\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", _fs_patches_1020 }, // FS 10.2.0
{ "FS", "\x16\x0D\x3E\x10\x4E\xAD\x61\x76", _fs_patches_1020 }, // FS 10.2.0 exfat
{ "FS", "\xE3\x99\x15\x6E\x84\x4E\xB0\xAA", _fs_patches_1100 }, // FS 11.0.0
{ "FS", "\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", _fs_patches_1100 }, // FS 11.0.0 exfat
};
#include "pkg2_patches.inl"
static kip1_id_t *_kip_id_sets = _kip_ids;
static u32 _kip_id_sets_cnt = ARRAY_SIZE(_kip_ids);
@@ -1133,7 +470,7 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
if (numPatches >= MAX_NUM_PATCHES_REQUESTED)
return "too_many_patches";
}
else if (*p >= 'A' && *p <= 'Z')
else if (*p >= 'A' && *p <= 'Z') // Convert to lowercase.
*p += 0x20;
}
}
@@ -1258,15 +595,15 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
emummc_patch_selected = true;
patchesApplied |= appliedMask;
break;
continue; // Continue in case it's double defined.
}
if (currPatchset->patches == NULL)
{
gfx_printf("Patch '%s' not necessary for %s KIP1\n", currPatchset->name, (const char*)ki->kip1->name);
DPRINTF("Patch '%s' not necessary for %s KIP1\n", currPatchset->name, (const char*)ki->kip1->name);
patchesApplied |= appliedMask;
break;
continue; // Continue in case it's double defined.
}
unsigned char* kipSectData = ki->kip1->data;
@@ -1288,7 +625,7 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
}
u32 currOffset = GET_KIP_PATCH_OFFSET(currPatch->offset);
// If source is does not match and is not already patched, throw an error.
// If source does not match and is not already patched, throw an error.
if ((memcmp(&kipSectData[currOffset], currPatch->srcData, currPatch->length) != 0) &&
(memcmp(&kipSectData[currOffset], currPatch->dstData, currPatch->length) != 0))
{
@@ -1307,11 +644,11 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
}
patchesApplied |= appliedMask;
break;
continue; // Continue in case it's double defined.
}
currPatchset++;
}
if (emummc_patch_selected && !strncmp(_kip_id_sets[currKipIdx].name, "FS", 2))
if (emummc_patch_selected && !strncmp(_kip_id_sets[currKipIdx].name, "FS", sizeof(ki->kip1->name)))
{
emummc_patch_selected = false;
emu_cfg.fs_ver = currKipIdx;

View File

@@ -86,9 +86,9 @@ static ini_kip_sec_t *_ini_create_kip_section(link_t *dst, ini_kip_sec_t *ksec,
int ini_patch_parse(link_t *dst, char *ini_path)
{
FIL fp;
u32 lblen;
char lbuf[512];
FIL fp;
ini_kip_sec_t *ksec = NULL;
// Open ini.

View File

@@ -0,0 +1,730 @@
/*
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//TODO: Replace hardcoded AArch64 instructions with instruction macros.
//TODO: Reduce hardcoded values without searching kernel for patterns?
// The process ID send/receive kernel patches were taken from Atmosphère's kernel patches.
// They should only be used when running Atmosphère.
#define CODE_OFF_1ST_100 0x4797C
#define CODE_OFF_1ST_200 0x6486C
#define CODE_OFF_1ST_300 0x494A4
#define CODE_OFF_1ST_302 0x494BC
#define CODE_OFF_1ST_400 0x52890
#define CODE_OFF_1ST_500 0x5C020
#define CODE_OFF_1ST_600 0x5EE00
#define CODE_OFF_1ST_700 0x5FEC0
#define CODE_OFF_1ST_800 0x607F0
#define CODE_OFF_1ST_900 0x65780
#define CODE_OFF_1ST_1000 0x67790
#define CODE_OFF_1ST_1100 0x49EE8
#define CODE_OFF_1ST_1200 0x48810
#define ID_SND_OFF_100 0x23CC0
#define ID_SND_OFF_200 0x3F134
#define ID_SND_OFF_300 0x26080
#define ID_SND_OFF_302 0x26080
#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_SND_OFF_800 0x2F1FC
#define ID_SND_OFF_900 0x329A0
#define ID_SND_OFF_1000 0x34404
#define ID_SND_OFF_1100 0x245B4
#define ID_SND_OFF_1101 0x245B8
#define ID_SND_OFF_1200 0x24CF4
#define ID_RCV_OFF_100 0x219F0
#define ID_RCV_OFF_200 0x3D1A8
#define ID_RCV_OFF_300 0x240F0
#define ID_RCV_OFF_302 0x240F0
#define ID_RCV_OFF_400 0x28F6C
#define ID_RCV_OFF_500 0x28DAC
#define ID_RCV_OFF_600 0x29B6C
#define ID_RCV_OFF_700 0x2B23C
#define ID_RCV_OFF_800 0x2D424
#define ID_RCV_OFF_900 0x309B4
#define ID_RCV_OFF_1000 0x322F8
#define ID_RCV_OFF_1100 0x22B24
#define ID_RCV_OFF_1101 0x22B28
#define ID_RCV_OFF_1200 0x23424
static u32 PRC_ID_SND_100[] =
{
0xA9BF2FEA, 0x2A0E03EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9412948, 0xA8C12FEA
};
#define CODE_OFF_2ND_100 (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,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9412968, 0xA8C12FEA
};
static u32 PRC_ID_SND_200[] =
{
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9413148, 0xA8C12FEA
};
#define CODE_OFF_2ND_200 (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,
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9413168, 0xA8C12FEA
};
static u32 PRC_ID_SND_300[] =
{
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA
};
#define CODE_OFF_2ND_300 (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,
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA
};
#define CODE_OFF_2ND_302 (CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300) + sizeof(u32))
static u32 PRC_ID_SND_400[] =
{
0x2A1703EA, 0xD37EF54A, 0xF86A6B8A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
0xEB09015F, 0x54000060, 0xF94053EA, 0xF9415948, 0xF94053EA
};
#define CODE_OFF_2ND_400 (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,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B28, 0xD503201F
};
static u32 PRC_ID_SND_500[] =
{
0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA
};
#define CODE_OFF_2ND_500 (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,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA
};
static u32 PRC_ID_SND_600[] =
{
0xA9BF2FEA, 0xF94037EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_600 (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,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
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 CODE_OFF_2ND_700 (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
};
#define CODE_OFF_2ND_800 (CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700) + sizeof(u32))
static u32 PRC_ID_SND_900[] =
{
0xA9BF2FEA, 0xF94037EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_900 (CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900) + sizeof(u32))
static u32 PRC_ID_RCV_900[] =
{
0xA9BF2FEA, 0xF9404BEB, 0x2A1703EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1000[] =
{
0xA9BF2FEA, 0xF94063EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_1000 (CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000) + sizeof(u32))
static u32 PRC_ID_RCV_1000[] =
{
0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1100[] =
{
0xA9BF2FEA, 0xF94043EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_1100 (CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100) + sizeof(u32))
static u32 PRC_ID_RCV_1100[] =
{
0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1200[] =
{
0xA9BF2FEA, 0xF9404FEB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002C8, 0xF9401D08, 0xAA1603E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_1200 (CODE_OFF_1ST_1200 + sizeof(PRC_ID_SND_1200) + sizeof(u32))
static u32 PRC_ID_RCV_1200[] =
{
0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0,
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
{ DEBUG_MODE_EN, 0x44074, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_GEN_PATCH, ID_SND_OFF_100, _B(ID_SND_OFF_100, CODE_OFF_1ST_100), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_100, sizeof(PRC_ID_SND_100) >> 2, PRC_ID_SND_100 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), // Branch back and skip 1 instruction.
_B(CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), ID_SND_OFF_100 + 0x4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_100, _B(ID_RCV_OFF_100, CODE_OFF_2ND_100), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_100, sizeof(PRC_ID_RCV_100) >> 2, PRC_ID_RCV_100 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), // Branch back and skip 1 instruction.
_B(CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), ID_RCV_OFF_100 + 0x4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_2_patchset,
{ SVC_VERIFY_DS, 0x54834, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x6086C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_GEN_PATCH, ID_SND_OFF_200, _B(ID_SND_OFF_200, CODE_OFF_1ST_200), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_200, sizeof(PRC_ID_SND_200) >> 2, PRC_ID_SND_200 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), // Branch back and skip 1 instruction.
_B(CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), ID_SND_OFF_200 + 0x4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_200, _B(ID_RCV_OFF_200, CODE_OFF_2ND_200), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_200, sizeof(PRC_ID_RCV_200) >> 2, PRC_ID_RCV_200 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), // Branch back and skip 1 instruction.
_B(CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), ID_RCV_OFF_200 + 0x4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_3_patchset,
{ SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x483FC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_GEN_PATCH, ID_SND_OFF_300, _B(ID_SND_OFF_300, CODE_OFF_1ST_300), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_300, sizeof(PRC_ID_SND_300) >> 2, PRC_ID_SND_300 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction.
_B(CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), ID_SND_OFF_300 + 0x4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_300, _B(ID_RCV_OFF_300, CODE_OFF_2ND_300), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_300, sizeof(PRC_ID_RCV_300) >> 2, PRC_ID_RCV_300 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction.
_B(CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_300 + 0x4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_302_patchset,
{ SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x48414, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_GEN_PATCH, ID_SND_OFF_302, _B(ID_SND_OFF_302, CODE_OFF_1ST_302), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_302, sizeof(PRC_ID_SND_300) >> 2, PRC_ID_SND_300 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction.
_B(CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300), ID_SND_OFF_302 + 0x4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_302, _B(ID_RCV_OFF_302, CODE_OFF_2ND_302), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_302, sizeof(PRC_ID_RCV_300) >> 2, PRC_ID_RCV_300 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction.
_B(CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_302 + 0x4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_4_patchset,
{ SVC_VERIFY_DS, 0x41EB4, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x4EBFC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_GEN_PATCH, ID_SND_OFF_400, _B(ID_SND_OFF_400, CODE_OFF_1ST_400), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_400, sizeof(PRC_ID_SND_400) >> 2, PRC_ID_SND_400 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), // Branch back and skip 2 instructions.
_B(CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), ID_SND_OFF_400 + 0x4 * 2), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_400, _B(ID_RCV_OFF_400, CODE_OFF_2ND_400), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_400, sizeof(PRC_ID_RCV_400) >> 2, PRC_ID_RCV_400 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), // Branch back and skip 1 instruction.
_B(CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), ID_RCV_OFF_400 + 0x4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_5_patchset,
{ SVC_GENERIC, 0x38C2C, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x54E30, _MOVZW(8, 0x1E00, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_500, _B(ID_SND_OFF_500, CODE_OFF_1ST_500), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_500, sizeof(PRC_ID_SND_500) >> 2, PRC_ID_SND_500 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), // Branch back and skip 2 instructions.
_B(CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), ID_SND_OFF_500 + 0x4 * 2), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_500, _B(ID_RCV_OFF_500, CODE_OFF_2ND_500), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_500, sizeof(PRC_ID_RCV_500) >> 2, PRC_ID_RCV_500 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), // Branch back and skip 2 instructions.
_B(CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), ID_RCV_OFF_500 + 0x4 * 2), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_6_patchset,
{ SVC_GENERIC, 0x3A8CC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x57330, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_600, _B(ID_SND_OFF_600, CODE_OFF_1ST_600), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_600, sizeof(PRC_ID_SND_600) >> 2, PRC_ID_SND_600 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), ID_SND_OFF_600 + 0x4 * 4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_600, _B(ID_RCV_OFF_600, CODE_OFF_2ND_600), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_600, sizeof(PRC_ID_RCV_600) >> 2, PRC_ID_RCV_600 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), ID_RCV_OFF_600 + 0x4 * 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_SYSM_INCR, 0x57F98, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_700, _B(ID_SND_OFF_700, CODE_OFF_1ST_700), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_700, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), ID_SND_OFF_700 + 0x4 * 4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_700, _B(ID_RCV_OFF_700, CODE_OFF_2ND_700), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_700, sizeof(PRC_ID_RCV_700) >> 2, PRC_ID_RCV_700 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_700 + sizeof(PRC_ID_RCV_700), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_700 + sizeof(PRC_ID_RCV_700), ID_RCV_OFF_700 + 0x4 * 4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_8_patchset,
{ SVC_GENERIC, 0x3FAD0, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x4D15C, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x5BFAC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x5F9A4, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_800, _B(ID_SND_OFF_800, CODE_OFF_1ST_800), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_800, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), ID_SND_OFF_800 + 0x4 * 4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_800, _B(ID_RCV_OFF_800, CODE_OFF_2ND_800), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_800, sizeof(PRC_ID_RCV_700) >> 2, PRC_ID_RCV_700 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_800 + sizeof(PRC_ID_RCV_700), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_800 + sizeof(PRC_ID_RCV_700), ID_RCV_OFF_800 + 0x4 * 4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_9_patchset,
{ SVC_GENERIC, 0x43DFC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x50628, _NOP(), NULL }, // Disable SVC verifications
{ DEBUG_MODE_EN, 0x609E8, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x6493C, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_900, _B(ID_SND_OFF_900, CODE_OFF_1ST_900), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_900, sizeof(PRC_ID_SND_900) >> 2, PRC_ID_SND_900 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), ID_SND_OFF_900 + 0x4 * 4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_900, _B(ID_RCV_OFF_900, CODE_OFF_2ND_900), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_900, sizeof(PRC_ID_RCV_900) >> 2, PRC_ID_RCV_900 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_900 + sizeof(PRC_ID_RCV_900), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_900 + sizeof(PRC_ID_RCV_900), ID_RCV_OFF_900 + 0x4 * 4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_10_patchset,
{ SVC_GENERIC, 0x45DAC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x523E4, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x62B14, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x66950, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1000, _B(ID_SND_OFF_1000, CODE_OFF_1ST_1000), NULL }, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_1000, sizeof(PRC_ID_SND_1000) >> 2, PRC_ID_SND_1000 }, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), ID_SND_OFF_1000 + 0x4 * 4), NULL },
{ ATM_GEN_PATCH, ID_RCV_OFF_1000, _B(ID_RCV_OFF_1000, CODE_OFF_2ND_1000), NULL }, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_1000, sizeof(PRC_ID_RCV_1000) >> 2, PRC_ID_RCV_1000 }, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), ID_RCV_OFF_1000 + 0x4 * 4), NULL }
);
KERNEL_PATCHSET_DEF(_kernel_11_patchset,
{ SVC_GENERIC, 0x2FCE0, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x39194, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x460C0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x490C4, _MOVZW(21, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1100, _B(ID_SND_OFF_1100, CODE_OFF_1ST_1100), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_1100, sizeof(PRC_ID_SND_1100) >> 2, PRC_ID_SND_1100}, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), ID_SND_OFF_1100 + 0x4 * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_1100, _B(ID_RCV_OFF_1100, CODE_OFF_2ND_1100), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_1100, sizeof(PRC_ID_RCV_1100) >> 2, PRC_ID_RCV_1100}, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), ID_RCV_OFF_1100 + 0x4 * 4), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_1101_patchset,
{ SVC_GENERIC, 0x2FD04, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x39194, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x460C0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x490C4, _MOVZW(21, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1101, _B(ID_SND_OFF_1101, CODE_OFF_1ST_1100), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_1100, sizeof(PRC_ID_SND_1100) >> 2, PRC_ID_SND_1100}, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100), ID_SND_OFF_1101 + 0x4 * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_1101, _B(ID_RCV_OFF_1101, CODE_OFF_2ND_1100), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_1100, sizeof(PRC_ID_RCV_1100) >> 2, PRC_ID_RCV_1100}, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_1100 + sizeof(PRC_ID_RCV_1100), ID_RCV_OFF_1101 + 0x4 * 4), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_12_patchset,
{ SVC_GENERIC, 0x2FCB4, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x38440, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x45118, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x4809C, _MOVZW(21, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1200, _B(ID_SND_OFF_1200, CODE_OFF_1ST_1200), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, CODE_OFF_1ST_1200, sizeof(PRC_ID_SND_1200) >> 2, PRC_ID_SND_1200}, // Send process id code.
{ ATM_GEN_PATCH, CODE_OFF_1ST_1200 + sizeof(PRC_ID_SND_1200), // Branch back and skip 4 instructions.
_B(CODE_OFF_1ST_1200 + sizeof(PRC_ID_SND_1200), ID_SND_OFF_1200 + 0x4 * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_1200, _B(ID_RCV_OFF_1200, CODE_OFF_2ND_1200), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, CODE_OFF_2ND_1200, sizeof(PRC_ID_RCV_1200) >> 2, PRC_ID_RCV_1200}, // Receive process id code.
{ ATM_GEN_PATCH, CODE_OFF_2ND_1200 + sizeof(PRC_ID_RCV_1200), // Branch back and skip 4 instructions.
_B(CODE_OFF_2ND_1200 + sizeof(PRC_ID_RCV_1200), ID_RCV_OFF_1200 + 0x4 * 4), NULL}
);
// Kernel sha256 hashes. Offset 0x800 up to INI1 start.
static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
{
{ "\xb8\xc5\x0c\x68\x25\xa9\xb9\x5b", _kernel_1_patchset }, // 1.0.0
{ "\x64\x0b\x51\xff\x28\x01\xb8\x30", _kernel_2_patchset }, // 2.0.0 - 2.3.0
{ "\x50\x84\x23\xac\x6f\xa1\x5d\x3b", _kernel_3_patchset }, // 3.0.0 - 3.0.1
{ "\x81\x9d\x08\xbe\xe4\x5e\x1f\xbb", _kernel_302_patchset }, // 3.0.2
{ "\xe6\xc0\xb7\xe3\x2f\xf9\x44\x51", _kernel_4_patchset }, // 4.0.0 - 4.1.0
{ "\xb2\x38\x61\xa8\xe1\xe2\xe4\xe4", _kernel_5_patchset }, // 5.0.0 - 5.1.0
{ "\x85\x97\x40\xf6\xc0\x3e\x3d\x44", _kernel_6_patchset }, // 6.0.0 - 6.2.0
{ "\xa2\x5e\x47\x0c\x8e\x6d\x2f\xd7", _kernel_7_patchset }, // 7.0.0 - 7.0.1
{ "\xf1\x5e\xc8\x34\xfd\x68\xf0\xf0", _kernel_8_patchset }, // 8.0.0 - 8.1.0. Kernel only.
{ "\x69\x00\x39\xdf\x21\x56\x70\x6b", _kernel_9_patchset }, // 9.0.0 - 9.1.0. Kernel only.
{ "\xa2\xe3\xad\x1c\x98\xd8\x7a\x62", _kernel_9_patchset }, // 9.2.0. Kernel only.
{ "\x21\xc1\xd7\x24\x8e\xcd\xbd\xa8", _kernel_10_patchset }, // 10.0.0. Kernel only.
{ "\xD5\xD0\xBA\x5D\x52\xB9\x77\x85", _kernel_11_patchset }, // 11.0.0. Kernel only.
{ "\xF8\x1E\xE0\x30\x3C\x7A\x08\x04", _kernel_1101_patchset },// 11.0.1. Kernel only.
{ "\xA6\xD8\xFF\xF3\x67\x4A\x33\xFC", _kernel_12_patchset }, // 12.0.0. Kernel only.
};
// All kip patch offsets are without the 0x100-sized header.
static kip1_patch_t _fs_emummc[] =
{
{ KPS(KIP_TEXT) | 1, 0, "", "" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_100[] =
{
{ "nogc", NULL },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_40x },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_410 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_50x },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ "nogc", _fs_nogc_510 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
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[] =
{
{ 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[] =
{
{ "nogc", _fs_nogc_600 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_600_exfat[] =
{
{ "nogc", _fs_nogc_600_exfat },
{ "emummc", _fs_emummc },
{ 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[] =
{
{ "nogc", _fs_nogc_700 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_700_exfat[] =
{
{ "nogc", _fs_nogc_700_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_800[] =
{
{ KPS(KIP_TEXT) | 0x136800, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15EB94, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patch_t _fs_nogc_800_exfat[] =
{
{ KPS(KIP_TEXT) | 0x141DB0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x16A144, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_800[] =
{
{ "nogc", _fs_nogc_800 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_800_exfat[] =
{
{ "nogc", _fs_nogc_800_exfat },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_900[] =
{
{ KPS(KIP_TEXT) | 0x129420, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_900[] =
{
{ "nogc", _fs_nogc_900 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_910[] =
{
{ KPS(KIP_TEXT) | 0x129430, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143278, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_910[] =
{
{ "nogc", _fs_nogc_910 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1000[] =
{
{ KPS(KIP_TEXT) | 0x13BE90, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14DE08, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1000[] =
{
{ "nogc", _fs_nogc_1000 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1020[] =
{
{ KPS(KIP_TEXT) | 0x13C2F0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14E268, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1020[] =
{
{ "nogc", _fs_nogc_1020 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1100[] =
{
{ KPS(KIP_TEXT) | 0x1398B4, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x156EB8, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1100[] =
{
{ "nogc", _fs_nogc_1100 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1200[] =
{
{ KPS(KIP_TEXT) | 0x13EA24, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x155368, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1200[] =
{
{ "nogc", _fs_nogc_1200 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
// SHA256 hashes.
static kip1_id_t _kip_ids[] =
{
{ "FS", "\xde\x9f\xdd\xa4\x08\x5d\xd5\xfe", _fs_patches_100 }, // FS 1.0.0
{ "FS", "\xfc\x3e\x80\x99\x1d\xca\x17\x96", _fs_patches_100 }, // FS 1.0.0 exfat
{ "FS", "\xcd\x7b\xbe\x18\xd6\x13\x0b\x28", _fs_patches_100 }, // FS 2.0.0
{ "FS", "\xe7\x66\x92\xdf\xaa\x04\x20\xe9", _fs_patches_100 }, // FS 2.0.0 exfat
{ "FS", "\x0d\x70\x05\x62\x7b\x07\x76\x7c", _fs_patches_100 }, // FS 2.1.0
{ "FS", "\xdb\xd8\x5f\xca\xcc\x19\x3d\xa8", _fs_patches_100 }, // FS 2.1.0 exfat
{ "FS", "\xa8\x6d\xa5\xe8\x7e\xf1\x09\x7b", _fs_patches_100 }, // FS 3.0.0
{ "FS", "\x98\x1c\x57\xe7\xf0\x2f\x70\xf7", _fs_patches_100 }, // FS 3.0.0 exfat
{ "FS", "\x57\x39\x7c\x06\x3f\x10\xb6\x31", _fs_patches_100 }, // FS 3.0.1
{ "FS", "\x07\x30\x99\xd7\xc6\xad\x7d\x89", _fs_patches_100 }, // FS 3.0.1 exfat
{ "FS", "\x06\xe9\x07\x19\x59\x5a\x01\x0c", _fs_patches_40x }, // FS 4.0.1
{ "FS", "\x54\x9b\x0f\x8d\x6f\x72\xc4\xe9", _fs_patches_40x }, // FS 4.0.1 exfat
{ "FS", "\x80\x96\xaf\x7c\x6a\x35\xaa\x82", _fs_patches_410 }, // FS 4.1.0
{ "FS", "\x02\xd5\xab\xaa\xfd\x20\xc8\xb0", _fs_patches_410 }, // FS 4.1.0 exfat
{ "FS", "\xa6\xf2\x7a\xd9\xac\x7c\x73\xad", _fs_patches_50x }, // FS 5.0.0
{ "FS", "\xce\x3e\xcb\xa2\xf2\xf0\x62\xf5", _fs_patches_50x }, // FS 5.0.0 exfat
{ "FS", "\x76\xf8\x74\x02\xc9\x38\x7c\x0f", _fs_patches_510 }, // FS 5.1.0
{ "FS", "\x10\xb2\xd8\x16\x05\x48\x85\x99", _fs_patches_510 }, // FS 5.1.0 exfat
{ "FS", "\x1b\x82\xcb\x22\x18\x67\xcb\x52", _fs_patches_600 }, // FS 6.0.0-4.0
{ "FS", "\x96\x6a\xdd\x3d\x20\xb6\x27\x13", _fs_patches_600_exfat }, // FS 6.0.0-4.0 exfat
{ "FS", "\x3a\x57\x4d\x43\x61\x86\x19\x1d", _fs_patches_600 }, // FS 6.0.0-5.0
{ "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4", _fs_patches_600_exfat }, // FS 6.0.0-5.0 exfat
{ "FS", "\x2A\xDB\xE9\x7E\x9B\x5F\x41\x77", _fs_patches_700 }, // FS 7.0.0
{ "FS", "\x2C\xCE\x65\x9C\xEC\x53\x6A\x8E", _fs_patches_700_exfat }, // FS 7.0.0 exfat
{ "FS", "\xB2\xF5\x17\x6B\x35\x48\x36\x4D", _fs_patches_800 }, // FS 8.0.0
{ "FS", "\xDB\xD9\x41\xC0\xC5\x3C\x52\xCC", _fs_patches_800_exfat }, // FS 8.0.0 exfat
{ "FS", "\x6B\x09\xB6\x7B\x29\xC0\x20\x24", _fs_patches_800 }, // FS 8.1.0
{ "FS", "\xB4\xCA\xE1\xF2\x49\x65\xD9\x2E", _fs_patches_800_exfat }, // FS 8.1.0 exfat
{ "FS", "\x46\x87\x40\x76\x1E\x19\x3E\xB7", _fs_patches_900 }, // FS 9.0.0
{ "FS", "\x7C\x95\x13\x76\xE5\xC1\x2D\xF8", _fs_patches_900 }, // FS 9.0.0 exfat
{ "FS", "\xB5\xE7\xA6\x4C\x6F\x5C\x4F\xE3", _fs_patches_910 }, // FS 9.1.0
{ "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exfat
{ "FS", "\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", _fs_patches_1000 }, // FS 10.0.0
{ "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exfat
{ "FS", "\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", _fs_patches_1020 }, // FS 10.2.0
{ "FS", "\x16\x0D\x3E\x10\x4E\xAD\x61\x76", _fs_patches_1020 }, // FS 10.2.0 exfat
{ "FS", "\xE3\x99\x15\x6E\x84\x4E\xB0\xAA", _fs_patches_1100 }, // FS 11.0.0
{ "FS", "\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", _fs_patches_1100 }, // FS 11.0.0 exfat
{ "FS", "\xDC\x2A\x08\x49\x96\xBB\x3C\x01", _fs_patches_1200 }, // FS 12.0.0
{ "FS", "\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", _fs_patches_1200 }, // FS 12.0.0 exfat
};

View File

@@ -145,6 +145,7 @@ typedef struct _atm_fatal_error_ctx
#define EXO_FLAG_USER_PMU BIT(4)
#define EXO_FLAG_CAL0_BLANKING BIT(5)
#define EXO_FLAG_CAL0_WRITES_SYS BIT(6)
#define EXO_FLAG_ENABLE_USB3 BIT(7)
#define EXO_FW_VER(mj, mn, rv) (((mj) << 24) | ((mn) << 16) | ((rv) << 8))
@@ -152,6 +153,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base, bool exo_new)
{
u32 exo_fw_no = 0;
u32 exo_flags = 0;
bool usb3_force = false;
bool user_debug = false;
bool cal0_blanking = false;
bool cal0_allow_writes_sys = false;
@@ -167,17 +169,17 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base, bool exo_new)
exo_fw_no = ctxt->pkg1_id->fuses - 1; // 3.0.1 - 7.0.1, 8.0.0 - 8.0.1.
if (!memcmp(ctxt->pkg1_id->id, "20190314172056", 8)) // 8.0.0 - 8.0.1.
exo_fw_no++;
exo_fw_no++;
if (!memcmp(ctxt->pkg1_id->id, "20210129111626", 8)) // 12.0.0.
exo_fw_no++;
// Feed old exosphere target versioning to new.
if (exo_new)
{
switch (exo_fw_no)
{
case 1:
case 2:
case 3:
case 4:
case 1 ... 4:
case 6:
exo_fw_no = EXO_FW_VER(exo_fw_no, 0, 0);
break;
@@ -190,11 +192,8 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base, bool exo_new)
case 7:
exo_fw_no = EXO_FW_VER(6, 2, 0);
break;
case 8:
exo_fw_no = EXO_FW_VER(7, 0, 0);
break;
case 9:
exo_fw_no = EXO_FW_VER(8, 0, 0);
case 8 ... 9:
exo_fw_no = EXO_FW_VER(exo_fw_no - 1, 0, 0);
break;
case 10:
exo_fw_no = EXO_FW_VER(8, 1, 0);
@@ -205,11 +204,8 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base, bool exo_new)
case 12:
exo_fw_no = EXO_FW_VER(9, 1, 0);
break;
case 13:
exo_fw_no = EXO_FW_VER(10, 0, 0);
break;
case 14:
exo_fw_no = EXO_FW_VER(11, 0, 0);
case 13 ... 15:
exo_fw_no = EXO_FW_VER(exo_fw_no - 3, 0, 0);
break;
}
}
@@ -252,6 +248,34 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base, bool exo_new)
break;
}
}
// Parse usb mtim settings. Avoid parsing if it's overridden.
if (ctxt->fss0_main_path && !ctxt->exo_ctx.usb3_force)
{
char set_path[256];
strcpy(set_path, ctxt->fss0_main_path);
strcat(set_path, "config/system_settings.ini");
LIST_INIT(sys_settings);
if (ini_parse(&ini_sections, set_path, false))
{
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
{
// Only parse usb section.
if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "usb"))
continue;
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
if (!strcmp("usb30_force_enabled", kv->key))
{
usb3_force = !strcmp("u8!0x1", kv->val);
break; // Only parse usb30_force_enabled key.
}
}
break;
}
}
}
}
// To avoid problems, make private debug mode always on if not semi-stock.
@@ -270,6 +294,11 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base, bool exo_new)
if (ctxt->exo_ctx.user_pmu)
exo_flags |= EXO_FLAG_USER_PMU;
// Enable USB 3.0. Check if system_settings ini value is overridden. If not, check if enabled in ini.
if ((ctxt->exo_ctx.usb3_force && *ctxt->exo_ctx.usb3_force)
|| (!ctxt->exo_ctx.usb3_force && usb3_force))
exo_flags |= EXO_FLAG_ENABLE_USB3;
// Enable prodinfo blanking. Check if exo ini value is overridden. If not, check if enabled in exo ini.
if ((ctxt->exo_ctx.cal0_blank && *ctxt->exo_ctx.cal0_blank)
|| (!ctxt->exo_ctx.cal0_blank && cal0_blanking))

View File

@@ -5,8 +5,8 @@ SECTIONS {
. = __ipl_start;
.text : {
*(.text._start);
*(._boot_cfg);
*(._ipl_version);
KEEP(*(._boot_cfg));
KEEP(*(._ipl_version));
*(.text._irq_setup);
*(.text*);
}

View File

@@ -143,6 +143,7 @@ void check_power_off_from_hos()
#define EXT_PAYLOAD_ADDR 0xC0000000
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
#define COREBOOT_END_ADDR 0xD0000000
#define COREBOOT_VER_OFF 0x41
#define CBFS_DRAM_EN_ADDR 0x4003e000
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
@@ -204,9 +205,9 @@ bool is_ipl_updated(void *buf, char *path, bool force)
return true;
}
int launch_payload(char *path, bool update)
int launch_payload(char *path, bool update, bool clear_screen)
{
if (!update)
if (clear_screen)
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
@@ -215,7 +216,7 @@ int launch_payload(char *path, bool update)
FIL fp;
if (f_open(&fp, path, FA_READ))
{
gfx_con.mute = 0;
gfx_con.mute = false;
EPRINTFARGS("Payload file is missing!\n(%s)", path);
goto out;
@@ -235,7 +236,7 @@ int launch_payload(char *path, bool update)
{
f_close(&fp);
gfx_con.mute = 0;
gfx_con.mute = false;
EPRINTF("Coreboot not allowed on Mariko!");
goto out;
@@ -268,7 +269,12 @@ int launch_payload(char *path, bool update)
else
{
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
hw_reinit_workaround(true, 0);
// Get coreboot seamless display magic.
u32 magic = 0;
char *magic_ptr = buf + COREBOOT_VER_OFF;
memcpy(&magic, magic_ptr + strlen(magic_ptr) - 4, 4);
hw_reinit_workaround(true, magic);
}
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
@@ -302,7 +308,7 @@ void auto_launch_update()
{
// Check if update.bin exists and is newer and launch it. Otherwise create it.
if (!f_stat("bootloader/update.bin", NULL))
launch_payload("bootloader/update.bin", true);
launch_payload("bootloader/update.bin", true, false);
else
{
u8 *buf = calloc(0x200, 1);
@@ -387,7 +393,7 @@ void launch_tools()
memcpy(dir + strlen(dir), "/", 2);
memcpy(dir + strlen(dir), file_sec, strlen(file_sec) + 1);
launch_payload(dir, false);
launch_payload(dir, false, true);
EPRINTF("Failed to launch payload.");
}
@@ -448,7 +454,7 @@ void ini_list_launcher()
if (cfg_sec)
{
u32 non_cfg = 1;
for (int j = 2; j < i; j++)
for (u32 j = 2; j < i; j++)
{
if (ments[j].type != INI_CHOICE)
non_cfg++;
@@ -506,7 +512,7 @@ void ini_list_launcher()
if (payload_path)
{
launch_payload(payload_path, false);
launch_payload(payload_path, false, true);
EPRINTF("Failed to launch payload.");
free(payload_path);
}
@@ -590,7 +596,7 @@ void launch_firmware()
if (cfg_sec)
{
u8 non_cfg = 4;
for (int j = 5; j < i; j++)
for (u32 j = 5; j < i; j++)
{
if (ments[j].type != INI_CHOICE)
non_cfg++;
@@ -648,7 +654,7 @@ void launch_firmware()
if (payload_path)
{
launch_payload(payload_path, false);
launch_payload(payload_path, false, true);
EPRINTF("Failed to launch payload.");
free(payload_path);
}
@@ -1058,7 +1064,7 @@ skip_list:
if (payload_path)
{
launch_payload(payload_path, false);
launch_payload(payload_path, false, false);
free(payload_path);
goto payload_error;
}
@@ -1086,7 +1092,7 @@ wrong_emupath:
}
payload_error:
gfx_con.mute = 0;
gfx_con.mute = false;
gfx_printf("\nPress any key...\n");
display_backlight_brightness(h_cfg.backlight, 1000);
msleep(500);
@@ -1355,8 +1361,8 @@ void ipl_reload()
static 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"
" (c) 2018-2021, CTCaer\n\n"
" ___________________________________________\n\n"
"Thanks to: %kderrek, nedwill, plutoo,\n"
" shuffle2, smea, thexyz, yellows8%k\n"
@@ -1365,15 +1371,15 @@ static void _about()
" Shiny Quagsire, WinterMute\n"
" ___________________________________________\n\n"
"Open source and free packages used:\n\n"
" - FatFs R0.13b,\n"
" Copyright (c) 2018, ChaN\n\n"
" - bcl-1.2.0,\n"
" Copyright (c) 2003-2006, Marcus Geelnard\n\n"
" - Atmosphere (Exo st/types, prc id patches),\n"
" Copyright (c) 2018-2019, Atmosphere-NX\n\n"
" - elfload,\n"
" Copyright (c) 2014, Owen Shepherd\n"
" Copyright (c) 2018, M4xw\n"
" - FatFs R0.13b\n"
" (c) 2018, ChaN\n\n"
" - bcl-1.2.0\n"
" (c) 2003-2006, Marcus Geelnard\n\n"
" - Atmosphere (Exo st/types, prc id patches)\n"
" (c) 2018-2019, Atmosphere-NX\n\n"
" - elfload\n"
" (c) 2014, Owen Shepherd\n"
" (c) 2018, M4xw\n"
" ___________________________________________\n\n";
static const char octopus[] =
" %k___\n"
@@ -1508,7 +1514,7 @@ ment_t ment_top[] = {
MDEF_END()
};
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.5.4", 0, 0 };
menu_t menu_top = { ment_top, "hekate v5.5.6", 0, 0 };
extern void pivot_stack(u32 stack_top);
@@ -1538,8 +1544,7 @@ void ipl_main()
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
// Save sdram lp0 config.
void *sdram_params =
hw_get_chip_id() == GP_HIDREV_MAJOR_T210 ? sdram_get_params_patched() : sdram_get_params_t210b01();
void *sdram_params = h_cfg.t210b01 ? sdram_get_params_t210b01() : sdram_get_params_patched();
if (!ianos_loader("bootloader/sys/libsys_lp0.bso", DRAM_LIB, sdram_params))
h_cfg.errors |= ERR_LIBSYS_LP0;
@@ -1558,7 +1563,7 @@ void ipl_main()
//display_backlight_brightness(h_cfg.backlight, 1000);
// Overclock BPMP.
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
// Check if we had a panic while in CFW.
secmon_exo_check_panic();

View File

@@ -34,6 +34,10 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
emummc_storage_read(NX_GPT_FIRST_LBA, NX_GPT_NUM_BLOCKS, gpt_buf);
// Check if no GPT or more than max allowed entries.
if (memcmp(&gpt_buf->header.signature, "EFI PART", 8) || gpt_buf->header.num_part_ents > 128)
goto out;
for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++)
{
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1);
@@ -54,6 +58,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
list_append(gpt, &part->link);
}
out:
free(gpt_buf);
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2021 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,
@@ -59,6 +59,11 @@ bool sd_get_card_removed()
return false;
}
bool sd_get_card_mounted()
{
return sd_mounted;
}
u32 sd_get_mode()
{
return sd_mode;

View File

@@ -29,8 +29,11 @@ OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
CUSTOMDEFINES := -DBL_MAGIC=$(IPL_MAGIC)
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
WARNINGS := -Wall -Wno-array-bounds -Wno-stringop-overflow
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=LDR_LOAD_ADDR=$(LDR_LOAD_ADDR)
################################################################################

View File

@@ -5,9 +5,9 @@ SECTIONS {
. = __ipl_start;
.text : {
*(.text._start);
*(._boot_cfg);
*(._ipl_version);
*(._octopus);
KEEP(*(._boot_cfg));
KEEP(*(._ipl_version));
KEEP(*(._octopus));
*(.text*);
}
.data : {

View File

@@ -59,11 +59,6 @@ const volatile char __attribute__((section ("._octopus"))) octopus[] =
void loader_main()
{
// Preserve sections.
__asm__ ("" : : "" (b_cfg));
__asm__ ("" : : "" (ipl_ver));
__asm__ ("" : : "" (octopus[0]));
// Preliminary BPMP clocks init.
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set SCLK div to 1.

View File

@@ -94,8 +94,8 @@ enum tree_update_mode_t
enum emc_channels
{
EMC_CH0 = 0,
EMC_CH1 = 1
EMC_CHANNEL0 = 0,
EMC_CHANNEL1 = 1
};
enum EMC_2X_CLK_SRC
@@ -140,7 +140,4 @@ void _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg);
/* Over temp and periodic compensation, should not access EMC_MRR at the same time. */
u32 _minerva_do_periodic_compensation(emc_table_t *mtc_table_entry);
/* Main function used to access all Minerva functions. */
void _minerva_init(mtc_config_t *mtc_cfg, void* bp);
#endif

View File

@@ -179,7 +179,8 @@
#define TIMING_UPDATE_STALLED (1 << 23)
#define MRR_DIVLD (1 << 20)
#define IN_SELF_REFRESH_MASK (3 << 8)
#define IN_POWERDOWN_MASK (3 << 4)
#define IN_POWERDOWN_BOTH_MASK (3 << 4)
#define IN_POWERDOWN_1DEV_MASK (1 << 4)
#define REQ_FIFO_EMPTY (1 << 0)
#define EMC_CFG_2 0x2B8

File diff suppressed because it is too large Load Diff

View File

@@ -89,8 +89,11 @@ CUSTOMDEFINES += -DNYX -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
# LvGL UART LOG.
#CUSTOMDEFINES += -DDEBUG_UART_LV_LOG
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
WARNINGS := -Wall -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=NYX_LOAD_ADDR=$(NYX_LOAD_ADDR)
################################################################################

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2021 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,
@@ -64,7 +64,7 @@ void set_nyx_default_configuration()
n_cfg.verification = 1;
n_cfg.ums_emmc_rw = 0;
n_cfg.jc_disable = 0;
n_cfg.new_powersave = 1;
n_cfg.bpmp_clock = 0;
}
int create_config_entry()
@@ -72,7 +72,7 @@ int create_config_entry()
if (!sd_mount())
return 1;
char lbuf[32];
char lbuf[64];
FIL fp;
bool mainIniFound = false;
@@ -173,12 +173,14 @@ int create_config_entry()
return 0;
}
int create_nyx_config_entry()
int create_nyx_config_entry(bool force_unmount)
{
bool sd_mounted = sd_get_card_mounted();
if (!sd_mount())
return 1;
char lbuf[32];
char lbuf[64];
FIL fp;
// Make sure that bootloader folder exists.
@@ -206,13 +208,15 @@ int create_nyx_config_entry()
f_puts("\njcdisable=", &fp);
itoa(n_cfg.jc_disable, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nnewpowersave=", &fp);
itoa(n_cfg.new_powersave, lbuf, 10);
f_puts("\nbpmpclock=", &fp);
itoa(n_cfg.bpmp_clock, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\n", &fp);
f_close(&fp);
sd_unmount();
if (force_unmount || !sd_mounted)
sd_unmount();
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2021 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,
@@ -51,12 +51,12 @@ typedef struct _nyx_config
u32 verification;
u32 ums_emmc_rw;
u32 jc_disable;
u32 new_powersave;
u32 bpmp_clock;
} nyx_config;
void set_default_configuration();
void set_nyx_default_configuration();
int create_config_entry();
int create_nyx_config_entry();
int create_nyx_config_entry(bool force_unmount);
#endif /* _CONFIG_H_ */

View File

@@ -55,12 +55,13 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
*part_idx = 0;
int i = 0;
u32 curr_part_size = 0;
// Find first partition with emuMMC GPP.
for (i = 1; i < 4; i++)
{
curr_part_size = mbr->partitions[i].size_sct;
*sector_start = mbr->partitions[i].start_sct;
u8 type = mbr->partitions[i].type;
u32 sector_size_safe = !backup ? (*sector_size) + 0x8000 : (*sector_size);
u32 sector_size_safe = backup ? 0x400000 : (*sector_size) + 0x8000; // 2GB min safe size for backup.
if ((curr_part_size >= sector_size_safe) && *sector_start && type != 0x83 && (!backup || type == 0xE0))
{
if (backup)
@@ -84,6 +85,7 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
break;
}
}
free(mbr);
if (i < 4)
*part_idx = i;
@@ -94,7 +96,7 @@ static void _get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_
*part_idx = 0;
}
free(mbr);
// Get emuMMC GPP size.
if (backup && *part_idx && *sector_size)
{
gpt_t *gpt = (gpt_t *)calloc(sizeof(gpt_t), 1);
@@ -353,6 +355,7 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_part,
partial_sd_full_unmount = false;
u32 multipartSplitSize = (1u << 31);
u32 lba_end = part->lba_end;
u32 totalSectors = part->lba_end - part->lba_start + 1;
u32 currPartIdx = 0;
u32 numSplitParts = 0;
@@ -384,7 +387,10 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_part,
}
sd_sector_off = sector_start + (0x2000 * active_part);
if (active_part == 2)
{
totalSectors = sector_size;
lba_end = sector_size + part->lba_start - 1;
}
}
s_printf(gui->txt_buf, "#96FF00 SD Card free space:# %d MiB\n#96FF00 Total backup size:# %d MiB\n\n",
@@ -670,7 +676,7 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_part,
manual_system_maintenance(false);
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(lba_end - part->lba_start);
if (pct != prevPct)
{
lv_bar_set_value(gui->bar, pct);
@@ -981,14 +987,23 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
if (f_stat(outFilename, &fno) && !gui->raw_emummc)
if ((u32)((u64)totalCheckFileSize >> (u64)9) > totalSectors)
{
s_printf(gui->txt_buf, "#FFDD00 Error (%d) file not found#\n#FFDD00 %s.#\n#FFDD00 Aborting...#", res, outFilename);
s_printf(gui->txt_buf, "#FF8000 Size of SD Card split backup exceeds#\n#FF8000 eMMC's selected part size!#\n#FFDD00 Aborting...#");
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
return 0;
}
else if (f_stat(outFilename, &fno) && !gui->raw_emummc)
{
s_printf(gui->txt_buf, "#FFDD00 Error (%d) file not found#\n#FFDD00 %s.#\n\n", res, outFilename);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
// Attempt a smaller restore.
break;
}
else if (f_stat(outFilename, &fno) && gui->raw_emummc)
{
totalSectors = (u32)((u64)totalCheckFileSize >> (u64)9);
@@ -1020,7 +1035,7 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
{
lv_obj_t *warn_mbox_bg = create_mbox_text(
"#FF8000 Size of SD Card split backup does not match,#\n#FF8000 eMMC's selected part size!#\n\n"
"#FFDD00 The backup might be corrupted!#\n#FFDD00 Aborting is suggested!#\n\n"
"#FFDD00 The backup might be corrupted,#\n#FFDD00 or missing files!#\n#FFDD00 Aborting is suggested!#\n\n"
"Press #FF8000 POWER# to Continue.\nPress #FF8000 VOL# to abort.", false);
manual_system_maintenance(true);
@@ -1078,7 +1093,17 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
}
else if (!use_multipart && (((u32)((u64)f_size(&fp) >> (u64)9)) != totalSectors)) // Check total restore size vs emmc size.
{
if (!gui->raw_emummc)
if (((u32)((u64)f_size(&fp) >> (u64)9)) > totalSectors)
{
s_printf(gui->txt_buf, "#FF8000 Size of SD Card backup exceeds#\n#FF8000 eMMC's selected part size!#\n#FFDD00 Aborting...#");
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
f_close(&fp);
return 0;
}
else if (!gui->raw_emummc)
{
lv_obj_t *warn_mbox_bg = create_mbox_text(
"#FF8000 Size of the SD Card backup does not match,#\n#FF8000 eMMC's selected part size!#\n\n"

View File

@@ -527,9 +527,9 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
if (resized_count)
{
// Get USER partition info.
LIST_INIT(gpt);
nx_emmc_gpt_parse(&gpt, storage);
emmc_part_t *user_part = nx_emmc_part_find(&gpt, "USER");
LIST_INIT(gpt_parsed);
nx_emmc_gpt_parse(&gpt_parsed, storage);
emmc_part_t *user_part = nx_emmc_part_find(&gpt_parsed, "USER");
if (!user_part)
{
s_printf(gui->txt_buf, "\n#FFDD00 USER partition not found!#\n");
@@ -541,7 +541,7 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
user_offset = user_part->lba_start;
part->lba_end = user_offset - 1;
nx_emmc_gpt_free(&gpt);
nx_emmc_gpt_free(&gpt_parsed);
}
u32 totalSectors = part->lba_end - part->lba_start + 1;
@@ -695,55 +695,58 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
// Read MBR, GPT and backup GPT.
mbr_t mbr;
gpt_t gpt_main;
gpt_t *gpt = calloc(1, sizeof(gpt_t));
gpt_header_t gpt_hdr_backup;
sdmmc_storage_read(storage, 0, 1, &mbr);
sdmmc_storage_read(storage, 1, sizeof(gpt_t) >> 9, &gpt_main);
sdmmc_storage_read(storage, gpt_main.header.alt_lba, 1, &gpt_hdr_backup);
sdmmc_storage_read(storage, 1, sizeof(gpt_t) >> 9, gpt);
sdmmc_storage_read(storage, gpt->header.alt_lba, 1, &gpt_hdr_backup);
// Find USER partition.
u32 gpt_entry_idx = 0;
for (gpt_entry_idx = 0; gpt_entry_idx < gpt_main.header.num_part_ents; gpt_entry_idx++)
if (!memcmp(gpt_main.entries[gpt_entry_idx].name, (char[]) { 'U', 0, 'S', 0, 'E', 0, 'R', 0 }, 8))
for (gpt_entry_idx = 0; gpt_entry_idx < gpt->header.num_part_ents; gpt_entry_idx++)
if (!memcmp(gpt->entries[gpt_entry_idx].name, (char[]) { 'U', 0, 'S', 0, 'E', 0, 'R', 0 }, 8))
break;
if (gpt_entry_idx >= gpt_main.header.num_part_ents)
if (gpt_entry_idx >= gpt->header.num_part_ents)
{
s_printf(gui->txt_buf, "\n#FF0000 No USER partition...#\nPlease try again...\n");
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
free(gpt);
return 0;
}
// Set new emuMMC size and USER size.
mbr.partitions[0].size_sct = resized_count;
gpt_main.entries[gpt_entry_idx].lba_end = user_offset + user_sectors - 1;
gpt->entries[gpt_entry_idx].lba_end = user_offset + user_sectors - 1;
// Update Main GPT.
gpt_main.header.alt_lba = resized_count - 1;
gpt_main.header.last_use_lba = resized_count - 34;
gpt_main.header.part_ents_crc32 = crc32_calc(0, (const u8 *)gpt_main.entries, sizeof(gpt_entry_t) * gpt_main.header.num_part_ents);
gpt_main.header.crc32 = 0; // Set to 0 for calculation.
gpt_main.header.crc32 = crc32_calc(0, (const u8 *)&gpt_main.header, gpt_main.header.size);
gpt->header.alt_lba = resized_count - 1;
gpt->header.last_use_lba = resized_count - 34;
gpt->header.part_ents_crc32 = crc32_calc(0, (const u8 *)gpt->entries, sizeof(gpt_entry_t) * gpt->header.num_part_ents);
gpt->header.crc32 = 0; // Set to 0 for calculation.
gpt->header.crc32 = crc32_calc(0, (const u8 *)&gpt->header, gpt->header.size);
// Update Backup GPT.
gpt_hdr_backup.my_lba = resized_count - 1;
gpt_hdr_backup.part_ent_lba = resized_count - 33;
gpt_hdr_backup.part_ents_crc32 = gpt_main.header.part_ents_crc32;
gpt_hdr_backup.part_ents_crc32 = gpt->header.part_ents_crc32;
gpt_hdr_backup.crc32 = 0; // Set to 0 for calculation.
gpt_hdr_backup.crc32 = crc32_calc(0, (const u8 *)&gpt_hdr_backup, gpt_hdr_backup.size);
// Write main GPT.
sdmmc_storage_write(&sd_storage, sd_sector_off + gpt_main.header.my_lba, sizeof(gpt_t) >> 9, &gpt_main);
sdmmc_storage_write(&sd_storage, sd_sector_off + gpt->header.my_lba, sizeof(gpt_t) >> 9, gpt);
// Write backup GPT partition table.
sdmmc_storage_write(&sd_storage, sd_sector_off + gpt_hdr_backup.part_ent_lba, ((sizeof(gpt_entry_t) * 128) >> 9), gpt_main.entries);
sdmmc_storage_write(&sd_storage, sd_sector_off + gpt_hdr_backup.part_ent_lba, ((sizeof(gpt_entry_t) * 128) >> 9), gpt->entries);
// Write backup GPT header.
sdmmc_storage_write(&sd_storage, sd_sector_off + gpt_hdr_backup.my_lba, 1, &gpt_hdr_backup);
// Write MBR.
sdmmc_storage_write(&sd_storage, sd_sector_off, 1, &mbr);
free(gpt);
}
return 1;

View File

@@ -2106,6 +2106,14 @@ static void _nyx_set_default_styles(lv_theme_t * th)
s_printf(text_color, "#%06X", tmp_color.full & 0xFFFFFF);
}
lv_task_t *task_bpmp_clock;
void first_time_bpmp_clock(void *param)
{
n_cfg.bpmp_clock = 1;
create_nyx_config_entry(false);
lv_task_del(task_bpmp_clock);
}
static void _nyx_main_menu(lv_theme_t * th)
{
static lv_style_t no_padding;
@@ -2240,30 +2248,9 @@ static void _nyx_main_menu(lv_theme_t * th)
lv_task_t *task_run_clock = lv_task_create(first_time_clock_edit, LV_TASK_ONESHOT, LV_TASK_PRIO_MID, NULL);
lv_task_once(task_run_clock);
}
}
static void _nyx_gui_loop_powersave_ram()
{
// Saves 280 mW.
while (true)
{
minerva_change_freq(FREQ_1600); // Takes 295 us.
lv_task_handler();
minerva_change_freq(FREQ_800); // Takes 80 us.
}
}
static void _nyx_gui_loop_powersave_cpu()
{
// Saves 75 mW.
while (true)
{
lv_task_handler();
bpmp_usleep(HALT_COP_MAX_CNT); // Takes 200 us.
}
if (!n_cfg.bpmp_clock)
task_bpmp_clock = lv_task_create(first_time_bpmp_clock, 5000, LV_TASK_PRIO_LOWEST, NULL);
}
void nyx_load_and_run()
@@ -2331,8 +2318,16 @@ void nyx_load_and_run()
while (true)
lv_task_handler();
}
else if (n_cfg.new_powersave)
_nyx_gui_loop_powersave_ram(); // Alternate DRAM frequencies. Higher power savings.
else
_nyx_gui_loop_powersave_cpu(); // Suspend CPU. Lower power savings.
{
// Alternate DRAM frequencies. Saves 280 mW.
while (true)
{
minerva_change_freq(FREQ_1600); // Takes 295 us.
lv_task_handler();
minerva_change_freq(FREQ_800); // Takes 80 us.
}
}
}

View File

@@ -703,7 +703,7 @@ static lv_res_t _create_emummc_migrate_action(lv_obj_t * btns, const char * txt)
{
s_printf(txt_buf,
"#C7EA46 Found SD Partition based emuMMC!#\n\n"
"#FF8000 Do you want to repair the config for it?#\n");
"#FF8000 Do you want to repair the config and partition type for it?#\n");
lv_mbox_add_btns(mbox, mbox_btn_map, _create_emummc_mig3_action);
}
else if (em_raw && em_file)

View File

@@ -453,7 +453,7 @@ t210b01:;
cal0->bd_mac[0], cal0->bd_mac[1], cal0->bd_mac[2], cal0->bd_mac[3], cal0->bd_mac[4], cal0->bd_mac[5],
cal0->battery_lot);
u8 display_rev = (nyx_str->info.disp_id >> 8) & 0xFF;
u8 display_rev = (cal0->lcd_vendor >> 8) & 0xFF;
u32 display_id = (cal0->lcd_vendor & 0xFF) << 8 | (cal0->lcd_vendor & 0xFF0000) >> 16;
switch (display_id)
{
@@ -731,7 +731,10 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
strcpy(fuses_hos_version, "10.0.0 - 10.2.0");
break;
case 14:
strcpy(fuses_hos_version, "11.0.0+");
strcpy(fuses_hos_version, "11.0.0 - 12.0.1");
break;
case 15:
strcpy(fuses_hos_version, "12.0.2+");
break;
default:
strcpy(fuses_hos_version, "#FF8000 Unknown#");
@@ -887,6 +890,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case 0x96:
strcat(txt_buf, "-AZ3");
break;
case 0x98:
strcat(txt_buf, "-???");
break;
default:
strcat(txt_buf, " #FFDD00 Contact me!#");
break;
@@ -943,9 +949,18 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
touch_panel = touch_get_panel_vendor();
if (touch_panel)
strcat(txt_buf, touch_panel->vendor);
{
if (touch_panel->idx == -2) // Touch panel not found, print gpios.
{
s_printf(txt_buf + strlen(txt_buf), "%2X%2X%2X #FFDD00 Contact me!#",
touch_panel->gpio0, touch_panel->gpio1, touch_panel->gpio2);
touch_panel = NULL;
}
else
strcat(txt_buf, touch_panel->vendor);
}
else
strcat(txt_buf, "Unknown #FFDD00 Contact me!#");
strcat(txt_buf, "#FFDD00 Error!#");
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# %08X (", touch_fw.fw_id);
@@ -982,6 +997,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
break;
case 0x32000501:
case 0x33000502:
case 0x33000503:
strcat(txt_buf, "4CD UNKN");
if (touch_panel)
panel_ic_paired = touch_panel->idx == 4;
@@ -994,6 +1010,8 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
s_printf(txt_buf + strlen(txt_buf), " - %s)\n#FF8000 FTB ver:# %04X\n#FF8000 FW rev:# %04X",
panel_ic_paired ? "Paired" : "#FFDD00 Error#", touch_fw.ftb_ver, touch_fw.fw_rev);
}
else
strcat(txt_buf, "\n\n#FFDD00 Failed to get touch info!#");
// Check if patched unit.
if (!fuse_check_patched_rcm())
@@ -1258,6 +1276,9 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
if (sd_bench)
{
storage = &sd_storage;
// Re-initialize to update trimmers.
sd_end();
res = !sd_mount();
}
else
@@ -1272,6 +1293,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
lv_mbox_set_text(mbox, "#FFDD00 Failed to init Storage!#");
else
{
int error = 0;
u32 iters = 3;
u32 offset_chunk_start = ALIGN_DOWN(storage->sec_cnt / 3, 0x8000); // Align to 16MB.
if (storage->sec_cnt < 0xC00000)
@@ -1292,7 +1314,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
while (data_remaining)
{
u32 time_taken = get_tmr_us();
sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
time_taken = get_tmr_us() - time_taken;
timer += time_taken;
@@ -1309,8 +1331,11 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
prevPct = pct;
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
break;
error = -1;
}
if (error)
goto error;
}
lv_bar_set_value(bar, 100);
@@ -1333,7 +1358,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
while (data_remaining)
{
u32 time_taken = get_tmr_us();
sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED);
time_taken = get_tmr_us() - time_taken;
timer += time_taken;
@@ -1350,8 +1375,11 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
prevPct = pct;
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
break;
error = -1;
}
if (error)
goto error;
}
lv_bar_set_value(bar, 100);
@@ -1388,7 +1416,7 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
while (data_remaining)
{
u32 time_taken = get_tmr_us();
sdmmc_storage_read(storage, sector + random_offsets[lba_idx], sector_num, (u8 *)MIXD_BUF_ALIGNED);
error = !sdmmc_storage_read(storage, sector + random_offsets[lba_idx], sector_num, (u8 *)MIXD_BUF_ALIGNED);
time_taken = get_tmr_us() - time_taken;
timer += time_taken;
@@ -1405,7 +1433,13 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
prevPct = pct;
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
break;
error = -1;
}
if (error)
{
free(random_offsets);
goto error;
}
}
lv_bar_set_value(bar, 100);
@@ -1416,6 +1450,8 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
s_printf(txt_buf + strlen(txt_buf),
" Random 4KiB - Rate: #C7EA46 %3d.%02d MiB/s#, IOPS: #C7EA46 %4d#\n",
rate_1k / 1000, (rate_1k % 1000) / 10, iops_1k);
if (iter_curr == iters - 1)
txt_buf[strlen(txt_buf) - 1] = 0; // Cut off last line change.
lv_label_set_text(lbl_status, txt_buf);
lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
@@ -1423,6 +1459,18 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
free(random_offsets);
}
error:
if (error)
{
if (error == -1)
s_printf(txt_buf + strlen(txt_buf), "\n#FFDD00 Aborted!#");
else
s_printf(txt_buf + strlen(txt_buf), "\n#FFDD00 IO Error occurred!#");
lv_label_set_text(lbl_status, txt_buf);
lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0);
}
lv_obj_del(bar);
if (sd_bench)
@@ -1716,13 +1764,13 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
// Identify manufacturer.
switch (sd_storage.cid.manfid)
{
case 1:
case 0x01:
strcat(txt_buf, "Panasonic ");
break;
case 2:
case 0x02:
strcat(txt_buf, "Toshiba ");
break;
case 3:
case 0x03:
strcat(txt_buf, "SanDisk ");
break;
case 0x1B:
@@ -1752,6 +1800,14 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
case 0x82:
strcat(txt_buf, "Sony ");
break;
//TODO: Investigate which OEM/ODM makes these.
// case 0x9C: // LX512 SO
// case 0xAD: // LX512 LS
// strcat(txt_buf, "Lexar ");
// break;
default:
strcat(txt_buf, "Unknown ");
break;
}
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c\n%c%c\n%X\n%X\n%08x\n%02d/%04d\n\n",

View File

@@ -336,7 +336,7 @@ static lv_res_t _save_nyx_options_action(lv_obj_t *btn)
lv_obj_t * mbox = lv_mbox_create(lv_scr_act(), NULL);
lv_mbox_set_recolor_text(mbox, true);
int res = !create_nyx_config_entry();
int res = !create_nyx_config_entry(true);
nyx_changes_made = false;
@@ -400,7 +400,7 @@ static lv_res_t _save_theme_color_action(lv_obj_t *btn)
n_cfg.themecolor = color_test.hue;
// Save nyx config.
create_nyx_config_entry();
create_nyx_config_entry(true);
reload_nyx();
@@ -622,6 +622,8 @@ static lv_res_t _action_clock_edit(lv_obj_t *btns, const char * txt)
u32 new_epoch = max77620_rtc_date_to_epoch(&time);
n_cfg.timeoff = new_epoch - epoch;
if (!n_cfg.timeoff)
n_cfg.timeoff = 1;
nyx_changes_made = true;
}

View File

@@ -348,7 +348,7 @@ static lv_res_t _action_hid_jc(lv_obj_t *btn)
// Reduce BPMP, RAM and backlight and power off SDMMC1 to conserve power.
sd_end();
minerva_change_freq(FREQ_800);
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
display_backlight_brightness(10, 1000);
usb_ctxt_t usbs;
@@ -360,7 +360,7 @@ static lv_res_t _action_hid_jc(lv_obj_t *btn)
// Restore BPMP, RAM and backlight.
minerva_change_freq(FREQ_1600);
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(prev_fid);
display_backlight_brightness(h_cfg.backlight - 20, 1000);
return LV_RES_OK;
@@ -372,7 +372,7 @@ static lv_res_t _action_hid_touch(lv_obj_t *btn)
// Reduce BPMP, RAM and backlight and power off SDMMC1 to conserve power.
sd_end();
minerva_change_freq(FREQ_800);
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
display_backlight_brightness(10, 1000);
usb_ctxt_t usbs;
@@ -384,7 +384,7 @@ static lv_res_t _action_hid_touch(lv_obj_t *btn)
// Restore BPMP, RAM and backlight.
minerva_change_freq(FREQ_1600);
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(prev_fid);
display_backlight_brightness(h_cfg.backlight - 20, 1000);
return LV_RES_OK;

View File

@@ -41,6 +41,7 @@ extern volatile nyx_storage_t *nyx_str;
typedef struct _partition_ctxt_t
{
u32 total_sct;
u32 alignment;
int backup_possible;
s32 hos_size;
@@ -50,7 +51,7 @@ typedef struct _partition_ctxt_t
bool emu_double;
mbr_t *mbr_old;
mbr_t mbr_old;
lv_obj_t *bar_hos;
lv_obj_t *bar_emu;
@@ -222,17 +223,15 @@ static int _backup_and_restore_files(char *path, u32 *total_files, u32 *total_si
static void _prepare_and_flash_mbr_gpt()
{
u8 random_number[16];
mbr_t mbr;
gpt_t gpt = { 0 };
gpt_header_t gpt_hdr_backup = { 0 };
u8 random_number[16];
// Read current MBR.
sdmmc_storage_read(&sd_storage, 0, 1, &mbr);
// Copy over metadata if they exist.
if (part_info.mbr_old->bootstrap[0x80])
memcpy(&mbr.bootstrap[0x80], &part_info.mbr_old->bootstrap[0x80], 304);
if (*(u32 *)&part_info.mbr_old.bootstrap[0x80])
memcpy(&mbr.bootstrap[0x80], &part_info.mbr_old.bootstrap[0x80], 304);
// Clear the first 16MB.
memset((void *)SDMMC_UPPER_BUFFER, 0, 0x8000);
@@ -262,11 +261,11 @@ static void _prepare_and_flash_mbr_gpt()
mbr.partitions[mbr_idx].size_sct = (part_info.emu_size << 11) - 0x800; // Reserve 1MB.
else
{
mbr.partitions[mbr_idx].type = 0xE0; // emuMMC partition.
mbr.partitions[mbr_idx].size_sct = part_info.emu_size << 10;
mbr_idx++;
// 2nd emuMMC.
mbr.partitions[mbr_idx].type = 0xE0; // emuMMC partition.
mbr.partitions[mbr_idx].start_sct = mbr.partitions[mbr_idx - 1].start_sct + (part_info.emu_size << 10);
mbr.partitions[mbr_idx].size_sct = (part_info.emu_size << 10) - 0x800; // Reserve 1MB.
}
@@ -275,49 +274,52 @@ static void _prepare_and_flash_mbr_gpt()
if (part_info.and_size)
{
gpt_t *gpt = calloc(1, sizeof(gpt_t));
gpt_header_t gpt_hdr_backup = { 0 };
mbr.partitions[mbr_idx].type = 0xEE; // GPT protective partition.
mbr.partitions[mbr_idx].start_sct = 1;
mbr.partitions[mbr_idx].size_sct = sd_storage.sec_cnt - 1;
mbr_idx++;
// Set GPT header.
memcpy(&gpt.header.signature, "EFI PART", 8);
gpt.header.revision = 0x10000;
gpt.header.size = 92;
gpt.header.my_lba = 1;
gpt.header.alt_lba = sd_storage.sec_cnt - 1;
gpt.header.first_use_lba = (sizeof(mbr_t) + sizeof(gpt_t)) >> 9;
gpt.header.last_use_lba = sd_storage.sec_cnt - 0x800 - 1; // sd_storage.sec_cnt - 33 is start of backup gpt partition entries.
memcpy(&gpt->header.signature, "EFI PART", 8);
gpt->header.revision = 0x10000;
gpt->header.size = 92;
gpt->header.my_lba = 1;
gpt->header.alt_lba = sd_storage.sec_cnt - 1;
gpt->header.first_use_lba = (sizeof(mbr_t) + sizeof(gpt_t)) >> 9;
gpt->header.last_use_lba = sd_storage.sec_cnt - 0x800 - 1; // sd_storage.sec_cnt - 33 is start of backup gpt partition entries.
se_gen_prng128(random_number);
memcpy(gpt.header.disk_guid, random_number, 10);
memcpy(gpt.header.disk_guid + 10, "NYXGPT", 6);
gpt.header.part_ent_lba = 2;
gpt.header.part_ent_size = 128;
memcpy(gpt->header.disk_guid, random_number, 10);
memcpy(gpt->header.disk_guid + 10, "NYXGPT", 6);
gpt->header.part_ent_lba = 2;
gpt->header.part_ent_size = 128;
// Set GPT partitions.
u8 basic_part_guid[] = { 0xA2, 0xA0, 0xD0, 0xEB, 0xE5, 0xB9, 0x33, 0x44, 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 };
memcpy(gpt.entries[0].type_guid, basic_part_guid, 16);
memcpy(gpt->entries[0].type_guid, basic_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[0].part_guid, random_number, 16);
memcpy(gpt->entries[0].part_guid, random_number, 16);
// Clear non-standard Windows MBR attributes. bit4: Read only, bit5: Shadow copy, bit6: Hidden, bit7: No drive letter.
gpt.entries[0].part_guid[7] = 0;
gpt->entries[0].part_guid[7] = 0;
gpt.entries[0].lba_start = mbr.partitions[0].start_sct;
gpt.entries[0].lba_end = mbr.partitions[0].start_sct + mbr.partitions[0].size_sct - 1;
memcpy(gpt.entries[0].name, (char[]) { 'h', 0, 'o', 0, 's', 0, '_', 0, 'd', 0, 'a', 0, 't', 0, 'a', 0 }, 16);
gpt->entries[0].lba_start = mbr.partitions[0].start_sct;
gpt->entries[0].lba_end = mbr.partitions[0].start_sct + mbr.partitions[0].size_sct - 1;
memcpy(gpt->entries[0].name, (char[]) { 'h', 0, 'o', 0, 's', 0, '_', 0, 'd', 0, 'a', 0, 't', 0, 'a', 0 }, 16);
u8 gpt_idx = 1;
u32 curr_part_lba = 0x8000 + ((u32)part_info.hos_size << 11);
u8 android_part_guid[] = { 0xAF, 0x3D, 0xC6, 0x0F, 0x83, 0x84, 0x72, 0x47, 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4 };
if (part_info.l4t_size)
{
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + (part_info.l4t_size << 11) - 1;
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'l', 0, '4', 0, 't', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + (part_info.l4t_size << 11) - 1;
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'l', 0, '4', 0, 't', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += (part_info.l4t_size << 11);
@@ -325,89 +327,89 @@ static void _prepare_and_flash_mbr_gpt()
}
// Android Vendor partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x200000 - 1; // 1GB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'v', 0, 'e', 0, 'n', 0, 'd', 0, 'o', 0, 'r', 0 }, 12);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x200000 - 1; // 1GB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'v', 0, 'e', 0, 'n', 0, 'd', 0, 'o', 0, 'r', 0 }, 12);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += 0x200000;
gpt_idx++;
// Android System partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x400000 - 1; // 2GB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'A', 0, 'P', 0, 'P', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x400000 - 1; // 2GB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'A', 0, 'P', 0, 'P', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += 0x400000;
gpt_idx++;
// Android Linux Kernel partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x10000 - 1; // 32MB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x10000 - 1; // 32MB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += 0x10000;
gpt_idx++;
// Android Recovery partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x20000 - 1; // 64MB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x20000 - 1; // 64MB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += 0x20000;
gpt_idx++;
// Android Device Tree Reference partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x800 - 1; // 1MB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x800 - 1; // 1MB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += 0x800;
gpt_idx++;
// Android Encryption partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x8000 - 1; // 16MB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'M', 0, 'D', 0, 'A', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x8000 - 1; // 16MB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'M', 0, 'D', 0, 'A', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x8000, (void *)SDMMC_UPPER_BUFFER); // Clear 16MB.
curr_part_lba += 0x8000;
gpt_idx++;
// Android Cache partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x15E000 - 1; // 700MB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'C', 0, 'A', 0, 'C', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x15E000 - 1; // 700MB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'C', 0, 'A', 0, 'C', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += 0x15E000;
gpt_idx++;
// Android Misc partition.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x1800 - 1; // 3MB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'M', 0, 'S', 0, 'C', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + 0x1800 - 1; // 3MB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'M', 0, 'S', 0, 'C', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += 0x1800;
gpt_idx++;
@@ -416,12 +418,12 @@ static void _prepare_and_flash_mbr_gpt()
u32 user_size = (part_info.and_size << 11) - 0x798000; // Subtract the other partitions (3888MB).
if (!part_info.emu_size)
user_size -= 0x800; // Reserve 1MB.
memcpy(gpt.entries[gpt_idx].type_guid, android_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, android_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + user_size - 1;
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'U', 0, 'D', 0, 'A', 0 }, 6);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + user_size - 1;
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'U', 0, 'D', 0, 'A', 0 }, 6);
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
curr_part_lba += user_size;
gpt_idx++;
@@ -429,37 +431,37 @@ static void _prepare_and_flash_mbr_gpt()
if (part_info.emu_size)
{
u8 emu_part_guid[] = { 0x00, 0x7E, 0xCA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 'e', 'm', 'u', 'M', 'M', 'C' };
memcpy(gpt.entries[gpt_idx].type_guid, emu_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, emu_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
if (!part_info.emu_double)
gpt.entries[gpt_idx].lba_end = curr_part_lba + (part_info.emu_size << 11) - 0x800 - 1; // Reserve 1MB.
gpt->entries[gpt_idx].lba_end = curr_part_lba + (part_info.emu_size << 11) - 0x800 - 1; // Reserve 1MB.
else
gpt.entries[gpt_idx].lba_end = curr_part_lba + (part_info.emu_size << 10) - 1;
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'e', 0, 'm', 0, 'u', 0, 'm', 0, 'm', 0, 'c', 0 }, 12);
gpt->entries[gpt_idx].lba_end = curr_part_lba + (part_info.emu_size << 10) - 1;
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'e', 0, 'm', 0, 'u', 0, 'm', 0, 'm', 0, 'c', 0 }, 12);
gpt_idx++;
if (part_info.emu_double)
{
curr_part_lba += (part_info.emu_size << 10);
memcpy(gpt.entries[gpt_idx].type_guid, emu_part_guid, 16);
memcpy(gpt->entries[gpt_idx].type_guid, emu_part_guid, 16);
se_gen_prng128(random_number);
memcpy(gpt.entries[gpt_idx].part_guid, random_number, 16);
gpt.entries[gpt_idx].lba_start = curr_part_lba;
gpt.entries[gpt_idx].lba_end = curr_part_lba + (part_info.emu_size << 10) - 0x800 - 1; // Reserve 1MB.
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'e', 0, 'm', 0, 'u', 0, 'm', 0, 'm', 0, 'c', 0, '2', 0 }, 14);
memcpy(gpt->entries[gpt_idx].part_guid, random_number, 16);
gpt->entries[gpt_idx].lba_start = curr_part_lba;
gpt->entries[gpt_idx].lba_end = curr_part_lba + (part_info.emu_size << 10) - 0x800 - 1; // Reserve 1MB.
memcpy(gpt->entries[gpt_idx].name, (char[]) { 'e', 0, 'm', 0, 'u', 0, 'm', 0, 'm', 0, 'c', 0, '2', 0 }, 14);
gpt_idx++;
}
}
// Set final GPT header parameters.
gpt.header.num_part_ents = 128;
gpt.header.part_ents_crc32 = crc32_calc(0, (const u8 *)gpt.entries, sizeof(gpt_entry_t) * 128);
gpt.header.crc32 = 0; // Set to 0 for calculation.
gpt.header.crc32 = crc32_calc(0, (const u8 *)&gpt.header, gpt.header.size);
gpt->header.num_part_ents = 128;
gpt->header.part_ents_crc32 = crc32_calc(0, (const u8 *)gpt->entries, sizeof(gpt_entry_t) * 128);
gpt->header.crc32 = 0; // Set to 0 for calculation.
gpt->header.crc32 = crc32_calc(0, (const u8 *)&gpt->header, gpt->header.size);
memcpy(&gpt_hdr_backup, &gpt.header, sizeof(gpt_header_t));
memcpy(&gpt_hdr_backup, &gpt->header, sizeof(gpt_header_t));
gpt_hdr_backup.my_lba = sd_storage.sec_cnt - 1;
gpt_hdr_backup.alt_lba = 1;
gpt_hdr_backup.part_ent_lba = sd_storage.sec_cnt - 33;
@@ -467,13 +469,15 @@ static void _prepare_and_flash_mbr_gpt()
gpt_hdr_backup.crc32 = crc32_calc(0, (const u8 *)&gpt_hdr_backup, gpt_hdr_backup.size);
// Write main GPT.
sdmmc_storage_write(&sd_storage, gpt.header.my_lba, sizeof(gpt_t) >> 9, &gpt);
sdmmc_storage_write(&sd_storage, gpt->header.my_lba, sizeof(gpt_t) >> 9, gpt);
// Write backup GPT partition table.
sdmmc_storage_write(&sd_storage, gpt_hdr_backup.part_ent_lba, ((sizeof(gpt_entry_t) * 128) >> 9), gpt.entries);
sdmmc_storage_write(&sd_storage, gpt_hdr_backup.part_ent_lba, ((sizeof(gpt_entry_t) * 128) >> 9), gpt->entries);
// Write backup GPT header.
sdmmc_storage_write(&sd_storage, gpt_hdr_backup.my_lba, 1, &gpt_hdr_backup);
free(gpt);
}
// Write MBR.
@@ -735,7 +739,7 @@ exit:
static u32 _get_available_l4t_partition()
{
mbr_t mbr = { 0 };
gpt_t gpt = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t));
memset(&l4t_flash_ctxt, 0, sizeof(l4t_flasher_ctxt_t));
@@ -743,18 +747,18 @@ static u32 _get_available_l4t_partition()
sdmmc_storage_read(&sd_storage, 0, 1, &mbr);
// Read main GPT.
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, &gpt);
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt);
// Search for a suitable partition.
u32 size_sct = 0;
if (!memcmp(&gpt.header.signature, "EFI PART", 8))
if (!memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128)
{
for (u32 i = 0; i < gpt.header.num_part_ents; i++)
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt.entries[i].name, (char[]) { 'l', 0, '4', 0, 't', 0 }, 6))
if (!memcmp(gpt->entries[i].name, (char[]) { 'l', 0, '4', 0, 't', 0 }, 6))
{
l4t_flash_ctxt.offset_sct = gpt.entries[i].lba_start;
size_sct = (gpt.entries[i].lba_end + 1) - gpt.entries[i].lba_start;
l4t_flash_ctxt.offset_sct = gpt->entries[i].lba_start;
size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start;
break;
}
@@ -775,30 +779,39 @@ static u32 _get_available_l4t_partition()
}
}
free(gpt);
return size_sct;
}
static bool _get_available_android_partition()
{
gpt_t gpt = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t));
// Read main GPT.
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, &gpt);
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt);
// Check if GPT.
if (memcmp(&gpt.header.signature, "EFI PART", 8))
return false;
if (memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128)
goto out;
// Find kernel partition.
for (u32 i = 0; i < gpt.header.num_part_ents; i++)
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (gpt.entries[i].lba_start && !memcmp(gpt.entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6))
if (gpt->entries[i].lba_start && !memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6))
{
free(gpt);
return true;
}
if (i > 126)
break;
}
out:
free(gpt);
return false;
}
@@ -956,7 +969,7 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
if (!btn_idx)
{
char path[128];
gpt_t gpt = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t));
char *txt_buf = malloc(0x1000);
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
@@ -983,10 +996,10 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
sd_mount();
// Read main GPT.
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, &gpt);
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt);
bool boot_twrp = false;
if (memcmp(&gpt.header.signature, "EFI PART", 8))
if (memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128)
{
lv_label_set_text(lbl_status, "#FFDD00 Error:# No Android GPT was found!");
goto error;
@@ -997,12 +1010,12 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
{
u32 offset_sct = 0;
u32 size_sct = 0;
for (u32 i = 0; i < gpt.header.num_part_ents; i++)
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt.entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6))
if (!memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6))
{
offset_sct = gpt.entries[i].lba_start;
size_sct = (gpt.entries[i].lba_end + 1) - gpt.entries[i].lba_start;
offset_sct = gpt->entries[i].lba_start;
size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start;
break;
}
@@ -1050,12 +1063,12 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
{
u32 offset_sct = 0;
u32 size_sct = 0;
for (u32 i = 0; i < gpt.header.num_part_ents; i++)
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt.entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6))
if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6))
{
offset_sct = gpt.entries[i].lba_start;
size_sct = (gpt.entries[i].lba_end + 1) - gpt.entries[i].lba_start;
offset_sct = gpt->entries[i].lba_start;
size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start;
break;
}
@@ -1102,12 +1115,12 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
{
u32 offset_sct = 0;
u32 size_sct = 0;
for (u32 i = 0; i < gpt.header.num_part_ents; i++)
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt.entries[i].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6))
if (!memcmp(gpt->entries[i].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6))
{
offset_sct = gpt.entries[i].lba_start;
size_sct = (gpt.entries[i].lba_end + 1) - gpt.entries[i].lba_start;
offset_sct = gpt->entries[i].lba_start;
size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start;
break;
}
@@ -1149,12 +1162,12 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt)
lv_label_set_text(lbl_status, txt_buf);
// Check if TWRP is flashed unconditionally.
for (u32 i = 0; i < gpt.header.num_part_ents; i++)
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
if (!memcmp(gpt.entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6))
if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6))
{
u8 *buf = malloc(512);
sdmmc_storage_read(&sd_storage, gpt.entries[i].lba_start, 1, buf);
sdmmc_storage_read(&sd_storage, gpt->entries[i].lba_start, 1, buf);
if (!memcmp(buf, "ANDROID", 7))
boot_twrp = true;
free(buf);
@@ -1178,6 +1191,7 @@ error:
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
free(txt_buf);
free(gpt);
sd_unmount();
}
@@ -1359,8 +1373,7 @@ static lv_res_t _create_mbox_start_partitioning(lv_obj_t *btn)
u32 total_size = 0;
// Read current MBR.
part_info.mbr_old = (mbr_t *)calloc(512, 1);
sdmmc_storage_read(&sd_storage, 0, 1, part_info.mbr_old);
sdmmc_storage_read(&sd_storage, 0, 1, &part_info.mbr_old);
lv_label_set_text(lbl_status, "#00DDFF Status:# Initializing Ramdisk...");
lv_label_set_text(lbl_paths[0], "Please wait...");
@@ -1405,6 +1418,7 @@ static lv_res_t _create_mbox_start_partitioning(lv_obj_t *btn)
// Set reserved size.
u32 part_rsvd_size = (part_info.emu_size << 11) + (part_info.l4t_size << 11) + (part_info.and_size << 11);
part_rsvd_size += part_info.alignment;
disk_set_info(DRIVE_SD, SET_SECTOR_COUNT, &part_rsvd_size);
u8 *buf = malloc(0x400000);
@@ -1929,7 +1943,7 @@ static void create_mbox_check_files_total_size()
lv_obj_t *lbl_part = lv_label_create(h1, NULL);
lv_label_set_recolor(lbl_part, true);
lv_label_set_text(lbl_part, "#00DDFF Current partition layout:#");
lv_label_set_text(lbl_part, "#00DDFF Current MBR partition layout:#");
// Read current MBR.
mbr_t mbr = { 0 };
@@ -2038,53 +2052,66 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
}
mbr_t mbr[2] = { 0 };
gpt_t gpt = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t));
sdmmc_storage_read(&sd_storage, 0, 1, &mbr[0]);
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, &gpt);
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt);
memcpy(&mbr[1], &mbr[0], sizeof(mbr_t));
sd_unmount();
if (memcmp(&gpt.header.signature, "EFI PART", 8))
if (memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128)
{
lv_label_set_text(lbl_status, "#FFDD00 Warning:# No GPT was found!");
lv_label_set_text(lbl_status, "#FFDD00 Warning:# No valid GPT was found!");
goto out;
}
// Parse GPT.
LIST_INIT(gpt_parsed);
for (u32 i = 0; i < gpt.header.num_part_ents; i++)
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1);
if (gpt.entries[i].lba_start < gpt.header.first_use_lba)
if (gpt->entries[i].lba_start < gpt->header.first_use_lba)
continue;
part->index = i;
part->lba_start = gpt.entries[i].lba_start;
part->lba_end = gpt.entries[i].lba_end;
part->attrs = gpt.entries[i].attrs;
part->lba_start = gpt->entries[i].lba_start;
part->lba_end = gpt->entries[i].lba_end;
// ASCII conversion. Copy only the LSByte of the UTF-16LE name.
for (u32 j = 0; j < 36; j++)
part->name[j] = gpt.entries[i].name[j];
part->name[j] = gpt->entries[i].name[j];
part->name[35] = 0;
list_append(&gpt_parsed, &part->link);
}
free(gpt);
u32 mbr_idx = 0;
// Set FAT and emuMMC partitions.
u32 mbr_idx = 1;
bool found_hos_data = false;
LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt_parsed, link)
{
if (!strcmp(part->name, "hos_data"))
// FatFS simple GPT found a fat partition, set it.
if (sd_fs.part_type && !part->index)
{
mbr[1].partitions[mbr_idx].type = sd_fs.fs_type == FS_EXFAT ? 0x7 : 0xC;
mbr[1].partitions[mbr_idx].start_sct = part->lba_start;
mbr[1].partitions[mbr_idx].size_sct = (part->lba_end - part->lba_start + 1);
mbr_idx++;
mbr[1].partitions[0].type = sd_fs.fs_type == FS_EXFAT ? 0x7 : 0xC;
mbr[1].partitions[0].start_sct = part->lba_start;
mbr[1].partitions[0].size_sct = (part->lba_end - part->lba_start + 1);
}
// FatFS simple GPT didn't find a fat partition as the first one.
if (!sd_fs.part_type && !found_hos_data && !strcmp(part->name, "hos_data"))
{
mbr[1].partitions[0].type = 0xC;
mbr[1].partitions[0].start_sct = part->lba_start;
mbr[1].partitions[0].size_sct = (part->lba_end - part->lba_start + 1);
found_hos_data = true;
}
// Set up to max 2 emuMMC partitions.
if (!strcmp(part->name, "emummc") || !strcmp(part->name, "emummc2"))
{
mbr[1].partitions[mbr_idx].type = 0xE0;
@@ -2093,11 +2120,15 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
mbr_idx++;
}
if (mbr_idx > 2)
// Total reached last slot.
if (mbr_idx >= 3)
break;
}
mbr[1].partitions[mbr_idx].type = 0xEE; // GPT protective partition.
nx_emmc_gpt_free(&gpt_parsed);
// Set GPT protective partition.
mbr[1].partitions[mbr_idx].type = 0xEE;
mbr[1].partitions[mbr_idx].start_sct = 1;
mbr[1].partitions[mbr_idx].size_sct = sd_storage.sec_cnt - 1;
@@ -2264,6 +2295,11 @@ lv_res_t create_window_partition_manager(lv_obj_t *btn)
char *txt_buf = malloc(0x2000);
part_info.total_sct = sd_storage.sec_cnt;
// Align down total size to ensure alignment of all partitions after HOS one.
part_info.alignment = part_info.total_sct - ALIGN_DOWN(part_info.total_sct, 0x8000);
part_info.total_sct -= part_info.alignment;
u32 extra_sct = 0x8000 + 0x400000; // Reserved 16MB alignment for FAT partition + 2GB.
// Set initial HOS partition size, so the correct cluster size can be selected.

View File

@@ -207,6 +207,21 @@ void gfx_putc(char c)
cbuf++;
}
gfx_con.x += 16;
if (gfx_con.x > gfx_ctxt.width - 16)
{
gfx_con.x = gfx_column;
gfx_con.y += 16;
if (gfx_con.y > gfx_ctxt.height - 33)
{
gfx_con.y = 0;
if (!gfx_column)
gfx_column = 640;
else
gfx_column = 0;
gfx_con.x = gfx_column;
}
}
}
else if (c == '\n')
{
@@ -243,6 +258,21 @@ void gfx_putc(char c)
}
}
gfx_con.x += 8;
if (gfx_con.x > gfx_ctxt.width / 2 + gfx_column - 8)
{
gfx_con.x = gfx_column;
gfx_con.y += 8;
if (gfx_con.y > gfx_ctxt.height - 33)
{
gfx_con.y = 0;
if (!gfx_column)
gfx_column = 640;
else
gfx_column = 0;
gfx_con.x = gfx_column;
}
}
}
else if (c == '\n')
{

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@ static const u8 sec_map_100[3] = { PK11_SECTION_SM, PK11_SECTION_LD, PK11_SECTIO
static const u8 sec_map_2xx[3] = { PK11_SECTION_WB, PK11_SECTION_LD, PK11_SECTION_SM };
static const u8 sec_map_4xx[3] = { PK11_SECTION_LD, PK11_SECTION_SM, PK11_SECTION_WB };
// ID (Timestamp), KB, TSEC, PK11, SECMON, Warmboot.
static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0, 0x1900, 0x3FE0, 0x40014020, 0x8000D000 }, // 1.0.0.
{ "20170210155124", 0, 0x1900, 0x3FE0, 0x4002D000, 0x8000D000 }, // 2.0.0 - 2.3.0.
@@ -57,8 +58,9 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20190809135709", 9, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 9.0.0 - 9.0.1.
{ "20191021113848", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 9.1.0 - 9.2.0.
{ "20200303104606", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 10.0.0 - 10.2.0.
{ "20201030110855", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 11.0.0+
{ NULL } //End.
{ "20201030110855", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 11.0.0 - 11.0.1.
{ "20210129111626", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 12.0.0 - 12.0.1.
{ "20210422145837", 10, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 12.0.2+
};
const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date)
@@ -69,7 +71,7 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date)
build_date[14] = 0;
}
for (u32 i = 0; _pkg1_ids[i].id; i++)
for (u32 i = 0; i < ARRAY_SIZE(_pkg1_ids); i++)
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 8))
return &_pkg1_ids[i];
return NULL;
@@ -77,13 +79,13 @@ const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date)
int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
{
// Decrypt package1.
pk11_hdr_t *hdr;
u8 *pkg11 = pkg1 + id->pkg11_off;
u32 pkg11_size = *(u32 *)pkg11;
// Decrypt package1.
if (!h_cfg.t210b01)
{
u8 *pkg11 = pkg1 + id->pkg11_off;
u32 pkg11_size = *(u32 *)pkg11;
hdr = (pk11_hdr_t *)(pkg11 + 0x20);
se_aes_crypt_ctr(11, hdr, pkg11_size, hdr, pkg11_size, pkg11 + 0x10);
}

View File

@@ -5,7 +5,7 @@ SECTIONS {
. = __ipl_start;
.text : {
*(.text._start);
*(._ipl_version);
KEEP(*(._ipl_version));
*(.text._irq_setup);
*(.text*);
}

View File

@@ -292,8 +292,8 @@ void load_saved_configuration()
n_cfg.ums_emmc_rw = atoi(kv->val) == 1;
else if (!strcmp("jcdisable", kv->key))
n_cfg.jc_disable = atoi(kv->val) == 1;
else if (!strcmp("newpowersave", kv->key))
n_cfg.new_powersave = atoi(kv->val) == 1;
else if (!strcmp("bpmpclock", kv->key))
n_cfg.bpmp_clock = strtol(kv->val, NULL, 10);
}
break;
@@ -361,7 +361,9 @@ void nyx_init_load_res()
{
bpmp_mmu_enable();
bpmp_clk_rate_get();
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
// Set a modest clock for init. It will be restored later if possible.
bpmp_clk_rate_set(BPMP_CLK_LOWER_BOOST);
// Set bootloader's default configuration.
set_default_configuration();
@@ -395,6 +397,19 @@ void nyx_init_load_res()
load_saved_configuration();
// Initialize nyx cfg to lower clock for T210.
// In case of lower binned SoC, this can help with hangs.
if (!n_cfg.bpmp_clock)
{
n_cfg.bpmp_clock = h_cfg.t210b01 ? 1 : 2; // Set lower clock for T210.
create_nyx_config_entry(false);
n_cfg.bpmp_clock = h_cfg.t210b01 ? 1 : 0; // Restore for T210 and keep for T210B01.
}
// Restore clock to max.
if (n_cfg.bpmp_clock < 2)
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
FIL fp;
if (!f_open(&fp, "bootloader/sys/res.pak", FA_READ))
{

View File

@@ -33,6 +33,10 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
sdmmc_storage_read(storage, NX_GPT_FIRST_LBA, NX_GPT_NUM_BLOCKS, gpt_buf);
// Check if no GPT or more than max allowed entries.
if (memcmp(&gpt_buf->header.signature, "EFI PART", 8) || gpt_buf->header.num_part_ents > 128)
goto out;
for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++)
{
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1);
@@ -53,6 +57,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
list_append(gpt, &part->link);
}
out:
free(gpt_buf);
}

View File

@@ -65,6 +65,11 @@ bool sd_get_card_initialized()
return sd_init_done;
}
bool sd_get_card_mounted()
{
return sd_mounted;
}
u32 sd_get_mode()
{
return sd_mode;
@@ -197,6 +202,11 @@ static void _sd_deinit(bool deinit)
void sd_unmount() { _sd_deinit(false); }
void sd_end() { _sd_deinit(true); }
bool sd_is_gpt()
{
return sd_fs.part_type;
}
void *sd_file_read(const char *path, u32 *fsize)
{
FIL fp;

View File

@@ -9,7 +9,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
@@ -34,32 +33,39 @@ main ( int argc, char* argv[] )
{
unsigned char buf[BUFSIZ];
char* ident;
int fd, i, total, rd, need_comma;
FILE *fd;
size_t size, i, total, blksize = BUFSIZ;
int need_comma = 0;
if ( argc < 2 )
if ( argc != 2 )
{
fprintf ( stderr, "Usage: %s binary_file > output_file\n", argv[0] );
return -1;
}
fd = open ( argv[1], O_RDONLY );
if ( fd == -1 )
fd = fopen ( argv[1], "rb" );
if ( fd == NULL )
{
fprintf ( stderr, "%s: can't open %s for reading\n", argv[0], argv[1] );
return -1;
}
fseek(fd, 0, SEEK_END);
size = ftell(fd);
rewind(fd);
ident = make_ident ( argv[1] );
printf ( "static const unsigned char __attribute__((section (\"._%s\"))) %s[] = {", ident, ident );
for ( total = 0, need_comma = 0; ( rd = read ( fd, buf, BUFSIZ ) ) != 0; )
for ( total = 0; total < size; )
{
if ( rd == -1 )
if ( size - total < blksize ) blksize = size - total;
if ( fread ( buf, 1, blksize, fd ) != blksize )
{
fprintf ( stderr, "%s: file read error\n", argv[0] );
return -1;
}
for ( i = 0; i < rd; i++ )
for ( i = 0; i < blksize; i++ )
{
if ( need_comma ) printf ( ", " );
else need_comma = 1;
@@ -70,7 +76,7 @@ main ( int argc, char* argv[] )
}
printf ( "\n};\n" );
close ( fd );
fclose ( fd );
free ( ident );
return 0;