Exemple #1
0
int get_emunand_offsets(uint32_t location, uint32_t *offset, uint32_t *header)
{
    if (sdmmc_sdcard_readsectors(location + 1, 1, fcram_temp) == 0) {
        if (*(uint32_t *)(fcram_temp + 0x100) == NCSD_MAGIC) {
            if (offset && header) {
                print("emuNAND detected: redNAND");
                *offset = location + 1;
                *header = location + 1;
            }
            return 0;
        }
    }

    uint32_t nand_size = getMMCDevice(0)->total_size;

    if (sdmmc_sdcard_readsectors(location + nand_size, 1, fcram_temp) == 0) {
        if (*(uint32_t *)(fcram_temp + 0x100) == NCSD_MAGIC) {
            if (offset && header) {
                print("emuNAND detected: Gateway");
                *offset = location;
                *header = location + nand_size;
            }
            return 0;
        }
    }

    return 1;
}
Exemple #2
0
void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND)
{
    static u8 *const temp = (u8 *)0x24300000;

    const u32 nandSize = getMMCDevice(0)->total_size;
    u32 nandOffset = *emuNAND == 1 ? 0 :
                                  (nandSize > 0x200000 ? 0x400000 : 0x200000);

    //Check for RedNAND
    if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) &&
       *(u32 *)(temp + 0x100) == NCSD_MAGIC)
    {
        *off = nandOffset + 1;
        *head = nandOffset + 1;
    }

    //Check for Gateway emuNAND
    else if(!sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) &&
            *(u32 *)(temp + 0x100) == NCSD_MAGIC)
    {
        *off = nandOffset;
        *head = nandOffset + nandSize;
    }

    /* Fallback to the first emuNAND if there's no second one,
       or to SysNAND if there isn't any */
    else
    {
        (*emuNAND)--;
        if(*emuNAND) getEmunandSect(off, head, emuNAND);
    }
}
Exemple #3
0
u32 CheckEmuNand(void)
{
    u8* buffer = BUFFER_ADDRESS;
    u32 nand_size_sectors = getMMCDevice(0)->total_size;

    u32 nand_offset;
    if (emunand_no > 0) {
        if (nand_size_sectors > EMUNAND_MULTI_OFFSET_O3DS) {
            nand_offset = EMUNAND_MULTI_OFFSET_N3DS * (emunand_no - 1 );
        } else {
            nand_offset = EMUNAND_MULTI_OFFSET_O3DS * (emunand_no - 1 );
        }
    } else {
        nand_offset = 0;
    }

    // check the MBR for presence of EmuNAND
    sdmmc_sdcard_readsectors(0, 1, buffer);
    if (nand_offset+nand_size_sectors > getle32(buffer + 0x1BE + 0x8))
        return EMUNAND_NOT_READY;

    // check for Gateway type EmuNAND
    sdmmc_sdcard_readsectors(nand_offset+nand_size_sectors, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_GATEWAY;

    // check for RedNAND type EmuNAND
    sdmmc_sdcard_readsectors(nand_offset + 1, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_REDNAND;

    // EmuNAND ready but not set up
    return EMUNAND_READY;
}
Exemple #4
0
u32 SetNand(bool set_emunand, bool force_emunand)
{
    if (set_emunand) {
        u32 emunand_state = CheckEmuNand();
        if ((emunand_state == EMUNAND_READY) && force_emunand)
            emunand_state = EMUNAND_GATEWAY;
        switch (emunand_state) {
            case EMUNAND_NOT_READY:
                Debug("SD is not formatted for EmuNAND");
                return 1;
            case EMUNAND_GATEWAY:
                emunand_header = getMMCDevice(0)->total_size;
                emunand_offset = 0;
                Debug("Using EmuNAND @ %06X/%06X", emunand_header, emunand_offset);
                return 0;
            case EMUNAND_REDNAND:
                emunand_header = 1;
                emunand_offset = 1;
                Debug("Using RedNAND @ %06X/%06X", emunand_header, emunand_offset);
                return 0;
            default:
                Debug("EmuNAND is not available");
                return 1;
        }
    } else {
        emunand_header = 0;
        emunand_offset = 0;
        return 0;
    }
}
Exemple #5
0
u32 DumpNand(u32 param)
{
    char filename[64];
    u8* buffer = BUFFER_ADDRESS;
    u32 nand_size = getMMCDevice(0)->total_size * NAND_SECTOR_SIZE;
    u32 result = 0;

    Debug("Dumping %sNAND. Size (MB): %u", (param & N_EMUNAND) ? "Emu" : "Sys", nand_size / (1024 * 1024));
    
    if (OutputFileNameSelector(filename, "NAND.bin", NULL, param & N_EMUNAND) != 0)
        return 1;
    if (!DebugFileCreate(filename, true))
        return 1;

    u32 n_sectors = nand_size / NAND_SECTOR_SIZE;
    for (u32 i = 0; i < n_sectors; i += SECTORS_PER_READ) {
        u32 read_sectors = min(SECTORS_PER_READ, (n_sectors - i));
        ShowProgress(i, n_sectors);
        ReadNandSectors(i, read_sectors, buffer);
        if(!DebugFileWrite(buffer, NAND_SECTOR_SIZE * read_sectors, i * NAND_SECTOR_SIZE)) {
            result = 1;
            break;
        }
    }

    ShowProgress(0, 0);
    FileClose();

    return result;
}
Exemple #6
0
void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND)
{
    u8 *const temp = (u8 *)0x24300000;

    const u32 nandSize = getMMCDevice(0)->total_size;
    u32 nandOffset = *emuNAND == 1 ? 0 :
                                  (nandSize > 0x200000 ? 0x400000 : 0x200000);

    //Check for RedNAND
    if(sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) == 0)
    {
        if(*(u32 *)(temp + 0x100) == NCSD_MAGIC)
        {
            *off = nandOffset + 1;
            *head = nandOffset + 1;
        }
        //Check for Gateway emuNAND
        else if(sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) == 0)
        {
            if(*(u32 *)(temp + 0x100) == NCSD_MAGIC)
            {
                *off = nandOffset;
                *head = nandOffset + nandSize;
            }
            //Fallback to the first emuNAND if there's no second one
            else if(*emuNAND == 2)
            {
                *emuNAND = 1;
                getEmunandSect(off, head, emuNAND);
            }
            else *emuNAND = 0;
        }
    }
}
Exemple #7
0
void getEmunandSect(u32 *off, u32 *head){
    u32 nandSize = getMMCDevice(0)->total_size;
    if (sdmmc_sdcard_readsectors(nandSize, 1, temp) == 0) {
        if (*(u32*)(temp + 0x100) == NCSD_MAGIC) {
            *off = 0;
            *head = nandSize;
        }
    }
}
Exemple #8
0
void menu_emunand()
{
    char emunands[MAX_OPTIONS][0x20];  // We have a max size for the strings...
    char unnamed[] = "emuNAND #";

    uint32_t gap;
    if (getMMCDevice(0)->total_size > 0x200000) {
        gap = 0x400000;
    } else {
        gap = 0x200000;
    }

    // Scan for available emuNANDS. Assume they're placed right behind eachother.
    int count;
    for (count = 0; count <= MAX_OPTIONS; count++) {
        if (get_emunand_offsets(count * gap, NULL, NULL) == 0) {
            if (sdmmc_sdcard_readsectors(count * gap, 1, fcram_temp) == 0 &&
                    memcmp(fcram_temp + 11, "NAME", 4) == 0) {
                memcpy(emunands[count], fcram_temp + 15, 0x1F);
                emunands[count][0x1F] = 0;
            } else {
                memcpy(emunands[count], unnamed, sizeof(unnamed));
                emunands[count][sizeof(unnamed) - 1] = '1' + count;
                emunands[count][sizeof(unnamed)] = 0;
            }
            continue;
        }

        break;
    }

    if (count <= 0) {
        print("Failed to find any emuNAND");
        draw_message("Failed to find any emuNAND",
                "There's 3 possible causes for this error:\n"
                " - You don't even have an emuNAND installed\n"
                " - Your SD card can't be read\n"
                " - You're using an unsupported emuNAND format");
        return;
    }

    // Make the pointer array
    char *options[count];
    for (int x = 0; x <= count; x++) options[x] = emunands[x];

    int result = draw_menu("Select emuNAND", 1, count, options);
    if (result == -1) return;

    config->emunand_location = result * gap;
    patches_modified = 1;
}
Exemple #9
0
int REDNAND(void){
	u8 buf[0x200];
	sdmmc_sdcard_readsectors(1, 1, buf); //"rednand"
	if (strncmp((char *)(buf+0x100), "NCSD", 4) == 0){
		emunand_code[22] = 1;
		emunand_code[23] = 1;
		return 0;
	}
	
	mmcdevice *nand = getMMCDevice(0);
	sdmmc_sdcard_readsectors(nand->total_size, 1, buf); //"emunand"
	if (strncmp((char *)(buf+0x100), "NCSD", 4) == 0){
		emunand_code[22] = 0;
		emunand_code[23] = nand->total_size;
		return 0;
	}
	
	return -1;
}
Exemple #10
0
u32 CheckEmuNand(void)
{
    u8* buffer = BUFFER_ADDRESS;
    u32 nand_size_sectors = getMMCDevice(0)->total_size;
    
    // check the MBR for presence of EmuNAND
    sdmmc_sdcard_readsectors(0, 1, buffer);
    if (nand_size_sectors > getle32(buffer + 0x1BE + 0x8))
        return EMUNAND_NOT_READY;
    
    // check for Gateway type EmuNAND
    sdmmc_sdcard_readsectors(nand_size_sectors, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_GATEWAY;
    
    // check for RedNAND type EmuNAND
    sdmmc_sdcard_readsectors(1, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_REDNAND;
        
    // EmuNAND ready but not set up
    return EMUNAND_READY;
}
Exemple #11
0
uint64_t ctr_sd_interface_disk_size(void *io)
{
	return getMMCDevice(1)->total_size * (uint64_t)512u;
}