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"
This commit is contained in:
Michael Scire 2019-06-19 12:05:51 -07:00
parent 63a9c856fc
commit 0468bd9483
17 changed files with 245 additions and 108 deletions

View file

@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/m4xw/emuMMC remote = https://github.com/m4xw/emuMMC
branch = develop branch = develop
commit = 44ecdb457a59d365423e7bd7e312253e87b2e176 commit = 817020a94a4a6e3a238fbdcab21673dba462c798
parent = 31fde233e177ba53e1359686f01ed4188c3a282e parent = 63a9c856fcd0e6c69aead75c91e43cba3a71e271
method = rebase method = rebase
cmdver = 0.4.0 cmdver = 0.4.0

View file

@ -20,7 +20,8 @@
#include "../utils/types.h" #include "../utils/types.h"
typedef struct { typedef struct
{
char *device_addr_buffer; char *device_addr_buffer;
uint64_t device_addr_buffer_size; uint64_t device_addr_buffer_size;
char *device_addr_buffer_masked; char *device_addr_buffer_masked;
@ -28,7 +29,8 @@ typedef struct {
_Static_assert(__alignof(sdmmc_dma_buffer_t) == 8, "sdmmc_dma_buffer_t definition"); _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 *ctor;
void *dtor; void *dtor;
void *map_device_addr_space; void *map_device_addr_space;
@ -39,14 +41,18 @@ typedef struct sdmmc_accessor_vt {
// More not included because we don't use it. // More not included because we don't use it.
} sdmmc_accessor_vt_t; } sdmmc_accessor_vt_t;
typedef struct { _Static_assert(__alignof(sdmmc_accessor_vt_t) == 8, "sdmmc_accessor_vt_t definition");
typedef struct
{
void *vtab; void *vtab;
t210_sdmmc_t *io_map; t210_sdmmc_t *io_map;
sdmmc_dma_buffer_t dmaBuffers[3]; sdmmc_dma_buffer_t dmaBuffers[3];
// More not included because we don't use it. // More not included because we don't use it.
} mmc_obj_t; } mmc_obj_t;
typedef struct { typedef struct
{
sdmmc_accessor_vt_t *vtab; sdmmc_accessor_vt_t *vtab;
mmc_obj_t *parent; mmc_obj_t *parent;
// More not included because we don't use it. // More not included because we don't use it.

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_200_NINTENDO_PATHS \ #define FS_OFFSET_200_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_200_H__ #endif // __FS_200_H__

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_200_EXFAT_NINTENDO_PATHS \ #define FS_OFFSET_200_EXFAT_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_200_EXFAT_H__ #endif // __FS_200_EXFAT_H__

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_210_NINTENDO_PATHS \ #define FS_OFFSET_210_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_210_H__ #endif // __FS_210_H__

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_210_EXFAT_NINTENDO_PATHS \ #define FS_OFFSET_210_EXFAT_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_210_EXFAT_H__ #endif // __FS_210_EXFAT_H__

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_300_NINTENDO_PATHS \ #define FS_OFFSET_300_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_300_H__ #endif // __FS_300_H__

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_300_EXFAT_NINTENDO_PATHS \ #define FS_OFFSET_300_EXFAT_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_300_EXFAT_H__ #endif // __FS_300_EXFAT_H__

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_301_NINTENDO_PATHS \ #define FS_OFFSET_301_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_301_H__ #endif // __FS_301_H__

View file

@ -47,10 +47,10 @@
// Nintendo Paths // Nintendo Paths
#define FS_OFFSET_301_EXFAT_NINTENDO_PATHS \ #define FS_OFFSET_301_EXFAT_NINTENDO_PATHS \
{ \ { \
{.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 4}, \ {.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 0x0000000C}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
} }
#endif // __FS_301_EXFAT_H__ #endif // __FS_301_EXFAT_H__

View file

@ -23,9 +23,13 @@
#include "sd.h" #include "sd.h"
#include "../utils/types.h" #include "../utils/types.h"
#include "../utils/util.h" #include "../utils/util.h"
#include "../utils/fatal.h"
#define DPRINTF(...) //fprintf(stdout, __VA_ARGS__) #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) static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
{ {
const u32 mask = (size < 32 ? 1 << size : 0) - 1; 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. * 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) static int _sdmmc_storage_check_result(u32 res)
{ {
//Error mask: //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) 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_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_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.buf = buf;
reqbuf.num_sectors = num_sectors; reqbuf.num_sectors = num_sectors;
reqbuf.blksize = 512; 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; reqbuf.is_auto_cmd12 = 1;
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out)) if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out))
{ {
u32 tmp = 0;
sdmmc_stop_transmission(storage->sdmmc, &tmp); sdmmc_stop_transmission(storage->sdmmc, &tmp);
_sdmmc_storage_get_status(storage, &tmp, 0); _sdmmc_storage_get_status(storage, &tmp, 0);
return 0; return 0;
} }
return 1; return 1;
} }

View file

@ -19,6 +19,7 @@
#define _SDMMC_H_ #define _SDMMC_H_
#include "../utils/types.h" #include "../utils/types.h"
#include "../FS/FS.h"
#include "sdmmc_driver.h" #include "sdmmc_driver.h"
typedef struct _mmc_cid typedef struct _mmc_cid
@ -102,6 +103,9 @@ typedef struct _sdmmc_storage_t
sd_ssr_t ssr; sd_ssr_t ssr;
} sdmmc_storage_t; } 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_end(sdmmc_storage_t *storage);
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf); 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); 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_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_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); 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 #endif

View file

@ -27,6 +27,7 @@
#include "../soc/pmc.h" #include "../soc/pmc.h"
#include "../soc/pinmux.h" #include "../soc/pinmux.h"
#include "../soc/gpio.h" #include "../soc/gpio.h"
#include "../utils/fatal.h"
#define DPRINTF(...) #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) 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; bool should_enable_sd_clock = false;
if (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE) 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; u32 blkcnt = req->num_sectors;
if (blkcnt >= 0xFFFF) if (blkcnt >= 0xFFFF)
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. //Check alignment.
if (admaaddr & 7) if (admaaddr & 7)
@ -870,7 +896,22 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (req) if (req)
{ {
_sdmmc_config_dma(sdmmc, &blkcnt, 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); _sdmmc_enable_interrupts(sdmmc);
is_data_present = true; 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->expected_rsp_type = cmd->rsp_type;
_sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, 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); _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) 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) if (blkcnt_out)
*blkcnt_out = blkcnt; *blkcnt_out = blkcnt;

View file

@ -83,7 +83,7 @@ typedef struct _sdmmc_t
int venclkctl_set; int venclkctl_set;
u32 venclkctl_tap; u32 venclkctl_tap;
u32 expected_rsp_type; u32 expected_rsp_type;
u64 dma_addr_fs; u64 last_dma_idx;
u64 dma_addr_next; u64 dma_addr_next;
u32 rsp[4]; u32 rsp[4];
u32 rsp3; u32 rsp3;

View file

@ -24,6 +24,7 @@
#include "emummc.h" #include "emummc.h"
#include "emummc_ctx.h" #include "emummc_ctx.h"
static bool sdmmc_first_init = false;
static bool storageMMCinitialized = false; static bool storageMMCinitialized = false;
static bool storageSDinitialized = false; static bool storageSDinitialized = false;
@ -68,15 +69,25 @@ static void _sdmmc_ensure_device_attached(void)
static void _sdmmc_ensure_initialized(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; 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(); if (gpio_read(GPIO_PORT_E, GPIO_PIN_4) == 0)
sdmmc_initialize(); {
init_done = true; 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)); memset(&f_emu, 0, sizeof(file_based_ctxt));
memcpy(path, (void *)emuMMC_ctx.storagePath, sizeof(emuMMC_ctx.storagePath)); memcpy(path, (void *)emuMMC_ctx.storagePath, sizeof(emuMMC_ctx.storagePath));
strcat(path, "/eMMC"); strcat(path, "/eMMC/");
int path_len = strlen(path); int path_len = strlen(path);
// Open BOOT0 physical partition. // Open BOOT0 physical partition.
@ -188,23 +199,33 @@ bool sdmmc_initialize(void)
if (!storageSDinitialized) 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; if (sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11))
// File based emummc.
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted)
{ {
f_emu.sd_fs = (FATFS *)malloc(sizeof(FATFS)); storageSDinitialized = true;
if (f_mount(f_emu.sd_fs, "", 1) != FR_OK)
fatal_abort(Fatal_InitSD);
else
fat_mounted = 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); fatal_abort(Fatal_InitSD);
} }
@ -213,38 +234,6 @@ bool sdmmc_initialize(void)
return storageMMCinitialized && storageSDinitialized; 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 *sdmmc_accessor_get(int mmc_id)
{ {
sdmmc_accessor_t *_this; 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) if (mmc_id == FS_SDMMC_EMMC || mmc_id == FS_SDMMC_SD)
{ {
mutex_lock_handler(mmc_id); 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. // Make sure we're attached to the device address space.
_sdmmc_ensure_device_attached(); _sdmmc_ensure_device_attached();
// Make sure we're still initialized if boot killed sd card power. // 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) if (mmc_id == FS_SDMMC_EMMC)
{ {
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
// Call hekates driver. // Call hekates driver.
if (emummc_read_write_inner(buf, sector, num_sectors, false)) 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) if (mmc_id == FS_SDMMC_SD)
{ {
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
// Call hekates driver. // Call hekates driver.
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf)) 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) if (mmc_id == FS_SDMMC_EMMC)
{ {
mutex_lock_handler(mmc_id); mutex_lock_handler(mmc_id);
_current_accessor = _this;
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
// Call hekates driver. // Call hekates driver.
if (emummc_read_write_inner(buf, sector, num_sectors, true)) 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) if (mmc_id == FS_SDMMC_SD)
{ {
mutex_lock_handler(mmc_id); mutex_lock_handler(mmc_id);
_current_accessor = _this;
sector += 0; sector += 0;
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
// Call hekates driver. // Call hekates driver.
if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf)) if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf))

View file

@ -50,8 +50,6 @@ sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id);
void mutex_lock_handler(int mmc_id); void mutex_lock_handler(int mmc_id);
void mutex_unlock_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_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); uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize);

View file

@ -316,6 +316,4 @@ void __init()
populate_function_pointers(); populate_function_pointers();
write_nops(); write_nops();
setup_nintendo_paths(); setup_nintendo_paths();
sdmmc_initialize();
} }