diff options
| author | bunnei <bunneidev@gmail.com> | 2017-12-31 16:10:01 -0500 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2017-12-31 16:10:01 -0500 | 
| commit | 9d0c3bda7f3d42e1574b12335f9150dd8f480112 (patch) | |
| tree | 567b90f8920f2b032c9c909d7dd8c718f914fbb2 /src/core/hle | |
| parent | 001091fa720227a0075364b52c6778d8bdfacbd9 (diff) | |
svc: Implement svcCreateThread.
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/svc.cpp | 59 | 
1 files changed, 57 insertions, 2 deletions
| diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 0c53db1c5..3b2eb5d5e 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -224,6 +224,62 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd      return QueryProcessMemory(memory_info, page_info, Kernel::CurrentProcess, addr);  } +/// Creates a new thread +static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, +                               u32 priority, s32 processor_id) { +    std::string name = Common::StringFromFormat("unknown-%016" PRIX64, entry_point); + +    if (priority > THREADPRIO_LOWEST) { +        return Kernel::ERR_OUT_OF_RANGE; +    } + +    SharedPtr<Kernel::ResourceLimit>& resource_limit = Kernel::g_current_process->resource_limit; +    if (resource_limit->GetMaxResourceValue(Kernel::ResourceTypes::PRIORITY) > priority) { +        return Kernel::ERR_NOT_AUTHORIZED; +    } + +    if (processor_id == THREADPROCESSORID_DEFAULT) { +        // Set the target CPU to the one specified in the process' exheader. +        processor_id = Kernel::g_current_process->ideal_processor; +        ASSERT(processor_id != THREADPROCESSORID_DEFAULT); +    } + +    switch (processor_id) { +    case THREADPROCESSORID_0: +        break; +    case THREADPROCESSORID_ALL: +        LOG_INFO(Kernel_SVC, +                 "Newly created thread is allowed to be run in any Core, unimplemented."); +        break; +    case THREADPROCESSORID_1: +        LOG_ERROR(Kernel_SVC, +                  "Newly created thread must run in the SysCore (Core1), unimplemented."); +        break; +    default: +        // TODO(bunnei): Implement support for other processor IDs +        ASSERT_MSG(false, "Unsupported thread processor ID: %d", processor_id); +        break; +    } + +    CASCADE_RESULT(SharedPtr<Kernel::Thread> thread, +                   Kernel::Thread::Create(name, entry_point, priority, arg, processor_id, stack_top, +                                          Kernel::g_current_process)); + +    thread->context.fpscr = +        FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000 + +    CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread))); + +    Core::System::GetInstance().PrepareReschedule(); + +    LOG_TRACE(Kernel_SVC, +              "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " +              "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", +              entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); + +    return RESULT_SUCCESS; +} +  /// Starts the thread for the provided handle  static ResultCode StartThread(Handle thread_handle) {      LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); @@ -288,8 +344,7 @@ static const FunctionDef SVC_Table[] = {      {0x05, HLE::Wrap<UnmapMemory>, "svcUnmapMemory"},      {0x06, HLE::Wrap<QueryMemory>, "svcQueryMemory"},      {0x07, nullptr, "svcExitProcess"}, -    {0x08, nullptr, "svcCreateThread"}, -    {0x09, nullptr, "svcStartThread"}, +    {0x08, HLE::Wrap<CreateThread>, "svcCreateThread"},      {0x09, HLE::Wrap<StartThread>, "svcStartThread"},      {0x0A, nullptr, "svcExitThread"},      {0x0B, HLE::Wrap<SleepThread>, "svcSleepThread"}, | 
