mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-02-02 05:44:20 +01:00
[rpcsx-os/orbis-kernel] random fixes
fix pipe fix socketpair fix bridge fix evf_wait with timeout fix umtx_op(0x17) implement ipmi evf stub sched_get_priority_max/min stub sys_rtprio_thread implement sys_yield emit event on signal stub ajm register/unregister ioctls stub av_control ioctl hack removal
This commit is contained in:
parent
bbfcda5f10
commit
e90566e7de
|
|
@ -223,7 +223,8 @@ private:
|
|||
}
|
||||
|
||||
position = 0;
|
||||
waitPuller(0);
|
||||
header->push = position;
|
||||
waitPuller(position);
|
||||
}
|
||||
|
||||
return position;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
static int gShmFd = -1;
|
||||
static constexpr std::size_t kShmSize = sizeof(amdgpu::bridge::BridgeHeader) +
|
||||
(sizeof(std::uint64_t) * (1024 * 1024));
|
||||
(sizeof(std::uint64_t) * 256);
|
||||
std::uint32_t amdgpu::bridge::expGpuPid = 0;
|
||||
|
||||
amdgpu::bridge::BridgeHeader *
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ struct EventFlag final {
|
|||
char name[32];
|
||||
|
||||
bool isDeleted = false;
|
||||
std::uint8_t attrs;
|
||||
std::uint8_t attrs = kEvfAttrMulti | kEvfAttrThFifo;
|
||||
std::atomic<unsigned> references{0};
|
||||
std::atomic<std::uint64_t> value;
|
||||
std::atomic<std::uint64_t> value{0};
|
||||
|
||||
struct WaitingThread {
|
||||
Thread *thread;
|
||||
|
|
@ -61,7 +61,8 @@ struct EventFlag final {
|
|||
|
||||
enum class NotifyType { Set, Cancel, Destroy };
|
||||
|
||||
explicit EventFlag(std::int32_t attrs, std::uint64_t initPattern)
|
||||
EventFlag() = default;
|
||||
EventFlag(std::int32_t attrs, std::uint64_t initPattern)
|
||||
: attrs(attrs), value(initPattern) {}
|
||||
|
||||
ErrorCode wait(Thread *thread, std::uint8_t waitMode,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ struct IpmiClient : RcBase {
|
|||
shared_cv sessionCv;
|
||||
sint pid;
|
||||
kdeque<kvector<std::byte>> messages;
|
||||
kdeque<EventFlag> eventFlags;
|
||||
shared_cv messageCv;
|
||||
|
||||
explicit IpmiClient(kstring name) : name(std::move(name)) {}
|
||||
|
|
@ -77,7 +78,6 @@ struct IpmiSession : RcBase {
|
|||
shared_mutex mutex;
|
||||
shared_cv responseCv;
|
||||
kdeque<MessageResponse> messageResponses;
|
||||
EventFlag evf{0, 0};
|
||||
shared_cv connectCv;
|
||||
bool expectedOutput = false; // TODO: verify
|
||||
sint connectionStatus{0};
|
||||
|
|
@ -98,12 +98,19 @@ struct IpmiCreateServerConfig {
|
|||
|
||||
static_assert(sizeof(IpmiCreateServerConfig) == 0x38);
|
||||
|
||||
struct IpmiCreateClientConfig {
|
||||
orbis::uint64_t size;
|
||||
orbis::uint32_t unk[80];
|
||||
orbis::ptr<void> userData;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiCreateClientConfig) == 0x150);
|
||||
|
||||
struct IpmiBufferInfo {
|
||||
ptr<void> data;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiBufferInfo) == 0x10);
|
||||
|
||||
struct IpmiDataInfo {
|
||||
ptr<void> data;
|
||||
|
|
@ -111,6 +118,7 @@ struct IpmiDataInfo {
|
|||
uint64_t capacity; //?
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiBufferInfo) == 0x10);
|
||||
static_assert(sizeof(IpmiDataInfo) == 0x18);
|
||||
|
||||
struct IpmiSyncMessageHeader {
|
||||
|
|
@ -124,7 +132,7 @@ struct IpmiSyncMessageHeader {
|
|||
static_assert(sizeof(IpmiSyncMessageHeader) == 0x18);
|
||||
|
||||
ErrorCode ipmiCreateClient(Process *proc, void *clientImpl, const char *name,
|
||||
void *config, Ref<IpmiClient> &result);
|
||||
const IpmiCreateClientConfig &config, Ref<IpmiClient> &result);
|
||||
ErrorCode ipmiCreateServer(Process *proc, void *serverImpl, const char *name,
|
||||
const IpmiCreateServerConfig &config,
|
||||
Ref<IpmiServer> &result);
|
||||
|
|
@ -151,16 +159,21 @@ SysResult sysIpmiSendConnectResult(Thread *thread, ptr<uint> result, uint kid,
|
|||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionRespondSync(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientInvokeAsyncMethod(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiClientTryGetResult(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiClientGetMessage(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientTryGetMessage(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionTrySendMessage(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiClientDisconnect(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiClientDisconnect(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionGetClientPid(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result,
|
||||
|
|
@ -172,11 +185,10 @@ SysResult sysIpmiSessionGetUserData(Thread *thread, ptr<uint> result, uint kid,
|
|||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiServerGetName(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientWaitEventFlag(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiClientPollEventFlag(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionWaitEventFlag(Thread *thread, ptr<uint> result,
|
||||
uint kid, ptr<void> params,
|
||||
uint64_t paramsSz);
|
||||
SysResult sysIpmiSessionSetEventFlag(Thread *thread, ptr<uint> result, uint kid,
|
||||
ptr<void> params, uint64_t paramsSz);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@
|
|||
#include "utils/Rc.hpp"
|
||||
#include "utils/SharedCV.hpp"
|
||||
#include "utils/SharedMutex.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace orbis {
|
||||
struct Pipe final : File {
|
||||
shared_cv cv;
|
||||
kvector<std::byte> data;
|
||||
Ref<Pipe> other;
|
||||
};
|
||||
|
||||
Ref<Pipe> createPipe();
|
||||
std::pair<Ref<Pipe>, Ref<Pipe>> createPipe();
|
||||
} // namespace orbis
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct Stat;
|
|||
struct stack_t;
|
||||
struct IoVec;
|
||||
struct BatchMapEntry;
|
||||
struct UContext;
|
||||
|
||||
SysResult nosys(Thread *thread);
|
||||
|
||||
|
|
@ -743,10 +744,10 @@ SysResult sys_mmap_dmem(Thread *thread, caddr_t addr, size_t len,
|
|||
SysResult sys_physhm_open(Thread *thread /* TODO */);
|
||||
SysResult sys_physhm_unlink(Thread *thread /* TODO */);
|
||||
SysResult sys_resume_internal_hdd(Thread *thread /* TODO */);
|
||||
SysResult sys_thr_suspend_ucontext(Thread *thread /* TODO */);
|
||||
SysResult sys_thr_resume_ucontext(Thread *thread /* TODO */);
|
||||
SysResult sys_thr_get_ucontext(Thread *thread /* TODO */);
|
||||
SysResult sys_thr_set_ucontext(Thread *thread /* TODO */);
|
||||
SysResult sys_thr_suspend_ucontext(Thread *thread, lwpid_t tid);
|
||||
SysResult sys_thr_resume_ucontext(Thread *thread, lwpid_t tid);
|
||||
SysResult sys_thr_get_ucontext(Thread *thread, lwpid_t tid, ptr<UContext> context);
|
||||
SysResult sys_thr_set_ucontext(Thread *thread, lwpid_t tid, ptr<UContext> context);
|
||||
SysResult sys_set_timezone_info(Thread *thread /* TODO */);
|
||||
SysResult sys_set_phys_fmem_limit(Thread *thread /* TODO */);
|
||||
SysResult sys_utc_to_localtime(Thread *thread, int64_t time, int64_t *localtime,
|
||||
|
|
|
|||
|
|
@ -27,5 +27,7 @@ struct thr_param {
|
|||
// following flags:
|
||||
ptr<rtprio> rtp; // Real-time scheduling priority for the new thread. May be
|
||||
// NULL to inherit the priority from the creating thread
|
||||
ptr<char> name;
|
||||
ptr<void> spare[2];
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
|
|||
70
orbis-kernel/include/orbis/ucontext.hpp
Normal file
70
orbis-kernel/include/orbis/ucontext.hpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
|
||||
#include "orbis-config.hpp"
|
||||
namespace orbis {
|
||||
|
||||
struct MContext {
|
||||
ulong onstack;
|
||||
ulong rdi;
|
||||
ulong rsi;
|
||||
ulong rdx;
|
||||
ulong rcx;
|
||||
ulong r8;
|
||||
ulong r9;
|
||||
ulong rax;
|
||||
ulong rbx;
|
||||
ulong rbp;
|
||||
ulong r10;
|
||||
ulong r11;
|
||||
ulong r12;
|
||||
ulong r13;
|
||||
ulong r14;
|
||||
ulong r15;
|
||||
uint trapno;
|
||||
ushort fs;
|
||||
ushort gs;
|
||||
ulong addr;
|
||||
uint flags;
|
||||
ushort es;
|
||||
ushort ds;
|
||||
ulong err;
|
||||
ulong rip;
|
||||
ulong cs;
|
||||
ulong rflags;
|
||||
ulong rsp;
|
||||
ulong ss;
|
||||
ulong len;
|
||||
ulong fpformat;
|
||||
ulong ownedfp;
|
||||
ulong lbrfrom;
|
||||
ulong lbrto;
|
||||
ulong aux1;
|
||||
ulong aux2;
|
||||
ulong fpstate[104];
|
||||
ulong fsbase;
|
||||
ulong gsbase;
|
||||
ulong spare[6];
|
||||
};
|
||||
|
||||
struct Stack {
|
||||
ptr<void> sp;
|
||||
size_t size;
|
||||
sint flags;
|
||||
sint align;
|
||||
};
|
||||
|
||||
struct SigSet {
|
||||
ulong bits[2];
|
||||
};
|
||||
|
||||
struct UContext {
|
||||
SigSet sigmask;
|
||||
sint unk0[12];
|
||||
MContext mcontext;
|
||||
ptr<UContext> link;
|
||||
Stack stack;
|
||||
sint uc_flags;
|
||||
sint spare[4];
|
||||
sint unk1[3];
|
||||
};
|
||||
} // namespace orbis
|
||||
|
|
@ -85,7 +85,7 @@ ErrorCode umtx_rw_wrlock(Thread *thread, ptr<urwlock> rwlock, ulong ut);
|
|||
ErrorCode umtx_rw_unlock(Thread *thread, ptr<urwlock> rwlock);
|
||||
ErrorCode umtx_wake_private(Thread *thread, ptr<void> uaddr, sint n_wake);
|
||||
ErrorCode umtx_wait_umutex(Thread *thread, ptr<umutex> m, std::uint64_t ut);
|
||||
ErrorCode umtx_wake_umutex(Thread *thread, ptr<umutex> m);
|
||||
ErrorCode umtx_wake_umutex(Thread *thread, ptr<umutex> m, sint wakeFlags);
|
||||
ErrorCode umtx_sem_wait(Thread *thread, ptr<usem> sem, std::uint64_t ut);
|
||||
ErrorCode umtx_sem_wake(Thread *thread, ptr<usem> sem);
|
||||
ErrorCode umtx_nwake_private(Thread *thread, ptr<void *> uaddrs,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
#include "KernelContext.hpp"
|
||||
#include "thread/Process.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
#include <chrono>
|
||||
|
||||
orbis::ErrorCode orbis::ipmiCreateClient(Process *proc, void *clientImpl,
|
||||
const char *name, void *config,
|
||||
const char *name,
|
||||
const IpmiCreateClientConfig &config,
|
||||
Ref<IpmiClient> &result) {
|
||||
auto client = knew<IpmiClient>(name);
|
||||
if (client == nullptr) {
|
||||
|
|
@ -14,6 +16,8 @@ orbis::ErrorCode orbis::ipmiCreateClient(Process *proc, void *clientImpl,
|
|||
client->clientImpl = clientImpl;
|
||||
client->name = name;
|
||||
client->pid = proc->pid;
|
||||
client->userData = config.userData;
|
||||
client->eventFlags.resize(32);
|
||||
result = client;
|
||||
return {};
|
||||
}
|
||||
|
|
@ -84,7 +88,7 @@ orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr<uint> result,
|
|||
struct IpmiCreateClientParams {
|
||||
ptr<void> clientImpl;
|
||||
ptr<const char> name;
|
||||
ptr<void> config; // FIXME: describe
|
||||
ptr<IpmiCreateClientConfig> config;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiCreateClientParams) == 0x18);
|
||||
|
|
@ -94,13 +98,15 @@ orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr<uint> result,
|
|||
}
|
||||
|
||||
IpmiCreateClientParams _params;
|
||||
IpmiCreateClientConfig _config;
|
||||
char _name[25];
|
||||
Ref<IpmiClient> client;
|
||||
|
||||
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiCreateClientParams>(params)));
|
||||
ORBIS_RET_ON_ERROR(uread(_config, _params.config));
|
||||
ORBIS_RET_ON_ERROR(ureadString(_name, sizeof(_name), _params.name));
|
||||
ORBIS_RET_ON_ERROR(ipmiCreateClient(thread->tproc, _params.clientImpl, _name,
|
||||
nullptr, client));
|
||||
_config, client));
|
||||
|
||||
auto kid = thread->tproc->ipmiMap.insert(std::move(client));
|
||||
|
||||
|
|
@ -316,6 +322,7 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
|
|||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, session->client->name);
|
||||
thread->where();
|
||||
|
||||
kvector<std::byte> data;
|
||||
|
||||
|
|
@ -340,22 +347,181 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
|
|||
session->responseCv.notify_one(session->mutex);
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
orbis::SysResult orbis::sysIpmiClientGetMessage(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
orbis::SysResult orbis::sysIpmiClientInvokeAsyncMethod(Thread *thread,
|
||||
ptr<uint> result,
|
||||
uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct IpmiAsyncCallParams {
|
||||
uint32_t method;
|
||||
uint32_t unkNotifee0;
|
||||
uint64_t unkNotifee1;
|
||||
uint32_t numInData;
|
||||
uint32_t padding1;
|
||||
ptr<IpmiDataInfo> pInData;
|
||||
ptr<sint> pResult;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiAsyncCallParams) == 0x30);
|
||||
|
||||
if (paramsSz != sizeof(IpmiAsyncCallParams)) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();
|
||||
|
||||
if (client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, client->name, client->messages.size(),
|
||||
paramsSz);
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::days(1));
|
||||
IpmiAsyncCallParams _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, (ptr<IpmiAsyncCallParams>)params));
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, client->name, _params.method,
|
||||
_params.unkNotifee0, _params.unkNotifee1, _params.numInData,
|
||||
_params.padding1, _params.pInData, _params.pResult,
|
||||
_params.flags);
|
||||
thread->where();
|
||||
|
||||
if (_params.unkNotifee0 != -1) {
|
||||
client->eventFlags[_params.unkNotifee0].set(1);
|
||||
}
|
||||
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pResult, 0));
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiClientTryGetResult(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct IpmiTryGetResultParams {
|
||||
uint32_t method;
|
||||
uint32_t unk;
|
||||
ptr<sint> pResult;
|
||||
uint32_t numOutData;
|
||||
uint32_t padding;
|
||||
ptr<IpmiBufferInfo> pOutData;
|
||||
uint64_t padding2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiTryGetResultParams) == 0x28);
|
||||
|
||||
if (paramsSz != sizeof(IpmiTryGetResultParams)) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
return uwrite<uint>(result, 0x80020000 + static_cast<int>(ErrorCode::AGAIN));
|
||||
|
||||
IpmiTryGetResultParams _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, (ptr<IpmiTryGetResultParams>)params));
|
||||
|
||||
auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();
|
||||
|
||||
if (client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, client->name, _params.method,
|
||||
_params.unk, _params.pResult, _params.numOutData,
|
||||
_params.padding, _params.pOutData, _params.padding2);
|
||||
thread->where();
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pResult, 0));
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
orbis::SysResult orbis::sysIpmiClientGetMessage(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct SceIpmiClientGetArgs {
|
||||
uint32_t unk; // 0
|
||||
uint32_t padding;
|
||||
ptr<std::byte> message;
|
||||
ptr<uint64_t> pSize;
|
||||
uint64_t maxSize;
|
||||
ptr<uint> pTimeout;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SceIpmiClientGetArgs) == 0x28);
|
||||
|
||||
if (paramsSz != sizeof(SceIpmiClientGetArgs)) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();
|
||||
|
||||
if (client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
SceIpmiClientGetArgs _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, ptr<SceIpmiClientGetArgs>(params)));
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, client->name, client->messages.size(),
|
||||
_params.unk, _params.padding, _params.message, _params.pSize,
|
||||
_params.maxSize, _params.pTimeout);
|
||||
|
||||
std::lock_guard lock(client->mutex);
|
||||
|
||||
using clock = std::chrono::high_resolution_clock;
|
||||
|
||||
clock::time_point timeoutPoint = clock::time_point::max();
|
||||
if (_params.pTimeout != nullptr) {
|
||||
std::uint32_t timeout{};
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, timeout);
|
||||
ORBIS_RET_ON_ERROR(uread(timeout, _params.pTimeout));
|
||||
timeoutPoint = clock::now() + std::chrono::microseconds(timeout);
|
||||
}
|
||||
|
||||
if (client->messages.empty()) {
|
||||
if (timeoutPoint != clock::time_point::max()) {
|
||||
while (true) {
|
||||
auto now = clock::now();
|
||||
if (now >= timeoutPoint) {
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, 0u));
|
||||
return uwrite<uint>(
|
||||
result, 0x80020000 + static_cast<int>(ErrorCode::TIMEDOUT));
|
||||
}
|
||||
|
||||
auto waitTime = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
timeoutPoint - now);
|
||||
client->messageCv.wait(client->mutex, waitTime.count());
|
||||
|
||||
if (!client->messages.empty()) {
|
||||
now = clock::now();
|
||||
|
||||
if (now >= timeoutPoint) {
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, 0u));
|
||||
} else {
|
||||
std::uint32_t restTime =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
timeoutPoint - now)
|
||||
.count();
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, restTime));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (client->messages.empty()) {
|
||||
client->messageCv.wait(client->mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto &message = client->messages.front();
|
||||
|
||||
if (_params.maxSize < message.size()) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, "too small buffer");
|
||||
return uwrite<uint>(result,
|
||||
0x80020000 + static_cast<int>(ErrorCode::INVAL));
|
||||
}
|
||||
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pSize, message.size()));
|
||||
ORBIS_RET_ON_ERROR(
|
||||
uwriteRaw(_params.message, message.data(), message.size()));
|
||||
client->messages.pop_front();
|
||||
return uwrite<uint>(result, 0);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread,
|
||||
|
|
@ -543,16 +709,18 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
|
|||
auto session = client->session;
|
||||
|
||||
if (session == nullptr) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, "waiting for connection", client->name,
|
||||
_params.method);
|
||||
// ORBIS_LOG_TODO(__FUNCTION__, "waiting for connection", client->name,
|
||||
// _params.method);
|
||||
|
||||
while (session == nullptr) {
|
||||
client->sessionCv.wait(client->mutex);
|
||||
session = client->session;
|
||||
}
|
||||
// while (session == nullptr) {
|
||||
// client->sessionCv.wait(client->mutex);
|
||||
// session = client->session;
|
||||
// }
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, client->name, "sync call", _params.method);
|
||||
// thread->where();
|
||||
|
||||
std::lock_guard sessionLock(session->mutex);
|
||||
auto server = session->server;
|
||||
|
|
@ -822,14 +990,70 @@ orbis::SysResult orbis::sysIpmiServerGetName(Thread *thread, ptr<uint> result,
|
|||
return uwrite<uint>(result, 0);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiClientWaitEventFlag(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct IpmiWaitEventFlagParam {
|
||||
uint32_t index;
|
||||
uint32_t padding0;
|
||||
uint64_t patternSet;
|
||||
uint32_t mode;
|
||||
uint32_t padding1;
|
||||
ptr<uint64_t> pPatternSet;
|
||||
ptr<uint32_t> pTimeout;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiWaitEventFlagParam) == 0x28);
|
||||
|
||||
IpmiWaitEventFlagParam _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiWaitEventFlagParam>(params)));
|
||||
|
||||
auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();
|
||||
|
||||
if (client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, kid, client->name, _params.index,
|
||||
_params.padding0, _params.patternSet, _params.mode,
|
||||
_params.padding1, _params.pPatternSet, _params.pTimeout);
|
||||
|
||||
if (client->eventFlags.size() <= _params.index) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
std::uint32_t resultTimeout{};
|
||||
|
||||
if (_params.pTimeout != nullptr) {
|
||||
ORBIS_RET_ON_ERROR(uread(resultTimeout, _params.pTimeout));
|
||||
}
|
||||
|
||||
auto &evf = client->eventFlags[_params.index];
|
||||
auto waitResult =
|
||||
evf.wait(thread, _params.mode, _params.patternSet, &resultTimeout);
|
||||
|
||||
// FIXME
|
||||
// if (_params.pPatternSet != nullptr) {
|
||||
// ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, thread->evfResultPattern));
|
||||
// }
|
||||
ORBIS_RET_ON_ERROR(uwrite(result, 0u));
|
||||
if (_params.pTimeout != nullptr) {
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, resultTimeout));
|
||||
}
|
||||
return waitResult;
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct IpmiPollEventFlagParam {
|
||||
uint64_t index;
|
||||
uint32_t index;
|
||||
uint32_t padding0;
|
||||
uint64_t patternSet;
|
||||
uint64_t mode;
|
||||
uint32_t mode;
|
||||
uint32_t padding1;
|
||||
ptr<uint64_t> pPatternSet;
|
||||
};
|
||||
|
||||
|
|
@ -848,21 +1072,23 @@ orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread,
|
|||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
// ORBIS_LOG_TODO(__FUNCTION__, client->name, _params.index,
|
||||
// _params.patternSet,
|
||||
// _params.mode, _params.pPatternSet);
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, 0u));
|
||||
// client->evf.set(_params.a);
|
||||
return SysResult::notAnError(ErrorCode::BUSY);
|
||||
}
|
||||
// ORBIS_LOG_TODO(__FUNCTION__, thread->tid, kid, client->name, _params.index,
|
||||
// _params.padding0, _params.patternSet, _params.mode,
|
||||
// _params.padding1, _params.pPatternSet);
|
||||
|
||||
orbis::SysResult orbis::sysIpmiSessionWaitEventFlag(Thread *thread,
|
||||
ptr<uint> result, uint kid,
|
||||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, paramsSz);
|
||||
thread->where();
|
||||
return uwrite<uint>(result, 0);
|
||||
if (client->eventFlags.size() <= _params.index) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
uint64_t patternSet;
|
||||
ORBIS_RET_ON_ERROR(uread(patternSet, _params.pPatternSet));
|
||||
auto &evf = client->eventFlags[_params.index];
|
||||
auto waitResult = evf.tryWait(thread, _params.mode, patternSet);
|
||||
|
||||
ORBIS_RET_ON_ERROR(uread(patternSet, _params.pPatternSet));
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, thread->evfResultPattern));
|
||||
ORBIS_RET_ON_ERROR(uwrite(result, 0u));
|
||||
return SysResult::notAnError(waitResult);
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread,
|
||||
|
|
@ -870,8 +1096,9 @@ orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread,
|
|||
ptr<void> params,
|
||||
uint64_t paramsSz) {
|
||||
struct IpmiSetEventFlagParam {
|
||||
uint32_t index;
|
||||
uint32_t padding;
|
||||
uint64_t patternSet;
|
||||
uint64_t index;
|
||||
};
|
||||
|
||||
static_assert(sizeof(IpmiSetEventFlagParam) == 0x10);
|
||||
|
|
@ -891,6 +1118,16 @@ orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread,
|
|||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, session->client->name, _params.patternSet,
|
||||
_params.index);
|
||||
session->evf.set(_params.patternSet);
|
||||
auto client = session->client;
|
||||
if (client == nullptr) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
if (client->eventFlags.size() <= _params.index) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
auto &evf = client->eventFlags[_params.index];
|
||||
evf.set(_params.patternSet);
|
||||
return uwrite<uint>(result, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio,
|
|||
|
||||
static orbis::ErrorCode pipe_write(orbis::File *file, orbis::Uio *uio,
|
||||
orbis::Thread *thread) {
|
||||
auto pipe = static_cast<orbis::Pipe *>(file);
|
||||
auto pipe = static_cast<orbis::Pipe *>(file)->other;
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file);
|
||||
|
||||
std::size_t cnt = 0;
|
||||
|
|
@ -79,8 +79,12 @@ static orbis::FileOps pipe_ops = {
|
|||
.write = pipe_write,
|
||||
};
|
||||
|
||||
orbis::Ref<orbis::Pipe> orbis::createPipe() {
|
||||
auto result = knew<Pipe>();
|
||||
result->ops = &pipe_ops;
|
||||
return result;
|
||||
std::pair<orbis::Ref<orbis::Pipe>, orbis::Ref<orbis::Pipe>> orbis::createPipe() {
|
||||
auto a = knew<Pipe>();
|
||||
auto b = knew<Pipe>();
|
||||
a->ops = &pipe_ops;
|
||||
b->ops = &pipe_ops;
|
||||
a->other = b;
|
||||
b->other = a;
|
||||
return {a, b};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,6 @@ orbis::SysResult orbis::sys_dup(Thread *thread, uint fd) {
|
|||
orbis::SysResult orbis::sys_fcntl(Thread *thread, sint fd, sint cmd,
|
||||
slong arg) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, fd, cmd, arg);
|
||||
if (cmd == 0xb) {
|
||||
// TODO: hack
|
||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_close(Thread *thread, sint fd) {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
#include "sys/sysproto.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
#include <chrono>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
orbis::SysResult orbis::sys_exit(Thread *thread, sint status) {
|
||||
if (auto exit = thread->tproc->ops->exit) {
|
||||
|
|
@ -33,22 +33,27 @@ orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr<sint> status,
|
|||
}
|
||||
|
||||
::rusage hostUsage;
|
||||
int stat;
|
||||
int result = ::wait4(hostPid, &stat, options, &hostUsage);
|
||||
if (result < 0) {
|
||||
return static_cast<ErrorCode>(errno);
|
||||
while (true) {
|
||||
int stat;
|
||||
int result = ::wait4(hostPid, &stat, options, &hostUsage);
|
||||
if (result < 0) {
|
||||
return static_cast<ErrorCode>(errno);
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat);
|
||||
|
||||
auto process = g_context.findProcessByHostId(result);
|
||||
if (process == nullptr) {
|
||||
ORBIS_LOG_ERROR("host process not found", result);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status != nullptr) {
|
||||
ORBIS_RET_ON_ERROR(uwrite(status, stat));
|
||||
}
|
||||
thread->retval[0] = process->pid;
|
||||
break;
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat);
|
||||
|
||||
auto process = g_context.findProcessByHostId(result);
|
||||
if (process == nullptr) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
if (status != nullptr) {
|
||||
ORBIS_RET_ON_ERROR(uwrite(status, stat));
|
||||
}
|
||||
thread->retval[0] = process->pid;
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "sys/sysproto.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
#include <thread>
|
||||
|
||||
orbis::SysResult
|
||||
|
|
@ -24,11 +25,15 @@ orbis::SysResult orbis::sys_sched_yield(Thread *thread) {
|
|||
}
|
||||
orbis::SysResult orbis::sys_sched_get_priority_max(Thread *thread,
|
||||
sint policy) {
|
||||
return ErrorCode::NOSYS;
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, policy);
|
||||
thread->retval[0] = 90;
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_sched_get_priority_min(Thread *thread,
|
||||
sint policy) {
|
||||
return ErrorCode::NOSYS;
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, policy);
|
||||
thread->retval[0] = 10;
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_sched_rr_get_interval(Thread *thread, pid_t pid,
|
||||
ptr<timespec> interval) {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
#include <pipe.hpp>
|
||||
|
||||
orbis::SysResult orbis::sys_pipe(Thread *thread) {
|
||||
auto pipe = createPipe();
|
||||
auto fd0 = thread->tproc->fileDescriptors.insert(pipe);
|
||||
auto fd1 = thread->tproc->fileDescriptors.insert(pipe);
|
||||
auto [a, b] = createPipe();
|
||||
auto fd0 = thread->tproc->fileDescriptors.insert(a);
|
||||
auto fd1 = thread->tproc->fileDescriptors.insert(b);
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, fd0, fd1);
|
||||
thread->retval[0] = fd0;
|
||||
thread->retval[1] = fd1;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "sys/sysproto.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
|
||||
namespace orbis {
|
||||
struct rlimit {
|
||||
|
|
@ -7,7 +8,6 @@ struct rlimit {
|
|||
};
|
||||
} // namespace orbis
|
||||
|
||||
|
||||
orbis::SysResult orbis::sys_getpriority(Thread *thread, sint which, sint who) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
|
|
@ -18,7 +18,12 @@ orbis::SysResult orbis::sys_setpriority(Thread *thread, sint which, sint who,
|
|||
orbis::SysResult orbis::sys_rtprio_thread(Thread *thread, sint function,
|
||||
lwpid_t lwpid,
|
||||
ptr<struct rtprio> rtp) {
|
||||
std::printf("sys_rtprio_thread: unimplemented\n");
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, function, lwpid, rtp->prio, rtp->type);
|
||||
thread->where();
|
||||
if (function == 0) {
|
||||
rtp->type = 2;
|
||||
rtp->prio = 10;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_rtprio(Thread *thread, sint function, pid_t pid,
|
||||
|
|
|
|||
|
|
@ -281,11 +281,13 @@ orbis::SysResult orbis::sys_evf_wait(Thread *thread, sint id,
|
|||
}
|
||||
|
||||
std::uint32_t resultTimeout{};
|
||||
if (pTimeout != nullptr) {
|
||||
ORBIS_RET_ON_ERROR(uread(resultTimeout, pTimeout));
|
||||
}
|
||||
|
||||
auto result = evf->wait(thread, mode, patternSet,
|
||||
pTimeout != nullptr ? &resultTimeout : nullptr);
|
||||
|
||||
ORBIS_LOG_TRACE("sys_evf_wait wakeup", thread->tid, thread->evfResultPattern);
|
||||
|
||||
if (pPatternSet != nullptr) {
|
||||
ORBIS_RET_ON_ERROR(uwrite(pPatternSet, thread->evfResultPattern));
|
||||
}
|
||||
|
|
@ -336,7 +338,7 @@ orbis::SysResult orbis::sys_evf_set(Thread *thread, sint id, uint64_t value) {
|
|||
return ErrorCode::SRCH;
|
||||
}
|
||||
|
||||
ORBIS_LOG_TRACE(__FUNCTION__, evf->name, thread->tid, id, value);
|
||||
// ORBIS_LOG_TRACE(__FUNCTION__, evf->name, thread->tid, id, value);
|
||||
evf->set(value);
|
||||
return {};
|
||||
}
|
||||
|
|
@ -960,7 +962,7 @@ orbis::SysResult orbis::sys_mdbg_service(Thread *thread, uint32_t op,
|
|||
}
|
||||
|
||||
case 0x14: {
|
||||
std::this_thread::sleep_for(std::chrono::years(1));
|
||||
// std::this_thread::sleep_for(std::chrono::years(1));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1184,6 +1186,11 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid,
|
|||
return sysIpmiSendConnectResult(thread, result, kid, params, paramsSz);
|
||||
case 0x232:
|
||||
return sysIpmiSessionRespondSync(thread, result, kid, params, paramsSz);
|
||||
case 0x241:
|
||||
return sysIpmiClientInvokeAsyncMethod(thread, result, kid, params,
|
||||
paramsSz);
|
||||
case 0x243:
|
||||
return sysIpmiClientTryGetResult(thread, result, kid, params, paramsSz);
|
||||
case 0x251:
|
||||
return sysIpmiClientGetMessage(thread, result, kid, params, paramsSz);
|
||||
case 0x252:
|
||||
|
|
@ -1202,12 +1209,35 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid,
|
|||
return sysIpmiSessionGetUserData(thread, result, kid, params, paramsSz);
|
||||
case 0x46a:
|
||||
return sysIpmiServerGetName(thread, result, kid, params, paramsSz);
|
||||
case 0x490:
|
||||
return sysIpmiClientWaitEventFlag(thread, result, kid, params, paramsSz);
|
||||
case 0x491:
|
||||
return sysIpmiClientPollEventFlag(thread, result, kid, params, paramsSz);
|
||||
case 0x493:
|
||||
return sysIpmiSessionSetEventFlag(thread, result, kid, params, paramsSz);
|
||||
}
|
||||
|
||||
if (auto ipmi = thread->tproc->ipmiMap.get(kid)) {
|
||||
if (auto client = ipmi.cast<IpmiClient>()) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, client->name, result,
|
||||
params, paramsSz);
|
||||
thread->where();
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
if (auto server = ipmi.cast<IpmiServer>()) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, server->name, result,
|
||||
params, paramsSz);
|
||||
thread->where();
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
if (auto session = ipmi.cast<IpmiSession>(); session && session->client) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, session->client->name,
|
||||
result, params, paramsSz);
|
||||
thread->where();
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, kid, result, params, paramsSz);
|
||||
thread->where();
|
||||
return uwrite(result, 0u);
|
||||
|
|
@ -1247,16 +1277,22 @@ orbis::SysResult orbis::sys_physhm_unlink(Thread *thread /* TODO */) {
|
|||
orbis::SysResult orbis::sys_resume_internal_hdd(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_thr_suspend_ucontext(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
orbis::SysResult orbis::sys_thr_suspend_ucontext(Thread *thread, lwpid_t tid) {
|
||||
// ORBIS_LOG_FATAL(__FUNCTION__, tid);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_thr_resume_ucontext(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
orbis::SysResult orbis::sys_thr_resume_ucontext(Thread *thread, lwpid_t tid) {
|
||||
// ORBIS_LOG_FATAL(__FUNCTION__, tid);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_thr_get_ucontext(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
orbis::SysResult orbis::sys_thr_get_ucontext(Thread *thread, lwpid_t tid,
|
||||
ptr<UContext> context) {
|
||||
// ORBIS_LOG_FATAL(__FUNCTION__, tid, context);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_thr_set_ucontext(Thread *thread /* TODO */) {
|
||||
orbis::SysResult orbis::sys_thr_set_ucontext(Thread *thread, lwpid_t tid,
|
||||
ptr<UContext> context) {
|
||||
ORBIS_LOG_FATAL(__FUNCTION__, tid, context);
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_set_timezone_info(Thread *thread /* TODO */) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
#include "sys/sysproto.hpp"
|
||||
#include <thread>
|
||||
|
||||
orbis::SysResult orbis::sys_yield(Thread *thread) { return ErrorCode::NOSYS; }
|
||||
orbis::SysResult orbis::sys_yield(Thread *thread) {
|
||||
std::this_thread::yield();
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
|
||||
enum sysctl_kern {
|
||||
usrstack = 33,
|
||||
kern_14 = 14,
|
||||
kern_37 = 37,
|
||||
proc = 14,
|
||||
arnd = 37,
|
||||
|
||||
// FIXME
|
||||
smp_cpus = 1000,
|
||||
|
|
@ -39,15 +39,25 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
kern_heap_size,
|
||||
};
|
||||
|
||||
enum sysctl_hw_config { chassis_info };
|
||||
enum sysctl_hw_config {
|
||||
chassis_info,
|
||||
optical_out = 1000,
|
||||
};
|
||||
|
||||
enum sysctl_machdep {
|
||||
// FIXME
|
||||
tsc_freq = 1000,
|
||||
liverpool,
|
||||
bootparams,
|
||||
};
|
||||
|
||||
enum sysctl_machdep_liverpool { telemetry = 1000, icc_max };
|
||||
enum sysctl_machdep_liverpool {
|
||||
telemetry = 1000,
|
||||
icc_max,
|
||||
};
|
||||
enum sysctl_machdep_bootparams {
|
||||
is_main_on_standby = 1000,
|
||||
};
|
||||
|
||||
struct ProcInfo {
|
||||
char data[0x448];
|
||||
|
|
@ -60,7 +70,17 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
if (namelen == 3) {
|
||||
// 1 - 14 - 41 - debug flags?
|
||||
|
||||
if (name[0] == kern && name[1] == 14 && name[2] == 41) {
|
||||
if (name[0] == machdep && name[1] == bootparams &&
|
||||
name[2] == is_main_on_standby) {
|
||||
if (*oldlenp != 4 || new_ != nullptr || newlen != 0) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
*(uint32_t *)old = 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (name[0] == kern && name[1] == proc && name[2] == 41) {
|
||||
// std::printf(" kern.14.41\n");
|
||||
|
||||
if (*oldlenp != 4 || new_ != nullptr || newlen != 0) {
|
||||
|
|
@ -71,7 +91,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
return {};
|
||||
}
|
||||
|
||||
if (name[0] == kern && name[1] == 14 && name[2] == 42) {
|
||||
if (name[0] == kern && name[1] == proc && name[2] == 42) {
|
||||
// std::printf(" kern.14.42\n");
|
||||
|
||||
if ((oldlenp != nullptr && *oldlenp != 0) || new_ == nullptr ||
|
||||
|
|
@ -85,8 +105,10 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
return {};
|
||||
}
|
||||
|
||||
if (name[0] == kern && name[1] == 14 && name[2] == 8) {
|
||||
if (name[0] == kern && name[1] == proc && name[2] == 8) {
|
||||
// KERN_PROC_PROC
|
||||
ORBIS_LOG_ERROR("KERN_PROC_PROC");
|
||||
thread->where();
|
||||
std::memset(old, 0, sizeof(ProcInfo));
|
||||
*oldlenp = sizeof(ProcInfo);
|
||||
return {};
|
||||
|
|
@ -120,13 +142,15 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
}
|
||||
|
||||
if (namelen == 4) {
|
||||
if (name[0] == kern && name[1] == 14 && name[2] == 1) {
|
||||
if (name[0] == kern && name[1] == proc && name[2] == 1) {
|
||||
ORBIS_LOG_ERROR("KERN_PROC_PROC 2");
|
||||
|
||||
std::memset(old, 0, sizeof(ProcInfo));
|
||||
*oldlenp = sizeof(ProcInfo);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (name[0] == 1 && name[1] == 14 && name[2] == 35) {
|
||||
if (name[0] == 1 && name[1] == proc && name[2] == 35) {
|
||||
// AppInfo get/set
|
||||
|
||||
// 1 - 14 - 35 - pid
|
||||
|
|
@ -346,6 +370,24 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
|
||||
dest[count++] = vm;
|
||||
dest[count++] = swap_total;
|
||||
} else if (searchName == "machdep.bootparams.is_main_on_standby") {
|
||||
if (*oldlenp < 3 * sizeof(uint32_t)) {
|
||||
std::fprintf(stderr, " %s error\n", searchName.data());
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
dest[count++] = machdep;
|
||||
dest[count++] = bootparams;
|
||||
dest[count++] = is_main_on_standby;
|
||||
} else if (searchName == "hw.config.optical_out") {
|
||||
if (*oldlenp < 3 * sizeof(uint32_t)) {
|
||||
std::fprintf(stderr, " %s error\n", searchName.data());
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
dest[count++] = hw;
|
||||
dest[count++] = config;
|
||||
dest[count++] = optical_out;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
|
|
@ -411,7 +453,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
|||
std::memset(old, 0, 0x40);
|
||||
return {};
|
||||
|
||||
case sysctl_kern::kern_37: {
|
||||
case sysctl_kern::arnd: {
|
||||
struct kern37_value {
|
||||
std::uint64_t size;
|
||||
std::uint64_t unk[7];
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr<void> obj, sint op,
|
|||
});
|
||||
}
|
||||
case 18:
|
||||
return umtx_wake_umutex(thread, (ptr<umutex>)obj);
|
||||
return umtx_wake_umutex(thread, (ptr<umutex>)obj, 0);
|
||||
case 19:
|
||||
return with_timeout(
|
||||
[&](std::uint64_t ut) {
|
||||
|
|
@ -171,8 +171,9 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr<void> obj, sint op,
|
|||
case 22:
|
||||
return umtx_wake2_umutex(thread, obj, val, uaddr1, uaddr2);
|
||||
case 23:
|
||||
ORBIS_LOG_ERROR("sys__umtx_op: unknown wake operation", op);
|
||||
return umtx_wake_umutex(thread, (orbis::ptr<orbis::umutex>)obj);
|
||||
ORBIS_LOG_ERROR("sys__umtx_op: unknown wake operation", op, val, uaddr1, uaddr2);
|
||||
// thread->where();
|
||||
return umtx_wake_umutex(thread, (orbis::ptr<orbis::umutex>)obj, val);
|
||||
}
|
||||
|
||||
return ErrorCode::INVAL;
|
||||
|
|
|
|||
|
|
@ -187,12 +187,12 @@ static ErrorCode do_lock_normal(Thread *thread, ptr<umutex> m, uint flags,
|
|||
}
|
||||
static ErrorCode do_lock_pi(Thread *thread, ptr<umutex> m, uint flags,
|
||||
std::uint64_t ut, umutex_lock_mode mode) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode);
|
||||
// ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode);
|
||||
return do_lock_normal(thread, m, flags, ut, mode);
|
||||
}
|
||||
static ErrorCode do_lock_pp(Thread *thread, ptr<umutex> m, uint flags,
|
||||
std::uint64_t ut, umutex_lock_mode mode) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode);
|
||||
// ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode);
|
||||
return do_lock_normal(thread, m, flags, ut, mode);
|
||||
}
|
||||
static ErrorCode do_unlock_normal(Thread *thread, ptr<umutex> m, uint flags) {
|
||||
|
|
@ -576,17 +576,18 @@ orbis::ErrorCode orbis::umtx_rw_unlock(Thread *thread, ptr<urwlock> rwlock) {
|
|||
|
||||
auto state = rwlock->state.load(std::memory_order::relaxed);
|
||||
if (state & kUrwLockWriteOwner) {
|
||||
while (true) {
|
||||
if (rwlock->state.compare_exchange_weak(state, state & ~kUrwLockWriteOwner)) {
|
||||
while (true) {
|
||||
if (rwlock->state.compare_exchange_weak(state,
|
||||
state & ~kUrwLockWriteOwner)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(state & kUrwLockWriteOwner)) {
|
||||
return ErrorCode::PERM;
|
||||
}
|
||||
}
|
||||
} else if ((state & kUrwLockMaxReaders) != 0) {
|
||||
while (true) {
|
||||
}
|
||||
} else if ((state & kUrwLockMaxReaders) != 0) {
|
||||
while (true) {
|
||||
if (rwlock->state.compare_exchange_weak(state, state - 1)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -594,26 +595,26 @@ orbis::ErrorCode orbis::umtx_rw_unlock(Thread *thread, ptr<urwlock> rwlock) {
|
|||
if ((state & kUrwLockMaxReaders) == 0) {
|
||||
return ErrorCode::PERM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ErrorCode::PERM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ErrorCode::PERM;
|
||||
}
|
||||
|
||||
unsigned count = 0;
|
||||
|
||||
if (!(flags & kUrwLockPreferReader)) {
|
||||
if (state & kUrwLockWriteWaiters) {
|
||||
count = 1;
|
||||
} else if (state & kUrwLockReadWaiters) {
|
||||
count = UINT_MAX;
|
||||
}
|
||||
} else {
|
||||
if (state & kUrwLockReadWaiters) {
|
||||
count = UINT_MAX;
|
||||
} else if (state & kUrwLockWriteWaiters) {
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
if (state & kUrwLockWriteWaiters) {
|
||||
count = 1;
|
||||
} else if (state & kUrwLockReadWaiters) {
|
||||
count = UINT_MAX;
|
||||
}
|
||||
} else {
|
||||
if (state & kUrwLockReadWaiters) {
|
||||
count = UINT_MAX;
|
||||
} else if (state & kUrwLockWriteWaiters) {
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
chain.notify_one(key);
|
||||
|
|
@ -655,7 +656,8 @@ orbis::ErrorCode orbis::umtx_wait_umutex(Thread *thread, ptr<umutex> m,
|
|||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
orbis::ErrorCode orbis::umtx_wake_umutex(Thread *thread, ptr<umutex> m) {
|
||||
orbis::ErrorCode orbis::umtx_wake_umutex(Thread *thread, ptr<umutex> m,
|
||||
sint wakeFlags) {
|
||||
ORBIS_LOG_TRACE(__FUNCTION__, m);
|
||||
int owner = m->owner.load(std::memory_order::acquire);
|
||||
if ((owner & ~kUmutexContested) != 0)
|
||||
|
|
@ -671,8 +673,13 @@ orbis::ErrorCode orbis::umtx_wake_umutex(Thread *thread, ptr<umutex> m) {
|
|||
owner = kUmutexContested;
|
||||
m->owner.compare_exchange_strong(owner, kUmutexUnowned);
|
||||
}
|
||||
if (count != 0 && (owner & ~kUmutexContested) == 0)
|
||||
chain.notify_one(key);
|
||||
if (count != 0 && (owner & ~kUmutexContested) == 0) {
|
||||
if ((wakeFlags & 0x400) || (flags & 1)) {
|
||||
chain.notify_all(key);
|
||||
} else {
|
||||
chain.notify_one(key);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "io-device.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
|
||||
struct AjmFile : orbis::File {};
|
||||
|
|
@ -8,7 +9,17 @@ struct AjmFile : orbis::File {};
|
|||
static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request,
|
||||
void *argp, orbis::Thread *thread) {
|
||||
|
||||
// 0xc0288903 - module register
|
||||
// 0xc0288904 - module unregister
|
||||
if (request == 0xc0288903 || request == 0xc0288904) {
|
||||
auto arg = reinterpret_cast<std::uint32_t *>(argp)[2];
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, request, arg);
|
||||
*reinterpret_cast<std::uint64_t *>(argp) = 0;
|
||||
// return{};
|
||||
}
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled AJM ioctl", request);
|
||||
thread->where();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#include "io-device.hpp"
|
||||
#include "orbis-config.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/error/ErrorCode.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
|
||||
struct AVControlFile : orbis::File {};
|
||||
|
|
@ -8,7 +11,21 @@ struct AVControlFile : orbis::File {};
|
|||
static orbis::ErrorCode av_control_ioctl(orbis::File *file, std::uint64_t request,
|
||||
void *argp, orbis::Thread *thread) {
|
||||
|
||||
if (request == 0xc0109a0e) {
|
||||
struct Args {
|
||||
orbis::sint unk;
|
||||
orbis::sint padding;
|
||||
orbis::ptr<orbis::sint> pResult;
|
||||
};
|
||||
|
||||
Args _args;
|
||||
ORBIS_RET_ON_ERROR(orbis::uread(_args, orbis::ptr<Args>(argp)));
|
||||
|
||||
return orbis::uwrite(_args.pResult, 1);
|
||||
}
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled av_control ioctl", request);
|
||||
thread->where();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "io-device.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
|
||||
struct HDMIFile : orbis::File {};
|
||||
|
|
@ -9,6 +10,7 @@ static orbis::ErrorCode hdmi_ioctl(orbis::File *file, std::uint64_t request,
|
|||
void *argp, orbis::Thread *thread) {
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled hdmi ioctl", request);
|
||||
thread->where();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
|||
rx::vm::mapProtToString(origVmProt).c_str());
|
||||
}
|
||||
|
||||
if (orbis::g_currentThread != nullptr) {
|
||||
orbis::g_currentThread->tproc->event.emit(orbis::kEvFiltProc, orbis::kNoteExit, sig);
|
||||
}
|
||||
|
||||
if (g_gpuPid > 0) {
|
||||
// stop gpu thread
|
||||
// ::kill(g_gpuPid, SIGINT);
|
||||
|
|
@ -673,9 +677,12 @@ static void runRpsxGpu() {
|
|||
static orbis::Semaphore *createSemaphore(std::string_view name, uint32_t attrs,
|
||||
uint64_t initCount,
|
||||
uint64_t maxCount) {
|
||||
return orbis::g_context
|
||||
auto result = orbis::g_context
|
||||
.createSemaphore(orbis::kstring(name), attrs, initCount, maxCount)
|
||||
.first;
|
||||
std::memcpy(result->name, name.data(), name.size());
|
||||
result->name[name.size()] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static orbis::EventFlag *createEventFlag(std::string_view name, uint32_t attrs,
|
||||
|
|
@ -1653,7 +1660,10 @@ int main(int argc, const char *argv[]) {
|
|||
createGnmCompositorObjects(initProcess);
|
||||
createShellCoreObjects(initProcess);
|
||||
|
||||
createIpmiServer(initProcess, "SceCdlgRichProf"); // ?
|
||||
// ?
|
||||
createIpmiServer(initProcess, "SceCdlgRichProf");
|
||||
createIpmiServer(initProcess, "SceRemoteplayIpc");
|
||||
createIpmiServer(initProcess, "SceGlsIpc");
|
||||
initProcess->cwd = "/app0/";
|
||||
|
||||
launchDaemon(mainThread, "/system/sys/orbis_audiod.elf",
|
||||
|
|
|
|||
|
|
@ -369,6 +369,7 @@ orbis::SysResult socketPair(orbis::Thread *thread, orbis::sint domain,
|
|||
|
||||
*a = wrapSocket(fds[0], "", domain, type, protocol);
|
||||
*b = wrapSocket(fds[1], "", domain, type, protocol);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto result = wrapSocket(-1, "", domain, type, protocol);
|
||||
|
|
@ -551,8 +552,13 @@ SysResult thr_new(orbis::Thread *thread, orbis::ptr<thr_param> param,
|
|||
// FIXME: implement scheduler
|
||||
|
||||
ORBIS_LOG_NOTICE("Starting child thread", childThread->tid,
|
||||
childThread->stackStart);
|
||||
|
||||
childThread->stackStart, _param.rtp, _param.name,
|
||||
_param.spare[0], _param.spare[1]);
|
||||
if (_param.rtp != 0) {
|
||||
rtprio _rtp;
|
||||
ORBIS_RET_ON_ERROR(uread(_rtp, _param.rtp));
|
||||
ORBIS_LOG_NOTICE(" rtp: ", _rtp.type, _rtp.prio);
|
||||
}
|
||||
auto stdthr = std::thread{[=, childThread = Ref<Thread>(childThread)] {
|
||||
static_cast<void>(
|
||||
uwrite(_param.child_tid, slong(childThread->tid))); // TODO: verify
|
||||
|
|
@ -712,9 +718,9 @@ SysResult processNeeded(Thread *thread) {
|
|||
}
|
||||
|
||||
SysResult fork(Thread *thread, slong flags) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, flags);
|
||||
|
||||
auto childPid = g_context.allocatePid() * 10000 + 1;
|
||||
ORBIS_LOG_TODO(__FUNCTION__, flags, childPid, thread->tid);
|
||||
thread->where();
|
||||
auto flag = knew<std::atomic<bool>>();
|
||||
*flag = false;
|
||||
|
||||
|
|
@ -790,6 +796,7 @@ SysResult fork(Thread *thread, slong flags) {
|
|||
SysResult execve(Thread *thread, ptr<char> fname, ptr<ptr<char>> argv,
|
||||
ptr<ptr<char>> envv) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, fname);
|
||||
thread->where();
|
||||
|
||||
std::vector<std::string> _argv;
|
||||
std::vector<std::string> _envv;
|
||||
|
|
|
|||
Loading…
Reference in a new issue