@@ -74,4 +74,15 @@ typedef void (*sif_cmd_cb)(const struct sif_cmd_header *header,
int sif_request_cmd(u32 cmd_id, sif_cmd_cb cb, void *arg);
+struct sif_rpc_client
+{
+ iop_addr_t server;
+ iop_addr_t server_buffer;
+
+ size_t client_size_max;
+ void *client_buffer;
+
+ struct completion done;
+};
+
#endif /* __ASM_MACH_PS2_SIF_H */
@@ -51,6 +51,35 @@
#define SIF0_BUFFER_SIZE PAGE_SIZE
#define SIF1_BUFFER_SIZE PAGE_SIZE
+struct sif_rpc_packet_header {
+ u32 rec_id;
+ void *pkt_addr;
+ u32 rpc_id;
+};
+
+struct sif_rpc_request_end_packet {
+ struct sif_rpc_packet_header header;
+ struct sif_rpc_client *client;
+ u32 client_id;
+
+ iop_addr_t server;
+ iop_addr_t server_buffer;
+
+ void *client_buffer;
+};
+
+struct sif_rpc_bind_packet {
+ struct sif_rpc_packet_header header;
+ struct sif_rpc_client *client;
+ u32 server_id;
+};
+
+struct sif_cmd_handler
+{
+ sif_cmd_cb cb;
+ void *arg;
+};
+
static DEFINE_SPINLOCK(sregs_lock);
static s32 sregs[32];
@@ -269,6 +298,21 @@ static struct sif_cmd_handler *handler_from_cid(u32 cmd_id)
return id < CMD_HANDLER_MAX ? &cmd_handlers[id] : NULL;
}
+static void cmd_rpc_bind(const struct sif_cmd_header *header,
+ const void *data, void *arg)
+{
+ const struct sif_rpc_bind_packet *bind = data;
+ const struct sif_rpc_request_end_packet packet = {
+ .client = bind->client,
+ .client_id = SIF_CMD_RPC_BIND,
+ };
+ int err;
+
+ err = sif_cmd(SIF_CMD_RPC_END, &packet, sizeof(packet));
+ if (err)
+ pr_err_once("sif: cmd_rpc_bind failed with %d\n", err);
+}
+
int sif_request_cmd(u32 cmd_id, sif_cmd_cb cb, void *arg)
{
struct sif_cmd_handler *handler = handler_from_cid(cmd_id);
@@ -361,6 +405,8 @@ static int sif_request_cmds(void)
struct cmd_data *arg;
} cmds[] = {
{ SIF_CMD_WRITE_SREG, cmd_write_sreg, NULL },
+
+ { SIF_CMD_RPC_BIND, cmd_rpc_bind, NULL },
};
int err = 0;
size_t i;
@@ -458,6 +504,9 @@ static int __init sif_init(void)
{
int err;
+ BUILD_BUG_ON(sizeof(struct sif_rpc_packet_header) != 12);
+ BUILD_BUG_ON(sizeof(struct sif_rpc_request_end_packet) != 32);
+ BUILD_BUG_ON(sizeof(struct sif_rpc_bind_packet) != 20);
BUILD_BUG_ON(sizeof(struct sif_cmd_header) != 16);
sif_disable_dma();
The IOP can service remote procedure calls (RPCs) from the main (R5900) processor. The first step is to send a bind command that the IOP will respond to, to establish a client connection. The main processor responds by issuing a bind end command to the IOP. Allocating IOP memory and linking IOP modules are examples of IOP RPC services that will be used in subsequent changes. IOP memory is needed for USB OHCI support. Signed-off-by: Fredrik Noring <noring@nocrew.org> --- arch/mips/include/asm/mach-ps2/sif.h | 11 +++++++ drivers/ps2/sif.c | 49 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+)