mirror of
https://github.com/valentderah/totk-pc-recomp.git
synced 2026-11-11 18:01:03 +00:00
Shared runtime code now goes through runtime/platform/platform.h, implemented by platform/win32.c and a new platform/linux.c: futex locks, a userfaultfd and PAGEMAP_SCAN write watch, signal-based async preemption, our own fiber switch, and a SIGSEGV handler for the thaw and crash hooks. The window, input, menu and software keyboard get SDL3 back ends beside the Win32 ones, with the swapchain (gfx_present.c) and input merging (input.c) shared. SHA-256 replaces BCrypt, ELF builds get their own override sections, and the build tools gain Linux branches. On Linux the selftest and the gfx-abi, astc, nvn and window probes pass. probe-vkmem still fails: imported guest memory cannot be write-watched on Linux, which the shadow buffers in vk_memory.c will address.
69 lines
2.9 KiB
C
69 lines
2.9 KiB
C
// Adapted from MacNativeGames games/totk/runtime/ipc.h @ b75be8c (MIT, Copyright (c) 2026 MacNativeGames
|
|
// contributors). Message framing per libnx sf/hipc.h, cmif.h, tipc.h (ISC), read for the layout only.
|
|
// In-process Horizon IPC: HIPC messages with CMIF or TIPC payloads, answered in
|
|
// place in the caller's message buffer. Services are host implementations looked up by name through sm:.
|
|
#pragma once
|
|
#include <stdint.h>
|
|
|
|
#include "host.h"
|
|
|
|
#define IPC_MAX_BUF 8
|
|
#define IPC_MSG_BYTES 0x100
|
|
#define IPC_R_BAD_HANDLE 0xE401u // kernel: invalid handle
|
|
#define IPC_R_UNKNOWN_COMMAND 0xF601u // sf: unknown command (module 10, description 123)
|
|
|
|
typedef struct { uint64_t addr, size; unsigned index; } IpcBuffer;
|
|
|
|
typedef struct {
|
|
unsigned type, cmd; // HIPC type (4/5/6/7 CMIF, >= 16 TIPC) and command id
|
|
int has_pid;
|
|
uint64_t pid;
|
|
uint32_t copy[8], move[8];
|
|
unsigned ncopy, nmove;
|
|
IpcBuffer x[IPC_MAX_BUF], a[IPC_MAX_BUF], b[IPC_MAX_BUF], w[IPC_MAX_BUF], c[IPC_MAX_BUF];
|
|
unsigned nx, na, nb, nw, nc;
|
|
const uint8_t *data; // command arguments after the CMIF header (TIPC: after the HIPC header)
|
|
uint32_t data_size;
|
|
} IpcRequest;
|
|
|
|
typedef struct {
|
|
uint32_t result;
|
|
uint8_t data[0x100];
|
|
uint32_t data_size;
|
|
uint32_t copy[8], move[8];
|
|
unsigned ncopy, nmove;
|
|
IpcBuffer xout[IPC_MAX_BUF]; // pointer data the service placed into the client's C buffers
|
|
unsigned nxout;
|
|
} IpcResponse;
|
|
|
|
typedef struct IpcSession IpcSession;
|
|
typedef void (*IpcHandler)(IpcSession *s, const IpcRequest *rq, IpcResponse *rs);
|
|
|
|
// One server object. Every kernel handle to it (the first one, CloneCurrentObject copies) holds a reference; the
|
|
// last CloseHandle calls close(state).
|
|
struct IpcSession {
|
|
const char *name;
|
|
IpcHandler handler;
|
|
void *state;
|
|
void (*close)(void *state);
|
|
int32_t refs;
|
|
};
|
|
|
|
uint32_t ipc_session_new(const char *name, IpcHandler handler, void *state, void (*close)(void *state)); // handle
|
|
void ipc_out(IpcResponse *rs, const void *p, uint32_t n);
|
|
const void *ipc_arg(const IpcRequest *rq, uint32_t off, uint32_t n);
|
|
void *ipc_guest(uint64_t addr, uint64_t size); // a client buffer as a host pointer (identity map), range checked
|
|
__attribute__((noreturn)) void ipc_unimplemented(const IpcSession *s, const IpcRequest *rq);
|
|
#define IPC_OUT(rs, v) ipc_out((rs), &(v), sizeof(v))
|
|
#define IPC_ARG(rq, T, off) (*(const T *)ipc_arg((rq), (off), sizeof(T)))
|
|
|
|
// Transfer memory from svcCreateTransferMemory (0x15), a KERN_TMEM handle object.
|
|
typedef struct { uint64_t addr, size; uint32_t perm; } IpcTransferMemory;
|
|
|
|
// Server objects alive now and closed so far (the probe checks CloseHandle releases them).
|
|
long ipc_sessions_live(void);
|
|
uint64_t ipc_sessions_released(void);
|
|
|
|
// The guest frame chain of the request being served, for fatal reports from services.
|
|
void ipc_backtrace(void);
|