Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
562a6fb61d | ||
|
|
938562cc0a | ||
|
|
1e4d63731b | ||
|
|
8ff01301cb | ||
|
|
a664118fc7 | ||
|
|
87d376654b | ||
|
|
c6e92311f9 | ||
|
|
24d30a40f9 | ||
|
|
ae283aef59 | ||
|
|
e4f7928513 | ||
|
|
bd8a5ece58 | ||
|
|
d0850516ab | ||
|
|
4c5a78de6f | ||
|
|
97d3b745d9 | ||
|
|
c12c696e53 | ||
|
|
f256bd5909 | ||
|
|
0290892b23 | ||
|
|
643a8ea8f9 | ||
|
|
a6d8854499 | ||
|
|
96bafd8bd7 | ||
|
|
65ee728939 | ||
|
|
e1748a0727 | ||
|
|
6734513d47 | ||
|
|
dbe6ed4060 | ||
|
|
943477fdde | ||
|
|
35e853fd03 | ||
|
|
7e26be6587 | ||
|
|
733da0f4d5 | ||
|
|
a357395cc6 | ||
|
|
48c15a8fde | ||
|
|
edc2b12f0f | ||
|
|
0b45a5a11a | ||
|
|
bc7dec2e61 | ||
|
|
9811ba53e0 | ||
|
|
a16b1af698 | ||
|
|
641a57a4f6 | ||
|
|
84328aa676 | ||
|
|
66c4f30bdf | ||
|
|
dd8ec0d28b | ||
|
|
0b1eebefe1 | ||
|
|
168de9ddd8 | ||
|
|
c24d943122 | ||
|
|
b61b212218 | ||
|
|
ec10b572d1 | ||
|
|
d1e50c558e | ||
|
|
9476e0ab45 | ||
|
|
ccf36fd2cb | ||
|
|
9a082c1b18 | ||
|
|
2c1da3a97d | ||
|
|
29a51124fd | ||
|
|
74452074f6 | ||
|
|
598073e50c | ||
|
|
58b57a7b14 | ||
|
|
426c86182d | ||
|
|
65fbdfddbf | ||
|
|
7c42f72b8a | ||
|
|
9104b85143 | ||
|
|
2857fcca52 | ||
|
|
6433dbd1ee |
12
Makefile
12
Makefile
@@ -7,13 +7,8 @@ include $(DEVKITARM)/base_rules
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
IPL_LOAD_ADDR := 0x40008000
|
IPL_LOAD_ADDR := 0x40008000
|
||||||
NYX_STORAGE_ADDR := 0xED000000
|
|
||||||
IPL_MAGIC := 0x43544349 #"ICTC"
|
IPL_MAGIC := 0x43544349 #"ICTC"
|
||||||
BLVERSION_MAJOR := 5
|
include ./Versions.inc
|
||||||
BLVERSION_MINOR := 0
|
|
||||||
BLVERSION_HOTFX := 2
|
|
||||||
|
|
||||||
BL_RESERVED := 0
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
@@ -60,8 +55,9 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DNYX_STORAGE_ADDR=$(NYX_STORAGE_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
|
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
|
||||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BL_RESERVED)
|
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)
|
||||||
|
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||||
#CUSTOMDEFINES += -DMENU_LOGO_ENABLE
|
#CUSTOMDEFINES += -DMENU_LOGO_ENABLE
|
||||||
|
|
||||||
# 0: UART_A, 1: UART_B.
|
# 0: UART_A, 1: UART_B.
|
||||||
|
|||||||
33
README.md
33
README.md
@@ -13,8 +13,8 @@ Custom Nintendo Switch bootloader, firmware patcher, and more.
|
|||||||
| bootloader | Main folder. |
|
| bootloader | Main folder. |
|
||||||
| \|__ bootlogo.bmp | It is used when custom is on and no logopath found. Can be skipped. |
|
| \|__ bootlogo.bmp | It is used when custom is on and no logopath found. Can be skipped. |
|
||||||
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries. |
|
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries. |
|
||||||
| \|__ patches.ini | Add external patches. If not found `patches_template.ini` will be loaded. Can be skipped. |
|
| \|__ patches.ini | Add external patches. Can be skipped. A template can be found [here](./res/patches_template.ini) |
|
||||||
| \|__ update.bin | If newer, it is loaded at boot. For modchips. Can be skipped. |
|
| \|__ update.bin | If newer, it is loaded at boot. For modchips. Auto updated. Can be skipped. |
|
||||||
| bootloader/ini/ | For individual inis. 'More configs...' menu. Autoboot is supported. |
|
| bootloader/ini/ | For individual inis. 'More configs...' menu. Autoboot is supported. |
|
||||||
| bootloader/res/ | Nyx user resources. Icons and more. |
|
| bootloader/res/ | Nyx user resources. Icons and more. |
|
||||||
| \|__ background.bmp | Nyx - custom background. |
|
| \|__ background.bmp | Nyx - custom background. |
|
||||||
@@ -42,6 +42,9 @@ The bootloader can be configured via 'bootloader/hekate_ipl.ini' (if it is prese
|
|||||||
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
|
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
|
||||||
|
|
||||||
|
|
||||||
|
You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||||
|
|
||||||
|
|
||||||
### Global Configuration keys/values when boot entry is **config**:
|
### Global Configuration keys/values when boot entry is **config**:
|
||||||
|
|
||||||
| Config option | Description |
|
| Config option | Description |
|
||||||
@@ -52,6 +55,7 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||||||
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||||
|
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
|
||||||
| backlight=100 | Screen backlight level. 0-255. |
|
| backlight=100 | Screen backlight level. 0-255. |
|
||||||
|
|
||||||
|
|
||||||
@@ -59,21 +63,23 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||||||
|
|
||||||
| Config option | Description |
|
| Config option | Description |
|
||||||
| ---------------------- | ---------------------------------------------------------- |
|
| ---------------------- | ---------------------------------------------------------- |
|
||||||
| logopath={SD path} | If global customlogo is 1 and logopath empty, bootlogo.bmp will be used. If logopath exists, it will load the specified bitmap. |
|
|
||||||
| warmboot={SD path} | Replaces the warmboot binary |
|
| warmboot={SD path} | Replaces the warmboot binary |
|
||||||
| secmon={SD path} | Replaces the security monitor binary |
|
| secmon={SD path} | Replaces the security monitor binary |
|
||||||
| kernel={SD path} | Replaces the kernel binary |
|
| kernel={SD path} | Replaces the kernel binary |
|
||||||
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||||
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||||
| fss0={SD path} | Takes a fusee-secondary binary and extracts all needed parts from it. |
|
| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. |
|
||||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. Current available patches nosigchk. |
|
| 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) |
|
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||||
| atmosphere=1 | Enables Atmosphère patching. |
|
| atmosphere=1 | Enables Atmosphère patching. |
|
||||||
| nouserexceptions=1 | Disables usermode exception handlers when paired with Exosphère. |
|
| nouserexceptions=1 | Disables usermode exception handlers when paired with Exosphère. |
|
||||||
|
| userpmu=1 | Allows user access to PMU when paired with Exosphère. |
|
||||||
| emummc_force_disable=1 | Disabled emuMMC if it's enabled. |
|
| emummc_force_disable=1 | Disabled emuMMC if it's enabled. |
|
||||||
| stock=1 | Disables unneeded kernel patching when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disabled=1` is required to run completely stock. |
|
| stock=1 | Disables unneeded kernel patching when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disabled=1` is required to run completely stock. |
|
||||||
|
| id=idname | Identifies boot entry for forced boot via id. Max 7 chars. |
|
||||||
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
||||||
|
| logopath={SD path} | If no logopath, `bootloader/bootlogo.bmp` will be used if exists. If logopath exists, it will load the specified bitmap. |
|
||||||
| 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. |
|
| 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.
|
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||||
@@ -81,24 +87,24 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||||||
**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`.
|
**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.
|
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||||
|
|
||||||
**Warning**: Never define core kips when using `fss0` and make sure that the folder (when using `/*`), does not include them. This is in case the kips are incompatible between them.
|
**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).
|
||||||
|
|
||||||
|
|
||||||
### Payload storage:
|
### Payload storage:
|
||||||
|
|
||||||
Hekate now has a new storage in the binary that helps it configure it outside of BPMP enviroment:
|
hekate has a boot storage in the binary that helps it configure it outside of BPMP enviroment:
|
||||||
|
|
||||||
| Offset / Name | Description |
|
| Offset / Name | Description |
|
||||||
| -------------------- | ----------------------------------------------------------------- |
|
| -------------------- | ----------------------------------------------------------------- |
|
||||||
| '0x94' boot_cfg | bit0: Force AutoBoot, bit1: Show launch log, bit2: sept run. |
|
| '0x94' boot_cfg | bit0: Force AutoBoot, bit1: Show launch log, bit2: Boot from ID, bit7: sept run. |
|
||||||
| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
|
| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
|
||||||
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||||
| '0x97' extra_cfg | bit7: Force Nyx to run `Dump pkg1/2. |
|
| '0x97' extra_cfg | bit7: Force Nyx to run `Dump pkg1/2`. |
|
||||||
| '0x98' rsvd[128] | Reserved. |
|
| '0x98' id[8] | When Boot from ID is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
|
||||||
|
| '0x98' xt_str[128] | Depends on the set cfg bits. |
|
||||||
|
|
||||||
|
|
||||||
You can find a template [Here](./res/hekate_ipl_template.ini)
|
|
||||||
|
|
||||||
If the main .ini is not found, it is created on the first hekate boot.
|
If the main .ini is not found, it is created on the first hekate boot.
|
||||||
|
|
||||||
|
|
||||||
@@ -112,7 +118,8 @@ Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
|||||||
Open source and free packages used:
|
Open source and free packages used:
|
||||||
- FatFs R0.13a, Copyright (C) 2017, ChaN
|
- FatFs R0.13a, Copyright (C) 2017, ChaN
|
||||||
- bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard
|
- bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard
|
||||||
- Atmosphère (SE sha256, prc id kernel patches), Copyright (C) 2018, Atmosphère-NX
|
- Atmosphère (Exosphere types/panic, prc id kernel patches),
|
||||||
|
Copyright (C) 2018-2019, Atmosphère-NX
|
||||||
- elfload, Copyright (C) 2014 Owen Shepherd, Copyright (C) 2018 M4xw
|
- elfload, Copyright (C) 2014 Owen Shepherd, Copyright (C) 2018 M4xw
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|||||||
11
Versions.inc
Normal file
11
Versions.inc
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# IPL Version.
|
||||||
|
BLVERSION_MAJOR := 5
|
||||||
|
BLVERSION_MINOR := 1
|
||||||
|
BLVERSION_HOTFX := 1
|
||||||
|
BLVERSION_RSVD := 0
|
||||||
|
|
||||||
|
# Nyx Version.
|
||||||
|
NYXVERSION_MAJOR := 0
|
||||||
|
NYXVERSION_MINOR := 8
|
||||||
|
NYXVERSION_HOTFX := 4
|
||||||
|
NYXVERSION_RSVD := 0
|
||||||
@@ -43,6 +43,7 @@ void set_default_configuration()
|
|||||||
h_cfg.backlight = 100;
|
h_cfg.backlight = 100;
|
||||||
h_cfg.autohosoff = 0;
|
h_cfg.autohosoff = 0;
|
||||||
h_cfg.autonogc = 1;
|
h_cfg.autonogc = 1;
|
||||||
|
h_cfg.updater2p = 0;
|
||||||
h_cfg.brand = NULL;
|
h_cfg.brand = NULL;
|
||||||
h_cfg.tagline = NULL;
|
h_cfg.tagline = NULL;
|
||||||
h_cfg.errors = 0;
|
h_cfg.errors = 0;
|
||||||
@@ -108,6 +109,9 @@ int create_config_entry()
|
|||||||
f_puts("\nautonogc=", &fp);
|
f_puts("\nautonogc=", &fp);
|
||||||
itoa(h_cfg.autonogc, lbuf, 10);
|
itoa(h_cfg.autonogc, lbuf, 10);
|
||||||
f_puts(lbuf, &fp);
|
f_puts(lbuf, &fp);
|
||||||
|
f_puts("\nupdater2p=", &fp);
|
||||||
|
itoa(h_cfg.updater2p, lbuf, 10);
|
||||||
|
f_puts(lbuf, &fp);
|
||||||
if (h_cfg.brand)
|
if (h_cfg.brand)
|
||||||
{
|
{
|
||||||
f_puts("\nbrand=", &fp);
|
f_puts("\nbrand=", &fp);
|
||||||
@@ -227,8 +231,7 @@ static void _config_autoboot_list(void *ent)
|
|||||||
|
|
||||||
else
|
else
|
||||||
boot_text[(i - 1) * 512] = '*';
|
boot_text[(i - 1) * 512] = '*';
|
||||||
memcpy(boot_text + (i - 1) * 512 + 1, ini_sec->name, strlen(ini_sec->name) + 1);
|
strcpy(boot_text + (i - 1) * 512 + 1, ini_sec->name);
|
||||||
boot_text[strlen(ini_sec->name) + (i - 1) * 512 + 1] = 0;
|
|
||||||
ments[i].caption = &boot_text[(i - 1) * 512];
|
ments[i].caption = &boot_text[(i - 1) * 512];
|
||||||
}
|
}
|
||||||
ments[i].type = ini_sec->type;
|
ments[i].type = ini_sec->type;
|
||||||
@@ -335,8 +338,7 @@ void config_autoboot()
|
|||||||
|
|
||||||
else
|
else
|
||||||
boot_text[(i - 4) * 512] = '*';
|
boot_text[(i - 4) * 512] = '*';
|
||||||
memcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name, strlen(ini_sec->name) + 1);
|
strcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name);
|
||||||
boot_text[strlen(ini_sec->name) + (i - 4) * 512 + 1] = 0;
|
|
||||||
ments[i].caption = &boot_text[(i - 4) * 512];
|
ments[i].caption = &boot_text[(i - 4) * 512];
|
||||||
}
|
}
|
||||||
ments[i].type = ini_sec->type;
|
ments[i].type = ini_sec->type;
|
||||||
@@ -421,7 +423,7 @@ void config_bootdelay()
|
|||||||
else
|
else
|
||||||
delay_text[i * 32] = '*';
|
delay_text[i * 32] = '*';
|
||||||
delay_text[i * 32 + 1] = i + '0';
|
delay_text[i * 32 + 1] = i + '0';
|
||||||
memcpy(delay_text + i * 32 + 2, " seconds", 9);
|
strcpy(delay_text + i * 32 + 2, " seconds");
|
||||||
|
|
||||||
ments[i + 2].type = MENT_DATA;
|
ments[i + 2].type = MENT_DATA;
|
||||||
ments[i + 2].caption = delay_text + i * 32;
|
ments[i + 2].caption = delay_text + i * 32;
|
||||||
@@ -468,9 +470,9 @@ void config_verification()
|
|||||||
|
|
||||||
ments[1].type = MENT_CHGLINE;
|
ments[1].type = MENT_CHGLINE;
|
||||||
|
|
||||||
memcpy(vr_text, " Disable (Fastest - Unsafe)", 28);
|
strcpy(vr_text, " Disable (Fastest - Unsafe)");
|
||||||
memcpy(vr_text + 64, " Sparse (Fast - Safe)", 23);
|
strcpy(vr_text + 64, " Sparse (Fast - Safe)");
|
||||||
memcpy(vr_text + 128, " Full (Slow - Safe)", 23);
|
strcpy(vr_text + 128, " Full (Slow - Safe)");
|
||||||
|
|
||||||
for (u32 i = 0; i < 3; i++)
|
for (u32 i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
@@ -530,10 +532,10 @@ void config_backlight()
|
|||||||
if (i < 10)
|
if (i < 10)
|
||||||
{
|
{
|
||||||
bri_text[i * 32 + 1] = i + '0';
|
bri_text[i * 32 + 1] = i + '0';
|
||||||
memcpy(bri_text + i * 32 + 2, "0%", 3);
|
strcpy(bri_text + i * 32 + 2, "0%");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
memcpy(bri_text + i * 32 + 1, "100%", 5);
|
strcpy(bri_text + i * 32 + 1, "100%");
|
||||||
|
|
||||||
ments[i + 1].type = MENT_DATA;
|
ments[i + 1].type = MENT_DATA;
|
||||||
ments[i + 1].caption = bri_text + i * 32;
|
ments[i + 1].caption = bri_text + i * 32;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ typedef struct _hekate_config
|
|||||||
u32 backlight;
|
u32 backlight;
|
||||||
u32 autohosoff;
|
u32 autohosoff;
|
||||||
u32 autonogc;
|
u32 autonogc;
|
||||||
|
u32 updater2p;
|
||||||
char *brand;
|
char *brand;
|
||||||
char *tagline;
|
char *tagline;
|
||||||
// Global temporary config.
|
// Global temporary config.
|
||||||
@@ -40,11 +41,6 @@ typedef struct _hekate_config
|
|||||||
u32 errors;
|
u32 errors;
|
||||||
} hekate_config;
|
} hekate_config;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
ERR_LIBSYS_LP0 = (1 << 0),
|
|
||||||
} hsysmodule_t;
|
|
||||||
|
|
||||||
void set_default_configuration();
|
void set_default_configuration();
|
||||||
int create_config_entry();
|
int create_config_entry();
|
||||||
void config_autoboot();
|
void config_autoboot();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018-2019 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -78,7 +78,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||||||
|
|
||||||
char *filename = (char *)malloc(256);
|
char *filename = (char *)malloc(256);
|
||||||
|
|
||||||
memcpy(filename, ini_path, pathlen + 1);
|
strcpy(filename, ini_path);
|
||||||
|
|
||||||
// Get all ini filenames.
|
// Get all ini filenames.
|
||||||
if (is_dir)
|
if (is_dir)
|
||||||
@@ -89,7 +89,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||||||
free(filename);
|
free(filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(filename + pathlen, "/", 2);
|
strcpy(filename + pathlen, "/");
|
||||||
pathlen++;
|
pathlen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||||||
{
|
{
|
||||||
if (filelist[k * 256])
|
if (filelist[k * 256])
|
||||||
{
|
{
|
||||||
memcpy(filename + pathlen, &filelist[k * 256], strlen(&filelist[k * 256]) + 1);
|
strcpy(filename + pathlen, &filelist[k * 256]);
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "fe_emmc_tools.h"
|
#include "fe_emmc_tools.h"
|
||||||
|
#include "../../common/memory_map.h"
|
||||||
#include "../config/config.h"
|
#include "../config/config.h"
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
#include "../gfx/tui.h"
|
#include "../gfx/tui.h"
|
||||||
@@ -31,10 +32,6 @@
|
|||||||
#include "../utils/btn.h"
|
#include "../utils/btn.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
#define EMMC_BUF_ALIGNED 0xB5000000
|
|
||||||
#define SDXC_BUF_ALIGNED 0xB6000000
|
|
||||||
#define MIXD_BUF_ALIGNED 0xB7000000
|
|
||||||
|
|
||||||
#define NUM_SECTORS_PER_ITER 8192 // 4MB Cache.
|
#define NUM_SECTORS_PER_ITER 8192 // 4MB Cache.
|
||||||
#define OUT_FILENAME_SZ 128
|
#define OUT_FILENAME_SZ 128
|
||||||
#define SHA256_SZ 0x20
|
#define SHA256_SZ 0x20
|
||||||
@@ -185,7 +182,7 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
|||||||
|
|
||||||
FIL partialIdxFp;
|
FIL partialIdxFp;
|
||||||
char partialIdxFilename[12];
|
char partialIdxFilename[12];
|
||||||
memcpy(partialIdxFilename, "partial.idx", 12);
|
strcpy(partialIdxFilename, "partial.idx");
|
||||||
|
|
||||||
gfx_con.fntsz = 8;
|
gfx_con.fntsz = 8;
|
||||||
gfx_printf("\nSD Card free space: %d MiB, Total backup size %d MiB\n\n",
|
gfx_printf("\nSD Card free space: %d MiB, Total backup size %d MiB\n\n",
|
||||||
@@ -203,7 +200,7 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
|
|||||||
{
|
{
|
||||||
isSmallSdCard = true;
|
isSmallSdCard = true;
|
||||||
|
|
||||||
gfx_printf("%k\nSD card free space is smaller than total backup size.%k\n", 0xFFFFBA00, 0xFFCCCCCC);
|
gfx_printf("%k\nSD card free space is smaller than backup size.%k\n", 0xFFFFBA00, 0xFFCCCCCC);
|
||||||
|
|
||||||
if (!maxSplitParts)
|
if (!maxSplitParts)
|
||||||
{
|
{
|
||||||
@@ -518,7 +515,7 @@ static void _dump_emmc_selected(emmcPartType_t dumpType)
|
|||||||
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
memcpy(bootPart.name, "BOOT", 5);
|
strcpy(bootPart.name, "BOOT");
|
||||||
bootPart.name[4] = (u8)('0' + i);
|
bootPart.name[4] = (u8)('0' + i);
|
||||||
bootPart.name[5] = 0;
|
bootPart.name[5] = 0;
|
||||||
|
|
||||||
@@ -874,7 +871,7 @@ static void _restore_emmc_selected(emmcPartType_t restoreType)
|
|||||||
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
memcpy(bootPart.name, "BOOT", 4);
|
strcpy(bootPart.name, "BOOT");
|
||||||
bootPart.name[4] = (u8)('0' + i);
|
bootPart.name[4] = (u8)('0' + i);
|
||||||
bootPart.name[5] = 0;
|
bootPart.name[5] = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -201,40 +201,33 @@ void print_mmc_info()
|
|||||||
gfx_printf("%kExtended CSD V1.%d:%k\n",
|
gfx_printf("%kExtended CSD V1.%d:%k\n",
|
||||||
0xFF00DDFF, storage.ext_csd.ext_struct, 0xFFCCCCCC);
|
0xFF00DDFF, storage.ext_csd.ext_struct, 0xFFCCCCCC);
|
||||||
card_type = storage.ext_csd.card_type;
|
card_type = storage.ext_csd.card_type;
|
||||||
u8 card_type_support[96];
|
char card_type_support[96];
|
||||||
u8 pos_type = 0;
|
|
||||||
card_type_support[0] = 0;
|
card_type_support[0] = 0;
|
||||||
if (card_type & EXT_CSD_CARD_TYPE_HS_26)
|
if (card_type & EXT_CSD_CARD_TYPE_HS_26)
|
||||||
{
|
{
|
||||||
memcpy(card_type_support, "HS26", 4);
|
strcat(card_type_support, "HS26");
|
||||||
speed = (26 << 16) | 26;
|
speed = (26 << 16) | 26;
|
||||||
pos_type += 4;
|
|
||||||
}
|
}
|
||||||
if (card_type & EXT_CSD_CARD_TYPE_HS_52)
|
if (card_type & EXT_CSD_CARD_TYPE_HS_52)
|
||||||
{
|
{
|
||||||
memcpy(card_type_support + pos_type, ", HS52", 6);
|
strcat(card_type_support, ", HS52");
|
||||||
speed = (52 << 16) | 52;
|
speed = (52 << 16) | 52;
|
||||||
pos_type += 6;
|
|
||||||
}
|
}
|
||||||
if (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
|
if (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
|
||||||
{
|
{
|
||||||
memcpy(card_type_support + pos_type, ", DDR52_1.8V", 12);
|
strcat(card_type_support, ", DDR52_1.8V");
|
||||||
speed = (52 << 16) | 104;
|
speed = (52 << 16) | 104;
|
||||||
pos_type += 12;
|
|
||||||
}
|
}
|
||||||
if (card_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
|
if (card_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
|
||||||
{
|
{
|
||||||
memcpy(card_type_support + pos_type, ", HS200_1.8V", 12);
|
strcat(card_type_support, ", HS200_1.8V");
|
||||||
speed = (200 << 16) | 200;
|
speed = (200 << 16) | 200;
|
||||||
pos_type += 12;
|
|
||||||
}
|
}
|
||||||
if (card_type & EXT_CSD_CARD_TYPE_HS400_1_8V)
|
if (card_type & EXT_CSD_CARD_TYPE_HS400_1_8V)
|
||||||
{
|
{
|
||||||
memcpy(card_type_support + pos_type, ", HS400_1.8V", 12);
|
strcat(card_type_support, ", HS400_1.8V");
|
||||||
speed = (200 << 16) | 400;
|
speed = (200 << 16) | 400;
|
||||||
pos_type += 12;
|
|
||||||
}
|
}
|
||||||
card_type_support[pos_type] = 0;
|
|
||||||
|
|
||||||
gfx_printf(
|
gfx_printf(
|
||||||
" Spec Version: %02X\n"
|
" Spec Version: %02X\n"
|
||||||
@@ -420,7 +413,6 @@ void print_tsec_key()
|
|||||||
for (u32 j = 0; j < 0x10; j++)
|
for (u32 j = 0; j < 0x10; j++)
|
||||||
gfx_printf("%02X", keys[j]);
|
gfx_printf("%02X", keys[j]);
|
||||||
|
|
||||||
|
|
||||||
if (pkg1_id->kb == KB_FIRMWARE_VERSION_620)
|
if (pkg1_id->kb == KB_FIRMWARE_VERSION_620)
|
||||||
{
|
{
|
||||||
gfx_printf("\n%kTSEC root: %k", 0xFF00DDFF, 0xFFCCCCCC);
|
gfx_printf("\n%kTSEC root: %k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||||
|
|||||||
@@ -480,13 +480,13 @@ void _fix_sd_attr(u32 type)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
memcpy(path, "/", 2);
|
strcpy(path, "/");
|
||||||
memcpy(label, "SD Card", 8);
|
strcpy(label, "SD Card");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
default:
|
default:
|
||||||
memcpy(path, "/Nintendo", 10);
|
strcpy(path, "/Nintendo");
|
||||||
memcpy(label, "Nintendo folder", 16);
|
strcpy(label, "Nintendo folder");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,11 +262,12 @@ void display_color_screen(u32 color)
|
|||||||
u32 *display_init_framebuffer()
|
u32 *display_init_framebuffer()
|
||||||
{
|
{
|
||||||
// Sanitize framebuffer area.
|
// Sanitize framebuffer area.
|
||||||
memset((u32 *)FB_ADDRESS, 0, 0x3C0000);
|
memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
|
||||||
|
|
||||||
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
|
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
|
||||||
usleep(35000);
|
usleep(35000);
|
||||||
|
|
||||||
return (u32 *)FB_ADDRESS;
|
return (u32 *)IPL_FB_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -18,10 +18,9 @@
|
|||||||
#ifndef _DI_H_
|
#ifndef _DI_H_
|
||||||
#define _DI_H_
|
#define _DI_H_
|
||||||
|
|
||||||
|
#include "../../common/memory_map.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
#define FB_ADDRESS 0xC0000000
|
|
||||||
|
|
||||||
/*! Display registers. */
|
/*! Display registers. */
|
||||||
#define _DIREG(reg) ((reg) * 4)
|
#define _DIREG(reg) ((reg) * 4)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -415,7 +415,7 @@ static const cfg_op_t _display_config_11[113] = {
|
|||||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||||
{DC_DISP_BACK_PORCH, 0x90048},
|
{DC_DISP_BACK_PORCH, 0x90048},
|
||||||
{DC_DISP_ACTIVE, 0x50002D0},
|
{DC_DISP_ACTIVE, 0x50002D0},
|
||||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||||
/* End of Display timings */
|
/* End of Display timings */
|
||||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||||
@@ -548,7 +548,7 @@ static const cfg_op_t cfg_display_framebuffer[32] = {
|
|||||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||||
{DC_WIN_BUFFER_CONTROL, 0},
|
{DC_WIN_BUFFER_CONTROL, 0},
|
||||||
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
||||||
{DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address.
|
{DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
|
||||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018-2019 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -185,7 +185,7 @@ void gfx_putc(char c)
|
|||||||
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
|
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
|
||||||
u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride;
|
u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride;
|
||||||
|
|
||||||
for (u32 i = 0; i < 16; i+=2)
|
for (u32 i = 0; i < 16; i += 2)
|
||||||
{
|
{
|
||||||
u8 v = *cbuf++;
|
u8 v = *cbuf++;
|
||||||
for (u32 k = 0; k < 2; k++)
|
for (u32 k = 0; k < 2; k++)
|
||||||
@@ -254,7 +254,6 @@ void gfx_putc(char c)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx_puts(const char *s)
|
void gfx_puts(const char *s)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018-2019 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
* Copyright (C) 2018 M4xw
|
* Copyright (c) 2018 M4xw
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -157,14 +157,9 @@ void *tui_do_menu(menu_t *menu)
|
|||||||
gfx_con_setcol(0xFFCCCCCC, 1, 0xFF1B1B1B);
|
gfx_con_setcol(0xFFCCCCCC, 1, 0xFF1B1B1B);
|
||||||
gfx_putc('\n');
|
gfx_putc('\n');
|
||||||
|
|
||||||
// Print help and battery status.
|
// Print errors, help and battery status.
|
||||||
gfx_con_setpos(0, 1127);
|
gfx_con_setpos(0, 1127);
|
||||||
if (h_cfg.errors)
|
gfx_printf("%k Warning: %k Nyx is missing!", 0xFF800000, 0xFF555555);
|
||||||
{
|
|
||||||
gfx_printf("%k Warning: %k", 0xFF800000, 0xFF555555);
|
|
||||||
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
|
||||||
gfx_printf("Sleep mode library is missing!\n");
|
|
||||||
}
|
|
||||||
gfx_con_setpos(0, 1191);
|
gfx_con_setpos(0, 1191);
|
||||||
gfx_printf("%k VOL: Move up/down\n PWR: Select option%k", 0xFF555555, 0xFFCCCCCC);
|
gfx_printf("%k VOL: Move up/down\n PWR: Select option%k", 0xFF555555, 0xFFCCCCCC);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
extern hekate_config h_cfg;
|
extern hekate_config h_cfg;
|
||||||
|
|
||||||
|
extern void *sd_file_read(const char *path, u32 *fsize);
|
||||||
|
extern bool is_ipl_updated(void *buf, char *path, bool force);
|
||||||
|
|
||||||
#define FSS0_MAGIC 0x30535346
|
#define FSS0_MAGIC 0x30535346
|
||||||
#define CNT_TYPE_FSP 0
|
#define CNT_TYPE_FSP 0
|
||||||
#define CNT_TYPE_EXO 1
|
#define CNT_TYPE_EXO 1
|
||||||
@@ -62,7 +65,32 @@ typedef struct _fss_content_t
|
|||||||
char name[0x10];
|
char name[0x10];
|
||||||
} fss_content_t;
|
} fss_content_t;
|
||||||
|
|
||||||
int parse_fss(launch_ctxt_t *ctxt, const char *value)
|
static void _update_r2p(const char *path)
|
||||||
|
{
|
||||||
|
char *r2p_path = malloc(256);
|
||||||
|
u32 path_len = strlen(path);
|
||||||
|
strcpy(r2p_path, path);
|
||||||
|
|
||||||
|
while(path_len)
|
||||||
|
{
|
||||||
|
if ((r2p_path[path_len - 1] == '/') || (r2p_path[path_len - 1] == 0x5C))
|
||||||
|
{
|
||||||
|
r2p_path[path_len] = 0;
|
||||||
|
strcat(r2p_path, "reboot_payload.bin");
|
||||||
|
u8 *r2p_payload = sd_file_read(r2p_path, NULL);
|
||||||
|
|
||||||
|
is_ipl_updated(r2p_payload, r2p_path, h_cfg.updater2p ? true : false);
|
||||||
|
|
||||||
|
free(r2p_payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
path_len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(r2p_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_fss(launch_ctxt_t *ctxt, const char *path)
|
||||||
{
|
{
|
||||||
FIL fp;
|
FIL fp;
|
||||||
|
|
||||||
@@ -78,7 +106,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *value)
|
|||||||
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
|
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ctxt->atmosphere = true;
|
ctxt->atmosphere = true;
|
||||||
@@ -139,6 +167,8 @@ int parse_fss(launch_ctxt_t *ctxt, const char *value)
|
|||||||
gfx_printf("Done!\n");
|
gfx_printf("Done!\n");
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
|
||||||
|
_update_r2p(path);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,6 @@
|
|||||||
|
|
||||||
#include "hos.h"
|
#include "hos.h"
|
||||||
|
|
||||||
int parse_fss(launch_ctxt_t *ctxt, const char *value);
|
int parse_fss(launch_ctxt_t *ctxt, const char *path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -103,9 +103,10 @@ static const u8 console_keyseed_4xx_5xx[0x10] =
|
|||||||
|
|
||||||
static void _hos_crit_error(const char *text)
|
static void _hos_crit_error(const char *text)
|
||||||
{
|
{
|
||||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
|
||||||
gfx_con.mute = false;
|
gfx_con.mute = false;
|
||||||
gfx_printf("%k%s%k\n", 0xFFFF0000, text, 0xFFCCCCCC);
|
gfx_printf("%k%s%k\n", 0xFFFF0000, text, 0xFFCCCCCC);
|
||||||
|
|
||||||
|
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _se_lock(bool lock_se)
|
static void _se_lock(bool lock_se)
|
||||||
@@ -113,11 +114,11 @@ static void _se_lock(bool lock_se)
|
|||||||
if (lock_se)
|
if (lock_se)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < 16; i++)
|
for (u32 i = 0; i < 16; i++)
|
||||||
se_key_acc_ctrl(i, 0x15);
|
se_key_acc_ctrl(i, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
|
||||||
|
|
||||||
for (u32 i = 0; i < 2; i++)
|
for (u32 i = 0; i < 2; i++)
|
||||||
se_rsa_acc_ctrl(i, 1);
|
se_rsa_acc_ctrl(i, SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||||
SE(0x4) = 0; // Make this reg secure only.
|
SE(SE_TZRAM_SECURITY_0) = 0; // Make SE TZRAM secure only.
|
||||||
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = 0; // Make all key access regs secure only.
|
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = 0; // Make all key access regs secure only.
|
||||||
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = 0; // Make all RSA access regs secure only.
|
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = 0; // Make all RSA access regs secure only.
|
||||||
SE(SE_SECURITY_0) &= 0xFFFFFFFB; // Make access lock regs secure only.
|
SE(SE_SECURITY_0) &= 0xFFFFFFFB; // Make access lock regs secure only.
|
||||||
@@ -263,8 +264,8 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
se_key_acc_ctrl(13, 0x15);
|
se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
|
||||||
se_key_acc_ctrl(14, 0x15);
|
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
|
||||||
|
|
||||||
// Set TSEC key.
|
// Set TSEC key.
|
||||||
se_aes_key_set(13, tmp, 0x10);
|
se_aes_key_set(13, tmp, 0x10);
|
||||||
@@ -319,7 +320,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Package2 key.
|
// Package2 key.
|
||||||
se_key_acc_ctrl(8, 0x15);
|
se_key_acc_ctrl(8, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
|
||||||
se_aes_unwrap_key(8, 12, package2_keyseed);
|
se_aes_unwrap_key(8, 12, package2_keyseed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,11 +329,20 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt)
|
|||||||
|
|
||||||
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
|
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
|
||||||
{
|
{
|
||||||
int res = 0;
|
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
|
|
||||||
emummc_storage_init_mmc(&storage, &sdmmc);
|
int res = emummc_storage_init_mmc(&storage, &sdmmc);
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (res == 2)
|
||||||
|
_hos_crit_error("Failed to init eMMC");
|
||||||
|
else
|
||||||
|
_hos_crit_error("Failed to init emuMMC");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Read package1.
|
// Read package1.
|
||||||
ctxt->pkg1 = (void *)malloc(0x40000);
|
ctxt->pkg1 = (void *)malloc(0x40000);
|
||||||
@@ -363,8 +373,18 @@ static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt)
|
|||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
|
|
||||||
if (!emummc_storage_init_mmc(&storage, &sdmmc))
|
int res = emummc_storage_init_mmc(&storage, &sdmmc);
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (res == 2)
|
||||||
|
_hos_crit_error("Failed to init eMMC");
|
||||||
|
else
|
||||||
|
_hos_crit_error("Failed to init emuMMC");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
emummc_storage_set_mmc_partition(&storage, 0);
|
emummc_storage_set_mmc_partition(&storage, 0);
|
||||||
|
|
||||||
// Parse eMMC GPT.
|
// Parse eMMC GPT.
|
||||||
@@ -484,7 +504,7 @@ int hos_launch(ini_sec_t *cfg)
|
|||||||
|
|
||||||
if (!keygen(ctxt.keyblob, ctxt.pkg1_id->kb, &tsec_ctxt, &ctxt))
|
if (!keygen(ctxt.keyblob, ctxt.pkg1_id->kb, &tsec_ctxt, &ctxt))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("Generated keys\n");
|
gfx_printf("Generated keys\n");
|
||||||
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
|
||||||
h_cfg.se_keygen_done = 1;
|
h_cfg.se_keygen_done = 1;
|
||||||
}
|
}
|
||||||
@@ -553,6 +573,8 @@ DPRINTF("Generated keys\n");
|
|||||||
if (!pkg2_hdr)
|
if (!pkg2_hdr)
|
||||||
{
|
{
|
||||||
_hos_crit_error("Pkg2 decryption failed!");
|
_hos_crit_error("Pkg2 decryption failed!");
|
||||||
|
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
||||||
|
EPRINTF("Is Sept updated?");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +603,7 @@ DPRINTF("Generated keys\n");
|
|||||||
if (!ctxt.pkg2_kernel_id)
|
if (!ctxt.pkg2_kernel_id)
|
||||||
{
|
{
|
||||||
_hos_crit_error("Failed to identify kernel!");
|
_hos_crit_error("Failed to identify kernel!");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +642,6 @@ DPRINTF("Generated keys\n");
|
|||||||
if (unappliedPatch != NULL)
|
if (unappliedPatch != NULL)
|
||||||
{
|
{
|
||||||
EHPRINTFARGS("Failed to apply '%s'!", unappliedPatch);
|
EHPRINTFARGS("Failed to apply '%s'!", unappliedPatch);
|
||||||
sd_unmount(); // Just exiting is not enough until pkg2_patch_kips stops modifying the string passed into it.
|
|
||||||
|
|
||||||
_free_launch_components(&ctxt);
|
_free_launch_components(&ctxt);
|
||||||
return 0; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
|
return 0; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
|
||||||
@@ -652,16 +674,16 @@ DPRINTF("Generated keys\n");
|
|||||||
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id.
|
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id.
|
||||||
else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301)
|
else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301)
|
||||||
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id.
|
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id.
|
||||||
se_key_acc_ctrl(12, 0xFF);
|
se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
|
||||||
se_key_acc_ctrl(13, 0xFF);
|
se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
|
||||||
bootStateDramPkg2 = 2;
|
bootStateDramPkg2 = 2;
|
||||||
bootStatePkg2Continue = 3;
|
bootStatePkg2Continue = 3;
|
||||||
break;
|
break;
|
||||||
case KB_FIRMWARE_VERSION_400:
|
case KB_FIRMWARE_VERSION_400:
|
||||||
case KB_FIRMWARE_VERSION_500:
|
case KB_FIRMWARE_VERSION_500:
|
||||||
case KB_FIRMWARE_VERSION_600:
|
case KB_FIRMWARE_VERSION_600:
|
||||||
se_key_acc_ctrl(12, 0xFF);
|
se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
|
||||||
se_key_acc_ctrl(15, 0xFF);
|
se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG);
|
||||||
default:
|
default:
|
||||||
bootStateDramPkg2 = 2;
|
bootStateDramPkg2 = 2;
|
||||||
bootStatePkg2Continue = 4;
|
bootStatePkg2Continue = 4;
|
||||||
@@ -723,7 +745,7 @@ DPRINTF("Generated keys\n");
|
|||||||
// Flush cache and disable MMU.
|
// Flush cache and disable MMU.
|
||||||
bpmp_mmu_disable();
|
bpmp_mmu_disable();
|
||||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||||
minerva_change_freq(FREQ_800);
|
minerva_change_freq(FREQ_1600);
|
||||||
|
|
||||||
// emuMMC: Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
// emuMMC: Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||||
sdmmc_storage_init_wait_sd();
|
sdmmc_storage_init_wait_sd();
|
||||||
|
|||||||
@@ -33,7 +33,8 @@
|
|||||||
#define KB_FIRMWARE_VERSION_700 7
|
#define KB_FIRMWARE_VERSION_700 7
|
||||||
#define KB_FIRMWARE_VERSION_810 8
|
#define KB_FIRMWARE_VERSION_810 8
|
||||||
#define KB_FIRMWARE_VERSION_900 9
|
#define KB_FIRMWARE_VERSION_900 9
|
||||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_900
|
#define KB_FIRMWARE_VERSION_910 10
|
||||||
|
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_910
|
||||||
|
|
||||||
#define HOS_PKG11_MAGIC 0x31314B50
|
#define HOS_PKG11_MAGIC 0x31314B50
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ typedef struct _launch_ctxt_t
|
|||||||
bool stock;
|
bool stock;
|
||||||
bool atmosphere;
|
bool atmosphere;
|
||||||
bool exo_no_user_exceptions;
|
bool exo_no_user_exceptions;
|
||||||
|
bool exo_user_pmu;
|
||||||
bool emuMMC;
|
bool emuMMC;
|
||||||
|
|
||||||
ini_sec_t *cfg;
|
ini_sec_t *cfg;
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||||||
if (!memcmp(value + strlen(value) - 1, "*", 1))
|
if (!memcmp(value + strlen(value) - 1, "*", 1))
|
||||||
{
|
{
|
||||||
char *dir = (char *)malloc(256);
|
char *dir = (char *)malloc(256);
|
||||||
memcpy(dir, value, strlen(value) + 1);
|
strcpy(dir, value);
|
||||||
|
|
||||||
u32 dirlen = 0;
|
u32 dirlen = 0;
|
||||||
dir[strlen(dir) - 2] = 0;
|
dir[strlen(dir) - 2] = 0;
|
||||||
char *filelist = dirlist(dir, "*.kip*", false);
|
char *filelist = dirlist(dir, "*.kip*", false);
|
||||||
|
|
||||||
memcpy(dir + strlen(dir), "/", 2);
|
strcat(dir, "/");
|
||||||
dirlen = strlen(dir);
|
dirlen = strlen(dir);
|
||||||
|
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
@@ -82,7 +82,7 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||||||
if (!filelist[i * 256])
|
if (!filelist[i * 256])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
memcpy(dir + dirlen, &filelist[i * 256], strlen(&filelist[i * 256]) + 1);
|
strcpy(dir + dirlen, &filelist[i * 256]);
|
||||||
|
|
||||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||||
mkip1->kip1 = sd_file_read(dir, &size);
|
mkip1->kip1 = sd_file_read(dir, &size);
|
||||||
@@ -201,6 +201,16 @@ static int _config_dis_exo_user_exceptions(launch_ctxt_t *ctxt, const char *valu
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value)
|
||||||
|
{
|
||||||
|
if (*value == '1')
|
||||||
|
{
|
||||||
|
DPRINTF("Enabled user access to PMU\n");
|
||||||
|
ctxt->exo_user_pmu = true;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int _config_fss(launch_ctxt_t *ctxt, const char *value)
|
static int _config_fss(launch_ctxt_t *ctxt, const char *value)
|
||||||
{
|
{
|
||||||
return parse_fss(ctxt, value);
|
return parse_fss(ctxt, value);
|
||||||
@@ -223,6 +233,7 @@ static const cfg_handler_t _config_handlers[] = {
|
|||||||
{ "stock", _config_stock },
|
{ "stock", _config_stock },
|
||||||
{ "atmosphere", _config_atmosphere },
|
{ "atmosphere", _config_atmosphere },
|
||||||
{ "nouserexceptions", _config_dis_exo_user_exceptions },
|
{ "nouserexceptions", _config_dis_exo_user_exceptions },
|
||||||
|
{ "userpmu", _config_exo_user_pmu_access },
|
||||||
{ "fss0", _config_fss },
|
{ "fss0", _config_fss },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "pkg1.h"
|
#include "pkg1.h"
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
|
#include "../mem/heap.h"
|
||||||
#include "../sec/se.h"
|
#include "../sec/se.h"
|
||||||
#include "../utils/aarch64_util.h"
|
#include "../utils/aarch64_util.h"
|
||||||
|
|
||||||
@@ -133,19 +134,20 @@ PATCHSET_DEF(_warmboot_4_patchset,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static const pkg1_id_t _pkg1_ids[] = {
|
static const pkg1_id_t _pkg1_ids[] = {
|
||||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, _secmon_1_patchset, _warmboot_1_patchset }, //1.0.0 (Patched relocator)
|
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, _secmon_1_patchset, _warmboot_1_patchset }, //1.0.0 (Patched relocator)
|
||||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_2_patchset, _warmboot_2_patchset }, //2.0.0 - 2.3.0
|
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_2_patchset, _warmboot_2_patchset }, //2.0.0 - 2.3.0
|
||||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0
|
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0
|
||||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2
|
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2
|
||||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0
|
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0
|
||||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_4_patchset }, //5.0.0 - 5.1.0
|
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_4_patchset }, //5.0.0 - 5.1.0
|
||||||
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_4_patchset }, //6.0.0 - 6.1.0
|
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_4_patchset }, //6.0.0 - 6.1.0
|
||||||
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_4_patchset }, //6.2.0
|
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_4_patchset }, //6.2.0
|
||||||
{ "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.0
|
{ "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.0
|
||||||
{ "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.1
|
{ "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.1
|
||||||
{ "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.0.0 - 8.0.1
|
{ "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.0.0 - 8.0.1
|
||||||
{ "20190531152432", 8, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.1.0
|
{ "20190531152432", 8, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.1.0
|
||||||
{ "20190809135709", 9, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.0.0
|
{ "20190809135709", 9, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.0.0 - 9.0.1
|
||||||
|
{ "20191021113848", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.1.0
|
||||||
{ NULL } //End.
|
{ NULL } //End.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ KERNEL_PATCHSET_DEF(_kernel_5_patchset,
|
|||||||
{ SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications
|
{ SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications
|
||||||
{ DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
{ DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||||
// Atmosphère kernel patches.
|
// 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_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_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.
|
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), // Branch back and skip 2 instructions.
|
||||||
@@ -279,6 +280,7 @@ KERNEL_PATCHSET_DEF(_kernel_6_patchset,
|
|||||||
{ SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications
|
{ SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications
|
||||||
{ DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
{ DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||||
// Atmosphère kernel patches.
|
// 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_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_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.
|
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), // Branch back and skip 4 instructions.
|
||||||
@@ -294,6 +296,7 @@ KERNEL_PATCHSET_DEF(_kernel_7_patchset,
|
|||||||
{ SVC_VERIFY_DS, 0x49E5C, _NOP(), NULL }, // Disable SVC verifications
|
{ SVC_VERIFY_DS, 0x49E5C, _NOP(), NULL }, // Disable SVC verifications
|
||||||
{ DEBUG_MODE_EN, 0x581B0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
{ DEBUG_MODE_EN, 0x581B0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||||
// Atmosphère kernel patches.
|
// 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_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_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.
|
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
|
||||||
@@ -309,6 +312,7 @@ KERNEL_PATCHSET_DEF(_kernel_8_patchset,
|
|||||||
{ SVC_VERIFY_DS, 0x4D15C, _NOP(), NULL }, // Disable SVC verifications
|
{ SVC_VERIFY_DS, 0x4D15C, _NOP(), NULL }, // Disable SVC verifications
|
||||||
{ DEBUG_MODE_EN, 0x5BFAC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
{ DEBUG_MODE_EN, 0x5BFAC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||||
// Atmosphère kernel patches.
|
// 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_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_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.
|
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
|
||||||
@@ -324,6 +328,7 @@ KERNEL_PATCHSET_DEF(_kernel_9_patchset,
|
|||||||
{ SVC_VERIFY_DS, 0x50628, _NOP(), NULL }, // Disable SVC verifications
|
{ SVC_VERIFY_DS, 0x50628, _NOP(), NULL }, // Disable SVC verifications
|
||||||
{ DEBUG_MODE_EN, 0x609E8, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
{ DEBUG_MODE_EN, 0x609E8, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||||
// Atmosphère kernel patches.
|
// 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_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_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.
|
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), // Branch back and skip 4 instructions.
|
||||||
@@ -344,9 +349,9 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
|
|||||||
{ "\xe6\xc0\xb7\xe3\x2f\xf9\x44\x51", _kernel_4_patchset }, //4.0.0 - 4.1.0
|
{ "\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
|
{ "\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
|
{ "\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
|
{ "\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. Kernel only.
|
{ "\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. Kernel only.
|
{ "\x69\x00\x39\xdf\x21\x56\x70\x6b", _kernel_9_patchset } //9.0.0 - 9.1.0. Kernel only.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum kip_offset_section
|
enum kip_offset_section
|
||||||
@@ -533,6 +538,20 @@ static kip1_patchset_t _fs_patches_900[] =
|
|||||||
{ NULL, NULL }
|
{ 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 }
|
||||||
|
};
|
||||||
|
|
||||||
// SHA256 hashes.
|
// SHA256 hashes.
|
||||||
static kip1_id_t _kip_ids[] =
|
static kip1_id_t _kip_ids[] =
|
||||||
{
|
{
|
||||||
@@ -565,7 +584,9 @@ static kip1_id_t _kip_ids[] =
|
|||||||
{ "FS", "\x6B\x09\xB6\x7B\x29\xC0\x20\x24", _fs_patches_800 }, // FS 8.1.0
|
{ "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", "\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", "\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", "\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
|
||||||
};
|
};
|
||||||
|
|
||||||
static void parse_external_kip_patches()
|
static void parse_external_kip_patches()
|
||||||
@@ -574,10 +595,6 @@ static void parse_external_kip_patches()
|
|||||||
char path[64];
|
char path[64];
|
||||||
strcpy(path, "bootloader/patches.ini");
|
strcpy(path, "bootloader/patches.ini");
|
||||||
|
|
||||||
// If patches.ini not found, try to load from template.
|
|
||||||
if (f_stat(path, NULL))
|
|
||||||
strcpy(path, "bootloader/patches_template.ini");
|
|
||||||
|
|
||||||
LIST_INIT(ini_kip_sections);
|
LIST_INIT(ini_kip_sections);
|
||||||
if (ini_patch_parse(&ini_kip_sections, path))
|
if (ini_patch_parse(&ini_kip_sections, path))
|
||||||
{
|
{
|
||||||
@@ -588,7 +605,7 @@ static void parse_external_kip_patches()
|
|||||||
|
|
||||||
if (!strcmp(curr_kip->name, ini_psec->name) && !memcmp(curr_kip->hash, ini_psec->hash, 8))
|
if (!strcmp(curr_kip->name, ini_psec->name) && !memcmp(curr_kip->hash, ini_psec->hash, 8))
|
||||||
{
|
{
|
||||||
kip1_patchset_t *patchsets = (kip1_patchset_t *)calloc(sizeof(kip1_patchset_t), 8);
|
kip1_patchset_t *patchsets = (kip1_patchset_t *)calloc(sizeof(kip1_patchset_t), 8); // Max 8 patchsets per kip.
|
||||||
|
|
||||||
u32 curr_patchset_idx;
|
u32 curr_patchset_idx;
|
||||||
for(curr_patchset_idx = 0; curr_kip->patchset[curr_patchset_idx].name != NULL; curr_patchset_idx++)
|
for(curr_patchset_idx = 0; curr_kip->patchset[curr_patchset_idx].name != NULL; curr_patchset_idx++)
|
||||||
@@ -602,7 +619,7 @@ static void parse_external_kip_patches()
|
|||||||
u32 curr_patch_idx = 0;
|
u32 curr_patch_idx = 0;
|
||||||
|
|
||||||
// Parse patches and glue them together to a patchset.
|
// Parse patches and glue them together to a patchset.
|
||||||
kip1_patch_t *patches = calloc(sizeof(kip1_patch_t), 16);
|
kip1_patch_t *patches = calloc(sizeof(kip1_patch_t), 16); // Max 16 patches per set.
|
||||||
LIST_FOREACH_ENTRY(ini_patchset_t, pt, &ini_psec->pts, link)
|
LIST_FOREACH_ENTRY(ini_patchset_t, pt, &ini_psec->pts, link)
|
||||||
{
|
{
|
||||||
if (first_ext_patch)
|
if (first_ext_patch)
|
||||||
@@ -614,11 +631,12 @@ static void parse_external_kip_patches()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Check if new patchset name is found and create a new set.
|
||||||
if (strcmp(pt->name, patchsets[curr_patchset_idx].name))
|
if (strcmp(pt->name, patchsets[curr_patchset_idx].name))
|
||||||
{
|
{
|
||||||
curr_patchset_idx++;
|
curr_patchset_idx++;
|
||||||
curr_patch_idx = 0;
|
curr_patch_idx = 0;
|
||||||
patches = calloc(sizeof(kip1_patch_t), 16);
|
patches = calloc(sizeof(kip1_patch_t), 16); // Max 16 patches per set.
|
||||||
|
|
||||||
patchsets[curr_patchset_idx].name = malloc(strlen(pt->name) + 1);
|
patchsets[curr_patchset_idx].name = malloc(strlen(pt->name) + 1);
|
||||||
strcpy(patchsets[curr_patchset_idx].name, pt->name);
|
strcpy(patchsets[curr_patchset_idx].name, pt->name);
|
||||||
@@ -636,6 +654,8 @@ static void parse_external_kip_patches()
|
|||||||
memcpy(patches[curr_patch_idx].srcData, pt->srcData, pt->length);
|
memcpy(patches[curr_patch_idx].srcData, pt->srcData, pt->length);
|
||||||
memcpy(patches[curr_patch_idx].dstData, pt->dstData, pt->length);
|
memcpy(patches[curr_patch_idx].dstData, pt->dstData, pt->length);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
patches[curr_patch_idx].srcData = malloc(1); // Empty patches check. Keep everything else as 0.
|
||||||
|
|
||||||
curr_patch_idx++;
|
curr_patch_idx++;
|
||||||
}
|
}
|
||||||
@@ -1024,13 +1044,20 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 appliedMask = 1u << currEnabIdx;
|
u32 appliedMask = 1u << currEnabIdx;
|
||||||
if (currPatchset->patches == NULL || !strcmp(currPatchset->name, "emummc"))
|
|
||||||
|
if (!strcmp(currPatchset->name, "emummc"))
|
||||||
|
{
|
||||||
|
emummc_patch_selected = true;
|
||||||
|
patchesApplied |= appliedMask;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currPatchset->patches == NULL)
|
||||||
{
|
{
|
||||||
gfx_printf("Patch '%s' not necessary for %s KIP1\n", currPatchset->name, (const char*)ki->kip1->name);
|
gfx_printf("Patch '%s' not necessary for %s KIP1\n", currPatchset->name, (const char*)ki->kip1->name);
|
||||||
patchesApplied |= appliedMask;
|
patchesApplied |= appliedMask;
|
||||||
|
|
||||||
if (!strcmp(currPatchset->name, "emummc"))
|
|
||||||
emummc_patch_selected = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,15 +1067,23 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
|
|||||||
if (bitsAffected & (1u << currSectIdx))
|
if (bitsAffected & (1u << currSectIdx))
|
||||||
{
|
{
|
||||||
gfx_printf("Applying patch '%s' on %s KIP1 sect %d\n", currPatchset->name, (const char*)ki->kip1->name, currSectIdx);
|
gfx_printf("Applying patch '%s' on %s KIP1 sect %d\n", currPatchset->name, (const char*)ki->kip1->name, currSectIdx);
|
||||||
for (const kip1_patch_t* currPatch = currPatchset->patches; currPatch != NULL && currPatch->length != 0; currPatch++)
|
for (const kip1_patch_t* currPatch = currPatchset->patches; currPatch != NULL && currPatch->srcData != 0; currPatch++)
|
||||||
{
|
{
|
||||||
if (GET_KIP_PATCH_SECTION(currPatch->offset) != currSectIdx)
|
if (GET_KIP_PATCH_SECTION(currPatch->offset) != currSectIdx)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 currOffset = GET_KIP_PATCH_OFFSET(currPatch->offset);
|
if (!currPatch->length)
|
||||||
if (memcmp(&kipSectData[currOffset], currPatch->srcData, currPatch->length) != 0)
|
|
||||||
{
|
{
|
||||||
gfx_printf("%kDATA MISMATCH FOR PATCH AT OFFSET 0x%x!!!%k\n", 0xFFFF0000, currOffset, 0xFFCCCCCC);
|
gfx_printf("%kPatch is empty!%k\n", 0xFFFF0000, 0xFFCCCCCC);
|
||||||
|
return currPatchset->name; // MUST stop here as it's not probably intended.
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 currOffset = GET_KIP_PATCH_OFFSET(currPatch->offset);
|
||||||
|
// If source is 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))
|
||||||
|
{
|
||||||
|
gfx_printf("%kPatch data mismatch at 0x%x!%k\n", 0xFFFF0000, currOffset, 0xFFCCCCCC);
|
||||||
return currPatchset->name; // MUST stop here as kip is likely corrupt.
|
return currPatchset->name; // MUST stop here as kip is likely corrupt.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1066,7 +1101,7 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
|
|||||||
}
|
}
|
||||||
currPatchset++;
|
currPatchset++;
|
||||||
}
|
}
|
||||||
if (!strncmp(_kip_ids[currKipIdx].name, "FS", 2) && emummc_patch_selected)
|
if (emummc_patch_selected && !strncmp(_kip_ids[currKipIdx].name, "FS", 2))
|
||||||
{
|
{
|
||||||
emummc_patch_selected = false;
|
emummc_patch_selected = false;
|
||||||
emu_cfg.fs_ver = currKipIdx;
|
emu_cfg.fs_ver = currKipIdx;
|
||||||
@@ -1091,11 +1126,31 @@ const char* pkg2_patch_kips(link_t *info, char* patchNames)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t mkey_keyseed_8xx[][0x10] =
|
static const u8 mkey_keyseed_8xx[][0x10] =
|
||||||
{
|
{
|
||||||
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80} // Master key 8 encrypted with 9.
|
// 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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool _pkg2_key_unwrap_validate(pkg2_hdr_t *tmp_test, pkg2_hdr_t *hdr, u8 src_slot, u8 *mkey, const u8 *key_seed)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Decrypt older encrypted mkey.
|
||||||
|
se_aes_crypt_ecb(src_slot, 0, mkey, 0x10, key_seed, 0x10);
|
||||||
|
// Set and unwrap pkg2 key.
|
||||||
|
se_aes_key_clear(9);
|
||||||
|
se_aes_key_set(9, mkey, 0x10);
|
||||||
|
se_aes_unwrap_key(9, 9, package2_keyseed);
|
||||||
|
|
||||||
|
// Decrypt header.
|
||||||
|
se_aes_crypt_ctr(9, tmp_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||||
|
|
||||||
|
// Return if header is valid.
|
||||||
|
return (tmp_test->magic == PKG2_MAGIC);
|
||||||
|
}
|
||||||
|
|
||||||
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
||||||
{
|
{
|
||||||
pkg2_hdr_t mkey_test;
|
pkg2_hdr_t mkey_test;
|
||||||
@@ -1110,25 +1165,58 @@ pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb)
|
|||||||
// Skip header.
|
// Skip header.
|
||||||
pdata += sizeof(pkg2_hdr_t);
|
pdata += sizeof(pkg2_hdr_t);
|
||||||
|
|
||||||
//! Check if we need to decrypt with newer mkeys. Valid for 8.1.0 and up.
|
//! Check if we need to decrypt with newer mkeys. Valid for sept for 8.1.0 and up.
|
||||||
|
se_aes_crypt_ctr(8, &mkey_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||||
|
|
||||||
|
if (mkey_test.magic == PKG2_MAGIC)
|
||||||
|
goto key_found;
|
||||||
|
|
||||||
|
// Decrypt older pkg2 via new mkeys.
|
||||||
if ((kb >= KB_FIRMWARE_VERSION_810) && (kb < KB_FIRMWARE_VERSION_MAX))
|
if ((kb >= KB_FIRMWARE_VERSION_810) && (kb < KB_FIRMWARE_VERSION_MAX))
|
||||||
{
|
{
|
||||||
u8 tmp_mkey[0x10];
|
u8 tmp_mkey[0x10];
|
||||||
// Decrypt older encrypted mkey.
|
u8 decr_slot = 12; // Sept mkey.
|
||||||
se_aes_crypt_ecb(12, 0, tmp_mkey, 0x10, mkey_keyseed_8xx[KB_FIRMWARE_VERSION_MAX - kb - 1], 0x10);
|
u8 mkey_seeds_cnt = sizeof(mkey_keyseed_8xx) / 0x10;
|
||||||
// Set and unwrap pkg2 key.
|
u8 mkey_seeds_idx = mkey_seeds_cnt; // Real index + 1.
|
||||||
se_aes_key_set(9, tmp_mkey, 0x10);
|
u8 mkey_seeds_min_idx = mkey_seeds_cnt - (KB_FIRMWARE_VERSION_MAX - kb);
|
||||||
se_aes_unwrap_key(9, 9, package2_keyseed);
|
|
||||||
|
|
||||||
// Decrypt header and test if it's valid.
|
while (mkey_seeds_cnt)
|
||||||
se_aes_crypt_ctr(9, &mkey_test, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
{
|
||||||
|
// Decrypt and validate mkey.
|
||||||
|
int res = _pkg2_key_unwrap_validate(&mkey_test, hdr, decr_slot,
|
||||||
|
tmp_mkey, mkey_keyseed_8xx[mkey_seeds_idx - 1]);
|
||||||
|
|
||||||
if (mkey_test.magic == PKG2_MAGIC)
|
if (res)
|
||||||
keyslot = 9;
|
{
|
||||||
else
|
keyslot = 9;
|
||||||
se_aes_key_clear(9);
|
goto key_found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set current mkey in order to decrypt a lower mkey.
|
||||||
|
mkey_seeds_idx--;
|
||||||
|
se_aes_key_clear(9);
|
||||||
|
se_aes_key_set(9, tmp_mkey, 0x10);
|
||||||
|
|
||||||
|
decr_slot = 9; // Temp key.
|
||||||
|
|
||||||
|
// Check if we tried last key for that pkg2 version.
|
||||||
|
// And start with a lower mkey in case sept is older.
|
||||||
|
if (mkey_seeds_idx == mkey_seeds_min_idx)
|
||||||
|
{
|
||||||
|
mkey_seeds_cnt--;
|
||||||
|
mkey_seeds_idx = mkey_seeds_cnt;
|
||||||
|
decr_slot = 12; // Sept mkey.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Out of keys. pkg2 is latest or process failed.
|
||||||
|
if (!mkey_seeds_cnt)
|
||||||
|
se_aes_key_clear(9);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key_found:
|
||||||
// Decrypt header.
|
// Decrypt header.
|
||||||
se_aes_crypt_ctr(keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
se_aes_crypt_ctr(keyslot, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||||
//gfx_hexdump((u32)hdr, hdr, 0x100);
|
//gfx_hexdump((u32)hdr, hdr, 0x100);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018-2019 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -54,10 +54,11 @@ enum
|
|||||||
SVC_GENERIC = 0,
|
SVC_GENERIC = 0,
|
||||||
// Generic instruction patches.
|
// Generic instruction patches.
|
||||||
SVC_VERIFY_DS = 0x10,
|
SVC_VERIFY_DS = 0x10,
|
||||||
DEBUG_MODE_EN,
|
DEBUG_MODE_EN = 0x11,
|
||||||
ATM_GEN_PATCH,
|
ATM_GEN_PATCH = 0x12,
|
||||||
|
ATM_SYSM_INCR = ATM_GEN_PATCH,
|
||||||
// >4 bytes patches. Value is a pointer of a u32 array.
|
// >4 bytes patches. Value is a pointer of a u32 array.
|
||||||
ATM_ARR_PATCH,
|
ATM_ARR_PATCH = 0x13,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _pkg2_hdr_t
|
typedef struct _pkg2_hdr_t
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ typedef struct _atm_fatal_error_ctx
|
|||||||
#define EXO_FLAG_DBG_PRIV (1 << 1)
|
#define EXO_FLAG_DBG_PRIV (1 << 1)
|
||||||
#define EXO_FLAG_DBG_USER (1 << 2)
|
#define EXO_FLAG_DBG_USER (1 << 2)
|
||||||
#define EXO_FLAG_NO_USER_EXC (1 << 3)
|
#define EXO_FLAG_NO_USER_EXC (1 << 3)
|
||||||
|
#define EXO_FLAG_USER_PMU (1 << 4)
|
||||||
|
|
||||||
void config_exosphere(launch_ctxt_t *ctxt)
|
void config_exosphere(launch_ctxt_t *ctxt)
|
||||||
{
|
{
|
||||||
@@ -172,6 +173,10 @@ void config_exosphere(launch_ctxt_t *ctxt)
|
|||||||
if (ctxt->exo_no_user_exceptions)
|
if (ctxt->exo_no_user_exceptions)
|
||||||
exoFlags |= EXO_FLAG_NO_USER_EXC;
|
exoFlags |= EXO_FLAG_NO_USER_EXC;
|
||||||
|
|
||||||
|
// Enable user access to PMU.
|
||||||
|
if (ctxt->exo_user_pmu)
|
||||||
|
exoFlags |= EXO_FLAG_USER_PMU;
|
||||||
|
|
||||||
// Set mailbox values.
|
// Set mailbox values.
|
||||||
exo_cfg->magic = EXO_MAGIC_VAL;
|
exo_cfg->magic = EXO_MAGIC_VAL;
|
||||||
|
|
||||||
@@ -271,10 +276,10 @@ void secmon_exo_check_panic()
|
|||||||
// Save context to the SD card.
|
// Save context to the SD card.
|
||||||
char filepath[0x40];
|
char filepath[0x40];
|
||||||
f_mkdir("atmosphere/fatal_errors");
|
f_mkdir("atmosphere/fatal_errors");
|
||||||
memcpy(filepath, "/atmosphere/fatal_errors/report_", 33);
|
strcpy(filepath, "/atmosphere/fatal_errors/report_");
|
||||||
itoa((u32)((u64)rpt->report_identifier >> 32), filepath + strlen(filepath), 16);
|
itoa((u32)((u64)rpt->report_identifier >> 32), filepath + strlen(filepath), 16);
|
||||||
itoa((u32)(rpt->report_identifier), filepath + strlen(filepath), 16);
|
itoa((u32)(rpt->report_identifier), filepath + strlen(filepath), 16);
|
||||||
memcpy(filepath + strlen(filepath), ".bin", 5);
|
strcat(filepath, ".bin");
|
||||||
|
|
||||||
sd_save_to_file((void *)rpt, sizeof(atm_fatal_error_ctx), filepath);
|
sd_save_to_file((void *)rpt, sizeof(atm_fatal_error_ctx), filepath);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2018-2019 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -91,11 +91,17 @@ void check_sept()
|
|||||||
|
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
if (!emummc_storage_init_mmc(&storage, &sdmmc))
|
int res = emummc_storage_init_mmc(&storage, &sdmmc);
|
||||||
|
if (res)
|
||||||
{
|
{
|
||||||
EPRINTF("Failed to init eMMC.");
|
if (res == 2)
|
||||||
|
EPRINTF("Failed to init eMMC");
|
||||||
|
else
|
||||||
|
EPRINTF("Failed to init emuMMC");
|
||||||
|
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
emummc_storage_set_mmc_partition(&storage, 1);
|
emummc_storage_set_mmc_partition(&storage, 1);
|
||||||
|
|
||||||
// Read package1.
|
// Read package1.
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../../../common/memory_map.h"
|
||||||
|
|
||||||
#include "diskio.h" /* FatFs lower layer API */
|
#include "diskio.h" /* FatFs lower layer API */
|
||||||
#include "../../storage/sdmmc.h"
|
#include "../../storage/sdmmc.h"
|
||||||
|
|
||||||
#define SDMMC_UPPER_BUFFER 0xB8000000
|
|
||||||
#define DRAM_START 0x80000000
|
|
||||||
|
|
||||||
extern sdmmc_storage_t sd_storage;
|
extern sdmmc_storage_t sd_storage;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
@@ -46,7 +46,8 @@ DRESULT disk_read (
|
|||||||
UINT count /* Number of sectors to read */
|
UINT count /* Number of sectors to read */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ((u32)buff >= DRAM_START)
|
// Ensure that buffer resides in DRAM and it's DMA aligned.
|
||||||
|
if (((u32)buff >= DRAM_START) && !((u32)buff % 8))
|
||||||
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
|
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
|
||||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||||
if (sdmmc_storage_read(&sd_storage, sector, count, buf))
|
if (sdmmc_storage_read(&sd_storage, sector, count, buf))
|
||||||
@@ -67,9 +68,10 @@ DRESULT disk_write (
|
|||||||
UINT count /* Number of sectors to write */
|
UINT count /* Number of sectors to write */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ((u32)buff >= DRAM_START)
|
// Ensure that buffer resides in DRAM and it's DMA aligned.
|
||||||
|
if (((u32)buff >= DRAM_START) && !((u32)buff % 8))
|
||||||
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere.
|
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||||
memcpy(buf, buff, 512 * count);
|
memcpy(buf, buff, 512 * count);
|
||||||
if (sdmmc_storage_write(&sd_storage, sector, count, buf))
|
if (sdmmc_storage_write(&sd_storage, sector, count, buf))
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "../common/memory_map.h"
|
||||||
|
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "gfx/di.h"
|
#include "gfx/di.h"
|
||||||
#include "gfx/gfx.h"
|
#include "gfx/gfx.h"
|
||||||
@@ -250,19 +252,39 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_ipl_updated(void *buf)
|
bool is_ipl_updated(void *buf, char *path, bool force)
|
||||||
{
|
{
|
||||||
ipl_ver_meta_t *update_ft = (ipl_ver_meta_t *)(buf + PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
ipl_ver_meta_t *update_ft = (ipl_ver_meta_t *)(buf + PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
||||||
|
|
||||||
if (update_ft->magic == ipl_ver.magic)
|
// Check if newer version.
|
||||||
{
|
if (!force && (update_ft->magic == ipl_ver.magic))
|
||||||
if (byte_swap_32(update_ft->version) <= byte_swap_32(ipl_ver.version))
|
if (byte_swap_32(update_ft->version) > byte_swap_32(ipl_ver.version))
|
||||||
return true;
|
return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
|
// Update if old or broken.
|
||||||
|
if ((force && (update_ft->magic != ipl_ver.magic)) ||
|
||||||
|
(byte_swap_32(update_ft->version) < byte_swap_32(ipl_ver.version)))
|
||||||
|
{
|
||||||
|
FIL fp;
|
||||||
|
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
|
||||||
|
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
||||||
|
memset(tmp_cfg, 0, sizeof(boot_cfg_t));
|
||||||
|
|
||||||
|
f_open(&fp, path, FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
|
f_write(&fp, (u8 *)reloc->start, reloc->end - reloc->start, NULL);
|
||||||
|
|
||||||
|
// Write needed tag in case injected ipl uses old versioning.
|
||||||
|
f_write(&fp, "ICTC49", 6, NULL);
|
||||||
|
|
||||||
|
// Reset boot storage configuration.
|
||||||
|
f_lseek(&fp, PATCHED_RELOC_SZ);
|
||||||
|
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
|
||||||
|
|
||||||
|
f_close(&fp);
|
||||||
|
free(tmp_cfg);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int launch_payload(char *path, bool update)
|
int launch_payload(char *path, bool update)
|
||||||
@@ -270,8 +292,6 @@ int launch_payload(char *path, bool update)
|
|||||||
if (!update)
|
if (!update)
|
||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
if (!path)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (sd_mount())
|
if (sd_mount())
|
||||||
{
|
{
|
||||||
@@ -279,9 +299,8 @@ int launch_payload(char *path, bool update)
|
|||||||
if (f_open(&fp, path, FA_READ))
|
if (f_open(&fp, path, FA_READ))
|
||||||
{
|
{
|
||||||
EPRINTFARGS("Payload file is missing!\n(%s)", path);
|
EPRINTFARGS("Payload file is missing!\n(%s)", path);
|
||||||
sd_unmount();
|
|
||||||
|
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and copy the payload to our chosen address
|
// Read and copy the payload to our chosen address
|
||||||
@@ -296,15 +315,14 @@ int launch_payload(char *path, bool update)
|
|||||||
if (f_read(&fp, buf, size, NULL))
|
if (f_read(&fp, buf, size, NULL))
|
||||||
{
|
{
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
sd_unmount();
|
|
||||||
|
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
|
||||||
if (update && is_ipl_updated(buf))
|
if (update && is_ipl_updated(buf, path, false))
|
||||||
return 1;
|
goto out;
|
||||||
|
|
||||||
sd_unmount();
|
sd_unmount();
|
||||||
|
|
||||||
@@ -339,6 +357,10 @@ int launch_payload(char *path, bool update)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (!update)
|
||||||
|
sd_unmount();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,6 +429,7 @@ void launch_tools()
|
|||||||
free(dir);
|
free(dir);
|
||||||
free(filelist);
|
free(filelist);
|
||||||
sd_unmount();
|
sd_unmount();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -422,17 +445,13 @@ void launch_tools()
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (file_sec)
|
if (file_sec)
|
||||||
{
|
{
|
||||||
memcpy(dir + strlen(dir), "/", 2);
|
memcpy(dir + strlen(dir), "/", 2);
|
||||||
memcpy(dir + strlen(dir), file_sec, strlen(file_sec) + 1);
|
memcpy(dir + strlen(dir), file_sec, strlen(file_sec) + 1);
|
||||||
|
|
||||||
if (launch_payload(dir, false))
|
launch_payload(dir, false);
|
||||||
{
|
EPRINTF("Failed to launch payload.");
|
||||||
EPRINTF("Failed to launch payload.");
|
|
||||||
free(dir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -532,11 +551,9 @@ void ini_list_launcher()
|
|||||||
|
|
||||||
if (payload_path)
|
if (payload_path)
|
||||||
{
|
{
|
||||||
if (launch_payload(payload_path, false))
|
launch_payload(payload_path, false);
|
||||||
{
|
EPRINTF("Failed to launch payload.");
|
||||||
EPRINTF("Failed to launch payload.");
|
free(payload_path);
|
||||||
free(payload_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!hos_launch(cfg_sec))
|
else if (!hos_launch(cfg_sec))
|
||||||
{
|
{
|
||||||
@@ -666,11 +683,9 @@ void launch_firmware()
|
|||||||
|
|
||||||
if (payload_path)
|
if (payload_path)
|
||||||
{
|
{
|
||||||
if (launch_payload(payload_path, false))
|
launch_payload(payload_path, false);
|
||||||
{
|
EPRINTF("Failed to launch payload.");
|
||||||
EPRINTF("Failed to launch payload.");
|
free(payload_path);
|
||||||
free(payload_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!hos_launch(cfg_sec))
|
else if (!hos_launch(cfg_sec))
|
||||||
EPRINTF("Failed to launch firmware.");
|
EPRINTF("Failed to launch firmware.");
|
||||||
@@ -683,6 +698,8 @@ out:
|
|||||||
btn_wait();
|
btn_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define NYX_VER_OFF 0x9C
|
||||||
|
|
||||||
void nyx_load_run()
|
void nyx_load_run()
|
||||||
{
|
{
|
||||||
sd_mount();
|
sd_mount();
|
||||||
@@ -693,6 +710,9 @@ void nyx_load_run()
|
|||||||
|
|
||||||
sd_unmount();
|
sd_unmount();
|
||||||
|
|
||||||
|
u32 expected_nyx_ver = ((NYX_VER_MJ + '0') << 24) | ((NYX_VER_MN + '0') << 16) | ((NYX_VER_HF + '0') << 8);
|
||||||
|
u32 nyx_ver = byte_swap_32(*(u32 *)(nyx + NYX_VER_OFF));
|
||||||
|
|
||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
u8 *BOOTLOGO = (void *)malloc(0x4000);
|
u8 *BOOTLOGO = (void *)malloc(0x4000);
|
||||||
blz_uncompress_srcdest(BOOTLOGO_BLZ, SZ_BOOTLOGO_BLZ, BOOTLOGO, SZ_BOOTLOGO);
|
blz_uncompress_srcdest(BOOTLOGO_BLZ, SZ_BOOTLOGO_BLZ, BOOTLOGO, SZ_BOOTLOGO);
|
||||||
@@ -700,16 +720,29 @@ void nyx_load_run()
|
|||||||
free(BOOTLOGO);
|
free(BOOTLOGO);
|
||||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||||
|
|
||||||
|
// Check if Nyx version is old.
|
||||||
|
if (nyx_ver < expected_nyx_ver)
|
||||||
|
{
|
||||||
|
h_cfg.errors |= ERR_SYSOLD_NYX;
|
||||||
|
|
||||||
|
gfx_con_setpos(0, 0);
|
||||||
|
WPRINTF("Old Nyx GUI found! There will be dragons!\n");
|
||||||
|
WPRINTF("\nUpdate your bootloader folder!\n\n");
|
||||||
|
WPRINTF("Press any key...");
|
||||||
|
|
||||||
|
msleep(2000);
|
||||||
|
btn_wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
nyx_str->info.errors = h_cfg.errors;
|
||||||
nyx_str->cfg = 0;
|
nyx_str->cfg = 0;
|
||||||
if (b_cfg.extra_cfg & EXTRA_CFG_NYX_DUMP)
|
if (b_cfg.extra_cfg & EXTRA_CFG_NYX_DUMP)
|
||||||
{
|
{
|
||||||
b_cfg.extra_cfg &= ~(EXTRA_CFG_NYX_DUMP);
|
b_cfg.extra_cfg &= ~(EXTRA_CFG_NYX_DUMP);
|
||||||
nyx_str->cfg |= NYX_CFG_DUMP;
|
nyx_str->cfg |= NYX_CFG_DUMP;
|
||||||
}
|
}
|
||||||
if (nyx_str->mtc_cfg.mtc_table)
|
|
||||||
nyx_str->cfg |= NYX_CFG_MINERVA;
|
|
||||||
|
|
||||||
nyx_str->version = ipl_ver.version - 0x303030;
|
nyx_str->version = ipl_ver.version - 0x303030; // Convert ASCII to numbers.
|
||||||
|
|
||||||
//memcpy((u8 *)nyx_str->irama, (void *)IRAM_BASE, 0x8000);
|
//memcpy((u8 *)nyx_str->irama, (void *)IRAM_BASE, 0x8000);
|
||||||
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
|
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
|
||||||
@@ -727,7 +760,7 @@ void nyx_load_run()
|
|||||||
(*nyx_ptr)();
|
(*nyx_ptr)();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char *bootlogoCustomEntry)
|
static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomEntry)
|
||||||
{
|
{
|
||||||
ini_sec_t *cfg_sec = NULL;
|
ini_sec_t *cfg_sec = NULL;
|
||||||
|
|
||||||
@@ -741,20 +774,20 @@ static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char *bootlogoCustomEn
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!strcmp("logopath", kv->key))
|
if (!strcmp("logopath", kv->key))
|
||||||
bootlogoCustomEntry = kv->val;
|
*bootlogoCustomEntry = kv->val;
|
||||||
if (!strcmp("emummc_force_disable", kv->key))
|
if (!strcmp("emummc_force_disable", kv->key))
|
||||||
h_cfg.emummc_force_disable = atoi(kv->val);
|
h_cfg.emummc_force_disable = atoi(kv->val);
|
||||||
}
|
}
|
||||||
if (!cfg_sec)
|
if (!cfg_sec)
|
||||||
{
|
{
|
||||||
bootlogoCustomEntry = NULL;
|
*bootlogoCustomEntry = NULL;
|
||||||
h_cfg.emummc_force_disable = false;
|
h_cfg.emummc_force_disable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg_sec;
|
return cfg_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void auto_launch_firmware()
|
static void _auto_launch_firmware()
|
||||||
{
|
{
|
||||||
if(b_cfg.extra_cfg & EXTRA_CFG_NYX_DUMP)
|
if(b_cfg.extra_cfg & EXTRA_CFG_NYX_DUMP)
|
||||||
{
|
{
|
||||||
@@ -829,6 +862,8 @@ void auto_launch_firmware()
|
|||||||
h_cfg.autohosoff = atoi(kv->val);
|
h_cfg.autohosoff = atoi(kv->val);
|
||||||
else if (!strcmp("autonogc", kv->key))
|
else if (!strcmp("autonogc", kv->key))
|
||||||
h_cfg.autonogc = atoi(kv->val);
|
h_cfg.autonogc = atoi(kv->val);
|
||||||
|
else if (!strcmp("updater2p", kv->key))
|
||||||
|
h_cfg.updater2p = atoi(kv->val);
|
||||||
else if (!strcmp("brand", kv->key))
|
else if (!strcmp("brand", kv->key))
|
||||||
{
|
{
|
||||||
h_cfg.brand = malloc(strlen(kv->val) + 1);
|
h_cfg.brand = malloc(strlen(kv->val) + 1);
|
||||||
@@ -858,7 +893,7 @@ void auto_launch_firmware()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (boot_from_id)
|
if (boot_from_id)
|
||||||
cfg_sec = get_ini_sec_from_id(ini_sec, bootlogoCustomEntry);
|
cfg_sec = get_ini_sec_from_id(ini_sec, &bootlogoCustomEntry);
|
||||||
else if (h_cfg.autoboot == boot_entry_id && configEntry)
|
else if (h_cfg.autoboot == boot_entry_id && configEntry)
|
||||||
{
|
{
|
||||||
cfg_sec = ini_sec;
|
cfg_sec = ini_sec;
|
||||||
@@ -898,7 +933,7 @@ void auto_launch_firmware()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (boot_from_id)
|
if (boot_from_id)
|
||||||
cfg_sec = get_ini_sec_from_id(ini_sec_list, bootlogoCustomEntry);
|
cfg_sec = get_ini_sec_from_id(ini_sec_list, &bootlogoCustomEntry);
|
||||||
else if (h_cfg.autoboot == boot_entry_id)
|
else if (h_cfg.autoboot == boot_entry_id)
|
||||||
{
|
{
|
||||||
h_cfg.emummc_force_disable = false;
|
h_cfg.emummc_force_disable = false;
|
||||||
@@ -915,7 +950,6 @@ void auto_launch_firmware()
|
|||||||
break;
|
break;
|
||||||
boot_entry_id++;
|
boot_entry_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1006,7 +1040,7 @@ skip_list:
|
|||||||
// Wait before booting. If VOL- is pressed go into bootloader menu.
|
// Wait before booting. If VOL- is pressed go into bootloader menu.
|
||||||
if (!h_cfg.sept_run && !(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
if (!h_cfg.sept_run && !(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||||
{
|
{
|
||||||
btn = btn_wait_timeout(h_cfg.bootwait * 1000, BTN_VOL_DOWN);
|
btn = btn_wait_timeout(h_cfg.bootwait * 1000, BTN_VOL_DOWN | BTN_SINGLE);
|
||||||
|
|
||||||
if (btn & BTN_VOL_DOWN)
|
if (btn & BTN_VOL_DOWN)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1016,13 +1050,18 @@ skip_list:
|
|||||||
|
|
||||||
if (payload_path)
|
if (payload_path)
|
||||||
{
|
{
|
||||||
if (launch_payload(payload_path, false))
|
launch_payload(payload_path, false);
|
||||||
free(payload_path);
|
free(payload_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
check_sept();
|
check_sept();
|
||||||
hos_launch(cfg_sec);
|
hos_launch(cfg_sec);
|
||||||
|
|
||||||
|
EPRINTF("\nFailed to launch HOS!");
|
||||||
|
gfx_printf("\nPress any key...\n");
|
||||||
|
msleep(500);
|
||||||
|
btn_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1039,7 +1078,7 @@ out:
|
|||||||
sd_unmount();
|
sd_unmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void patched_rcm_protection()
|
static void _patched_rcm_protection()
|
||||||
{
|
{
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
@@ -1081,7 +1120,28 @@ void patched_rcm_protection()
|
|||||||
sdmmc_storage_end(&storage);
|
sdmmc_storage_end(&storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void about()
|
static void _show_errors()
|
||||||
|
{
|
||||||
|
if (h_cfg.errors)
|
||||||
|
{
|
||||||
|
gfx_clear_grey(0x1B);
|
||||||
|
gfx_con_setpos(0, 0);
|
||||||
|
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||||
|
|
||||||
|
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
||||||
|
WPRINTF("Missing LP0 (sleep mode) library!\n");
|
||||||
|
if (h_cfg.errors & ERR_SYSOLD_MTC)
|
||||||
|
WPRINTF("Missing or old Minerva library!\n");
|
||||||
|
|
||||||
|
WPRINTF("\nUpdate your bootloader folder!\n\n");
|
||||||
|
WPRINTF("Press any key...");
|
||||||
|
|
||||||
|
msleep(2000);
|
||||||
|
btn_wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _about()
|
||||||
{
|
{
|
||||||
static const char credits[] =
|
static const char credits[] =
|
||||||
"\nhekate (c) 2018 naehrwert, st4rk\n\n"
|
"\nhekate (c) 2018 naehrwert, st4rk\n\n"
|
||||||
@@ -1098,8 +1158,8 @@ void about()
|
|||||||
" Copyright (c) 2018, ChaN\n\n"
|
" Copyright (c) 2018, ChaN\n\n"
|
||||||
" - bcl-1.2.0,\n"
|
" - bcl-1.2.0,\n"
|
||||||
" Copyright (c) 2003-2006, Marcus Geelnard\n\n"
|
" Copyright (c) 2003-2006, Marcus Geelnard\n\n"
|
||||||
" - Atmosphere (SE sha256, prc id patches),\n"
|
" - Atmosphere (Exo st/types, prc id patches),\n"
|
||||||
" Copyright (c) 2018, Atmosphere-NX\n\n"
|
" Copyright (c) 2018-2019, Atmosphere-NX\n\n"
|
||||||
" - elfload,\n"
|
" - elfload,\n"
|
||||||
" Copyright (c) 2014, Owen Shepherd\n"
|
" Copyright (c) 2014, Owen Shepherd\n"
|
||||||
" Copyright (c) 2018, M4xw\n"
|
" Copyright (c) 2018, M4xw\n"
|
||||||
@@ -1229,15 +1289,11 @@ ment_t ment_top[] = {
|
|||||||
MDEF_HANDLER("Reboot (RCM)", reboot_rcm),
|
MDEF_HANDLER("Reboot (RCM)", reboot_rcm),
|
||||||
MDEF_HANDLER("Power off", power_off),
|
MDEF_HANDLER("Power off", power_off),
|
||||||
MDEF_CAPTION("---------------", 0xFF444444),
|
MDEF_CAPTION("---------------", 0xFF444444),
|
||||||
MDEF_HANDLER("About", about),
|
MDEF_HANDLER("About", _about),
|
||||||
MDEF_END()
|
MDEF_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.0.2", 0, 0 };
|
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.1.1", 0, 0 };
|
||||||
|
|
||||||
#define IPL_STACK_TOP 0x90010000
|
|
||||||
#define IPL_HEAP_START 0x90020000
|
|
||||||
#define IPL_HEAP_END 0xB5000000
|
|
||||||
|
|
||||||
extern void pivot_stack(u32 stack_top);
|
extern void pivot_stack(u32 stack_top);
|
||||||
|
|
||||||
@@ -1267,8 +1323,8 @@ void ipl_main()
|
|||||||
h_cfg.errors |= ERR_LIBSYS_LP0;
|
h_cfg.errors |= ERR_LIBSYS_LP0;
|
||||||
|
|
||||||
// Train DRAM and switch to max frequency.
|
// Train DRAM and switch to max frequency.
|
||||||
minerva_init();
|
if (minerva_init())
|
||||||
minerva_change_freq(FREQ_1600);
|
h_cfg.errors |= ERR_SYSOLD_MTC;
|
||||||
|
|
||||||
display_init();
|
display_init();
|
||||||
|
|
||||||
@@ -1286,19 +1342,22 @@ void ipl_main()
|
|||||||
//display_backlight_brightness(h_cfg.backlight, 1000);
|
//display_backlight_brightness(h_cfg.backlight, 1000);
|
||||||
|
|
||||||
// Overclock BPMP.
|
// Overclock BPMP.
|
||||||
bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST);
|
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
||||||
|
|
||||||
// Check if we had a panic while in CFW.
|
// Check if we had a panic while in CFW.
|
||||||
secmon_exo_check_panic();
|
secmon_exo_check_panic();
|
||||||
|
|
||||||
// Check if RCM is patched and protect from a possible brick.
|
// Check if RCM is patched and protect from a possible brick.
|
||||||
patched_rcm_protection();
|
_patched_rcm_protection();
|
||||||
|
|
||||||
// Load emuMMC configuration from SD.
|
// Load emuMMC configuration from SD.
|
||||||
emummc_load_cfg();
|
emummc_load_cfg();
|
||||||
|
|
||||||
|
// Show library errors.
|
||||||
|
_show_errors();
|
||||||
|
|
||||||
// Load saved configuration and auto boot if enabled.
|
// Load saved configuration and auto boot if enabled.
|
||||||
auto_launch_firmware();
|
_auto_launch_firmware();
|
||||||
|
|
||||||
minerva_change_freq(FREQ_800);
|
minerva_change_freq(FREQ_800);
|
||||||
|
|
||||||
|
|||||||
1186
bootloader/mem/emc.h
1186
bootloader/mem/emc.h
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
#include "../gfx/gfx.h"
|
||||||
#include "../../common/common_heap.h"
|
#include "../../common/common_heap.h"
|
||||||
|
|
||||||
static void _heap_create(heap_t *heap, u32 start)
|
static void _heap_create(heap_t *heap, u32 start)
|
||||||
@@ -25,12 +26,13 @@ static void _heap_create(heap_t *heap, u32 start)
|
|||||||
heap->first = NULL;
|
heap->first = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 _heap_alloc(heap_t *heap, u32 size, u32 alignment)
|
// Node info is before node address.
|
||||||
|
static u32 _heap_alloc(heap_t *heap, u32 size)
|
||||||
{
|
{
|
||||||
hnode_t *node, *new;
|
hnode_t *node, *new;
|
||||||
int search = 1;
|
|
||||||
|
|
||||||
size = ALIGN(size, alignment);
|
// Align to cache line size.
|
||||||
|
size = ALIGN(size, sizeof(hnode_t));
|
||||||
|
|
||||||
if (!heap->first)
|
if (!heap->first)
|
||||||
{
|
{
|
||||||
@@ -45,26 +47,35 @@ static u32 _heap_alloc(heap_t *heap, u32 size, u32 alignment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
node = heap->first;
|
node = heap->first;
|
||||||
while (search)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!node->used && size + sizeof(hnode_t) < node->size)
|
if (!node->used && (size <= node->size))
|
||||||
{
|
{
|
||||||
|
u32 new_size = node->size - size;
|
||||||
new = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
|
new = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
|
||||||
|
|
||||||
new->size = node->size - sizeof(hnode_t) - size;
|
// If there's aligned leftover space, create a new node.
|
||||||
|
if (new_size >= (sizeof(hnode_t) << 2))
|
||||||
|
{
|
||||||
|
new->size = new_size - sizeof(hnode_t);
|
||||||
|
new->used = 0;
|
||||||
|
new->next = node->next;
|
||||||
|
new->next->prev = new;
|
||||||
|
new->prev = node;
|
||||||
|
node->next = new;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
size += new_size;
|
||||||
|
|
||||||
node->size = size;
|
node->size = size;
|
||||||
node->used = 1;
|
node->used = 1;
|
||||||
new->used = 0;
|
|
||||||
new->next = node->next;
|
|
||||||
new->prev = node;
|
|
||||||
node->next = new;
|
|
||||||
|
|
||||||
return (u32)node + sizeof(hnode_t);
|
return (u32)node + sizeof(hnode_t);
|
||||||
}
|
}
|
||||||
if (node->next)
|
if (node->next)
|
||||||
node = node->next;
|
node = node->next;
|
||||||
else
|
else
|
||||||
search = 0;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
|
new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
|
||||||
@@ -107,12 +118,12 @@ void heap_init(u32 base)
|
|||||||
|
|
||||||
void *malloc(u32 size)
|
void *malloc(u32 size)
|
||||||
{
|
{
|
||||||
return (void *)_heap_alloc(&_heap, size, sizeof(hnode_t));
|
return (void *)_heap_alloc(&_heap, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *calloc(u32 num, u32 size)
|
void *calloc(u32 num, u32 size)
|
||||||
{
|
{
|
||||||
void *res = (void *)_heap_alloc(&_heap, num * size, sizeof(hnode_t));
|
void *res = (void *)_heap_alloc(&_heap, num * size);
|
||||||
memset(res, 0, num * size);
|
memset(res, 0, num * size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -122,3 +133,30 @@ void free(void *buf)
|
|||||||
if ((u32)buf >= _heap.start)
|
if ((u32)buf >= _heap.start)
|
||||||
_heap_free(&_heap, (u32)buf);
|
_heap_free(&_heap, (u32)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||||
|
{
|
||||||
|
u32 count = 0;
|
||||||
|
memset(mon, 0, sizeof(heap_monitor_t));
|
||||||
|
|
||||||
|
hnode_t *node = _heap.first;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (node->used)
|
||||||
|
mon->used += node->size + sizeof(hnode_t);
|
||||||
|
else
|
||||||
|
mon->total += node->size + sizeof(hnode_t);
|
||||||
|
|
||||||
|
if (print_node_stats)
|
||||||
|
gfx_printf("%3d - %d, addr: 0x%08X, size: 0x%X\n",
|
||||||
|
count, node->used, (u32)node + sizeof(hnode_t), node->size);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (node->next)
|
||||||
|
node = node->next;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mon->total += mon->used;
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,10 +18,12 @@
|
|||||||
#define _HEAP_H_
|
#define _HEAP_H_
|
||||||
|
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
#include "../../common/common_heap.h"
|
||||||
|
|
||||||
void heap_init(u32 base);
|
void heap_init(u32 base);
|
||||||
void *malloc(u32 size);
|
void *malloc(u32 size);
|
||||||
void *calloc(u32 num, u32 size);
|
void *calloc(u32 num, u32 size);
|
||||||
void free(void *buf);
|
void free(void *buf);
|
||||||
|
void heap_monitor(heap_monitor_t *mon, bool print_node_stats);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -28,20 +28,26 @@
|
|||||||
|
|
||||||
extern volatile nyx_storage_t *nyx_str;
|
extern volatile nyx_storage_t *nyx_str;
|
||||||
|
|
||||||
void minerva_init()
|
u32 minerva_init()
|
||||||
{
|
{
|
||||||
u32 curr_ram_idx = 0;
|
u32 curr_ram_idx = 0;
|
||||||
|
|
||||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||||
|
|
||||||
// Set table to ram.
|
// Set table to nyx storage.
|
||||||
mtc_cfg->mtc_table = NULL;
|
mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table;
|
||||||
|
|
||||||
mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
|
mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
|
||||||
|
mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table.
|
||||||
|
|
||||||
u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
||||||
minerva_cfg = (void *)ep_addr;
|
|
||||||
|
// Ensure that Minerva is new.
|
||||||
|
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
|
||||||
|
minerva_cfg = (void *)ep_addr;
|
||||||
|
|
||||||
if (!minerva_cfg)
|
if (!minerva_cfg)
|
||||||
return;
|
return 1;
|
||||||
|
|
||||||
// Get current frequency
|
// Get current frequency
|
||||||
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
||||||
@@ -58,6 +64,17 @@ void minerva_init()
|
|||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
mtc_cfg->rate_to = 1600000;
|
mtc_cfg->rate_to = 1600000;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
|
|
||||||
|
// FSP WAR.
|
||||||
|
mtc_cfg->train_mode = OP_SWITCH;
|
||||||
|
mtc_cfg->rate_to = 800000;
|
||||||
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
|
|
||||||
|
// Switch to max.
|
||||||
|
mtc_cfg->rate_to = 1600000;
|
||||||
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void minerva_change_freq(minerva_freq_t freq)
|
void minerva_change_freq(minerva_freq_t freq)
|
||||||
@@ -66,7 +83,7 @@ void minerva_change_freq(minerva_freq_t freq)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||||
if (minerva_cfg && (mtc_cfg->rate_from != freq))
|
if (mtc_cfg->rate_from != freq)
|
||||||
{
|
{
|
||||||
mtc_cfg->rate_to = freq;
|
mtc_cfg->rate_to = freq;
|
||||||
mtc_cfg->train_mode = OP_SWITCH;
|
mtc_cfg->train_mode = OP_SWITCH;
|
||||||
@@ -80,7 +97,7 @@ void minerva_periodic_training()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||||
if (minerva_cfg && mtc_cfg->rate_from == FREQ_1600)
|
if (mtc_cfg->rate_from == FREQ_1600)
|
||||||
{
|
{
|
||||||
mtc_cfg->train_mode = OP_PERIODIC_TRAIN;
|
mtc_cfg->train_mode = OP_PERIODIC_TRAIN;
|
||||||
minerva_cfg(mtc_cfg, NULL);
|
minerva_cfg(mtc_cfg, NULL);
|
||||||
|
|||||||
@@ -20,7 +20,10 @@
|
|||||||
#include "mtc_table.h"
|
#include "mtc_table.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
#define EMC_PERIODIC_TRAIN_MS 100
|
#define MTC_INIT_MAGIC 0x3043544D
|
||||||
|
#define MTC_NEW_MAGIC 0x5243544D
|
||||||
|
|
||||||
|
#define EMC_PERIODIC_TRAIN_MS 250
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -35,6 +38,7 @@ typedef struct
|
|||||||
bool emc_2X_clk_src_is_pllmb;
|
bool emc_2X_clk_src_is_pllmb;
|
||||||
bool fsp_for_src_freq;
|
bool fsp_for_src_freq;
|
||||||
bool train_ram_patterns;
|
bool train_ram_patterns;
|
||||||
|
bool init_done;
|
||||||
} mtc_config_t;
|
} mtc_config_t;
|
||||||
|
|
||||||
enum train_mode_t
|
enum train_mode_t
|
||||||
@@ -54,7 +58,7 @@ typedef enum
|
|||||||
} minerva_freq_t;
|
} minerva_freq_t;
|
||||||
|
|
||||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||||
void minerva_init();
|
u32 minerva_init();
|
||||||
void minerva_change_freq(minerva_freq_t freq);
|
void minerva_change_freq(minerva_freq_t freq);
|
||||||
void minerva_periodic_training();
|
void minerva_periodic_training();
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,18 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../soc/i2c.h"
|
|
||||||
#include "../soc/t210.h"
|
|
||||||
#include "mc.h"
|
#include "mc.h"
|
||||||
#include "emc.h"
|
#include "emc.h"
|
||||||
#include "sdram_param_t210.h"
|
#include "sdram_param_t210.h"
|
||||||
#include "../soc/pmc.h"
|
#include "../../common/memory_map.h"
|
||||||
#include "../utils/util.h"
|
|
||||||
#include "../soc/fuse.h"
|
|
||||||
#include "../power/max77620.h"
|
#include "../power/max77620.h"
|
||||||
#include "../power/max7762x.h"
|
#include "../power/max7762x.h"
|
||||||
#include "../soc/clock.h"
|
#include "../soc/clock.h"
|
||||||
|
#include "../soc/fuse.h"
|
||||||
|
#include "../soc/i2c.h"
|
||||||
|
#include "../soc/pmc.h"
|
||||||
|
#include "../soc/t210.h"
|
||||||
|
#include "../utils/util.h"
|
||||||
|
|
||||||
#define CONFIG_SDRAM_COMPRESS_CFG
|
#define CONFIG_SDRAM_COMPRESS_CFG
|
||||||
|
|
||||||
@@ -50,19 +51,31 @@ static u32 _get_sdram_id()
|
|||||||
|
|
||||||
static void _sdram_config(const sdram_params_t *params)
|
static void _sdram_config(const sdram_params_t *params)
|
||||||
{
|
{
|
||||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = (((4 * params->emc_pmc_scratch1 >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;
|
// Program DPD3/DPD4 regs (coldboot path).
|
||||||
|
// Enable sel_dpd on unused pins.
|
||||||
|
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x80000000;
|
||||||
|
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
|
||||||
usleep(params->pmc_io_dpd3_req_wait);
|
usleep(params->pmc_io_dpd3_req_wait);
|
||||||
|
|
||||||
u32 req = (4 * params->emc_pmc_scratch2 >> 2) + 0x80000000;
|
// Disable e_dpd_vttgen.
|
||||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req >> 16 << 16) ^ 0x3FFF0000;
|
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | 0x80000000;
|
||||||
|
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
|
||||||
usleep(params->pmc_io_dpd4_req_wait);
|
usleep(params->pmc_io_dpd4_req_wait);
|
||||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF;
|
|
||||||
|
// Disable e_dpd_bg.
|
||||||
|
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
|
||||||
usleep(params->pmc_io_dpd4_req_wait);
|
usleep(params->pmc_io_dpd4_req_wait);
|
||||||
|
|
||||||
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
|
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
|
||||||
usleep(1);
|
usleep(1);
|
||||||
|
|
||||||
|
// Start clocks.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;
|
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;
|
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;
|
||||||
|
|
||||||
|
// u32 tmp = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20);
|
||||||
|
// CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = tmp;
|
||||||
|
// CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = tmp | 0x40000000;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | 0x40000000 | ((params->pllm_post_divider & 0xFFFF) << 20);
|
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | 0x40000000 | ((params->pllm_post_divider & 0xFFFF) << 20);
|
||||||
|
|
||||||
u32 wait_end = get_tmr_us() + 300;
|
u32 wait_end = get_tmr_us() + 300;
|
||||||
@@ -72,24 +85,35 @@ static void _sdram_config(const sdram_params_t *params)
|
|||||||
goto break_nosleep;
|
goto break_nosleep;
|
||||||
}
|
}
|
||||||
usleep(10);
|
usleep(10);
|
||||||
break_nosleep:
|
|
||||||
|
|
||||||
|
break_nosleep:
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);
|
||||||
if (params->emc_clock_source_dll)
|
if (params->emc_clock_source_dll)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
||||||
if (params->clear_clock2_mc1)
|
if (params->clear_clock2_mc1)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000;
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000;
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001;
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000;
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001;
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock.
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001; // Clear EMC and MEM resets.
|
||||||
|
|
||||||
|
// Set pad macros.
|
||||||
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
|
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
|
||||||
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
|
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
|
||||||
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
|
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
|
||||||
EMC(EMC_TIMING_CONTROL) = 1;
|
|
||||||
usleep(1);
|
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||||
|
usleep(10); // Ensure the regulators settle.
|
||||||
|
|
||||||
|
// Select EMC write mux.
|
||||||
EMC(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;
|
EMC(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;
|
||||||
|
|
||||||
|
// Patch 2 using BCT spare variables.
|
||||||
if (params->emc_bct_spare2)
|
if (params->emc_bct_spare2)
|
||||||
*(vu32 *)params->emc_bct_spare2 = params->emc_bct_spare3;
|
*(vu32 *)params->emc_bct_spare2 = params->emc_bct_spare3;
|
||||||
|
|
||||||
|
// Program CMD mapping. Required before brick mapping, else
|
||||||
|
// we can't guarantee CK will be differential at all times.
|
||||||
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
|
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
|
||||||
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
|
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
|
||||||
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
|
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
|
||||||
@@ -104,25 +128,40 @@ break_nosleep:
|
|||||||
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
|
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
|
||||||
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
|
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
|
||||||
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
|
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
|
||||||
|
|
||||||
|
// Program brick mapping.
|
||||||
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
|
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
|
||||||
EMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;
|
EMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;
|
||||||
EMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;
|
EMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112) | 0x1EED1EED;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112) | 0x1EED1EED;
|
||||||
|
|
||||||
|
// This is required to do any reads from the pad macros.
|
||||||
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
|
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
|
||||||
|
|
||||||
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
|
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
|
||||||
|
|
||||||
|
// Set swizzle for Rank 0.
|
||||||
EMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;
|
EMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;
|
||||||
EMC(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;
|
EMC(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;
|
||||||
EMC(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;
|
EMC(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;
|
||||||
EMC(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;
|
EMC(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;
|
||||||
|
// Set swizzle for Rank 1.
|
||||||
EMC(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;
|
EMC(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;
|
||||||
EMC(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;
|
EMC(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;
|
||||||
EMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;
|
EMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;
|
||||||
EMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;
|
EMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;
|
||||||
|
|
||||||
|
// Patch 4 using BCT spare variables.
|
||||||
if (params->emc_bct_spare6)
|
if (params->emc_bct_spare6)
|
||||||
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
|
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
|
||||||
|
|
||||||
|
// Set pad controls.
|
||||||
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
|
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
|
||||||
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
|
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
|
||||||
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
|
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
|
||||||
|
|
||||||
|
// Program Autocal controls with shadowed register fields.
|
||||||
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
|
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
|
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
|
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
|
||||||
@@ -130,6 +169,7 @@ break_nosleep:
|
|||||||
EMC(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;
|
EMC(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
|
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
|
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
|
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
|
||||||
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
|
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
|
||||||
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
|
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
|
||||||
@@ -137,9 +177,11 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
|
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
|
||||||
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
|
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
|
||||||
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
|
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
|
||||||
|
|
||||||
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
|
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
|
||||||
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
|
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
|
||||||
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
|
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
|
||||||
|
|
||||||
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
|
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
|
||||||
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
|
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
|
||||||
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
|
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
|
||||||
@@ -152,8 +194,10 @@ break_nosleep:
|
|||||||
EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
|
EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
|
||||||
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
|
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
|
||||||
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
|
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;
|
||||||
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
|
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
|
EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;
|
||||||
EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;
|
EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;
|
||||||
@@ -164,6 +208,7 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
|
EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
|
||||||
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
|
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
|
||||||
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
|
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
|
||||||
|
|
||||||
EMC(EMC_CFG_3) = params->emc_cfg3;
|
EMC(EMC_CFG_3) = params->emc_cfg3;
|
||||||
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
|
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
|
||||||
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
|
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
|
||||||
@@ -189,6 +234,7 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
|
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
|
||||||
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
|
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
|
||||||
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
|
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
|
||||||
@@ -202,6 +248,7 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
|
||||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
|
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
|
||||||
@@ -214,6 +261,7 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;
|
||||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;
|
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;
|
||||||
@@ -234,6 +282,7 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;
|
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;
|
||||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
||||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
|
||||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
|
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
|
||||||
@@ -242,10 +291,17 @@ break_nosleep:
|
|||||||
EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
|
EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
|
||||||
EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
|
EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
|
||||||
EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
|
EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
|
||||||
|
|
||||||
|
// Common pad macro (cpm).
|
||||||
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = (params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE;
|
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = (params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE;
|
||||||
|
|
||||||
|
// Patch 3 using BCT spare variables.
|
||||||
if (params->emc_bct_spare4)
|
if (params->emc_bct_spare4)
|
||||||
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
|
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
|
||||||
EMC(EMC_TIMING_CONTROL) = 1;
|
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||||
|
|
||||||
|
// Initialize MC VPR settings.
|
||||||
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
|
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
|
||||||
MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
|
MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
|
||||||
MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
|
MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
|
||||||
@@ -253,20 +309,32 @@ break_nosleep:
|
|||||||
MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
|
MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
|
||||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;
|
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;
|
||||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;
|
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;
|
||||||
|
|
||||||
|
// Program SDRAM geometry parameters.
|
||||||
MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
|
MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
|
||||||
MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
|
MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
|
||||||
MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
|
MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
|
||||||
MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
|
MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
|
||||||
|
|
||||||
|
// Program bank swizzling.
|
||||||
MC(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;
|
MC(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;
|
||||||
MC(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;
|
MC(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;
|
||||||
MC(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;
|
MC(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;
|
||||||
|
|
||||||
|
// Program external memory aperture (base and size).
|
||||||
MC(MC_EMEM_CFG) = params->mc_emem_cfg;
|
MC(MC_EMEM_CFG) = params->mc_emem_cfg;
|
||||||
|
|
||||||
|
// Program SEC carveout (base and size).
|
||||||
MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
|
MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
|
||||||
MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
|
MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
|
||||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;
|
MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;
|
||||||
|
|
||||||
|
// Program MTS carveout (base and size).
|
||||||
MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
|
MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
|
||||||
MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
|
MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
|
||||||
MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;
|
MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;
|
||||||
|
|
||||||
|
// Program the memory arbiter.
|
||||||
MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
|
MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
|
||||||
MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;
|
MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;
|
||||||
MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
|
MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
|
||||||
@@ -295,21 +363,38 @@ break_nosleep:
|
|||||||
MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
|
MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
|
||||||
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
|
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
|
||||||
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
|
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
|
||||||
MC(MC_TIMING_CONTROL) = 1;
|
|
||||||
|
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
||||||
|
|
||||||
|
// Program second-level clock enable overrides.
|
||||||
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
|
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
|
||||||
|
|
||||||
|
// Program statistics gathering.
|
||||||
MC(MC_STAT_CONTROL) = params->mc_stat_control;
|
MC(MC_STAT_CONTROL) = params->mc_stat_control;
|
||||||
|
|
||||||
|
// Program SDRAM geometry parameters.
|
||||||
EMC(EMC_ADR_CFG) = params->emc_adr_cfg;
|
EMC(EMC_ADR_CFG) = params->emc_adr_cfg;
|
||||||
|
|
||||||
|
// Program second-level clock enable overrides.
|
||||||
EMC(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;
|
EMC(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;
|
||||||
|
|
||||||
|
// Program EMC pad auto calibration.
|
||||||
EMC(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;
|
EMC(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;
|
||||||
EMC(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;
|
EMC(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;
|
||||||
EMC(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;
|
EMC(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;
|
||||||
|
|
||||||
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
|
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
|
||||||
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
|
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
|
||||||
|
|
||||||
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
|
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
|
||||||
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
|
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
|
||||||
usleep(params->emc_auto_cal_wait);
|
usleep(params->emc_auto_cal_wait);
|
||||||
|
|
||||||
|
// Patch 5 using BCT spare variables.
|
||||||
if (params->emc_bct_spare8)
|
if (params->emc_bct_spare8)
|
||||||
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
|
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
|
||||||
|
|
||||||
|
// Program EMC timing configuration.
|
||||||
EMC(EMC_CFG_2) = params->emc_cfg2;
|
EMC(EMC_CFG_2) = params->emc_cfg2;
|
||||||
EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
|
EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
|
||||||
EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
|
EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
|
||||||
@@ -354,9 +439,11 @@ break_nosleep:
|
|||||||
EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;
|
EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;
|
||||||
EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
|
EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
|
||||||
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
|
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
|
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
|
||||||
EMC(EMC_DBG) = params->emc_dbg;
|
EMC(EMC_DBG) = params->emc_dbg;
|
||||||
EMC(EMC_QRST) = params->emc_qrst;
|
EMC(EMC_QRST) = params->emc_qrst;
|
||||||
|
EMC(EMC_ISSUE_QRST) = 1;
|
||||||
EMC(EMC_ISSUE_QRST) = 0;
|
EMC(EMC_ISSUE_QRST) = 0;
|
||||||
EMC(EMC_QSAFE) = params->emc_qsafe;
|
EMC(EMC_QSAFE) = params->emc_qsafe;
|
||||||
EMC(EMC_RDV) = params->emc_rdv;
|
EMC(EMC_RDV) = params->emc_rdv;
|
||||||
@@ -389,6 +476,8 @@ break_nosleep:
|
|||||||
EMC(EMC_ODT_WRITE) = params->emc_odt_write;
|
EMC(EMC_ODT_WRITE) = params->emc_odt_write;
|
||||||
EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
|
EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
|
||||||
EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
|
EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
|
||||||
|
|
||||||
|
// Don't write CFG_ADR_EN (bit 1) here - lock bit written later.
|
||||||
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
|
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
|
||||||
EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
|
EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
|
||||||
EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;
|
EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;
|
||||||
@@ -396,70 +485,104 @@ break_nosleep:
|
|||||||
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
|
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
|
||||||
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
|
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
|
||||||
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
|
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
|
||||||
|
|
||||||
|
// Set pipe bypass enable bits before sending any DRAM commands.
|
||||||
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
|
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
|
||||||
|
|
||||||
|
// Patch BootROM.
|
||||||
if (params->boot_rom_patch_control & (1 << 31))
|
if (params->boot_rom_patch_control & (1 << 31))
|
||||||
{
|
{
|
||||||
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
|
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
|
||||||
MC(MC_TIMING_CONTROL) = 1;
|
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
||||||
}
|
}
|
||||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((4 * params->emc_pmc_scratch1 >> 2) + 0x40000000) & 0xCFFF0000;
|
|
||||||
|
// Release SEL_DPD_CMD.
|
||||||
|
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
|
||||||
usleep(params->pmc_io_dpd3_req_wait);
|
usleep(params->pmc_io_dpd3_req_wait);
|
||||||
|
|
||||||
|
// Set autocal interval if not configured.
|
||||||
if (!params->emc_auto_cal_interval)
|
if (!params->emc_auto_cal_interval)
|
||||||
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;
|
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;
|
||||||
|
|
||||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;
|
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;
|
||||||
|
|
||||||
|
// ZQ CAL setup (not actually issuing ZQ CAL now).
|
||||||
if (params->emc_zcal_warm_cold_boot_enables & 1)
|
if (params->emc_zcal_warm_cold_boot_enables & 1)
|
||||||
{
|
{
|
||||||
if (params->memory_type == 2)
|
if (params->memory_type == 2)
|
||||||
EMC(EMC_ZCAL_WAIT_CNT) = 8 * params->emc_zcal_wait_cnt;
|
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt << 3;
|
||||||
if (params->memory_type == 3)
|
if (params->memory_type == 3)
|
||||||
{
|
{
|
||||||
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
|
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
|
||||||
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EMC(EMC_TIMING_CONTROL) = 1;
|
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||||
usleep(params->emc_timing_control_wait);
|
usleep(params->emc_timing_control_wait);
|
||||||
|
|
||||||
|
// Deassert HOLD_CKE_LOW.
|
||||||
PMC(APBDEV_PMC_DDR_CNTRL) &= 0xFFF8007F;
|
PMC(APBDEV_PMC_DDR_CNTRL) &= 0xFFF8007F;
|
||||||
usleep(params->pmc_ddr_ctrl_wait);
|
usleep(params->pmc_ddr_ctrl_wait);
|
||||||
if (params->memory_type == 2)
|
|
||||||
|
// Set clock enable signal.
|
||||||
|
u32 pin_gpio_cfg = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
|
||||||
|
if (params->memory_type == 2 || params->memory_type == 3)
|
||||||
{
|
{
|
||||||
EMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
|
EMC(EMC_PIN) = pin_gpio_cfg;
|
||||||
|
(void)EMC(EMC_PIN);
|
||||||
usleep(params->emc_pin_extra_wait + 200);
|
usleep(params->emc_pin_extra_wait + 200);
|
||||||
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;
|
EMC(EMC_PIN) = pin_gpio_cfg | 0x100;
|
||||||
usleep(params->emc_pin_extra_wait + 500);
|
(void)EMC(EMC_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->memory_type == 3)
|
if (params->memory_type == 3)
|
||||||
{
|
|
||||||
EMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
|
|
||||||
usleep(params->emc_pin_extra_wait + 200);
|
|
||||||
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;
|
|
||||||
usleep(params->emc_pin_extra_wait + 2000);
|
usleep(params->emc_pin_extra_wait + 2000);
|
||||||
}
|
else if (params->memory_type == 2)
|
||||||
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 0x101;
|
usleep(params->emc_pin_extra_wait + 500);
|
||||||
|
|
||||||
|
// Enable clock enable signal.
|
||||||
|
EMC(EMC_PIN) = pin_gpio_cfg | 0x101;
|
||||||
|
(void)EMC(EMC_PIN);
|
||||||
usleep(params->emc_pin_program_wait);
|
usleep(params->emc_pin_program_wait);
|
||||||
|
|
||||||
|
// Send NOP (trigger just needs to be non-zero).
|
||||||
if (params->memory_type != 3)
|
if (params->memory_type != 3)
|
||||||
EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;
|
EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;
|
||||||
|
|
||||||
|
// On coldboot w/LPDDR2/3, wait 200 uSec after asserting CKE high.
|
||||||
if (params->memory_type == 1)
|
if (params->memory_type == 1)
|
||||||
usleep(params->emc_pin_extra_wait + 200);
|
usleep(params->emc_pin_extra_wait + 200);
|
||||||
|
|
||||||
|
// Init zq calibration,
|
||||||
if (params->memory_type == 3)
|
if (params->memory_type == 3)
|
||||||
{
|
{
|
||||||
|
// Patch 6 using BCT spare variables.
|
||||||
if (params->emc_bct_spare10)
|
if (params->emc_bct_spare10)
|
||||||
*(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
|
*(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
|
||||||
|
|
||||||
|
// Write mode registers.
|
||||||
EMC(EMC_MRW2) = params->emc_mrw2;
|
EMC(EMC_MRW2) = params->emc_mrw2;
|
||||||
EMC(EMC_MRW) = params->emc_mrw1;
|
EMC(EMC_MRW) = params->emc_mrw1;
|
||||||
EMC(EMC_MRW3) = params->emc_mrw3;
|
EMC(EMC_MRW3) = params->emc_mrw3;
|
||||||
EMC(EMC_MRW4) = params->emc_mrw4;
|
EMC(EMC_MRW4) = params->emc_mrw4;
|
||||||
EMC(EMC_MRW6) = params->emc_mrw6;
|
EMC(EMC_MRW6) = params->emc_mrw6;
|
||||||
EMC(EMC_MRW14) = params->emc_mrw14;
|
EMC(EMC_MRW14) = params->emc_mrw14;
|
||||||
|
|
||||||
EMC(EMC_MRW8) = params->emc_mrw8;
|
EMC(EMC_MRW8) = params->emc_mrw8;
|
||||||
EMC(EMC_MRW12) = params->emc_mrw12;
|
EMC(EMC_MRW12) = params->emc_mrw12;
|
||||||
EMC(EMC_MRW9) = params->emc_mrw9;
|
EMC(EMC_MRW9) = params->emc_mrw9;
|
||||||
EMC(EMC_MRW13) = params->emc_mrw13;
|
EMC(EMC_MRW13) = params->emc_mrw13;
|
||||||
|
|
||||||
if (params->emc_zcal_warm_cold_boot_enables & 1)
|
if (params->emc_zcal_warm_cold_boot_enables & 1)
|
||||||
{
|
{
|
||||||
|
// Issue ZQCAL start, device 0.
|
||||||
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
|
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
|
||||||
usleep(params->emc_zcal_init_wait);
|
usleep(params->emc_zcal_init_wait);
|
||||||
|
|
||||||
|
// Issue ZQCAL latch.
|
||||||
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
|
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
|
||||||
|
// Same for device 1.
|
||||||
if (!(params->emc_dev_select & 2))
|
if (!(params->emc_dev_select & 2))
|
||||||
{
|
{
|
||||||
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
|
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
|
||||||
@@ -468,42 +591,64 @@ break_nosleep:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set package and DPD pad control.
|
||||||
PMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg;
|
PMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg;
|
||||||
|
|
||||||
|
// Start periodic ZQ calibration (LPDDRx only).
|
||||||
if (params->memory_type - 1 <= 2)
|
if (params->memory_type - 1 <= 2)
|
||||||
{
|
{
|
||||||
EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
|
EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
|
||||||
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
|
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
|
||||||
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Patch 7 using BCT spare variables.
|
||||||
if (params->emc_bct_spare12)
|
if (params->emc_bct_spare12)
|
||||||
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
|
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
|
||||||
EMC(EMC_TIMING_CONTROL) = 1;
|
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||||
|
|
||||||
if (params->emc_extra_refresh_num)
|
if (params->emc_extra_refresh_num)
|
||||||
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 0xFD) | (params->emc_pin_gpio << 30);
|
EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3;
|
||||||
|
|
||||||
|
// Enable refresh.
|
||||||
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
|
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
|
||||||
|
|
||||||
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
|
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
|
||||||
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
|
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
|
||||||
EMC(EMC_CFG) = params->emc_cfg;
|
EMC(EMC_CFG) = params->emc_cfg;
|
||||||
EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
|
EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
|
||||||
EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
|
EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
|
||||||
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
|
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
|
||||||
|
|
||||||
|
// Write addr swizzle lock bit.
|
||||||
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
|
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
|
||||||
EMC(EMC_TIMING_CONTROL) = 1;
|
|
||||||
|
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
|
||||||
|
|
||||||
|
// Enable EMC pipe clock gating.
|
||||||
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
|
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
|
||||||
|
|
||||||
|
// Depending on freqency, enable CMD/CLK fdpd.
|
||||||
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
|
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
|
||||||
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16);
|
|
||||||
|
// Enable arbiter.
|
||||||
|
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | (params->ahb_arbitration_xbar_ctrl_meminit_done << 16);
|
||||||
|
|
||||||
|
// Lock carveouts per BCT cfg.
|
||||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
|
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
|
||||||
MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
|
MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
|
||||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
|
MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
|
||||||
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of EMC registers.
|
|
||||||
|
//Disable write access to a bunch of EMC registers.
|
||||||
|
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdram_params_t *sdram_get_params()
|
sdram_params_t *sdram_get_params()
|
||||||
{
|
{
|
||||||
//TODO: sdram_id should be in [0, 7].
|
|
||||||
|
|
||||||
#ifdef CONFIG_SDRAM_COMPRESS_CFG
|
#ifdef CONFIG_SDRAM_COMPRESS_CFG
|
||||||
u8 *buf = (u8 *)0x40030000;
|
u8 *buf = (u8 *)SDRAM_PARAMS_ADDR;
|
||||||
LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
|
LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
|
||||||
return (sdram_params_t *)&buf[sizeof(sdram_params_t) * _get_sdram_id()];
|
return (sdram_params_t *)&buf[sizeof(sdram_params_t) * _get_sdram_id()];
|
||||||
#else
|
#else
|
||||||
@@ -535,7 +680,17 @@ sdram_params_t *sdram_get_params_patched()
|
|||||||
// Disable Warmboot signature check.
|
// Disable Warmboot signature check.
|
||||||
sdram_params->boot_rom_patch_control = (1 << 31) | (((IPATCH_BASE + 4) - APB_MISC_BASE) / 4);
|
sdram_params->boot_rom_patch_control = (1 << 31) | (((IPATCH_BASE + 4) - APB_MISC_BASE) / 4);
|
||||||
sdram_params->boot_rom_patch_data = IPATCH_CONFIG(0x10459E, 0x2000);
|
sdram_params->boot_rom_patch_data = IPATCH_CONFIG(0x10459E, 0x2000);
|
||||||
|
/*
|
||||||
|
// Disable SBK lock.
|
||||||
|
sdram_params->emc_bct_spare8 = (IPATCH_BASE + 7 * 4);
|
||||||
|
sdram_params->emc_bct_spare9 = IPATCH_CONFIG(0x10210E, 0x2000);
|
||||||
|
|
||||||
|
// Disable bootrom read lock.
|
||||||
|
sdram_params->emc_bct_spare10 = (IPATCH_BASE + 10 * 4);
|
||||||
|
sdram_params->emc_bct_spare11 = IPATCH_CONFIG(0x100FDC, 0xF000);
|
||||||
|
sdram_params->emc_bct_spare12 = (IPATCH_BASE + 11 * 4);
|
||||||
|
sdram_params->emc_bct_spare13 = IPATCH_CONFIG(0x100FDE, 0xE320);
|
||||||
|
*/
|
||||||
return sdram_params;
|
return sdram_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,16 +699,24 @@ void sdram_init()
|
|||||||
//TODO: sdram_id should be in [0,4].
|
//TODO: sdram_id should be in [0,4].
|
||||||
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
|
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
|
||||||
|
|
||||||
|
// Set DRAM voltage.
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);
|
||||||
max77620_regulator_set_voltage(REGULATOR_SD1, 1100000); // Set DRAM voltage.
|
max77620_regulator_set_voltage(REGULATOR_SD1, 1100000);
|
||||||
|
|
||||||
|
// VDDP Select.
|
||||||
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
||||||
usleep(params->pmc_vddp_sel_wait);
|
usleep(params->pmc_vddp_sel_wait);
|
||||||
|
|
||||||
|
// Set DDR pad voltage.
|
||||||
PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR);
|
PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR);
|
||||||
|
|
||||||
|
// Turn on MEM IO Power.
|
||||||
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
|
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
|
||||||
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
|
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
|
||||||
|
|
||||||
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
|
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
|
||||||
|
|
||||||
|
// Patch 1 using BCT spare variables
|
||||||
if (params->emc_bct_spare0)
|
if (params->emc_bct_spare0)
|
||||||
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
|
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
||||||
* Copyright 2014 Google Inc.
|
* Copyright 2014 Google Inc.
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
* Battery charger driver for Nintendo Switch's TI BQ24193
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
* Battery charger driver for Nintendo Switch's TI BQ24193
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Samsung Electronics
|
* Copyright (c) 2011 Samsung Electronics
|
||||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
||||||
* Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
|
* Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Samsung Electronics
|
* Copyright (c) 2011 Samsung Electronics
|
||||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Defining registers address and its bit definitions of MAX77620 and MAX20024
|
* Defining registers address and its bit definitions of MAX77620 and MAX20024
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||||
* Copyright (c) 2019 CTCaer
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -19,9 +19,19 @@
|
|||||||
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
|
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
|
||||||
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
|
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
|
||||||
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
|
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
|
||||||
#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
|
#define MAX77620_CNFGGLBL1_LBHYST_100 (0 << 4)
|
||||||
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
|
#define MAX77620_CNFGGLBL1_LBHYST_200 (1 << 4)
|
||||||
#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
|
#define MAX77620_CNFGGLBL1_LBHYST_300 (2 << 4)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBHYST_400 (3 << 4)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_MASK 0x0E
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_2700 (0 << 1)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_2800 (1 << 1)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_2900 (2 << 1)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_3000 (3 << 1)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_3100 (4 << 1)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_3200 (5 << 1)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_3300 (6 << 1)
|
||||||
|
#define MAX77620_CNFGGLBL1_LBDAC_3400 (7 << 1)
|
||||||
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
|
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
|
||||||
|
|
||||||
#define MAX77620_REG_CNFGGLBL2 0x01
|
#define MAX77620_REG_CNFGGLBL2 0x01
|
||||||
|
|||||||
@@ -64,6 +64,16 @@ static const max77620_regulator_t _pmic_regulators[] = {
|
|||||||
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
|
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void _max77620_try_set_reg(u8 reg, u8 val)
|
||||||
|
{
|
||||||
|
u8 tmp;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg, val);
|
||||||
|
tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg);
|
||||||
|
} while (val != tmp);
|
||||||
|
}
|
||||||
|
|
||||||
int max77620_regulator_get_status(u32 id)
|
int max77620_regulator_get_status(u32 id)
|
||||||
{
|
{
|
||||||
if (id > REGULATOR_MAX)
|
if (id > REGULATOR_MAX)
|
||||||
@@ -83,7 +93,7 @@ int max77620_regulator_config_fps(u32 id)
|
|||||||
|
|
||||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||||
|
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->fps_addr,
|
_max77620_try_set_reg(reg->fps_addr,
|
||||||
(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
|
(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -102,7 +112,7 @@ int max77620_regulator_set_voltage(u32 id, u32 mv)
|
|||||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);
|
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);
|
||||||
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
|
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);
|
_max77620_try_set_reg(reg->volt_addr, val);
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -121,7 +131,7 @@ int max77620_regulator_enable(u32 id, int enable)
|
|||||||
val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
|
val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
|
||||||
else
|
else
|
||||||
val &= ~reg->enable_mask;
|
val &= ~reg->enable_mask;
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, addr, val);
|
_max77620_try_set_reg(addr, val);
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -139,7 +149,7 @@ int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
|
|||||||
|
|
||||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||||
u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
|
u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);
|
_max77620_try_set_reg(reg->volt_addr, val);
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -155,11 +165,12 @@ void max77620_config_default()
|
|||||||
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
|
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
|
||||||
max77620_regulator_enable(i, 1);
|
max77620_regulator_enable(i, 1);
|
||||||
}
|
}
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 4);
|
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void max77620_low_battery_monitor_config()
|
void max77620_low_battery_monitor_config()
|
||||||
{
|
{
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,
|
_max77620_try_set_reg(MAX77620_REG_CNFGGLBL1,
|
||||||
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);
|
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_MPPLD |
|
||||||
|
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
* Copyright (c) 2018 Atmosphère-NX
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -66,8 +65,8 @@ static int _se_wait()
|
|||||||
while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))
|
while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))
|
||||||
;
|
;
|
||||||
if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||
|
if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||
|
||||||
SE(SE_STATUS_0) & 3 ||
|
SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN ||
|
||||||
SE(SE_ERR_STATUS_0) != 0)
|
SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -93,12 +92,12 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
|
|||||||
SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);
|
SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);
|
||||||
SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);
|
SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);
|
||||||
|
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
|
|
||||||
SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
|
SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
|
||||||
int res = _se_wait();
|
int res = _se_wait();
|
||||||
|
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
|
|
||||||
if (src)
|
if (src)
|
||||||
free(ll_src);
|
free(ll_src);
|
||||||
@@ -135,17 +134,19 @@ static void _se_aes_ctr_set(void *ctr)
|
|||||||
|
|
||||||
void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
||||||
{
|
{
|
||||||
if (flags & 0x7F)
|
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG)
|
||||||
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) =
|
||||||
if (flags & 0x80)
|
((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |
|
||||||
|
((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG);
|
||||||
|
if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
||||||
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);
|
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_key_acc_ctrl(u32 ks, u32 flags)
|
void se_key_acc_ctrl(u32 ks, u32 flags)
|
||||||
{
|
{
|
||||||
if (flags & 0x7F)
|
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
|
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
|
||||||
if (flags & 0x80)
|
if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
||||||
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);
|
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,15 +281,15 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size)
|
|||||||
int res;
|
int res;
|
||||||
// Setup config for SHA256, size = BITS(src_size).
|
// Setup config for SHA256, size = BITS(src_size).
|
||||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||||
SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_ENABLE;
|
SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_HASH;
|
||||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3);
|
SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(src_size << 3);
|
||||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 1) = 0;
|
SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = 0;
|
||||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 2) = 0;
|
SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0;
|
||||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 3) = 0;
|
SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0;
|
||||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3);
|
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(src_size << 3);
|
||||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 1) = 0;
|
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = 0;
|
||||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 2) = 0;
|
SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0;
|
||||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 3) = 0;
|
SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0;
|
||||||
|
|
||||||
// Trigger the operation.
|
// Trigger the operation.
|
||||||
res = _se_execute(OP_START, NULL, 0, src, src_size);
|
res = _se_execute(OP_START, NULL, 0, src, src_size);
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#define SE_SECURITY_0 0x000
|
#define SE_SECURITY_0 0x000
|
||||||
#define SE_KEY_SCHED_READ_SHIFT 3
|
#define SE_KEY_SCHED_READ_SHIFT 3
|
||||||
|
|
||||||
|
#define SE_TZRAM_SECURITY_0 0x004
|
||||||
|
|
||||||
#define SE_CONFIG_REG_OFFSET 0x014
|
#define SE_CONFIG_REG_OFFSET 0x014
|
||||||
#define SE_CONFIG_ENC_ALG_SHIFT 12
|
#define SE_CONFIG_ENC_ALG_SHIFT 12
|
||||||
#define SE_CONFIG_DEC_ALG_SHIFT 8
|
#define SE_CONFIG_DEC_ALG_SHIFT 8
|
||||||
@@ -209,8 +211,12 @@
|
|||||||
#define SE_INT_OP_DONE(x) (x << SE_INT_OP_DONE_SHIFT)
|
#define SE_INT_OP_DONE(x) (x << SE_INT_OP_DONE_SHIFT)
|
||||||
#define SE_INT_ERROR_SHIFT 16
|
#define SE_INT_ERROR_SHIFT 16
|
||||||
#define SE_INT_ERROR(x) (x << SE_INT_ERROR_SHIFT)
|
#define SE_INT_ERROR(x) (x << SE_INT_ERROR_SHIFT)
|
||||||
|
|
||||||
#define SE_STATUS_0 0x800
|
#define SE_STATUS_0 0x800
|
||||||
|
#define SE_STATUS_0_STATE_WAIT_IN 3
|
||||||
|
|
||||||
#define SE_ERR_STATUS_0 0x804
|
#define SE_ERR_STATUS_0 0x804
|
||||||
|
#define SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR 0
|
||||||
|
|
||||||
#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330
|
#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330
|
||||||
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
|
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
|
||||||
@@ -231,11 +237,17 @@
|
|||||||
#define SE_SPARE_0_REG_OFFSET 0x80c
|
#define SE_SPARE_0_REG_OFFSET 0x80c
|
||||||
|
|
||||||
#define SE_SHA_CONFIG_REG_OFFSET 0x200
|
#define SE_SHA_CONFIG_REG_OFFSET 0x200
|
||||||
#define SHA_DISABLE 0
|
#define SHA_CONTINUE 0
|
||||||
#define SHA_ENABLE 1
|
#define SHA_INIT_HASH 1
|
||||||
|
|
||||||
#define SE_SHA_MSG_LENGTH_REG_OFFSET 0x204
|
#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204
|
||||||
#define SE_SHA_MSG_LEFT_REG_OFFSET 0x214
|
#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208
|
||||||
|
#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C
|
||||||
|
#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210
|
||||||
|
#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214
|
||||||
|
#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218
|
||||||
|
#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C
|
||||||
|
#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220
|
||||||
|
|
||||||
#define SE_HASH_RESULT_REG_COUNT 16
|
#define SE_HASH_RESULT_REG_COUNT 16
|
||||||
#define SE_HASH_RESULT_REG_OFFSET 0x030
|
#define SE_HASH_RESULT_REG_OFFSET 0x030
|
||||||
@@ -254,13 +266,24 @@
|
|||||||
TEGRA_SE_RNG_DT_SIZE)
|
TEGRA_SE_RNG_DT_SIZE)
|
||||||
|
|
||||||
#define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16
|
#define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16
|
||||||
#define TEGRA_SE_RSA512_DIGEST_SIZE 64
|
#define TEGRA_SE_RSA512_DIGEST_SIZE 64
|
||||||
#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
|
#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
|
||||||
#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
|
#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
|
||||||
#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
|
#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
|
||||||
|
|
||||||
#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280
|
#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280
|
||||||
|
#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
||||||
|
|
||||||
#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
|
#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
|
||||||
|
#define SE_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0)
|
||||||
|
#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1)
|
||||||
|
#define SE_KEY_TBL_DIS_OIVREAD_FLAG (1 << 2)
|
||||||
|
#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG (1 << 3)
|
||||||
|
#define SE_KEY_TBL_DIS_UIVREAD_FLAG (1 << 4)
|
||||||
|
#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG (1 << 5)
|
||||||
|
#define SE_KEY_TBL_DIS_KEYUSE_FLAG (1 << 6)
|
||||||
|
#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
|
||||||
|
|
||||||
#define SE_KEY_READ_DISABLE_SHIFT 0
|
#define SE_KEY_READ_DISABLE_SHIFT 0
|
||||||
#define SE_KEY_UPDATE_DISABLE_SHIFT 1
|
#define SE_KEY_UPDATE_DISABLE_SHIFT 1
|
||||||
|
|
||||||
@@ -312,7 +335,16 @@
|
|||||||
#define TEGRA_SE_RSA_KEYSLOT_COUNT 2
|
#define TEGRA_SE_RSA_KEYSLOT_COUNT 2
|
||||||
|
|
||||||
#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C
|
#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
||||||
|
|
||||||
#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410
|
#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0)
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1)
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG)
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG (1 << 2)
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT (1 << 2)
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7
|
||||||
|
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F
|
||||||
|
|
||||||
#define SE_RSA_KEYTABLE_ADDR 0x420
|
#define SE_RSA_KEYTABLE_ADDR 0x420
|
||||||
#define SE_RSA_KEYTABLE_DATA 0x424
|
#define SE_RSA_KEYTABLE_DATA 0x424
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "../sec/se_t210.h"
|
#include "../sec/se_t210.h"
|
||||||
#include "../soc/bpmp.h"
|
#include "../soc/bpmp.h"
|
||||||
#include "../soc/clock.h"
|
#include "../soc/clock.h"
|
||||||
|
#include "../soc/kfuse.h"
|
||||||
#include "../soc/smmu.h"
|
#include "../soc/smmu.h"
|
||||||
#include "../soc/t210.h"
|
#include "../soc/t210.h"
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
@@ -78,6 +79,8 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||||||
clock_enable_sor1();
|
clock_enable_sor1();
|
||||||
clock_enable_kfuse();
|
clock_enable_kfuse();
|
||||||
|
|
||||||
|
kfuse_wait_ready();
|
||||||
|
|
||||||
// Configure Falcon.
|
// Configure Falcon.
|
||||||
TSEC(TSEC_DMACTL) = 0;
|
TSEC(TSEC_DMACTL) = 0;
|
||||||
TSEC(TSEC_IRQMSET) =
|
TSEC(TSEC_IRQMSET) =
|
||||||
@@ -209,7 +212,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||||||
res = -6;
|
res = -6;
|
||||||
smmu_deinit_for_tsec();
|
smmu_deinit_for_tsec();
|
||||||
|
|
||||||
goto out;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give some extra time to make sure PKG1.1 is decrypted.
|
// Give some extra time to make sure PKG1.1 is decrypted.
|
||||||
@@ -279,7 +282,7 @@ out:;
|
|||||||
clock_disable_sor_safe();
|
clock_disable_sor_safe();
|
||||||
clock_disable_tsec();
|
clock_disable_tsec();
|
||||||
bpmp_mmu_enable();
|
bpmp_mmu_enable();
|
||||||
bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST);
|
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "bpmp.h"
|
#include "bpmp.h"
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
#include "t210.h"
|
#include "t210.h"
|
||||||
|
#include "../../common/memory_map.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
#define BPMP_CACHE_CONFIG 0x0
|
#define BPMP_CACHE_CONFIG 0x0
|
||||||
@@ -74,13 +75,13 @@
|
|||||||
|
|
||||||
bpmp_mmu_entry_t mmu_entries[] =
|
bpmp_mmu_entry_t mmu_entries[] =
|
||||||
{
|
{
|
||||||
{ 0x80000000, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
|
{ DRAM_START, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
|
||||||
{ IPL_LOAD_ADDR, 0x40040000, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
|
{ IRAM_BASE, 0x4003FFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
|
||||||
};
|
};
|
||||||
|
|
||||||
void bpmp_mmu_maintenance(u32 op)
|
void bpmp_mmu_maintenance(u32 op, bool force)
|
||||||
{
|
{
|
||||||
if (!(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))
|
if (!force && !(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = INT_CLR_MAINT_DONE;
|
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = INT_CLR_MAINT_DONE;
|
||||||
@@ -132,13 +133,13 @@ void bpmp_mmu_enable()
|
|||||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;
|
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;
|
||||||
|
|
||||||
// Invalidate cache.
|
// Invalidate cache.
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, true);
|
||||||
|
|
||||||
// Enable cache.
|
// Enable cache.
|
||||||
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = CFG_ENABLE | CFG_FORCE_WRITE_THROUGH | CFG_TAG_CHK_ABRT_ON_ERR;
|
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = CFG_ENABLE | CFG_FORCE_WRITE_THROUGH | CFG_TAG_CHK_ABRT_ON_ERR;
|
||||||
|
|
||||||
// HW bug. Invalidate cache again.
|
// HW bug. Invalidate cache again.
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bpmp_mmu_disable()
|
void bpmp_mmu_disable()
|
||||||
@@ -147,21 +148,19 @@ void bpmp_mmu_disable()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Clean and invalidate cache.
|
// Clean and invalidate cache.
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
|
|
||||||
// Disable cache.
|
// Disable cache.
|
||||||
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
|
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
|
||||||
|
|
||||||
// HW bug. Invalidate cache again.
|
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8 pllc4_divn[] = {
|
const u8 pllc4_divn[] = {
|
||||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||||
85, // BPMP_CLK_LOW_BOOST: 544MHz 33% - 136MHz APB.
|
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||||
90, // BPMP_CLK_MID_BOOST: 576MHz 41% - 144MHz APB.
|
90, // BPMP_CLK_SUPER_BOOST: 576MHz 41% - 144MHz APB.
|
||||||
94 // BPMP_CLK_SUPER_BOOST: 602MHz 48% - 150MHz APB.
|
92 // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB.
|
||||||
//95 // BPMP_CLK_SUPER_BOOST: 608MHz 49% - 152MHz APB.
|
// Do not use for public releases!
|
||||||
|
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
||||||
};
|
};
|
||||||
|
|
||||||
bpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;
|
bpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;
|
||||||
|
|||||||
@@ -36,13 +36,16 @@ typedef struct _bpmp_mmu_entry_t
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB.
|
BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB.
|
||||||
BPMP_CLK_LOW_BOOST, // 544MHz 33% - 136MHz APB.
|
BPMP_CLK_HIGH_BOOST, // 544MHz 33% - 136MHz APB.
|
||||||
BPMP_CLK_MID_BOOST, // 576MHz 41% - 144MHz APB.
|
BPMP_CLK_SUPER_BOOST, // 576MHz 41% - 144MHz APB.
|
||||||
BPMP_CLK_SUPER_BOOST, // 608MHz 49% - 152MHz APB.
|
BPMP_CLK_HYPER_BOOST, // 589MHz 44% - 147MHz APB.
|
||||||
|
//BPMP_CLK_DEV_BOOST, // 608MHz 49% - 152MHz APB.
|
||||||
BPMP_CLK_MAX
|
BPMP_CLK_MAX
|
||||||
} bpmp_freq_t;
|
} bpmp_freq_t;
|
||||||
|
|
||||||
void bpmp_mmu_maintenance(u32 op);
|
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||||
|
|
||||||
|
void bpmp_mmu_maintenance(u32 op, bool force);
|
||||||
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
|
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
|
||||||
void bpmp_mmu_enable();
|
void bpmp_mmu_enable();
|
||||||
void bpmp_mmu_disable();
|
void bpmp_mmu_disable();
|
||||||
|
|||||||
@@ -29,13 +29,14 @@ static const clock_t _clock_uart[] = {
|
|||||||
/* UART E */ { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, 20, 0, 2 }
|
/* UART E */ { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, 20, 0, 2 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0 FM_DIV: 26.
|
||||||
static const clock_t _clock_i2c[] = {
|
static const clock_t _clock_i2c[] = {
|
||||||
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 12, 6, 0 }, // 0, 19 }, // 100KHz
|
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 12, 0, 19 }, //20.4MHz -> 100KHz
|
||||||
/* I2C2 */ { 0 },
|
/* I2C2 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, 22, 0, 4 }, //81.6MHz -> 400KHz
|
||||||
/* I2C3 */ { 0 },
|
/* I2C3 */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, 3, 0, 4 }, //81.6MHz -> 400KHz
|
||||||
/* I2C4 */ { 0 },
|
/* I2C4 */ { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, 7, 0, 19 }, //20.4MHz -> 100KHz
|
||||||
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 15, 6, 0 }, // 0, 4 }, // 400KHz
|
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 15, 0, 4 }, //81.6MHz -> 400KHz
|
||||||
/* I2C6 */ { 0 }
|
/* I2C6 */ { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, 6, 0, 19 } //20.4MHz -> 100KHz
|
||||||
};
|
};
|
||||||
|
|
||||||
static clock_t _clock_se = {
|
static clock_t _clock_se = {
|
||||||
@@ -73,7 +74,7 @@ static clock_t _clock_coresight = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static clock_t _clock_pwm = {
|
static clock_t _clock_pwm = {
|
||||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, 17, 6, 4 // Freference: 6.2MHz.
|
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, 17, 6, 4 // Fref: 6.2MHz.
|
||||||
};
|
};
|
||||||
|
|
||||||
void clock_enable(const clock_t *clk)
|
void clock_enable(const clock_t *clk)
|
||||||
@@ -87,6 +88,8 @@ void clock_enable(const clock_t *clk)
|
|||||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
|
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
|
||||||
// Enable.
|
// Enable.
|
||||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);
|
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);
|
||||||
|
usleep(2);
|
||||||
|
|
||||||
// Take clock off reset.
|
// Take clock off reset.
|
||||||
CLOCK(clk->reset) &= ~(1 << clk->index);
|
CLOCK(clk->reset) &= ~(1 << clk->index);
|
||||||
}
|
}
|
||||||
@@ -366,7 +369,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
|||||||
static u32 _clock_sdmmc_table[8] = { 0 };
|
static u32 _clock_sdmmc_table[8] = { 0 };
|
||||||
|
|
||||||
#define PLLP_OUT0 0x0
|
#define PLLP_OUT0 0x0
|
||||||
static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
|
static int _clock_sdmmc_config_clock_host(u32 *pout, u32 id, u32 val)
|
||||||
{
|
{
|
||||||
u32 divisor = 0;
|
u32 divisor = 0;
|
||||||
u32 source = PLLP_OUT0;
|
u32 source = PLLP_OUT0;
|
||||||
@@ -414,6 +417,7 @@ static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
|
|||||||
_clock_sdmmc_table[2 * id] = val;
|
_clock_sdmmc_table[2 * id] = val;
|
||||||
_clock_sdmmc_table[2 * id + 1] = *pout;
|
_clock_sdmmc_table[2 * id + 1] = *pout;
|
||||||
|
|
||||||
|
// Set SDMMC clock.
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case SDMMC_1:
|
case SDMMC_1:
|
||||||
@@ -444,15 +448,16 @@ void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val)
|
|||||||
int is_enabled = _clock_sdmmc_is_enabled(id);
|
int is_enabled = _clock_sdmmc_is_enabled(id);
|
||||||
if (is_enabled)
|
if (is_enabled)
|
||||||
_clock_sdmmc_clear_enable(id);
|
_clock_sdmmc_clear_enable(id);
|
||||||
_clock_sdmmc_config_clock_source_inner(pout, id, val);
|
_clock_sdmmc_config_clock_host(pout, id, val);
|
||||||
if (is_enabled)
|
if (is_enabled)
|
||||||
_clock_sdmmc_set_enable(id);
|
_clock_sdmmc_set_enable(id);
|
||||||
_clock_sdmmc_is_reset(id);
|
_clock_sdmmc_is_reset(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type)
|
void clock_sdmmc_get_card_clock_div(u32 *pout, u16 *pdivisor, u32 type)
|
||||||
{
|
{
|
||||||
|
// Get Card clock divisor.
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -513,7 +518,7 @@ void clock_sdmmc_enable(u32 id, u32 val)
|
|||||||
if (_clock_sdmmc_is_enabled(id))
|
if (_clock_sdmmc_is_enabled(id))
|
||||||
_clock_sdmmc_clear_enable(id);
|
_clock_sdmmc_clear_enable(id);
|
||||||
_clock_sdmmc_set_reset(id);
|
_clock_sdmmc_set_reset(id);
|
||||||
_clock_sdmmc_config_clock_source_inner(&div, id, val);
|
_clock_sdmmc_config_clock_host(&div, id, val);
|
||||||
_clock_sdmmc_set_enable(id);
|
_clock_sdmmc_set_enable(id);
|
||||||
_clock_sdmmc_is_reset(id);
|
_clock_sdmmc_is_reset(id);
|
||||||
usleep((100000 + div - 1) / div);
|
usleep((100000 + div - 1) / div);
|
||||||
|
|||||||
@@ -104,6 +104,7 @@
|
|||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
||||||
|
#define CLK_RST_CONTROLLER_RST_DEV_V_CLR 0x434
|
||||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
|
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
|
||||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR 0x444
|
#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR 0x444
|
||||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448
|
#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448
|
||||||
@@ -181,7 +182,7 @@ void clock_disable_coresight();
|
|||||||
void clock_enable_pwm();
|
void clock_enable_pwm();
|
||||||
void clock_disable_pwm();
|
void clock_disable_pwm();
|
||||||
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
|
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
|
||||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);
|
void clock_sdmmc_get_card_clock_div(u32 *pout, u16 *pdivisor, u32 type);
|
||||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||||
void clock_sdmmc_enable(u32 id, u32 val);
|
void clock_sdmmc_enable(u32 id, u32 val);
|
||||||
void clock_sdmmc_disable(u32 id);
|
void clock_sdmmc_disable(u32 id);
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ void cluster_boot_cpu0(u32 entry)
|
|||||||
|
|
||||||
_cluster_enable_power();
|
_cluster_enable_power();
|
||||||
|
|
||||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000))
|
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000)) // PLLX_ENABLE.
|
||||||
{
|
{
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7;
|
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7; // Disable IDDQ.
|
||||||
usleep(2);
|
usleep(2);
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;
|
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;
|
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;
|
||||||
@@ -127,6 +127,9 @@ void cluster_boot_cpu0(u32 entry)
|
|||||||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||||
(void)SB(SB_CSR);
|
(void)SB(SB_CSR);
|
||||||
|
|
||||||
|
// Tighten up the security aperture.
|
||||||
|
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||||
|
|
||||||
// Clear MSELECT reset.
|
// Clear MSELECT reset.
|
||||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
|
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
|
||||||
// Clear NONCPU reset.
|
// Clear NONCPU reset.
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#define FUSE_PRIVATE_KEY3 0x1B0
|
#define FUSE_PRIVATE_KEY3 0x1B0
|
||||||
#define FUSE_PRIVATE_KEY4 0x1B4
|
#define FUSE_PRIVATE_KEY4 0x1B4
|
||||||
#define FUSE_RESERVED_SW 0x1C0
|
#define FUSE_RESERVED_SW 0x1C0
|
||||||
|
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
|
||||||
#define FUSE_OPT_VENDOR_CODE 0x200
|
#define FUSE_OPT_VENDOR_CODE 0x200
|
||||||
#define FUSE_OPT_FAB_CODE 0x204
|
#define FUSE_OPT_FAB_CODE 0x204
|
||||||
#define FUSE_OPT_LOT_CODE_0 0x208
|
#define FUSE_OPT_LOT_CODE_0 0x208
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ void _config_regulators()
|
|||||||
{
|
{
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
|
||||||
(1 << 6) | (1 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
||||||
|
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
|
||||||
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||||
@@ -258,7 +258,7 @@ void _config_regulators()
|
|||||||
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
|
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
|
||||||
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
|
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
|
||||||
|
|
||||||
// Disable low battery shutdown monitor.
|
// Enable low battery shutdown monitor for < 2800mV.
|
||||||
max77620_low_battery_monitor_config();
|
max77620_low_battery_monitor_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +275,7 @@ void config_hw()
|
|||||||
|
|
||||||
// Enable fuse clock.
|
// Enable fuse clock.
|
||||||
clock_enable_fuse(true);
|
clock_enable_fuse(true);
|
||||||
|
|
||||||
// Disable fuse programming.
|
// Disable fuse programming.
|
||||||
fuse_disable_program();
|
fuse_disable_program();
|
||||||
|
|
||||||
|
|||||||
@@ -21,16 +21,25 @@
|
|||||||
#pragma GCC push_options
|
#pragma GCC push_options
|
||||||
#pragma GCC optimize ("Os")
|
#pragma GCC optimize ("Os")
|
||||||
|
|
||||||
|
int kfuse_wait_ready()
|
||||||
|
{
|
||||||
|
// Wait for KFUSE to finish init and verification of data.
|
||||||
|
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int kfuse_read(u32 *buf)
|
int kfuse_read(u32 *buf)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
clock_enable_kfuse();
|
clock_enable_kfuse();
|
||||||
|
|
||||||
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
|
if (!kfuse_wait_ready())
|
||||||
;
|
|
||||||
|
|
||||||
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
|
KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#define KFUSE_NUM_WORDS 144
|
#define KFUSE_NUM_WORDS 144
|
||||||
|
|
||||||
|
int kfuse_wait_ready();
|
||||||
int kfuse_read(u32 *buf);
|
int kfuse_read(u32 *buf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ bool smmu_is_used()
|
|||||||
|
|
||||||
void smmu_exit()
|
void smmu_exit()
|
||||||
{
|
{
|
||||||
*(uint32_t *)(smmu_payload + 0x14) = _NOP();
|
*(u32 *)(smmu_payload + 0x14) = _NOP();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
|
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
|
||||||
|
|||||||
@@ -108,6 +108,14 @@
|
|||||||
|
|
||||||
/*! EVP registers. */
|
/*! EVP registers. */
|
||||||
#define EVP_CPU_RESET_VECTOR 0x100
|
#define EVP_CPU_RESET_VECTOR 0x100
|
||||||
|
#define EVP_COP_RESET_VECTOR 0x200
|
||||||
|
#define EVP_COP_UNDEF_VECTOR 0x204
|
||||||
|
#define EVP_COP_SWI_VECTOR 0x208
|
||||||
|
#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
|
||||||
|
#define EVP_COP_DATA_ABORT_VECTOR 0x210
|
||||||
|
#define EVP_COP_RSVD_VECTOR 0x214
|
||||||
|
#define EVP_COP_IRQ_VECTOR 0x218
|
||||||
|
#define EVP_COP_FIQ_VECTOR 0x21C
|
||||||
|
|
||||||
/*! Misc registers. */
|
/*! Misc registers. */
|
||||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
|
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
|
||||||
@@ -208,7 +216,7 @@
|
|||||||
#define HALT_COP_JTAG (1 << 28)
|
#define HALT_COP_JTAG (1 << 28)
|
||||||
#define HALT_COP_WAIT_EVENT (1 << 30)
|
#define HALT_COP_WAIT_EVENT (1 << 30)
|
||||||
#define HALT_COP_WAIT_IRQ (1 << 31)
|
#define HALT_COP_WAIT_IRQ (1 << 31)
|
||||||
#define HALT_COP_MAX_CNT 0xFF
|
#define HALT_COP_MAX_CNT 0xFF
|
||||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void uart_init(u32 idx, u32 baud)
|
|||||||
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
|
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
|
||||||
uart->UART_THR_DLAB = (u8)rate; // Divisor latch LSB.
|
uart->UART_THR_DLAB = (u8)rate; // Divisor latch LSB.
|
||||||
uart->UART_IER_DLAB = (u8)(rate >> 8); // Divisor latch MSB.
|
uart->UART_IER_DLAB = (u8)(rate >> 8); // Divisor latch MSB.
|
||||||
uart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Diable DLAB.
|
uart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Disable DLAB.
|
||||||
|
|
||||||
// Setup and flush fifo.
|
// Setup and flush fifo.
|
||||||
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_RX_CLR | UART_IIR_FCR_TX_CLR;
|
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_RX_CLR | UART_IIR_FCR_TX_CLR;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 CTCaer
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -92,18 +92,14 @@ static int emummc_raw_get_part_off(int part_idx)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
|
int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
|
||||||
{
|
{
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
if (!sdmmc_storage_init_mmc(storage, sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
|
if (!sdmmc_storage_init_mmc(storage, sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
|
||||||
{
|
return 2;
|
||||||
EPRINTF("Failed to init eMMC.");
|
|
||||||
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (h_cfg.emummc_force_disable)
|
if (h_cfg.emummc_force_disable)
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
emu_cfg.active_part = 0;
|
emu_cfg.active_part = 0;
|
||||||
if (!sd_mount())
|
if (!sd_mount())
|
||||||
@@ -129,10 +125,11 @@ int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
|
|||||||
}
|
}
|
||||||
emu_cfg.file_based_part_size = fno.fsize >> 9;
|
emu_cfg.file_based_part_size = fno.fsize >> 9;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int emummc_storage_end(sdmmc_storage_t *storage)
|
int emummc_storage_end(sdmmc_storage_t *storage)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 CTCaer
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
|
|||||||
part->lba_end = ent->lba_end;
|
part->lba_end = ent->lba_end;
|
||||||
part->attrs = ent->attrs;
|
part->attrs = ent->attrs;
|
||||||
|
|
||||||
//HACK
|
// ASCII conversion. Copy only the LSByte of the UTF-16LE name.
|
||||||
for (u32 i = 0; i < 36; i++)
|
for (u32 i = 0; i < 36; i++)
|
||||||
part->name[i] = ent->name[i];
|
part->name[i] = ent->name[i];
|
||||||
part->name[36] = 0;
|
part->name[36] = 0;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* include/linux/mmc/sd.h
|
* include/linux/mmc/sd.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
|
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -40,7 +40,9 @@
|
|||||||
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
||||||
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
|
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
|
||||||
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
|
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
|
||||||
|
#define SD_OCR_VDD_27_34 (0x7F << 15) /* VDD voltage 2.7 ~ 3.4 */
|
||||||
#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
|
#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
|
||||||
|
#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SD_SWITCH argument format:
|
* SD_SWITCH argument format:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018-2019 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "sdmmc.h"
|
#include "sdmmc.h"
|
||||||
#include "mmc.h"
|
#include "mmc.h"
|
||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
|
#include "../../common/memory_map.h"
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
@@ -220,10 +221,10 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
|
|||||||
switch (power)
|
switch (power)
|
||||||
{
|
{
|
||||||
case SDMMC_POWER_1_8:
|
case SDMMC_POWER_1_8:
|
||||||
arg = 0x40000080; //Sector access, voltage.
|
arg = SD_OCR_CCS | SD_OCR_VDD_18;
|
||||||
break;
|
break;
|
||||||
case SDMMC_POWER_3_3:
|
case SDMMC_POWER_3_3:
|
||||||
arg = 0x403F8000; //Sector access, voltage.
|
arg = SD_OCR_CCS | SD_OCR_VDD_27_34;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -248,7 +249,7 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
|
|||||||
|
|
||||||
if (cond & MMC_CARD_BUSY)
|
if (cond & MMC_CARD_BUSY)
|
||||||
{
|
{
|
||||||
if (cond & 0x40000000)
|
if (cond & SD_OCR_CCS)
|
||||||
storage->has_sector_access = 1;
|
storage->has_sector_access = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -569,7 +570,7 @@ DPRINTF("[MMC] BKOPS disabled\n");
|
|||||||
|
|
||||||
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
|
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[MMC] succesfully switched to highspeed mode\n");
|
DPRINTF("[MMC] succesfully switched to HS mode\n");
|
||||||
|
|
||||||
sdmmc_sd_clock_ctrl(storage->sdmmc, 1);
|
sdmmc_sd_clock_ctrl(storage->sdmmc, 1);
|
||||||
|
|
||||||
@@ -819,17 +820,17 @@ void _sd_storage_set_current_limit(sdmmc_storage_t *storage, u8 *buf)
|
|||||||
switch (pwr)
|
switch (pwr)
|
||||||
{
|
{
|
||||||
case SD_SET_CURRENT_LIMIT_800:
|
case SD_SET_CURRENT_LIMIT_800:
|
||||||
DPRINTF("[SD] Power limit raised to 800mA\n");
|
DPRINTF("[SD] power limit raised to 800mA\n");
|
||||||
break;
|
break;
|
||||||
case SD_SET_CURRENT_LIMIT_600:
|
case SD_SET_CURRENT_LIMIT_600:
|
||||||
DPRINTF("[SD] Power limit raised to 600mA\n");
|
DPRINTF("[SD] power limit raised to 600mA\n");
|
||||||
break;
|
break;
|
||||||
case SD_SET_CURRENT_LIMIT_400:
|
case SD_SET_CURRENT_LIMIT_400:
|
||||||
DPRINTF("[SD] Power limit raised to 800mA\n");
|
DPRINTF("[SD] power limit raised to 800mA\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case SD_SET_CURRENT_LIMIT_200:
|
case SD_SET_CURRENT_LIMIT_200:
|
||||||
DPRINTF("[SD] Power limit defaulted to 200mA\n");
|
DPRINTF("[SD] power limit defaulted to 200mA\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -857,7 +858,7 @@ DPRINTF("[SD] SD supports selected (U)HS mode\n");
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
|
int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
|
||||||
{
|
{
|
||||||
// Try to raise the current limit to let the card perform better.
|
// Try to raise the current limit to let the card perform better.
|
||||||
_sd_storage_set_current_limit(storage, buf);
|
_sd_storage_set_current_limit(storage, buf);
|
||||||
@@ -878,7 +879,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8
|
|||||||
{
|
{
|
||||||
type = 11;
|
type = 11;
|
||||||
hs_type = UHS_SDR104_BUS_SPEED;
|
hs_type = UHS_SDR104_BUS_SPEED;
|
||||||
DPRINTF("[SD] Bus speed set to SDR104\n");
|
DPRINTF("[SD] bus speed set to SDR104\n");
|
||||||
storage->csd.busspeed = 104;
|
storage->csd.busspeed = 104;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -887,7 +888,7 @@ DPRINTF("[SD] Bus speed set to SDR104\n");
|
|||||||
{
|
{
|
||||||
type = 10;
|
type = 10;
|
||||||
hs_type = UHS_SDR50_BUS_SPEED;
|
hs_type = UHS_SDR50_BUS_SPEED;
|
||||||
DPRINTF("[SD] Bus speed set to SDR50\n");
|
DPRINTF("[SD] bus speed set to SDR50\n");
|
||||||
storage->csd.busspeed = 50;
|
storage->csd.busspeed = 50;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -896,7 +897,7 @@ DPRINTF("[SD] Bus speed set to SDR50\n");
|
|||||||
return 0;
|
return 0;
|
||||||
type = 8;
|
type = 8;
|
||||||
hs_type = UHS_SDR12_BUS_SPEED;
|
hs_type = UHS_SDR12_BUS_SPEED;
|
||||||
DPRINTF("[SD] Bus speed set to SDR12\n");
|
DPRINTF("[SD] bus speed set to SDR12\n");
|
||||||
storage->csd.busspeed = 12;
|
storage->csd.busspeed = 12;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -916,7 +917,7 @@ DPRINTF("[SD] config tuning\n");
|
|||||||
return _sdmmc_storage_check_status(storage);
|
return _sdmmc_storage_check_status(storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf)
|
int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf)
|
||||||
{
|
{
|
||||||
if (!_sd_storage_switch_get(storage, buf))
|
if (!_sd_storage_switch_get(storage, buf))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1064,8 +1065,9 @@ void sdmmc_storage_init_wait_sd()
|
|||||||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)
|
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)
|
||||||
{
|
{
|
||||||
int is_version_1 = 0;
|
int is_version_1 = 0;
|
||||||
|
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||||
|
|
||||||
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
// Some cards (SanDisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||||
sdmmc_storage_init_wait_sd();
|
sdmmc_storage_init_wait_sd();
|
||||||
|
|
||||||
memset(storage, 0, sizeof(sdmmc_storage_t));
|
memset(storage, 0, sizeof(sdmmc_storage_t));
|
||||||
@@ -1138,12 +1140,8 @@ DPRINTF("[SD] set blocklen to 512\n");
|
|||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] cleared card detect\n");
|
DPRINTF("[SD] cleared card detect\n");
|
||||||
|
|
||||||
u8 *buf = (u8 *)malloc(512);
|
|
||||||
if (!_sd_storage_get_scr(storage, buf))
|
if (!_sd_storage_get_scr(storage, buf))
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
//gfx_hexdump(0, storage->raw_scr, 8);
|
//gfx_hexdump(0, storage->raw_scr, 8);
|
||||||
DPRINTF("[SD] got scr\n");
|
DPRINTF("[SD] got scr\n");
|
||||||
@@ -1152,10 +1150,8 @@ DPRINTF("[SD] got scr\n");
|
|||||||
if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF))
|
if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF))
|
||||||
{
|
{
|
||||||
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))
|
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);
|
sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);
|
||||||
DPRINTF("[SD] switched to wide bus width\n");
|
DPRINTF("[SD] switched to wide bus width\n");
|
||||||
}
|
}
|
||||||
@@ -1166,20 +1162,15 @@ DPRINTF("[SD] SD does not support wide bus width\n");
|
|||||||
|
|
||||||
if (storage->is_low_voltage)
|
if (storage->is_low_voltage)
|
||||||
{
|
{
|
||||||
if (!_sd_storage_enable_highspeed_low_volt(storage, type, buf))
|
if (!_sd_storage_enable_uhs_low_volt(storage, type, buf))
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
DPRINTF("[SD] enabled UHS\n");
|
DPRINTF("[SD] enabled UHS\n");
|
||||||
}
|
}
|
||||||
else if (type != 6 && (storage->scr.sda_vsn & 0xF) != 0)
|
else if (type != 6 && (storage->scr.sda_vsn & 0xF) != 0)
|
||||||
{
|
{
|
||||||
if (!_sd_storage_enable_highspeed_high_volt(storage, buf))
|
if (!_sd_storage_enable_hs_high_volt(storage, buf))
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
DPRINTF("[SD] enabled HS\n");
|
DPRINTF("[SD] enabled HS\n");
|
||||||
storage->csd.busspeed = 25;
|
storage->csd.busspeed = 25;
|
||||||
}
|
}
|
||||||
@@ -1192,7 +1183,6 @@ DPRINTF("[SD] enabled HS\n");
|
|||||||
DPRINTF("[SD] got sd status\n");
|
DPRINTF("[SD] got sd status\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
|||||||
|
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
u16 divisor;
|
u16 divisor;
|
||||||
clock_sdmmc_get_params(&tmp, &divisor, type);
|
clock_sdmmc_get_card_clock_div(&tmp, &divisor, type);
|
||||||
clock_sdmmc_config_clock_source(&tmp, sdmmc->id, tmp);
|
clock_sdmmc_config_clock_source(&tmp, sdmmc->id, tmp);
|
||||||
sdmmc->divisor = (tmp + divisor - 1) / divisor;
|
sdmmc->divisor = (tmp + divisor - 1) / divisor;
|
||||||
|
|
||||||
@@ -830,7 +830,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
|||||||
trnmode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
|
trnmode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
|
||||||
if (req->is_auto_cmd12)
|
if (req->is_auto_cmd12)
|
||||||
trnmode = (trnmode & 0xFFF3) | TEGRA_MMC_TRNMOD_AUTO_CMD12;
|
trnmode = (trnmode & 0xFFF3) | TEGRA_MMC_TRNMOD_AUTO_CMD12;
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
sdmmc->regs->trnmod = trnmode;
|
sdmmc->regs->trnmod = trnmode;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -855,7 +855,7 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
|
|||||||
break;
|
break;
|
||||||
if (intr & TEGRA_MMC_NORINTSTS_XFER_COMPLETE)
|
if (intr & TEGRA_MMC_NORINTSTS_XFER_COMPLETE)
|
||||||
{
|
{
|
||||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||||
return 1; // Transfer complete.
|
return 1; // Transfer complete.
|
||||||
}
|
}
|
||||||
if (intr & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT)
|
if (intr & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT)
|
||||||
@@ -1015,7 +1015,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n
|
|||||||
|
|
||||||
u32 clock;
|
u32 clock;
|
||||||
u16 divisor;
|
u16 divisor;
|
||||||
clock_sdmmc_get_params(&clock, &divisor, type);
|
clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
|
||||||
clock_sdmmc_enable(id, clock);
|
clock_sdmmc_enable(id, clock);
|
||||||
|
|
||||||
sdmmc->clock_stopped = 0;
|
sdmmc->clock_stopped = 0;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -25,11 +26,12 @@
|
|||||||
|
|
||||||
#define _PAGEOFF(x) ((x) & 0xFFFFF000)
|
#define _PAGEOFF(x) ((x) & 0xFFFFF000)
|
||||||
|
|
||||||
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
|
#define _ADRP(r, o) (0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F))
|
||||||
#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
#define _BL(a, o) (0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||||
#define _B(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
#define _B(a, o) (0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||||
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
#define _MOVKX(r, i, s) (0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||||
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
#define _MOVZX(r, i, s) (0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||||
|
#define _MOVZW(r, i, s) (0x52800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||||
#define _NOP() 0xD503201F
|
#define _NOP() 0xD503201F
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -61,16 +61,28 @@ u8 btn_wait()
|
|||||||
|
|
||||||
u8 btn_wait_timeout(u32 time_ms, u8 mask)
|
u8 btn_wait_timeout(u32 time_ms, u8 mask)
|
||||||
{
|
{
|
||||||
|
u8 single_button = mask & BTN_SINGLE;
|
||||||
|
mask &= ~BTN_SINGLE;
|
||||||
|
|
||||||
u32 timeout = get_tmr_ms() + time_ms;
|
u32 timeout = get_tmr_ms() + time_ms;
|
||||||
u8 res = btn_read() & mask;
|
u8 res = btn_read();
|
||||||
|
|
||||||
while (get_tmr_ms() < timeout)
|
while (get_tmr_ms() < timeout)
|
||||||
{
|
{
|
||||||
if (res == mask)
|
if ((res & mask) == mask)
|
||||||
break;
|
{
|
||||||
|
if (single_button && (res & ~mask)) // Undesired button detected.
|
||||||
|
res = btn_read();
|
||||||
|
else
|
||||||
|
return (res & mask);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
res = btn_read() & mask;
|
res = btn_read();
|
||||||
};
|
};
|
||||||
|
|
||||||
return res;
|
// Timed out.
|
||||||
|
if (!single_button || !time_ms)
|
||||||
|
return (res & mask);
|
||||||
|
else
|
||||||
|
return 0; // Return no button press if single button requested.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#define BTN_POWER (1 << 0)
|
#define BTN_POWER (1 << 0)
|
||||||
#define BTN_VOL_DOWN (1 << 1)
|
#define BTN_VOL_DOWN (1 << 1)
|
||||||
#define BTN_VOL_UP (1 << 2)
|
#define BTN_VOL_UP (1 << 2)
|
||||||
|
#define BTN_SINGLE (1 << 7)
|
||||||
|
|
||||||
u8 btn_read();
|
u8 btn_read();
|
||||||
u8 btn_wait();
|
u8 btn_wait();
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
|
|||||||
break;
|
break;
|
||||||
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||||
{
|
{
|
||||||
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
strcpy(dir_entries + (k * 256), fno.fname);
|
||||||
k++;
|
k++;
|
||||||
if (k > (max_entries - 1))
|
if (k > (max_entries - 1))
|
||||||
break;
|
break;
|
||||||
@@ -56,7 +56,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
|
|||||||
{
|
{
|
||||||
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||||
{
|
{
|
||||||
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
strcpy(dir_entries + (k * 256), fno.fname);
|
||||||
k++;
|
k++;
|
||||||
if (k > (max_entries - 1))
|
if (k > (max_entries - 1))
|
||||||
break;
|
break;
|
||||||
@@ -81,9 +81,9 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
|
|||||||
{
|
{
|
||||||
if (strcmp(&dir_entries[i * 256], &dir_entries[j * 256]) > 0)
|
if (strcmp(&dir_entries[i * 256], &dir_entries[j * 256]) > 0)
|
||||||
{
|
{
|
||||||
memcpy(temp, &dir_entries[i * 256], strlen(&dir_entries[i * 256]) + 1);
|
strcpy(temp, &dir_entries[i * 256]);
|
||||||
memcpy(&dir_entries[i * 256], &dir_entries[j * 256], strlen(&dir_entries[j * 256]) + 1);
|
strcpy(&dir_entries[i * 256], &dir_entries[j * 256]);
|
||||||
memcpy(&dir_entries[j * 256], temp, strlen(temp) + 1);
|
strcpy(&dir_entries[j * 256], temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
|
|
||||||
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||||||
|
#define ALIGN_DOWN(x, a) (((x) - ((a) - 1)) & ~((a) - 1))
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "../gfx/di.h"
|
#include "../gfx/di.h"
|
||||||
|
#include "../mem/minerva.h"
|
||||||
#include "../power/max77620.h"
|
#include "../power/max77620.h"
|
||||||
#include "../rtc/max77620-rtc.h"
|
#include "../rtc/max77620-rtc.h"
|
||||||
#include "../soc/bpmp.h"
|
#include "../soc/bpmp.h"
|
||||||
@@ -26,6 +27,8 @@
|
|||||||
|
|
||||||
#define USE_RTC_TIMER
|
#define USE_RTC_TIMER
|
||||||
|
|
||||||
|
extern volatile nyx_storage_t *nyx_str;
|
||||||
|
|
||||||
extern void sd_unmount();
|
extern void sd_unmount();
|
||||||
|
|
||||||
u32 get_tmr_s()
|
u32 get_tmr_s()
|
||||||
@@ -100,6 +103,8 @@ void reboot_normal()
|
|||||||
sd_unmount();
|
sd_unmount();
|
||||||
display_end();
|
display_end();
|
||||||
|
|
||||||
|
nyx_str->mtc_cfg.init_done = 0;
|
||||||
|
|
||||||
panic(0x21); // Bypass fuse programming in package1.
|
panic(0x21); // Bypass fuse programming in package1.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +115,8 @@ void reboot_rcm()
|
|||||||
sd_unmount();
|
sd_unmount();
|
||||||
display_end();
|
display_end();
|
||||||
|
|
||||||
|
nyx_str->mtc_cfg.init_done = 0;
|
||||||
|
|
||||||
PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm.
|
PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm.
|
||||||
PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;
|
PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -21,8 +21,17 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "../mem/minerva.h"
|
#include "../mem/minerva.h"
|
||||||
|
|
||||||
#define NYX_CFG_DUMP (1 << 7)
|
typedef enum
|
||||||
#define NYX_CFG_MINERVA (1 << 8)
|
{
|
||||||
|
NYX_CFG_DUMP = (1 << 7),
|
||||||
|
} nyx_cfg_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ERR_LIBSYS_LP0 = (1 << 0),
|
||||||
|
ERR_SYSOLD_NYX = (1 << 1),
|
||||||
|
ERR_SYSOLD_MTC = (1 << 2),
|
||||||
|
} hekate_errors_t;
|
||||||
|
|
||||||
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000))
|
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000))
|
||||||
@@ -33,14 +42,22 @@ typedef struct _cfg_op_t
|
|||||||
u32 val;
|
u32 val;
|
||||||
} cfg_op_t;
|
} cfg_op_t;
|
||||||
|
|
||||||
|
typedef struct _nyx_info_t
|
||||||
|
{
|
||||||
|
u32 rsvd;
|
||||||
|
u32 errors;
|
||||||
|
} nyx_info_t;
|
||||||
|
|
||||||
typedef struct _nyx_storage_t
|
typedef struct _nyx_storage_t
|
||||||
{
|
{
|
||||||
u32 version;
|
u32 version;
|
||||||
u32 cfg;
|
u32 cfg;
|
||||||
u8 irama[0x8000];
|
u8 irama[0x8000];
|
||||||
u8 hekate[0x30000];
|
u8 hekate[0x30000];
|
||||||
u8 rsvd[0x800000];
|
u8 rsvd[0x800000 - sizeof(nyx_info_t)];
|
||||||
|
nyx_info_t info;
|
||||||
mtc_config_t mtc_cfg;
|
mtc_config_t mtc_cfg;
|
||||||
|
emc_table_t mtc_table;
|
||||||
} nyx_storage_t;
|
} nyx_storage_t;
|
||||||
|
|
||||||
u32 get_tmr_us();
|
u32 get_tmr_us();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Common Gfx Header
|
* Common Gfx Header
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
* Copyright (C) 2018 M4xw
|
* Copyright (c) 2018 M4xw
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ typedef struct _hnode
|
|||||||
u32 size;
|
u32 size;
|
||||||
struct _hnode *prev;
|
struct _hnode *prev;
|
||||||
struct _hnode *next;
|
struct _hnode *next;
|
||||||
|
u32 align[4]; // Align to arch cache line size.
|
||||||
} hnode_t;
|
} hnode_t;
|
||||||
|
|
||||||
typedef struct _heap
|
typedef struct _heap
|
||||||
@@ -32,3 +33,9 @@ typedef struct _heap
|
|||||||
u32 start;
|
u32 start;
|
||||||
hnode_t *first;
|
hnode_t *first;
|
||||||
} heap_t;
|
} heap_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 total;
|
||||||
|
u32 used;
|
||||||
|
} heap_monitor_t;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Common Module Header
|
* Common Module Header
|
||||||
* Copyright (C) 2018 M4xw
|
* Copyright (c) 2018 M4xw
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
87
common/memory_map.h
Normal file
87
common/memory_map.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 CTCaer
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MEMORY_MAP_H_
|
||||||
|
#define _MEMORY_MAP_H_
|
||||||
|
|
||||||
|
//#define IPL_STACK_TOP 0x4003FF00
|
||||||
|
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
|
||||||
|
/* --- IPL: 0x40008000 - 0x40028000 --- */
|
||||||
|
#define IPL_LOAD_ADDR 0x40008000
|
||||||
|
#define IPL_SZ_MAX 0x20000 // 128KB.
|
||||||
|
//#define IRAM_LIB_ADDR 0x4002B000
|
||||||
|
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
||||||
|
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
|
||||||
|
|
||||||
|
/* --- DRAM START --- */
|
||||||
|
#define DRAM_START 0x80000000
|
||||||
|
/* Do not write anything in this area */
|
||||||
|
#define NYX_LOAD_ADDR 0x81000000
|
||||||
|
#define NYX_SZ_MAX 0x1000000
|
||||||
|
/* Stack theoretical max: 220MB */
|
||||||
|
#define IPL_STACK_TOP 0x90010000
|
||||||
|
#define IPL_HEAP_START 0x90020000
|
||||||
|
#define IPL_HEAP_SZ 0x24FE0000 // 592MB.
|
||||||
|
/* --- Gap: 0xB5000000 - 0xB5FFFFFF --- */
|
||||||
|
|
||||||
|
// SDMMC DMA buffers
|
||||||
|
#define SDXC_BUF_ALIGNED 0xB6000000
|
||||||
|
#define MIXD_BUF_ALIGNED 0xB7000000
|
||||||
|
#define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED
|
||||||
|
#define SDMMC_DMA_BUF_SZ 0x1000000 // 16MB (4MB currently used).
|
||||||
|
#define SDMMC_UPPER_BUFFER 0xB8000000
|
||||||
|
#define SDMMC_UP_BUF_SZ 0x8000000 // 128MB.
|
||||||
|
|
||||||
|
// Virtual disk / Chainloader buffers.
|
||||||
|
#define RAM_DISK_ADDR 0xC1000000
|
||||||
|
#define RAM_DISK_SZ 0x20000000
|
||||||
|
//#define DRAM_LIB_ADDR 0xE0000000
|
||||||
|
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
||||||
|
/* --- Gap: 464MB 0xD0000000 - 0xECFFFFFF --- */
|
||||||
|
|
||||||
|
// Nyx buffers.
|
||||||
|
#define NYX_STORAGE_ADDR 0xED000000
|
||||||
|
#define NYX_RES_ADDR 0xEE000000
|
||||||
|
|
||||||
|
// Framebuffer addresses.
|
||||||
|
#define IPL_FB_ADDRESS 0xF0000000
|
||||||
|
#define IPL_FB_SZ 0x384000 // 720 x 1280 x 4.
|
||||||
|
#define LOG_FB_ADDRESS 0xF0400000
|
||||||
|
#define LOG_FB_SZ 0x334000 // 1280 x 656 x 4.
|
||||||
|
#define NYX_FB_ADDRESS 0xF0800000
|
||||||
|
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||||
|
|
||||||
|
// Nyx LvGL buffers.
|
||||||
|
#define NYX_LV_VDB_ADR 0xF0C00000
|
||||||
|
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||||
|
#define NYX_LV_MEM_ADR 0xF1000000
|
||||||
|
#define NYX_LV_MEM_SZ 0x8000000
|
||||||
|
|
||||||
|
// NX BIS driver sector cache.
|
||||||
|
#define NX_BIS_CACHE_ADDR 0xF9000000
|
||||||
|
#define NX_BIS_CACHE_SZ 0x8800
|
||||||
|
/* --- Gap: 111MB 0xF9008800 - 0xFFFFFFFF --- */
|
||||||
|
|
||||||
|
// #define EXT_PAYLOAD_ADDR 0xC03C0000
|
||||||
|
// #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||||
|
// #define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
||||||
|
|
||||||
|
// NYX
|
||||||
|
// #define EXT_PAYLOAD_ADDR 0xC0000000
|
||||||
|
// #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||||
|
// #define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
||||||
* Copyright 2014 Google Inc.
|
* Copyright 2014 Google Inc.
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
||||||
* Copyright 2014 Google Inc.
|
* Copyright 2014 Google Inc.
|
||||||
* Copyright (C) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ For more, check [Here](https://github.com/CTCaer/minerva_tc).
|
|||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Minerva Training Cell (C) 2018 CTCaer.
|
Minerva Training Cell (c) 2018 CTCaer.
|
||||||
|
|
||||||
/* Pain... And suffering. */
|
/* Pain... And suffering. */
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -30,7 +30,9 @@
|
|||||||
#define EMC_BASE 0x7001B000
|
#define EMC_BASE 0x7001B000
|
||||||
#define EMC0_BASE 0x7001E000
|
#define EMC0_BASE 0x7001E000
|
||||||
#define EMC1_BASE 0x7001F000
|
#define EMC1_BASE 0x7001F000
|
||||||
#define MTC_TABLE 0x8F000000
|
|
||||||
|
#define MTC_INIT_MAGIC 0x3043544D
|
||||||
|
#define MTC_NEW_MAGIC 0x5243544D
|
||||||
|
|
||||||
#define _REG(base, off) *(vu32 *)((base) + (off))
|
#define _REG(base, off) *(vu32 *)((base) + (off))
|
||||||
|
|
||||||
@@ -61,6 +63,7 @@ typedef struct
|
|||||||
bool emc_2X_clk_src_is_pllmb;
|
bool emc_2X_clk_src_is_pllmb;
|
||||||
bool fsp_for_src_freq;
|
bool fsp_for_src_freq;
|
||||||
bool train_ram_patterns;
|
bool train_ram_patterns;
|
||||||
|
bool init_done;
|
||||||
} mtc_config_t;
|
} mtc_config_t;
|
||||||
|
|
||||||
enum train_mode_t
|
enum train_mode_t
|
||||||
|
|||||||
@@ -23,8 +23,9 @@
|
|||||||
/* Clock controller registers */
|
/* Clock controller registers */
|
||||||
#define CLK_RST_CONTROLLER_PLLM_BASE 0x90
|
#define CLK_RST_CONTROLLER_PLLM_BASE 0x90
|
||||||
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
||||||
#define PLLM_ENABLE (1 << 30)
|
#define PLLM_ENABLE (1 << 30)
|
||||||
#define PLLM_LOCK (1 << 27)
|
#define PLLM_LOCK (1 << 27)
|
||||||
|
#define PLLM_EN_LCKDET (1 << 4)
|
||||||
|
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
|
||||||
#define EMC_2X_CLK_SRC_SHIFT 29
|
#define EMC_2X_CLK_SRC_SHIFT 29
|
||||||
@@ -34,6 +35,9 @@
|
|||||||
#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR 0x288
|
#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR 0x288
|
||||||
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
|
||||||
|
#define EMC_DLL_PLLM_VCOB (1 << 10)
|
||||||
|
#define EMC_DLL_SWITCH_OUT (1 << 11)
|
||||||
|
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_SAFE 0x724
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_SAFE 0x724
|
||||||
|
|
||||||
/* Memory controller registers */
|
/* Memory controller registers */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -254,7 +254,6 @@ void gfx_putc(gfx_con_t *con, char c)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx_puts(gfx_con_t *con, const char *s)
|
void gfx_puts(gfx_con_t *con, const char *s)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
* Copyright (C) 2018 M4xw
|
* Copyright (c) 2018 M4xw
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
19
nyx/Makefile
19
nyx/Makefile
@@ -6,15 +6,9 @@ include $(DEVKITARM)/base_rules
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
NYX_LOAD_ADDR := 0x40003000
|
NYX_LOAD_ADDR := 0x81000000
|
||||||
NYX_RES_ADDR := 0xEE000000
|
|
||||||
NYX_STORAGE_ADDR := 0xED000000
|
|
||||||
NYX_MAGIC := 0x43544347 #"GCTC"
|
NYX_MAGIC := 0x43544347 #"GCTC"
|
||||||
BLVERSION_MAJOR := 0
|
include ./../Versions.inc
|
||||||
BLVERSION_MINOR := 8
|
|
||||||
BLVERSION_HOTFX := 2
|
|
||||||
|
|
||||||
BL_RESERVED := 0
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
@@ -39,7 +33,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||||||
bpmp.o clock.o cluster.o di.o gpio.o i2c.o mc.o sdram.o pinmux.o se.o smmu.o tsec.o uart.o \
|
bpmp.o clock.o cluster.o di.o gpio.o i2c.o mc.o sdram.o pinmux.o se.o smmu.o tsec.o uart.o \
|
||||||
fuse.o kfuse.o minerva.o \
|
fuse.o kfuse.o minerva.o \
|
||||||
sdmmc.o sdmmc_driver.o \
|
sdmmc.o sdmmc_driver.o \
|
||||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
|
||||||
touch.o tmp451.o fan.o \
|
touch.o tmp451.o fan.o \
|
||||||
hw_init.o \
|
hw_init.o \
|
||||||
)
|
)
|
||||||
@@ -74,9 +68,8 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
CUSTOMDEFINES := -DNYX_RES_ADDR=$(NYX_RES_ADDR) -DNYX_STORAGE_ADDR=$(NYX_STORAGE_ADDR)
|
CUSTOMDEFINES += -DNYX_LOAD_ADDR=$(NYX_LOAD_ADDR) -DNYX_MAGIC=$(NYX_MAGIC)
|
||||||
CUSTOMDEFINES += -DNYX_LOAD_ADDR=$(NYX_LOAD_ADDR) -DBL_MAGIC=$(NYX_MAGIC)
|
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BL_RESERVED)
|
|
||||||
|
|
||||||
# 0: UART_A, 1: UART_B.
|
# 0: UART_A, 1: UART_B.
|
||||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=1
|
#CUSTOMDEFINES += -DDEBUG_UART_PORT=1
|
||||||
@@ -84,7 +77,7 @@ CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -
|
|||||||
#CUSTOMDEFINES += -DDEBUG
|
#CUSTOMDEFINES += -DDEBUG
|
||||||
|
|
||||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
|
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
|
||||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -flto -fomit-frame-pointer -fno-inline -fno-strict-aliasing -std=gnu11 -Wall $(CUSTOMDEFINES)
|
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||||
CFLAGS += -g
|
CFLAGS += -g
|
||||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=NYX_LOAD_ADDR=$(NYX_LOAD_ADDR)
|
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=NYX_LOAD_ADDR=$(NYX_LOAD_ADDR)
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ extern hekate_config h_cfg;
|
|||||||
extern bool sd_mount();
|
extern bool sd_mount();
|
||||||
extern void sd_unmount(bool deinit);
|
extern void sd_unmount(bool deinit);
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
void set_default_configuration()
|
void set_default_configuration()
|
||||||
{
|
{
|
||||||
h_cfg.autoboot = 0;
|
h_cfg.autoboot = 0;
|
||||||
@@ -46,6 +43,7 @@ void set_default_configuration()
|
|||||||
h_cfg.backlight = 100;
|
h_cfg.backlight = 100;
|
||||||
h_cfg.autohosoff = 0;
|
h_cfg.autohosoff = 0;
|
||||||
h_cfg.autonogc = 1;
|
h_cfg.autonogc = 1;
|
||||||
|
h_cfg.updater2p = 0;
|
||||||
h_cfg.brand = NULL;
|
h_cfg.brand = NULL;
|
||||||
h_cfg.tagline = NULL;
|
h_cfg.tagline = NULL;
|
||||||
h_cfg.errors = 0;
|
h_cfg.errors = 0;
|
||||||
@@ -111,6 +109,9 @@ int create_config_entry()
|
|||||||
f_puts("\nautonogc=", &fp);
|
f_puts("\nautonogc=", &fp);
|
||||||
itoa(h_cfg.autonogc, lbuf, 10);
|
itoa(h_cfg.autonogc, lbuf, 10);
|
||||||
f_puts(lbuf, &fp);
|
f_puts(lbuf, &fp);
|
||||||
|
f_puts("\nupdater2p=", &fp);
|
||||||
|
itoa(h_cfg.updater2p, lbuf, 10);
|
||||||
|
f_puts(lbuf, &fp);
|
||||||
if (h_cfg.brand)
|
if (h_cfg.brand)
|
||||||
{
|
{
|
||||||
f_puts("\nbrand=", &fp);
|
f_puts("\nbrand=", &fp);
|
||||||
@@ -169,4 +170,3 @@ int create_config_entry()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ typedef struct _hekate_config
|
|||||||
u32 backlight;
|
u32 backlight;
|
||||||
u32 autohosoff;
|
u32 autohosoff;
|
||||||
u32 autonogc;
|
u32 autonogc;
|
||||||
|
u32 updater2p;
|
||||||
char *brand;
|
char *brand;
|
||||||
char *tagline;
|
char *tagline;
|
||||||
// Global temporary config.
|
// Global temporary config.
|
||||||
@@ -40,11 +41,6 @@ typedef struct _hekate_config
|
|||||||
u32 errors;
|
u32 errors;
|
||||||
} hekate_config;
|
} hekate_config;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
ERR_LIBSYS_LP0 = (1 << 0),
|
|
||||||
} hsysmodule_t;
|
|
||||||
|
|
||||||
void set_default_configuration();
|
void set_default_configuration();
|
||||||
int create_config_entry();
|
int create_config_entry();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018-2019 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -78,7 +78,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||||||
|
|
||||||
char *filename = (char *)malloc(256);
|
char *filename = (char *)malloc(256);
|
||||||
|
|
||||||
memcpy(filename, ini_path, pathlen + 1);
|
strcpy(filename, ini_path);
|
||||||
|
|
||||||
// Get all ini filenames.
|
// Get all ini filenames.
|
||||||
if (is_dir)
|
if (is_dir)
|
||||||
@@ -89,7 +89,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||||||
free(filename);
|
free(filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(filename + pathlen, "/", 2);
|
strcpy(filename + pathlen, "/");
|
||||||
pathlen++;
|
pathlen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||||||
{
|
{
|
||||||
if (filelist[k * 256])
|
if (filelist[k * 256])
|
||||||
{
|
{
|
||||||
memcpy(filename + pathlen, &filelist[k * 256], strlen(&filelist[k * 256]) + 1);
|
strcpy(filename + pathlen, &filelist[k * 256]);
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
|||||||
@@ -24,20 +24,18 @@
|
|||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "fe_emmc_tools.h"
|
#include "fe_emmc_tools.h"
|
||||||
#include "fe_emummc_tools.h"
|
#include "fe_emummc_tools.h"
|
||||||
|
#include "../../../common/memory_map.h"
|
||||||
#include "../config/config.h"
|
#include "../config/config.h"
|
||||||
#include "../libs/fatfs/ff.h"
|
#include "../libs/fatfs/ff.h"
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
#include "../sec/se.h"
|
#include "../sec/se.h"
|
||||||
|
#include "../sec/se_t210.h"
|
||||||
#include "../storage/nx_emmc.h"
|
#include "../storage/nx_emmc.h"
|
||||||
#include "../storage/sdmmc.h"
|
#include "../storage/sdmmc.h"
|
||||||
#include "../utils/btn.h"
|
#include "../utils/btn.h"
|
||||||
#include "../utils/sprintf.h"
|
#include "../utils/sprintf.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
#define EMMC_BUF_ALIGNED 0xB5000000
|
|
||||||
#define SDXC_BUF_ALIGNED 0xB6000000
|
|
||||||
#define MIXD_BUF_ALIGNED 0xB7000000
|
|
||||||
|
|
||||||
#define NUM_SECTORS_PER_ITER 8192 // 4MB Cache.
|
#define NUM_SECTORS_PER_ITER 8192 // 4MB Cache.
|
||||||
#define OUT_FILENAME_SZ 128
|
#define OUT_FILENAME_SZ 128
|
||||||
#define HASH_FILENAME_SZ (OUT_FILENAME_SZ + 11) // 11 == strlen(".sha256sums")
|
#define HASH_FILENAME_SZ (OUT_FILENAME_SZ + 11) // 11 == strlen(".sha256sums")
|
||||||
@@ -52,9 +50,6 @@ extern bool sd_mount();
|
|||||||
extern void sd_unmount(bool deinit);
|
extern void sd_unmount(bool deinit);
|
||||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
static void get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_idx, bool backup)
|
static void get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_idx, bool backup)
|
||||||
{
|
{
|
||||||
sd_mount();
|
sd_mount();
|
||||||
@@ -143,8 +138,6 @@ static void _update_filename(char *outFilename, u32 sdPathLen, u32 currPartIdx)
|
|||||||
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|
||||||
static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32 lba_curr, char *outFilename, emmc_part_t *part)
|
static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32 lba_curr, char *outFilename, emmc_part_t *part)
|
||||||
{
|
{
|
||||||
FIL fp;
|
FIL fp;
|
||||||
@@ -232,6 +225,9 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
se_calc_sha256(hashEm, NULL, bufEm, num << 9, 0, SHA_INIT_HASH, false);
|
||||||
|
|
||||||
f_lseek(&fp, (u64)sdFileSector << (u64)9);
|
f_lseek(&fp, (u64)sdFileSector << (u64)9);
|
||||||
if (f_read_fast(&fp, bufSd, num << 9))
|
if (f_read_fast(&fp, bufSd, num << 9))
|
||||||
{
|
{
|
||||||
@@ -250,8 +246,8 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
se_calc_sha256(hashEm, bufEm, num << 9);
|
se_calc_sha256_finalize(hashEm, NULL);
|
||||||
se_calc_sha256(hashSd, bufSd, num << 9);
|
se_calc_sha256(hashSd, NULL, bufSd, num << 9, 0, SHA_INIT_HASH, true);
|
||||||
res = memcmp(hashEm, hashSd, 0x10);
|
res = memcmp(hashEm, hashSd, 0x10);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
@@ -363,7 +359,7 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t
|
|||||||
|
|
||||||
FIL partialIdxFp;
|
FIL partialIdxFp;
|
||||||
char partialIdxFilename[12];
|
char partialIdxFilename[12];
|
||||||
memcpy(partialIdxFilename, "partial.idx", 12);
|
strcpy(partialIdxFilename, "partial.idx");
|
||||||
|
|
||||||
s_printf(gui->txt_buf, "#96FF00 SD Card free space:# %d MiB\n#96FF00 Total backup size:# %d MiB\n\n",
|
s_printf(gui->txt_buf, "#96FF00 SD Card free space:# %d MiB\n#96FF00 Total backup size:# %d MiB\n\n",
|
||||||
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF,
|
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF,
|
||||||
@@ -769,7 +765,7 @@ void dump_emmc_selected(emmcPartType_t dumpType, emmc_tool_gui_t *gui)
|
|||||||
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
memcpy(bootPart.name, "BOOT", 5);
|
strcpy(bootPart.name, "BOOT");
|
||||||
bootPart.name[4] = (u8)('0' + i);
|
bootPart.name[4] = (u8)('0' + i);
|
||||||
bootPart.name[5] = 0;
|
bootPart.name[5] = 0;
|
||||||
|
|
||||||
@@ -1349,7 +1345,7 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
|
|||||||
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
memcpy(bootPart.name, "BOOT", 4);
|
strcpy(bootPart.name, "BOOT");
|
||||||
bootPart.name[4] = (u8)('0' + i);
|
bootPart.name[4] = (u8)('0' + i);
|
||||||
bootPart.name[5] = 0;
|
bootPart.name[5] = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,8 @@
|
|||||||
#include "../utils/sprintf.h"
|
#include "../utils/sprintf.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
#define EMMC_BUF_ALIGNED 0xB5000000
|
|
||||||
#define SDXC_BUF_ALIGNED 0xB6000000
|
|
||||||
#define MIXD_BUF_ALIGNED 0xB7000000
|
|
||||||
|
|
||||||
#define NUM_SECTORS_PER_ITER 8192 // 4MB Cache.
|
#define NUM_SECTORS_PER_ITER 8192 // 4MB Cache.
|
||||||
#define OUT_FILENAME_SZ 128
|
#define OUT_FILENAME_SZ 128
|
||||||
#define SHA256_SZ 0x20
|
|
||||||
|
|
||||||
#define MBR_1ST_PART_TYPE_OFF 0x1C2
|
#define MBR_1ST_PART_TYPE_OFF 0x1C2
|
||||||
|
|
||||||
@@ -50,9 +45,6 @@ extern hekate_config h_cfg;
|
|||||||
extern bool sd_mount();
|
extern bool sd_mount();
|
||||||
extern void sd_unmount(bool deinit);
|
extern void sd_unmount(bool deinit);
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
void save_emummc_cfg(u32 part_idx, u32 sector_start, const char *path)
|
void save_emummc_cfg(u32 part_idx, u32 sector_start, const char *path)
|
||||||
{
|
{
|
||||||
sd_mount();
|
sd_mount();
|
||||||
@@ -101,8 +93,6 @@ void save_emummc_cfg(u32 part_idx, u32 sector_start, const char *path)
|
|||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|
||||||
static void _update_emummc_base_folder(char *outFilename, u32 sdPathLen, u32 currPartIdx)
|
static void _update_emummc_base_folder(char *outFilename, u32 sdPathLen, u32 currPartIdx)
|
||||||
{
|
{
|
||||||
if (currPartIdx < 10)
|
if (currPartIdx < 10)
|
||||||
@@ -368,7 +358,7 @@ void dump_emummc_file(emmc_tool_gui_t *gui)
|
|||||||
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
memcpy(bootPart.name, "BOOT", 5);
|
strcpy(bootPart.name, "BOOT");
|
||||||
bootPart.name[4] = (u8)('0' + i);
|
bootPart.name[4] = (u8)('0' + i);
|
||||||
bootPart.name[5] = 0;
|
bootPart.name[5] = 0;
|
||||||
|
|
||||||
@@ -623,7 +613,7 @@ void dump_emummc_raw(emmc_tool_gui_t *gui, int part_idx, u32 sector_start)
|
|||||||
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
memcpy(bootPart.name, "BOOT", 5);
|
strcpy(bootPart.name, "BOOT");
|
||||||
bootPart.name[4] = (u8)('0' + i);
|
bootPart.name[4] = (u8)('0' + i);
|
||||||
bootPart.name[5] = 0;
|
bootPart.name[5] = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "../soc/hw_init.h"
|
#include "../soc/hw_init.h"
|
||||||
#include "../soc/t210.h"
|
#include "../soc/t210.h"
|
||||||
#include "../storage/sdmmc.h"
|
#include "../storage/sdmmc.h"
|
||||||
|
#include "../thermal/fan.h"
|
||||||
#include "../thermal/tmp451.h"
|
#include "../thermal/tmp451.h"
|
||||||
#include "../utils/dirlist.h"
|
#include "../utils/dirlist.h"
|
||||||
#include "../utils/sprintf.h"
|
#include "../utils/sprintf.h"
|
||||||
@@ -87,7 +88,7 @@ static void _save_fb_to_bmp()
|
|||||||
const u32 file_size = 0x384000 + 0x36;
|
const u32 file_size = 0x384000 + 0x36;
|
||||||
u8 *bitmap = malloc(file_size);
|
u8 *bitmap = malloc(file_size);
|
||||||
u32 *fb = malloc(0x384000);
|
u32 *fb = malloc(0x384000);
|
||||||
u32 *fb_ptr = gfx_ctxt.fb;
|
u32 *fb_ptr = (u32 *)NYX_FB_ADDRESS;
|
||||||
|
|
||||||
// Reconstruct FB for bottom-top, landscape bmp.
|
// Reconstruct FB for bottom-top, landscape bmp.
|
||||||
for (u32 x = 0; x < 1280; x++)
|
for (u32 x = 0; x < 1280; x++)
|
||||||
@@ -163,7 +164,7 @@ static void _save_fb_to_bmp()
|
|||||||
static void _disp_fb_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t *color_p)
|
static void _disp_fb_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t *color_p)
|
||||||
{
|
{
|
||||||
// Draw to framebuffer.
|
// Draw to framebuffer.
|
||||||
gfx_set_rect_land_pitch(gfx_ctxt.fb, (u32 *)color_p, x1, y1, x2, y2); //pitch
|
gfx_set_rect_land_pitch((u32 *)NYX_FB_ADDRESS, (u32 *)color_p, x1, y1, x2, y2); //pitch
|
||||||
|
|
||||||
// Check if display init was done. If it's the first big draw, init.
|
// Check if display init was done. If it's the first big draw, init.
|
||||||
if (!disp_init_done && ((x2 - x1 + 1) > 600))
|
if (!disp_init_done && ((x2 - x1 + 1) > 600))
|
||||||
@@ -327,9 +328,6 @@ lv_img_dsc_t *bmp_to_lvimg_obj(const char *path)
|
|||||||
return (lv_img_dsc_t *)bitmap;
|
return (lv_img_dsc_t *)bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
lv_res_t nyx_generic_onoff_toggle(lv_obj_t *btn)
|
lv_res_t nyx_generic_onoff_toggle(lv_obj_t *btn)
|
||||||
{
|
{
|
||||||
lv_obj_t *label_btn = lv_obj_get_child(btn, NULL);
|
lv_obj_t *label_btn = lv_obj_get_child(btn, NULL);
|
||||||
@@ -402,7 +400,6 @@ void nyx_window_toggle_buttons(lv_obj_t *win, bool disable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lv_obj_t *nyx_create_standard_window(const char *win_title)
|
lv_obj_t *nyx_create_standard_window(const char *win_title)
|
||||||
{
|
{
|
||||||
static lv_style_t win_bg_style;
|
static lv_style_t win_bg_style;
|
||||||
@@ -715,8 +712,8 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
|
|||||||
" Copyright (c) 2018, ChaN\n\n"
|
" Copyright (c) 2018, ChaN\n\n"
|
||||||
" - bcl-1.2.0,\n"
|
" - bcl-1.2.0,\n"
|
||||||
" Copyright (c) 2003-2006, Marcus Geelnard\n\n"
|
" Copyright (c) 2003-2006, Marcus Geelnard\n\n"
|
||||||
" - Atmosphere (SE sha256, process id patches),\n"
|
" - Atmosphere (Exosphere types/panic, proc id patches),\n"
|
||||||
" Copyright (c) 2018, Atmosphere-NX\n\n"
|
" Copyright (c) 2018-2019, Atmosphere-NX\n\n"
|
||||||
" - elfload,\n"
|
" - elfload,\n"
|
||||||
" Copyright (c) 2014, Owen Shepherd\n"
|
" Copyright (c) 2014, Owen Shepherd\n"
|
||||||
" Copyright (c) 2018, M4xw\n\n"
|
" Copyright (c) 2018, M4xw\n\n"
|
||||||
@@ -724,9 +721,8 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
|
|||||||
" Copyright (c) 2016 Gabor Kiss-Vamosi"
|
" Copyright (c) 2016 Gabor Kiss-Vamosi"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
lv_obj_t * lbl_octopus = lv_label_create(parent, NULL);
|
lv_obj_t * lbl_octopus = lv_label_create(parent, NULL);
|
||||||
lv_obj_align(lbl_octopus, lbl_credits, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI, 0);
|
lv_obj_align(lbl_octopus, lbl_credits, LV_ALIGN_OUT_RIGHT_TOP, -LV_DPI / 10, 0);
|
||||||
lv_ta_set_style(lbl_octopus, LV_TA_STYLE_BG, &monospace_text);
|
lv_ta_set_style(lbl_octopus, LV_TA_STYLE_BG, &monospace_text);
|
||||||
lv_label_set_recolor(lbl_octopus, true);
|
lv_label_set_recolor(lbl_octopus, true);
|
||||||
|
|
||||||
@@ -760,15 +756,13 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
|
|||||||
lv_obj_align(ctcaer_img, lbl_octopus, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, LV_DPI * 2 / 3);
|
lv_obj_align(ctcaer_img, lbl_octopus, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, LV_DPI * 2 / 3);
|
||||||
|
|
||||||
char version[32];
|
char version[32];
|
||||||
s_printf(version, "Nyx v%d.%d.%d", BL_VER_MJ, BL_VER_MN, BL_VER_HF);
|
s_printf(version, "Nyx v%d.%d.%d", NYX_VER_MJ, NYX_VER_MN, NYX_VER_HF);
|
||||||
lv_obj_t * lbl_ver = lv_label_create(parent, NULL);
|
lv_obj_t * lbl_ver = lv_label_create(parent, NULL);
|
||||||
lv_obj_align(lbl_ver, ctcaer_img, LV_ALIGN_OUT_BOTTOM_RIGHT, -LV_DPI / 20, LV_DPI / 4);
|
lv_obj_align(lbl_ver, ctcaer_img, LV_ALIGN_OUT_BOTTOM_RIGHT, -LV_DPI / 20, LV_DPI / 4);
|
||||||
lv_ta_set_style(lbl_ver, LV_TA_STYLE_BG, &monospace_text);
|
lv_ta_set_style(lbl_ver, LV_TA_STYLE_BG, &monospace_text);
|
||||||
lv_label_set_text(lbl_ver, version);
|
lv_label_set_text(lbl_ver, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|
||||||
static void _update_status_bar(void *params)
|
static void _update_status_bar(void *params)
|
||||||
{
|
{
|
||||||
char *label = (char *)malloc(64);
|
char *label = (char *)malloc(64);
|
||||||
@@ -788,10 +782,19 @@ static void _update_status_bar(void *params)
|
|||||||
max17050_get_property(MAX17050_VCELL, &batt_volt);
|
max17050_get_property(MAX17050_VCELL, &batt_volt);
|
||||||
max17050_get_property(MAX17050_Current, &batt_curr);
|
max17050_get_property(MAX17050_Current, &batt_curr);
|
||||||
|
|
||||||
|
u32 soc_temp_dec = (soc_temp >> 8);
|
||||||
|
// Enable fan if more than 44 oC.
|
||||||
|
if (soc_temp_dec > 50)
|
||||||
|
set_fan_duty(100);
|
||||||
|
else if (soc_temp_dec > 44)
|
||||||
|
set_fan_duty(53);
|
||||||
|
else
|
||||||
|
set_fan_duty(0);
|
||||||
|
|
||||||
//! TODO: Parse time and use offset.
|
//! TODO: Parse time and use offset.
|
||||||
// Set time and SoC temperature.
|
// Set time and SoC temperature.
|
||||||
s_printf(label, "%02d:%02d "SYMBOL_DOT" "SYMBOL_TEMPERATURE" %02d.%d",
|
s_printf(label, "%02d:%02d "SYMBOL_DOT" "SYMBOL_TEMPERATURE" %02d.%d",
|
||||||
time.hour, time.min, soc_temp >> 8, (soc_temp & 0xFF) / 10);
|
time.hour, time.min, soc_temp_dec, (soc_temp & 0xFF) / 10);
|
||||||
|
|
||||||
lv_label_set_array_text(status_bar.time_temp, label, 64);
|
lv_label_set_array_text(status_bar.time_temp, label, 64);
|
||||||
|
|
||||||
@@ -825,7 +828,9 @@ static void _update_status_bar(void *params)
|
|||||||
else
|
else
|
||||||
s_printf(label, "#FF3C28 -%d", (~batt_curr + 1) / 1000);
|
s_printf(label, "#FF3C28 -%d", (~batt_curr + 1) / 1000);
|
||||||
|
|
||||||
s_printf(label + strlen(label), " mA# (%d mV)", batt_volt);
|
bool voltage_empty = batt_volt < 3200;
|
||||||
|
s_printf(label + strlen(label), " mA# (%s%d mV%s)",
|
||||||
|
voltage_empty ? "FFF8000" : "", batt_volt, voltage_empty ? "#" : "");
|
||||||
|
|
||||||
lv_label_set_array_text(status_bar.battery_more, label, 64);
|
lv_label_set_array_text(status_bar.battery_more, label, 64);
|
||||||
lv_obj_realign(status_bar.battery_more);
|
lv_obj_realign(status_bar.battery_more);
|
||||||
@@ -1217,9 +1222,6 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
|
|||||||
return LV_RES_OK;
|
return LV_RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
static void _create_tab_home(lv_theme_t *th, lv_obj_t *parent)
|
static void _create_tab_home(lv_theme_t *th, lv_obj_t *parent)
|
||||||
{
|
{
|
||||||
lv_page_set_scrl_layout(parent, LV_LAYOUT_OFF);
|
lv_page_set_scrl_layout(parent, LV_LAYOUT_OFF);
|
||||||
@@ -1573,7 +1575,7 @@ static void _nyx_main_menu(lv_theme_t * th)
|
|||||||
static lv_style_t line_style;
|
static lv_style_t line_style;
|
||||||
lv_style_copy(&line_style, &lv_style_plain_color);
|
lv_style_copy(&line_style, &lv_style_plain_color);
|
||||||
|
|
||||||
line_style.body.main_color = LV_COLOR_HEX3(0xDDD); // 0x505050
|
line_style.body.main_color = LV_COLOR_HEX(0xDDDDDD); // 0x505050
|
||||||
line_style.body.grad_color = line_style.body.main_color;
|
line_style.body.grad_color = line_style.body.main_color;
|
||||||
line_style.body.shadow.width = 0;
|
line_style.body.shadow.width = 0;
|
||||||
|
|
||||||
@@ -1599,8 +1601,6 @@ static void _nyx_main_menu(lv_theme_t * th)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|
||||||
void nyx_load_and_run()
|
void nyx_load_and_run()
|
||||||
{
|
{
|
||||||
memset(&system_tasks, 0, sizeof(system_maintenance_tasks_t));
|
memset(&system_tasks, 0, sizeof(system_maintenance_tasks_t));
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ extern bool sd_mount();
|
|||||||
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
typedef struct _emmc_backup_buttons_t
|
typedef struct _emmc_backup_buttons_t
|
||||||
{
|
{
|
||||||
lv_obj_t *emmc_boot;
|
lv_obj_t *emmc_boot;
|
||||||
@@ -470,5 +467,3 @@ lv_res_t create_window_backup_restore_tool(lv_obj_t *btn)
|
|||||||
|
|
||||||
return LV_RES_OK;
|
return LV_RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|||||||
@@ -39,9 +39,6 @@ extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_st
|
|||||||
static int part_idx;
|
static int part_idx;
|
||||||
static u32 sector_start;
|
static u32 sector_start;
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
static void _create_window_emummc()
|
static void _create_window_emummc()
|
||||||
{
|
{
|
||||||
emmc_tool_gui_t emmc_tool_gui_ctxt;
|
emmc_tool_gui_t emmc_tool_gui_ctxt;
|
||||||
@@ -55,7 +52,7 @@ static void _create_window_emummc()
|
|||||||
//Disable buttons.
|
//Disable buttons.
|
||||||
nyx_window_toggle_buttons(win, true);
|
nyx_window_toggle_buttons(win, true);
|
||||||
|
|
||||||
// Chreate important info container.
|
// Create important info container.
|
||||||
lv_obj_t *h1 = lv_cont_create(win, NULL);
|
lv_obj_t *h1 = lv_cont_create(win, NULL);
|
||||||
lv_cont_set_fit(h1, false, true);
|
lv_cont_set_fit(h1, false, true);
|
||||||
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 5);
|
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 5);
|
||||||
@@ -728,7 +725,6 @@ static lv_res_t _save_disable_emummc_cfg_action(lv_obj_t * btn)
|
|||||||
_create_emummc_saved_mbox();
|
_create_emummc_saved_mbox();
|
||||||
sd_unmount(false);
|
sd_unmount(false);
|
||||||
|
|
||||||
|
|
||||||
return LV_RES_INV;
|
return LV_RES_INV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1152,5 +1148,3 @@ lv_res_t create_win_emummc_tools(lv_obj_t *btn)
|
|||||||
|
|
||||||
return LV_RES_OK;
|
return LV_RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|||||||
@@ -45,9 +45,6 @@ extern void sd_unmount(bool deinit);
|
|||||||
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
static lv_res_t _create_window_dump_done(int error, char *dump_filenames)
|
static lv_res_t _create_window_dump_done(int error, char *dump_filenames)
|
||||||
{
|
{
|
||||||
lv_style_t *darken;
|
lv_style_t *darken;
|
||||||
@@ -278,13 +275,13 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
|
|||||||
s_printf(dram_man, "Samsung %s", (!dram_id) ? "4GB" : "6GB");
|
s_printf(dram_man, "Samsung %s", (!dram_id) ? "4GB" : "6GB");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
memcpy(dram_man, "Hynix 4GB", 10);
|
strcpy(dram_man, "Hynix 4GB");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
memcpy(dram_man, "Micron 4GB", 11);
|
strcpy(dram_man, "Micron 4GB");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
memcpy(dram_man, "Unknown", 8);
|
strcpy(dram_man, "Unknown");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,7 +886,9 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||||||
s_printf(txt_buf + strlen(txt_buf), "-%d mA\n", (~value + 1) / 1000);
|
s_printf(txt_buf + strlen(txt_buf), "-%d mA\n", (~value + 1) / 1000);
|
||||||
|
|
||||||
max17050_get_property(MAX17050_VCELL, &value);
|
max17050_get_property(MAX17050_VCELL, &value);
|
||||||
s_printf(txt_buf + strlen(txt_buf), "%d mV\n", value);
|
bool voltage_empty = value < 3200;
|
||||||
|
s_printf(txt_buf + strlen(txt_buf), "%s%d mV%s\n",
|
||||||
|
voltage_empty ? "FFF8000" : "", value, voltage_empty ? " (Empty!)#" : "");
|
||||||
|
|
||||||
max17050_get_property(MAX17050_OCVInternal, &value);
|
max17050_get_property(MAX17050_OCVInternal, &value);
|
||||||
s_printf(txt_buf + strlen(txt_buf), "%d mV\n", value);
|
s_printf(txt_buf + strlen(txt_buf), "%d mV\n", value);
|
||||||
@@ -1067,7 +1066,7 @@ void create_tab_info(lv_theme_t *th, lv_obj_t *parent)
|
|||||||
|
|
||||||
static lv_style_t line_style;
|
static lv_style_t line_style;
|
||||||
lv_style_copy(&line_style, th->line.decor);
|
lv_style_copy(&line_style, th->line.decor);
|
||||||
line_style.line.color = LV_COLOR_HEX3(0x444);
|
line_style.line.color = LV_COLOR_HEX(0x444444);
|
||||||
|
|
||||||
line_sep = lv_line_create(h1, line_sep);
|
line_sep = lv_line_create(h1, line_sep);
|
||||||
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 16);
|
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 16);
|
||||||
@@ -1171,5 +1170,3 @@ void create_tab_info(lv_theme_t *th, lv_obj_t *parent)
|
|||||||
lv_obj_set_style(label_txt6, &hint_small_style);
|
lv_obj_set_style(label_txt6, &hint_small_style);
|
||||||
lv_obj_align(label_txt6, btn7, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
|
lv_obj_align(label_txt6, btn7, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ extern void sd_unmount(bool deinit);
|
|||||||
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
|
|
||||||
bool get_autorcm_status(bool change)
|
bool get_autorcm_status(bool change)
|
||||||
{
|
{
|
||||||
u8 corr_mod_byte0;
|
u8 corr_mod_byte0;
|
||||||
@@ -277,9 +274,9 @@ static lv_res_t _create_window_unset_abit_tool(lv_obj_t *btn)
|
|||||||
u32 total = 0;
|
u32 total = 0;
|
||||||
|
|
||||||
if (!nintendo_folder)
|
if (!nintendo_folder)
|
||||||
memcpy(path, "", 1);
|
path[0] = 0;
|
||||||
else
|
else
|
||||||
memcpy(path, "Nintendo", 9);
|
strcpy(path, "Nintendo");
|
||||||
|
|
||||||
u32 ufidx = 0;
|
u32 ufidx = 0;
|
||||||
|
|
||||||
@@ -288,7 +285,7 @@ static lv_res_t _create_window_unset_abit_tool(lv_obj_t *btn)
|
|||||||
// Also fix the emuMMC Nintendo folders.
|
// Also fix the emuMMC Nintendo folders.
|
||||||
if (nintendo_folder)
|
if (nintendo_folder)
|
||||||
{
|
{
|
||||||
memcpy(path, "emuMMC", 7);
|
strcpy(path, "emuMMC");
|
||||||
_fix_attributes(&ufidx, lb_val, path, &total, nintendo_folder, nintendo_folder);
|
_fix_attributes(&ufidx, lb_val, path, &total, nintendo_folder, nintendo_folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,7 +821,7 @@ static void _create_tab_tools_arc_autorcm(lv_theme_t *th, lv_obj_t *parent)
|
|||||||
label_btn = lv_label_create(btn3, NULL);
|
label_btn = lv_label_create(btn3, NULL);
|
||||||
lv_btn_set_fit(btn3, true, true);
|
lv_btn_set_fit(btn3, true, true);
|
||||||
lv_label_set_recolor(label_btn, true);
|
lv_label_set_recolor(label_btn, true);
|
||||||
lv_label_set_static_text(label_btn, SYMBOL_REFRESH" AutoRCM #00ffc9 ON #");
|
lv_label_set_static_text(label_btn, SYMBOL_REFRESH" AutoRCM #00FFC9 ON #");
|
||||||
lv_obj_align(btn3, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
|
lv_obj_align(btn3, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
|
||||||
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, _create_mbox_autorcm_status);
|
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, _create_mbox_autorcm_status);
|
||||||
|
|
||||||
@@ -894,5 +891,3 @@ void create_tab_tools(lv_theme_t *th, lv_obj_t *parent)
|
|||||||
|
|
||||||
lv_tabview_set_tab_act(tv, 0, false);
|
lv_tabview_set_tab_act(tv, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|||||||
@@ -29,10 +29,6 @@
|
|||||||
#include "../soc/t210.h"
|
#include "../soc/t210.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC target ("thumb")
|
|
||||||
#pragma GCC optimize ("Os")
|
|
||||||
|
|
||||||
#include "di.inl"
|
#include "di.inl"
|
||||||
|
|
||||||
static u32 _display_ver = 0;
|
static u32 _display_ver = 0;
|
||||||
@@ -258,6 +254,7 @@ void display_color_screen(u32 color)
|
|||||||
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
|
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
|
||||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
|
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
|
||||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
|
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
|
||||||
|
|
||||||
usleep(35000);
|
usleep(35000);
|
||||||
|
|
||||||
display_backlight(true);
|
display_backlight(true);
|
||||||
@@ -265,26 +262,21 @@ void display_color_screen(u32 color)
|
|||||||
|
|
||||||
u32 *display_init_framebuffer()
|
u32 *display_init_framebuffer()
|
||||||
{
|
{
|
||||||
// Sanitize framebuffer area.
|
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||||
//memset((u32 *)FB_ADDRESS, 0, 0x3C0000);
|
|
||||||
// This configures the framebuffer @ FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
|
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
|
||||||
|
|
||||||
usleep(35000);
|
usleep(35000);
|
||||||
|
|
||||||
return (u32 *)FB_ADDRESS;
|
return (u32 *)NYX_FB_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *display_init_framebuffer2()
|
u32 *display_init_framebuffer2()
|
||||||
{
|
{
|
||||||
// Sanitize framebuffer area.
|
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||||
memset((u32 *)FB_ADDRESS, 0, 0x3C0000);
|
|
||||||
// This configures the framebuffer @ FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
|
||||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer2, 32);
|
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer2, 32);
|
||||||
|
|
||||||
usleep(35000);
|
usleep(35000);
|
||||||
|
|
||||||
return (u32 *)FB_ADDRESS;
|
return (u32 *)NYX_FB_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -18,10 +18,9 @@
|
|||||||
#ifndef _DI_H_
|
#ifndef _DI_H_
|
||||||
#define _DI_H_
|
#define _DI_H_
|
||||||
|
|
||||||
|
#include "../../../common/memory_map.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
#define FB_ADDRESS 0xF0800000
|
|
||||||
|
|
||||||
/*! Display registers. */
|
/*! Display registers. */
|
||||||
#define _DIREG(reg) ((reg) * 4)
|
#define _DIREG(reg) ((reg) * 4)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (c) 2018 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -415,7 +415,7 @@ static const cfg_op_t _display_config_11[113] = {
|
|||||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||||
{DC_DISP_BACK_PORCH, 0x90048},
|
{DC_DISP_BACK_PORCH, 0x90048},
|
||||||
{DC_DISP_ACTIVE, 0x50002D0},
|
{DC_DISP_ACTIVE, 0x50002D0},
|
||||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||||
/* End of Display timings */
|
/* End of Display timings */
|
||||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||||
@@ -548,7 +548,7 @@ static const cfg_op_t cfg_display_framebuffer[32] = {
|
|||||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||||
{DC_WIN_BUFFER_CONTROL, 0},
|
{DC_WIN_BUFFER_CONTROL, 0},
|
||||||
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
||||||
{DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address.
|
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||||
{DC_WINBUF_ADDR_H_OFFSET, 0}, //Linear: 0x383FFC, Block: 0x3813FC
|
{DC_WINBUF_ADDR_H_OFFSET, 0}, //Linear: 0x383FFC, Block: 0x3813FC
|
||||||
{DC_WINBUF_ADDR_V_OFFSET, 1279}, //Linear: 1279, Block: 0
|
{DC_WINBUF_ADDR_V_OFFSET, 1279}, //Linear: 1279, Block: 0
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
@@ -557,7 +557,7 @@ static const cfg_op_t cfg_display_framebuffer[32] = {
|
|||||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, //Enable window AD.
|
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
|
||||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
|
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
|
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
|
||||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
|
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
|
||||||
@@ -583,7 +583,7 @@ static const cfg_op_t cfg_display_framebuffer2[32] = {
|
|||||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||||
{DC_WIN_BUFFER_CONTROL, 0},
|
{DC_WIN_BUFFER_CONTROL, 0},
|
||||||
{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK}, //Regular surface.
|
{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK}, //Regular surface.
|
||||||
{DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address.
|
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||||
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, //Linear: 0x383FFC, Block: 0x3813FC
|
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, //Linear: 0x383FFC, Block: 0x3813FC
|
||||||
{DC_WINBUF_ADDR_V_OFFSET, 0}, //Linear: 1279, Block: 0
|
{DC_WINBUF_ADDR_V_OFFSET, 0}, //Linear: 1279, Block: 0
|
||||||
{DC_WIN_WIN_OPTIONS, 0},
|
{DC_WIN_WIN_OPTIONS, 0},
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user