From b12825bb9baa8a29694d27d434cfa3d9f1b062a3 Mon Sep 17 00:00:00 2001 From: Christopher Dellman <christopher@dellman.net> Date: Tue, 9 Jul 2024 22:38:39 -0400 Subject: [PATCH] Added presence IPC command --- patches/include/ipc.h | 162 ++++++++++++++++++++++++++++++----- patches/source/flippy_sync.c | 32 +++++++ patches/source/flippy_sync.h | 4 +- 3 files changed, 174 insertions(+), 24 deletions(-) diff --git a/patches/include/ipc.h b/patches/include/ipc.h index 45d0cfc..bd7fcc9 100644 --- a/patches/include/ipc.h +++ b/patches/include/ipc.h @@ -2,16 +2,26 @@ #include <stddef.h> #include <stdint.h> +#define FLIPPY_IPC_MAJORVER = 1; +#define FLIPPY_IPC_MINORVER = 3; + #define GCN_ALIGNED(type) type __attribute__((aligned(32))) +// Pre-C11: define a fallback mechanism +#define ASSERT_SIZE_MULTIPLE_OF_32(T) + //MUST be a multiple of 32 for DMA reasons in the cube #define MAX_FILE_NAME 256 #define FD_IPC_MAXRESP 1024*16 +#define FD_BYPASS_EXIT_MAGIC0 0xE3F72BAB +#define FD_BYPASS_EXIT_MAGIC1 0X72648977 + #define IPC_MAGIC 0xAA55F641 #pragma pack(push,1) #define IPC_READ_STATUS_RESPONSE_LEN sizeof(file_status_t) +#define IPC_FS_INFO_RESPONSE_LEN sizeof(fs_info_t) #define IPC_FILE_READ_RESPONSE_LEN read_len #define IPC_FILE_WRITE_RESPONSE_LEN 0 #define IPC_FILE_OPEN_RESPONSE_LEN 0 @@ -19,14 +29,26 @@ #define IPC_FILE_STAT_RESPONSE_LEN static_assert(0, "STAT format not yet defined"); #define IPC_FILE_SEEK_RESPONSE_LEN 0 #define IPC_FILE_UNLINK_RESPONSE_LEN 0 +#define IPC_FILE_MKDIR_RESPONSE_LEN 0 +#define IPC_FILE_RENAME_RESPONSE_LEN 0 #define IPC_FILE_READDIR_RESPONSE_LEN sizeof(file_entry_t) +#define IPC_NET_STATUS_RESPONSE_LEN sizeof(flippydrive_net_status_t) +#define IPC_NET_CONFIGURE_RESPONSE_LEN 0 +#define IPC_NET_PRESENCE_RESPONSE_LEN 0 -#define IPC_RESERVED0_SIZE 204 +#define IPC_WRITE_PAYLOAD_MAX_LEN FD_IPC_MAXRESP-32 + +#define IPC_RESERVED0_SIZE 224 typedef enum { IPC_READ_STATUS = 0x00, IPC_SET_DEFAULT_FD = 0x01, //Purely 2040 + IPC_RELOAD_CONFIG = 0x02, //Purely 2040 + IPC_NET_STATUS = 0x03, + IPC_RESET = 0x05, //Purely 2040 + IPC_FS_INFO = 0x06, + IPC_FILE_MKDIR = 0x07, IPC_FILE_READ = 0x08, IPC_FILE_WRITE = 0x09, IPC_FILE_OPEN = 0x0A, @@ -36,10 +58,12 @@ typedef enum { IPC_FILE_UNLINK = 0x0E, IPC_FILE_READDIR = 0x0F, - IPC_RESERVED0 = 0x10, + IPC_NET_CONFIGURE = 0x10, IPC_FILE_OPEN_FLASH = 0x11, //Purely 2040 IPC_FILE_UNLINK_FLASH = 0x12, //Purely 2040 - IPC_RESERVED3 = 0x13, + IPC_FILE_RENAME = 0x13, + + IPC_NET_PRESENCE = 0x14, IPC_CMD_MAX = 0x1F } ipc_command_type_t; @@ -49,15 +73,24 @@ typedef struct uint32_t result; uint64_t fsize; uint8_t fd; //Valid after open - uint8_t pad[19]; + uint8_t flags; + uint8_t pad[18]; } file_status_t; +ASSERT_SIZE_MULTIPLE_OF_32(file_status_t); + typedef struct { - uint8_t data[FD_IPC_MAXRESP-32]; -} file_payload_t; + uint32_t result; + uint64_t free; + uint64_t total; + uint8_t pad[12]; +} fs_info_t; + +ASSERT_SIZE_MULTIPLE_OF_32(fs_info_t); enum { + IPC_FILE_FLAG_NONE = 0x00, IPC_FILE_FLAG_DISABLECACHE = 0x01, IPC_FILE_FLAG_DISABLEFASTSEEK = 0x02, IPC_FILE_FLAG_DISABLESPEEDEMU = 0x04, @@ -74,6 +107,46 @@ typedef struct { uint8_t pad[10]; } file_entry_t; +ASSERT_SIZE_MULTIPLE_OF_32(file_entry_t); + +#define FLIPPYDRIVE_NET_STATE_MASK 0x7 +#define FLIPPYDRIVE_NET_FAIL_MASK 0x8 + +#define FLIPPYDRIVE_NET_STATE_NONE 0 +#define FLIPPYDRIVE_NET_STATE_LINK 1 +#define FLIPPYDRIVE_NET_STATE_IP 2 +#define FLIPPYDRIVE_NET_STATE_CONNECT 3 + +typedef struct +{ + uint8_t net_flags; + uint8_t net_status; + char ssid[33]; + char addrstr[40]; + uint8_t nm; + uint8_t gw[16]; + uint8_t dns0[16]; + uint8_t dns1[16]; + + uint8_t server[16]; + + uint8_t pad[20]; +} flippydrive_net_status_t; + +ASSERT_SIZE_MULTIPLE_OF_32(flippydrive_net_status_t); + +typedef struct +{ + uint8_t presence; //Bit 0 - Online/Active + char status[40]; + char sub_status[40]; + char sys_state[40]; + + uint8_t pad[135]; +} flippydrive_net_presence_t; + +ASSERT_SIZE_MULTIPLE_OF_32(flippydrive_net_presence_t); + typedef struct { uint32_t magic; uint8_t ipc_command_type; @@ -82,7 +155,7 @@ typedef struct { uint8_t subcmd; union { - uint8_t shortpayload[8]; + uint8_t shortpayload[24]; __attribute__((packed)) struct { uint32_t offset; @@ -91,46 +164,89 @@ typedef struct { }; } ipc_req_header_t; +ASSERT_SIZE_MULTIPLE_OF_32(ipc_req_header_t); + +typedef struct +{ + ipc_req_header_t hdr; + flippydrive_net_presence_t presence; +} ipc_req_net_presence_t; + +ASSERT_SIZE_MULTIPLE_OF_32(ipc_req_net_presence_t); + typedef struct { ipc_req_header_t hdr; file_entry_t file; } ipc_req_open_t; +ASSERT_SIZE_MULTIPLE_OF_32(ipc_req_open_t); + typedef struct { //Setup alignment such that the payload is 32-byte aligned for the GCN's DMA ipc_req_header_t hdr; - uint8_t pad[16]; - file_payload_t payload; + uint8_t payload[IPC_WRITE_PAYLOAD_MAX_LEN]; } ipc_req_write_t; +ASSERT_SIZE_MULTIPLE_OF_32(ipc_req_write_t); + typedef struct { ipc_req_header_t hdr; file_entry_t file; } ipc_req_unlink_t; +ASSERT_SIZE_MULTIPLE_OF_32(ipc_req_unlink_t); + +typedef struct +{ + ipc_req_header_t hdr; + file_entry_t file; +} ipc_req_mkdir_t; + +ASSERT_SIZE_MULTIPLE_OF_32(ipc_req_mkdir_t); + +typedef struct +{ + ipc_req_header_t hdr; + file_entry_t oldfile; + file_entry_t newfile; +} ipc_req_rename_t; + +ASSERT_SIZE_MULTIPLE_OF_32(ipc_req_rename_t); + enum file_entry_type_enum { FILE_ENTRY_TYPE_FILE = 0, FILE_ENTRY_TYPE_DIR = 1, + FILE_ENTRY_TYPE_BAD = 0xFF, FILE_ENTRY_TYPE_MAX = 0xFF }; #pragma pack(pop) static const size_t ipc_payloadlen[IPC_CMD_MAX] = { - 0, 0, 0, 0, 0, 0, 0, 0, //CMD 0-7 - 0, //FILE_READ - 0, //FILE_WRITE - sizeof(file_entry_t), //FILE_OPEN - 0, //FILE_CLOSE - 0, //FILE_STAT - 0, //FILE_SEEK - sizeof(file_entry_t), //FILE_UNLINK - 0, //READDIR - - IPC_RESERVED0_SIZE, //RESERVED0 - 0, //FILE_OPEN_FLASH is purely internal to RP2040 and has no meaning over IPC - 0, //FILE_UNLINK_FLASH is purely internal -}; + 0, // Read status + 0, // Set default fd + 0, // reload config + 0, // RESERVED1 + 0, + 0, // RESET + 0, // FS_INFO + sizeof(file_entry_t), // FILE_MKDIR + 0, // FILE_READ + 0, // FILE_WRITE + sizeof(file_entry_t), // FILE_OPEN + 0, // FILE_CLOSE + 0, // FILE_STAT + 0, // FILE_SEEK + sizeof(file_entry_t), // FILE_UNLINK + 0, // READDIR + + IPC_RESERVED0_SIZE, // RESERVED0 + 0, // FILE_OPEN_FLASH is purely internal to RP2040 and has no meaning over IPC + 0, // FILE_UNLINK_FLASH is purely internal + sizeof(file_entry_t)*2, // FILE_RENAME + + sizeof(flippydrive_net_presence_t), //IPC_NET_PRESENCE +}; diff --git a/patches/source/flippy_sync.c b/patches/source/flippy_sync.c index d1e7c32..e9f335c 100644 --- a/patches/source/flippy_sync.c +++ b/patches/source/flippy_sync.c @@ -418,4 +418,36 @@ void dvd_custom_bypass() { ; // transfer complete register return; +} + +int dvd_custom_presence(bool playing, const char *status, const char *sub_status) +{ + GCN_ALIGNED(flippydrive_net_presence_t) presence = {}; + + strncpy(presence.status, status, sizeof(presence.status)-1); + strncpy(presence.sub_status, sub_status, sizeof(presence.sub_status)-1); + + presence.presence = playing ? 0x01 : 0x00; + + DCFlushRange(&presence, sizeof(flippydrive_net_presence_t)); + + _di_regs[DI_SR] = (DI_SR_BRKINTMASK | DI_SR_TCINTMASK | DI_SR_DEINT | DI_SR_DEINTMASK); + _di_regs[DI_CVR] = 0; // clear cover int + + _di_regs[DI_CMDBUF0] = DVD_FLIPPY_FILEAPI_BASE | IPC_FILE_OPEN_FLASH; + _di_regs[DI_CMDBUF1] = 0; + _di_regs[DI_CMDBUF2] = 0; //TODO this was sizeof(file_entry_t) before for no particular reason + + _di_regs[DI_MAR] = (u32)&presence & 0x1FFFFFFF; + _di_regs[DI_LENGTH] = sizeof(flippydrive_net_presence_t); + _di_regs[DI_CR] = (DI_CR_RW | DI_CR_DMA | DI_CR_TSTART); // start transfer + + while (_di_regs[DI_CR] & DI_CR_TSTART) + ; // transfer complete register + + // check if ERR was asserted + if (_di_regs[DI_SR] & DI_SR_DEINT) { + return 1; + } + return 0; } \ No newline at end of file diff --git a/patches/source/flippy_sync.h b/patches/source/flippy_sync.h index 1fb1cdb..5197a83 100644 --- a/patches/source/flippy_sync.h +++ b/patches/source/flippy_sync.h @@ -51,4 +51,6 @@ int dvd_custom_unlink(char *path); int dvd_custom_unlink_flash(char *path); int dvd_custom_open(char *path, uint8_t type, uint8_t flags); int dvd_custom_open_flash(char *path, uint8_t type, uint8_t flags); -void dvd_custom_bypass(); \ No newline at end of file +void dvd_custom_bypass(); + +int dvd_custom_presence(bool playing, const char *status, const char* sub_status);