Filesystem stuff

This commit is contained in:
wheremyfoodat 2022-10-09 15:59:09 +03:00
parent 5992a58351
commit 272cdefca1
13 changed files with 222 additions and 32 deletions

View file

@ -0,0 +1,61 @@
#pragma once
#include <optional>
#include "helpers.hpp"
#include "memory.hpp"
namespace PathType {
enum : u32 {
Invalid = 0,
Empty = 1,
Binary = 2,
ASCII = 3,
UTF8 = 4,
};
}
namespace ArchiveID {
enum : u32 {
SelfNCCH = 3,
SaveData = 4,
ExtSaveData = 6,
SharedExtSaveData = 7,
SystemSaveData = 8,
SDMC = 9,
SDMCWriteOnly = 0xA
};
static const char* toString(u32 id) {
switch (id) {
case SelfNCCH: return "SelfNCCH";
case SaveData: return "SaveData";
case ExtSaveData: return "ExtSaveData";
case SharedExtSaveData: return "SharedExtSaveData";
case SystemSaveData: return "SystemSaveData";
case SDMC: return "SDMC";
case SDMCWriteOnly: return "SDMC (Write-only)";
default: return "Unknown archive";
}
}
}
struct FSPath {
u32 type;
u32 size;
u32 pointer; // Pointer to the actual path data
};
class ArchiveBase {
protected:
using Result = u32;
using Handle = u32;
Memory& mem;
public:
virtual const char* name() = 0;
virtual u64 getFreeBytes() = 0;
virtual bool openFile(const FSPath& path) = 0;
virtual ArchiveBase* openArchive(FSPath& path) = 0;
ArchiveBase(Memory& mem) : mem(mem) {}
};

View file

@ -0,0 +1,28 @@
#include "archive_base.hpp"
class SelfNCCHArchive : public ArchiveBase {
public:
SelfNCCHArchive(Memory& mem) : ArchiveBase(mem) {}
u64 getFreeBytes() override { return 0; }
const char* name() override { return "SelfNCCH"; }
bool openFile(const FSPath& path) override {
if (path.type != PathType::Binary) {
printf("Invalid SelfNCCH path type");
return false;
}
return true;
}
ArchiveBase* openArchive(FSPath& path) override {
if (path.type != PathType::Empty) {
printf("Invalid path type for SelfNCCH archive: %d\n", path.type);
return nullptr;
}
return this;
}
};

View file

@ -55,16 +55,6 @@ class Kernel {
return &objects[handle];
}
Handle makeObject(KernelObjectType type) {
if (handleCounter > KernelHandles::Max) [[unlikely]] {
Helpers::panic("Hlep we somehow created enough kernel objects to overflow this thing");
}
objects.push_back(KernelObject(handleCounter, type));
log("Created %s object with handle %d\n", kernelObjectTypeToString(type), handleCounter);
return handleCounter++;
}
Handle makeArbiter();
Handle makeEvent(ResetType resetType);
Handle makeProcess(u32 id);
@ -118,11 +108,29 @@ class Kernel {
void outputDebugString();
void waitSynchronization1();
// File operations
void handleFileOperation(u32 messagePointer, Handle file);
void readFile(u32 messagePointer, Handle file);
public:
Kernel(CPU& cpu, Memory& mem, GPU& gpu);
void setVersion(u8 major, u8 minor);
void serviceSVC(u32 svc);
void reset();
Handle makeObject(KernelObjectType type) {
if (handleCounter > KernelHandles::Max) [[unlikely]] {
Helpers::panic("Hlep we somehow created enough kernel objects to overflow this thing");
}
objects.push_back(KernelObject(handleCounter, type));
log("Created %s object with handle %d\n", kernelObjectTypeToString(type), handleCounter);
return handleCounter++;
}
std::vector<KernelObject>& getObjects() {
return objects;
}
void sendGPUInterrupt(GPUInterrupt type) { serviceManager.requestGPUInterrupt(type); }
};

View file

@ -1,6 +1,7 @@
#pragma once
#include <array>
#include <cstring>
#include "fs/archive_base.hpp"
#include "handles.hpp"
#include "helpers.hpp"
@ -23,7 +24,7 @@ namespace SVCResult {
}
enum class KernelObjectType : u8 {
AddressArbiter, Event, Port, Process, ResourceLimit, Session, Thread, Dummy
AddressArbiter, Event, File, Port, Process, ResourceLimit, Session, Thread, Dummy
};
enum class ResourceLimitCategory : int {
@ -92,6 +93,15 @@ struct Session {
Session(Handle portHandle) : portHandle(portHandle) {}
};
struct FileSession {
ArchiveBase* archive = nullptr;
FSPath path;
FileSession(ArchiveBase* archive, const FSPath& filePath) : archive(archive) {
path = filePath;
}
};
enum class ThreadStatus {
Running, // Currently running
Ready, // Ready to run
@ -127,6 +137,7 @@ static const char* kernelObjectTypeToString(KernelObjectType t) {
switch (t) {
case KernelObjectType::AddressArbiter: return "address arbiter";
case KernelObjectType::Event: return "event";
case KernelObjectType::File: return "file";
case KernelObjectType::Port: return "port";
case KernelObjectType::Process: return "process";
case KernelObjectType::ResourceLimit: return "resource limit";

View file

@ -18,19 +18,20 @@ namespace Log {
};
// Our loggers here. Enable/disable by toggling the template param
static Logger<false> kernelLogger;
static Logger<true> kernelLogger;
static Logger<true> debugStringLogger; // Enables output for the outputDebugString SVC
static Logger<false> svcLogger;
static Logger<false> gpuLogger;
static Logger<true> errorLogger;
static Logger<true> svcLogger;
static Logger<true> gpuLogger;
// Service loggers
static Logger<false> aptLogger;
static Logger<false> fsLogger;
static Logger<false> hidLogger;
static Logger<false> gspGPULogger;
static Logger<false> gspLCDLogger;
static Logger<false> ndmLogger;
static Logger<false> srvLogger;
static Logger<true> aptLogger;
static Logger<true> fsLogger;
static Logger<true> hidLogger;
static Logger<true> gspGPULogger;
static Logger<true> gspLCDLogger;
static Logger<true> ndmLogger;
static Logger<true> srvLogger;
#define MAKE_LOG_FUNCTION(functionName, logger) \
template <typename... Args> \

View file

@ -1,21 +1,32 @@
#pragma once
#include "fs/archive_ncch.hpp"
#include "helpers.hpp"
#include "kernel_types.hpp"
#include "logger.hpp"
#include "memory.hpp"
// Yay, more circular dependencies
class Kernel;
class FSService {
Handle handle = KernelHandles::FS;
Memory& mem;
Kernel& kernel;
MAKE_LOG_FUNCTION(log, fsLogger)
SelfNCCHArchive selfNcch;
ArchiveBase* getArchiveFromID(u32 id);
std::optional<Handle> openFile(ArchiveBase* archive, const FSPath& path);
// Service commands
void initialize(u32 messagePointer);
void openArchive(u32 messagePointer);
void openFileDirectly(u32 messagePointer);
public:
FSService(Memory& mem) : mem(mem) {}
FSService(Memory& mem, Kernel& kernel) : mem(mem), selfNcch(mem), kernel(kernel) {}
void reset();
void handleSyncRequest(u32 messagePointer);
};

View file

@ -10,6 +10,8 @@
#include "services/gsp_lcd.hpp"
#include "services/ndm.hpp"
class Kernel;
class ServiceManager {
std::array<u32, 16>& regs;
Memory& mem;
@ -28,7 +30,7 @@ class ServiceManager {
void registerClient(u32 messagePointer);
public:
ServiceManager(std::array<u32, 16>& regs, Memory& mem, GPU& gpu, u32& currentPID);
ServiceManager(std::array<u32, 16>& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel);
void reset();
void handleSyncRequest(u32 messagePointer);