Compare commits

...

40 Commits

Author SHA1 Message Date
Christoph Baumann
76508c74e8 file based emmc emummc, some other stuff 2025-05-12 01:24:01 +02:00
Christoph Baumann
79b6df64d6 fix emummc status 2025-05-08 01:52:05 +02:00
Christoph Baumann
0a7a004839 file based emummc on emmc 2025-05-08 01:48:04 +02:00
Christoph Baumann
7521055bec fix name 2025-05-07 17:29:04 +02:00
Christoph Baumann
39d99a77fe remove debug prtint 2025-05-07 17:28:56 +02:00
Christoph Baumann
b0f0e9be47 get actual size of file based emummc instead of reading from gpt 2025-05-07 17:28:47 +02:00
Christoph Baumann
55a4a814e0 fix emummc ums writes 2025-05-07 17:28:11 +02:00
Christoph Baumann
4bfe1fe2cd add missing fsync 2025-05-07 17:27:58 +02:00
Christoph Baumann
6d09e65d85 fix emummc bis 2025-05-07 16:46:48 +02:00
Christoph Baumann
59a173c994 add support for emummc ums, this is terrible plz fix 2025-05-07 16:46:36 +02:00
Christoph Baumann
e5ceb4a2de add mmc types for emummc, used only for emummc ums 2025-05-07 16:45:26 +02:00
Christoph Baumann
ea3dae672e allow configuring size for file based emummc 2025-05-07 16:44:51 +02:00
Christoph Baumann
2af1cc0b8c ums support for file based emummc 2025-05-07 16:42:57 +02:00
Christoph Baumann
942e7defe3 add methods to access file based emummc 2025-05-07 16:42:36 +02:00
Christoph Baumann
39b74dd50d file based bis support 2025-05-07 12:17:13 +02:00
Christoph Baumann
bbe8ddaf66 ask to resize, if emu partition is larger than required 2025-05-06 17:40:53 +02:00
Christoph Baumann
47e030c7fc fix boot drive name 2025-05-06 12:58:44 +02:00
Christoph Baumann
4a127db80b add emusd ums 2025-05-06 12:57:40 +02:00
Christoph Baumann
241b0f2274 . 2025-05-06 12:37:46 +02:00
Christoph Baumann
ba6073610c support for android emmc 2025-05-02 17:08:49 +02:00
Christoph Baumann
70cb99cd0c add symbol to boot storage ums 2025-05-02 17:08:16 +02:00
Christoph Baumann
7941a3d4d6 fix boot storage selection 2025-05-02 17:07:42 +02:00
Christoph Baumann
1ddf9690b1 l4t flashing for emmc 2025-05-02 11:38:44 +02:00
Christoph Baumann
f4d8ee4efc fix ums storage after partitioning 2025-05-02 11:15:52 +02:00
Christoph Baumann
4f72660603 fuck 2025-05-02 01:43:51 +02:00
Christoph Baumann
2440318cb5 emmc bis storage 2025-04-30 11:29:06 +02:00
Christoph Baumann
61e91f79c1 emmc partitioning mostly fixed 2025-04-30 01:36:55 +02:00
Christoph Baumann
bad8566c58 account for 1mb for backup gpt 2025-04-29 12:48:44 +02:00
Christoph Baumann
28796b417b fix indicators, add emmc_mount, various fixes 2025-04-29 12:36:32 +02:00
Christoph Baumann
31c8ad0d88 add drive to access an area on emmc/sd as disk 2025-04-27 01:05:09 +02:00
Christoph Baumann
0be3fd4f64 only show remaining bar when it has non negligible size 2025-04-26 23:42:37 +02:00
Christoph Baumann
3e9def3608 Add emuSD to partition manager, finer emuMMC partition size control, allow double android 2025-04-26 23:37:45 +02:00
Christoph Baumann
678ce79a54 emmc partition layout selection, adjusted emummc partition size steps 2025-04-26 02:34:43 +02:00
Christoph Baumann
b11e8095ed . 2025-04-25 15:29:22 +02:00
Christoph Baumann
849d533200 UMS: check if successfully initialized, don't care about fat mounted 2025-04-24 18:29:24 +02:00
Christoph Baumann
337f219ac6 Support for NYX to load from BOOT1/GPP/SD in that order, UMS option to mount whatever volume is selected as boot storage 2025-04-24 12:06:15 +02:00
Christoph Baumann
4e9e21b3b1 move boot_storage.h/.c to bdk/storage, check result of ensure_partition 2025-04-22 14:25:14 +02:00
Christoph Baumann
fe5e4dc40a use enum for drive numbers 2025-04-22 14:15:45 +02:00
Christoph Baumann
5798dcde0d Add support for reading boot files from FAT partition on BOOT1/GPP/SD in that order
Emummc config is read from boot partition, file based files still read from SD
2025-04-22 13:42:20 +02:00
Christoph Baumann
9d2ec42a9f fatfs: extend gpt support 2025-04-20 19:52:15 +02:00
57 changed files with 6468 additions and 2011 deletions

View File

@@ -35,9 +35,9 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
mc.o sdram.o minerva.o \
gpio.o pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
fuse.o kfuse.o \
sdmmc.o sdmmc_driver.o emmc.o sd.o emummc.o \
sdmmc.o sdmmc_driver.o emmc.o sd.o emummc.o emummc_file_based.o \
bq24193.o max17050.o max7762x.o max77620-rtc.o \
hw_init.o \
hw_init.o boot_storage.o \
)
# Utilities.

View File

@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/boot_storage.h>
#include <string.h>
#include "ianos.h"
@@ -75,7 +76,7 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
uintptr_t epaddr = 0;
// Read library.
fileBuf = sd_file_read(path, NULL);
fileBuf = boot_storage_file_read(path, NULL);
if (!fileBuf)
goto out;

View File

@@ -10,6 +10,7 @@ extern "C" {
#endif
#include <utils/types.h>
#include <fatfs_cfg.h>
/* Status of Disk Functions */
typedef BYTE DSTATUS;
@@ -23,14 +24,6 @@ typedef enum {
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
typedef enum {
DRIVE_SD = 0,
DRIVE_RAM = 1,
DRIVE_EMMC = 2,
DRIVE_BIS = 3,
DRIVE_EMU = 4
} DDRIVE;
/*---------------------------------------*/
/* Prototypes for disk control functions */

View File

@@ -473,6 +473,10 @@ static const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS}; /* Pre-define
#endif
#endif
#if FF_SIMPLE_GPT
static const BYTE GUID_MS_Basic[16] = {0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7};
#endif
/*--------------------------------*/
/* LFN/Directory working buffer */
@@ -3319,15 +3323,28 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
}
#if FF_SIMPLE_GPT
if (fmt >= 2) {
/* If GPT Check the first partition */
/* If GPT, iterate over all part entries and check MS Basic partitions */
gpt_header_t *gpt_header = (gpt_header_t *)fs->win;
if (move_window(fs, 1) != FR_OK) return FR_DISK_ERR;
if (!mem_cmp(&gpt_header->signature, "EFI PART", 8)) {
if (move_window(fs, gpt_header->part_ent_lba) != FR_OK) return FR_DISK_ERR;
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win;
fs->part_type = 1;
bsect = gpt_entry->lba_start;
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
DWORD cur_entry, ofs, part;
part = LD2PT(vol);
cur_entry = 0;
for(i = 0; i < gpt_header->num_part_ents; i++){
if (move_window(fs, gpt_header->part_ent_lba + i * sizeof(gpt_entry_t) / SS(fs))) return FR_DISK_ERR;
ofs = i * sizeof(gpt_entry_t) % SS(fs);
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win + ofs;
if (!mem_cmp(gpt_entry->type_guid, GUID_MS_Basic, 16)){
cur_entry++;
bsect = gpt_entry->lba_start;
fmt = bsect ? check_fs(fs, bsect) : 3;
if(part == 0 && fmt <= 1) break;
if(part != 0 && cur_entry == part) break;
}
}
if(part && part != cur_entry){
fmt = 3;
}
}
}
#endif

253
bdk/storage/boot_storage.c Normal file
View File

@@ -0,0 +1,253 @@
#include "boot_storage.h"
#include <libs/fatfs/ff.h>
#include <fatfs_cfg.h>
#include <storage/sd.h>
#include <storage/emmc.h>
#include <utils/types.h>
#include <gfx_utils.h>
#include <stdlib.h>
#define DEV_INVALID 0xff
static FATFS boot_storage_fs;
static BYTE drive_cur = -1;
static BYTE drive = -1;
static const char* drive_base_paths[] = {
[DRIVE_SD] = "sd:",
[DRIVE_BOOT1] = "boot1_:",
[DRIVE_BOOT1_1MB] = "boot1_1mb:",
[DRIVE_EMMC] = "emmc:",
};
static bool _is_eligible(){
if(f_stat(".no_boot_storage", NULL) == FR_OK){
return false;
}
return true;
}
bool boot_storage_get_mounted(){
switch(drive_cur){
case DRIVE_SD:
return sd_get_card_mounted();
case DRIVE_EMMC:
return emmc_get_mounted();
case DRIVE_BOOT1:
case DRIVE_BOOT1_1MB:
return drive_cur != DEV_INVALID;
}
return false;
}
bool boot_storage_get_initialized(){
switch(drive_cur){
case DRIVE_BOOT1:
case DRIVE_EMMC:
case DRIVE_BOOT1_1MB:
return emmc_get_initialized();
case DRIVE_SD:
return sd_get_card_initialized();
}
return false;
}
static bool _boot_storage_initialize(){
switch(drive_cur){
case DRIVE_BOOT1:
case DRIVE_EMMC:
case DRIVE_BOOT1_1MB:
return emmc_initialize(false);
case DRIVE_SD:
return sd_initialize(false);
}
return false;
}
static void _boot_storage_end(bool deinit){
if(boot_storage_get_mounted()){
switch(drive_cur){
case DRIVE_SD:
sd_unmount();
break;
case DRIVE_EMMC:
emmc_unmount();
break;
case DRIVE_BOOT1:
case DRIVE_BOOT1_1MB:
f_mount(NULL, drive_base_paths[drive_cur], 0);
}
drive_cur = DEV_INVALID;
}
if(deinit){
switch(drive_cur){
case DRIVE_SD:
sd_end();
break;
case DRIVE_EMMC:
case DRIVE_BOOT1:
case DRIVE_BOOT1_1MB:
emmc_end();
break;
}
}
}
void boot_storage_unmount(){
_boot_storage_end(false);
}
void boot_storage_end(){
_boot_storage_end(true);
}
u8 boot_storage_get_drive(){
return drive;
}
static bool _boot_storage_mount(){
// may want to check sd card first and prioritize it
FRESULT res;
if(!emmc_get_initialized() && !emmc_initialize(false)){
goto emmc_init_fail;
}
static const BYTE emmc_drives[] = {DRIVE_BOOT1_1MB, DRIVE_BOOT1};
for(BYTE i = 0; i < ARRAY_SIZE(emmc_drives); i++){
res = f_mount(&boot_storage_fs, drive_base_paths[emmc_drives[i]], true);
if(res == FR_OK){
gfx_printf("trying %s\n", drive_base_paths[emmc_drives[i]]);
res = f_chdrive(drive_base_paths[emmc_drives[i]]);
if(res == FR_OK && _is_eligible()){
gfx_printf("%s ok\n", drive_base_paths[emmc_drives[i]]);
drive_cur = emmc_drives[i];
drive = drive_cur;
break;
}else{
gfx_printf("%s fail\n", drive_base_paths[emmc_drives[i]]);
f_mount(NULL, drive_base_paths[emmc_drives[i]],false);
res = FR_INVALID_DRIVE;
}
}
}
if(res != FR_OK){
emmc_end();
}
if(res == FR_OK){
return true;
}
emmc_init_fail:
if(!emmc_initialize(false)){
goto emmc_init_fail2;
}
if(!emmc_mount()){
emmc_end();
goto emmc_init_fail2;
}
res = f_chdrive(drive_base_paths[DRIVE_EMMC]);
if(res == FR_OK && _is_eligible()){
drive_cur = DRIVE_EMMC;
drive = drive_cur;
return true;
}
emmc_init_fail2:
if(!sd_initialize(false)){
goto out;
}
if(!sd_mount()){
sd_end();
goto out;
}
res = f_chdrive(drive_base_paths[DRIVE_SD]);
if(res == FR_OK && _is_eligible()){
drive_cur = DRIVE_SD;
drive = drive_cur;
return true;
}
sd_end();
out:
return false;
}
bool boot_storage_mount(){
bool mounted = boot_storage_get_mounted();
bool initialized = boot_storage_get_initialized();
bool res = mounted && initialized;
if(!mounted){
// not mounted. mounting will also initialize.
res = _boot_storage_mount();
}else if(!initialized){
res = _boot_storage_initialize();
}
if(res){
res = f_chdrive(drive_base_paths[drive_cur]) == FR_OK;
}
return res;
}
void *boot_storage_file_read(const char *path, u32 *fsize)
{
FIL fp;
if (!boot_storage_get_mounted())
return NULL;
if (f_open(&fp, path, FA_READ) != FR_OK)
return NULL;
u32 size = f_size(&fp);
if (fsize)
*fsize = size;
void *buf = malloc(size);
if (f_read(&fp, buf, size, NULL) != FR_OK)
{
free(buf);
f_close(&fp);
return NULL;
}
f_close(&fp);
return buf;
}
int boot_storage_save_to_file(const void *buf, u32 size, const char *filename)
{
FIL fp;
u32 res = 0;
if (!boot_storage_get_mounted())
return FR_DISK_ERR;
res = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);
if (res)
{
EPRINTFARGS("Error (%d) creating file\n%s.\n", res, filename);
return res;
}
f_write(&fp, buf, size, NULL);
f_close(&fp);
return 0;
}

View File

@@ -0,0 +1,21 @@
#ifndef _BOOT_STORAGE_H
#define _BOOT_STORAGE_H
#include <utils/types.h>
// check if boot1 (1mb), boot1, gpp, sd (in that order) have fat32 partition,
// mount the partition and set the current drive to it
bool boot_storage_mount();
void boot_storage_unmount();
void boot_storage_end();
bool boot_storage_get_mounted();
bool boot_storage_get_initialized();
void *boot_storage_file_read(const char *path, u32 *fsize);
int boot_storage_save_to_file(const void *buf, u32 size, const char *filename);
u8 boot_storage_get_drive();
#endif

View File

@@ -21,10 +21,14 @@
#include <mem/heap.h>
#include <soc/fuse.h>
#include <storage/mbr_gpt.h>
#include <gfx_utils.h>
#include <utils/list.h>
#include <storage/emummc_file_based.h>
static u16 emmc_errors[3] = { 0 }; // Init and Read/Write errors.
static u32 emmc_mode = EMMC_MMC_HS400;
static bool emmc_init_done = false;
static bool emmc_mounted = false;
sdmmc_t emmc_sdmmc;
sdmmc_storage_t emmc_storage;
@@ -61,7 +65,26 @@ u32 emmc_get_mode()
return emmc_mode;
}
void emmc_end() { sdmmc_storage_end(&emmc_storage); }
static void _emmc_deinit(bool deinit){
if(emmc_init_done){
// TODO: Allow unmount even when not init'd?
if(emmc_mounted){
f_mount(NULL, "emmc:", 0);
}
if(deinit){
sdmmc_storage_end(&emmc_storage);
emmc_init_done = false;
}
}
emmc_mounted = false;
}
void emmc_end() { _emmc_deinit(true); }
bool emmc_get_initialized(){
return emmc_init_done;
}
int emmc_init_retry(bool power_cycle)
{
@@ -97,7 +120,13 @@ int emmc_init_retry(bool power_cycle)
emmc_mode = EMMC_MMC_HS400;
}
return sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, bus_width, type);
int res = sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, bus_width, type);
if(res){
emmc_init_done = true;
}else{
emmc_init_done = false;
}
return res;
}
bool emmc_initialize(bool power_cycle)
@@ -212,6 +241,14 @@ int emmc_part_write(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *bu
#endif
}
sdmmc_storage_t *emmc_part_get_storage(){
#ifdef BDK_EMUMMC_ENABLE
return emummc_get_storage();
#else
return &emmc_storage;
#endif
}
void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1)
{
if (fuse_read_hw_state() == FUSE_NX_HW_STATE_PROD)
@@ -225,3 +262,44 @@ void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1)
*mod1 = 0x84;
}
}
bool emmc_mount()
{
if (emmc_init_done && emmc_mounted)
return true;
int res = 0;
if (!emmc_init_done)
res = !emmc_initialize(false);
if (res)
{
gfx_con.mute = false;
EPRINTF("Failed to init eMMC.");
}
else
{
if (!emmc_mounted)
res = f_mount(&emmc_fs, "emmc:", 1); // Volume 0 is SD.
if (res == FR_OK)
{
emmc_mounted = true;
return true;
}
else
{
gfx_con.mute = false;
EPRINTFARGS("Failed to mount eMMC (FatFS Error %d).\nMake sure that a FAT partition exists..", res);
}
}
return false;
}
bool emmc_get_mounted(){
return emmc_mounted;
}
void emmc_unmount() { _emmc_deinit(false); }

View File

@@ -65,12 +65,17 @@ int emmc_init_retry(bool power_cycle);
bool emmc_initialize(bool power_cycle);
int emmc_set_partition(u32 partition);
void emmc_end();
bool emmc_mount();
void emmc_unmount();
bool emmc_get_initialized();
bool emmc_get_mounted();
void emmc_gpt_parse(link_t *gpt);
void emmc_gpt_free(link_t *gpt);
emmc_part_t *emmc_part_find(link_t *gpt, const char *name);
int emmc_part_read(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
int emmc_part_write(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
sdmmc_storage_t *emmc_part_get_storage();
void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1);

View File

@@ -0,0 +1,233 @@
#include "emummc_file_based.h"
#include <string.h>
#include <stdlib.h>
#include <libs/fatfs/ff.h>
#include <gfx_utils.h>
// TODO: fast read/writes
static FIL active_file;
// -0xff: none, -1: boot 0, -2: boot1, 0+: gpp
static s32 active_file_idx;
static char file_based_base_path[0x80];
static u32 file_part_sz_sct;
static u32 active_part;
static u32 file_based_base_path_len;
static int _emummc_storage_file_based_read_write_single(u32 sector, u32 num_sectors, void *buf, bool is_write){
#if FF_FS_READONLY == 1
if(is_write){
return FR_WRITE_PROTECTED;
}
#endif
int res = f_lseek(&active_file, (u64)sector << 9);
if(res != FR_OK){
return res;
}
if(is_write){
res = f_write(&active_file, buf, (u64)num_sectors << 9, NULL);
}else{
res = f_read(&active_file, buf, (u64)num_sectors << 9, NULL);
}
if(res != FR_OK){
return res;
}
return FR_OK;
}
static int _emummc_storage_file_based_change_file(const char *name, s32 idx){
int res;
if(active_file_idx == idx){
return FR_OK;
}
if(active_file_idx != -0xff){
f_close(&active_file);
active_file_idx = -0xff;
}
strcpy(file_based_base_path + file_based_base_path_len, name);
#if FF_FS_READONLY == 1
res = f_open(&active_file, file_based_base_path, FA_READ);
#else
res = f_open(&active_file, file_based_base_path, FA_READ | FA_WRITE);
#endif
if(res != FR_OK){
return res;
}
active_file_idx = idx;
return FR_OK;
}
static int _emummc_storage_file_based_read_write(u32 sector, u32 num_sectors, void *buf, bool is_write){
#if FF_FS_READONLY == 1
if(is_write){
return 0;
}
#endif
if(file_part_sz_sct == 0){
return 0;
}
int res;
if(active_part == 1){
// boot0
res = _emummc_storage_file_based_change_file("BOOT0", -1);
if(res != FR_OK){
return 0;
}
res = _emummc_storage_file_based_read_write_single(sector, num_sectors, buf, is_write);
if(res != FR_OK){
return 0;
}
f_sync(&active_file);
return 1;
}else if(active_part == 2){
// boot1
res = _emummc_storage_file_based_change_file("BOOT1", -2);
if(res != FR_OK){
return 0;
}
res = _emummc_storage_file_based_read_write_single(sector, num_sectors, buf, is_write) == FR_OK;
if(res != FR_OK){
return 0;
}
f_sync(&active_file);
return 1;
}else if(active_part == 0){
// GPP
if(file_part_sz_sct == 0){
return 0;
}
u32 scts_left = num_sectors;
u32 cur_sct = sector;
while(scts_left){
// offset within file
u32 offset = cur_sct % file_part_sz_sct;
// read up to start of next file or sectors left, whatever is less
u32 sct_cnt = file_part_sz_sct - offset;
sct_cnt = MIN(sct_cnt, scts_left);
u32 file_idx = cur_sct / file_part_sz_sct;
if((s32)file_idx != active_file_idx){
char name[3] = "";
if(file_idx < 10){
strcpy(name, "0");
}
itoa(file_idx, name + strlen(name), 10);
res = _emummc_storage_file_based_change_file(name, file_idx);
if(res != FR_OK){
return 0;
}
}
res = _emummc_storage_file_based_read_write_single(offset, sct_cnt, buf + ((u64)(num_sectors - scts_left) << 9), is_write);
if(res != FR_OK){
return 0;
}
cur_sct += sct_cnt;
scts_left -= sct_cnt;
}
if(res != FR_OK){
return 0;
}
f_sync(&active_file);
return 1;
}
return 0;
}
int emummc_storage_file_base_set_partition(u32 partition){
active_part = partition;
return 1;
}
int emummc_storage_file_based_init(const char *path){
strcpy(file_based_base_path, path);
file_based_base_path_len = strlen(file_based_base_path);
strcat(file_based_base_path + file_based_base_path_len, "00");
active_part = 0;
FILINFO fi;
if(f_stat(file_based_base_path, &fi) != FR_OK){
return 0;
}
file_part_sz_sct = 0;
if(fi.fsize){
file_part_sz_sct = fi.fsize >> 9;
}
active_file_idx = -0xff;
return 1;
}
void emummc_storage_file_based_end(){
if(active_file_idx != -0xff){
f_close(&active_file);
}
active_file_idx = -0xff;
file_based_base_path[0] = '\0';
file_part_sz_sct = 0;
}
#if FF_FS_READONLY == 0
int emummc_storage_file_based_write(u32 sector, u32 num_sectors, void *buf){
return _emummc_storage_file_based_read_write(sector, num_sectors, buf, true);
}
#endif
int emummc_storage_file_based_read(u32 sector, u32 num_sectors, void *buf){
return _emummc_storage_file_based_read_write(sector, num_sectors, buf, false);
}
u32 emummc_storage_file_based_get_total_gpp_size(const char *path){
u32 path_len = strlen(path);
u32 total_size_sct = 0;
char file_path[0x80];
u32 cur_idx = 0;
int res;
strcpy(file_path, path);
strcpy(file_path + path_len, "00");
FILINFO fi;
res = f_stat(file_path, &fi);
while(res == FR_OK){
cur_idx++;
total_size_sct += fi.fsize >> 9;
char name[3] = "0";
if(cur_idx >= 10){
name[0] = '\0';
}
itoa(cur_idx, name + strlen(name), 10);
strcpy(file_path + path_len, name);
res = f_stat(file_path, &fi);
}
return total_size_sct;
}

View File

@@ -0,0 +1,14 @@
#ifndef _EMUMMC_FILE_BASED_H
#define _EMUMMC_FILE_BASED_H
#include <bdk.h>
int emummc_storage_file_base_set_partition(u32 partition);
int emummc_storage_file_based_init(const char *path);
void emummc_storage_file_based_end();
int emummc_storage_file_based_write(u32 sector, u32 num_sectors, void *buf);
int emummc_storage_file_based_read(u32 sector, u32 num_sectors, void *buf);
u32 emummc_storage_file_based_get_total_gpp_size(const char *path);
sdmmc_storage_t *emummc_get_storage();
#endif

39
bdk/storage/mbr_gpt.c Normal file
View File

@@ -0,0 +1,39 @@
#include "mbr_gpt.h"
#include <utils/types.h>
#include <string.h>
bool mbr_has_gpt(const mbr_t *mbr){
for(u32 i = 0; i < 4; i++){
if(mbr->partitions[i].type == 0xee){
return true;
}
}
return false;
}
void wctombs(const u16 *src, char *dest, u32 len_max){
const u16 *cur = src;
do{
*dest++ = *cur & 0xff;
len_max--;
}while(*cur++ && len_max);
}
void ctowcs(const char *src, u16 *dest, u32 len_max){
const char *cur = src;
do{
*dest++ = *cur;
len_max--;
}while(*cur++ && len_max);
}
s32 gpt_get_part_by_name(gpt_t *gpt, const char* name, s32 prev){
u16 wc_name[36];
ctowcs(name, wc_name, 36);
for(s32 i = prev + 1; i < (s32)gpt->header.num_part_ents && i < 128; i++){
if(!memcmp(wc_name, gpt->entries[i].name, strlen(name) * 2)){
return i;
}
}
return -1;
}

View File

@@ -81,4 +81,10 @@ typedef struct _gpt_t
gpt_entry_t entries[128];
} gpt_t;
bool mbr_has_gpt(const mbr_t *mbr);
void wctombs(const u16 *src, char *dest, u32 len_max);
void ctowcs(const char *src, u16 *dest, u32 len_max);
s32 gpt_get_part_by_name(gpt_t *gpt, const char* name, s32 prev);
#endif

View File

@@ -17,6 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libs/fatfs/ff.h>
#include <stdlib.h>
#include <storage/nx_emmc_bis.h>
#include <string.h>
#include <memory_map.h>
@@ -26,6 +29,7 @@
#include <storage/emmc.h>
#include <storage/sd.h>
#include <storage/sdmmc.h>
#include <storage/emummc_file_based.h>
#include <utils/types.h>
#define BIS_CLUSTER_SECTORS 32
@@ -56,6 +60,8 @@ static u32 emu_offset = 0;
static emmc_part_t *system_part = NULL;
static u32 *cache_lookup_tbl = (u32 *)NX_BIS_LOOKUP_ADDR;
static bis_cache_t *bis_cache = (bis_cache_t *)NX_BIS_CACHE_ADDR;
static sdmmc_storage_t *emu_storage = NULL;
static bool file_based = false;
static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush)
{
@@ -95,10 +101,14 @@ static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush
return 1; // Encryption error.
// If not reading from cache, do a regular read and decrypt.
if (!emu_offset)
if(emu_storage){
res = sdmmc_storage_write(emu_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
}else if(file_based){
res = emummc_storage_file_based_write(system_part->lba_start + sector, count, bis_cache->dma_buff);
}else{
res = emmc_part_write(system_part, sector, count, bis_cache->dma_buff);
else
res = sdmmc_storage_write(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
}
if (!res)
return 1; // R/W error.
@@ -155,10 +165,13 @@ static int nx_emmc_bis_read_block_normal(u32 sector, u32 count, void *buff)
u32 sector_in_cluster = sector % BIS_CLUSTER_SECTORS;
// If not reading from cache, do a regular read and decrypt.
if (!emu_offset)
if(emu_storage){
res = sdmmc_storage_read(emu_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
}else if(file_based){
res = emummc_storage_file_based_read(system_part->lba_start + sector, count, bis_cache->dma_buff);
}else{
res = emmc_part_read(system_part, sector, count, bis_cache->dma_buff);
else
res = sdmmc_storage_read(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
}
if (!res)
return 1; // R/W error.
@@ -212,10 +225,14 @@ static int nx_emmc_bis_read_block_cached(u32 sector, u32 count, void *buff)
cache_lookup_tbl[cluster] = bis_cache->top_idx;
// Read the whole cluster the sector resides in.
if (!emu_offset)
if (emu_storage){
res = sdmmc_storage_read(emu_storage, emu_offset + system_part->lba_start + cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
}else if(file_based){
res = emummc_storage_file_based_read(system_part->lba_start + cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
}else{
res = emmc_part_read(system_part, cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
else
res = sdmmc_storage_read(&sd_storage, emu_offset + system_part->lba_start + cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
}
if (!res)
return 1; // R/W error.
@@ -292,10 +309,11 @@ int nx_emmc_bis_write(u32 sector, u32 count, void *buff)
return 1;
}
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset)
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, sdmmc_storage_t *storage, u32 emummc_offset)
{
system_part = part;
emu_offset = emummc_offset;
emu_storage = storage;
_nx_emmc_bis_cluster_cache_init(enable_cache);
@@ -318,8 +336,31 @@ void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset)
system_part = NULL;
}
void nx_emmc_bis_init_file_based(emmc_part_t *part, bool enable_cache, const char *base_path){
emummc_storage_file_based_init(base_path);
file_based = true;
nx_emmc_bis_init(part, enable_cache, NULL, 0);
}
void nx_emmc_bis_end()
{
_nx_emmc_bis_flush_cache();
if(file_based){
emummc_storage_file_based_end();
}
system_part = NULL;
emu_storage = NULL;
emu_offset = 0;
file_based = false;
}
sdmmc_storage_t *nx_emmc_bis_get_storage(){
if(emu_storage == &emmc_storage){
return &emmc_storage;
}else{
return emmc_part_get_storage();
}
}

View File

@@ -229,7 +229,10 @@ typedef struct _nx_emmc_cal0_t
int nx_emmc_bis_read(u32 sector, u32 count, void *buff);
int nx_emmc_bis_write(u32 sector, u32 count, void *buff);
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset);
// when storage == NULL, use active emummc config, otherwise, access storage at offset
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, sdmmc_storage_t *storage, u32 emummc_offset);
void nx_emmc_bis_init_file_based(emmc_part_t *part, bool enable_cache, const char *base_path);
void nx_emmc_bis_end();
sdmmc_storage_t *nx_emmc_bis_get_storage();
#endif

View File

@@ -199,7 +199,7 @@ bool sd_mount()
else
{
if (!sd_mounted)
res = f_mount(&sd_fs, "0:", 1); // Volume 0 is SD.
res = f_mount(&sd_fs, "sd:", 1); // Volume 0 is SD.
if (res == FR_OK)
{
sd_mounted = true;
@@ -227,7 +227,7 @@ static void _sd_deinit(bool deinit)
if (sd_init_done)
{
if (sd_mounted)
f_mount(NULL, "0:", 1); // Volume 0 is SD.
f_mount(NULL, "sd:", 1); // Volume 0 is SD.
if (deinit)
{
@@ -246,14 +246,30 @@ bool sd_is_gpt()
return sd_fs.part_type;
}
void *sd_file_read(const char *path, u32 *fsize)
{
FIL fp;
if (!sd_get_card_mounted())
return NULL;
if (f_open(&fp, path, FA_READ) != FR_OK)
char *cwd = (char*)malloc(0x200);
if(f_getcwd(cwd, 0x200) != FR_OK){
free(cwd);
return NULL;
}
if(f_chdrive("sd:") != FR_OK){
free(cwd);
return NULL;
}
if (f_open(&fp, path, FA_READ) != FR_OK){
f_chdrive(cwd);
free(cwd);
return NULL;
}
u32 size = f_size(&fp);
if (fsize)
@@ -263,13 +279,17 @@ void *sd_file_read(const char *path, u32 *fsize)
if (f_read(&fp, buf, size, NULL) != FR_OK)
{
f_chdrive(cwd);
free(buf);
free(cwd);
f_close(&fp);
return NULL;
}
f_chdrive(cwd);
f_close(&fp);
free(cwd);
return buf;
}
@@ -281,13 +301,33 @@ int sd_save_to_file(const void *buf, u32 size, const char *filename)
if (!sd_get_card_mounted())
return FR_DISK_ERR;
char *cwd = malloc(0x200);
res = f_getcwd(cwd, 0x200);
if(res != FR_OK){
free(cwd);
return res;
}
res = f_chdrive("sd:");
if(res != FR_OK){
free(cwd);
return res;
}
res = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);
if (res)
{
EPRINTFARGS("Error (%d) creating file\n%s.\n", res, filename);
f_chdrive(cwd);
free(cwd);
return res;
}
f_chdrive(cwd);
free(cwd);
f_write(&fp, buf, size, NULL);
f_close(&fp);

View File

@@ -29,8 +29,12 @@ extern u32 sd_power_cycle_time_start;
typedef enum _sdmmc_type
{
MMC_SD = 0,
MMC_EMMC = 1,
MMC_SD = 0,
MMC_EMMC = 1,
MMC_EMUMMC_FILE = 2,
MMC_EMUMMC_RAW_SD = 3,
MMC_EMUMMC_RAW_EMMC = 4,
MMC_EMUMMC_FILE_EMMC = 5,
EMMC_GPP = 0,
EMMC_BOOT0 = 1,

View File

@@ -19,6 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/emmc.h>
#include <storage/emummc_file_based.h>
#include <string.h>
#include <usb/usbd.h>
@@ -495,8 +497,14 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
}
// Do the SDMMC read.
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, sdmmc_buf))
amount = 0;
if(ums->lun.storage){
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, sdmmc_buf))
amount = 0;
}else{
if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, sdmmc_buf)){
amount = 0;
}
}
// Wait for the async USB transfer to finish.
if (!first_read)
@@ -650,9 +658,15 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
goto empty_write;
// Perform the write.
if (!sdmmc_storage_write(ums->lun.storage, ums->lun.offset + lba_offset,
amount >> UMS_DISK_LBA_SHIFT, (u8 *)bulk_ctxt->bulk_out_buf))
amount = 0;
if(ums->lun.storage){
if (!sdmmc_storage_write(ums->lun.storage, ums->lun.offset + lba_offset,
amount >> UMS_DISK_LBA_SHIFT, (u8 *)bulk_ctxt->bulk_out_buf))
amount = 0;
}else{
if(!emummc_storage_file_based_write(ums->lun.offset + lba_offset, amount >> UMS_DISK_LBA_SHIFT, (u8*)bulk_ctxt->bulk_out_buf)){
amount = 0;
}
}
DPRINTF("file write %X @ %X\n", amount, lba_offset);
@@ -722,8 +736,14 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
break;
}
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf))
amount = 0;
if(ums->lun.storage){
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf))
amount = 0;
}else{
if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf)){
amount = 0;
}
}
DPRINTF("File read %X @ %X\n", amount, lba_offset);
@@ -756,8 +776,12 @@ static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
buf[3] = 20; // Additional length.
buf += 4;
s_printf((char *)buf, "%04X%s",
ums->lun.storage->cid.serial, ums->lun.type == MMC_SD ? " SD " : " eMMC ");
if(ums->lun.storage){
s_printf((char *)buf, "%04X%s",
ums->lun.storage->cid.serial, ums->lun.type == MMC_SD ? " SD " : " eMMC ");
}else{
strcpy((char*)buf, "0000 emuMMC");
}
switch (ums->lun.partition)
{
@@ -1861,7 +1885,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
if (usbs->type == MMC_SD)
{
sd_end();
if (!sd_mount())
if (!sd_mount() && !sd_get_card_initialized())
{
ums.set_text(ums.label, "#FFDD00 Failed to init SD!#");
res = 1;
@@ -1871,9 +1895,46 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
ums.lun.sdmmc = &sd_sdmmc;
ums.lun.storage = &sd_storage;
}else if(usbs->type == MMC_EMUMMC_FILE){
// sd must be already mounted and emummc file based initialized
if(!sd_get_card_mounted()){
ums.set_text(ums.label, "#FFDD00 Failed to init SD!#");
res = 1;
goto init_fail;
}
ums.lun.storage = NULL;
ums.lun.sdmmc = NULL;
}
else
{
else if(usbs->type == MMC_EMUMMC_RAW_EMMC){
if (!emmc_initialize(false))
{
ums.set_text(ums.label, "#FFDD00 Failed to init eMMC!#");
res = 1;
goto init_fail;
}
emmc_set_partition(EMMC_GPP);
ums.lun.sdmmc = &emmc_sdmmc;
ums.lun.storage = &emmc_storage;
}else if(usbs->type == MMC_EMUMMC_RAW_SD){
if (!sd_initialize(false))
{
ums.set_text(ums.label, "#FFDD00 Failed to init SD!#");
res = 1;
goto init_fail;
}
ums.lun.sdmmc = &emmc_sdmmc;
ums.lun.storage = &emmc_storage;
}else if(usbs->type == MMC_EMUMMC_FILE_EMMC){
if(!emmc_get_mounted()){
ums.set_text(ums.label, "#FFDD00 Failed to init eMMC!#");
res = 1;
goto init_fail;
}
ums.lun.storage = NULL;
ums.lun.sdmmc = NULL;
} else{
if (!emmc_initialize(false))
{
ums.set_text(ums.label, "#FFDD00 Failed to init eMMC!#");
@@ -1902,10 +1963,24 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
// If partition sectors are not set get them from hardware.
if (!ums.lun.num_sectors)
{
if (usbs->type == MMC_EMMC && (ums.lun.partition - 1)) // eMMC BOOT0/1.
ums.lun.num_sectors = emmc_storage.ext_csd.boot_mult << 8;
else
ums.lun.num_sectors = ums.lun.storage->sec_cnt; // eMMC GPP or SD.
switch(usbs->type){
case MMC_EMMC:
if(ums.lun.partition - 1){
ums.lun.num_sectors = emmc_storage.ext_csd.boot_mult << 8;
}else{
ums.lun.num_sectors = ums.lun.storage->sec_cnt;
}
break;
case MMC_SD:
ums.lun.num_sectors = ums.lun.storage->sec_cnt;
break;
case MMC_EMUMMC_FILE:
case MMC_EMUMMC_FILE_EMMC:
case MMC_EMUMMC_RAW_SD:
case MMC_EMUMMC_RAW_EMMC:
ums.set_text(ums.label, "#FFDD00 No sector count set for emuMMC!#");
break;
}
}
do

View File

@@ -105,6 +105,9 @@ typedef unsigned long uptr;
#define likely(x) (__builtin_expect((x) != 0, 1))
#define unlikely(x) (__builtin_expect((x) != 0, 0))
#define XSTR(a) STR(a)
#define STR(a) #a
/* Bootloader/Nyx */
#define BOOT_CFG_AUTOBOOT_EN BIT(0)
#define BOOT_CFG_FROM_LAUNCH BIT(1)
@@ -126,7 +129,12 @@ typedef enum _nyx_ums_type
NYX_UMS_EMMC_GPP,
NYX_UMS_EMUMMC_BOOT0,
NYX_UMS_EMUMMC_BOOT1,
NYX_UMS_EMUMMC_GPP
NYX_UMS_EMUMMC_GPP,
NYX_UMS_BOOT_STRG_SD,
NYX_UMS_BOOT_STRG_BOOT1,
NYX_UMS_BOOT_STRG_BOOT1_1MB,
NYX_UMS_BOOT_STRG_GPP,
NYX_UMS_EMUSD,
} nyx_ums_type;
typedef struct __attribute__((__packed__)) _boot_cfg_t

View File

@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/boot_storage.h>
#include <string.h>
#include <mem/heap.h>
@@ -258,6 +259,7 @@ void power_set_state(power_state_t state)
u8 reg;
// Unmount and power down sd card.
boot_storage_end();
sd_end();
// De-initialize and power down various hardware.

View File

@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/sd.h>
#include <string.h>
#include <bdk.h>
@@ -232,20 +233,19 @@ void print_sdcard_info()
sd_storage.ssr.app_class, sd_storage.csd.write_protect,
sd_errors[0], sd_errors[1], sd_errors[2]); // SD_ERROR_INIT_FAIL, SD_ERROR_RW_FAIL, SD_ERROR_RW_RETRY.
int res = f_mount(&sd_fs, "", 1);
if (!res)
if (sd_mount())
{
gfx_puts("Acquiring FAT volume info...\n\n");
f_getfree("", &sd_fs.free_clst, NULL);
f_getfree("sd:", &sd_fs.free_clst, NULL);
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
TXT_CLR_CYAN_L, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", TXT_CLR_DEFAULT,
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
f_mount(NULL, "", 1);
sd_end();
}
else
{
EPRINTFARGS("Failed to mount SD card (FatFS Error %d).\n"
"Make sure that a FAT partition exists..", res);
EPRINTF("Failed to mount SD card.\n"
"Make sure that a FAT partition exists..");
}
sd_end();

View File

@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/boot_storage.h>
#include <string.h>
#include <bdk.h>
@@ -84,7 +85,7 @@ typedef struct _fss_content_t
static void _fss_update_r2p()
{
u8 *r2p_payload = sd_file_read("atmosphere/reboot_payload.bin", NULL);
u8 *r2p_payload = boot_storage_file_read("atmosphere/reboot_payload.bin", NULL);
is_ipl_updated(r2p_payload, "atmosphere/reboot_payload.bin", h_cfg.updater2p ? true : false);

View File

@@ -28,6 +28,7 @@
#include "../frontend/fe_tools.h"
#include "../config.h"
#include "../storage/emummc.h"
#include <storage/boot_storage.h>
extern hekate_config h_cfg;
@@ -409,7 +410,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool i
*/
// Use custom TSEC Hovi Keygen firmware.
tsec_ctxt->fw = sd_file_read("bootloader/sys/thk.bin", NULL);
tsec_ctxt->fw = boot_storage_file_read("bootloader/sys/thk.bin", NULL);
if (!tsec_ctxt->fw)
{
_hos_crit_error("\nFailed to load thk.bin");
@@ -785,6 +786,7 @@ int hos_launch(ini_sec_t *cfg)
}
// Check if SD Card is GPT.
// TODO: not relevant with emuSD
if (sd_is_gpt())
{
_hos_crit_error("SD has GPT only!");
@@ -1086,6 +1088,7 @@ int hos_launch(ini_sec_t *cfg)
config_exosphere(&ctxt, warmboot_base);
// Unmount SD card and eMMC.
boot_storage_end();
sd_end();
emmc_end();

View File

@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/boot_storage.h>
#include <string.h>
#include <bdk.h>
@@ -29,7 +30,7 @@
static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
{
ctxt->warmboot = sd_file_read(value, &ctxt->warmboot_size);
ctxt->warmboot = boot_storage_file_read(value, &ctxt->warmboot_size);
if (!ctxt->warmboot)
return 0;
@@ -38,7 +39,7 @@ static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
{
ctxt->secmon = sd_file_read(value, &ctxt->secmon_size);
ctxt->secmon = boot_storage_file_read(value, &ctxt->secmon_size);
if (!ctxt->secmon)
return 0;
@@ -47,7 +48,7 @@ static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
static int _config_kernel(launch_ctxt_t *ctxt, const char *value)
{
ctxt->kernel = sd_file_read(value, &ctxt->kernel_size);
ctxt->kernel = boot_storage_file_read(value, &ctxt->kernel_size);
if (!ctxt->kernel)
return 0;
@@ -81,7 +82,7 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
strcpy(dir + dirlen, filelist->name[i]);
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
mkip1->kip1 = sd_file_read(dir, &size);
mkip1->kip1 = boot_storage_file_read(dir, &size);
if (!mkip1->kip1)
{
free(mkip1);
@@ -103,7 +104,7 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
else
{
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
mkip1->kip1 = sd_file_read(value, &size);
mkip1->kip1 = boot_storage_file_read(value, &size);
if (!mkip1->kip1)
{
free(mkip1);
@@ -265,7 +266,7 @@ static int _config_fss(launch_ctxt_t *ctxt, const char *value)
static int _config_exo_fatal_payload(launch_ctxt_t *ctxt, const char *value)
{
ctxt->exofatal = sd_file_read(value, &ctxt->exofatal_size);
ctxt->exofatal = boot_storage_file_read(value, &ctxt->exofatal_size);
if (!ctxt->exofatal)
return 0;

View File

@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/boot_storage.h>
#include <string.h>
#include <stdlib.h>
@@ -387,7 +388,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb)
_warmboot_filename(path, burnt_fuses);
if (!f_stat(path, NULL))
{
ctxt->warmboot = sd_file_read(path, &ctxt->warmboot_size);
ctxt->warmboot = boot_storage_file_read(path, &ctxt->warmboot_size);
burnt_fuses = tmp_fuses;
break;
}

View File

@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/boot_storage.h>
#include <string.h>
#include <bdk.h>
@@ -382,7 +383,7 @@ static int _kipm_inject(const char *kipm_path, char *target_name, pkg2_kip1_info
if (!strcmp((char *)ki->kip1->name, target_name))
{
u32 size = 0;
u8 *kipm_data = (u8 *)sd_file_read(kipm_path, &size);
u8 *kipm_data = (u8 *)boot_storage_file_read(kipm_path, &size);
if (!kipm_data)
return 1;

View File

@@ -25,6 +25,7 @@
#include "../hos/pkg1.h"
#include "l4t.h"
#include "l4t_config.inl"
#include <storage/boot_storage.h>
/*
* API Revision info
@@ -1025,7 +1026,7 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
return;
// Done loading bootloaders/firmware.
sd_end();
boot_storage_end();
// We don't need AHB aperture open.
mc_disable_ahb_redirect();

View File

@@ -7,11 +7,37 @@
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include <storage/sd.h>
#include <storage/sdmmc.h>
#include <string.h>
#include <bdk.h>
#include <libs/fatfs/diskio.h> /* FatFs lower layer API */
#include <fatfs_cfg.h>
static bool ensure_partition(BYTE pdrv){
u8 part;
switch(pdrv){
case DRIVE_SD:
return true;
case DRIVE_BOOT1:
case DRIVE_BOOT1_1MB:
part = EMMC_BOOT1;
break;
case DRIVE_EMMC:
part = EMMC_GPP;
break;
default:
return false;
}
if(emmc_storage.partition != part){
return emmc_set_partition(part);
}
return true;
}
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
@@ -43,7 +69,30 @@ DRESULT disk_read (
UINT count /* Number of sectors to read */
)
{
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
if(!ensure_partition(pdrv)){
return RES_ERROR;
}
sdmmc_storage_t *storage = &sd_storage;
u32 actual_sector = sector;
switch(pdrv){
case DRIVE_SD:
break;
case DRIVE_BOOT1:
case DRIVE_EMMC:
storage = &emmc_storage;
break;
case DRIVE_BOOT1_1MB:
storage = &emmc_storage;
actual_sector = sector + (0x100000 / 512);
break;
default:
return RES_ERROR;
}
return sdmmc_storage_read(storage, actual_sector, count, buff) ? RES_OK : RES_ERROR;
}
/*-----------------------------------------------------------------------*/
@@ -56,7 +105,30 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
if(!ensure_partition(pdrv)){
return RES_ERROR;
}
sdmmc_storage_t *storage = &sd_storage;
u32 actual_sector = sector;
switch(pdrv){
case DRIVE_SD:
break;
case DRIVE_BOOT1:
case DRIVE_EMMC:
storage = &emmc_storage;
break;
case DRIVE_BOOT1_1MB:
storage = &emmc_storage;
actual_sector = sector + (0x100000 / 512);
break;
default:
return RES_ERROR;
}
return sdmmc_storage_write(storage, actual_sector, count, (void*)buff) ? RES_OK : RES_ERROR;
}
/*-----------------------------------------------------------------------*/

View File

@@ -166,7 +166,7 @@
*/
#define FF_FS_RPATH 0
#define FF_FS_RPATH 2
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related functions.
@@ -179,12 +179,12 @@
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 1
#define FF_VOLUMES 4
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "sd"
#define FF_STR_VOLUME_ID 1
#define FF_VOLUME_STRS "sd", "boot1", "boot1_1mb", "emmc"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
@@ -301,5 +301,11 @@
/ included somewhere in the scope of ff.h. */
typedef enum {
DRIVE_SD = 0,
DRIVE_BOOT1 = 1,
DRIVE_BOOT1_1MB = 2,
DRIVE_EMMC = 3,
} DDRIVE;
/*--- End of configuration options ---*/

View File

@@ -31,6 +31,7 @@
#include <libs/compr/blz.h>
#include <libs/fatfs/ff.h>
#include "storage/emummc.h"
#include <storage/boot_storage.h>
#include "frontend/fe_tools.h"
#include "frontend/fe_info.h"
@@ -205,7 +206,7 @@ static void _launch_payload(char *path, bool update, bool clear_screen)
if (update && is_ipl_updated(buf, path, false))
goto out;
sd_end();
boot_storage_end();
if (size < 0x30000)
{
@@ -264,8 +265,8 @@ static void _launch_payloads()
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
if (!sd_mount())
goto failed_sd_mount;
if (!boot_storage_mount())
goto failed_boot_storage_mount;
ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
@@ -308,7 +309,7 @@ static void _launch_payloads()
free(ments);
free(dir);
free(filelist);
sd_end();
boot_storage_end();
return;
}
@@ -324,11 +325,11 @@ static void _launch_payloads()
_launch_payload(dir, false, true);
}
failed_sd_mount:
failed_boot_storage_mount:
free(dir);
free(ments);
free(filelist);
sd_end();
boot_storage_end();
btn_wait();
}
@@ -346,7 +347,7 @@ static void _launch_ini_list()
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
if (!sd_mount())
if (!boot_storage_mount())
goto parse_failed;
// Check that ini files exist and parse them.
@@ -449,7 +450,7 @@ parse_failed:
wrong_emupath:
if (emummc_path)
{
sd_mount();
boot_storage_mount();
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
}
}
@@ -474,7 +475,7 @@ static void _launch_config()
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
if (!sd_mount())
if (!boot_storage_mount())
goto parse_failed;
// Load emuMMC configuration.
@@ -557,7 +558,7 @@ static void _launch_config()
if (!cfg_sec)
{
free(ments);
sd_end();
boot_storage_end();
return;
}
@@ -592,13 +593,13 @@ parse_failed:
wrong_emupath:
if (emummc_path)
{
sd_mount();
boot_storage_mount();
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
}
}
out:
sd_end();
boot_storage_end();
free(ments);
@@ -611,11 +612,11 @@ out:
static void _nyx_load_run()
{
u8 *nyx = sd_file_read("bootloader/sys/nyx.bin", NULL);
u8 *nyx = boot_storage_file_read("bootloader/sys/nyx.bin", NULL);
if (!nyx)
return;
sd_end();
boot_storage_end();
render_static_bootlogo();
display_backlight_brightness(h_cfg.backlight, 1000);
@@ -913,11 +914,11 @@ skip_list:
// Check if user set custom logo path at the boot entry.
if (bootlogoCustomEntry)
bitmap = (u8 *)sd_file_read(bootlogoCustomEntry, &fsize);
bitmap = (u8 *)boot_storage_file_read(bootlogoCustomEntry, &fsize);
// Custom entry bootlogo not found, trying default custom one.
if (!bitmap)
bitmap = (u8 *)sd_file_read("bootloader/bootlogo.bmp", &fsize);
bitmap = (u8 *)boot_storage_file_read("bootloader/bootlogo.bmp", &fsize);
if (bitmap)
{
@@ -1010,7 +1011,7 @@ skip_list:
wrong_emupath:
if (emummc_path || b_cfg.boot_cfg & BOOT_CFG_TO_EMUMMC)
{
sd_mount();
boot_storage_mount();
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
}
@@ -1482,7 +1483,8 @@ void ipl_main()
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
// Mount SD Card.
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
// TODO: boot storage may not be sd card -> set proper error
h_cfg.errors |= !boot_storage_mount() ? ERR_SD_BOOT_EN : 0;
// Check if watchdog was fired previously.
if (watchdog_fired())
@@ -1525,7 +1527,7 @@ skip_lp0_minerva_config:
_auto_launch();
// Failed to launch Nyx, unmount SD Card.
sd_end();
boot_storage_end();
// Set ram to a freq that doesn't need periodic training.
minerva_change_freq(FREQ_800);

View File

@@ -14,6 +14,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <storage/emmc.h>
#include <storage/sd.h>
#include <storage/sdmmc.h>
#include <string.h>
#include <stdlib.h>
@@ -22,6 +25,7 @@
#include "emummc.h"
#include "../config.h"
#include <libs/fatfs/ff.h>
#include <storage/emummc_file_based.h>
extern hekate_config h_cfg;
emummc_cfg_t emu_cfg = { 0 };
@@ -77,33 +81,68 @@ bool emummc_set_path(char *path)
FIL fp;
bool found = false;
strcpy(emu_cfg.emummc_file_based_path, path);
// strcpy(emu_cfg.emummc_file_based_path, "sd:");
strcpy(emu_cfg.emummc_file_based_path, "");
strcat(emu_cfg.emummc_file_based_path, path);
strcat(emu_cfg.emummc_file_based_path, "/raw_based");
if (!f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
{
if (!f_read(&fp, &emu_cfg.sector, 4, NULL))
if (emu_cfg.sector)
if (!f_read(&fp, &emu_cfg.sector, 4, NULL)){
if (emu_cfg.sector){
found = true;
}
else
{
strcpy(emu_cfg.emummc_file_based_path, path);
strcat(emu_cfg.emummc_file_based_path, "/file_based");
if (!f_stat(emu_cfg.emummc_file_based_path, NULL))
{
emu_cfg.sector = 0;
emu_cfg.path = path;
found = true;
emu_cfg.enabled = 1;
goto out;
}
}
}
if (found)
strcpy(emu_cfg.emummc_file_based_path, "");
strcat(emu_cfg.emummc_file_based_path, path);
strcat(emu_cfg.emummc_file_based_path, "/raw_emmc_based");
if (!f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
{
if (!f_read(&fp, &emu_cfg.sector, 4, NULL)){
if (emu_cfg.sector){
found = true;
emu_cfg.enabled = 4;
goto out;
}
}
}
// strcpy(emu_cfg.emummc_file_based_path, "sd:");
strcpy(emu_cfg.emummc_file_based_path, "");
strcat(emu_cfg.emummc_file_based_path, path);
strcat(emu_cfg.emummc_file_based_path, "/file_based");
if (!f_stat(emu_cfg.emummc_file_based_path, NULL))
{
emu_cfg.sector = 0;
emu_cfg.path = path;
emu_cfg.enabled = 1;
found = true;
goto out;
}
// strcpy(emu_cfg.emummc_file_based_path, "sd:");
strcpy(emu_cfg.emummc_file_based_path, "");
strcat(emu_cfg.emummc_file_based_path, path);
strcat(emu_cfg.emummc_file_based_path, "/file_emmc_based");
if (!f_stat(emu_cfg.emummc_file_based_path, NULL))
{
emu_cfg.sector = 0;
emu_cfg.path = path;
emu_cfg.enabled = 4;
found = true;
goto out;
}
out:
if (found)
{
// Get ID from path.
u32 id_from_path = 0;
u32 path_size = strlen(path);
@@ -134,7 +173,7 @@ static int emummc_raw_get_part_off(int part_idx)
int emummc_storage_init_mmc()
{
FILINFO fno;
// FILINFO fno;
emu_cfg.active_part = 0;
// Always init eMMC even when in emuMMC. eMMC is needed from the emuMMC driver anyway.
@@ -144,86 +183,105 @@ int emummc_storage_init_mmc()
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
return 0;
if (!sd_mount())
goto out;
bool file_based = false;
if (!emu_cfg.sector)
{
strcpy(emu_cfg.emummc_file_based_path, emu_cfg.path);
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
if (f_stat(emu_cfg.emummc_file_based_path, &fno))
{
EPRINTF("Failed to open eMMC folder.");
goto out;
if(emu_cfg.enabled == 4){
// emmc based
if(!emu_cfg.sector){
// file based
if(!emmc_mount()){
return 1;
}
strcpy(emu_cfg.emummc_file_based_path, "emmc:");
strcat(emu_cfg.emummc_file_based_path, emu_cfg.path);
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
file_based = true;
}else{
// raw based
// emmc already initialized
}
f_chmod(emu_cfg.emummc_file_based_path, AM_ARC, AM_ARC);
strcat(emu_cfg.emummc_file_based_path, "/00");
if (f_stat(emu_cfg.emummc_file_based_path, &fno))
{
EPRINTF("Failed to open emuMMC rawnand.");
goto out;
}else{
// sd based
if(!emu_cfg.sector){
// file based
if(!sd_mount()){
return 1;
}
strcpy(emu_cfg.emummc_file_based_path, "sd:");
strcat(emu_cfg.emummc_file_based_path, emu_cfg.path);
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
file_based = true;
}else{
// raw based
if(!sd_initialize(false)){
return 1;
}
}
emu_cfg.file_based_part_size = fno.fsize >> 9;
}
if(file_based){
return emummc_storage_file_based_init(emu_cfg.emummc_file_based_path) == 0;
}
return 0;
out:
return 1;
}
int emummc_storage_end()
{
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
if(!h_cfg.emummc_force_disable && emu_cfg.enabled && !emu_cfg.sector){
emummc_storage_file_based_end();
}
if(!emu_cfg.enabled || h_cfg.emummc_force_disable || emu_cfg.enabled == 4){
emmc_end();
else
}else{
sd_end();
}
return 1;
}
int emummc_storage_read(u32 sector, u32 num_sectors, void *buf)
{
FIL fp;
sdmmc_storage_t *storage = emu_cfg.enabled == 4 ? &emmc_storage : &sd_storage;
// FIL fp;
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
return sdmmc_storage_read(&emmc_storage, sector, num_sectors, buf);
else if (emu_cfg.sector)
{
sector += emu_cfg.sector;
sector += emummc_raw_get_part_off(emu_cfg.active_part) * 0x2000;
return sdmmc_storage_read(&sd_storage, sector, num_sectors, buf);
return sdmmc_storage_read(storage, sector, num_sectors, buf);
}
else
{
if (!emu_cfg.active_part)
{
u32 file_part = sector / emu_cfg.file_based_part_size;
sector = sector % emu_cfg.file_based_part_size;
if (file_part >= 10)
itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 2, 10);
else
{
emu_cfg.emummc_file_based_path[strlen(emu_cfg.emummc_file_based_path) - 2] = '0';
itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10);
}
}
if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
{
EPRINTF("Failed to open emuMMC image.");
return 0;
}
f_lseek(&fp, (u64)sector << 9);
if (f_read(&fp, buf, (u64)num_sectors << 9, NULL))
{
EPRINTF("Failed to read emuMMC image.");
f_close(&fp);
return 0;
}
return emummc_storage_file_based_read(sector, num_sectors, buf);
// if (!emu_cfg.active_part)
// {
// u32 file_part = sector / emu_cfg.file_based_part_size;
// sector = sector % emu_cfg.file_based_part_size;
// if (file_part >= 10)
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 2, 10);
// else
// {
// emu_cfg.emummc_file_based_path[strlen(emu_cfg.emummc_file_based_path) - 2] = '0';
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10);
// }
// }
// if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
// {
// EPRINTF("Failed to open emuMMC image.");
// return 0;
// }
// f_lseek(&fp, (u64)sector << 9);
// if (f_read(&fp, buf, (u64)num_sectors << 9, NULL))
// {
// EPRINTF("Failed to read emuMMC image.");
// f_close(&fp);
// return 0;
// }
f_close(&fp);
return 1;
// f_close(&fp);
// return 1;
}
return 1;
@@ -231,72 +289,73 @@ int emummc_storage_read(u32 sector, u32 num_sectors, void *buf)
int emummc_storage_write(u32 sector, u32 num_sectors, void *buf)
{
FIL fp;
sdmmc_storage_t *storage = emu_cfg.enabled == 4 ? &emmc_storage : &sd_storage;
// FIL fp;
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
return sdmmc_storage_write(&emmc_storage, sector, num_sectors, buf);
else if (emu_cfg.sector)
{
sector += emu_cfg.sector;
sector += emummc_raw_get_part_off(emu_cfg.active_part) * 0x2000;
return sdmmc_storage_write(&sd_storage, sector, num_sectors, buf);
return sdmmc_storage_write(storage, sector, num_sectors, buf);
}
else
{
if (!emu_cfg.active_part)
{
u32 file_part = sector / emu_cfg.file_based_part_size;
sector = sector % emu_cfg.file_based_part_size;
if (file_part >= 10)
itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 2, 10);
else
{
emu_cfg.emummc_file_based_path[strlen(emu_cfg.emummc_file_based_path) - 2] = '0';
itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10);
}
}
return emummc_storage_file_based_write(sector, num_sectors, buf);
// if (!emu_cfg.active_part)
// {
// u32 file_part = sector / emu_cfg.file_based_part_size;
// sector = sector % emu_cfg.file_based_part_size;
// if (file_part >= 10)
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 2, 10);
// else
// {
// emu_cfg.emummc_file_based_path[strlen(emu_cfg.emummc_file_based_path) - 2] = '0';
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10);
// }
// }
if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_WRITE))
return 0;
// if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_WRITE))
// return 0;
f_lseek(&fp, (u64)sector << 9);
if (f_write(&fp, buf, (u64)num_sectors << 9, NULL))
{
f_close(&fp);
return 0;
}
// f_lseek(&fp, (u64)sector << 9);
// if (f_write(&fp, buf, (u64)num_sectors << 9, NULL))
// {
// f_close(&fp);
// return 0;
// }
f_close(&fp);
return 1;
// f_close(&fp);
// return 1;
}
}
int emummc_storage_set_mmc_partition(u32 partition)
{
emu_cfg.active_part = partition;
emmc_set_partition(partition);
if (!emu_cfg.enabled || h_cfg.emummc_force_disable || emu_cfg.sector)
return 1;
else
{
strcpy(emu_cfg.emummc_file_based_path, emu_cfg.path);
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
switch (partition)
{
case 0:
strcat(emu_cfg.emummc_file_based_path, "/00");
break;
case 1:
strcat(emu_cfg.emummc_file_based_path, "/BOOT0");
break;
case 2:
strcat(emu_cfg.emummc_file_based_path, "/BOOT1");
break;
}
if(h_cfg.emummc_force_disable){
emmc_set_partition(partition);
return 1;
}
if(!emu_cfg.enabled){
return 1;
}
if(!emu_cfg.sector){
emummc_storage_file_base_set_partition(partition);
return 1;
}
if(emu_cfg.enabled != 4){
emmc_set_partition(partition);
}else{
emmc_set_partition(EMMC_GPP);
}
return 1;
}
sdmmc_storage_t *emummc_get_storage(){
return emu_cfg.enabled == 4 ? &emmc_storage : &sd_storage;
}

View File

@@ -55,5 +55,6 @@ int emummc_storage_end();
int emummc_storage_read(u32 sector, u32 num_sectors, void *buf);
int emummc_storage_write(u32 sector, u32 num_sectors, void *buf);
int emummc_storage_set_mmc_partition(u32 partition);
sdmmc_storage_t *emummc_get_storage();
#endif

View File

@@ -27,8 +27,8 @@ OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
start.o exception_handlers.o \
nyx.o heap.o \
gfx.o \
gui.o gui_info.o gui_tools.o gui_options.o gui_emmc_tools.o gui_emummc_tools.o gui_tools_partition_manager.o \
fe_emummc_tools.o fe_emmc_tools.o \
gui.o gui_info.o gui_tools.o gui_options.o gui_emmc_tools.o gui_emummc_tools.o gui_tools_partition_manager.o gui_emu_tools.o gui_emusd_tools.o \
fe_emummc_tools.o fe_emmc_tools.o fe_emusd_tools.o \
)
# Hardware.
@@ -41,7 +41,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
touch.o joycon.o tmp451.o fan.o \
usbd.o xusbd.o usb_descriptors.o usb_gadget_ums.o usb_gadget_hid.o \
hw_init.o \
hw_init.o boot_storage.o sfd.o mbr_gpt.o emummc_file_based.o \
)
# Utilities.

View File

@@ -21,6 +21,7 @@
#include "config.h"
#include <libs/fatfs/ff.h>
#include <storage/boot_storage.h>
extern hekate_config h_cfg;
extern nyx_config n_cfg;
@@ -187,9 +188,9 @@ int create_config_entry()
int create_nyx_config_entry(bool force_unmount)
{
bool sd_mounted = sd_get_card_mounted();
bool sd_mounted = boot_storage_get_mounted();
if (!sd_mount())
if (!boot_storage_mount())
return 1;
char lbuf[64];
@@ -247,7 +248,7 @@ int create_nyx_config_entry(bool force_unmount)
f_close(&fp);
if (force_unmount || !sd_mounted)
sd_unmount();
boot_storage_unmount();
return 0;
}

View File

@@ -18,6 +18,7 @@
//! fix the dram stuff and the pop ups
#include <storage/boot_storage.h>
#include <string.h>
#include <stdlib.h>
@@ -932,11 +933,11 @@ out:
free(txt_buf);
free(gui->base_path);
if (!partial_sd_full_unmount)
sd_unmount();
boot_storage_unmount();
else
{
partial_sd_full_unmount = false;
sd_end();
boot_storage_end();
}
}
@@ -1361,7 +1362,7 @@ multipart_not_allowed:
f_close(&fp_raw);
s_printf(sdPath, "emuMMC/RAW%d", part_idx);
save_emummc_cfg(part_idx, sector_start, sdPath);
save_emummc_cfg(part_idx, sector_start, sdPath, DRIVE_SD);
}
return 1;

File diff suppressed because it is too large Load Diff

View File

@@ -30,9 +30,9 @@ typedef struct _emummc_cfg_t
} emummc_cfg_t;
void load_emummc_cfg(emummc_cfg_t *emu_info);
void save_emummc_cfg(u32 part_idx, u32 sector_start, const char *path);
void dump_emummc_file(emmc_tool_gui_t *gui);
void dump_emummc_raw(emmc_tool_gui_t *gui, int part_idx, u32 sector_start, u32 resized_count);
void save_emummc_cfg(u32 part_idx, u32 sector_start, const char *path, u8 drive);
void dump_emummc_file(emmc_tool_gui_t *gui, u32 resized_cnt, u8 drive);
void dump_emummc_raw(emmc_tool_gui_t *gui, int part_idx, u32 sector_start, u32 resized_count, u8 drive);
void update_emummc_base_folder(char *outFilename, u32 sdPathLen, u32 currPartIdx);
#endif

View File

@@ -0,0 +1,123 @@
#include "fe_emusd_tools.h"
#include "../storage/sfd.h"
#include <sec/se.h>
#include <storage/boot_storage.h>
#include <libs/fatfs/ff.h>
#include <storage/emmc.h>
#include <storage/mbr_gpt.h>
#include <storage/sdmmc.h>
#include <utils/list.h>
#include <utils/ini.h>
#include <string.h>
#include <stdlib.h>
void load_emusd_cfg(emusd_cfg_t *emu_info){
memset(emu_info, 0, sizeof(emusd_cfg_t));
// Parse emuMMC configuration.
LIST_INIT(ini_sections);
if (!ini_parse(&ini_sections, "emuSD/emusd.ini", false))
return;
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
{
if (!strcmp(ini_sec->name, "emusd"))
{
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
if (!strcmp("enabled", kv->key))
emu_info->enabled = atoi(kv->val);
else if(!strcmp("sector", kv->key))
emu_info->sector = strtol(kv->val, NULL, 16);
/*else (!strcmp("id", kv->key))
emu_info->id = strtol(kv->val, NULL, 16);*/
}
break;
}
}
ini_free(&ini_sections);
}
void save_emusd_cfg(u32 part_idx, u32 sector_start){
boot_storage_mount();
char lbuf[16];
FIL fp;
f_mkdir("emuSD");
if (f_open(&fp, "emuSD/emusd.ini", FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
return;
// Add config entry.
f_puts("[emusd]\nenabled=", &fp);
if(sector_start){
f_puts("4", &fp);
}else{
f_puts("0", &fp);
}
if(!sector_start){
f_puts("\nsector=0x0", &fp);
}else{
f_puts("\nsector=0x", &fp);
itoa(sector_start, lbuf, 16);
f_puts(lbuf, &fp);
}
f_puts("\n", &fp);
f_close(&fp);
}
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name){
sfd_init(&emmc_storage, sector_start, sector_size);
u8 *buf = malloc(SZ_4M);
FIL f;
u32 cluster_size = 65536;
u32 mkfs_error = f_mkfs("sfd:", FM_FAT32 | FM_SFD, cluster_size, buf, SZ_4M);
while(mkfs_error != FR_OK && cluster_size > 4096){
cluster_size /= 2;
mkfs_error = f_mkfs("sfd:", FM_FAT32 | FM_SFD, cluster_size, buf, SZ_4M);
}
if(mkfs_error == FR_OK){
FATFS fs;
mkfs_error = f_mount(&fs, "sfd:", 1);
if(mkfs_error == FR_OK){
mkfs_error = f_open(&f, "sfd:.no_boot_storage", FA_CREATE_ALWAYS | FA_WRITE);
f_close(&f);
if(mkfs_error == FR_OK){
char label[0x30];
strcpy(label, "sfd:");
strcat(label, name);
mkfs_error = f_setlabel(label);
if(mkfs_error == FR_OK){
u8 random_number[16];
mbr_t mbr = {0};
se_gen_prng128(random_number);
memcpy(&mbr.signature, random_number, 4);
mbr.boot_signature = 0xaa55;
mbr.partitions[0].start_sct = sector_start - sector_mbr;
mbr.partitions[0].size_sct = sector_size;
mbr.partitions[0].type = 0x0c;
mkfs_error = sdmmc_storage_write(&emmc_storage, sector_mbr, 1, &mbr) ? FR_OK : FR_DISK_ERR;
}
}
}
f_mount(NULL, "sfd:", 0);
}
sfd_end();
return mkfs_error;
}

View File

@@ -0,0 +1,16 @@
#ifndef _FE_EMUSD_TOOLS_H_
#define _FE_EMUSD_TOOLS_H_
#include "gui.h"
typedef struct _emusd_cfg_t{
// 0: disabled, 1: enabled
int enabled;
u32 sector;
} emusd_cfg_t;
void load_emusd_cfg(emusd_cfg_t *emu_info);
void save_emusd_cfg(u32 part_idx, u32 sector_start);
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name);
#endif

View File

@@ -19,6 +19,7 @@
#include <bdk.h>
#include "gui.h"
#include "gui_emu_tools.h"
#include "gui_emummc_tools.h"
#include "gui_tools.h"
#include "gui_info.h"
@@ -29,6 +30,7 @@
#include "../config.h"
#include <libs/fatfs/ff.h>
#include <storage/boot_storage.h>
extern hekate_config h_cfg;
extern nyx_config n_cfg;
@@ -187,7 +189,7 @@ static void _save_log_to_bmp(char *fname)
char path[0x80];
strcpy(path, "bootloader/screenshots");
s_printf(path + strlen(path), "/nyx%s_log.bmp", fname);
sd_save_to_file(bitmap, file_size, path);
boot_storage_save_to_file(bitmap, file_size, path);
free(bitmap);
free(fb);
@@ -271,7 +273,7 @@ static void _save_fb_to_bmp()
bmp->res_v = 2834;
bmp->rsvd2 = 0;
sd_mount();
boot_storage_mount();
char path[0x80];
@@ -288,7 +290,7 @@ static void _save_fb_to_bmp()
s_printf(path + strlen(path), "/nyx%s.bmp", fname);
// Save screenshot and log.
int res = sd_save_to_file(bitmap, file_size, path);
int res = boot_storage_save_to_file(bitmap, file_size, path);
if (!res)
_save_log_to_bmp(fname);
@@ -651,7 +653,7 @@ void manual_system_maintenance(bool refresh)
lv_img_dsc_t *bmp_to_lvimg_obj(const char *path)
{
u32 fsize;
u8 *bitmap = sd_file_read(path, &fsize);
u8 *bitmap = boot_storage_file_read(path, &fsize);
if (!bitmap)
return NULL;
@@ -921,7 +923,9 @@ static void _launch_hos(u8 autoboot, u8 autoboot_list)
void (*main_ptr)() = (void *)nyx_str->hekate;
boot_storage_end();
sd_end();
emmc_end();
hw_deinit(false, 0);
@@ -937,6 +941,9 @@ void reload_nyx()
void (*main_ptr)() = (void *)nyx_str->hekate;
// TODO:
boot_storage_end();
emmc_end();
sd_end();
hw_deinit(false, 0);
@@ -981,7 +988,7 @@ static void _check_sd_card_removed(void *params)
// The following checks if SDMMC_1 is initialized.
// If yes and card was removed, shows a message box,
// that will reload Nyx, when the card is inserted again.
if (!do_reload && sd_get_card_removed())
if (!do_reload && sd_get_card_removed() && boot_storage_get_drive() == DRIVE_SD)
{
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
@@ -1003,7 +1010,7 @@ static void _check_sd_card_removed(void *params)
}
// If in reload state and card was inserted, reload nyx.
if (do_reload && !sd_get_card_removed())
if (do_reload && !sd_get_card_removed() && boot_storage_get_drive() == DRIVE_SD)
reload_nyx();
}
@@ -1387,8 +1394,9 @@ static lv_res_t _create_mbox_payloads(lv_obj_t *btn)
lv_obj_set_size(list, LV_HOR_RES * 3 / 7, LV_VER_RES * 3 / 7);
lv_list_set_single_mode(list, true);
if (!sd_mount())
if (!boot_storage_mount())
{
// TODO: may not be SD, change error
lv_mbox_set_text(mbox, "#FFDD00 Failed to init SD!#");
goto out_end;
@@ -1699,7 +1707,7 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
u32 curr_btn_idx = 0; // Active buttons.
LIST_INIT(ini_sections);
if (!sd_mount())
if (!boot_storage_mount())
goto failed_sd_mount;
// Check if we use custom system icons.
@@ -1895,7 +1903,7 @@ failed_sd_mount:
if (curr_btn_idx < 1)
no_boot_entries = true;
sd_unmount();
boot_storage_unmount();
free(tmp_path);
@@ -2026,7 +2034,7 @@ static void _create_tab_home(lv_theme_t *th, lv_obj_t *parent)
label_btn = lv_label_create(btn_emummc, label_btn);
s_printf(btn_colored_text, "%s%s", text_color, " "SYMBOL_LIST"#");
lv_label_set_text(label_btn, btn_colored_text);
lv_btn_set_action(btn_emummc, LV_BTN_ACTION_CLICK, create_win_emummc_tools);
lv_btn_set_action(btn_emummc, LV_BTN_ACTION_CLICK, create_win_emu_tools);
lv_btn_set_layout(btn_emummc, LV_LAYOUT_OFF);
lv_obj_align(label_btn, NULL, LV_ALIGN_CENTER, 0, -28);
lv_obj_set_pos(btn_emummc, 959, 160);
@@ -2058,7 +2066,7 @@ static lv_res_t _save_options_action(lv_obj_t *btn)
int res = 0;
if (sd_mount())
if (boot_storage_mount())
res = !create_config_entry();
if (res)
@@ -2070,7 +2078,7 @@ static lv_res_t _save_options_action(lv_obj_t *btn)
nyx_options_clear_ini_changes_made();
sd_unmount();
boot_storage_unmount();
return LV_RES_OK;
}

View File

@@ -0,0 +1,79 @@
#include "gui_emu_tools.h"
#include "gui.h"
#include "gui_emummc_tools.h"
#include "gui_emusd_tools.h"
#include <libs/lvgl/lv_core/lv_obj.h>
#include <libs/lvgl/lv_core/lv_style.h>
#include <libs/lvgl/lv_objx/lv_cont.h>
#include <libs/lvgl/lv_objx/lv_label.h>
#include <libs/lvgl/lv_objx/lv_line.h>
#include <libs/lvgl/lv_objx/lv_page.h>
#include <libs/lvgl/lv_objx/lv_tabview.h>
#include <libs/lvgl/lv_objx/lv_win.h>
#include <libs/lvgl/lv_themes/lv_theme.h>
#include <gfx_utils.h>
static lv_obj_t *_create_container(lv_obj_t *parent){
static lv_style_t h_style;
lv_style_copy(&h_style, &lv_style_transp);
h_style.body.padding.inner = 0;
h_style.body.padding.hor = 0;
h_style.body.padding.ver = 0;
lv_obj_t *h1 = lv_cont_create(parent, NULL);
lv_cont_set_style(h1, &h_style);
lv_cont_set_fit(h1, false, true);
lv_obj_set_width(h1, LV_HOR_RES - 62);
lv_obj_set_click(h1, false);
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
return h1;
}
lv_res_t create_win_emu_tools(lv_obj_t *btn){
lv_obj_t *win = nyx_create_standard_window(SYMBOL_EDIT " emuMMC Manage");
static lv_style_t win_style_no_pad;
lv_style_copy(&win_style_no_pad, lv_win_get_style(win, LV_WIN_STYLE_CONTENT_BG));
win_style_no_pad.body.padding.hor = 0;
win_style_no_pad.body.padding.inner = 0;
lv_win_set_style(win, LV_WIN_STYLE_CONTENT_BG, &win_style_no_pad);
lv_obj_t *tv = lv_tabview_create(win, NULL);
lv_obj_set_size(tv, LV_HOR_RES - 62, 572);
gfx_printf("w: %d\n",(u32)lv_obj_get_width(tv));
static lv_style_t tv_style;
lv_style_copy(&tv_style, lv_theme_get_current()->tabview.btn.rel);
tv_style.body.padding.ver = LV_DPI / 8;
tv_style.body.padding.hor = 0;
lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_REL, &tv_style);
if(hekate_bg){
lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_PR, &tabview_btn_pr);
lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_TGL_PR, &tabview_btn_tgl_pr);
}
lv_tabview_set_sliding(tv, false);
lv_tabview_set_btns_pos(tv, LV_TABVIEW_BTNS_POS_BOTTOM);
lv_obj_t *tab_emummc = lv_tabview_add_tab(tv, SYMBOL_CHIP " emuMMC");
lv_obj_t *tab_emusd = lv_tabview_add_tab(tv, SYMBOL_SD " emuSD");
lv_obj_t *line_sep = lv_line_create(tv, NULL);
static const lv_point_t line_pp[] = {{0,0}, {0, LV_DPI / 4}};
lv_line_set_points(line_sep, line_pp, 2);
lv_line_set_style(line_sep, lv_theme_get_current()->line.decor);
lv_obj_align(line_sep, tv, LV_ALIGN_IN_BOTTOM_MID, -1, -LV_DPI * 2 / 12);
create_tab_emummc_tools(_create_container(tab_emummc));
create_tab_emusd_tools(_create_container(tab_emusd));
lv_tabview_set_tab_act(tv, 0, false);
return LV_RES_OK;
}

View File

@@ -0,0 +1,8 @@
#ifndef _GUI_EMU_TOOLS_H_
#define _GUI_EMU_TOOLS_H_
#include <libs/lvgl/lvgl.h>
lv_res_t create_win_emu_tools(lv_obj_t *btn);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,6 @@
#include <libs/lvgl/lvgl.h>
lv_res_t create_win_emummc_tools(lv_obj_t *btn);
lv_res_t create_tab_emummc_tools(lv_obj_t *parent);
#endif

View File

@@ -0,0 +1,461 @@
#include "gui_emusd_tools.h"
#include "fe_emusd_tools.h"
#include "gui_tools_partition_manager.h"
#include "gui.h"
#include <libs/fatfs/ff.h>
#include <libs/lvgl/lv_core/lv_obj.h>
#include <libs/lvgl/lv_objx/lv_btnm.h>
#include <libs/lvgl/lv_objx/lv_list.h>
#include <libs/lvgl/lv_objx/lv_mbox.h>
#include <storage/boot_storage.h>
#include "fe_emusd_tools.h"
#include <stdlib.h>
#include <storage/emmc.h>
#include <storage/mbr_gpt.h>
#include <storage/sdmmc.h>
#include <string.h>
#include <utils/sprintf.h>
#include <mem/heap.h>
#include <utils/types.h>
#include <gfx_utils.h>
typedef struct _gpt_ctxt_t{
u32 sector[3];
u32 sector_mbr[3];
u32 part_idx[3];
u32 size[3];
char name[3][36];
u8 cnt;
u8 valid_parts[3];
u8 valid_cnt;
} gpt_ctxt_t;
static gpt_ctxt_t gpt_ctxt;
static lv_obj_t *emusd_parent_cont;
static lv_res_t (*emusd_tools)(lv_obj_t *parent);
static void _get_emusd_parts(gpt_t *gpt){
u8 cnt = 0;
s32 gpt_idx = gpt_get_part_by_name(gpt, "emusd_mbr", -1);
while(gpt_idx != -1 && cnt < 3){
u32 sector_mbr = gpt->entries[gpt_idx].lba_start;
gpt_idx = gpt_get_part_by_name(gpt, "emusd", gpt_idx);
if(gpt_idx == -1){
// should never happen
continue;
}
u32 sector = gpt->entries[gpt_idx].lba_start;
u32 size = gpt->entries[gpt_idx].lba_end - sector + 1;
gpt_ctxt.sector_mbr[cnt] = sector_mbr;
gpt_ctxt.sector[cnt] = sector;
gpt_ctxt.part_idx[cnt] = gpt_idx;
gpt_ctxt.size[cnt] = size;
wctombs(gpt->entries[gpt_idx].name, gpt_ctxt.name[cnt], 36);
cnt++;
gpt_idx = gpt_get_part_by_name(gpt, "emusd", gpt_idx);
}
gpt_ctxt.cnt = cnt;
}
static lv_res_t _close_mbox_and_reload(lv_obj_t *btns, const char *txt){
lv_obj_clean(emusd_parent_cont);
mbox_action(btns, txt);
(*emusd_tools)(emusd_parent_cont);
return LV_RES_INV;
}
static void _create_emusd(u8 idx){
boot_storage_mount();
emmc_initialize(false);
static const char *mbox_btn_map[] = { "\251", "\222OK", "\251", "" };
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
char *txt_buf = malloc(SZ_16K);
strcpy(txt_buf, "#FF8000 emuSD creation tool#\n\n"
"#00DDFF Status:# Formatting emuSD partition...");
lv_mbox_set_text(mbox, txt_buf);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_top(mbox, true);
manual_system_maintenance(true);
int res = create_emusd(gpt_ctxt.part_idx[idx], gpt_ctxt.sector_mbr[idx], gpt_ctxt.sector[idx], gpt_ctxt.size[idx], gpt_ctxt.name[idx]);
if(res == FR_OK){
strcpy(txt_buf, "#FF8000 emuSD creation tool#\n\n"
"#00DDFF Status:# Done!");
char path[0x80];
strcpy(path, "emuSD");
f_mkdir(path);
s_printf(path + strlen(path), "/RAW_EMMC%d", gpt_ctxt.part_idx[idx]);
f_mkdir(path);
strcat(path, "/raw_emmc_based");
FIL f;
f_open(&f, path, FA_CREATE_ALWAYS | FA_WRITE);
f_write(&f, &gpt_ctxt.sector_mbr[idx], 4, NULL);
f_close(&f);
save_emusd_cfg(gpt_ctxt.part_idx[idx], gpt_ctxt.sector_mbr[idx]);
}else{
strcpy(txt_buf, "#FF8000 emuSD creation tool#\n\n"
"#00DDFF Status:# Failed to format partition!");
}
lv_mbox_set_text(mbox, txt_buf);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_mbox_add_btns(mbox, mbox_btn_map, _close_mbox_and_reload);
manual_system_maintenance(true);
boot_storage_unmount();
emmc_end();
free(txt_buf);
}
static lv_res_t _emusd_create_action(lv_obj_t *btns, const char *txt){
u32 idx = lv_btnm_get_pressed(btns);
mbox_action(btns, txt);
if(idx < gpt_ctxt.cnt){
_create_emusd(idx);
}
return LV_RES_INV;
}
static lv_res_t _emusd_format_action(lv_obj_t *btns, const char *txt){
u32 idx = lv_btnm_get_pressed(btns);
mbox_action(btns, txt);
if(idx){
create_window_partition_manager(btns, DRIVE_EMMC);
}
return LV_RES_INV;
}
static void _change_emusd(u8 idx){
boot_storage_mount();
save_emusd_cfg(gpt_ctxt.part_idx[gpt_ctxt.valid_parts[idx]], gpt_ctxt.sector_mbr[gpt_ctxt.valid_parts[idx]]);
boot_storage_unmount();
}
static lv_res_t _emusd_change_action(lv_obj_t *btns, const char *txt){
u32 idx = lv_btnm_get_pressed(btns);
if(idx < gpt_ctxt.valid_cnt){
_change_emusd(idx);
_close_mbox_and_reload(btns, txt);
}else if(idx == gpt_ctxt.valid_cnt){
boot_storage_mount();
save_emusd_cfg(0, 0);
boot_storage_unmount();
_close_mbox_and_reload(btns, txt);
}else{
mbox_action(btns, txt);
}
return LV_RES_INV;
}
static lv_res_t _create_mbox_change_emusd(lv_obj_t *btn){
boot_storage_mount();
emmc_initialize(false);
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
static char mbox_part_strs[6][0x10];
static char *mbox_btn_parts[] = {mbox_part_strs[0], mbox_part_strs[1], mbox_part_strs[2], mbox_part_strs[3], mbox_part_strs[4], mbox_part_strs[5]};
dirlist_t *emusd_dir_list = dirlist("emuSD", NULL, false, true);
char path[0x80];
mbr_t mbr = {0};
gpt_t *gpt = NULL;
char *txt_buf = malloc(SZ_16K);
u32 emusd_idx = 0;
FIL f;
sdmmc_storage_read(&emmc_storage, 0, 1, &mbr);
if(!mbr_has_gpt(&mbr)){
goto out;
}
gpt = zalloc(sizeof(*gpt));
sdmmc_storage_read(&emmc_storage, 1, sizeof(*gpt) / 0x200, gpt);
_get_emusd_parts(gpt);
u8 cnt = 0;
while(emusd_dir_list && emusd_dir_list->name[emusd_idx]){
s_printf(path, "emuSD/%s/raw_emmc_based", emusd_dir_list->name[emusd_idx]);
if(f_stat(path, NULL) == FR_OK){
f_open(&f, path, FA_READ);
u32 sector = 0;
f_read(&f, &sector, 4, NULL);
f_close(&f);
for(u32 i = 0; i < gpt_ctxt.cnt ; i++){
if(sector == gpt_ctxt.sector_mbr[i]){
s_printf(mbox_btn_parts[cnt], "Part %d", gpt_ctxt.part_idx[i]);
gpt_ctxt.valid_parts[cnt] = i;
cnt++;
}
}
}
emusd_idx++;
}
gpt_ctxt.valid_cnt = cnt;
strcpy(mbox_btn_parts[cnt], "Disable");
strcpy(mbox_btn_parts[cnt + 1], "Cancel");
mbox_btn_parts[cnt + 2][0] = 0;
if(cnt){
strcpy(txt_buf, "#C7EA46 Found emuSD partition(s)!#\n"
"#FF8000 Choose a partition or disable emuSD.#\n\n");
for(u32 i = 0; i < cnt; i++){
s_printf(txt_buf + strlen(txt_buf), "Part %d (%s): Start: 0x%x, Size: 0x%x\n", gpt_ctxt.part_idx[gpt_ctxt.valid_parts[i]], gpt_ctxt.name[gpt_ctxt.valid_parts[i]], gpt_ctxt.sector[gpt_ctxt.valid_parts[i]], gpt_ctxt.size[gpt_ctxt.valid_parts[i]]);
}
}else{
strcpy(txt_buf, "#FF8000 No set up emuSD partitions found.\nFirst, create an emuSD\n#");
}
lv_mbox_set_text(mbox, txt_buf);
lv_mbox_add_btns(mbox, (const char **)mbox_btn_parts, _emusd_change_action);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
out:
free(gpt);
free(emusd_dir_list);
boot_storage_unmount();
emmc_end();
return LV_RES_OK;
}
static lv_res_t _create_mbox_emusd_create(lv_obj_t *btn){
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
static char mbox_part_strs[5][0x10];
static char *mbox_btn_parts[] = {mbox_part_strs[0], mbox_part_strs[1], mbox_part_strs[2], mbox_part_strs[3], mbox_part_strs[4]};
static const char *mbox_btn_format[] = {"\222Continue", "\222Cancel", ""};
char *txt_buf = (char*)malloc(SZ_16K);
emmc_initialize(false);
emmc_set_partition(EMMC_GPP);
gpt_t *gpt = NULL;
mbr_t mbr = {0};
u8 cnt = 0;
sdmmc_storage_read(&emmc_storage, 0, 1, &mbr);
if(mbr_has_gpt(&mbr)){
gpt = zalloc(sizeof(*gpt));
sdmmc_storage_read(&emmc_storage, 1, sizeof(*gpt) / 0x200, gpt);
_get_emusd_parts(gpt);
cnt = gpt_ctxt.cnt;
}
if(cnt){
s_printf(txt_buf,
"#C7EA46 Found applicable eMMC partition(s)!#\n"
"#FF8000 Choose a partition to continue:#\n\n");
for(u32 i = 0; i < cnt; i++){
char name[36];
u8 idx = gpt_ctxt.part_idx[i];
u32 size = gpt->entries[idx].lba_end - gpt->entries[idx].lba_start + 1;
wctombs(gpt->entries[idx].name, name, 36);
s_printf(txt_buf + strlen(txt_buf), "Part %d (%s): Start: 0x%x, Size: 0x%x\n", idx, name, gpt_ctxt.sector[i], size);
s_printf(mbox_btn_parts[i], "\222Part %d", gpt_ctxt.part_idx[i]);
}
s_printf(mbox_btn_parts[cnt], "\222Cancel");
mbox_btn_parts[cnt + 1][0] = '\0';
lv_mbox_add_btns(mbox, (const char **)mbox_btn_parts, _emusd_create_action);
}else{
s_printf(txt_buf, "#FFDD00 Failed to find applicable partition!#\n\n"
"#FF8000 Do you want to partition the eMMC?#\n"
"#FF8000 (You will be asked on how to proceed)#");
lv_mbox_add_btns(mbox, mbox_btn_format, _emusd_format_action);
}
lv_mbox_set_text(mbox, txt_buf);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
emmc_end();
free(txt_buf);
free(gpt);
return LV_RES_OK;
}
lv_res_t create_tab_emusd_tools(lv_obj_t *parent)
{
emusd_parent_cont = parent;
emusd_tools = &create_tab_emusd_tools;
boot_storage_mount();
emusd_cfg_t emu_info;
load_emusd_cfg(&emu_info);
boot_storage_unmount();
static lv_style_t h_style;
lv_style_copy(&h_style, &lv_style_transp);
h_style.body.padding.inner = 0;
h_style.body.padding.hor = LV_DPI - (LV_DPI / 4);
h_style.body.padding.ver = LV_DPI / 9;
// Create emuSD Info & Selection container.
lv_obj_t *h1 = lv_cont_create(parent, NULL);
lv_cont_set_style(h1, &h_style);
lv_cont_set_fit(h1, false, true);
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 4);
lv_obj_set_click(h1, false);
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
lv_obj_t *label_sep = lv_label_create(h1, NULL);
lv_label_set_static_text(label_sep, "");
lv_obj_t *label_txt = lv_label_create(h1, NULL);
lv_label_set_static_text(label_txt, "emuSD Info & Selection");
lv_obj_set_style(label_txt, lv_theme_get_current()->label.prim);
lv_obj_align(label_txt, h1, LV_ALIGN_IN_TOP_LEFT, LV_DPI / 4, -LV_DPI / 9);
lv_obj_t *line_sep = lv_line_create(h1, NULL);
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
lv_line_set_points(line_sep, line_pp, 2);
lv_line_set_style(line_sep, lv_theme_get_current()->line.decor);
lv_obj_align(line_sep, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
// Create emuSD info labels.
lv_obj_t *label_btn = lv_label_create(h1, NULL);
lv_label_set_recolor(label_btn, true);
lv_label_set_static_text(label_btn, emu_info.enabled ? "#96FF00 "SYMBOL_OK" Enabled!#" : "#FF8000 "SYMBOL_CLOSE" Disabled!#");
lv_obj_align(label_btn, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
lv_obj_t *label_txt2 = lv_label_create(h1, NULL);
lv_label_set_recolor(label_txt2, true);
char *txt_buf = (char *)malloc(SZ_16K);
if (emu_info.enabled)
{
s_printf(txt_buf, "#00DDFF Type:# eMMC Raw Partition\n#00DDFF Sector:# 0x%08X",
emu_info.sector);
lv_label_set_text(label_txt2, txt_buf);
}
else
{
lv_label_set_static_text(label_txt2, "emuSD is disabled and SD will be used for boot.\n\n");
}
free(txt_buf);
lv_obj_set_style(label_txt2, &hint_small_style);
lv_obj_align(label_txt2, label_btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
// Create Change emuMMC button.
lv_obj_t *btn2 = lv_btn_create(h1, NULL);
lv_btn_set_fit(btn2, true, true);
label_btn = lv_label_create(btn2, NULL);
lv_label_set_static_text(label_btn, SYMBOL_SETTINGS" Change emuSD");
lv_obj_align(btn2, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI * 6 / 10);
lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, _create_mbox_change_emusd);
label_txt2 = lv_label_create(h1, NULL);
lv_label_set_recolor(label_txt2, true);
lv_label_set_static_text(label_txt2,
"Choose an emuSD partition\n"
"You can at most have 3 emuSD partitions.");
lv_obj_set_style(label_txt2, &hint_small_style);
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
// Create emuMMC Tools container.
lv_obj_t *h2 = lv_cont_create(parent, NULL);
lv_cont_set_style(h2, &h_style);
lv_cont_set_fit(h2, false, true);
lv_obj_set_width(h2, (LV_HOR_RES / 9) * 4);
lv_obj_set_click(h2, false);
lv_cont_set_layout(h2, LV_LAYOUT_OFF);
lv_obj_align(h2, h1, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI * 17 / 29, 0);
label_sep = lv_label_create(h2, NULL);
lv_label_set_static_text(label_sep, "");
lv_obj_t *label_txt3 = lv_label_create(h2, NULL);
lv_label_set_static_text(label_txt3, "emuSD Tools");
lv_obj_set_style(label_txt3, lv_theme_get_current()->label.prim);
lv_obj_align(label_txt3, h2, LV_ALIGN_IN_TOP_LEFT, LV_DPI / 4, 0);
line_sep = lv_line_create(h2, line_sep);
lv_obj_align(line_sep, label_txt3, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
// Create Create emuMMC button.
lv_obj_t *btn3 = lv_btn_create(h2, btn2);
label_btn = lv_label_create(btn3, NULL);
lv_btn_set_fit(btn3, true, true);
lv_label_set_static_text(label_btn, SYMBOL_DRIVE" Create emuSD");
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_emusd_create);
lv_obj_t *label_txt4 = lv_label_create(h2, NULL);
lv_label_set_recolor(label_txt4, true);
lv_label_set_static_text(label_txt4,
"Allows you to create a new emuSD on a suitable #C7EA46 eMMC# partition");
lv_obj_set_style(label_txt4, &hint_small_style);
lv_obj_align(label_txt4, btn3, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
lv_obj_align(h1, parent, LV_ALIGN_IN_TOP_LEFT, 0, 0);
lv_obj_align(h2, h1, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI * 17 / 29, 0);
return LV_RES_OK;
}

View File

@@ -0,0 +1,8 @@
#ifndef _GUI_EMUSD_TOOLS_H_
#define _GUI_EMUSD_TOOLS_H_
#include <libs/lvgl/lvgl.h>
lv_res_t create_tab_emusd_tools(lv_obj_t *parent);
#endif

View File

@@ -23,6 +23,7 @@
#include "../hos/hos.h"
#include "../hos/pkg1.h"
#include <libs/fatfs/ff.h>
#include <storage/boot_storage.h>
#define SECTORS_TO_MIB_COEFF 11
@@ -72,15 +73,15 @@ static lv_res_t _cal0_dump_window_action(lv_obj_t *btns, const char * txt)
if (btn_idx == 1)
{
int error = !sd_mount();
int error = !boot_storage_mount();
if (!error)
{
char path[64];
emmcsn_path_impl(path, "/dumps", "cal0.bin", NULL);
error = sd_save_to_file((u8 *)cal0_buf, SZ_32K, path);
error = boot_storage_save_to_file((u8 *)cal0_buf, SZ_32K, path);
sd_unmount();
boot_storage_unmount();
}
_create_window_dump_done(error, "cal0.bin");
@@ -92,7 +93,7 @@ static lv_res_t _cal0_dump_window_action(lv_obj_t *btns, const char * txt)
static lv_res_t _battery_dump_window_action(lv_obj_t * btn)
{
int error = !sd_mount();
int error = !boot_storage_mount();
if (!error)
{
@@ -102,9 +103,9 @@ static lv_res_t _battery_dump_window_action(lv_obj_t * btn)
max17050_dump_regs(buf);
emmcsn_path_impl(path, "/dumps", "fuel_gauge.bin", NULL);
error = sd_save_to_file((u8 *)buf, 0x200, path);
error = boot_storage_save_to_file((u8 *)buf, 0x200, path);
sd_unmount();
boot_storage_unmount();
}
_create_window_dump_done(error, "fuel_gauge.bin");
@@ -116,7 +117,7 @@ static lv_res_t _bootrom_dump_window_action(lv_obj_t * btn)
{
static const u32 BOOTROM_SIZE = 0x18000;
int error = !sd_mount();
int error = !boot_storage_mount();
if (!error)
{
char path[64];
@@ -126,13 +127,13 @@ static lv_res_t _bootrom_dump_window_action(lv_obj_t * btn)
if (!error)
{
emmcsn_path_impl(path, "/dumps", "evp_thunks.bin", NULL);
error = sd_save_to_file((u8 *)iram_evp_thunks, iram_evp_thunks_len, path);
error = boot_storage_save_to_file((u8 *)iram_evp_thunks, iram_evp_thunks_len, path);
}
else
error = 255;
emmcsn_path_impl(path, "/dumps", "bootrom_patched.bin", NULL);
int res = sd_save_to_file((u8 *)IROM_BASE, BOOTROM_SIZE, path);
int res = boot_storage_save_to_file((u8 *)IROM_BASE, BOOTROM_SIZE, path);
if (!error)
error = res;
@@ -141,13 +142,13 @@ static lv_res_t _bootrom_dump_window_action(lv_obj_t * btn)
memset((void*)IPATCH_BASE, 0, sizeof(ipatch_cam)); // Zeroing valid entries is enough but zero everything.
emmcsn_path_impl(path, "/dumps", "bootrom_unpatched.bin", NULL);
res = sd_save_to_file((u8 *)IROM_BASE, BOOTROM_SIZE, path);
res = boot_storage_save_to_file((u8 *)IROM_BASE, BOOTROM_SIZE, path);
if (!error)
error = res;
memcpy((void*)IPATCH_BASE, ipatch_cam, sizeof(ipatch_cam));
sd_unmount();
boot_storage_unmount();
}
_create_window_dump_done(error, "evp_thunks.bin, bootrom_patched.bin, bootrom_unpatched.bin");
@@ -158,22 +159,22 @@ static lv_res_t _fuse_dump_window_action(lv_obj_t * btn)
{
const u32 fuse_array_size = (h_cfg.t210b01 ? FUSE_ARRAY_WORDS_NUM_B01 : FUSE_ARRAY_WORDS_NUM) * sizeof(u32);
int error = !sd_mount();
int error = !boot_storage_mount();
if (!error)
{
char path[128];
if (!h_cfg.t210b01)
{
emmcsn_path_impl(path, "/dumps", "fuse_cached_t210.bin", NULL);
error = sd_save_to_file((u8 *)0x7000F900, 0x300, path);
error = boot_storage_save_to_file((u8 *)0x7000F900, 0x300, path);
}
else
{
emmcsn_path_impl(path, "/dumps", "fuse_cached_t210b01_x898.bin", NULL);
error = sd_save_to_file((u8 *)0x7000F898, 0x68, path);
error = boot_storage_save_to_file((u8 *)0x7000F898, 0x68, path);
emmcsn_path_impl(path, "/dumps", "fuse_cached_t210b01_x900.bin", NULL);
if (!error)
error = sd_save_to_file((u8 *)0x7000F900, 0x300, path);
error = boot_storage_save_to_file((u8 *)0x7000F900, 0x300, path);
}
u32 words[FUSE_ARRAY_WORDS_NUM_B01];
@@ -182,11 +183,11 @@ static lv_res_t _fuse_dump_window_action(lv_obj_t * btn)
emmcsn_path_impl(path, "/dumps", "fuse_array_raw_t210.bin", NULL);
else
emmcsn_path_impl(path, "/dumps", "fuse_array_raw_t210b01.bin", NULL);
int res = sd_save_to_file((u8 *)words, fuse_array_size, path);
int res = boot_storage_save_to_file((u8 *)words, fuse_array_size, path);
if (!error)
error = res;
sd_unmount();
boot_storage_unmount();
}
if (!h_cfg.t210b01)
@@ -203,15 +204,15 @@ static lv_res_t _kfuse_dump_window_action(lv_obj_t * btn)
int error = !kfuse_read(buf);
if (!error)
error = !sd_mount();
error = !boot_storage_mount();
if (!error)
{
char path[64];
emmcsn_path_impl(path, "/dumps", "kfuses.bin", NULL);
error = sd_save_to_file((u8 *)buf, KFUSE_NUM_WORDS * 4, path);
error = boot_storage_save_to_file((u8 *)buf, KFUSE_NUM_WORDS * 4, path);
sd_unmount();
boot_storage_unmount();
}
_create_window_dump_done(error, "kfuses.bin");
@@ -241,7 +242,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
lv_label_set_style(lb_desc, &monospace_text);
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 4);
sd_mount();
boot_storage_mount();
// Dump CAL0.
int cal0_res = hos_dump_cal0();
@@ -341,7 +342,7 @@ static lv_res_t _create_mbox_cal0(lv_obj_t *btn)
out:
free(txt_buf);
sd_unmount();
boot_storage_unmount();
lv_mbox_add_btns(mbox, mbox_btn_map, _cal0_dump_window_action);
@@ -2432,7 +2433,7 @@ static bool _lockpick_exists_check()
bool found = false;
void *buf = malloc(0x200);
if (sd_mount())
if (boot_storage_mount())
{
FIL fp;
if (f_open(&fp, "bootloader/payloads/Lockpick_RCM.bin", FA_READ))
@@ -2457,7 +2458,7 @@ static bool _lockpick_exists_check()
out:
free(buf);
sd_unmount();
boot_storage_unmount();
return found;
}

View File

@@ -23,6 +23,7 @@
#include "../config.h"
#include <libs/lvgl/lv_themes/lv_theme_hekate.h>
#include <libs/lvgl/lvgl.h>
#include <storage/boot_storage.h>
#define CLOCK_MIN_YEAR 2024
#define CLOCK_MAX_YEAR (CLOCK_MIN_YEAR + 10)
@@ -227,7 +228,7 @@ static void _create_autoboot_window()
lv_obj_set_size(list_main, LV_HOR_RES * 4 / 10, LV_VER_RES * 4 / 7);
lv_list_set_single_mode(list_main, true);
sd_mount();
boot_storage_mount();
// Parse hekate main configuration.
LIST_INIT(ini_sections);
@@ -288,7 +289,7 @@ static void _create_autoboot_window()
ini_free(&ini_list_sections);
}
sd_unmount();
boot_storage_unmount();
}
static lv_res_t _autoboot_hide_delay_action(lv_obj_t *btn)
@@ -882,7 +883,7 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
jc_pad->bt_conn_r.type = is_r_hos ? jc_pad->bt_conn_r.type : 0;
save_data:
error = !sd_mount() ? 5 : 0;
error = !boot_storage_mount() ? 5 : 0;
if (!error)
{
@@ -896,7 +897,8 @@ save_data:
memcpy(data, &jc_pad->bt_conn_l, sizeof(jc_bt_conn_t));
memcpy(data + sizeof(jc_bt_conn_t), &jc_pad->bt_conn_r, sizeof(jc_bt_conn_t));
error = sd_save_to_file((u8 *)data, sizeof(jc_bt_conn_t) * 2, "switchroot/joycon_mac.bin") ? 4 : 0;
// TODO: JC dump should probably go to sd?
error = boot_storage_save_to_file((u8 *)data, sizeof(jc_bt_conn_t) * 2, "switchroot/joycon_mac.bin") ? 4 : 0;
// Save readable dump.
jc_bt_conn_t *bt = &jc_pad->bt_conn_l;
@@ -1024,7 +1026,7 @@ save_data:
}
}
sd_unmount();
boot_storage_unmount();
}
disabled_or_cal0_issue:;

View File

@@ -15,10 +15,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <fatfs_cfg.h>
#include <libs/lvgl/lv_core/lv_obj.h>
#include <libs/lvgl/lv_objx/lv_btn.h>
#include <libs/lvgl/lv_objx/lv_label.h>
#include <stdlib.h>
#include <bdk.h>
#include "../frontend/fe_emusd_tools.h"
#include "gui.h"
#include "gui_tools.h"
#include "gui_tools_partition_manager.h"
@@ -29,6 +34,15 @@
#include "../hos/pkg2.h"
#include "../hos/hos.h"
#include <libs/fatfs/ff.h>
#include <storage/boot_storage.h>
#include <storage/emmc.h>
#include <storage/emummc_file_based.h>
#include <storage/mbr_gpt.h>
#include <storage/sd.h>
#include <storage/sdmmc.h>
#include <string.h>
#include <usb/usbd.h>
#include <utils/types.h>
extern volatile boot_cfg_t *b_cfg;
extern hekate_config h_cfg;
@@ -218,7 +232,7 @@ static lv_res_t _create_mbox_hid(usb_ctxt_t *usbs)
return LV_RES_OK;
}
static lv_res_t _create_mbox_ums(usb_ctxt_t *usbs)
static lv_res_t _create_mbox_ums(usb_ctxt_t *usbs, u32 part)
{
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
@@ -233,38 +247,41 @@ static lv_res_t _create_mbox_ums(usb_ctxt_t *usbs)
s_printf(txt_buf, "#FF8000 USB Mass Storage#\n\n#C7EA46 Device:# ");
if (usbs->type == MMC_SD)
{
switch (usbs->partition)
{
case 0:
strcat(txt_buf, "SD Card");
break;
case EMMC_GPP + 1:
strcat(txt_buf, "emuMMC GPP");
break;
case EMMC_BOOT0 + 1:
strcat(txt_buf, "emuMMC BOOT0");
break;
case EMMC_BOOT1 + 1:
strcat(txt_buf, "emuMMC BOOT1");
break;
}
}
else
{
switch (usbs->partition)
{
case EMMC_GPP + 1:
strcat(txt_buf, "eMMC GPP");
break;
case EMMC_BOOT0 + 1:
switch(part){
case NYX_UMS_EMMC_BOOT0:
strcat(txt_buf, "eMMC BOOT0");
break;
case EMMC_BOOT1 + 1:
case NYX_UMS_EMMC_BOOT1:
strcat(txt_buf, "eMMC BOOT1");
break;
}
case NYX_UMS_EMMC_GPP:
strcat(txt_buf, "eMMC GPP");
break;
case NYX_UMS_EMUMMC_GPP:
strcat(txt_buf, "emuMMC GPP");
break;
case NYX_UMS_EMUMMC_BOOT0:
strcat(txt_buf, "emuMMC BOOT0");
break;
case NYX_UMS_EMUMMC_BOOT1:
strcat(txt_buf, "emuMMC BOOT1");
break;
case NYX_UMS_SD_CARD:
strcat(txt_buf, "SD Card");
break;
case NYX_UMS_BOOT_STRG_GPP:
strcat(txt_buf, "Boot drive (eMMC GPP)");
break;
case NYX_UMS_BOOT_STRG_BOOT1:
case NYX_UMS_BOOT_STRG_BOOT1_1MB:
strcat(txt_buf, "Boot drive (eMMC BOOT1)");
break;
case NYX_UMS_BOOT_STRG_SD:
strcat(txt_buf, "Boot drive (SD Card)");
break;
case NYX_UMS_EMUSD:
strcat(txt_buf, "emuSD");
break;
}
lv_mbox_set_text(mbox, txt_buf);
@@ -326,6 +343,13 @@ static lv_res_t _create_mbox_ums_error(int error)
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
// 1: boot storage fail
// 2: no emu active
// 3: emmc fail
// 4: sd fail
// 5: file based
static const char *mbox_btn_map[] = { "\251", "\222OK", "\251", "" };
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
@@ -333,14 +357,29 @@ static lv_res_t _create_mbox_ums_error(int error)
switch (error)
{
case 1:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Error mounting SD Card!#");
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Error mounting boot drive!#");
break;
case 2:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 No emuMMC found active!#");
break;
case 3:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize eMMC!#");
break;
case 4:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize SD Card!#");
break;
case 5:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Active emuMMC is not partition based!#");
break;
case 6:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Corrupt emuMMC partition!#");
break;
case 7:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 No emuSD found active!#");
break;
case 8:
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize file based emuMMC!#");
break;
}
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
@@ -417,216 +456,317 @@ lv_res_t action_ums_sd(lv_obj_t *btn)
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
_create_mbox_ums(&usbs);
_create_mbox_ums(&usbs, NYX_UMS_SD_CARD);
return LV_RES_OK;
}
static lv_res_t _action_ums_boot_storage(lv_obj_t *btn){
if(!nyx_emmc_check_battery_enough()){
return LV_RES_OK;
}
boot_storage_mount();
u8 drive = boot_storage_get_drive();
u32 part;
usb_ctxt_t usbs;
usbs.type = drive == DRIVE_SD ? MMC_SD : MMC_EMMC;
switch(drive){
case DRIVE_EMMC:
part = NYX_UMS_BOOT_STRG_GPP;
usbs.partition = EMMC_GPP + 1;
break;
case DRIVE_BOOT1:
part = NYX_UMS_BOOT_STRG_BOOT1;
usbs.partition = EMMC_BOOT1 + 1;
break;
case DRIVE_BOOT1_1MB:
part = NYX_UMS_BOOT_STRG_BOOT1_1MB;
usbs.partition = EMMC_BOOT1 + 1;
break;
case DRIVE_SD:
part = NYX_UMS_BOOT_STRG_SD;
usbs.partition = 0;
break;
default:
boot_storage_unmount();
return LV_RES_OK;
}
usbs.offset = drive == DRIVE_BOOT1_1MB ? (0x100000 / 0x200) : 0;
usbs.sectors = 0;
usbs.ro = false;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
_create_mbox_ums(&usbs, part);
boot_storage_unmount();
return LV_RES_OK;
}
static lv_res_t _ums_emmc(u32 part){
if (!nyx_emmc_check_battery_enough())
return LV_RES_OK;
usb_ctxt_t usbs;
usbs.type = MMC_EMMC;
switch(part){
case NYX_UMS_EMMC_BOOT0:
usbs.partition = EMMC_BOOT0 + 1;
break;
case NYX_UMS_EMMC_BOOT1:
usbs.partition = EMMC_BOOT1 + 1;
break;
case NYX_UMS_EMMC_GPP:
usbs.partition = EMMC_GPP + 1;
break;
}
usbs.offset = 0;
usbs.sectors = 0;
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
return _create_mbox_ums(&usbs, part);
}
static lv_res_t _action_ums_emmc_boot0(lv_obj_t *btn)
{
if (!nyx_emmc_check_battery_enough())
return LV_RES_OK;
usb_ctxt_t usbs;
usbs.type = MMC_EMMC;
usbs.partition = EMMC_BOOT0 + 1;
usbs.offset = 0;
usbs.sectors = 0;
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
_create_mbox_ums(&usbs);
return LV_RES_OK;
return _ums_emmc(NYX_UMS_EMMC_BOOT0);
}
static lv_res_t _action_ums_emmc_boot1(lv_obj_t *btn)
{
if (!nyx_emmc_check_battery_enough())
return _ums_emmc(NYX_UMS_EMMC_BOOT1);
}
lv_res_t action_ums_emmc_gpp(lv_obj_t *btn)
{
return _ums_emmc(NYX_UMS_EMMC_GPP);
}
static lv_res_t _action_ums_emusd(lv_obj_t * btn){
if(!nyx_emmc_check_battery_enough()){
return LV_RES_OK;
}
usb_ctxt_t usbs;
usbs.type = MMC_EMMC;
usbs.partition = EMMC_BOOT1 + 1;
usbs.offset = 0;
usbs.sectors = 0;
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
emusd_cfg_t emu_info;
_create_mbox_ums(&usbs);
int error = !boot_storage_mount();
if(!error){
load_emusd_cfg(&emu_info);
if(emu_info.enabled){
if(!emmc_initialize(false)){
error = 3;
}else{
mbr_t mbr = {0};
if(sdmmc_storage_read(&emmc_storage, emu_info.sector, 1, &mbr)){
error = 0;
usbs.offset = emu_info.sector;
usbs.sectors = mbr.partitions[0].size_sct;
usbs.type = MMC_EMMC;
usbs.partition = EMMC_GPP + 1;
usbs.ro = false;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
}else{
error = 3;
}
}
}else{
error = 7;
}
}
if(error){
_create_mbox_ums_error(error);
}else{
_create_mbox_ums(&usbs, NYX_UMS_EMUSD);
}
boot_storage_unmount();
return LV_RES_OK;
}
static lv_res_t _action_ums_emmc_gpp(lv_obj_t *btn)
{
static lv_res_t _ums_emummc(u32 part){
if (!nyx_emmc_check_battery_enough())
return LV_RES_OK;
usb_ctxt_t usbs;
usbs.type = MMC_EMMC;
usbs.partition = EMMC_GPP + 1;
usbs.offset = 0;
usbs.sectors = 0;
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
sdmmc_storage_t *storage;
emummc_cfg_t emu_info;
_create_mbox_ums(&usbs);
int error = !boot_storage_mount();
bool file_based = false;
char path[0x80];
if(!error){
load_emummc_cfg(&emu_info);
if(emu_info.enabled){
error = 0;
if(emu_info.enabled == 4 && emu_info.sector){
// emmc raw based
if(!emmc_initialize(false)){
error = 3;
}
storage = &emmc_storage;
}else if(emu_info.enabled == 1 && emu_info.sector){
// sd raw based
if(!sd_initialize(false)){
error = 4;
}
storage = &sd_storage;
}else if((emu_info.enabled == 1 || emu_info.enabled == 4) && !emu_info.sector){
// sd file based
if(emu_info.enabled == 1){
if(!sd_mount()){
error = 4;
}
}else{
if(!emmc_mount()){
error = 3;
}
}
if(error == 0){
file_based = true;
if(emu_info.enabled == 1){
strcpy(path, "sd:");
}else{
strcpy(path, "emmc:");
}
strcat(path, emu_info.path);
strcat(path, "/eMMC/");
if(!emummc_storage_file_based_init(path)){
error = 8;
}else{
switch(part){
case NYX_UMS_EMUMMC_BOOT0:
emummc_storage_file_base_set_partition(1);
break;
case NYX_UMS_EMUMMC_BOOT1:
emummc_storage_file_base_set_partition(2);
break;
case NYX_UMS_EMUMMC_GPP:
emummc_storage_file_base_set_partition(0);
break;
}
}
}
}else{
error = 2;
}
}else{
error = 2;
}
if(error == 0 && emu_info.enabled){
error = 6;
if(file_based){
usbs.offset = 0;
}else{
usbs.offset = emu_info.sector;
switch(part){
case NYX_UMS_EMUMMC_BOOT0:
usbs.offset += 0;
break;
case NYX_UMS_EMUMMC_BOOT1:
usbs.offset += 0x2000;
break;
case NYX_UMS_EMUMMC_GPP:
usbs.offset += 0x4000;
break;
}
}
if(part == NYX_UMS_EMUMMC_GPP){
if(file_based){
error = 8;
u32 sz = emummc_storage_file_based_get_total_gpp_size(path);
if(sz){
error = 0;
}
usbs.sectors = sz;
}else{
int res;
gpt_header_t *gpt_hdr = malloc(sizeof(*gpt_hdr));
res = sdmmc_storage_read(storage, usbs.offset + 1, 1, gpt_hdr);
if(res){
if(!memcmp(&gpt_hdr->signature, "EFI PART", 8)){
error = 0;
usbs.sectors = gpt_hdr->alt_lba + 1;
}
}
free(gpt_hdr);
}
}else{
error = 0;
usbs.sectors = 0x2000;
}
}
if(emu_info.path){
free(emu_info.path);
}
if(emu_info.nintendo_path){
free(emu_info.nintendo_path);
}
}
if(error){
_create_mbox_ums_error(error);
}else{
if(file_based){
usbs.type = emu_info.enabled == 4 ? MMC_EMUMMC_FILE_EMMC : MMC_EMUMMC_FILE;
}else{
usbs.type = emu_info.enabled == 4 ? MMC_EMUMMC_RAW_EMMC : MMC_EMUMMC_RAW_SD;
}
switch(part){
case NYX_UMS_EMUMMC_BOOT0:
usbs.partition = EMMC_GPP + 1;
break;
case NYX_UMS_EMUMMC_BOOT1:
usbs.partition = EMMC_BOOT1 + 1;
break;
case NYX_UMS_EMUMMC_GPP:
usbs.partition = EMMC_BOOT0 + 1;
break;
}
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
_create_mbox_ums(&usbs, part);
}
emummc_storage_file_based_end();
boot_storage_unmount();
return LV_RES_OK;
}
static lv_res_t _action_ums_emuemmc_boot0(lv_obj_t *btn)
{
if (!nyx_emmc_check_battery_enough())
return LV_RES_OK;
usb_ctxt_t usbs;
int error = !sd_mount();
if (!error)
{
emummc_cfg_t emu_info;
load_emummc_cfg(&emu_info);
error = 2;
if (emu_info.enabled)
{
error = 3;
if (emu_info.sector)
{
error = 0;
usbs.offset = emu_info.sector;
}
}
if (emu_info.path)
free(emu_info.path);
if (emu_info.nintendo_path)
free(emu_info.nintendo_path);
}
sd_unmount();
if (error)
_create_mbox_ums_error(error);
else
{
usbs.type = MMC_SD;
usbs.partition = EMMC_BOOT0 + 1;
usbs.sectors = 0x2000; // Forced 4MB.
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
_create_mbox_ums(&usbs);
}
return LV_RES_OK;
return _ums_emummc(NYX_UMS_EMUMMC_BOOT0);
}
static lv_res_t _action_ums_emuemmc_boot1(lv_obj_t *btn)
{
if (!nyx_emmc_check_battery_enough())
return LV_RES_OK;
usb_ctxt_t usbs;
int error = !sd_mount();
if (!error)
{
emummc_cfg_t emu_info;
load_emummc_cfg(&emu_info);
error = 2;
if (emu_info.enabled)
{
error = 3;
if (emu_info.sector)
{
error = 0;
usbs.offset = emu_info.sector + 0x2000;
}
}
if (emu_info.path)
free(emu_info.path);
if (emu_info.nintendo_path)
free(emu_info.nintendo_path);
}
sd_unmount();
if (error)
_create_mbox_ums_error(error);
else
{
usbs.type = MMC_SD;
usbs.partition = EMMC_BOOT1 + 1;
usbs.sectors = 0x2000; // Forced 4MB.
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
_create_mbox_ums(&usbs);
}
return LV_RES_OK;
return _ums_emummc(NYX_UMS_EMUMMC_BOOT1);
}
static lv_res_t _action_ums_emuemmc_gpp(lv_obj_t *btn)
{
if (!nyx_emmc_check_battery_enough())
return LV_RES_OK;
usb_ctxt_t usbs;
int error = !sd_mount();
if (!error)
{
emummc_cfg_t emu_info;
load_emummc_cfg(&emu_info);
error = 2;
if (emu_info.enabled)
{
error = 3;
if (emu_info.sector)
{
error = 1;
usbs.offset = emu_info.sector + 0x4000;
u8 *gpt = malloc(SD_BLOCKSIZE);
if (sdmmc_storage_read(&sd_storage, usbs.offset + 1, 1, gpt))
{
if (!memcmp(gpt, "EFI PART", 8))
{
error = 0;
usbs.sectors = *(u32 *)(gpt + 0x20) + 1; // Backup LBA + 1.
}
}
}
}
if (emu_info.path)
free(emu_info.path);
if (emu_info.nintendo_path)
free(emu_info.nintendo_path);
}
sd_unmount();
if (error)
_create_mbox_ums_error(error);
else
{
usbs.type = MMC_SD;
usbs.partition = EMMC_GPP + 1;
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
_create_mbox_ums(&usbs);
}
return LV_RES_OK;
return _ums_emummc(NYX_UMS_EMUMMC_GPP);
}
void nyx_run_ums(void *param)
@@ -651,7 +791,7 @@ void nyx_run_ums(void *param)
_action_ums_emmc_boot1(NULL);
break;
case NYX_UMS_EMMC_GPP:
_action_ums_emmc_gpp(NULL);
action_ums_emmc_gpp(NULL);
break;
case NYX_UMS_EMUMMC_BOOT0:
_action_ums_emuemmc_boot0(NULL);
@@ -718,18 +858,40 @@ static lv_res_t _create_window_usb_tools(lv_obj_t *parent)
lv_obj_t *label_txt2 = lv_label_create(h1, NULL);
lv_label_set_recolor(label_txt2, true);
lv_label_set_static_text(label_txt2,
"Allows you to mount the SD Card to a PC/Phone.\n"
"Allows you to mount the SD Card or boot drive to a PC/Phone.\n"
"#C7EA46 All operating systems are supported. Access is# #FF8000 Read/Write.#");
lv_obj_set_style(label_txt2, &hint_small_style);
lv_obj_align(label_txt2, btn1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
// Create emuSD button
lv_obj_t *btn_emusd = lv_btn_create(h1, btn1);
label_btn = lv_label_create(btn_emusd, NULL);
lv_label_set_text(label_btn, SYMBOL_MODULES_ALT " emuSD");
lv_obj_align(btn_emusd, btn1, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 10, 0);
lv_btn_set_action(btn_emusd, LV_BTN_ACTION_CLICK, _action_ums_emusd);
// Create Boot Storage UMS button
lv_obj_t *btn_boot_strg = lv_btn_create(h1, btn1);
label_btn = lv_label_create(btn_boot_strg, NULL);
lv_label_set_text(label_btn, boot_storage_get_drive() == DRIVE_SD ? SYMBOL_SD " Boot Drive" : SYMBOL_CHIP " Boot Drive");
lv_obj_align(btn_boot_strg, btn_emusd, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 10, 0);
lv_btn_set_action(btn_boot_strg, LV_BTN_ACTION_CLICK, _action_ums_boot_storage);
if(!boot_storage_mount()){
lv_obj_set_click(btn_boot_strg, false);
lv_btn_set_state(btn_boot_strg, LV_BTN_STATE_INA);
}
boot_storage_unmount();
// Create RAW GPP button.
lv_obj_t *btn_gpp = lv_btn_create(h1, btn1);
label_btn = lv_label_create(btn_gpp, NULL);
lv_label_set_static_text(label_btn, SYMBOL_CHIP" eMMC RAW GPP");
lv_obj_align(btn_gpp, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
lv_btn_set_action(btn_gpp, LV_BTN_ACTION_CLICK, _action_ums_emmc_gpp);
lv_btn_set_action(btn_gpp, LV_BTN_ACTION_CLICK, action_ums_emmc_gpp);
// Create BOOT0 button.
lv_obj_t *btn_boot0 = lv_btn_create(h1, btn1);
@@ -927,6 +1089,8 @@ out:
return res;
}
// TODO: emusd
static lv_res_t _create_window_unset_abit_tool(lv_obj_t *btn)
{
lv_obj_t *win = nyx_create_standard_window(SYMBOL_COPY" Fix Archive Bit (All folders)");
@@ -957,7 +1121,8 @@ static lv_res_t _create_window_unset_abit_tool(lv_obj_t *btn)
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
char *path = malloc(0x1000);
path[0] = 0;
strcpy(path, "sd:");
// path[0] = 0;
lv_label_set_text(lb_val, "");
lv_obj_set_width(lb_val, lv_obj_get_width(val));
@@ -1135,8 +1300,9 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
lv_label_set_recolor(lb_desc, true);
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
if (!sd_mount())
if (!boot_storage_mount())
{
// may not be sd, fix error
lv_label_set_text(lb_desc, "#FFDD00 Failed to init SD!#");
goto out_end;
@@ -1180,7 +1346,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump package1 in its encrypted state.
emmcsn_path_impl(path, "/pkg1", "pkg1_enc.bin", &emmc_storage);
bool res = sd_save_to_file(pkg1, BOOTLOADER_SIZE, path);
bool res = boot_storage_save_to_file(pkg1, BOOTLOADER_SIZE, path);
// Exit if unknown.
if (!pkg1_id)
@@ -1245,7 +1411,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump package1.1.
emmcsn_path_impl(path, "/pkg1", "pkg1_decr.bin", &emmc_storage);
if (sd_save_to_file(pkg1, SZ_256K, path))
if (boot_storage_save_to_file(pkg1, SZ_256K, path))
goto out_free;
strcat(txt_buf, "pkg1 dumped to pkg1_decr.bin\n");
lv_label_set_text(lb_desc, txt_buf);
@@ -1253,7 +1419,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump nxbootloader.
emmcsn_path_impl(path, "/pkg1", "nxloader.bin", &emmc_storage);
if (sd_save_to_file(loader, hdr_pk11->ldr_size, path))
if (boot_storage_save_to_file(loader, hdr_pk11->ldr_size, path))
goto out_free;
strcat(txt_buf, "NX Bootloader dumped to nxloader.bin\n");
lv_label_set_text(lb_desc, txt_buf);
@@ -1261,7 +1427,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump secmon.
emmcsn_path_impl(path, "/pkg1", "secmon.bin", &emmc_storage);
if (sd_save_to_file(secmon, hdr_pk11->sm_size, path))
if (boot_storage_save_to_file(secmon, hdr_pk11->sm_size, path))
goto out_free;
strcat(txt_buf, "Secure Monitor dumped to secmon.bin\n");
lv_label_set_text(lb_desc, txt_buf);
@@ -1269,7 +1435,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump warmboot.
emmcsn_path_impl(path, "/pkg1", "warmboot.bin", &emmc_storage);
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
if (boot_storage_save_to_file(warmboot, hdr_pk11->wb_size, path))
goto out_free;
// If T210B01, save a copy of decrypted warmboot binary also.
if (h_cfg.t210b01)
@@ -1279,7 +1445,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
se_aes_crypt_cbc(13, DECRYPT, warmboot + 0x330, hdr_pk11->wb_size - 0x330,
warmboot + 0x330, hdr_pk11->wb_size - 0x330);
emmcsn_path_impl(path, "/pkg1", "warmboot_dec.bin", &emmc_storage);
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
if (boot_storage_save_to_file(warmboot, hdr_pk11->wb_size, path))
goto out_free;
}
strcat(txt_buf, "Warmboot dumped to warmboot.bin\n\n");
@@ -1311,7 +1477,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump encrypted package2.
emmcsn_path_impl(path, "/pkg2", "pkg2_encr.bin", &emmc_storage);
res = sd_save_to_file(pkg2, pkg2_size, path);
res = boot_storage_save_to_file(pkg2, pkg2_size, path);
// Decrypt package2 and parse KIP1 blobs in INI1 section.
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2, kb);
@@ -1345,7 +1511,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump pkg2.1.
emmcsn_path_impl(path, "/pkg2", "pkg2_decr.bin", &emmc_storage);
if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
if (boot_storage_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
goto out;
strcat(txt_buf, "pkg2 dumped to pkg2_decr.bin\n");
lv_label_set_text(lb_desc, txt_buf);
@@ -1353,7 +1519,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Dump kernel.
emmcsn_path_impl(path, "/pkg2", "kernel.bin", &emmc_storage);
if (sd_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], path))
if (boot_storage_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], path))
goto out;
strcat(txt_buf, "Kernel dumped to kernel.bin\n");
lv_label_set_text(lb_desc, txt_buf);
@@ -1377,7 +1543,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)(pkg2_hdr->data + ini1_off);
emmcsn_path_impl(path, "/pkg2", "ini1.bin", &emmc_storage);
if (sd_save_to_file(ini1, ini1_size, path))
if (boot_storage_save_to_file(ini1, ini1_size, path))
goto out;
strcat(txt_buf, "INI1 dumped to ini1.bin\n\n");
@@ -1404,7 +1570,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
}
emmcsn_path_impl(path, "/pkg2/ini1", filename, &emmc_storage);
if (sd_save_to_file(kip1, kip1_size, path))
if (boot_storage_save_to_file(kip1, kip1_size, path))
{
free(kip_buffer);
goto out;
@@ -1429,6 +1595,7 @@ out_free:
free(txt_buf);
emmc_end();
sd_unmount();
boot_storage_unmount();
if (kb >= HOS_KB_VERSION_620)
se_aes_key_clear(8);
@@ -1439,6 +1606,26 @@ out_end:
return LV_RES_OK;
}
lv_res_t _partition_action(lv_obj_t *btnm, const char *txt){
u8 drive;
switch(lv_btnm_get_pressed(btnm)){
case 0:
// SD
drive = DRIVE_SD;
break;
case 1:
// eMMC
drive = DRIVE_EMMC;
break;
default:
return LV_RES_OK;
}
create_window_partition_manager(btnm, drive);
return LV_RES_OK;
}
static void _create_tab_tools_emmc_pkg12(lv_theme_t *th, lv_obj_t *parent)
{
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
@@ -1508,41 +1695,58 @@ static void _create_tab_tools_emmc_pkg12(lv_theme_t *th, lv_obj_t *parent)
lv_label_set_static_text(label_sep, "");
lv_obj_t *label_txt3 = lv_label_create(h2, NULL);
lv_label_set_static_text(label_txt3, "SD Partitions & USB");
lv_label_set_static_text(label_txt3, "Partitions & USB");
lv_obj_set_style(label_txt3, th->label.prim);
lv_obj_align(label_txt3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI * 3 / 10);
line_sep = lv_line_create(h2, line_sep);
lv_obj_align(line_sep, label_txt3, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
// Create Partition SD Card button.
lv_obj_t *btn3 = lv_btn_create(h2, NULL);
// Create Partition SD/eMMC Card button.
// TODO: Boot 1 partition option
static const char* btn_map[] = {"\222" SYMBOL_SD " SD", "\222" SYMBOL_CHIP " eMMC", ""};
lv_obj_t *btnm = lv_btnm_create(h2, NULL);
lv_btnm_set_style(btnm, LV_BTNM_STYLE_BG, th->bg);
lv_btnm_set_style(btnm, LV_BTNM_STYLE_BTN_REL, th->btn.rel);
lv_btnm_set_style(btnm, LV_BTNM_STYLE_BTN_PR, th->btn.pr);
lv_btnm_set_style(btnm, LV_BTNM_STYLE_BTN_TGL_REL, th->btn.tgl_rel);
lv_btnm_set_style(btnm, LV_BTNM_STYLE_BTN_TGL_PR, th->btn.tgl_pr);
lv_btnm_set_style(btnm, LV_BTNM_STYLE_BTN_INA, th->btn.ina);
if (hekate_bg)
{
lv_btn_set_style(btn3, LV_BTN_STYLE_REL, &btn_transp_rel);
lv_btn_set_style(btn3, LV_BTN_STYLE_PR, &btn_transp_pr);
lv_btn_set_style(btnm, LV_BTN_STYLE_REL, &btn_transp_rel);
lv_btn_set_style(btnm, LV_BTN_STYLE_PR, &btn_transp_pr);
}
label_btn = lv_label_create(btn3, NULL);
lv_btn_set_fit(btn3, true, true);
lv_label_set_static_text(label_btn, SYMBOL_SD" Partition SD Card");
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_window_partition_manager);
lv_coord_t font_h = lv_font_get_height(th->btn.rel->text.font);
lv_obj_set_size(btnm, 400, font_h + 2 * th->btn.rel->body.padding.ver + 2 * th->bg->body.padding.ver);
lv_obj_align(btnm, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4 - th->bg->body.padding.ver);
lv_btnm_set_map(btnm, btn_map);
lv_btnm_set_action(btnm, _partition_action);
lv_obj_t *label_txt4 = lv_label_create(h2, NULL);
lv_label_set_recolor(label_txt4, true);
lv_label_set_static_text(label_txt4,
"Allows you to partition the SD Card for using it with #C7EA46 emuMMC#,\n"
"#C7EA46 Android# and #C7EA46 Linux#. You can also flash Linux and Android.\n");
"Allows you to partition the SD Card or the eMMC \n"
"for using it with #C7EA46 emuMMC#, #C7EA46 Android# and #C7EA46 Linux#."
"\nYou can also flash Linux and Android.");
lv_obj_set_style(label_txt4, &hint_small_style);
lv_obj_align(label_txt4, btn3, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
lv_obj_align(label_txt4, btnm, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3 - th->bg->body.padding.ver);
label_sep = lv_label_create(h2, NULL);
lv_label_set_static_text(label_sep, "");
lv_obj_align(label_sep, label_txt4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI * 11 / 7);
// Create USB Tools button.
lv_obj_t *btn4 = lv_btn_create(h2, btn3);
lv_obj_t *btn4 = lv_btn_create(h2, NULL);
label_btn = lv_label_create(btn4, NULL);
if (hekate_bg)
{
lv_btn_set_style(btn4, LV_BTN_STYLE_REL, &btn_transp_rel);
lv_btn_set_style(btn4, LV_BTN_STYLE_PR, &btn_transp_pr);
}
lv_btn_set_fit(btn4, true, true);
lv_label_set_static_text(label_btn, SYMBOL_USB" USB Tools");
lv_obj_align(btn4, label_txt4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
lv_btn_set_action(btn4, LV_BTN_ACTION_CLICK, _create_window_usb_tools);

View File

@@ -25,5 +25,6 @@ void create_tab_tools(lv_theme_t *th, lv_obj_t *parent);
void nyx_run_ums(void *param);
bool get_set_autorcm_status(bool change);
lv_res_t action_ums_sd(lv_obj_t *btn);
lv_res_t action_ums_emmc_gpp(lv_obj_t *btn);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,6 @@
#ifndef _GUI_TOOLS_PART_MANAGER_H_
#define _GUI_TOOLS_PART_MANAGER_H_
lv_res_t create_window_partition_manager(lv_obj_t *btn);
lv_res_t create_window_partition_manager(lv_obj_t *btn, u8 drive);
#endif

View File

@@ -23,6 +23,7 @@
#include <bdk.h>
#include "hos.h"
#include <storage/boot_storage.h>
#include "../config.h"
extern hekate_config h_cfg;
@@ -393,7 +394,7 @@ int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
*/
// Use custom TSEC Hovi Keygen firmware.
tsec_ctxt->fw = sd_file_read("bootloader/sys/thk.bin", NULL);
tsec_ctxt->fw = boot_storage_file_read("bootloader/sys/thk.bin", NULL);
if (!tsec_ctxt->fw)
{
EPRINTF("\nFailed to load thk.bin");
@@ -699,7 +700,7 @@ int hos_dump_cal0()
LIST_INIT(gpt);
emmc_gpt_parse(&gpt);
emmc_part_t *cal0_part = emmc_part_find(&gpt, "PRODINFO"); // check if null
nx_emmc_bis_init(cal0_part, false, 0);
nx_emmc_bis_init(cal0_part, false, NULL, 0);
nx_emmc_bis_read(0, 0x40, cal0_buf);
nx_emmc_bis_end();
emmc_gpt_free(&gpt);

View File

@@ -9,15 +9,113 @@
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include <storage/emmc.h>
#include <string.h>
#include <bdk.h>
#include <libs/fatfs/diskio.h> /* FatFs lower layer API */
#include <fatfs_cfg.h>
#include "../../storage/sfd.h"
static u32 sd_rsvd_sectors = 0;
static u32 ramdisk_sectors = 0;
static u32 emummc_sectors = 0;
static u32 sfd_sectors = 0;
static u32 cur_partition;
static void save_cur_partition(BYTE pdrv){
bool save = false;
switch(pdrv){
case DRIVE_BOOT1:
case DRIVE_BOOT1_1MB:
case DRIVE_EMMC:
save = true;
break;
case DRIVE_SD:
case DRIVE_RAM:
break;
case DRIVE_BIS:
case DRIVE_EMU:
if(nx_emmc_bis_get_storage() == &emmc_storage){
save = true;
}
break;
case DRIVE_SFD:
if(sfd_get_storage() == &emmc_storage){
save = true;
}
break;
default:
break;
}
if(save){
cur_partition = emmc_storage.partition;
}
}
static void restore_cur_partition(BYTE pdrv){
bool restore = false;
switch(pdrv){
case DRIVE_BOOT1:
case DRIVE_BOOT1_1MB:
case DRIVE_EMMC:
restore = true;
break;
case DRIVE_SD:
case DRIVE_RAM:
break;
case DRIVE_BIS:
case DRIVE_EMU:
if(nx_emmc_bis_get_storage() == &emmc_storage){
restore = true;
}
break;
case DRIVE_SFD:
if(sfd_get_storage() == &emmc_storage){
restore = true;
}
break;
default:
break;
}
if(restore){
if(emmc_storage.partition != cur_partition){
emmc_set_partition(cur_partition);
}
}
}
static bool ensure_partition(BYTE pdrv){
u8 part;
switch(pdrv){
case DRIVE_BOOT1:
case DRIVE_BOOT1_1MB:
part = EMMC_BOOT1;
break;
case DRIVE_EMMC:
part = EMMC_GPP;
break;
case DRIVE_SD:
case DRIVE_RAM:
return true;
case DRIVE_BIS:
case DRIVE_EMU:
case DRIVE_SFD:
return true;
default:
return false;
}
if(emmc_storage.partition != part){
return emmc_set_partition(part);
}
return true;
}
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
@@ -49,20 +147,45 @@ DRESULT disk_read (
UINT count /* Number of sectors to read */
)
{
switch (pdrv)
{
case DRIVE_SD:
return sdmmc_storage_read(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
case DRIVE_RAM:
return ram_disk_read(sector, count, (void *)buff);
case DRIVE_EMMC:
return sdmmc_storage_read(&emmc_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
case DRIVE_BIS:
case DRIVE_EMU:
return nx_emmc_bis_read(sector, count, (void *)buff) ? RES_OK : RES_ERROR;
DRESULT res = RES_OK;
save_cur_partition(pdrv);
if(!ensure_partition(pdrv)){
res = RES_ERROR;
}
return RES_ERROR;
if(res == RES_OK){
switch (pdrv)
{
case DRIVE_SD:
res = sdmmc_storage_read(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_RAM:
res = ram_disk_read(sector, count, (void *)buff);
break;
case DRIVE_EMMC:
res = sdmmc_storage_read(&emmc_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_BIS:
case DRIVE_EMU:
res = nx_emmc_bis_read(sector, count, (void *)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_BOOT1_1MB:
res = sdmmc_storage_read(&emmc_storage, sector + (0x100000 / 512), count, buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_BOOT1:
res = sdmmc_storage_read(&emmc_storage, sector, count, buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_SFD:
res = sfd_read(sector, count, buff) ? RES_OK : RES_ERROR;
break;
}
}
restore_cur_partition(pdrv);
return res;
}
/*-----------------------------------------------------------------------*/
@@ -75,20 +198,47 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
switch (pdrv)
{
case DRIVE_SD:
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
case DRIVE_RAM:
return ram_disk_write(sector, count, (void *)buff);
case DRIVE_EMMC:
case DRIVE_BIS:
return RES_WRPRT;
case DRIVE_EMU:
return nx_emmc_bis_write(sector, count, (void *)buff) ? RES_OK : RES_ERROR;
DRESULT res = RES_OK;
save_cur_partition(pdrv);
if(!ensure_partition(pdrv)){
res = RES_ERROR;
}
return RES_ERROR;
if(res == RES_OK){
switch (pdrv)
{
case DRIVE_SD:
res = sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_RAM:
res = ram_disk_write(sector, count, (void *)buff);
break;
case DRIVE_EMMC:
res = sdmmc_storage_write(&emmc_storage, sector, count, (void*)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_BIS:
res = RES_WRPRT;
break;
case DRIVE_EMU:
res = nx_emmc_bis_write(sector, count, (void *)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_BOOT1_1MB:
res = sdmmc_storage_write(&emmc_storage, sector + (0x100000 / 512), count, (void*)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_BOOT1:
res = sdmmc_storage_write(&emmc_storage, sector, count, (void*)buff) ? RES_OK : RES_ERROR;
break;
case DRIVE_SFD:
res = sfd_write(sector, count, (void*)buff) ? RES_OK : RES_ERROR;
break;
}
}
restore_cur_partition(pdrv);
return res;
}
/*-----------------------------------------------------------------------*/
@@ -137,8 +287,16 @@ DRESULT disk_ioctl (
*buf = 32768; // Align to 16MB.
break;
}
}
else // Catch all for unknown devices.
}else if(pdrv == DRIVE_SFD){
switch(cmd){
case GET_SECTOR_COUNT:
*buf = sfd_sectors;
break;
case GET_BLOCK_SIZE:
*buf = 32768;
break;
}
}else // Catch all for unknown devices.
{
switch (cmd)
{
@@ -175,6 +333,9 @@ DRESULT disk_set_info (
case DRIVE_EMU:
emummc_sectors = *buf;
break;
case DRIVE_SFD:
sfd_sectors = *buf;
break;
}
}

View File

@@ -166,7 +166,7 @@
*/
#define FF_FS_RPATH 1
#define FF_FS_RPATH 2
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related functions.
@@ -179,13 +179,13 @@
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 5
#define FF_VOLUMES 8
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 1
// Order is important. Any change to order, must also be reflected to diskio drive enum.
#define FF_VOLUME_STRS "sd","ram","emmc","bis","emu"
#define FF_VOLUME_STRS "sd","ram","emmc","bis","emu", "boot1", "boot1_1mb", "sfd"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
@@ -301,6 +301,15 @@
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
typedef enum {
DRIVE_SD = 0,
DRIVE_RAM = 1,
DRIVE_EMMC = 2,
DRIVE_BIS = 3,
DRIVE_EMU = 4,
DRIVE_BOOT1 = 5,
DRIVE_BOOT1_1MB = 6,
DRIVE_SFD = 7,
} DDRIVE;
/*--- End of configuration options ---*/

View File

@@ -26,6 +26,7 @@
#include <ianos/ianos.h>
#include <libs/compr/blz.h>
#include <libs/fatfs/ff.h>
#include <storage/boot_storage.h>
#include "frontend/fe_emmc_tools.h"
#include "frontend/gui.h"
@@ -34,10 +35,10 @@ nyx_config n_cfg;
hekate_config h_cfg;
const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver = {
.magic = NYX_MAGIC,
.magic = NYX_MAGIC,
.version = (NYX_VER_MJ + '0') | ((NYX_VER_MN + '0') << 8) | ((NYX_VER_HF + '0') << 16) | ((NYX_VER_RL) << 24),
.rsvd0 = 0,
.rsvd1 = 0
.rsvd0 = 0,
.rsvd1 = 0
};
volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
@@ -134,7 +135,7 @@ lv_res_t launch_payload(lv_obj_t *list)
strcpy(path,"bootloader/payloads/");
strcat(path, filename);
if (!sd_mount())
if (!boot_storage_mount())
goto out;
FIL fp;
@@ -174,7 +175,7 @@ lv_res_t launch_payload(lv_obj_t *list)
f_close(&fp);
sd_end();
boot_storage_end();
if (size < 0x30000)
{
@@ -351,8 +352,8 @@ static void _show_errors(int sd_error)
if (*excp_enabled == EXCP_MAGIC || sd_error)
{
gfx_clear_grey(0);
gfx_con_setpos(0, 0, 0);
// gfx_clear_grey(0);
// gfx_con_setpos(0, 0, 0);
display_backlight_brightness(150, 1000);
display_init_window_d_console();
display_window_d_console_enable();
@@ -440,13 +441,13 @@ void nyx_init_load_res()
_show_errors(SD_NO_ERROR);
// Try 2 times to mount SD card.
if (!sd_mount())
if (!boot_storage_mount())
{
// Restore speed to SDR104.
sd_end();
boot_storage_end();
// Retry.
if (!sd_mount())
if (!boot_storage_mount())
_show_errors(SD_MOUNT_ERROR); // Fatal.
}
@@ -496,7 +497,7 @@ void nyx_init_load_res()
nyx_load_bg_icons();
// Unmount FAT partition.
sd_unmount();
boot_storage_unmount();
}
void ipl_main()

54
nyx/nyx_gui/storage/sfd.c Normal file
View File

@@ -0,0 +1,54 @@
#include "sfd.h"
#include <storage/emmc.h>
#include <storage/sdmmc.h>
#include <libs/fatfs/diskio.h>
static sdmmc_storage_t *_storage;
static u32 _offset;
static u32 _size;
static void ensure_partition(){
if(_storage == &emmc_storage){
emmc_set_partition(EMMC_GPP);
}
}
sdmmc_storage_t *sfd_get_storage(){
return _storage;
}
int sfd_read(u32 sector, u32 count, void *buff){
int res;
if(sector + count > _size){
return 0;
}
ensure_partition();
res = sdmmc_storage_read(_storage, sector + _offset, count, buff);
return res;
}
int sfd_write(u32 sector, u32 count, void *buff){
int res;
if(sector + count > _size){
return 0;
}
ensure_partition();
res = sdmmc_storage_write(_storage, sector + _offset, count, buff);
return res;
}
bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size){
_storage = storage;
_offset = offset;
_size = size;
disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &size);
return true;
}
void sfd_end(){
_storage = NULL;
_offset = 0;
_size = 0;
u32 size = 0;
disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &size);
}

15
nyx/nyx_gui/storage/sfd.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef _SFD_H
#define _SFD_H
#include <storage/sdmmc.h>
#include <utils/types.h>
int sfd_read(u32 sector, u32 count, void *buff);
int sfd_write(u32 sector, u32 count, void *buff);
bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size);
void sfd_end();
sdmmc_storage_t *sfd_get_storage();
#endif