Compare commits
40 Commits
v6.3.1
...
2adefd112c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76508c74e8 | ||
|
|
79b6df64d6 | ||
|
|
0a7a004839 | ||
|
|
7521055bec | ||
|
|
39d99a77fe | ||
|
|
b0f0e9be47 | ||
|
|
55a4a814e0 | ||
|
|
4bfe1fe2cd | ||
|
|
6d09e65d85 | ||
|
|
59a173c994 | ||
|
|
e5ceb4a2de | ||
|
|
ea3dae672e | ||
|
|
2af1cc0b8c | ||
|
|
942e7defe3 | ||
|
|
39b74dd50d | ||
|
|
bbe8ddaf66 | ||
|
|
47e030c7fc | ||
|
|
4a127db80b | ||
|
|
241b0f2274 | ||
|
|
ba6073610c | ||
|
|
70cb99cd0c | ||
|
|
7941a3d4d6 | ||
|
|
1ddf9690b1 | ||
|
|
f4d8ee4efc | ||
|
|
4f72660603 | ||
|
|
2440318cb5 | ||
|
|
61e91f79c1 | ||
|
|
bad8566c58 | ||
|
|
28796b417b | ||
|
|
31c8ad0d88 | ||
|
|
0be3fd4f64 | ||
|
|
3e9def3608 | ||
|
|
678ce79a54 | ||
|
|
b11e8095ed | ||
|
|
849d533200 | ||
|
|
337f219ac6 | ||
|
|
4e9e21b3b1 | ||
|
|
fe5e4dc40a | ||
|
|
5798dcde0d | ||
|
|
9d2ec42a9f |
4
Makefile
4
Makefile
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
253
bdk/storage/boot_storage.c
Normal 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;
|
||||
}
|
||||
21
bdk/storage/boot_storage.h
Normal file
21
bdk/storage/boot_storage.h
Normal 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
|
||||
@@ -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); }
|
||||
@@ -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);
|
||||
|
||||
|
||||
233
bdk/storage/emummc_file_based.c
Normal file
233
bdk/storage/emummc_file_based.c
Normal 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;
|
||||
}
|
||||
14
bdk/storage/emummc_file_based.h
Normal file
14
bdk/storage/emummc_file_based.h
Normal 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
39
bdk/storage/mbr_gpt.c
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
@@ -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 ---*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
123
nyx/nyx_gui/frontend/fe_emusd_tools.c
Normal file
123
nyx/nyx_gui/frontend/fe_emusd_tools.c
Normal 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;
|
||||
}
|
||||
16
nyx/nyx_gui/frontend/fe_emusd_tools.h
Normal file
16
nyx/nyx_gui/frontend/fe_emusd_tools.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
79
nyx/nyx_gui/frontend/gui_emu_tools.c
Normal file
79
nyx/nyx_gui/frontend/gui_emu_tools.c
Normal 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;
|
||||
}
|
||||
|
||||
8
nyx/nyx_gui/frontend/gui_emu_tools.h
Normal file
8
nyx/nyx_gui/frontend/gui_emu_tools.h
Normal 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
@@ -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
|
||||
|
||||
461
nyx/nyx_gui/frontend/gui_emusd_tools.c
Normal file
461
nyx/nyx_gui/frontend/gui_emusd_tools.c
Normal 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, §or, 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;
|
||||
}
|
||||
8
nyx/nyx_gui/frontend/gui_emusd_tools.h
Normal file
8
nyx/nyx_gui/frontend/gui_emusd_tools.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ---*/
|
||||
|
||||
@@ -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
54
nyx/nyx_gui/storage/sfd.c
Normal 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
15
nyx/nyx_gui/storage/sfd.h
Normal 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
|
||||
Reference in New Issue
Block a user