Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18cca6833e | ||
|
|
42f86cf82c | ||
|
|
a704679990 | ||
|
|
5876e1765d | ||
|
|
dcdf687a07 | ||
|
|
e94bd23d6f | ||
|
|
cd5b93feb1 | ||
|
|
f231173ebe | ||
|
|
561a96c62a | ||
|
|
57e6623d74 | ||
|
|
57623acc99 | ||
|
|
4f8d29d0b7 | ||
|
|
8eda2d805f | ||
|
|
432d4a4ffa | ||
|
|
539caf3d83 | ||
|
|
ce6926c36c | ||
|
|
8058d550ab | ||
|
|
9a21ff6976 | ||
|
|
1f4f41b6e6 | ||
|
|
a959196c2a | ||
|
|
3f22601022 | ||
|
|
a80a7ecba9 | ||
|
|
7c450f4a5f | ||
|
|
6316d3076d | ||
|
|
7181683d8e | ||
|
|
7d7134dd9e | ||
|
|
c29db97f73 | ||
|
|
05833bb38c | ||
|
|
253de81a6b | ||
|
|
21e6a0cf7e | ||
|
|
d0fefabad7 | ||
|
|
44db160ab1 | ||
|
|
cb633a8f32 | ||
|
|
66b7130641 | ||
|
|
80d9718770 | ||
|
|
dfbbca4c9f | ||
|
|
f4d08b2d9b | ||
|
|
588a834ae4 | ||
|
|
833dda7e7c | ||
|
|
6a4ab55930 | ||
|
|
d7ce2a81db | ||
|
|
4d90fa4830 | ||
|
|
501fdda138 | ||
|
|
678e8d34e3 | ||
|
|
07d1982abf | ||
|
|
fd05f83636 | ||
|
|
94e119fb51 | ||
|
|
c2ff4bf623 | ||
|
|
faf5651607 | ||
|
|
978e8344cf | ||
|
|
160d6eacc0 | ||
|
|
075d8e6393 | ||
|
|
28008ac7ac | ||
|
|
345d36287e | ||
|
|
edff6c551d | ||
|
|
d42a94f148 | ||
|
|
c01b8aa89c | ||
|
|
4958bd6a52 | ||
|
|
46038032a4 | ||
|
|
f66ddca100 | ||
|
|
6981c59de3 | ||
|
|
f21f13b15d | ||
|
|
ef5a01433d | ||
|
|
0e12d8545b | ||
|
|
9dbf745649 | ||
|
|
e8f73a42b8 | ||
|
|
dbe431095a | ||
|
|
513f77a2ad | ||
|
|
e8cf85bd65 | ||
|
|
be23d1fa15 | ||
|
|
4e7e5081a7 | ||
|
|
fff750e609 | ||
|
|
38ce46a158 | ||
|
|
7a27a7b3b5 |
5
Makefile
5
Makefile
@@ -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/*)
|
||||
|
||||
25
README.md
25
README.md
@@ -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. |
|
||||
@@ -99,6 +99,15 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| icon={SD path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise default will be used. |
|
||||
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
|
||||
|
||||
|
||||
### Boot entry key/value Exosphère combinations:
|
||||
|
||||
| Config option | Description |
|
||||
@@ -107,15 +116,13 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| userpmu=1 | Enables user access to PMU when paired with Exosphère. |
|
||||
| cal0blank=1 | Overrides Exosphère config `blank_prodinfo_{sys/emu}mmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| cal0writesys=1 | Overrides Exosphère config `allow_writing_to_cal_sysmmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| usb3force=1 | Overrides system settings mitm config `usb30_force_enabled`. If that key doesn't exist, `system_settings.ini` will be used. |
|
||||
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
**Note**: `cal0blank`, `cal0writesys`, `usb3force`, as stated override the `exosphere.ini` or `system_settings.ini`. 0: Disable, 1: Enable, Key Missing: Use original value.
|
||||
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Never define *fss0 core* kips when using `fss0` and make sure that the folder (when using `/*`), does not include them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
|
||||
**Note2**: `blank_prodinfo_{sys/emu}mmc`, `allow_writing_to_cal_sysmmc` and `usb30_force_enabled` in `exosphere.ini` and `system_settings.ini` respectively, are the only atmosphere config keys that can affect hekate booting configuration externally, **if** the equivalent keys in hekate config are missing.
|
||||
|
||||
|
||||
### Payload storage:
|
||||
@@ -139,9 +146,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.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# IPL Version.
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 5
|
||||
BLVERSION_HOTFX := 4
|
||||
BLVERSION_HOTFX := 8
|
||||
BLVERSION_RSVD := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 1
|
||||
NYXVERSION_MINOR := 0
|
||||
NYXVERSION_HOTFX := 0
|
||||
NYXVERSION_HOTFX := 5
|
||||
NYXVERSION_RSVD := 0
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
146
bdk/input/als.c
146
bdk/input/als.c
@@ -23,79 +23,117 @@
|
||||
#include <soc/pinmux.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define HOS_GAIN BH1730_GAIN_64X
|
||||
#define HOS_ITIME 38
|
||||
#define BH1730_DEFAULT_GAIN BH1730_GAIN_64X
|
||||
#define BH1730_DEFAULT_ICYCLE 38
|
||||
|
||||
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime)
|
||||
#define BH1730_INTERNAL_CLOCK_NS 2800
|
||||
#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */
|
||||
#define BH1730_ITIME_CYCLE_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */
|
||||
|
||||
#define BH1730_DEFAULT_ITIME_MS 100
|
||||
|
||||
#define BH1730_LUX_MULTIPLIER 3600
|
||||
#define BH1730_LUX_MULTIPLIER_AULA 1410
|
||||
|
||||
#define BH1730_LUX_MAX 100000
|
||||
|
||||
typedef struct _opt_win_cal_t
|
||||
{
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - itime));
|
||||
u32 rc;
|
||||
u32 cv;
|
||||
u32 ci;
|
||||
} opt_win_cal_t;
|
||||
|
||||
als_val->gain = gain;
|
||||
als_val->itime = itime;
|
||||
// Nintendo Switch Icosa/Iowa Optical Window calibration.
|
||||
const opt_win_cal_t opt_win_cal_default[] = {
|
||||
{ 500, 5002, 7502 },
|
||||
{ 754, 2250, 2000 },
|
||||
{ 1029, 1999, 1667 },
|
||||
{ 1373, 884, 583 },
|
||||
{ 1879, 309, 165 }
|
||||
};
|
||||
|
||||
// Nintendo Switch Aula Optical Window calibration.
|
||||
const opt_win_cal_t opt_win_cal_aula[] = {
|
||||
{ 231, 9697, 30300 },
|
||||
{ 993, 3333, 2778 },
|
||||
{ 1478, 1621, 1053 },
|
||||
{ 7500, 81, 10 }
|
||||
};
|
||||
|
||||
const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
|
||||
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
||||
{
|
||||
if (gain > BH1730_GAIN_128X)
|
||||
gain = BH1730_GAIN_128X;
|
||||
|
||||
if (!cycle)
|
||||
cycle = 1;
|
||||
else if (cycle > 255)
|
||||
cycle = 255;
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||
|
||||
als_ctxt->gain = gain;
|
||||
als_ctxt->cycle = cycle;
|
||||
}
|
||||
|
||||
void get_als_lux(als_table_t *als_val)
|
||||
void get_als_lux(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
u32 data[2];
|
||||
float pre_gain_lux;
|
||||
float visible_light;
|
||||
float ir_light;
|
||||
float light_ratio;
|
||||
u32 visible_light;
|
||||
u32 ir_light;
|
||||
u64 lux = 0;
|
||||
u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
|
||||
|
||||
u8 adc_ready = 0;
|
||||
u8 retries = 100;
|
||||
|
||||
const float als_gain_idx_tbl[4] = { 1.0, 2.0, 64.0, 128.0 };
|
||||
const float als_norm_res = 100.0;
|
||||
const float als_multiplier = 3.6;
|
||||
const float als_tint = 2.7;
|
||||
|
||||
// Wait for ADC to prepare new data.
|
||||
while (!(adc_ready & BH1730_CTL_ADC_VALID) && retries)
|
||||
{
|
||||
retries--;
|
||||
adc_ready = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG));
|
||||
}
|
||||
|
||||
// Get visible and ir light raw data.
|
||||
// Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter.
|
||||
data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
|
||||
data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
|
||||
|
||||
als_val->over_limit = data[0] > 65534 || data[1] > 65534;
|
||||
als_val->vi_light = data[0];
|
||||
als_val->ir_light = data[1];
|
||||
visible_light = data[0];
|
||||
ir_light = data[1];
|
||||
|
||||
if (!data[0] || !retries)
|
||||
als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534;
|
||||
als_ctxt->vi_light = visible_light;
|
||||
als_ctxt->ir_light = ir_light;
|
||||
|
||||
if (!visible_light)
|
||||
{
|
||||
als_val->lux = 0.0;
|
||||
als_ctxt->lux = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
visible_light = (float)data[0];
|
||||
ir_light = (float)data[1];
|
||||
light_ratio = (float)data[1] / (float)data[0];
|
||||
// Set calibration parameters.
|
||||
u32 lux_multiplier = BH1730_LUX_MULTIPLIER;
|
||||
u32 opt_win_cal_count = ARRAY_SIZE(opt_win_cal_default);
|
||||
const opt_win_cal_t *opt_win_cal = opt_win_cal_default;
|
||||
|
||||
// The following are specific to the light filter Switch uses.
|
||||
if (light_ratio < 0.5)
|
||||
pre_gain_lux = visible_light * 5.002 - ir_light * 7.502;
|
||||
else if (light_ratio < 0.754)
|
||||
pre_gain_lux = visible_light * 2.250 - ir_light * 2.000;
|
||||
else if (light_ratio < 1.029)
|
||||
pre_gain_lux = visible_light * 1.999 - ir_light * 1.667;
|
||||
else if (light_ratio < 1.373)
|
||||
pre_gain_lux = visible_light * 0.884 - ir_light * 0.583;
|
||||
else if (light_ratio < 1.879)
|
||||
pre_gain_lux = visible_light * 0.309 - ir_light * 0.165;
|
||||
else pre_gain_lux = 0.0;
|
||||
// Apply optical window calibration coefficients.
|
||||
for (u32 i = 0; i < opt_win_cal_count; i++)
|
||||
{
|
||||
if (1000 * ir_light / visible_light < opt_win_cal[i].rc)
|
||||
{
|
||||
lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
als_val->lux = (pre_gain_lux / als_gain_idx_tbl[als_val->gain]) * (als_norm_res / ((float)als_val->itime * als_tint)) * als_multiplier;
|
||||
lux *= BH1730_DEFAULT_ITIME_MS * lux_multiplier;
|
||||
lux /= als_gain_idx_tbl[als_ctxt->gain] * itime_us;
|
||||
lux /= 1000;
|
||||
|
||||
if (lux > BH1730_LUX_MAX)
|
||||
lux = BH1730_LUX_MAX;
|
||||
|
||||
als_ctxt->lux = lux;
|
||||
}
|
||||
|
||||
u8 als_init(als_table_t *als_val)
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
// Enable power to ALS IC.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
@@ -109,12 +147,10 @@ u8 als_init(als_table_t *als_val)
|
||||
// Initialize ALS.
|
||||
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), HOS_GAIN);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - HOS_ITIME));
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
|
||||
|
||||
als_val->gain = HOS_GAIN;
|
||||
als_val->itime = HOS_ITIME;
|
||||
set_als_cfg(als_ctxt, BH1730_DEFAULT_GAIN, BH1730_DEFAULT_ICYCLE);
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -48,18 +48,18 @@
|
||||
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg))
|
||||
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd))
|
||||
|
||||
typedef struct _als_table_t
|
||||
typedef struct _als_ctxt_t
|
||||
{
|
||||
float lux;
|
||||
u32 lux;
|
||||
bool over_limit;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 itime;
|
||||
} als_table_t;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 cycle;
|
||||
} als_ctxt_t;
|
||||
|
||||
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime);
|
||||
void get_als_lux(als_table_t *als_val);
|
||||
u8 als_init(als_table_t *als_val);
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle);
|
||||
void get_als_lux(als_ctxt_t *als_ctxt);
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt);
|
||||
|
||||
#endif /* __ALS_H_ */
|
||||
|
||||
@@ -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);
|
||||
@@ -694,9 +694,15 @@ retry:
|
||||
|
||||
void jc_deinit()
|
||||
{
|
||||
// Disable power.
|
||||
jc_power_supply(UART_B, false);
|
||||
jc_power_supply(UART_C, false);
|
||||
|
||||
// Turn off Joy-Con detect.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
// Send sleep command.
|
||||
u8 data = HCI_STATE_SLEEP;
|
||||
|
||||
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
||||
@@ -710,8 +716,9 @@ void jc_deinit()
|
||||
jc_rcv_pkt(&jc_l);
|
||||
}
|
||||
|
||||
jc_power_supply(UART_B, false);
|
||||
jc_power_supply(UART_C, false);
|
||||
// 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)
|
||||
@@ -878,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -491,8 +491,8 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
|
||||
/* DRAM size information */
|
||||
.mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
|
||||
.mc_emem_adr_cfg_dev0 = 0x00070302, // Rank 0 Density 512MB.
|
||||
.mc_emem_adr_cfg_dev1 = 0x00070302, // Rank 1 Density 512MB.
|
||||
.mc_emem_adr_cfg_dev0 = 0x00080302, // Rank 0 Density 1024MB.
|
||||
.mc_emem_adr_cfg_dev1 = 0x00080302, // Rank 1 Density 1024MB.
|
||||
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
|
||||
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
|
||||
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
|
||||
@@ -501,7 +501,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
*/
|
||||
.mc_emem_cfg = 0x00001000, // 4GB total density.
|
||||
.mc_emem_cfg = 0x00002000, // 8GB total density.
|
||||
|
||||
/* MC arbitration configuration */
|
||||
.mc_emem_arb_cfg = 0x08000001,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -21,25 +21,25 @@
|
||||
#include <utils/types.h>
|
||||
|
||||
static u8 reg_5v_dev = 0;
|
||||
static bool batt_src = false;
|
||||
static bool usb_src = false;
|
||||
|
||||
void regulator_5v_enable(u8 dev)
|
||||
{
|
||||
// The power supply selection from battery or USB is automatic.
|
||||
if (!reg_5v_dev)
|
||||
{
|
||||
// Fan and Rail power from internal 5V regulator (battery).
|
||||
// Fan and Rail power from battery 5V regulator.
|
||||
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1;
|
||||
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||
batt_src = true;
|
||||
|
||||
// Fan and Rail power from USB 5V VDD.
|
||||
// Fan and Rail power from USB 5V VBUS.
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
usb_src = false;
|
||||
|
||||
// Make sure GPIO power is enabled.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN;
|
||||
@@ -55,18 +55,18 @@ void regulator_5v_disable(u8 dev)
|
||||
|
||||
if (!reg_5v_dev)
|
||||
{
|
||||
// Rail power from internal 5V regulator (battery).
|
||||
// Rail power from battery 5V regulator.
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
|
||||
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_DISABLE);
|
||||
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_SPIO);
|
||||
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = PINMUX_PARKED | PINMUX_INPUT_ENABLE;
|
||||
batt_src = false;
|
||||
|
||||
// Rail power from USB 5V VDD.
|
||||
// Rail power from USB 5V VBUS.
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_SPIO);
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_PARKED | PINMUX_INPUT_ENABLE;
|
||||
usb_src = false;
|
||||
|
||||
// GPIO AO IO rails.
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_GPIO_IO_EN;
|
||||
@@ -78,10 +78,16 @@ bool regulator_5v_get_dev_enabled(u8 dev)
|
||||
return (reg_5v_dev & dev);
|
||||
}
|
||||
|
||||
void regulator_5v_batt_src_enable(bool enable)
|
||||
void regulator_5v_usb_src_enable(bool enable)
|
||||
{
|
||||
if (enable && !batt_src)
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||
else if (!enable && batt_src)
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
|
||||
if (enable && !usb_src)
|
||||
{
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
|
||||
usb_src = true;
|
||||
}
|
||||
else if (!enable && usb_src)
|
||||
{
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
usb_src = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,6 @@ enum
|
||||
void regulator_5v_enable(u8 dev);
|
||||
void regulator_5v_disable(u8 dev);
|
||||
bool regulator_5v_get_dev_enabled(u8 dev);
|
||||
void regulator_5v_batt_src_enable(bool enable);
|
||||
void regulator_5v_usb_src_enable(bool enable);
|
||||
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -121,18 +121,6 @@ u32 fuse_read_hw_type()
|
||||
return FUSE_NX_HW_TYPE_ICOSA;
|
||||
}
|
||||
|
||||
u8 fuse_count_burnt(u32 val)
|
||||
{
|
||||
u8 burnt_fuses = 0;
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
if ((val >> i) & 1)
|
||||
burnt_fuses++;
|
||||
}
|
||||
|
||||
return burnt_fuses;
|
||||
}
|
||||
|
||||
void fuse_wait_idle()
|
||||
{
|
||||
u32 ctrl;
|
||||
|
||||
@@ -97,7 +97,6 @@ u32 fuse_read_odm_keygen_rev();
|
||||
u32 fuse_read_dramid(bool raw_id);
|
||||
u32 fuse_read_hw_state();
|
||||
u32 fuse_read_hw_type();
|
||||
u8 fuse_count_burnt(u32 val);
|
||||
void fuse_wait_idle();
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Header for MultiMediaCard (MMC)
|
||||
*
|
||||
* Copyright 2002 Hewlett-Packard Company
|
||||
* Copyright 2018-2021 CTCaer
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
@@ -21,8 +22,8 @@
|
||||
* 15 May 2002
|
||||
*/
|
||||
|
||||
#ifndef LINUX_MMC_MMC_H
|
||||
#define LINUX_MMC_MMC_H
|
||||
#ifndef MMC_H
|
||||
#define MMC_H
|
||||
|
||||
/* Standard MMC commands (4.1) type argument response */
|
||||
/* class 1 */
|
||||
@@ -97,29 +98,29 @@
|
||||
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
||||
|
||||
/*
|
||||
* MMC_SWITCH argument format:
|
||||
*
|
||||
* [31:26] Always 0
|
||||
* [25:24] Access Mode
|
||||
* [23:16] Location of target Byte in EXT_CSD
|
||||
* [15:08] Value Byte
|
||||
* [07:03] Always 0
|
||||
* [02:00] Command Set
|
||||
*/
|
||||
* MMC_SWITCH argument format:
|
||||
*
|
||||
* [31:26] Always 0
|
||||
* [25:24] Access Mode
|
||||
* [23:16] Location of target Byte in EXT_CSD
|
||||
* [15:08] Value Byte
|
||||
* [07:03] Always 0
|
||||
* [02:00] Command Set
|
||||
*/
|
||||
|
||||
/*
|
||||
MMC status in R1, for native mode (SPI bits are different)
|
||||
Type
|
||||
e : error bit
|
||||
s : status bit
|
||||
r : detected and set for the actual command response
|
||||
x : detected and set during command execution. the host must poll
|
||||
the card by sending status command in order to read these bits.
|
||||
Clear condition
|
||||
a : according to the card state
|
||||
b : always related to the previous command. Reception of
|
||||
a valid command will clear it (with a delay of one command)
|
||||
c : clear by read
|
||||
* MMC status in R1, for native mode (SPI bits are different)
|
||||
* Type
|
||||
* e : error bit
|
||||
* s : status bit
|
||||
* r : detected and set for the actual command response
|
||||
* x : detected and set during command execution. the host must poll
|
||||
* the card by sending status command in order to read these bits.
|
||||
* Clear condition
|
||||
* a : according to the card state
|
||||
* b : always related to the previous command. Reception of a valid
|
||||
* command will clear it (with a delay of one command)
|
||||
* c : clear by read
|
||||
*/
|
||||
|
||||
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
|
||||
@@ -151,6 +152,7 @@ c : clear by read
|
||||
#define R1_AKE_SEQ_ERROR (1 << 3)
|
||||
|
||||
/* R1_CURRENT_STATE 12:9 */
|
||||
#define R1_STATE(x) ((x) << 9)
|
||||
#define R1_STATE_IDLE 0
|
||||
#define R1_STATE_READY 1
|
||||
#define R1_STATE_IDENT 2
|
||||
@@ -162,9 +164,9 @@ c : clear by read
|
||||
#define R1_STATE_DIS 8
|
||||
|
||||
/*
|
||||
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
|
||||
* R1 is the low order byte; R2 is the next highest byte, when present.
|
||||
*/
|
||||
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
|
||||
* R1 is the low order byte; R2 is the next highest byte, when present.
|
||||
*/
|
||||
#define R1_SPI_IDLE (1 << 0)
|
||||
#define R1_SPI_ERASE_RESET (1 << 1)
|
||||
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
|
||||
@@ -185,16 +187,16 @@ c : clear by read
|
||||
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
|
||||
|
||||
/*
|
||||
* OCR bits are mostly in host.h
|
||||
*/
|
||||
* OCR bits are mostly in host.h
|
||||
*/
|
||||
#define MMC_CARD_VDD_18 (1 << 7) /* Card VDD voltage 1.8 */
|
||||
#define MMC_CARD_VDD_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */
|
||||
#define MMC_CARD_CCS (1 << 30) /* Card Capacity status bit */
|
||||
#define MMC_CARD_BUSY (1 << 31) /* Card Power up status bit */
|
||||
|
||||
/*
|
||||
* Card Command Classes (CCC)
|
||||
*/
|
||||
* Card Command Classes (CCC)
|
||||
*/
|
||||
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
|
||||
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
|
||||
/* (and for SPI, CMD58,59) */
|
||||
@@ -222,8 +224,8 @@ c : clear by read
|
||||
/* (CMD?) */
|
||||
|
||||
/*
|
||||
* CSD field definitions
|
||||
*/
|
||||
* CSD field definitions
|
||||
*/
|
||||
|
||||
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
|
||||
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
|
||||
@@ -237,8 +239,8 @@ c : clear by read
|
||||
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
|
||||
|
||||
/*
|
||||
* EXT_CSD fields
|
||||
*/
|
||||
* EXT_CSD fields
|
||||
*/
|
||||
|
||||
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
|
||||
#define EXT_CSD_FLUSH_CACHE 32 /* W */
|
||||
@@ -316,8 +318,8 @@ c : clear by read
|
||||
#define EXT_CSD_HPI_FEATURES 503 /* RO */
|
||||
|
||||
/*
|
||||
* EXT_CSD field definitions
|
||||
*/
|
||||
* EXT_CSD field definitions
|
||||
*/
|
||||
|
||||
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
|
||||
|
||||
@@ -393,8 +395,8 @@ c : clear by read
|
||||
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
|
||||
|
||||
/*
|
||||
* EXCEPTION_EVENT_STATUS field
|
||||
*/
|
||||
* EXCEPTION_EVENT_STATUS field
|
||||
*/
|
||||
#define EXT_CSD_URGENT_BKOPS (1<<0)
|
||||
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
|
||||
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
|
||||
@@ -404,34 +406,34 @@ c : clear by read
|
||||
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
|
||||
|
||||
/*
|
||||
* BKOPS status level
|
||||
*/
|
||||
* BKOPS status level
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_LEVEL_2 0x2
|
||||
|
||||
/*
|
||||
* BKOPS modes
|
||||
*/
|
||||
* BKOPS modes
|
||||
*/
|
||||
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
|
||||
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
|
||||
|
||||
/*
|
||||
* Command Queue
|
||||
*/
|
||||
* Command Queue
|
||||
*/
|
||||
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
|
||||
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
|
||||
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
|
||||
|
||||
/*
|
||||
* MMC_SWITCH access modes
|
||||
*/
|
||||
* MMC_SWITCH access modes
|
||||
*/
|
||||
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
|
||||
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
|
||||
|
||||
/*
|
||||
* Erase/trim/discard
|
||||
*/
|
||||
* Erase/trim/discard
|
||||
*/
|
||||
#define MMC_ERASE_ARG 0x00000000
|
||||
#define MMC_SECURE_ERASE_ARG 0x80000000
|
||||
#define MMC_TRIM_ARG 0x00000001
|
||||
@@ -441,4 +443,9 @@ c : clear by read
|
||||
#define MMC_SECURE_ARGS 0x80000000
|
||||
#define MMC_TRIM_ARGS 0x00008001
|
||||
|
||||
#endif /* LINUX_MMC_MMC_H */
|
||||
/*
|
||||
* Vendor definitions and structs
|
||||
*/
|
||||
#define MMC_SANDISK_HEALTH_REPORT 0x96C9D71C
|
||||
|
||||
#endif /* MMC_H */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -139,6 +139,60 @@ static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
|
||||
return _sdmmc_storage_get_status(storage, &tmp, 0);
|
||||
}
|
||||
|
||||
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
|
||||
{
|
||||
sdmmc_cmd_t cmdbuf;
|
||||
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_62_CMD, arg, SDMMC_RSP_TYPE_1, 1);
|
||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))
|
||||
return 0;
|
||||
|
||||
u32 resp;
|
||||
sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_1);
|
||||
|
||||
resp = -1;
|
||||
u32 timeout = get_tmr_ms() + 1500;
|
||||
while (resp != (R1_READY_FOR_DATA | R1_STATE(R1_STATE_TRAN)))
|
||||
{
|
||||
_sdmmc_storage_get_status(storage, &resp, 0);
|
||||
|
||||
if (get_tmr_ms() > timeout)
|
||||
break;
|
||||
}
|
||||
|
||||
return _sdmmc_storage_check_card_status(resp);
|
||||
}
|
||||
|
||||
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
|
||||
{
|
||||
// Request health report.
|
||||
if (!sdmmc_storage_execute_vendor_cmd(storage, MMC_SANDISK_HEALTH_REPORT))
|
||||
return 2;
|
||||
|
||||
u32 tmp = 0;
|
||||
sdmmc_cmd_t cmdbuf;
|
||||
sdmmc_req_t reqbuf;
|
||||
|
||||
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_63_CMD, 0, SDMMC_RSP_TYPE_1, 0); // similar to CMD17 with arg 0x0.
|
||||
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.num_sectors = 1;
|
||||
reqbuf.blksize = 512;
|
||||
reqbuf.is_write = 0;
|
||||
reqbuf.is_multi_block = 0;
|
||||
reqbuf.is_auto_stop_trn = 0;
|
||||
|
||||
u32 blkcnt_out;
|
||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, &blkcnt_out))
|
||||
{
|
||||
sdmmc_stop_transmission(storage->sdmmc, &tmp);
|
||||
_sdmmc_storage_get_status(storage, &tmp, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
@@ -1360,8 +1414,6 @@ DPRINTF("[SD] SD does not support wide bus width\n");
|
||||
if (!_sd_storage_enable_uhs_low_volt(storage, type, buf))
|
||||
return 0;
|
||||
DPRINTF("[SD] enabled UHS\n");
|
||||
|
||||
sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE);
|
||||
}
|
||||
else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default speed and not SD Version 1.0.
|
||||
{
|
||||
@@ -1387,6 +1439,8 @@ DPRINTF("[SD] enabled HS\n");
|
||||
DPRINTF("[SD] got sd status\n");
|
||||
}
|
||||
|
||||
sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE);
|
||||
|
||||
storage->initialized = 1;
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -34,6 +34,81 @@ typedef enum _sdmmc_type
|
||||
EMMC_RPMB = 3
|
||||
} sdmmc_type;
|
||||
|
||||
typedef struct _mmc_sandisk_advanced_report_t
|
||||
{
|
||||
u32 power_inits;
|
||||
|
||||
u32 max_erase_cycles_sys;
|
||||
u32 max_erase_cycles_slc;
|
||||
u32 max_erase_cycles_mlc;
|
||||
|
||||
u32 min_erase_cycles_sys;
|
||||
u32 min_erase_cycles_slc;
|
||||
u32 min_erase_cycles_mlc;
|
||||
|
||||
u32 max_erase_cycles_euda;
|
||||
u32 min_erase_cycles_euda;
|
||||
u32 avg_erase_cycles_euda;
|
||||
u32 read_reclaim_cnt_euda;
|
||||
u32 bad_blocks_euda;
|
||||
|
||||
u32 pre_eol_euda;
|
||||
u32 pre_eol_sys;
|
||||
u32 pre_eol_mlc;
|
||||
|
||||
u32 uncorrectable_ecc;
|
||||
|
||||
u32 temperature_now;
|
||||
u32 temperature_min;
|
||||
u32 temperature_max;
|
||||
|
||||
u32 health_pct_euda;
|
||||
u32 health_pct_sys;
|
||||
u32 health_pct_mlc;
|
||||
|
||||
u32 unk0;
|
||||
u32 unk1;
|
||||
u32 unk2;
|
||||
|
||||
u32 reserved[78];
|
||||
} mmc_sandisk_advanced_report_t;
|
||||
|
||||
typedef struct _mmc_sandisk_report_t
|
||||
{
|
||||
u32 avg_erase_cycles_sys;
|
||||
u32 avg_erase_cycles_slc;
|
||||
u32 avg_erase_cycles_mlc;
|
||||
|
||||
u32 read_reclaim_cnt_sys;
|
||||
u32 read_reclaim_cnt_slc;
|
||||
u32 read_reclaim_cnt_mlc;
|
||||
|
||||
u32 bad_blocks_factory;
|
||||
u32 bad_blocks_sys;
|
||||
u32 bad_blocks_slc;
|
||||
u32 bad_blocks_mlc;
|
||||
|
||||
u32 fw_updates_cnt;
|
||||
|
||||
u8 fw_update_date[12];
|
||||
u8 fw_update_time[8];
|
||||
|
||||
u32 total_writes_100mb;
|
||||
u32 vdrops;
|
||||
u32 vdroops;
|
||||
|
||||
u32 vdrops_failed_data_rec;
|
||||
u32 vdrops_data_rec_ops;
|
||||
|
||||
u32 total_writes_slc_100mb;
|
||||
u32 total_writes_mlc_100mb;
|
||||
|
||||
u32 mlc_bigfile_mode_limit_exceeded;
|
||||
u32 avg_erase_cycles_hybrid;
|
||||
|
||||
mmc_sandisk_advanced_report_t advanced;
|
||||
} mmc_sandisk_report_t;
|
||||
|
||||
typedef struct _mmc_cid
|
||||
{
|
||||
u32 manfid;
|
||||
@@ -131,6 +206,9 @@ void sdmmc_storage_init_wait_sd();
|
||||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type);
|
||||
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
|
||||
|
||||
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
|
||||
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
|
||||
|
||||
int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf);
|
||||
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -30,6 +30,27 @@
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
u8 bit_count(u32 val)
|
||||
{
|
||||
u8 cnt = 0;
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
if ((val >> i) & 1)
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
u32 bit_count_mask(u8 bits)
|
||||
{
|
||||
u32 val = 0;
|
||||
for (u32 i = 0; i < bits; i++)
|
||||
val |= 1 << i;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
u32 get_tmr_s()
|
||||
{
|
||||
return RTC(APBDEV_RTC_SECONDS);
|
||||
|
||||
@@ -84,6 +84,9 @@ typedef struct _nyx_storage_t
|
||||
emc_table_t mtc_table[10];
|
||||
} nyx_storage_t;
|
||||
|
||||
u8 bit_count(u32 val);
|
||||
u32 bit_count_mask(u8 bits);
|
||||
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ void print_fuseinfo()
|
||||
break;
|
||||
}
|
||||
gfx_printf("Sdram ID: %d\n", fuse_read_dramid(true));
|
||||
gfx_printf("Burnt fuses: %d / 64\n", fuse_count_burnt(fuse_read_odm(7)));
|
||||
gfx_printf("Burnt fuses: %d / 64\n", bit_count(fuse_read_odm(7)));
|
||||
gfx_printf("Secure key: %08X%08X%08X%08X\n\n\n",
|
||||
byte_swap_32(FUSE(FUSE_PRIVATE_KEY0)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY1)),
|
||||
byte_swap_32(FUSE(FUSE_PRIVATE_KEY2)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY3)));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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--;
|
||||
@@ -149,25 +159,12 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
|
||||
// Check if valid FSS0 and parse it.
|
||||
if (fss_meta->magic == FSS0_MAGIC)
|
||||
{
|
||||
bool mariko_not_supported = false;
|
||||
if (h_cfg.t210b01 && (fss_meta->version < FSS0_VERSION_0_17_0))
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
mariko_not_supported = true;
|
||||
}
|
||||
|
||||
gfx_printf("Found FSS0, Atmosphere %d.%d.%d-%08x\n"
|
||||
"Max HOS supported: %d.%d.%d\n"
|
||||
"Unpacking and loading components.. ",
|
||||
fss_meta->version >> 24, (fss_meta->version >> 16) & 0xFF, (fss_meta->version >> 8) & 0xFF, fss_meta->git_rev,
|
||||
fss_meta->hos_ver >> 24, (fss_meta->hos_ver >> 16) & 0xFF, (fss_meta->hos_ver >> 8) & 0xFF);
|
||||
|
||||
if (mariko_not_supported)
|
||||
{
|
||||
EPRINTF("\nMariko not supported on < 0.17.0!");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!sept_ctxt)
|
||||
{
|
||||
ctxt->atmosphere = true;
|
||||
@@ -264,12 +261,11 @@ out:
|
||||
gfx_printf("Done!\n");
|
||||
f_close(&fp);
|
||||
|
||||
_update_r2p(path);
|
||||
_update_r2p(ctxt, path);
|
||||
|
||||
return (!sept_ctxt ? 1 : sept_used);
|
||||
}
|
||||
|
||||
fail:
|
||||
f_close(&fp);
|
||||
free(fss);
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ static const u8 master_kekseed_t210b01[][SE_KEY_128_SIZE] = {
|
||||
{ 0x5C, 0x24, 0xE3, 0xB8, 0xB4, 0xF7, 0x00, 0xC2, 0x3C, 0xFD, 0x0A, 0xCE, 0x13, 0xC3, 0xDC, 0x23 }, // 8.1.0.
|
||||
{ 0x86, 0x69, 0xF0, 0x09, 0x87, 0xC8, 0x05, 0xAE, 0xB5, 0x7B, 0x48, 0x74, 0xDE, 0x62, 0xA6, 0x13 }, // 9.0.0.
|
||||
{ 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82 }, // 9.1.0.
|
||||
{ 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1 }, // 12.1.0.
|
||||
};
|
||||
|
||||
static const u8 console_keyseed[SE_KEY_128_SIZE] =
|
||||
@@ -546,7 +547,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos
|
||||
{
|
||||
switch (kb)
|
||||
{
|
||||
case KB_FIRMWARE_VERSION_100_200:
|
||||
case KB_FIRMWARE_VERSION_100:
|
||||
case KB_FIRMWARE_VERSION_300:
|
||||
case KB_FIRMWARE_VERSION_301:
|
||||
se_aes_unwrap_key(13, 15, console_keyseed);
|
||||
@@ -609,7 +610,7 @@ try_load:
|
||||
// Try backup bootloader.
|
||||
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
|
||||
{
|
||||
EPRINTF("Trying backup bootloader...");
|
||||
EPRINTF("\nTrying backup bootloader...");
|
||||
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
|
||||
goto try_load;
|
||||
}
|
||||
@@ -684,7 +685,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))
|
||||
@@ -788,8 +789,9 @@ int hos_launch(ini_sec_t *cfg)
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Check if fuses lower than 4.0.0 or 9.0.0 or 11.0.0 and if yes apply NO Gamecard patch.
|
||||
// Additionally check if running emuMMC and disable GC if v3/v4 fuses are burnt and HOS is <= 8.1.0 or != 11.0.0.
|
||||
// If Auto NOGC is enabled, check if burnt fuses lower than installed HOS fuses and apply NOGC patch.
|
||||
// For emuMMC, unconditionally enable NOGC when burnt fuses are higher than installed HOS fuses.
|
||||
// Disable Auto NOGC in stock to prevent black screen (fatal error). Use kip1patch=nogc to force it.
|
||||
if (!ctxt.stock)
|
||||
{
|
||||
u32 fuses = fuse_read_odm(7);
|
||||
@@ -797,13 +799,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 12.0.2+ fuses burnt.
|
||||
)
|
||||
))
|
||||
config_kip1patch(&ctxt, "nogc");
|
||||
@@ -1053,7 +1059,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||
// Finalize per firmware key access. Skip access control if new exosphere.
|
||||
switch (kb | (exo_new << 7))
|
||||
{
|
||||
case KB_FIRMWARE_VERSION_100_200:
|
||||
case KB_FIRMWARE_VERSION_100:
|
||||
case KB_FIRMWARE_VERSION_300:
|
||||
case KB_FIRMWARE_VERSION_301:
|
||||
se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_LOCK_FLAG);
|
||||
@@ -1140,6 +1146,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();
|
||||
|
||||
|
||||
@@ -27,18 +27,19 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define KB_FIRMWARE_VERSION_100_200 0
|
||||
#define KB_FIRMWARE_VERSION_300 1
|
||||
#define KB_FIRMWARE_VERSION_301 2
|
||||
#define KB_FIRMWARE_VERSION_400 3
|
||||
#define KB_FIRMWARE_VERSION_500 4
|
||||
#define KB_FIRMWARE_VERSION_600 5
|
||||
#define KB_FIRMWARE_VERSION_620 6
|
||||
#define KB_FIRMWARE_VERSION_700 7
|
||||
#define KB_FIRMWARE_VERSION_810 8
|
||||
#define KB_FIRMWARE_VERSION_900 9
|
||||
#define KB_FIRMWARE_VERSION_910 10
|
||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910
|
||||
#define KB_FIRMWARE_VERSION_100 0
|
||||
#define KB_FIRMWARE_VERSION_300 1
|
||||
#define KB_FIRMWARE_VERSION_301 2
|
||||
#define KB_FIRMWARE_VERSION_400 3
|
||||
#define KB_FIRMWARE_VERSION_500 4
|
||||
#define KB_FIRMWARE_VERSION_600 5
|
||||
#define KB_FIRMWARE_VERSION_620 6
|
||||
#define KB_FIRMWARE_VERSION_700 7
|
||||
#define KB_FIRMWARE_VERSION_810 8
|
||||
#define KB_FIRMWARE_VERSION_900 9
|
||||
#define KB_FIRMWARE_VERSION_910 10
|
||||
#define KB_FIRMWARE_VERSION_1210 11
|
||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1210
|
||||
|
||||
#define HOS_PKG11_MAGIC 0x31314B50
|
||||
#define HOS_EKS_MAGIC 0x30534B45
|
||||
@@ -51,6 +52,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 +109,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;
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <soc/t210.h>
|
||||
#include <storage/nx_sd.h>
|
||||
#include <utils/aarch64_util.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
@@ -127,10 +128,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 +152,30 @@ 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 - 12.0.3.
|
||||
{ "20210607122020", 11, 15, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000, NULL }, // 12.1.0+
|
||||
};
|
||||
|
||||
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 +185,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 +193,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 +310,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;
|
||||
@@ -346,7 +357,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base)
|
||||
u32 pa_id;
|
||||
u32 fuses_max = 32; // Current ODM7 max.
|
||||
u32 fuses_fw = ctxt->pkg1_id->fuses;
|
||||
u8 burnt_fuses = fuse_count_burnt(fuse_read_odm(7));
|
||||
u8 burnt_fuses = bit_count(fuse_read_odm(7));
|
||||
|
||||
// Save current warmboot in storage cache (MWS) and check if another one is needed.
|
||||
if (!ctxt->warmboot)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -1338,10 +675,12 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
|
||||
|
||||
static const u8 mkey_vector_8xx[][SE_KEY_128_SIZE] =
|
||||
{
|
||||
// Master key 8 encrypted with 9. (8.1.0 with 9.0.0)
|
||||
// Master key 8 encrypted with 9. (8.1.0 with 9.0.0)
|
||||
{ 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 },
|
||||
// Master key 9 encrypted with 10. (9.0.0 with 9.1.0)
|
||||
{ 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }
|
||||
// Master key 9 encrypted with 10. (9.0.0 with 9.1.0)
|
||||
{ 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A },
|
||||
// Master key 10 encrypted with 11. (9.1.0 with 12.1.0)
|
||||
{ 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 },
|
||||
};
|
||||
|
||||
static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed)
|
||||
|
||||
@@ -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.
|
||||
|
||||
746
bootloader/hos/pkg2_patches.inl
Normal file
746
bootloader/hos/pkg2_patches.inl
Normal file
@@ -0,0 +1,746 @@
|
||||
/*
|
||||
* 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 }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_1203[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x13EB34, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x155478, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_1203[] =
|
||||
{
|
||||
{ "nogc", _fs_nogc_1203 },
|
||||
{ "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
|
||||
{ "FS", "\xC8\x67\x62\xBE\x19\xA5\x1F\xA0", _fs_patches_1203 }, // FS 12.0.3
|
||||
{ "FS", "\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", _fs_patches_1203 }, // FS 12.0.3 exfat
|
||||
};
|
||||
@@ -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))
|
||||
|
||||
@@ -5,8 +5,8 @@ SECTIONS {
|
||||
. = __ipl_start;
|
||||
.text : {
|
||||
*(.text._start);
|
||||
*(._boot_cfg);
|
||||
*(._ipl_version);
|
||||
KEEP(*(._boot_cfg));
|
||||
KEEP(*(._ipl_version));
|
||||
*(.text._irq_setup);
|
||||
*(.text*);
|
||||
}
|
||||
|
||||
@@ -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.8", 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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -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 : {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
@@ -376,7 +379,7 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_part,
|
||||
_get_valid_partition(§or_start, §or_size, &part_idx, true);
|
||||
if (!part_idx || !sector_size)
|
||||
{
|
||||
s_printf(gui->txt_buf, "#FFDD00 Failed to find a partition...#\n");
|
||||
s_printf(gui->txt_buf, "\n#FFDD00 Failed to find a partition...#\n");
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
@@ -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,17 +987,38 @@ 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)
|
||||
else if (f_stat(outFilename, &fno))
|
||||
{
|
||||
totalSectors = (u32)((u64)totalCheckFileSize >> (u64)9);
|
||||
if (!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.
|
||||
if (numSplitParts)
|
||||
break;
|
||||
}
|
||||
else
|
||||
totalSectors = (u32)((u64)totalCheckFileSize >> (u64)9);
|
||||
|
||||
// Restore folder is empty.
|
||||
if (!numSplitParts)
|
||||
{
|
||||
s_printf(gui->txt_buf, "#FFDD00 Restore folder is empty.#\n\n");
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1020,7 +1047,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 +1105,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"
|
||||
|
||||
@@ -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;
|
||||
@@ -651,6 +651,8 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
|
||||
|
||||
if (resized_count)
|
||||
{
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, "Done!\n");
|
||||
|
||||
// Calculate USER size and set it for FatFS.
|
||||
u32 user_sectors = resized_count - user_offset - 33;
|
||||
disk_set_info(DRIVE_EMU, SET_SECTOR_COUNT, &user_sectors);
|
||||
@@ -662,7 +664,7 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
|
||||
strcpy(user_part.name, "USER");
|
||||
nx_emmc_bis_init(&user_part, true, sd_sector_off);
|
||||
|
||||
s_printf(gui->txt_buf, "\nFormatting USER...\n");
|
||||
s_printf(gui->txt_buf, "Formatting USER... \n");
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
@@ -676,71 +678,75 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
|
||||
|
||||
if (mkfs_error)
|
||||
{
|
||||
s_printf(gui->txt_buf, "#FF0000 USER format failed (%d)...#\nPlease try again...\n", mkfs_error);
|
||||
s_printf(gui->txt_buf, "#FF0000 Failed (%d)!#\nPlease try again...\n", mkfs_error);
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, "Done!\n");
|
||||
|
||||
// Flush BIS cache, deinit, clear BIS keys slots and reinstate SBK.
|
||||
nx_emmc_bis_end();
|
||||
hos_bis_keys_clear();
|
||||
|
||||
s_printf(gui->txt_buf, "Writing new GPT...\n");
|
||||
s_printf(gui->txt_buf, "Writing new GPT... ");
|
||||
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
|
||||
manual_system_maintenance(true);
|
||||
|
||||
// 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, "#FF0000 No USER partition...#\nPlease try again...\n");
|
||||
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;
|
||||
|
||||
@@ -1262,14 +1262,9 @@ static void _update_status_bar(void *params)
|
||||
else
|
||||
strcat(label, "#FF3C28 "SYMBOL_BATTERY_EMPTY"#");
|
||||
|
||||
// Set charging symbol and regulator 5V source based on USB state.
|
||||
// Set charging symbol.
|
||||
if (charge_status)
|
||||
{
|
||||
strcat(label, " #FFDD00 "SYMBOL_CHARGE"#");
|
||||
regulator_5v_batt_src_enable(false);
|
||||
}
|
||||
else
|
||||
regulator_5v_batt_src_enable(true);
|
||||
|
||||
lv_label_set_text(status_bar.battery, label);
|
||||
lv_obj_realign(status_bar.battery);
|
||||
@@ -2106,6 +2101,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 +2243,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 +2313,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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -686,11 +686,17 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
}
|
||||
|
||||
// Count burnt fuses.
|
||||
u8 burnt_fuses_7 = fuse_count_burnt(fuse_read_odm(7));
|
||||
u8 burnt_fuses_6 = fuse_count_burnt(fuse_read_odm(6));
|
||||
u8 burnt_fuses_7 = bit_count(fuse_read_odm(7));
|
||||
u8 burnt_fuses_6 = bit_count(fuse_read_odm(6));
|
||||
|
||||
switch (burnt_fuses_7)
|
||||
// Check if overburnt.
|
||||
u8 burnt_fuses_hos = (fuse_read_odm(7) & ~bit_count_mask(burnt_fuses_7)) ? 255 : burnt_fuses_7;
|
||||
|
||||
switch (burnt_fuses_hos)
|
||||
{
|
||||
case 0:
|
||||
strcpy(fuses_hos_version, "#96FF00 Golden sample#");
|
||||
break;
|
||||
case 1:
|
||||
strcpy(fuses_hos_version, "1.0.0");
|
||||
break;
|
||||
@@ -731,7 +737,13 @@ 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;
|
||||
case 255:
|
||||
strcpy(fuses_hos_version, "#FFD000 Overburnt#");
|
||||
break;
|
||||
default:
|
||||
strcpy(fuses_hos_version, "#FF8000 Unknown#");
|
||||
@@ -887,6 +899,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;
|
||||
@@ -930,7 +945,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
break;
|
||||
}
|
||||
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# [%02X] %02X [%02X]",
|
||||
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# #96FF00 %02X# %02X #96FF00 %02X#",
|
||||
nyx_str->info.disp_id & 0xFF, (nyx_str->info.disp_id >> 8) & 0xFF, (nyx_str->info.disp_id >> 16) & 0xFF);
|
||||
|
||||
touch_fw_info_t touch_fw;
|
||||
@@ -943,9 +958,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);
|
||||
|
||||
@@ -956,35 +980,37 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
||||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == -1;
|
||||
break;
|
||||
case 0x00100200: // 4CD 1602.
|
||||
case 0x00120100:
|
||||
case 0x32000001:
|
||||
strcat(txt_buf, "4CD 1801");
|
||||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == 0;
|
||||
panel_ic_paired = touch_panel->idx == 0; // NISSHA NFT-K12D.
|
||||
break;
|
||||
case 0x001A0300:
|
||||
case 0x32000102:
|
||||
strcat(txt_buf, "4CD 2602");
|
||||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == 1;
|
||||
panel_ic_paired = touch_panel->idx == 1; // GiS GGM6 B2X.
|
||||
break;
|
||||
case 0x00290100:
|
||||
case 0x32000302:
|
||||
strcat(txt_buf, "4CD 3801");
|
||||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == 2;
|
||||
panel_ic_paired = touch_panel->idx == 2; // NISSHA NBF-K9A.
|
||||
break;
|
||||
case 0x31051820:
|
||||
case 0x32000402:
|
||||
strcat(txt_buf, "4CD XXXX");
|
||||
strcat(txt_buf, "4CD 4602"); // Assumed. Official is XXXX.
|
||||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == 3;
|
||||
panel_ic_paired = touch_panel->idx == 3; // GiS 5.5".
|
||||
break;
|
||||
case 0x32000501:
|
||||
case 0x33000502:
|
||||
case 0x33000503:
|
||||
strcat(txt_buf, "4CD UNKN");
|
||||
if (touch_panel)
|
||||
panel_ic_paired = touch_panel->idx == 4;
|
||||
panel_ic_paired = touch_panel->idx == 4; // Unknown Aula 6.2".
|
||||
break;
|
||||
default:
|
||||
strcat(txt_buf, "#FF8000 Unknown#");
|
||||
@@ -994,6 +1020,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())
|
||||
@@ -1212,6 +1240,197 @@ out:
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static lv_res_t _create_mbox_emmc_sandisk_report(lv_obj_t * btn)
|
||||
{
|
||||
static lv_style_t h_style;
|
||||
lv_style_copy(&h_style, &lv_style_transp);
|
||||
h_style.body.padding.inner = 0;
|
||||
h_style.body.padding.hor = LV_DPI - (LV_DPI / 4);
|
||||
h_style.body.padding.ver = LV_DPI / 6;
|
||||
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\211", "\222Close", "\211", "" };
|
||||
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 8);
|
||||
|
||||
lv_mbox_set_text(mbox, "#C7EA46 Sandisk Device Report#");
|
||||
|
||||
u8 *buf = calloc(512, 1);
|
||||
char *txt_buf = (char *)malloc(0x8000);
|
||||
char *txt_buf2 = (char *)malloc(0x8000);
|
||||
txt_buf[0] = 0;
|
||||
txt_buf2[0] = 0;
|
||||
|
||||
// Create SoC Info container.
|
||||
lv_obj_t *h1 = lv_cont_create(mbox, NULL);
|
||||
lv_cont_set_style(h1, &h_style);
|
||||
lv_cont_set_fit(h1, false, true);
|
||||
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 7);
|
||||
lv_obj_set_click(h1, false);
|
||||
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
|
||||
|
||||
lv_obj_t * lb_desc = lv_label_create(h1, NULL);
|
||||
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_recolor(lb_desc, true);
|
||||
lv_label_set_style(lb_desc, &monospace_text);
|
||||
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 4);
|
||||
|
||||
lv_obj_t * lb_desc2 = lv_label_create(h1, NULL);
|
||||
lv_label_set_long_mode(lb_desc2, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_recolor(lb_desc2, true);
|
||||
lv_label_set_style(lb_desc2, &monospace_text);
|
||||
lv_obj_set_width(lb_desc2, LV_HOR_RES / 9 * 3);
|
||||
lv_obj_align(lb_desc2, lb_desc, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
|
||||
|
||||
|
||||
if (!sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400))
|
||||
{
|
||||
lv_label_set_text(lb_desc, "#FFDD00 Failed to init eMMC!#");
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
int res = sdmmc_storage_vendor_sandisk_report(&emmc_storage, buf);
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
lv_label_set_text(lb_desc, "#FFDD00 Device Report not supported!#");
|
||||
lv_label_set_text(lb_desc2, " ");
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
mmc_sandisk_report_t *rpt = (mmc_sandisk_report_t *)buf;
|
||||
|
||||
u8 fw_update_date[13] = {0};
|
||||
u8 fw_update_time[9] = {0};
|
||||
memcpy(fw_update_date, rpt->fw_update_date, sizeof(rpt->fw_update_date));
|
||||
memcpy(fw_update_time, rpt->fw_update_time, sizeof(rpt->fw_update_time));
|
||||
|
||||
s_printf(txt_buf,
|
||||
"#00DDFF Device report#\n"
|
||||
//"#FF8000 Average Erases SYS:# %d\n"
|
||||
"#FF8000 Average Erases SLC:# %d\n"
|
||||
"#FF8000 Average Erases MLC:# %d\n"
|
||||
//"#FF8000 Read Reclaims SYS:# %d\n"
|
||||
"#FF8000 Read Reclaims SLC:# %d\n"
|
||||
"#FF8000 Read Reclaims MLC:# %d\n"
|
||||
"#FF8000 Bad Blocks Factory:# %d\n"
|
||||
"#FF8000 Bad Blocks SYS:# %d\n"
|
||||
"#FF8000 Bad Blocks SLC:# %d\n"
|
||||
"#FF8000 Bad Blocks MLC:# %d\n"
|
||||
"#FF8000 FW Updates:# %d\n"
|
||||
"#FF8000 FW Buildtime:# %s %s\n"
|
||||
"#FF8000 Total Writes:# %d MB\n"
|
||||
//"#FF8000 Voltage Drops:# %d\n"
|
||||
//"#FF8000 Voltage Droops:# %d\n"
|
||||
//"#FF8000 VD Failed Recovers:# %d\n"
|
||||
//"#FF8000 VD Recover Operations:# %d\n"
|
||||
"#FF8000 Total Writes SLC:# %d MB\n"
|
||||
"#FF8000 Total Writes MLC:# %d MB\n"
|
||||
"#FF8000 BigFile limit status:# %d\n"
|
||||
"#FF8000 Average Erases Hybrid:# %d",
|
||||
|
||||
//rpt->avg_erase_cycles_sys,
|
||||
rpt->avg_erase_cycles_slc,
|
||||
rpt->avg_erase_cycles_mlc,
|
||||
//rpt->read_reclaim_cnt_sys,
|
||||
rpt->read_reclaim_cnt_slc,
|
||||
rpt->read_reclaim_cnt_mlc,
|
||||
rpt->bad_blocks_factory,
|
||||
rpt->bad_blocks_sys,
|
||||
rpt->bad_blocks_slc,
|
||||
rpt->bad_blocks_mlc,
|
||||
rpt->fw_updates_cnt,
|
||||
fw_update_date,
|
||||
fw_update_time,
|
||||
rpt->total_writes_100mb * 100,
|
||||
//rpt->vdrops,
|
||||
//rpt->vdroops,
|
||||
//rpt->vdrops_failed_data_rec,
|
||||
//rpt->vdrops_data_rec_ops,
|
||||
rpt->total_writes_slc_100mb * 100,
|
||||
rpt->total_writes_mlc_100mb * 100,
|
||||
rpt->mlc_bigfile_mode_limit_exceeded,
|
||||
rpt->avg_erase_cycles_hybrid);
|
||||
|
||||
u8 advanced_report = 0;
|
||||
for (u32 i = 0; i < sizeof(mmc_sandisk_advanced_report_t); i++)
|
||||
advanced_report |= *(u8 *)((u8 *)&rpt->advanced + i);
|
||||
|
||||
if (advanced_report)
|
||||
{
|
||||
s_printf(txt_buf2,
|
||||
"#00DDFF Advanced Health Status#\n"
|
||||
"#FF8000 Power ups:# %d\n"
|
||||
//"#FF8000 Maximum Erases SYS:# %d\n"
|
||||
"#FF8000 Maximum Erases SLC:# %d\n"
|
||||
"#FF8000 Maximum Erases MLC:# %d\n"
|
||||
//"#FF8000 Minimum Erases SYS:# %d\n"
|
||||
"#FF8000 Minimum Erases SLC:# %d\n"
|
||||
"#FF8000 Minimum Erases MLC:# %d\n"
|
||||
"#FF8000 Maximum Erases EUDA:# %d\n"
|
||||
"#FF8000 Minimum Erases EUDA:# %d\n"
|
||||
"#FF8000 Average Erases EUDA:# %d\n"
|
||||
"#FF8000 Read Reclaims EUDA:# %d\n"
|
||||
"#FF8000 Bad Blocks EUDA:# %d\n"
|
||||
//"#FF8000 Pre EOL State EUDA:# %d\n"
|
||||
//"#FF8000 Pre EOL State SYS:# %d\n"
|
||||
//"#FF8000 Pre EOL State MLC:# %d\n"
|
||||
"#FF8000 Uncorrectable ECC:# %d\n"
|
||||
"#FF8000 Temperature Now:# %d oC\n"
|
||||
//"#FF8000 Temperature Min:# %d oC\n"
|
||||
"#FF8000 Temperature Max:# %d oC\n"
|
||||
"#FF8000 Health Level EUDA:# %d%%\n"
|
||||
//"#FF8000 Health Level SYS:# %d%%\n"
|
||||
"#FF8000 Health Level MLC:# %d%%",
|
||||
|
||||
rpt->advanced.power_inits,
|
||||
//rpt->advanced.max_erase_cycles_sys,
|
||||
rpt->advanced.max_erase_cycles_slc,
|
||||
rpt->advanced.max_erase_cycles_mlc,
|
||||
//rpt->advanced.min_erase_cycles_sys,
|
||||
rpt->advanced.min_erase_cycles_slc,
|
||||
rpt->advanced.min_erase_cycles_mlc,
|
||||
rpt->advanced.max_erase_cycles_euda,
|
||||
rpt->advanced.min_erase_cycles_euda,
|
||||
rpt->advanced.avg_erase_cycles_euda,
|
||||
rpt->advanced.read_reclaim_cnt_euda,
|
||||
rpt->advanced.bad_blocks_euda,
|
||||
//rpt->advanced.pre_eol_euda,
|
||||
//rpt->advanced.pre_eol_sys,
|
||||
//rpt->advanced.pre_eol_mlc,
|
||||
rpt->advanced.uncorrectable_ecc,
|
||||
rpt->advanced.temperature_now,
|
||||
//rpt->advanced.temperature_min,
|
||||
rpt->advanced.temperature_max,
|
||||
rpt->advanced.health_pct_euda ? 101 - rpt->advanced.health_pct_euda : 0,
|
||||
//rpt->advanced.health_pct_sys ? 101 - rpt->advanced.health_pct_sys : 0,
|
||||
rpt->advanced.health_pct_mlc ? 101 - rpt->advanced.health_pct_mlc : 0);
|
||||
}
|
||||
else
|
||||
strcpy(txt_buf2, "#00DDFF Device report#\n#FFDD00 Empty!#");
|
||||
|
||||
lv_label_set_text(lb_desc, txt_buf);
|
||||
lv_label_set_text(lb_desc2, txt_buf2);
|
||||
|
||||
out:
|
||||
free(buf);
|
||||
free (txt_buf);
|
||||
free (txt_buf2);
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); // Important. After set_text.
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_top(mbox, true);
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
||||
{
|
||||
sdmmc_storage_t *storage;
|
||||
@@ -1258,6 +1477,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 +1494,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 +1515,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 +1532,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 +1559,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 +1576,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 +1617,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 +1634,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 +1651,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 +1660,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)
|
||||
@@ -1497,6 +1746,7 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
|
||||
break;
|
||||
case 0x45: // Unofficial.
|
||||
strcat(txt_buf, "SanDisk ");
|
||||
lv_win_add_btn(win, NULL, SYMBOL_FILE_ALT" Device Report", _create_mbox_emmc_sandisk_report);
|
||||
break;
|
||||
case 0x90:
|
||||
strcat(txt_buf, "SK Hynix ");
|
||||
@@ -1716,13 +1966,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 +2002,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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1621,9 +1635,16 @@ static lv_res_t _create_mbox_partitioning_next(lv_obj_t *btn)
|
||||
s_printf(txt_buf, "#FFDD00 Warning: This will partition the SD Card!#\n\n");
|
||||
|
||||
if (part_info.backup_possible)
|
||||
strcat(txt_buf, "#C7EA46 Your files will be backed up and restored!#\n#FFDD00Any other partition will be wiped!#");
|
||||
{
|
||||
strcat(txt_buf, "#C7EA46 Your files will be backed up and restored!#\n"
|
||||
"#FFDD00 Any other partition will be wiped!#");
|
||||
}
|
||||
else
|
||||
strcat(txt_buf, "#FFDD00 Your files will be wiped!#\n#FFDD00 Use USB UMS to copy them over!#");
|
||||
{
|
||||
strcat(txt_buf, "#FFDD00 Your files will be wiped!#\n"
|
||||
"#FFDD00 Any other partition will be also wiped!#\n"
|
||||
"#FFDD00 Use USB UMS to copy them over!#");
|
||||
}
|
||||
|
||||
lv_label_set_text(lbl_status, txt_buf);
|
||||
|
||||
@@ -1909,7 +1930,8 @@ static void create_mbox_check_files_total_size()
|
||||
else
|
||||
{
|
||||
lv_mbox_set_text(mbox,
|
||||
"#FFDD00 The SD Card cannot be backed up!#\n\n"
|
||||
"#FFDD00 The SD Card cannot be backed up!#\n"
|
||||
"#FFDD00 Any other partition will be also wiped!#\n\n"
|
||||
"You will be asked to back up your files later via UMS.");
|
||||
}
|
||||
|
||||
@@ -1921,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 };
|
||||
@@ -2030,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;
|
||||
@@ -2085,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;
|
||||
|
||||
@@ -2256,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.
|
||||
|
||||
@@ -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')
|
||||
{
|
||||
|
||||
@@ -95,6 +95,7 @@ static const u8 master_kekseed_t210b01[][SE_KEY_128_SIZE] = {
|
||||
{ 0x5C, 0x24, 0xE3, 0xB8, 0xB4, 0xF7, 0x00, 0xC2, 0x3C, 0xFD, 0x0A, 0xCE, 0x13, 0xC3, 0xDC, 0x23 }, // 8.1.0.
|
||||
{ 0x86, 0x69, 0xF0, 0x09, 0x87, 0xC8, 0x05, 0xAE, 0xB5, 0x7B, 0x48, 0x74, 0xDE, 0x62, 0xA6, 0x13 }, // 9.0.0.
|
||||
{ 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82 }, // 9.1.0.
|
||||
{ 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1 }, // 12.1.0.
|
||||
};
|
||||
|
||||
static const u8 console_keyseed[SE_KEY_128_SIZE] =
|
||||
@@ -118,28 +119,31 @@ static const u8 mkey_vectors[KB_FIRMWARE_VERSION_MAX + 1][SE_KEY_128_SIZE] = {
|
||||
{ 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 }, // Mkey 07 encrypted with mkey 08.
|
||||
{ 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 }, // Mkey 08 encrypted with mkey 09.
|
||||
{ 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }, // Mkey 09 encrypted with mkey 10.
|
||||
{ 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 }, // Mkey 10 encrypted with mkey 11.
|
||||
};
|
||||
|
||||
static const u8 new_console_keyseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][SE_KEY_128_SIZE] = {
|
||||
{ 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D }, // 4.x New Device Key Source.
|
||||
{ 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C }, // 5.x New Device Key Source.
|
||||
{ 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 }, // 6.x New Device Key Source.
|
||||
{ 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 }, // 6.2.0 New Device Key Source.
|
||||
{ 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D }, // 7.0.0 New Device Key Source.
|
||||
{ 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE }, // 8.1.0 New Device Key Source.
|
||||
{ 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 }, // 9.0.0 New Device Key Source.
|
||||
{ 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 }, // 9.1.0 New Device Key Source.
|
||||
{ 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D }, // 4.x New Device Key Source.
|
||||
{ 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C }, // 5.x New Device Key Source.
|
||||
{ 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 }, // 6.x New Device Key Source.
|
||||
{ 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 }, // 6.2.0 New Device Key Source.
|
||||
{ 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D }, // 7.0.0 New Device Key Source.
|
||||
{ 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE }, // 8.1.0 New Device Key Source.
|
||||
{ 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 }, // 9.0.0 New Device Key Source.
|
||||
{ 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 }, // 9.1.0 New Device Key Source.
|
||||
{ 0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6 }, // 12.1.0 New Device Key Source.
|
||||
};
|
||||
|
||||
static const u8 new_console_kekseed[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][SE_KEY_128_SIZE] = {
|
||||
{ 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D }, // 4.x New Device Keygen Source.
|
||||
{ 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E }, // 5.x New Device Keygen Source.
|
||||
{ 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF }, // 6.x New Device Keygen Source.
|
||||
{ 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB }, // 6.2.0 New Device Keygen Source.
|
||||
{ 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E }, // 7.0.0 New Device Keygen Source.
|
||||
{ 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D }, // 8.1.0 New Device Keygen Source.
|
||||
{ 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED }, // 9.0.0 New Device Keygen Source.
|
||||
{ 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 }, // 9.1.0 New Device Keygen Source.
|
||||
{ 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D }, // 4.x New Device Keygen Source.
|
||||
{ 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E }, // 5.x New Device Keygen Source.
|
||||
{ 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF }, // 6.x New Device Keygen Source.
|
||||
{ 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB }, // 6.2.0 New Device Keygen Source.
|
||||
{ 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E }, // 7.0.0 New Device Keygen Source.
|
||||
{ 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D }, // 8.1.0 New Device Keygen Source.
|
||||
{ 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED }, // 9.0.0 New Device Keygen Source.
|
||||
{ 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 }, // 9.1.0 New Device Keygen Source.
|
||||
{ 0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3 }, // 12.1.0 New Device Keygen Source.
|
||||
};
|
||||
|
||||
static const u8 gen_keyseed[SE_KEY_128_SIZE] =
|
||||
@@ -566,7 +570,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
|
||||
switch (kb)
|
||||
{
|
||||
case KB_FIRMWARE_VERSION_100_200:
|
||||
case KB_FIRMWARE_VERSION_100:
|
||||
case KB_FIRMWARE_VERSION_300:
|
||||
case KB_FIRMWARE_VERSION_301:
|
||||
se_aes_unwrap_key(13, 15, console_keyseed);
|
||||
|
||||
@@ -27,18 +27,19 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define KB_FIRMWARE_VERSION_100_200 0
|
||||
#define KB_FIRMWARE_VERSION_300 1
|
||||
#define KB_FIRMWARE_VERSION_301 2
|
||||
#define KB_FIRMWARE_VERSION_400 3
|
||||
#define KB_FIRMWARE_VERSION_500 4
|
||||
#define KB_FIRMWARE_VERSION_600 5
|
||||
#define KB_FIRMWARE_VERSION_620 6
|
||||
#define KB_FIRMWARE_VERSION_700 7
|
||||
#define KB_FIRMWARE_VERSION_810 8
|
||||
#define KB_FIRMWARE_VERSION_900 9
|
||||
#define KB_FIRMWARE_VERSION_910 10
|
||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910
|
||||
#define KB_FIRMWARE_VERSION_100 0
|
||||
#define KB_FIRMWARE_VERSION_300 1
|
||||
#define KB_FIRMWARE_VERSION_301 2
|
||||
#define KB_FIRMWARE_VERSION_400 3
|
||||
#define KB_FIRMWARE_VERSION_500 4
|
||||
#define KB_FIRMWARE_VERSION_600 5
|
||||
#define KB_FIRMWARE_VERSION_620 6
|
||||
#define KB_FIRMWARE_VERSION_700 7
|
||||
#define KB_FIRMWARE_VERSION_810 8
|
||||
#define KB_FIRMWARE_VERSION_900 9
|
||||
#define KB_FIRMWARE_VERSION_910 10
|
||||
#define KB_FIRMWARE_VERSION_1210 11
|
||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1210
|
||||
|
||||
#define HOS_PKG11_MAGIC 0x31314B50
|
||||
#define HOS_EKS_MAGIC 0x30534B45
|
||||
|
||||
@@ -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,10 @@ 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 - 12.0.3.
|
||||
{ "20210607122020", 11, 0x0E00, 0x6FE0, 0x40030000, 0x4003E000 }, // 12.1.0+
|
||||
};
|
||||
|
||||
const pkg1_id_t *pkg1_identify(u8 *pkg1, char *build_date)
|
||||
@@ -69,7 +72,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 +80,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);
|
||||
}
|
||||
@@ -112,9 +115,9 @@ const u8 *pkg1_unpack(void *wm_dst, void *sm_dst, void *ldr_dst, const pkg1_id_t
|
||||
//u32 sec_off[3] = { hdr->wb_off, hdr->ldr_off, hdr->sm_off };
|
||||
|
||||
// Get correct header mapping.
|
||||
if (id->kb == KB_FIRMWARE_VERSION_100_200 && !strcmp(id->id, "20161121183008"))
|
||||
if (id->kb == KB_FIRMWARE_VERSION_100 && !strcmp(id->id, "20161121183008"))
|
||||
sec_map = sec_map_100;
|
||||
else if (id->kb >= KB_FIRMWARE_VERSION_100_200 && id->kb <= KB_FIRMWARE_VERSION_301)
|
||||
else if (id->kb >= KB_FIRMWARE_VERSION_100 && id->kb <= KB_FIRMWARE_VERSION_301)
|
||||
sec_map = sec_map_2xx;
|
||||
else
|
||||
sec_map = sec_map_4xx;
|
||||
|
||||
@@ -114,10 +114,12 @@ DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
|
||||
|
||||
static const u8 mkey_vector_8xx[][SE_KEY_128_SIZE] =
|
||||
{
|
||||
// Master key 8 encrypted with 9. (8.1.0 with 9.0.0)
|
||||
// Master key 8 encrypted with 9. (8.1.0 with 9.0.0)
|
||||
{ 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 },
|
||||
// Master key 9 encrypted with 10. (9.0.0 with 9.1.0)
|
||||
{ 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }
|
||||
// Master key 9 encrypted with 10. (9.0.0 with 9.1.0)
|
||||
{ 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A },
|
||||
// Master key 10 encrypted with 11. (9.1.0 with 12.1.0)
|
||||
{ 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 },
|
||||
};
|
||||
|
||||
static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed)
|
||||
|
||||
@@ -5,7 +5,7 @@ SECTIONS {
|
||||
. = __ipl_start;
|
||||
.text : {
|
||||
*(.text._start);
|
||||
*(._ipl_version);
|
||||
KEEP(*(._ipl_version));
|
||||
*(.text._irq_setup);
|
||||
*(.text*);
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush
|
||||
if (!emu_offset)
|
||||
res = nx_emmc_part_write(&emmc_storage, system_part, sector, count, bis_cache->dma_buff);
|
||||
else
|
||||
res = sdmmc_storage_read(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
res = sdmmc_storage_write(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
if (!res)
|
||||
return 1; // R/W error.
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user