Compare commits

...

24 Commits

Author SHA1 Message Date
bunnei
494275fd38 nvflinger: Remove superfluous buffer format check. 2018-03-16 20:11:50 -04:00
bunnei
e7ba2a4447 Merge pull request #232 from bunnei/heap-fixes
Various heap fixes for libtransistor
2018-03-16 20:06:27 -04:00
bunnei
cc6f22e0e4 process: MirrorMemory should use MemoryState::Mapped. 2018-03-16 19:24:54 -04:00
bunnei
e9a857ce82 process: Unmap previously allocated heap. 2018-03-16 18:32:25 -04:00
bunnei
403f8e79ea arm_interface: Support unmapping previously mapped memory. 2018-03-16 18:32:24 -04:00
bunnei
34a29ad051 svc: Use more correct values for GetInfo MapRegion and NewMapRegion. 2018-03-16 18:32:23 -04:00
bunnei
8581404482 kernel: Move stack region outside of application heap. 2018-03-16 18:32:23 -04:00
bunnei
69ee9edd8d memory: Add regions for map region, "new" map region, etc. 2018-03-16 18:32:22 -04:00
bunnei
3923b0f589 process: Fix stack memory state. 2018-03-16 18:32:21 -04:00
bunnei
8be7131033 MemoryState: Add additional memory states and improve naming. 2018-03-16 18:32:21 -04:00
bunnei
07ae1f972d Merge pull request #237 from mailwl/nifm-module
Service/NIFM: convert to module
2018-03-16 18:26:02 -04:00
mailwl
fbfa7ddd62 IGeneralService: fix function list 2018-03-16 16:34:12 +03:00
mailwl
9289255314 Service/NIFM: stub cancel function 2018-03-16 11:08:22 +03:00
mailwl
ec030a542f Service/NIFM: convert to module 2018-03-16 11:00:29 +03:00
bunnei
cde9386e0f Merge pull request #236 from bunnei/refactor-process-creation
core: Move process creation out of global state.
2018-03-14 19:33:27 -04:00
bunnei
7d6653268f core: Move process creation out of global state. 2018-03-14 18:42:19 -04:00
bunnei
8538e0bc3d Merge pull request #213 from Hexagon12/dynarmic-default
Make Dynarmic the default CPU core
2018-03-07 18:21:13 -05:00
bunnei
5750f6f046 Merge pull request #230 from Subv/gpu_draw
GPU: Intercept writes to the VERTEX_END_GL register.
2018-03-05 09:58:58 -05:00
Subv
5fb4c718cc GPU: Intercept writes to the VERTEX_END_GL register.
This is the register that gets written after a game calls DrawArrays().

We should collect all GPU state and draw using our graphics API here.
2018-03-04 19:14:04 -05:00
bunnei
80562aaf64 Merge pull request #229 from Subv/ensuresavedata_impl
FS: Make EnsureSaveData create the save data if it doesn't already exist.
2018-03-04 15:49:42 -05:00
Subv
84e1c0a430 FS: Use the correct error code when trying to open files that don't exist. 2018-03-04 14:34:48 -05:00
Subv
e4b7a1d160 FS: Stubbed CreateSaveData. It currently does nothing. 2018-03-04 14:31:57 -05:00
Subv
0eefe6e4d1 FS: Make EnsureSaveData create the savedata folder when called for the first time. 2018-03-04 14:30:07 -05:00
Hexagon12
a8d8c21e00 pls, that was easy 2018-02-14 19:47:51 +02:00
53 changed files with 390 additions and 325 deletions

View File

@@ -39,8 +39,12 @@ public:
Run(1);
}
/// Maps a backing memory region for the CPU
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) {}
Kernel::VMAPermission perms) = 0;
/// Unmaps a region of memory that was previously mapped using MapBackingMemory
virtual void UnmapMemory(VAddr address, size_t size) = 0;
/// Clear all instruction cache
virtual void ClearInstructionCache() = 0;

View File

@@ -8,6 +8,7 @@
#include <dynarmic/A64/config.h>
#include "common/logging/log.h"
#include "core/arm/dynarmic/arm_dynarmic.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/svc.h"
@@ -106,7 +107,7 @@ public:
};
std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_Callbacks>& cb) {
const auto page_table = Kernel::g_current_process->vm_manager.page_table.pointers.data();
const auto page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data();
Dynarmic::A64::UserConfig config;
config.callbacks = cb.get();
@@ -135,6 +136,10 @@ void ARM_Dynarmic::MapBackingMemory(u64 address, size_t size, u8* memory,
inner_unicorn.MapBackingMemory(address, size, memory, perms);
}
void ARM_Dynarmic::UnmapMemory(u64 address, size_t size) {
inner_unicorn.UnmapMemory(address, size);
}
void ARM_Dynarmic::SetPC(u64 pc) {
jit->SetPC(pc);
}

View File

@@ -19,7 +19,7 @@ public:
void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) override;
void UnmapMemory(u64 address, size_t size) override;
void SetPC(u64 pc) override;
u64 GetPC() const override;
u64 GetReg(int index) const override;

View File

@@ -77,6 +77,10 @@ void ARM_Unicorn::MapBackingMemory(VAddr address, size_t size, u8* memory,
CHECKED(uc_mem_map_ptr(uc, address, size, static_cast<u32>(perms), memory));
}
void ARM_Unicorn::UnmapMemory(VAddr address, size_t size) {
CHECKED(uc_mem_unmap(uc, address, size));
}
void ARM_Unicorn::SetPC(u64 pc) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &pc));
}

View File

@@ -14,6 +14,7 @@ public:
~ARM_Unicorn();
void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) override;
void UnmapMemory(VAddr address, size_t size) override;
void SetPC(u64 pc) override;
u64 GetPC() const override;
u64 GetReg(int index) const override;

View File

@@ -100,7 +100,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
return init_result;
}
const Loader::ResultStatus load_result{app_loader->Load(Kernel::g_current_process)};
const Loader::ResultStatus load_result{app_loader->Load(current_process)};
if (Loader::ResultStatus::Success != load_result) {
LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result);
System::Shutdown();
@@ -141,6 +141,8 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
CoreTiming::Init();
current_process = Kernel::Process::Create("main");
switch (Settings::values.cpu_core) {
case Settings::CpuCore::Unicorn:
cpu_core = std::make_shared<ARM_Unicorn>();

View File

@@ -7,6 +7,7 @@
#include <memory>
#include <string>
#include "common/common_types.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/scheduler.h"
#include "core/loader/loader.h"
#include "core/memory.h"
@@ -112,6 +113,10 @@ public:
return *scheduler;
}
Kernel::SharedPtr<Kernel::Process>& CurrentProcess() {
return current_process;
}
PerfStats perf_stats;
FrameLimiter frame_limiter;
@@ -149,6 +154,8 @@ private:
std::unique_ptr<Kernel::Scheduler> scheduler;
std::unique_ptr<Tegra::GPU> gpu_core;
Kernel::SharedPtr<Kernel::Process> current_process;
/// When true, signals that a reschedule should happen
bool reschedule_pending{};
@@ -169,4 +176,8 @@ inline TelemetrySession& Telemetry() {
return System::GetInstance().TelemetrySession();
}
inline Kernel::SharedPtr<Kernel::Process>& CurrentProcess() {
return System::GetInstance().CurrentProcess();
}
} // namespace Core

View File

@@ -7,6 +7,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/disk_filesystem.h"
#include "core/file_sys/errors.h"
namespace FileSys {
@@ -22,8 +23,7 @@ ResultVal<std::unique_ptr<StorageBackend>> Disk_FileSystem::OpenFile(const std::
auto file = std::make_shared<FileUtil::IOFile>(full_path, mode == Mode::Read ? "rb" : "wb");
if (!file->IsOpen()) {
// TODO(Subv): Find out the correct error code.
return ResultCode(-1);
return ERROR_PATH_NOT_FOUND;
}
return MakeResult<std::unique_ptr<StorageBackend>>(
@@ -100,8 +100,7 @@ u64 Disk_FileSystem::GetFreeSpaceSize() const {
ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& path) const {
std::string full_path = base_directory + path;
if (!FileUtil::Exists(full_path)) {
// TODO(Subv): Find out what this actually means
return ResultCode(ErrorModule::FS, 1);
return ERROR_PATH_NOT_FOUND;
}
// TODO(Subv): Find out the EntryType values

View File

@@ -10,36 +10,17 @@ namespace FileSys {
namespace ErrCodes {
enum {
RomFSNotFound = 100,
ArchiveNotMounted = 101,
FileNotFound = 112,
PathNotFound = 113,
GameCardNotInserted = 141,
NotFound = 120,
FileAlreadyExists = 180,
DirectoryAlreadyExists = 185,
AlreadyExists = 190,
InvalidOpenFlags = 230,
DirectoryNotEmpty = 240,
NotAFile = 250,
NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
ExeFSSectionNotFound = 567,
CommandNotAllowed = 630,
InvalidReadFlag = 700,
InvalidPath = 702,
WriteBeyondEnd = 705,
UnsupportedOpenFlags = 760,
IncorrectExeFSReadSize = 761,
UnexpectedFileOrDirectory = 770,
NotFound = 1,
};
}
constexpr ResultCode ERROR_PATH_NOT_FOUND(ErrorModule::FS, ErrCodes::NotFound);
// TODO(bunnei): Replace these with correct errors for Switch OS
constexpr ResultCode ERROR_INVALID_PATH(ResultCode(-1));
constexpr ResultCode ERROR_UNSUPPORTED_OPEN_FLAGS(ResultCode(-1));
constexpr ResultCode ERROR_INVALID_OPEN_FLAGS(ResultCode(-1));
constexpr ResultCode ERROR_FILE_NOT_FOUND(ResultCode(-1));
constexpr ResultCode ERROR_PATH_NOT_FOUND(ResultCode(-1));
constexpr ResultCode ERROR_UNEXPECTED_FILE_OR_DIRECTORY(ResultCode(-1));
constexpr ResultCode ERROR_DIRECTORY_ALREADY_EXISTS(ResultCode(-1));
constexpr ResultCode ERROR_FILE_ALREADY_EXISTS(ResultCode(-1));

View File

@@ -183,10 +183,9 @@ public:
/**
* Deletes the archive contents and then re-creates the base folder
* @param path Path to the archive
* @param format_info Format information for the new archive
* @return ResultCode of the operation, 0 on success
*/
virtual ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) = 0;
virtual ResultCode Format(const Path& path) = 0;
/**
* Retrieves the format info about the archive with the specified path

View File

@@ -23,7 +23,7 @@ ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& pa
return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive));
}
ResultCode RomFS_Factory::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) {
ResultCode RomFS_Factory::Format(const Path& path) {
LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
// TODO(bunnei): Find the right error code for this
return ResultCode(-1);

View File

@@ -23,7 +23,7 @@ public:
return "ArchiveFactory_RomFS";
}
ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
ResultCode Format(const Path& path) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
private:

View File

@@ -7,6 +7,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/file_sys/disk_filesystem.h"
#include "core/file_sys/savedata_factory.h"
#include "core/hle/kernel/process.h"
@@ -17,20 +18,26 @@ SaveData_Factory::SaveData_Factory(std::string nand_directory)
: nand_directory(std::move(nand_directory)) {}
ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& path) {
u64 title_id = Kernel::g_current_process->program_id;
// TODO(Subv): Somehow obtain this value.
u32 user = 0;
std::string save_directory = Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X",
nand_directory.c_str(), title_id, user);
std::string save_directory = GetFullPath();
// Return an error if the save data doesn't actually exist.
if (!FileUtil::IsDirectory(save_directory)) {
// TODO(Subv): Find out correct error code.
return ResultCode(-1);
}
auto archive = std::make_unique<Disk_FileSystem>(save_directory);
return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive));
}
ResultCode SaveData_Factory::Format(const Path& path,
const FileSys::ArchiveFormatInfo& format_info) {
LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
// TODO(bunnei): Find the right error code for this
return ResultCode(-1);
ResultCode SaveData_Factory::Format(const Path& path) {
LOG_WARNING(Service_FS, "Format archive %s", GetName().c_str());
// Create the save data directory.
if (!FileUtil::CreateFullPath(GetFullPath())) {
// TODO(Subv): Find the correct error code.
return ResultCode(-1);
}
return RESULT_SUCCESS;
}
ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const {
@@ -39,4 +46,12 @@ ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) c
return ResultCode(-1);
}
std::string SaveData_Factory::GetFullPath() const {
u64 title_id = Core::CurrentProcess()->program_id;
// TODO(Subv): Somehow obtain this value.
u32 user = 0;
return Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X/", nand_directory.c_str(), title_id,
user);
}
} // namespace FileSys

View File

@@ -21,11 +21,13 @@ public:
return "SaveData_Factory";
}
ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
ResultCode Format(const Path& path) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
private:
std::string nand_directory;
std::string GetFullPath() const;
};
} // namespace FileSys

View File

@@ -5,6 +5,7 @@
#include <utility>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
@@ -77,7 +78,7 @@ SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
if (handle == CurrentThread) {
return GetCurrentThread();
} else if (handle == CurrentProcess) {
return g_current_process;
return Core::CurrentProcess();
}
if (!IsValid(handle)) {

View File

@@ -41,7 +41,6 @@ void Shutdown() {
g_object_address_table.Clear();
Kernel::ThreadingShutdown();
g_current_process = nullptr;
Kernel::TimersShutdown();
Kernel::ResourceLimitsShutdown();

View File

@@ -33,10 +33,6 @@ enum class HandleType : u32 {
ServerSession,
};
enum {
DEFAULT_STACK_SIZE = 0x10000,
};
enum class ResetType {
OneShot,
Sticky,

View File

@@ -31,14 +31,14 @@ CodeSet::~CodeSet() {}
u32 Process::next_process_id;
SharedPtr<Process> Process::Create(std::string&& name, u64 program_id) {
SharedPtr<Process> Process::Create(std::string&& name) {
SharedPtr<Process> process(new Process);
process->name = std::move(name);
process->flags.raw = 0;
process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
process->status = ProcessStatus::Created;
process->program_id = program_id;
process->program_id = 0;
process_list.push_back(process);
return process;
@@ -117,11 +117,12 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
}
void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
// Allocate and map stack
// Allocate and map the main thread stack
// TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part
// of the user address space.
vm_manager
.MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size,
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
MemoryState::Heap)
.MapMemoryBlock(Memory::STACK_VADDR, std::make_shared<std::vector<u8>>(stack_size, 0), 0,
stack_size, MemoryState::Mapped)
.Unwrap();
misc_memory_used += stack_size;
memory_region->used += stack_size;
@@ -153,9 +154,9 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
};
// Map CodeSet segments
MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::Code);
MapSegment(module_->rodata, VMAPermission::Read, MemoryState::Static);
MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::Static);
MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic);
MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable);
MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
}
VAddr Process::GetLinearHeapAreaAddress() const {
@@ -182,6 +183,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
// Initialize heap
heap_memory = std::make_shared<std::vector<u8>>();
heap_start = heap_end = target;
} else {
vm_manager.UnmapRange(heap_start, heap_end - heap_start);
}
// If necessary, expand backing vector to cover new heap extents.
@@ -201,7 +204,7 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
size, MemoryState::Heap));
vm_manager.Reprotect(vma, perms);
heap_used += size;
heap_used = size;
memory_region->used += size;
return MakeResult<VAddr>(heap_end - size);
@@ -288,7 +291,7 @@ ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
CASCADE_RESULT(auto new_vma,
vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size,
vma->second.meminfo_state));
MemoryState::Mapped));
// Protect mirror with permissions from old region
vm_manager.Reprotect(new_vma, vma->second.permissions);
// Remove permissions from old region
@@ -319,5 +322,4 @@ SharedPtr<Process> GetProcessById(u32 process_id) {
return *itr;
}
SharedPtr<Process> g_current_process;
} // namespace Kernel

View File

@@ -95,7 +95,7 @@ private:
class Process final : public Object {
public:
static SharedPtr<Process> Create(std::string&& name, u64 program_id);
static SharedPtr<Process> Create(std::string&& name);
std::string GetTypeName() const override {
return "Process";
@@ -203,5 +203,4 @@ void ClearProcessList();
/// Retrieves a process from the current list of processes.
SharedPtr<Process> GetProcessById(u32 process_id);
extern SharedPtr<Process> g_current_process;
} // namespace Kernel

View File

@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/scheduler.h"
@@ -67,7 +68,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
// Cancel any outstanding wakeup events for this thread
new_thread->CancelWakeupTimer();
auto previous_process = Kernel::g_current_process;
auto previous_process = Core::CurrentProcess();
current_thread = new_thread;
@@ -75,8 +76,8 @@ void Scheduler::SwitchContext(Thread* new_thread) {
new_thread->status = THREADSTATUS_RUNNING;
if (previous_process != current_thread->owner_process) {
Kernel::g_current_process = current_thread->owner_process;
SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
Core::CurrentProcess() = current_thread->owner_process;
SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
}
cpu_core->LoadContext(new_thread->context);

View File

@@ -4,6 +4,7 @@
#include <tuple>
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
@@ -91,7 +92,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
Kernel::HLERequestContext context(this);
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process,
context.PopulateFromIncomingCommandBuffer(cmd_buf, *Core::CurrentProcess(),
Kernel::g_handle_table);
ResultCode result = RESULT_SUCCESS;

View File

@@ -4,6 +4,7 @@
#include <cstring>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/shared_memory.h"
@@ -51,8 +52,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
}
// Refresh the address mappings for the current process.
if (Kernel::g_current_process != nullptr) {
Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
if (Core::CurrentProcess() != nullptr) {
Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
}
} else {
auto& vm_manager = shared_memory->owner_process->vm_manager;

View File

@@ -8,6 +8,7 @@
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
@@ -31,7 +32,7 @@ namespace Kernel {
/// Set the process heap to a given Size. It can both extend and shrink the heap.
static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
LOG_TRACE(Kernel_SVC, "called, heap_size=0x%llx", heap_size);
auto& process = *g_current_process;
auto& process = *Core::CurrentProcess();
CASCADE_RESULT(*heap_addr,
process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
return RESULT_SUCCESS;
@@ -46,14 +47,14 @@ static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state
static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
src_addr, size);
return g_current_process->MirrorMemory(dst_addr, src_addr, size);
return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size);
}
/// Unmaps a region that was previously mapped with svcMapMemory
static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
src_addr, size);
return g_current_process->UnmapMemory(dst_addr, src_addr, size);
return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size);
}
/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -306,23 +307,23 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id,
info_sub_id, handle);
auto& vm_manager = g_current_process->vm_manager;
auto& vm_manager = Core::CurrentProcess()->vm_manager;
switch (static_cast<GetInfoType>(info_id)) {
case GetInfoType::AllowedCpuIdBitmask:
*result = g_current_process->allowed_processor_mask;
*result = Core::CurrentProcess()->allowed_processor_mask;
break;
case GetInfoType::AllowedThreadPrioBitmask:
*result = g_current_process->allowed_thread_priority_mask;
*result = Core::CurrentProcess()->allowed_thread_priority_mask;
break;
case GetInfoType::MapRegionBaseAddr:
*result = vm_manager.GetMapRegionBaseAddr();
*result = Memory::MAP_REGION_VADDR;
break;
case GetInfoType::MapRegionSize:
*result = vm_manager.GetAddressSpaceSize();
*result = Memory::MAP_REGION_SIZE;
break;
case GetInfoType::HeapRegionBaseAddr:
*result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize();
*result = Memory::HEAP_VADDR;
break;
case GetInfoType::HeapRegionSize:
*result = Memory::HEAP_SIZE;
@@ -346,13 +347,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = vm_manager.GetAddressSpaceSize();
break;
case GetInfoType::NewMapRegionBaseAddr:
*result = vm_manager.GetNewMapRegionBaseAddr();
*result = Memory::NEW_MAP_REGION_VADDR;
break;
case GetInfoType::NewMapRegionSize:
*result = vm_manager.GetNewMapRegionSize();
*result = Memory::NEW_MAP_REGION_SIZE;
break;
case GetInfoType::IsVirtualAddressMemoryEnabled:
*result = g_current_process->is_virtual_address_memory_enabled;
*result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
break;
case GetInfoType::TitleId:
LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
@@ -392,7 +393,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
// Note: The kernel uses the current process's resource limit instead of
// the one from the thread owner's resource limit.
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
return ERR_NOT_AUTHORIZED;
}
@@ -435,7 +436,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
case MemoryPermission::WriteExecute:
case MemoryPermission::ReadWriteExecute:
case MemoryPermission::DontCare:
return shared_memory->Map(g_current_process.get(), addr, permissions_type,
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
MemoryPermission::DontCare);
default:
LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
@@ -451,7 +452,7 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
return shared_memory->Unmap(g_current_process.get(), addr);
return shared_memory->Unmap(Core::CurrentProcess().get(), addr);
}
/// Query process memory
@@ -463,11 +464,11 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
}
auto vma = process->vm_manager.FindVMA(addr);
memory_info->attributes = 0;
if (vma == g_current_process->vm_manager.vma_map.end()) {
if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) {
memory_info->base_address = 0;
memory_info->permission = static_cast<u32>(VMAPermission::None);
memory_info->size = 0;
memory_info->type = static_cast<u32>(MemoryState::Free);
memory_info->type = static_cast<u32>(MemoryState::Unmapped);
} else {
memory_info->base_address = vma->second.base;
memory_info->permission = static_cast<u32>(vma->second.permissions);
@@ -487,16 +488,17 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
/// Exits the current process
static void ExitProcess() {
LOG_INFO(Kernel_SVC, "Process %u exiting", g_current_process->process_id);
LOG_INFO(Kernel_SVC, "Process %u exiting", Core::CurrentProcess()->process_id);
ASSERT_MSG(g_current_process->status == ProcessStatus::Running, "Process has already exited");
ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running,
"Process has already exited");
g_current_process->status = ProcessStatus::Exited;
Core::CurrentProcess()->status = ProcessStatus::Exited;
// Stop all the process threads that are currently waiting for objects.
auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList();
for (auto& thread : thread_list) {
if (thread->owner_process != g_current_process)
if (thread->owner_process != Core::CurrentProcess())
continue;
if (thread == GetCurrentThread())
@@ -525,14 +527,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
return ERR_OUT_OF_RANGE;
}
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
return ERR_NOT_AUTHORIZED;
}
if (processor_id == THREADPROCESSORID_DEFAULT) {
// Set the target CPU to the one specified in the process' exheader.
processor_id = g_current_process->ideal_processor;
processor_id = Core::CurrentProcess()->ideal_processor;
ASSERT(processor_id != THREADPROCESSORID_DEFAULT);
}
@@ -554,7 +556,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
CASCADE_RESULT(SharedPtr<Thread> thread,
Thread::Create(name, entry_point, priority, arg, processor_id, stack_top,
g_current_process));
Core::CurrentProcess()));
CASCADE_RESULT(thread->guest_handle, g_handle_table.Create(thread));
*out_handle = thread->guest_handle;

View File

@@ -94,7 +94,7 @@ void Thread::Stop() {
u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
u64 tls_slot =
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot);
Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
}
void WaitCurrentThread_Sleep() {
@@ -314,7 +314,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
// TODO(Subv): Find the correct MemoryState for this region.
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
linheap_memory, offset, Memory::PAGE_SIZE,
MemoryState::ThreadLocalStorage);
MemoryState::ThreadLocal);
}
// Mark the slot as used
@@ -353,11 +353,11 @@ void Thread::BoostPriority(u32 priority) {
SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority,
SharedPtr<Process> owner_process) {
// Setup page table so we can write to memory
SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
// Initialize new "main" thread
auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
Memory::HEAP_VADDR_END, owner_process);
Memory::STACK_VADDR_END, owner_process);
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();

View File

@@ -18,8 +18,26 @@ namespace Kernel {
static const char* GetMemoryStateName(MemoryState state) {
static const char* names[] = {
"Free", "Reserved", "IO", "Static", "Code", "Private",
"Shared", "Continuous", "Aliased", "Alias", "AliasCode", "Locked",
"Unmapped",
"Io",
"Normal",
"CodeStatic",
"CodeMutable",
"Heap",
"Shared",
"Unknown1"
"ModuleCodeStatic",
"ModuleCodeMutable",
"IpcBuffer0",
"Mapped",
"ThreadLocal",
"TransferMemoryIsolated",
"TransferMemory",
"ProcessMemory",
"Unknown2"
"IpcBuffer1",
"IpcBuffer3",
"KernelStack",
};
return names[(int)state];
@@ -142,7 +160,7 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
VirtualMemoryArea& vma = vma_handle->second;
vma.type = VMAType::Free;
vma.permissions = VMAPermission::None;
vma.meminfo_state = MemoryState::Free;
vma.meminfo_state = MemoryState::Unmapped;
vma.backing_block = nullptr;
vma.offset = 0;
@@ -166,6 +184,9 @@ ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
}
ASSERT(FindVMA(target)->second.size >= size);
Core::CPU().UnmapMemory(target, size);
return RESULT_SUCCESS;
}
@@ -377,19 +398,4 @@ u64 VMManager::GetAddressSpaceSize() {
return MAX_ADDRESS;
}
VAddr VMManager::GetMapRegionBaseAddr() {
LOG_WARNING(Kernel, "(STUBBED) called");
return Memory::HEAP_VADDR;
}
VAddr VMManager::GetNewMapRegionBaseAddr() {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x8000000;
}
u64 VMManager::GetNewMapRegionSize() {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x8000000;
}
} // namespace Kernel

View File

@@ -41,15 +41,24 @@ enum class VMAPermission : u8 {
/// Set of values returned in MemoryInfo.state by svcQueryMemory.
enum class MemoryState : u32 {
Free = 0,
IO = 1,
Normal = 2,
Code = 3,
Static = 4,
Heap = 5,
Shared = 6,
Mapped = 6,
ThreadLocalStorage = 12,
Unmapped = 0x0,
Io = 0x1,
Normal = 0x2,
CodeStatic = 0x3,
CodeMutable = 0x4,
Heap = 0x5,
Shared = 0x6,
ModuleCodeStatic = 0x8,
ModuleCodeMutable = 0x9,
IpcBuffer0 = 0xA,
Mapped = 0xB,
ThreadLocal = 0xC,
TransferMemoryIsolated = 0xD,
TransferMemory = 0xE,
ProcessMemory = 0xF,
IpcBuffer1 = 0x11,
IpcBuffer3 = 0x12,
KernelStack = 0x13,
};
/**
@@ -66,7 +75,7 @@ struct VirtualMemoryArea {
VMAType type = VMAType::Free;
VMAPermission permissions = VMAPermission::None;
/// Tag returned by svcQueryMemory. Not otherwise used.
MemoryState meminfo_state = MemoryState::Free;
MemoryState meminfo_state = MemoryState::Unmapped;
// Settings for type = AllocatedMemoryBlock
/// Memory block backing this VMA.
@@ -192,15 +201,6 @@ public:
/// Gets the total address space address size, used by svcGetInfo
u64 GetAddressSpaceSize();
/// Gets the map region base address, used by svcGetInfo
VAddr GetMapRegionBaseAddr();
/// Gets the base address for a new memory region, used by svcGetInfo
VAddr GetNewMapRegionBaseAddr();
/// Gets the size for a new memory region, used by svcGetInfo
u64 GetNewMapRegionSize();
/// Each VMManager has its own page table, which is set as the main one when the owning process
/// is scheduled.
Memory::PageTable page_table;

View File

@@ -2,12 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cinttypes>
#include "core/file_sys/filesystem.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/nvflinger/nvflinger.h"
namespace Service {
@@ -416,9 +419,24 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
}
void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u128 uid = rp.PopRaw<u128>();
LOG_WARNING(Service, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
FileSys::Path unused;
auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData, unused);
if (savedata.Failed()) {
// Create the save data and return an error indicating that the operation was performed.
FileSystem::FormatFileSystem(FileSystem::Type::SaveData);
// TODO(Subv): Find out the correct error code for this.
rb.Push(ResultCode(ErrorModule::FS, 40));
} else {
rb.Push(RESULT_SUCCESS);
}
rb.Push<u64>(0);
}

View File

@@ -43,6 +43,19 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
return itr->second->Open(path);
}
ResultCode FormatFileSystem(Type type) {
LOG_TRACE(Service_FS, "Formatting FileSystem with type=%d", type);
auto itr = filesystem_map.find(type);
if (itr == filesystem_map.end()) {
// TODO(bunnei): Find a better error code for this
return ResultCode(-1);
}
FileSys::Path unused;
return itr->second->Format(unused);
}
void RegisterFileSystems() {
filesystem_map.clear();

View File

@@ -44,6 +44,13 @@ ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& fact
ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
FileSys::Path& path);
/**
* Formats a file system
* @param type Type of the file system to format
* @return ResultCode of the operation
*/
ResultCode FormatFileSystem(Type type);
/// Registers all Filesystem services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);

View File

@@ -245,6 +245,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
static const FunctionInfo functions[] = {
{1, &FSP_SRV::Initalize, "Initalize"},
{18, &FSP_SRV::MountSdCard, "MountSdCard"},
{22, &FSP_SRV::CreateSaveData, "CreateSaveData"},
{51, &FSP_SRV::MountSaveData, "MountSaveData"},
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
{202, nullptr, "OpenDataStorageByDataId"},
@@ -279,6 +280,19 @@ void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto save_struct = rp.PopRaw<std::array<u8, 0x40>>();
auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
u128 uid = rp.PopRaw<u128>();
LOG_WARNING(Service_FS, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");

View File

@@ -24,6 +24,7 @@ private:
void Initalize(Kernel::HLERequestContext& ctx);
void MountSdCard(Kernel::HLERequestContext& ctx);
void CreateSaveData(Kernel::HLERequestContext& ctx);
void MountSaveData(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);

View File

@@ -32,7 +32,7 @@ public:
{0, &IRequest::GetRequestState, "GetRequestState"},
{1, &IRequest::GetResult, "GetResult"},
{2, &IRequest::GetSystemEventReadableHandles, "GetSystemEventReadableHandles"},
{3, nullptr, "Cancel"},
{3, &IRequest::Cancel, "Cancel"},
{4, nullptr, "Submit"},
{5, nullptr, "SetRequirement"},
{6, nullptr, "SetRequirementPreset"},
@@ -80,6 +80,11 @@ private:
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event1, event2);
}
void Cancel(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
Kernel::SharedPtr<Kernel::Event> event1, event2;
};
@@ -96,13 +101,56 @@ public:
}
};
class IGeneralService final : public ServiceFramework<IGeneralService> {
public:
IGeneralService();
private:
void GetClientId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
}
void CreateScanRequest(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IScanRequest>();
LOG_DEBUG(Service_NIFM, "called");
}
void CreateRequest(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IRequest>();
LOG_DEBUG(Service_NIFM, "called");
}
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<INetworkProfile>();
LOG_DEBUG(Service_NIFM, "called");
}
};
IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
static const FunctionInfo functions[] = {
{1, &IGeneralService::GetClientId, "GetClientId"},
{2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
{4, &IGeneralService::CreateRequest, "CreateRequest"},
{6, nullptr, "GetCurrentNetworkProfile"},
{7, nullptr, "EnumerateNetworkInterfaces"},
{5, nullptr, "GetCurrentNetworkProfile"},
{6, nullptr, "EnumerateNetworkInterfaces"},
{7, nullptr, "EnumerateNetworkProfiles"},
{8, nullptr, "GetNetworkProfile"},
{9, nullptr, "SetNetworkProfile"},
{10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
@@ -137,50 +185,28 @@ IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
RegisterHandlers(functions);
}
void IGeneralService::GetClientId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
}
void IGeneralService::CreateScanRequest(Kernel::HLERequestContext& ctx) {
void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IScanRequest>();
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void IGeneralService::CreateRequest(Kernel::HLERequestContext& ctx) {
void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IRequest>();
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void IGeneralService::RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void IGeneralService::CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<INetworkProfile>();
LOG_DEBUG(Service_NIFM, "called");
}
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
: ServiceFramework(name), module(std::move(module)) {}
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<NIFM_A>()->InstallAsService(service_manager);
std::make_shared<NIFM_S>()->InstallAsService(service_manager);
std::make_shared<NIFM_U>()->InstallAsService(service_manager);
auto module = std::make_shared<Module>();
std::make_shared<NIFM_A>(module)->InstallAsService(service_manager);
std::make_shared<NIFM_S>(module)->InstallAsService(service_manager);
std::make_shared<NIFM_U>(module)->InstallAsService(service_manager);
}
} // namespace NIFM

View File

@@ -9,16 +9,18 @@
namespace Service {
namespace NIFM {
class IGeneralService final : public ServiceFramework<IGeneralService> {
class Module final {
public:
IGeneralService();
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
private:
void GetClientId(Kernel::HLERequestContext& ctx);
void CreateScanRequest(Kernel::HLERequestContext& ctx);
void CreateRequest(Kernel::HLERequestContext& ctx);
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx);
void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx);
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
};
};
void InstallInterfaces(SM::ServiceManager& service_manager);

View File

@@ -2,29 +2,12 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_a.h"
namespace Service {
namespace NIFM {
void NIFM_A::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void NIFM_A::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
NIFM_A::NIFM_A() : ServiceFramework("nifm:a") {
NIFM_A::NIFM_A(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:a") {
static const FunctionInfo functions[] = {
{4, &NIFM_A::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_A::CreateGeneralService, "CreateGeneralService"},

View File

@@ -4,20 +4,14 @@
#pragma once
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/nifm/nifm.h"
namespace Service {
namespace NIFM {
class NIFM_A final : public ServiceFramework<NIFM_A> {
class NIFM_A final : public Module::Interface {
public:
NIFM_A();
~NIFM_A() = default;
private:
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
explicit NIFM_A(std::shared_ptr<Module> module);
};
} // namespace NIFM

View File

@@ -2,29 +2,12 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_s.h"
namespace Service {
namespace NIFM {
void NIFM_S::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void NIFM_S::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
NIFM_S::NIFM_S() : ServiceFramework("nifm:s") {
NIFM_S::NIFM_S(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:s") {
static const FunctionInfo functions[] = {
{4, &NIFM_S::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_S::CreateGeneralService, "CreateGeneralService"},

View File

@@ -4,20 +4,14 @@
#pragma once
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/nifm/nifm.h"
namespace Service {
namespace NIFM {
class NIFM_S final : public ServiceFramework<NIFM_S> {
class NIFM_S final : public Module::Interface {
public:
NIFM_S();
~NIFM_S() = default;
private:
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
explicit NIFM_S(std::shared_ptr<Module> module);
};
} // namespace NIFM

View File

@@ -2,29 +2,12 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_u.h"
namespace Service {
namespace NIFM {
void NIFM_U::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void NIFM_U::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
NIFM_U::NIFM_U() : ServiceFramework("nifm:u") {
NIFM_U::NIFM_U(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:u") {
static const FunctionInfo functions[] = {
{4, &NIFM_U::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_U::CreateGeneralService, "CreateGeneralService"},

View File

@@ -4,20 +4,14 @@
#pragma once
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/nifm/nifm.h"
namespace Service {
namespace NIFM {
class NIFM_U final : public ServiceFramework<NIFM_U> {
class NIFM_U final : public Module::Interface {
public:
NIFM_U();
~NIFM_U() = default;
private:
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
explicit NIFM_U(std::shared_ptr<Module> module);
};
} // namespace NIFM

View File

@@ -4,6 +4,7 @@
#include "common/common_paths.h"
#include "common/file_util.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/ns/pl_u.h"
@@ -90,13 +91,13 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
// dump. In the future, we need to replace this with a more robust solution.
// Map backing memory for the font data
Kernel::g_current_process->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, shared_font, 0,
SHARED_FONT_MEM_SIZE,
Kernel::MemoryState::Shared);
Core::CurrentProcess()->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, shared_font, 0,
SHARED_FONT_MEM_SIZE,
Kernel::MemoryState::Shared);
// Create shared font memory object
shared_font_mem = Kernel::SharedMemory::Create(
Kernel::g_current_process, SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite,
Core::CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite,
Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE,
"PL_U:shared_font_mem");
}

View File

@@ -36,9 +36,7 @@ u32 BufferQueue::DequeueBuffer(u32 pixel_format, u32 width, u32 height) {
return false;
// Make sure that the parameters match.
auto& igbp_buffer = buffer.igbp_buffer;
return igbp_buffer.format == pixel_format && igbp_buffer.width == width &&
igbp_buffer.height == height;
return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
});
if (itr == queue.end()) {
LOG_CRITICAL(Service_NVDRV, "no free buffers for pixel_format=%d, width=%d, height=%d",

View File

@@ -7,6 +7,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/hle/ipc.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
@@ -152,8 +153,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
}
u32* cmd_buf = (u32*)Memory::GetPointer(Kernel::GetCurrentThread()->GetTLSAddress());
context.WriteToOutgoingCommandBuffer(cmd_buf, *Kernel::g_current_process,
Kernel::g_handle_table);
context.WriteToOutgoingCommandBuffer(cmd_buf, *Core::CurrentProcess(), Kernel::g_handle_table);
return RESULT_SUCCESS;
}

View File

@@ -119,8 +119,6 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
}
metadata.Print();
process = Kernel::Process::Create("main", metadata.GetTitleID());
// Load NSO modules
VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
@@ -135,6 +133,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
}
}
process->program_id = metadata.GetTitleID();
process->svc_access_mask.set();
process->address_mappings = default_address_mappings;
process->resource_limit =

View File

@@ -406,7 +406,6 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR);
codeset->name = filename;
process = Kernel::Process::Create("main", 0);
process->LoadModule(codeset, codeset->entrypoint);
process->svc_access_mask.set();
process->address_mappings = default_address_mappings;
@@ -415,7 +414,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
process->Run(codeset->entrypoint, 48, Kernel::DEFAULT_STACK_SIZE);
process->Run(codeset->entrypoint, 48, Memory::STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;

View File

@@ -8,6 +8,7 @@
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/swap.h"
#include "core/core.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/loader/nro.h"
@@ -112,7 +113,7 @@ bool AppLoader_NRO::LoadNro(const std::string& path, VAddr load_base) {
// Load codeset for current process
codeset->name = path;
codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image));
Kernel::g_current_process->LoadModule(codeset, load_base);
Core::CurrentProcess()->LoadModule(codeset, load_base);
return true;
}
@@ -125,8 +126,6 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
return ResultStatus::Error;
}
process = Kernel::Process::Create("main", 0);
// Load NRO
static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR};
@@ -138,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
process->Run(base_addr, 48, Kernel::DEFAULT_STACK_SIZE);
process->Run(base_addr, 48, Memory::STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;

View File

@@ -9,6 +9,7 @@
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/swap.h"
#include "core/core.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/loader/nso.h"
@@ -142,7 +143,7 @@ VAddr AppLoader_NSO::LoadModule(const std::string& path, VAddr load_base) {
// Load codeset for current process
codeset->name = path;
codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image));
Kernel::g_current_process->LoadModule(codeset, load_base);
Core::CurrentProcess()->LoadModule(codeset, load_base);
return load_base + image_size;
}
@@ -155,8 +156,6 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
return ResultStatus::Error;
}
process = Kernel::Process::Create("main", 0);
// Load module
LoadModule(filepath, Memory::PROCESS_IMAGE_VADDR);
LOG_DEBUG(Loader, "loaded module %s @ 0x%" PRIx64, filepath.c_str(),
@@ -166,7 +165,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE);
process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;

View File

@@ -109,7 +109,7 @@ static std::set<MemoryHookPointer> GetSpecialHandlers(const PageTable& page_tabl
}
static std::set<MemoryHookPointer> GetSpecialHandlers(VAddr vaddr, u64 size) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
return GetSpecialHandlers(page_table, vaddr, size);
}
@@ -202,7 +202,7 @@ bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
}
bool IsValidVirtualAddress(const VAddr vaddr) {
return IsValidVirtualAddress(*Kernel::g_current_process, vaddr);
return IsValidVirtualAddress(*Core::CurrentProcess(), vaddr);
}
bool IsValidPhysicalAddress(const PAddr paddr) {
@@ -364,7 +364,7 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_
}
void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
ReadBlock(*Kernel::g_current_process, src_addr, dest_buffer, size);
ReadBlock(*Core::CurrentProcess(), src_addr, dest_buffer, size);
}
void Write8(const VAddr addr, const u8 data) {
@@ -435,11 +435,11 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
}
void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size) {
WriteBlock(*Kernel::g_current_process, dest_addr, src_buffer, size);
WriteBlock(*Core::CurrentProcess(), dest_addr, src_buffer, size);
}
void ZeroBlock(const VAddr dest_addr, const size_t size) {
const auto& process = *Kernel::g_current_process;
const auto& process = *Core::CurrentProcess();
size_t remaining_size = size;
size_t page_index = dest_addr >> PAGE_BITS;
@@ -480,7 +480,7 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
}
void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
const auto& process = *Kernel::g_current_process;
const auto& process = *Core::CurrentProcess();
size_t remaining_size = size;
size_t page_index = src_addr >> PAGE_BITS;
@@ -526,7 +526,7 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
template <>
boost::optional<u8> ReadSpecial<u8>(VAddr addr) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u8)))
if (auto result = handler->Read8(addr))
return *result;
@@ -535,7 +535,7 @@ boost::optional<u8> ReadSpecial<u8>(VAddr addr) {
template <>
boost::optional<u16> ReadSpecial<u16>(VAddr addr) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u16)))
if (auto result = handler->Read16(addr))
return *result;
@@ -544,7 +544,7 @@ boost::optional<u16> ReadSpecial<u16>(VAddr addr) {
template <>
boost::optional<u32> ReadSpecial<u32>(VAddr addr) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u32)))
if (auto result = handler->Read32(addr))
return *result;
@@ -553,7 +553,7 @@ boost::optional<u32> ReadSpecial<u32>(VAddr addr) {
template <>
boost::optional<u64> ReadSpecial<u64>(VAddr addr) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u64)))
if (auto result = handler->Read64(addr))
return *result;
@@ -562,7 +562,7 @@ boost::optional<u64> ReadSpecial<u64>(VAddr addr) {
template <>
bool WriteSpecial<u8>(VAddr addr, const u8 data) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u8)))
if (handler->Write8(addr, data))
return true;
@@ -571,7 +571,7 @@ bool WriteSpecial<u8>(VAddr addr, const u8 data) {
template <>
bool WriteSpecial<u16>(VAddr addr, const u16 data) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u16)))
if (handler->Write16(addr, data))
return true;
@@ -580,7 +580,7 @@ bool WriteSpecial<u16>(VAddr addr, const u16 data) {
template <>
bool WriteSpecial<u32>(VAddr addr, const u32 data) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u32)))
if (handler->Write32(addr, data))
return true;
@@ -589,7 +589,7 @@ bool WriteSpecial<u32>(VAddr addr, const u32 data) {
template <>
bool WriteSpecial<u64>(VAddr addr, const u64 data) {
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
const PageTable& page_table = Core::CurrentProcess()->vm_manager.page_table;
for (const auto& handler : GetSpecialHandlers(page_table, addr, sizeof(u64)))
if (handler->Write64(addr, data))
return true;
@@ -632,7 +632,7 @@ boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
} else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
return addr - VRAM_PADDR + VRAM_VADDR;
} else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
return addr - FCRAM_PADDR + Kernel::g_current_process->GetLinearHeapAreaAddress();
return addr - FCRAM_PADDR + Core::CurrentProcess()->GetLinearHeapAreaAddress();
} else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
} else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {

View File

@@ -129,21 +129,6 @@ enum : VAddr {
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
/// Area where IPC buffers are mapped onto.
IPC_MAPPING_VADDR = 0x04000000,
IPC_MAPPING_SIZE = 0x04000000,
IPC_MAPPING_VADDR_END = IPC_MAPPING_VADDR + IPC_MAPPING_SIZE,
/// Application heap (includes stack).
HEAP_VADDR = 0x108000000,
HEAP_SIZE = 0xF0000000,
HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE,
/// Area where shared memory buffers are mapped onto.
SHARED_MEMORY_VADDR = 0x10000000,
SHARED_MEMORY_SIZE = 0x04000000,
SHARED_MEMORY_VADDR_END = SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE,
/// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
/// memory.
LINEAR_HEAP_VADDR = 0x14000000,
@@ -176,14 +161,39 @@ enum : VAddr {
SHARED_PAGE_SIZE = 0x00001000,
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
/// Area where TLS (Thread-Local Storage) buffers are allocated.
TLS_AREA_VADDR = 0x228000000,
TLS_ENTRY_SIZE = 0x200,
/// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
NEW_LINEAR_HEAP_VADDR = 0x30000000,
NEW_LINEAR_HEAP_SIZE = 0x10000000,
NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
/// Area where TLS (Thread-Local Storage) buffers are allocated.
TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END,
TLS_ENTRY_SIZE = 0x200,
TLS_AREA_SIZE = 0x10000000,
TLS_ADREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
/// Application stack
STACK_VADDR = TLS_ADREA_VADDR_END,
STACK_SIZE = 0x10000,
STACK_VADDR_END = STACK_VADDR + STACK_SIZE,
/// Application heap
/// Size is confirmed to be a static value on fw 3.0.0
HEAP_VADDR = 0x108000000,
HEAP_SIZE = 0x180000000,
HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE,
/// New map region
/// Size is confirmed to be a static value on fw 3.0.0
NEW_MAP_REGION_VADDR = HEAP_VADDR_END,
NEW_MAP_REGION_SIZE = 0x80000000,
NEW_MAP_REGION_VADDR_END = NEW_MAP_REGION_VADDR + NEW_MAP_REGION_SIZE,
/// Map region
/// Size is confirmed to be a static value on fw 3.0.0
MAP_REGION_VADDR = NEW_MAP_REGION_VADDR_END,
MAP_REGION_SIZE = 0x1000000000,
MAP_REGION_VADDR_END = MAP_REGION_VADDR + MAP_REGION_SIZE,
};
/// Currently active page table

View File

@@ -15,8 +15,8 @@ static Memory::PageTable* page_table = nullptr;
TestEnvironment::TestEnvironment(bool mutable_memory_)
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
Kernel::g_current_process = Kernel::Process::Create("", 0);
page_table = &Kernel::g_current_process->vm_manager.page_table;
Core::CurrentProcess() = Kernel::Process::Create("");
page_table = &Core::CurrentProcess()->vm_manager.page_table;
page_table->pointers.fill(nullptr);
page_table->special_regions.clear();

View File

@@ -9,7 +9,7 @@
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
SECTION("these regions should not be mapped on an empty process") {
auto process = Kernel::Process::Create("", 0);
auto process = Kernel::Process::Create("");
CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
@@ -20,14 +20,14 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
}
SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
auto process = Kernel::Process::Create("", 0);
auto process = Kernel::Process::Create("");
Kernel::MapSharedPages(process->vm_manager);
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
}
SECTION("special regions should be valid after mapping them") {
auto process = Kernel::Process::Create("", 0);
auto process = Kernel::Process::Create("");
SECTION("VRAM") {
Kernel::HandleSpecialMapping(process->vm_manager,
{Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
@@ -48,7 +48,7 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
}
SECTION("Unmapping a VAddr should make it invalid") {
auto process = Kernel::Process::Create("", 0);
auto process = Kernel::Process::Create("");
Kernel::MapSharedPages(process->vm_manager);
process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);

View File

@@ -19,6 +19,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value) {
#define MAXWELL3D_REG_INDEX(field_name) (offsetof(Regs, field_name) / sizeof(u32))
switch (method) {
case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): {
DrawArrays();
break;
}
case MAXWELL3D_REG_INDEX(query.query_get): {
ProcessQueryGet();
break;
@@ -47,5 +51,10 @@ void Maxwell3D::ProcessQueryGet() {
UNIMPLEMENTED_MSG("Query mode %u not implemented", regs.query.query_get.mode.Value());
}
}
void Maxwell3D::DrawArrays() {
LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring");
}
} // namespace Engines
} // namespace Tegra

View File

@@ -32,7 +32,12 @@ public:
union {
struct {
INSERT_PADDING_WORDS(0x6C0);
INSERT_PADDING_WORDS(0x585);
struct {
u32 vertex_end_gl;
u32 vertex_begin_gl;
} draw;
INSERT_PADDING_WORDS(0x139);
struct {
u32 query_address_high;
u32 query_address_low;
@@ -61,6 +66,9 @@ private:
/// Handles a write to the QUERY_GET register.
void ProcessQueryGet();
/// Handles a write to the VERTEX_END_GL register, triggering a draw.
void DrawArrays();
MemoryManager& memory_manager;
};

View File

@@ -78,7 +78,7 @@ void Config::ReadValues() {
qt_config->beginGroup("Core");
Settings::values.cpu_core =
static_cast<Settings::CpuCore>(qt_config->value("cpu_core", 0).toInt());
static_cast<Settings::CpuCore>(qt_config->value("cpu_core", 1).toInt());
qt_config->endGroup();
qt_config->beginGroup("Renderer");