Skip to content

Commit

Permalink
implement unix socket ops
Browse files Browse the repository at this point in the history
implement cross process dmem support
implement ipmi try send message
implement sys_batch_map
store saves to game directory (.rpcsx subfolder)
fix get dir entries
added uvd & vce devices
  • Loading branch information
DHrpcs3 committed Dec 31, 2023
1 parent a6211b5 commit 6e25f34
Show file tree
Hide file tree
Showing 39 changed files with 1,509 additions and 277 deletions.
42 changes: 36 additions & 6 deletions hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#pragma once

#include <orbis/utils/SharedMutex.hpp>
#include <atomic>
#include <cstdint>
#include <cstring>
#include <initializer_list>
#include <orbis/utils/SharedCV.hpp>

namespace amdgpu::bridge {
extern std::uint32_t expGpuPid;
Expand Down Expand Up @@ -45,7 +45,8 @@ enum class CommandId : std::uint32_t {
Nop,
ProtectMemory,
CommandBuffer,
Flip
Flip,
MapDmem,
};

struct CmdMemoryProt {
Expand Down Expand Up @@ -77,6 +78,15 @@ struct CmdFlip {
std::uint64_t arg;
};

struct CmdMapDmem {
std::uint64_t offset;
std::uint64_t address;
std::uint64_t size;
std::uint32_t prot;
std::uint32_t pid;
std::uint32_t dmemIndex;
};

enum {
kPageWriteWatch = 1 << 0,
kPageReadWriteLock = 1 << 1,
Expand All @@ -91,6 +101,7 @@ struct BridgeHeader {
std::uint64_t info;
std::uint32_t pullerPid;
std::uint32_t pusherPid;
std::atomic<std::uint64_t> lock;
volatile std::uint64_t flags;
std::uint64_t vmAddress;
std::uint64_t vmSize;
Expand All @@ -103,7 +114,7 @@ struct BridgeHeader {
std::uint32_t memoryAreaCount;
std::uint32_t commandBufferCount;
std::uint32_t bufferCount;
CmdMemoryProt memoryAreas[128];
CmdMemoryProt memoryAreas[512];
CmdCommandBuffer commandBuffers[32];
CmdBuffer buffers[10];
// orbis::shared_mutex cacheCommandMtx;
Expand All @@ -125,6 +136,7 @@ struct Command {
CmdCommandBuffer commandBuffer;
CmdBuffer buffer;
CmdFlip flip;
CmdMapDmem mapDmem;
};
};

Expand All @@ -137,9 +149,6 @@ enum class BridgeFlags {
struct BridgePusher {
BridgeHeader *header = nullptr;

BridgePusher() = default;
BridgePusher(BridgeHeader *header) : header(header) {}

void setVm(std::uint64_t address, std::uint64_t size, const char *name) {
header->vmAddress = address;
header->vmSize = size;
Expand All @@ -155,6 +164,12 @@ struct BridgePusher {
}
}

void sendMapDmem(std::uint32_t pid, std::uint32_t dmemIndex, std::uint64_t address, std::uint64_t size, std::uint32_t prot, std::uint64_t offset) {
if (pid == expGpuPid) {
sendCommand(CommandId::MapDmem, {pid, dmemIndex, address, size, prot, offset});
}
}

void sendCommandBuffer(std::uint32_t pid, std::uint64_t queue,
std::uint64_t address, std::uint64_t size) {
if (pid == expGpuPid) {
Expand All @@ -181,6 +196,11 @@ struct BridgePusher {
}

void sendCommand(CommandId id, std::initializer_list<std::uint64_t> args) {
std::uint64_t exp = 0;
while (!header->lock.compare_exchange_weak(exp, 1, std::memory_order::acquire, std::memory_order::relaxed)) {
exp = 0;
}

std::size_t cmdSize = args.size() + 1;
std::uint64_t pos = getPushPosition(cmdSize);

Expand All @@ -189,6 +209,7 @@ struct BridgePusher {
header->commands[pos++] = arg;
}
header->push = pos;
header->lock.store(0, std::memory_order::release);
}

std::uint64_t getPushPosition(std::uint64_t cmdSize) {
Expand Down Expand Up @@ -279,6 +300,15 @@ struct BridgePuller {
result.flip.bufferIndex = args[1];
result.flip.arg = args[2];
return result;

case CommandId::MapDmem:
result.mapDmem.pid = args[0];
result.mapDmem.dmemIndex = args[1];
result.mapDmem.address = args[2];
result.mapDmem.size = args[3];
result.mapDmem.prot = args[4];
result.mapDmem.offset = args[5];
return result;
}

__builtin_trap();
Expand Down
36 changes: 22 additions & 14 deletions hw/amdgpu/device/src/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ using namespace amdgpu::device;
static const bool kUseDirectMemory = false;
static amdgpu::bridge::BridgeHeader *g_bridge;

void *g_rwMemory;
// void *g_rwMemory;
std::size_t g_memorySize;
std::uint64_t g_memoryBase;
RemoteMemory g_hostMemory;
Expand Down Expand Up @@ -4577,6 +4577,9 @@ static auto g_commandHandlers = [] {
static void handleCommandBuffer(TaskChain &waitTaskSet, QueueRegisters &regs,
std::span<std::uint32_t> &packets) {
while (!packets.empty()) {
// std::uint64_t address =
// (char *)packets.data() - g_hostMemory.shmPointer + 0x40000;
// std::fprintf(stderr, "address = %lx\n", address);
auto cmd = packets[0];
auto type = getBits(cmd, 31, 30);

Expand Down Expand Up @@ -4637,29 +4640,29 @@ void amdgpu::device::AmdgpuDevice::handleProtectMemory(std::uint64_t address,
break;

case PROT_WRITE | PROT_READ:
protStr = "W";
protStr = "RW";
break;

default:
protStr = "unknown";
break;
}
std::printf("Allocated area at %zx, size %lx, prot %s\n", address, size,
protStr);
std::fprintf(stderr, "Allocated area at %zx, size %lx, prot %s\n", address,
size, protStr);
} else {
memoryAreaTable.unmap(beginPage, endPage);
std::printf("Unmapped area at %zx, size %lx\n", address, size);
std::fprintf(stderr, "Unmapped area at %zx, size %lx\n", address, size);
}

std::size_t index = 0;
for (auto area : memoryAreaTable) {
// std::printf("area %lx-%lx\n", area.beginAddress * kPageSize,
// area.endAddress * kPageSize);

if (index >= std::size(g_bridge->memoryAreas)) {
util::unreachable("too many memory areas");
}

// std::printf("area %lx-%lx\n", area.beginAddress * kPageSize,
// area.endAddress * kPageSize);

g_bridge->memoryAreas[index++] = {
.address = area.beginAddress * kPageSize,
.size = (area.endAddress - area.beginAddress) * kPageSize,
Expand All @@ -4685,11 +4688,16 @@ void amdgpu::device::AmdgpuDevice::handleCommandBuffer(std::uint64_t queueId,

if (inserted) {
std::printf("creation queue %lx\n", queueId);
it->second.sched.enqueue([=, queue = &it->second] {
if (queueId == 0xc0023f00) {
setThreadName("Graphics queue");
} else {
setThreadName(("Compute queue" + std::to_string(queueId)).c_str());
it->second.sched.enqueue([=, queue = &it->second,
initialized = false] mutable {
if (!initialized) {
initialized = true;

if (queueId == 0xc0023f00) {
setThreadName("Graphics queue");
} else {
setThreadName(("Compute queue" + std::to_string(queueId)).c_str());
}
}

Queue::CommandBuffer *commandBuffer;
Expand All @@ -4715,7 +4723,7 @@ void amdgpu::device::AmdgpuDevice::handleCommandBuffer(std::uint64_t queueId,
});
}

// std::printf("address = %lx, count = %lx\n", address, count);
// std::fprintf(stderr, "address = %lx, count = %lx\n", address, count);

std::lock_guard lock(it->second.mtx);
it->second.commandBuffers.push_back(
Expand Down
9 changes: 9 additions & 0 deletions orbis-kernel/include/orbis/SocketAddress.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

namespace orbis {
struct SocketAddress {
unsigned char len;
unsigned char family;
char data[14];
};
} // namespace orbis
31 changes: 31 additions & 0 deletions orbis-kernel/include/orbis/file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ struct KNote;
struct Thread;
struct Stat;
struct Uio;
struct SocketAddress;
struct msghdr;
struct sf_hdtr;

struct FileOps {
std::int32_t flags;
Expand Down Expand Up @@ -41,6 +44,33 @@ struct FileOps {
Thread *thread) = nullptr;
ErrorCode (*munmap)(File *file, void **address, std::uint64_t size,
Thread *thread) = nullptr;

ErrorCode (*bind)(orbis::File *file, SocketAddress *address,
std::size_t addressLen, Thread *thread) = nullptr;
ErrorCode (*listen)(orbis::File *file, int backlog, Thread *thread) = nullptr;
ErrorCode (*accept)(orbis::File *file, SocketAddress *address,
std::uint32_t *addressLen, Thread *thread) = nullptr;
ErrorCode (*connect)(orbis::File *file, SocketAddress *address,
std::uint32_t addressLen, Thread *thread) = nullptr;
ErrorCode (*sendto)(orbis::File *file, const void *buf, size_t len,
sint flags, caddr_t to, sint tolen,
Thread *thread) = nullptr;
ErrorCode (*sendmsg)(orbis::File *file, msghdr *msg, sint flags,
Thread *thread) = nullptr;
ErrorCode (*recvfrom)(orbis::File *file, void *buf, size_t len,
sint flags, SocketAddress *from, uint32_t *fromlenaddr,
Thread *thread) = nullptr;
ErrorCode (*recvmsg)(orbis::File *file, msghdr *msg, sint flags,
Thread *thread) = nullptr;
ErrorCode (*shutdown)(orbis::File *file, sint how, Thread *thread) = nullptr;
ErrorCode (*setsockopt)(orbis::File *file, sint level, sint name,
const void *val, sint valsize,
Thread *thread) = nullptr;
ErrorCode (*getsockopt)(orbis::File *file, sint level, sint name, void *val,
sint *avalsize, Thread *thread) = nullptr;
ErrorCode (*sendfile)(orbis::File *file, sint fd, off_t offset, size_t nbytes,
ptr<struct sf_hdtr> hdtr, ptr<off_t> sbytes, sint flags,
Thread *thread) = nullptr;
};

struct File : RcBase {
Expand All @@ -49,6 +79,7 @@ struct File : RcBase {
const FileOps *ops = nullptr;
Ref<RcBase> device;
std::uint64_t nextOff = 0;
int hostFd = -1;
utils::kvector<Dirent> dirEntries;
};
} // namespace orbis
9 changes: 8 additions & 1 deletion orbis-kernel/include/orbis/ipmi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ struct IpmiSession : RcBase {
EventFlag evf{0, 0};
shared_cv connectCv;
bool expectedOutput = false; // TODO: verify
bool connected = false; // TODO: implement more states
sint connectionStatus{0};
};

Expand Down Expand Up @@ -152,8 +151,16 @@ 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 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);
SysResult sysIpmiSessionGetClientPid(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result,
Expand Down
3 changes: 2 additions & 1 deletion orbis-kernel/include/orbis/note.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <set>

namespace orbis {

struct File;
static constexpr auto kEvFiltRead = -1;
static constexpr auto kEvFiltWrite = -2;
static constexpr auto kEvFiltAio = -3;
Expand Down Expand Up @@ -75,6 +75,7 @@ struct KQueue;
struct KNote {
shared_mutex mutex;
Ref<KQueue> queue;
Ref<File> file;
KEvent event{};
bool enabled = true;
bool triggered = false;
Expand Down
15 changes: 9 additions & 6 deletions orbis-kernel/include/orbis/sys/sysproto.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct timespec;
struct Stat;
struct stack_t;
struct IoVec;
struct BatchMapEntry;

SysResult nosys(Thread *thread);

Expand Down Expand Up @@ -53,13 +54,13 @@ SysResult sys_recvmsg(Thread *thread, sint s, ptr<struct msghdr> msg,
SysResult sys_sendmsg(Thread *thread, sint s, ptr<struct msghdr> msg,
sint flags);
SysResult sys_recvfrom(Thread *thread, sint s, caddr_t buf, size_t len,
sint flags, ptr<struct sockaddr> from,
sint flags, ptr<SocketAddress> from,
ptr<uint32_t> fromlenaddr);
SysResult sys_accept(Thread *thread, sint s, ptr<struct sockaddr> from,
SysResult sys_accept(Thread *thread, sint s, ptr<SocketAddress> from,
ptr<uint32_t> fromlenaddr);
SysResult sys_getpeername(Thread *thread, sint fdes, ptr<struct sockaddr> asa,
SysResult sys_getpeername(Thread *thread, sint fdes, ptr<SocketAddress> asa,
ptr<uint32_t> alen);
SysResult sys_getsockname(Thread *thread, sint fdes, ptr<struct sockaddr> asa,
SysResult sys_getsockname(Thread *thread, sint fdes, ptr<SocketAddress> asa,
ptr<uint32_t> alen);
SysResult sys_access(Thread *thread, ptr<char> path, sint flags);
SysResult sys_chflags(Thread *thread, ptr<char> path, sint flags);
Expand Down Expand Up @@ -634,7 +635,8 @@ SysResult sys_evf_cancel(Thread *thread, sint id, uint64_t value,
ptr<sint> pNumWaitThreads);
SysResult sys_query_memory_protection(Thread *thread, ptr<void> address,
ptr<MemoryProtection> protection);
SysResult sys_batch_map(Thread *thread /* TODO */);
SysResult sys_batch_map(Thread *thread, sint unk, sint flags, ptr<BatchMapEntry> entries,
sint entriesCount, ptr<sint> processedCount);
SysResult sys_osem_create(Thread *thread, ptr<const char[32]> name, uint attrs,
sint initCount, sint maxCount);
SysResult sys_osem_delete(Thread *thread, sint id);
Expand Down Expand Up @@ -720,7 +722,8 @@ SysResult sys_get_proc_type_info(Thread *thread, ptr<sint> destProcessInfo);
SysResult sys_get_resident_count(Thread *thread, pid_t pid);
SysResult sys_prepare_to_suspend_process(Thread *thread, pid_t pid);
SysResult sys_get_resident_fmem_count(Thread *thread, pid_t pid);
SysResult sys_thr_get_name(Thread *thread, lwpid_t lwpid);
SysResult sys_thr_get_name(Thread *thread, lwpid_t lwpid, char *buf,
size_t buflen);
SysResult sys_set_gpo(Thread *thread /* TODO */);
SysResult sys_get_paging_stats_of_all_objects(Thread *thread /* TODO */);
SysResult sys_test_debug_rwmem(Thread *thread /* TODO */);
Expand Down
2 changes: 2 additions & 0 deletions orbis-kernel/include/orbis/thread/ProcessOps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ struct ProcessOps {
SysResult (*blockpool_unmap)(Thread *thread, caddr_t addr, size_t len);
SysResult (*socket)(Thread *thread, ptr<const char> name, sint domain,
sint type, sint protocol, Ref<File> *file);
SysResult (*socketpair)(Thread *thread, sint domain, sint type, sint protocol,
Ref<File> *a, Ref<File> *b);
SysResult (*shm_unlink)(Thread *thread, const char *path);
SysResult (*dynlib_get_obj_member)(Thread *thread, ModuleHandle handle,
uint64_t index, ptr<ptr<void>> addrp);
Expand Down
Loading

0 comments on commit 6e25f34

Please sign in to comment.