Skip to content

Commit

Permalink
Add stub code of fsp-srv
Browse files Browse the repository at this point in the history
  • Loading branch information
RKX1209 committed Jun 6, 2018
1 parent bbe4c66 commit 3d88811
Show file tree
Hide file tree
Showing 9 changed files with 883 additions and 730 deletions.
9 changes: 7 additions & 2 deletions Ipc.cpp
@@ -1,4 +1,5 @@
/* nsemu - LGPL - Copyright 2018 rkx1209<rkx1209dev@gmail.com> */
#define DEFINE_STUBS
#include "Nsemu.hpp"
#include "IpcStubs.hpp"

Expand Down Expand Up @@ -82,11 +83,15 @@ namespace IPC {

static uint32_t handle_id;
static SmService sm;
std::unordered_map<std::string, IpcService> services;
std::unordered_map<std::string, IpcService *> services;
bool is_domainobj = false;
std::unordered_map<uint32_t, IpcService *> handles;

void Initialize() {
#define SERVICE(str, iface) do { services[str] = new iface(); } while(0)

void InitIPC() {
sm.Initialize();
SERVICE_MAPPING(); // From IpcStubs.hpp
}

uint32_t NewHandle(IpcService *srv) {
Expand Down
156 changes: 156 additions & 0 deletions Ipcdefs/Fspsrv.def
@@ -0,0 +1,156 @@
type nn::fssrv::sf::SaveStruct = bytes<0x40>;
type nn::fssrv::sf::SaveCreateStruct = bytes<0x40>;
type nn::fssrv::sf::Partition = u32;

// --------------------------------------------- FSP-SRV ---------------------------------------------

interface nn::fssrv::sf::IFileSystemProxy is fsp-srv {
[1] Initialize(u64, pid);
[2] OpenDataFileSystemByCurrentProcess() -> object<nn::fssrv::sf::IFileSystem>;
[7] MountContent7(nn::ApplicationId tid, u32 ncaType) -> object<nn::fssrv::sf::IFileSystem>;
[8] MountContent(nn::ApplicationId tid, u32 flag, buffer<i8, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFileSystem> contentFs;
[9] OpenDataFileSystemByApplicationId(nn::ApplicationId tid) -> object<nn::fssrv::sf::IFileSystem> dataFiles;
[11] MountBis(nn::fssrv::sf::Partition partitionID, buffer<i8, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFileSystem> Bis;
[12] OpenBisPartition(nn::fssrv::sf::Partition partitionID) -> object<nn::fssrv::sf::IStorage> BisPartition;
[13] InvalidateBisCache();
[17] OpenHostFileSystemImpl(buffer<i8, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFileSystem>;
[18] MountSdCard() -> object<nn::fssrv::sf::IFileSystem> sdCard;
[19] FormatSdCard();
[21] DeleteSaveData(nn::ApplicationId tid);
[22] CreateSaveData(nn::fssrv::sf::SaveStruct saveStruct, nn::fssrv::sf::SaveCreateStruct saveCreate, u128 input);
[23] CreateSystemSaveData(nn::fssrv::sf::SaveStruct saveStruct, nn::fssrv::sf::SaveCreateStruct saveCreate);
[24] RegisterSaveDataAtomicDeletion(buffer<void, 5, 0>);
[25] DeleteSaveDataWithSpaceId(u8, u64);
[26] FormatSdCardDryRun();
[27] IsExFatSupported() -> u8 isSupported;
[30] OpenGameCardPartition(nn::fssrv::sf::Partition partitionID, u32) -> object<nn::fssrv::sf::IStorage> gameCardFs;
[31] MountGameCardPartition(u32, u32) -> object<nn::fssrv::sf::IFileSystem> gameCardPartitionFs;
[32] ExtendSaveData(u8, u64, u64, u64);
[51] MountSaveData(u8 input, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> saveDataFs;
[52] MountSystemSaveData(u8 input, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> systemSaveDataFs;
[53] MountSaveDataReadOnly(u8 input, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> saveDataFs;
[57] ReadSaveDataFileSystemExtraDataWithSpaceId (u8, u64) -> buffer<void, 6, 0>;
[58] ReadSaveDataFileSystemExtraData(u64) -> buffer<void, 6, 0>;
[59] WriteSaveDataFileSystemExtraData(u64, u8, buffer<void, 5, 0>);
[60] OpenSaveDataInfoReader() -> object<nn::fssrv::sf::ISaveDataInfoReader>;
[61] OpenSaveDataIterator(u8) -> object<IUnknown>;
[80] OpenSaveDataThumbnailFile(u8, bytes<0x40>, u32) -> object<nn::fssrv::sf::IFile> thumbnail;
[100] MountImageDirectory(u32) -> object<nn::fssrv::sf::IFileSystem> imageFs;
[110] MountContentStorage(u32 contentStorageID) -> object<nn::fssrv::sf::IFileSystem> contentFs;
[200] OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage;
[201] OpenDataStorageByApplicationId(nn::ApplicationId tid) -> object<nn::fssrv::sf::IStorage> dataStorage;
[202] OpenDataStorageByDataId(nn::ApplicationId tid, u8 storageId) -> object<nn::fssrv::sf::IStorage> dataStorage;
[203] OpenRomStorage() -> object<nn::fssrv::sf::IStorage>;
[400] OpenDeviceOperator() -> object<nn::fssrv::sf::IDeviceOperator>;
[500] OpenSdCardDetectionEventNotifier() -> object<nn::fssrv::sf::IEventNotifier> SdEventNotify;
[501] OpenGameCardDetectionEventNotifier() -> object<nn::fssrv::sf::IEventNotifier> GameCardEventNotify;
[600] SetCurrentPosixTime(u64 time);
[601] QuerySaveDataTotalSize(u64, u64) -> u64 saveDataSize;
[602] VerifySaveData(nn::ApplicationId tid) -> buffer<void, 6, 0>;
[603] CorruptSaveDataForDebug(nn::ApplicationId tid);
[604] CreatePaddingFile(u64 size);
[605] DeleteAllPaddingFiles();
[606] GetRightsId(u64, u8) -> u128 rights;
[607] RegisterExternalKey(u128, u128);
[608] UnregisterExternalKey();
[609] GetRightsIdByPath(buffer<i8, 0x19, 0x301> path) -> u128 rights;
[610] GetRightsIdByPath2(buffer<i8, 0x19, 0x301> path) -> (u128 rights, u8);
[620] SetSdCardEncryptionSeed(u128 seedmaybe);
[800] GetAndClearFileSystemProxyErrorInfo() -> bytes<0x80> errorInfo;
[1000] SetBisRootForHost(u32, buffer<i8, 0x19, 0x301> path);
[1001] SetSaveDataSize(u64, u64);
[1002] SetSaveDataRootPath(buffer<i8, 0x19, 0x301> path);
[1003] DisableAutoSaveDataCreation();
[1004] SetGlobalAccessLogMode(u32 mode);
[1005] GetGlobalAccessLogMode() -> u32 logMode;
[1006] OutputAccessLogToSdCard(buffer<void, 5, 0> logText);
}

interface nn::fssrv::sf::IStorage {
[0] Read(u64 offset, u64 length) -> buffer<i8, 0x46, 0> buffer;
[1] Write(u64 offset, u64 length, buffer<i8, 0x45, 0> data);
[2] Flush();
[3] SetSize(u64 size);
[4] GetSize() -> u64 size;
}

interface nn::fssrv::sf::IFileSystem {
[0] CreateFile(u64 mode, u32 size, buffer<i8, 0x19, 0x301> path);
[1] DeleteFile(buffer<i8, 0x19, 0x301> path);
[2] CreateDirectory(buffer<i8, 0x19, 0x301> path);
[3] DeleteDirectory(buffer<i8, 0x19, 0x301> path);
[4] DeleteDirectoryRecursively(buffer<i8, 0x19, 0x301> path);
[5] RenameFile(buffer<i8, 0x19, 0x301> oldPath, buffer<i8, 0x19, 0x301> newPath);
[6] RenameDirectory(buffer<i8, 0x19, 0x301> oldPath, buffer<i8, 0x19, 0x301> newPath);
[7] GetEntryType(buffer<i8, 0x19, 0x301> path) -> u32;
[8] OpenFile(u32 mode, buffer<i8, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFile> file;
[9] OpenDirectory(u32, buffer<i8, 0x19, 0x301> path) -> object<nn::fssrv::sf::IDirectory> directory;
[10] Commit();
[11] GetFreeSpaceSize(buffer<i8, 0x19, 0x301> path) -> u64 totalFreeSpace;
[12] GetTotalSpaceSize(buffer<i8, 0x19, 0x301> path) -> u64 totalSize;
[13] CleanDirectoryRecursively(buffer<i8, 0x19, 0x301> path);
[14] GetFileTimeStampRaw(buffer<i8, 0x19, 0x301> path) -> bytes<0x20> timestamp;
}

interface nn::fssrv::sf::IDeviceOperator {
[0] IsSdCardInserted() -> u8 isSdInserted;
[1] GetSdCardSpeedMode() -> u64 sdSpeed;
[2] GetSdCardCid(u64) -> buffer<unknown, 6, 0> cid;
[3] GetSdCardUserAreaSize() -> u64 size;
[4] GetSdCardProtectedAreaSize() -> u64 protectedSize;
[5] GetAndClearSdCardErrorInfo(u64) -> (u128, u64, buffer<unknown, 6, 0>);
[100] GetMmcCid(u64) -> buffer<unknown, 6, 0> cid;
[101] GetMmcSpeedMode() -> u64 speedMode;
[110] EraseMmc(u32);
[111] GetMmcPartitionSize(u32) -> u64 paritionSize;
[112] GetMmcPatrolCount() -> u32 patrolCount;
[113] GetAndClearMmcErrorInfo(u64) -> (u128, u64, buffer<unknown, 6, 0>);
[114] GetMmcExtendedCsd(u64) -> buffer<unknown, 6, 0>;
[200] IsGameCardInserted() -> u8 isGameInserted;
[201] EraseGameCard(u32, u64);
[202] GetGameCardHandle() -> u32 gamecardHandle;
[203] GetGameCardUpdatePartitionInfo(u32) -> (u32 version, nn::ApplicationId TID);
[204] FinalizeGameCardDriver();
[205] GetGameCardAttribute(u32) -> u8 attribute;
[206] GetGameCardDeviceCertificate(u64, u32) -> buffer<unknown, 6, 0> certificate;
[207] GetGameCardAsicInfo(u64, u64, buffer<unknown, 5, 0>) -> buffer<unknown, 6, 0>;
[208] GetGameCardIdSet(u64) -> buffer<unknown, 6, 0>;
[209] WriteToGameCard(u64, u64) -> buffer<unknown, 6, 0>;
[210] SetVerifyWriteEnalbleFlag(u8 flag);
[211] GetGameCardImageHash(u64, u32) -> buffer<unknown, 6, 0> imageHash;
[212] GetGameCardDeviceIdForProdCard(u64, u64, buffer<unknown, 5, 0>) -> buffer<unknown, 6, 0> errorInfo;
[213] EraseAndWriteParamDirectly(u64, buffer<unknown, 5, 0>);
[214] GetGameCardCid(u64) -> buffer<unknown, 6, 0> cid;
[215] ForceEraseGameCard();
[216] GetGameCardErrorInfo() -> u128 errorInfo;
[217] GetGameCardErrorReportInfo() -> bytes<0x40> errorReportInfo;
[218] GetGameCardDeviceId(u64) -> buffer<unknown, 6, 0> deviceID;
[300] SetSpeedEmulationMode(u32 mode);
[301] GetSpeedEmulationMode() -> u32 emuMode;
}

interface nn::fssrv::sf::IDirectory {
[0] Read() -> (u64, buffer<unknown, 6, 0>);
[1] GetEntryCount() -> u64;
}

interface nn::fssrv::sf::IFile {
[0] Read(u64, u64 offset, u32 size) -> (u64 out_size, buffer<i8, 0x46, 0> out_buf);
[1] Write(u64, u64 offset, u32 size, buffer<i8, 0x45, 0> buf);
[2] Flush();
[3] SetSize(u64 size);
[4] GetSize() -> u64 fileSize;
}

// --------------------------------------------- FSP-PR ---------------------------------------------
interface nn::fssrv::sf::IProgramRegistry {
[0] SetFsPermissions(u64, u64, u8, u64, u64, buffer<unknown, 5, 0>, buffer<unknown, 5, 0>);
[1] ClearFsPermissions(u64 pid);
[256] SetEnabledProgramVerification(u8 enabled);
}

// --------------------------------------------- FSP-LDR ---------------------------------------------
interface nn::fssrv::sf::IFileSystemProxyForLoader {
[0] MountCode(nn::ApplicationId TID, buffer<i8, 0x19, 0x301> contentPath) -> object<nn::fssrv::sf::IFileSystem> contentFs;
[1] IsCodeMounted(nn::ApplicationId TID) -> u8 isMounted;
}
6 changes: 4 additions & 2 deletions Makefile
Expand Up @@ -4,18 +4,20 @@ OBJ_FILES := $(SRC_FILES:.cpp=.o)
CXX_FLAGS := -std=gnu++1z -Iinclude -O3
LD_FLAGS := -llz4 -lpthread
MAKE := make
STUB := include/IpcStubs.hpp

all: nsemu
nsemu: $(OBJ_FILES)
nsemu: $(STUB) $(OBJ_FILES)
$(CXX) -o nsemu $(OBJ_FILES) $(LD_FLAGS)

%.o: %.cpp
$(CXX) $(CXX_FLAGS) -c -g -o $@ $<
testall:
$(MAKE) -C test/
distclean:
$(MAKE) clean -C test/
$(MAKE) clean
rm -f include/IpcStubs.h
rm -f $(STUB) Ipcdefs/cache
clean:
rm -f *.o */*.o
rm -f nsemu
1 change: 1 addition & 0 deletions Nsemu.cpp
Expand Up @@ -22,6 +22,7 @@ bool Nsemu::BootUp(const std::string& path) {
ns_print ("Booting... %s\n", path.c_str ());
Memory::InitMemmap (this);
LoadNso (this, path);
IPC::InitIPC();
cpu_thread = std::thread (CpuThread);
/* Run cpu */
cpu_thread.join ();
Expand Down
43 changes: 43 additions & 0 deletions Service/Fsp.cpp
@@ -0,0 +1,43 @@
/* nsemu - LGPL - Copyright 2018 rkx1209<rkx1209dev@gmail.com> */
#include "Nsemu.hpp"
#include "IpcStubs.hpp"

uint32_t nn::fssrv::sf::IFileSystemProxy::OpenBisPartition(nn::fssrv::sf::Partition partitionID, nn::fssrv::sf::IStorage* BisPartition) {
ns_print("Stub implementation for nn::fssrv::sf::IFileSystemProxy::OpenBisPartition\n");
//BisPartition = buildInterface(nn::fssrv::sf::IStorage, "bis.istorage");
return 0x0;
}

uint32_t nn::fssrv::sf::IFileSystemProxy::OpenDataStorageByApplicationId(nn::ApplicationId tid, nn::fssrv::sf::IStorage* dataStorage) {
ns_print("Stub implementation for nn::fssrv::sf::IFileSystemProxy::OpenDataStorageByApplicationId 0x%lx\n", tid);
std::stringstream ss;
ss << "tid_archives_" << hex << tid << ".istorage";
//dataStorage = buildInterface(nn::fssrv::sf::IStorage, ss.str());
return 0;
}

uint32_t nn::fssrv::sf::IFileSystemProxy::OpenDataStorageByCurrentProcess(nn::fssrv::sf::IStorage* dataStorage) {
ns_print("Stub implementation for nn::fssrv::sf::IFileSystemProxy::OpenDataStorageByCurrentProcess\n");
//dataStorage = buildInterface(nn::fssrv::sf::IStorage, "");
return 0;
}

uint32_t nn::fssrv::sf::IFileSystemProxy::OpenDataStorageByDataId(nn::ApplicationId tid, uint8_t storageId, nn::fssrv::sf::IStorage* dataStorage) {
ns_print("Stub implementation for nn::fssrv::sf::IFileSystemProxy::OpenDataStorageByDataId 0x%lx\n", 0x0100000000000800+(uint64_t)storageId);
std::stringstream ss;
ss << "archives/" << hex << setw(16) << setfill('0') << 0x0100000000000800+(uint64_t)storageId << ".istorage";
//dataStorage = buildInterface(nn::fssrv::sf::IStorage, ss.str());
return 0;
}

uint32_t nn::fssrv::sf::IFileSystemProxy::OpenGameCardPartition(nn::fssrv::sf::Partition partitionID, uint32_t _1, nn::fssrv::sf::IStorage* gameCardFs) {
ns_print("Stub implementation for nn::fssrv::sf::IFileSystemProxy::OpenGameCardPartition\n");
//gameCardFs = buildInterface(nn::fssrv::sf::IStorage, "GamePartition.istorage");
return 0;
}

uint32_t nn::fssrv::sf::IFileSystemProxy::OpenRomStorage(nn::fssrv::sf::IStorage* _0) {
ns_print("Stub implementation for nn::fssrv::sf::IFileSystemProxy::OpenRomStorage\n");
//_0 = buildInterface(nn::fssrv::sf::IStorage, "RomStorage.istorage");
return 0;
}
61 changes: 18 additions & 43 deletions Service/Sm.cpp
Expand Up @@ -5,60 +5,35 @@ uint32_t SmService::Initialize() {
return 0;
}

// uint32_t SmService::Dispatch(IpcMessage *req, IpcMessage *resp) {
// switch(req->cmd_id) {
// case 0: {
// resp->GenBuf(0, 0, 0);
// debug_print("IPC message to SmService::Dispatch\n");
// resp->error_code = Initialize();
// return 0;
// }
// case 1: {
// resp->GenBuf(1, 0, 0);
// IpcService service;
// std::string name = ARMv8::ReadString(req->GetDataPointer<uint64_t >(8));
// debug_print("IPC message to SmService::GetService: ServiceName name = %s\n", name.c_str());
// resp->error_code = GetService(name, &service);
// if(!resp->error_code)
// resp->SetMove(0, IPC::NewHandle(&service));
// return 0;
// }
// case 2: {
// resp->GenBuf(1, 0, 0);
// IpcService service;
// std::string name = ARMv8::ReadString(req->GetDataPointer<uint64_t>(8));
// debug_print("[TODO] IPC message to SmService::RegisterService: ServiceName name = %s\n", name.c_str());
// /* TODO: Currently hombrew applications with libtransistor doesn't use RegisterService message. */
// resp->error_code = RegisterService(name, &service);
// if(!resp->error_code)
// resp->SetMove(0, IPC::NewHandle(&service));
// return 0;
// }
// case 3: {
// resp->GenBuf(0, 0, 0);
// std::string name = ARMv8::ReadString(req->GetDataPointer<uint64_t>(8));
// debug_print("[TODO] IPC message to SmService::UnregisterService: ServiceName name = %s\n", name.c_str());
// /* TODO: */
// //resp.error_code = UnregisterService(req.GetDataPointer<ServiceName>(8));
// return 0;
// }
// default:
// ns_abort("Unknown message cmdId %u to interface SmService", req->cmd_id);
// }
// }
uint32_t SmService::GetService(ServiceName _name, IpcService *service) {
std::string name = (char *) _name;
if (IPC::services.find(name) == IPC::services.end()) {
ns_print("Unknown service name %s\n", name.c_str());
return 0xC15; //error code
}
service = &IPC::services[name];
service = IPC::services[name];
return 0;
}

uint32_t SmService::RegisterService(ServiceName _name, IpcService *service) {
std::string name = (char *) _name;
IpcService *new_srv = new IpcService();
debug_print("Registering service %s\n", _name);
IPC::services[name] = new_srv;
service = new_srv;
return 0;
}
uint32_t SmService::UnregisterService(ServiceName _name) {

uint32_t SmService::UnregisterService(ServiceName _name) {
std::string name = (char *) _name;
auto it = IPC::services.find(name);
if (it == IPC::services.end()) {
ns_print("Unknown service name %s\n", _name);
return 0xC15; //error code
}
IpcService *srv = it->second;
debug_print("Unregistering service %s\n", _name);
delete srv;
IPC::services.erase(it);
return 0;
}
4 changes: 2 additions & 2 deletions include/Ipc.hpp
Expand Up @@ -117,11 +117,11 @@ class IUnknown : public IpcService {

namespace IPC {

extern std::unordered_map<std::string, IpcService> services;
extern std::unordered_map<std::string, IpcService*> services;
extern std::unordered_map<uint32_t, IpcService *> handles;
extern bool is_domainobj;

void Initialize();
void InitIPC();

uint32_t NewHandle(IpcService *srv);

Expand Down

0 comments on commit 3d88811

Please sign in to comment.