From 0468bd94830addc9dc22891153f62dcc6ea5b898 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 19 Jun 2019 12:05:51 -0700 Subject: [PATCH] git subrepo pull emummc subrepo: subdir: "emummc" merged: "817020a9" upstream: origin: "https://github.com/m4xw/emuMMC" branch: "develop" commit: "817020a9" git-subrepo: version: "0.4.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "5d6aba9" --- emummc/.gitrepo | 4 +- emummc/source/FS/FS_structs.h | 14 ++-- emummc/source/FS/offsets/200.h | 8 +-- emummc/source/FS/offsets/200_exfat.h | 8 +-- emummc/source/FS/offsets/210.h | 8 +-- emummc/source/FS/offsets/210_exfat.h | 8 +-- emummc/source/FS/offsets/300.h | 8 +-- emummc/source/FS/offsets/300_exfat.h | 8 +-- emummc/source/FS/offsets/301.h | 8 +-- emummc/source/FS/offsets/301_exfat.h | 8 +-- emummc/source/emmc/sdmmc.c | 86 +++++++++++++++++++++- emummc/source/emmc/sdmmc.h | 6 ++ emummc/source/emmc/sdmmc_driver.c | 71 +++++++++++++++++-- emummc/source/emmc/sdmmc_driver.h | 2 +- emummc/source/emuMMC/emummc.c | 102 ++++++++++++--------------- emummc/source/emuMMC/emummc.h | 2 - emummc/source/main.c | 2 - 17 files changed, 245 insertions(+), 108 deletions(-) diff --git a/emummc/.gitrepo b/emummc/.gitrepo index 26931dd8d..063fa9481 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emuMMC branch = develop - commit = 44ecdb457a59d365423e7bd7e312253e87b2e176 - parent = 31fde233e177ba53e1359686f01ed4188c3a282e + commit = 817020a94a4a6e3a238fbdcab21673dba462c798 + parent = 63a9c856fcd0e6c69aead75c91e43cba3a71e271 method = rebase cmdver = 0.4.0 diff --git a/emummc/source/FS/FS_structs.h b/emummc/source/FS/FS_structs.h index 8d50352aa..cd4c6e187 100644 --- a/emummc/source/FS/FS_structs.h +++ b/emummc/source/FS/FS_structs.h @@ -20,7 +20,8 @@ #include "../utils/types.h" -typedef struct { +typedef struct +{ char *device_addr_buffer; uint64_t device_addr_buffer_size; char *device_addr_buffer_masked; @@ -28,7 +29,8 @@ typedef struct { _Static_assert(__alignof(sdmmc_dma_buffer_t) == 8, "sdmmc_dma_buffer_t definition"); -typedef struct sdmmc_accessor_vt { +typedef struct sdmmc_accessor_vt +{ void *ctor; void *dtor; void *map_device_addr_space; @@ -39,14 +41,18 @@ typedef struct sdmmc_accessor_vt { // More not included because we don't use it. } sdmmc_accessor_vt_t; -typedef struct { +_Static_assert(__alignof(sdmmc_accessor_vt_t) == 8, "sdmmc_accessor_vt_t definition"); + +typedef struct +{ void *vtab; t210_sdmmc_t *io_map; sdmmc_dma_buffer_t dmaBuffers[3]; // More not included because we don't use it. } mmc_obj_t; -typedef struct { +typedef struct +{ sdmmc_accessor_vt_t *vtab; mmc_obj_t *parent; // More not included because we don't use it. diff --git a/emummc/source/FS/offsets/200.h b/emummc/source/FS/offsets/200.h index 18078c9e1..a739af8b9 100644 --- a/emummc/source/FS/offsets/200.h +++ b/emummc/source/FS/offsets/200.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_200_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_200_H__ diff --git a/emummc/source/FS/offsets/200_exfat.h b/emummc/source/FS/offsets/200_exfat.h index db36502c1..3716e6723 100644 --- a/emummc/source/FS/offsets/200_exfat.h +++ b/emummc/source/FS/offsets/200_exfat.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_200_EXFAT_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_200_EXFAT_H__ diff --git a/emummc/source/FS/offsets/210.h b/emummc/source/FS/offsets/210.h index 086811888..731a19828 100644 --- a/emummc/source/FS/offsets/210.h +++ b/emummc/source/FS/offsets/210.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_210_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_210_H__ diff --git a/emummc/source/FS/offsets/210_exfat.h b/emummc/source/FS/offsets/210_exfat.h index 6c276cc1e..8111af2ea 100644 --- a/emummc/source/FS/offsets/210_exfat.h +++ b/emummc/source/FS/offsets/210_exfat.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_210_EXFAT_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_210_EXFAT_H__ diff --git a/emummc/source/FS/offsets/300.h b/emummc/source/FS/offsets/300.h index b69768331..c5cabf1ea 100644 --- a/emummc/source/FS/offsets/300.h +++ b/emummc/source/FS/offsets/300.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_300_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_300_H__ diff --git a/emummc/source/FS/offsets/300_exfat.h b/emummc/source/FS/offsets/300_exfat.h index 56a654252..7db7a9050 100644 --- a/emummc/source/FS/offsets/300_exfat.h +++ b/emummc/source/FS/offsets/300_exfat.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_300_EXFAT_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_300_EXFAT_H__ diff --git a/emummc/source/FS/offsets/301.h b/emummc/source/FS/offsets/301.h index 0dacf6526..73ff16978 100644 --- a/emummc/source/FS/offsets/301.h +++ b/emummc/source/FS/offsets/301.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_301_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_301_H__ diff --git a/emummc/source/FS/offsets/301_exfat.h b/emummc/source/FS/offsets/301_exfat.h index 3dfb45ca8..c73e315d4 100644 --- a/emummc/source/FS/offsets/301_exfat.h +++ b/emummc/source/FS/offsets/301_exfat.h @@ -47,10 +47,10 @@ // Nintendo Paths #define FS_OFFSET_301_EXFAT_NINTENDO_PATHS \ { \ - {.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 4}, \ - {.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 4}, \ - {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ + {.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 0x0000000C}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ } #endif // __FS_301_EXFAT_H__ diff --git a/emummc/source/emmc/sdmmc.c b/emummc/source/emmc/sdmmc.c index 166462e61..92c62c4b5 100644 --- a/emummc/source/emmc/sdmmc.c +++ b/emummc/source/emmc/sdmmc.c @@ -23,9 +23,13 @@ #include "sd.h" #include "../utils/types.h" #include "../utils/util.h" +#include "../utils/fatal.h" #define DPRINTF(...) //fprintf(stdout, __VA_ARGS__) +sdmmc_accessor_t *_current_accessor = NULL; +bool sdmmc_memcpy_buf = false; + static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size) { const u32 mask = (size < 32 ? 1 << size : 0) - 1; @@ -41,6 +45,80 @@ static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size) * Common functions for SD and MMC. */ +// FS DMA calculations. +intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors) +{ + int dma_buf_idx = 0; + char *_buf = (char *)buf; + char *actual_buf_start = _buf; + char *actual_buf_end = &_buf[512 * num_sectors]; + char *dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer; + + if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size]) + { + dma_buf_idx = FS_SDMMC_EMMC; + } + else + { + dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer; + if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size]) + { + dma_buf_idx = FS_SDMMC_SD; + } + else + { + dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer; + if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer_size]) + { + dma_buf_idx = FS_SDMMC_GC; + } + else + { + // If buffer is on a random heap + return 0; + } + } + } + + sdmmc_memcpy_buf = false; + + intptr_t admaaddr = (intptr_t)&_this->parent->dmaBuffers[dma_buf_idx].device_addr_buffer_masked[actual_buf_start - dma_buffer_start]; + return admaaddr; +} + +int sdmmc_get_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors) +{ + int dma_buf_idx = 0; + int blkSize = num_sectors * 512; + + if (_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size >= blkSize) + { + dma_buf_idx = FS_SDMMC_EMMC; + } + else + { + if (_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size >= blkSize) + { + dma_buf_idx = FS_SDMMC_SD; + } + else + { + if (_this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer_size >= blkSize) + { + dma_buf_idx = FS_SDMMC_GC; + } + else + { + // If buffer is on a random heap + return 0; + } + } + } + + sdmmc_memcpy_buf = true; + return dma_buf_idx; +} + static int _sdmmc_storage_check_result(u32 res) { //Error mask: @@ -129,9 +207,11 @@ static int _sdmmc_storage_check_status(sdmmc_storage_t *storage) static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write) { sdmmc_cmd_t cmdbuf; + sdmmc_req_t reqbuf; + u32 tmp = 0; + sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0); - sdmmc_req_t reqbuf; reqbuf.buf = buf; reqbuf.num_sectors = num_sectors; reqbuf.blksize = 512; @@ -140,12 +220,12 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out reqbuf.is_auto_cmd12 = 1; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out)) - { - u32 tmp = 0; + { sdmmc_stop_transmission(storage->sdmmc, &tmp); _sdmmc_storage_get_status(storage, &tmp, 0); return 0; } + return 1; } diff --git a/emummc/source/emmc/sdmmc.h b/emummc/source/emmc/sdmmc.h index 7ae20e346..130e60bfb 100644 --- a/emummc/source/emmc/sdmmc.h +++ b/emummc/source/emmc/sdmmc.h @@ -19,6 +19,7 @@ #define _SDMMC_H_ #include "../utils/types.h" +#include "../FS/FS.h" #include "sdmmc_driver.h" typedef struct _mmc_cid @@ -102,6 +103,9 @@ typedef struct _sdmmc_storage_t sd_ssr_t ssr; } sdmmc_storage_t; +extern sdmmc_accessor_t *_current_accessor; +extern bool sdmmc_memcpy_buf; + int sdmmc_storage_end(sdmmc_storage_t *storage); int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf); int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf); @@ -109,5 +113,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition); int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type); int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc); +intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors); +int sdmmc_get_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors); #endif diff --git a/emummc/source/emmc/sdmmc_driver.c b/emummc/source/emmc/sdmmc_driver.c index 0530c9361..c18c786f9 100644 --- a/emummc/source/emmc/sdmmc_driver.c +++ b/emummc/source/emmc/sdmmc_driver.c @@ -27,6 +27,7 @@ #include "../soc/pmc.h" #include "../soc/pinmux.h" #include "../soc/gpio.h" +#include "../utils/fatal.h" #define DPRINTF(...) @@ -640,6 +641,23 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power) static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power) { + if(sdmmc->id == SDMMC_1) + { + static int last_power = SDMMC_POWER_3_3; + if(power == SDMMC_POWER_1_8 && last_power == SDMMC_POWER_3_3) + { + last_power = power = SDMMC_POWER_1_8; + if (!_sdmmc_autocal_config_offset(sdmmc, power)) + return; + } + else if(power == SDMMC_POWER_3_3 && last_power == SDMMC_POWER_1_8) + { + last_power = power = SDMMC_POWER_3_3; + if (!_sdmmc_autocal_config_offset(sdmmc, power)) + return; + } + } + bool should_enable_sd_clock = false; if (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE) { @@ -788,7 +806,15 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req) u32 blkcnt = req->num_sectors; if (blkcnt >= 0xFFFF) blkcnt = 0xFFFF; - u64 admaaddr = sdmmc->dma_addr_fs; + + u64 admaaddr = (u64)sdmmc_calculate_dma_addr(_current_accessor, req->buf, blkcnt); + if (!admaaddr) + { + // buf is on a heap + int dma_idx = sdmmc_get_fitting_dma_index(_current_accessor, blkcnt); + admaaddr = (u64)&_current_accessor->parent->dmaBuffers[dma_idx].device_addr_buffer_masked[0]; + sdmmc->last_dma_idx = dma_idx; + } //Check alignment. if (admaaddr & 7) @@ -870,7 +896,22 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ if (req) { _sdmmc_config_dma(sdmmc, &blkcnt, req); - armDCacheFlush(req->buf, req->blksize * blkcnt); + if(!sdmmc_memcpy_buf) + { + // Flush from/to phys + armDCacheFlush(req->buf, req->blksize * blkcnt); + } + else + { + if(req->is_write) + { + void* dma_addr = &_current_accessor->parent->dmaBuffers[sdmmc->last_dma_idx].device_addr_buffer[0]; + memcpy(dma_addr, req->buf, req->blksize * blkcnt); + + // Flush to phys + armDCacheFlush(dma_addr, req->blksize * blkcnt); + } + } _sdmmc_enable_interrupts(sdmmc); is_data_present = true; @@ -892,8 +933,15 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ { sdmmc->expected_rsp_type = cmd->rsp_type; _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type); + + /*if(sdmmc->rsp[0] & 0xFDF9A080) + { + res = 0; + sdmmc->rsp[0] = 0; // Reset error + }*/ } - if (req) + + if (res && req) _sdmmc_update_dma(sdmmc); } @@ -903,7 +951,22 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ { if (req) { - armDCacheFlush(req->buf, req->blksize * blkcnt); + if(!req->is_write) + { + if(!sdmmc_memcpy_buf) + { + // Flush from phys + armDCacheFlush(req->buf, req->blksize * blkcnt); + } + else + { + void* dma_addr = &_current_accessor->parent->dmaBuffers[sdmmc->last_dma_idx].device_addr_buffer[0]; + // Flush from phys + armDCacheFlush(dma_addr, req->blksize * blkcnt); + // Copy to buffer + memcpy(req->buf, dma_addr, req->blksize * blkcnt); + } + } if (blkcnt_out) *blkcnt_out = blkcnt; diff --git a/emummc/source/emmc/sdmmc_driver.h b/emummc/source/emmc/sdmmc_driver.h index b2820e7e2..d5c36d7c5 100644 --- a/emummc/source/emmc/sdmmc_driver.h +++ b/emummc/source/emmc/sdmmc_driver.h @@ -83,7 +83,7 @@ typedef struct _sdmmc_t int venclkctl_set; u32 venclkctl_tap; u32 expected_rsp_type; - u64 dma_addr_fs; + u64 last_dma_idx; u64 dma_addr_next; u32 rsp[4]; u32 rsp3; diff --git a/emummc/source/emuMMC/emummc.c b/emummc/source/emuMMC/emummc.c index 9f0d5a1d7..4d959f459 100644 --- a/emummc/source/emuMMC/emummc.c +++ b/emummc/source/emuMMC/emummc.c @@ -24,6 +24,7 @@ #include "emummc.h" #include "emummc_ctx.h" +static bool sdmmc_first_init = false; static bool storageMMCinitialized = false; static bool storageSDinitialized = false; @@ -68,15 +69,25 @@ static void _sdmmc_ensure_device_attached(void) static void _sdmmc_ensure_initialized(void) { - // The boot sysmodule will eventually kill power to SD. Detect this, and reinitialize when it happens. static bool init_done = false; - if (!init_done) + + // First Initial init + if (!sdmmc_first_init) { - if (gpio_read(GPIO_PORT_E, GPIO_PIN_4) == 0) + sdmmc_initialize(); + sdmmc_first_init = true; + } + else + { + // The boot sysmodule will eventually kill power to SD. Detect this, and reinitialize when it happens. + if (!init_done) { - sdmmc_finalize(); - sdmmc_initialize(); - init_done = true; + if (gpio_read(GPIO_PORT_E, GPIO_PIN_4) == 0) + { + sdmmc_finalize(); + sdmmc_initialize(); + init_done = true; + } } } } @@ -128,7 +139,7 @@ static void _file_based_emmc_initialize(void) memset(&f_emu, 0, sizeof(file_based_ctxt)); memcpy(path, (void *)emuMMC_ctx.storagePath, sizeof(emuMMC_ctx.storagePath)); - strcat(path, "/eMMC"); + strcat(path, "/eMMC/"); int path_len = strlen(path); // Open BOOT0 physical partition. @@ -188,23 +199,33 @@ bool sdmmc_initialize(void) if (!storageSDinitialized) { - if (sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11)) + int retries = 5; + while (retries) { - storageSDinitialized = true; - - // File based emummc. - if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted) + if (sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11)) { - f_emu.sd_fs = (FATFS *)malloc(sizeof(FATFS)); - if (f_mount(f_emu.sd_fs, "", 1) != FR_OK) - fatal_abort(Fatal_InitSD); - else - fat_mounted = true; + storageSDinitialized = true; - _file_based_emmc_initialize(); + // File based emummc. + if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted) + { + f_emu.sd_fs = (FATFS *)malloc(sizeof(FATFS)); + if (f_mount(f_emu.sd_fs, "", 1) != FR_OK) + fatal_abort(Fatal_InitSD); + else + fat_mounted = true; + + _file_based_emmc_initialize(); + } + + break; } + + retries--; + msleep(100); } - else + + if (!storageSDinitialized) { fatal_abort(Fatal_InitSD); } @@ -213,38 +234,6 @@ bool sdmmc_initialize(void) return storageMMCinitialized && storageSDinitialized; } -// FS DMA calculations. -intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors) -{ - int dma_buf_idx = 0; - char *_buf = (char *)buf; - char *actual_buf_start = _buf; - char *actual_buf_end = &_buf[512 * num_sectors]; - char *dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer; - - if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size]) - { - dma_buf_idx = FS_SDMMC_EMMC; - } - else - { - dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer; - if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size]) - { - dma_buf_idx = FS_SDMMC_SD; - } - else - { - dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer; - dma_buf_idx = FS_SDMMC_GC; - } - } - - intptr_t admaaddr = (intptr_t)&_this->parent->dmaBuffers[dma_buf_idx].device_addr_buffer_masked[actual_buf_start - dma_buffer_start]; - - return admaaddr; -} - sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id) { sdmmc_accessor_t *_this; @@ -354,6 +343,8 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in if (mmc_id == FS_SDMMC_EMMC || mmc_id == FS_SDMMC_SD) { mutex_lock_handler(mmc_id); + // Assign FS accessor to the SDMMC driver + _current_accessor = _this; // Make sure we're attached to the device address space. _sdmmc_ensure_device_attached(); // Make sure we're still initialized if boot killed sd card power. @@ -362,8 +353,6 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in if (mmc_id == FS_SDMMC_EMMC) { - sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors); - // Call hekates driver. if (emummc_read_write_inner(buf, sector, num_sectors, false)) { @@ -377,8 +366,6 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in if (mmc_id == FS_SDMMC_SD) { - sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors); - // Call hekates driver. if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf)) { @@ -410,8 +397,7 @@ uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_s if (mmc_id == FS_SDMMC_EMMC) { mutex_lock_handler(mmc_id); - - sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors); + _current_accessor = _this; // Call hekates driver. if (emummc_read_write_inner(buf, sector, num_sectors, true)) @@ -427,9 +413,9 @@ uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_s if (mmc_id == FS_SDMMC_SD) { mutex_lock_handler(mmc_id); + _current_accessor = _this; sector += 0; - sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors); // Call hekates driver. if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf)) diff --git a/emummc/source/emuMMC/emummc.h b/emummc/source/emuMMC/emummc.h index d6f8c8c5e..7595e2357 100644 --- a/emummc/source/emuMMC/emummc.h +++ b/emummc/source/emuMMC/emummc.h @@ -50,8 +50,6 @@ sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id); void mutex_lock_handler(int mmc_id); void mutex_unlock_handler(int mmc_id); -intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors); - uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors); uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize); diff --git a/emummc/source/main.c b/emummc/source/main.c index 3e35ad27e..68508b498 100644 --- a/emummc/source/main.c +++ b/emummc/source/main.c @@ -316,6 +316,4 @@ void __init() populate_function_pointers(); write_nops(); setup_nintendo_paths(); - - sdmmc_initialize(); }