mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-28 01:20:58 +01:00
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:
parent
63a9c856fc
commit
0468bd9483
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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__
|
||||
|
@ -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__
|
||||
|
@ -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__
|
||||
|
@ -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__
|
||||
|
@ -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__
|
||||
|
@ -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__
|
||||
|
@ -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__
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
@ -141,11 +221,11 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
||||
|
@ -316,6 +316,4 @@ void __init()
|
||||
populate_function_pointers();
|
||||
write_nops();
|
||||
setup_nintendo_paths();
|
||||
|
||||
sdmmc_initialize();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user