Skip to content

Commit 6805c9d

Browse files
authored
Merge pull request #11108 from AdmiralCurtiss/fat-fs-callbacks
FatFsUtil: Add ability to provide callbacks for the FatFs code.
2 parents 0c19a1d + 3182d91 commit 6805c9d

2 files changed

Lines changed: 132 additions & 29 deletions

File tree

Source/Core/Common/FatFsUtil.cpp

Lines changed: 114 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,30 +33,21 @@ enum : u32
3333
};
3434

3535
static std::mutex s_fatfs_mutex;
36-
static File::IOFile* s_image;
37-
static bool s_deterministic;
36+
static Common::FatFsCallbacks* s_callbacks;
3837

39-
extern "C" DSTATUS disk_status(BYTE pdrv)
40-
{
41-
return 0;
42-
}
43-
44-
extern "C" DSTATUS disk_initialize(BYTE pdrv)
38+
namespace
4539
{
46-
return 0;
47-
}
48-
49-
extern "C" DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
40+
int SDCardDiskRead(File::IOFile* image, u8 pdrv, u8* buff, u32 sector, unsigned int count)
5041
{
5142
const u64 offset = static_cast<u64>(sector) * SECTOR_SIZE;
52-
if (!s_image->Seek(offset, File::SeekOrigin::Begin))
43+
if (!image->Seek(offset, File::SeekOrigin::Begin))
5344
{
5445
ERROR_LOG_FMT(COMMON, "SD image seek failed (offset={})", offset);
5546
return RES_ERROR;
5647
}
5748

5849
const size_t size = static_cast<size_t>(count) * SECTOR_SIZE;
59-
if (!s_image->ReadBytes(buff, size))
50+
if (!image->ReadBytes(buff, size))
6051
{
6152
ERROR_LOG_FMT(COMMON, "SD image read failed (offset={}, size={})", offset, size);
6253
return RES_ERROR;
@@ -65,17 +56,17 @@ extern "C" DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
6556
return RES_OK;
6657
}
6758

68-
extern "C" DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count)
59+
int SDCardDiskWrite(File::IOFile* image, u8 pdrv, const u8* buff, u32 sector, unsigned int count)
6960
{
7061
const u64 offset = static_cast<u64>(sector) * SECTOR_SIZE;
71-
if (!s_image->Seek(offset, File::SeekOrigin::Begin))
62+
if (!image->Seek(offset, File::SeekOrigin::Begin))
7263
{
7364
ERROR_LOG_FMT(COMMON, "SD image seek failed (offset={})", offset);
7465
return RES_ERROR;
7566
}
7667

7768
const size_t size = static_cast<size_t>(count) * SECTOR_SIZE;
78-
if (!s_image->WriteBytes(buff, size))
69+
if (!image->WriteBytes(buff, size))
7970
{
8071
ERROR_LOG_FMT(COMMON, "SD image write failed (offset={}, size={})", offset, size);
8172
return RES_ERROR;
@@ -84,26 +75,23 @@ extern "C" DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT co
8475
return RES_OK;
8576
}
8677

87-
extern "C" DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
78+
int SDCardDiskIOCtl(File::IOFile* image, u8 pdrv, u8 cmd, void* buff)
8879
{
8980
switch (cmd)
9081
{
9182
case CTRL_SYNC:
9283
return RES_OK;
9384
case GET_SECTOR_COUNT:
94-
*reinterpret_cast<LBA_t*>(buff) = s_image->GetSize() / SECTOR_SIZE;
85+
*reinterpret_cast<LBA_t*>(buff) = image->GetSize() / SECTOR_SIZE;
9586
return RES_OK;
9687
default:
9788
WARN_LOG_FMT(COMMON, "Unexpected SD image ioctl {}", cmd);
9889
return RES_OK;
9990
}
10091
}
10192

102-
extern "C" DWORD get_fattime(void)
93+
u32 GetSystemTimeFAT()
10394
{
104-
if (s_deterministic)
105-
return 0;
106-
10795
const std::time_t time = std::time(nullptr);
10896
std::tm tm;
10997
#ifdef _WIN32
@@ -121,6 +109,91 @@ extern "C" DWORD get_fattime(void)
121109
fattime |= std::min(tm.tm_sec, 59) >> 1;
122110
return fattime;
123111
}
112+
} // namespace
113+
114+
namespace Common
115+
{
116+
FatFsCallbacks::FatFsCallbacks() = default;
117+
FatFsCallbacks::~FatFsCallbacks() = default;
118+
119+
u8 FatFsCallbacks::DiskInitialize(u8 pdrv)
120+
{
121+
return 0;
122+
}
123+
124+
u8 FatFsCallbacks::DiskStatus(u8 pdrv)
125+
{
126+
return 0;
127+
}
128+
129+
u32 FatFsCallbacks::GetCurrentTimeFAT()
130+
{
131+
return GetSystemTimeFAT();
132+
}
133+
} // namespace Common
134+
135+
namespace
136+
{
137+
class SDCardFatFsCallbacks : public Common::FatFsCallbacks
138+
{
139+
public:
140+
int DiskRead(u8 pdrv, u8* buff, u32 sector, unsigned int count) override
141+
{
142+
return SDCardDiskRead(m_image, pdrv, buff, sector, count);
143+
}
144+
145+
int DiskWrite(u8 pdrv, const u8* buff, u32 sector, unsigned int count) override
146+
{
147+
return SDCardDiskWrite(m_image, pdrv, buff, sector, count);
148+
}
149+
150+
int DiskIOCtl(u8 pdrv, u8 cmd, void* buff) override
151+
{
152+
return SDCardDiskIOCtl(m_image, pdrv, cmd, buff);
153+
}
154+
155+
u32 GetCurrentTimeFAT() override
156+
{
157+
if (m_deterministic)
158+
return 0;
159+
160+
return GetSystemTimeFAT();
161+
}
162+
163+
File::IOFile* m_image;
164+
bool m_deterministic;
165+
};
166+
} // namespace
167+
168+
extern "C" DSTATUS disk_status(BYTE pdrv)
169+
{
170+
return static_cast<DSTATUS>(s_callbacks->DiskStatus(pdrv));
171+
}
172+
173+
extern "C" DSTATUS disk_initialize(BYTE pdrv)
174+
{
175+
return static_cast<DSTATUS>(s_callbacks->DiskInitialize(pdrv));
176+
}
177+
178+
extern "C" DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
179+
{
180+
return static_cast<DRESULT>(s_callbacks->DiskRead(pdrv, buff, sector, count));
181+
}
182+
183+
extern "C" DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count)
184+
{
185+
return static_cast<DRESULT>(s_callbacks->DiskWrite(pdrv, buff, sector, count));
186+
}
187+
188+
extern "C" DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
189+
{
190+
return static_cast<DRESULT>(s_callbacks->DiskIOCtl(pdrv, cmd, buff));
191+
}
192+
193+
extern "C" DWORD get_fattime(void)
194+
{
195+
return static_cast<DWORD>(s_callbacks->GetCurrentTimeFAT());
196+
}
124197

125198
extern "C" void* ff_memalloc(UINT msize)
126199
{
@@ -435,11 +508,13 @@ bool SyncSDFolderToSDImage(bool deterministic)
435508
size = AlignUp(size, MAX_CLUSTER_SIZE);
436509

437510
std::lock_guard lk(s_fatfs_mutex);
511+
SDCardFatFsCallbacks callbacks;
512+
s_callbacks = &callbacks;
513+
Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr; }};
438514

439515
File::IOFile image;
440-
s_image = &image;
441-
Common::ScopeGuard image_guard{[] { s_image = nullptr; }};
442-
s_deterministic = deterministic;
516+
callbacks.m_image = &image;
517+
callbacks.m_deterministic = deterministic;
443518

444519
const std::string temp_image_path = File::GetTempFilenameForAtomicWrite(image_path);
445520
if (!image.Open(temp_image_path, "w+b"))
@@ -672,17 +747,19 @@ bool SyncSDImageToSDFolder()
672747
return false;
673748

674749
std::lock_guard lk(s_fatfs_mutex);
750+
SDCardFatFsCallbacks callbacks;
751+
s_callbacks = &callbacks;
752+
Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr; }};
675753

676754
INFO_LOG_FMT(COMMON, "Starting SD card conversion from file {} to folder {}", image_path,
677755
target_dir);
678756

679757
File::IOFile image;
680-
s_image = &image;
681-
Common::ScopeGuard image_guard{[] { s_image = nullptr; }};
758+
callbacks.m_image = &image;
682759

683760
// this shouldn't matter since we're not modifying the SD image here, but initialize it to
684761
// something consistent just in case
685-
s_deterministic = true;
762+
callbacks.m_deterministic = true;
686763

687764
if (!image.Open(image_path, "r+b"))
688765
{
@@ -740,4 +817,12 @@ bool SyncSDImageToSDFolder()
740817
INFO_LOG_FMT(COMMON, "Successfully unpacked SD image {} to {}", image_path, target_dir);
741818
return true;
742819
}
820+
821+
void RunInFatFsContext(FatFsCallbacks& callbacks, const std::function<void()>& function)
822+
{
823+
std::lock_guard lk(s_fatfs_mutex);
824+
s_callbacks = &callbacks;
825+
Common::ScopeGuard callbacks_guard{[] { s_callbacks = nullptr; }};
826+
function();
827+
}
743828
} // namespace Common

Source/Core/Common/FatFsUtil.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,28 @@
33

44
#pragma once
55

6+
#include <functional>
7+
68
#include "Common/CommonTypes.h"
79

810
namespace Common
911
{
1012
bool SyncSDFolderToSDImage(bool deterministic);
1113
bool SyncSDImageToSDFolder();
14+
15+
class FatFsCallbacks
16+
{
17+
public:
18+
FatFsCallbacks();
19+
virtual ~FatFsCallbacks();
20+
21+
virtual u8 DiskInitialize(u8 pdrv);
22+
virtual u8 DiskStatus(u8 pdrv);
23+
virtual int DiskRead(u8 pdrv, u8* buff, u32 sector, unsigned int count) = 0;
24+
virtual int DiskWrite(u8 pdrv, const u8* buff, u32 sector, unsigned int count) = 0;
25+
virtual int DiskIOCtl(u8 pdrv, u8 cmd, void* buff) = 0;
26+
virtual u32 GetCurrentTimeFAT();
27+
};
28+
29+
void RunInFatFsContext(FatFsCallbacks& callbacks, const std::function<void()>& function);
1230
} // namespace Common

0 commit comments

Comments
 (0)