ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
rpc_client.c
Go to the documentation of this file.
1 #include <errno.h>
2 #include <kernel.h>
3 #include <sifrpc.h>
4 #include <string.h>
5 #include <malloc.h>
6 #include <netman.h>
7 #include <netman_rpc.h>
8 
9 #include "rpc_client.h"
10 
12 extern void *_gp;
13 
14 static union {
16  struct NetManIoctl IoctlArgs;
19  u8 buffer[128];
21 
22 static union {
27  u8 buffer[128];
29 
30 static int NetManIOSemaID = -1, NETMAN_Tx_threadID = -1;
31 static unsigned char NETMAN_Tx_ThreadStack[0x1000] ALIGNED(16);
32 
33 static unsigned short int IOPFrameBufferWrPtr;
34 static u8 *IOPFrameBuffer = NULL; /* On the IOP side. */
36 static struct NetManBD *FrameBufferStatus = NULL;
37 
38 static unsigned char IsInitialized=0, IsProcessingTx;
39 
40 static void deinitCleanup(void)
41 {
42  if(NetManIOSemaID >= 0)
43  {
45  NetManIOSemaID = -1;
46  }
47  if(NETMAN_Tx_threadID >= 0)
48  {
51  NETMAN_Tx_threadID = -1;
52  }
53 }
54 
55 static void NETMAN_TxThread(void *arg);
56 
58  static const char NetManID[]="NetMan";
59  int result;
60  ee_sema_t SemaData;
61  ee_thread_t thread;
62 
63  if(!IsInitialized)
64  {
65  SemaData.max_count=1;
66  SemaData.init_count=1;
67  SemaData.option=(u32)NetManID;
68  SemaData.attr=0;
69  if((NetManIOSemaID=CreateSema(&SemaData)) < 0)
70  {
71  deinitCleanup();
72  return NetManIOSemaID;
73  }
74 
75  thread.func=&NETMAN_TxThread;
77  thread.stack_size=sizeof(NETMAN_Tx_ThreadStack);
78  thread.gp_reg=&_gp;
79  thread.initial_priority=0x56; /* Should be given a higher priority than the protocol stack, so that it can dump frames in the EE and return. */
80  thread.attr=thread.option=0;
81 
82  if((NETMAN_Tx_threadID=CreateThread(&thread)) >= 0)
83  {
84  IsProcessingTx = 0;
86  } else {
87  deinitCleanup();
88  return NETMAN_Tx_threadID;
89  }
90 
92  nopdelay();
93 
95  {
96  if((result=ReceiveBuffer.result) == 0)
97  IsInitialized=1;
98  else
99  deinitCleanup();
100  }else{
101  deinitCleanup();
102  }
103  }
104  else result=0;
105 
106  return result;
107 }
108 
110 {
111  int result;
112 
114 
115  if(FrameBufferStatus == NULL) FrameBufferStatus = memalign(64, NETMAN_RPC_BLOCK_SIZE * sizeof(struct NetManBD));
116 
117  if(FrameBufferStatus != NULL)
118  {
119  memset(UNCACHED_SEG(FrameBufferStatus), 0, NETMAN_RPC_BLOCK_SIZE * sizeof(struct NetManBD));
120  TransmitBuffer.NetStack.FrameBufferStatus = FrameBufferStatus;
122 
124  {
125  if((result=ReceiveBuffer.NetStackResult.result) == 0)
126  {
127  IOPFrameBuffer = ReceiveBuffer.NetStackResult.FrameBuffer;
128  IOPFrameBufferStatus = ReceiveBuffer.NetStackResult.FrameBufferStatus;
129  }
130  }
131  }
132  else
133  {
134  result = -ENOMEM;
135  }
136 
138 
139  return result;
140 }
141 
143 {
144  int result;
145 
147 
151 
152  free(FrameBufferStatus);
154 
156 
157  return result;
158 }
159 
161 {
162  if(IsInitialized)
163  {
165 
167  deinitCleanup();
168 
169  IsInitialized=0;
170  }
171 }
172 
173 int NetManRpcIoctl(unsigned int command, void *args, unsigned int args_len, void *output, unsigned int length)
174 {
175  int result;
176  struct NetManIoctl *IoctlArgs=&TransmitBuffer.IoctlArgs;
177 
179 
181  memcpy(IoctlArgs->args, args, args_len);
185 
187  {
188  result=ReceiveBuffer.IoctlResult.result;
189  memcpy(output, ReceiveBuffer.IoctlResult.output, length);
190  }
191 
193 
194  return result;
195 }
196 
197 static void NETMAN_TxThread(void *arg)
198 {
199  static SifCmdHeader_t cmd ALIGNED(64);
200  SifDmaTransfer_t dmat[2];
201  struct NetManPktCmd *npcmd;
202  int dmat_id, length, unaligned, unalignedCache, NumTx;
203  void *payload, *payloadAligned, *payloadCacheAligned;
204  volatile struct NetManBD *bd, *bdNext;
205 
206  while(1)
207  {
208  SleepThread();
209 
210  NumTx = 0;
211  while((length = NetManTxPacketNext(&payload)) > 0)
212  {
213  IsProcessingTx = 1;
214 
215  //Write back D-cache, before performing a DMA transfer.
216  unaligned = (int)((u32)payload & 15);
217  unalignedCache = (int)((u32)payload & 63);
218  payloadAligned = (void*)((u32)payload & ~15);
219  payloadCacheAligned = (void*)((u32)payload & ~63);
220  SifWriteBackDCache(payloadCacheAligned, (length + unalignedCache + 63) & ~63);
221 
222  do {
223  //Wait for a spot to be freed up.
225  while(bd->length != 0){}
226 
227  //Transfer to IOP RAM
228  //Determine mode of transfer.
230  if((NumTx + 1) >= NETMAN_FRAME_GROUP_SIZE || bdNext->length == 0)
231  {
232  //Prepare SIFCMD packet
233  //Record the frame length.
234  npcmd = (struct NetManPktCmd*)&cmd.opt;
235  npcmd->length = length;
236  npcmd->offset = unaligned;
237  npcmd->id = IOPFrameBufferWrPtr;
238 
239  while((dmat_id = SifSendCmd(NETMAN_SIFCMD_ID, &cmd, sizeof(SifCmdHeader_t),
240  (void*)payloadAligned,
242  (length + unaligned + 15) & ~15)) == 0){ };
243  } else {
244  //Record the frame length.
245  bd->length = length;
246  bd->offset = unaligned;
247 
248  //Normal DMA transfer
249  dmat[0].src = (void*)payloadAligned;
251  dmat[0].size = (length + unaligned + 15) & ~15;
252  dmat[0].attr = 0;
253  dmat[1].src = (void*)&FrameBufferStatus[IOPFrameBufferWrPtr];
254  dmat[1].dest = (void*)&IOPFrameBufferStatus[IOPFrameBufferWrPtr];
255  dmat[1].size = sizeof(struct NetManBD);
256  dmat[1].attr = 0;
257 
258  while((dmat_id = SifSetDma(dmat, 2)) == 0){ };
259  }
260 
261  //Increase write pointer by one position.
263 
264  if((length = NetManTxPacketAfter(&payload)) > 0)
265  { //Write back the cache of the next packet, while waiting.
266  unaligned = (int)((u32)payload & 15);
267  unalignedCache = (int)((u32)payload & 63);
268  payloadAligned = (void*)((u32)payload & ~15);
269  payloadCacheAligned = (void*)((u32)payload & ~63);
270  SifWriteBackDCache(payloadCacheAligned, (length + unalignedCache + 63) & ~63);
271  }
272 
273  NumTx++;
274 
275  while(SifDmaStat(dmat_id) >= 0){ };
277  } while(length > 0);
278 
279  IsProcessingTx = 0;
280  }
281  }
282 }
283 
285 {
286  if(!IsProcessingTx)
288 }
289 
290 int NetManSetMainIF(const char *name)
291 {
292  int result;
293 
294  if (!IsInitialized)
295  return -1;
296 
298 
299  strncpy(TransmitBuffer.netifName, name, NETMAN_NETIF_NAME_MAX_LEN);
300  TransmitBuffer.netifName[NETMAN_NETIF_NAME_MAX_LEN-1] = '\0';
302  result=ReceiveBuffer.result;
303 
305 
306  return result;
307 }
308 
309 int NetManQueryMainIF(char *name)
310 {
311  int result;
312 
313  if (!IsInitialized)
314  return -1;
315 
317 
319  {
320  if((result=ReceiveBuffer.QueryMainNetIFResult.result) == 0)
321  {
322  strncpy(name, ReceiveBuffer.QueryMainNetIFResult.name, NETMAN_NETIF_NAME_MAX_LEN);
323  name[NETMAN_NETIF_NAME_MAX_LEN-1] = '\0';
324  }
325  }
326 
328 
329  return result;
330 }
331 
333 {
334  int result;
335 
336  if (!IsInitialized)
337  return -1;
338 
340 
341  TransmitBuffer.mode = mode;
343  result=ReceiveBuffer.result;
344 
346 
347  return result;
348 }
#define ENOMEM
Definition: errno.h:42
s32 CreateSema(ee_sema_t *sema)
s32 SignalSema(s32 sema_id)
s32 DeleteSema(s32 sema_id)
u32 SifSetDma(SifDmaTransfer_t *sdd, s32 len)
static void nopdelay(void)
Definition: kernel.h:141
s32 CreateThread(ee_thread_t *thread)
#define ALIGNED(x)
Definition: kernel.h:50
s32 WakeupThread(s32 thread_id)
s32 WaitSema(s32 sema_id)
s32 StartThread(s32 thread_id, void *args)
#define UNCACHED_SEG(x)
Definition: kernel.h:35
s32 SleepThread(void)
s32 SifDmaStat(u32 id)
s32 TerminateThread(s32 thread_id)
s32 DeleteThread(s32 thread_id)
s32 command
Definition: libpad.c:156
int NetManTxPacketAfter(void **payload)
Definition: netman.c:141
int NetManTxPacketNext(void **payload)
Definition: netman.c:130
void NetManTxPacketDeQ(void)
Definition: netman.c:135
#define NETMAN_FRAME_GROUP_SIZE
Definition: netman.h:14
#define NETMAN_NETIF_NAME_MAX_LEN
Definition: netman.h:12
#define NETMAN_RPC_BLOCK_SIZE
Definition: netman_rpc.h:54
#define NETMAN_MAX_FRAME_SIZE
Definition: netman_rpc.h:53
#define NETMAN_RPC_NUMBER
Definition: netman_rpc.h:12
#define NETMAN_SIFCMD_ID
Definition: netman_rpc.h:13
@ NETMAN_IOP_RPC_FUNC_DEINIT
Definition: netman_rpc.h:24
@ NETMAN_IOP_RPC_FUNC_SET_LINK_MODE
Definition: netman_rpc.h:30
@ NETMAN_IOP_RPC_FUNC_SET_MAIN_NETIF
Definition: netman_rpc.h:28
@ NETMAN_IOP_RPC_FUNC_IOCTL
Definition: netman_rpc.h:27
@ NETMAN_IOP_RPC_FUNC_REG_NETWORK_STACK
Definition: netman_rpc.h:25
@ NETMAN_IOP_RPC_FUNC_UNREG_NETWORK_STACK
Definition: netman_rpc.h:26
@ NETMAN_IOP_RPC_FUNC_INIT
Definition: netman_rpc.h:23
@ NETMAN_IOP_RPC_FUNC_QUERY_MAIN_NETIF
Definition: netman_rpc.h:29
int NetManRpcIoctl(unsigned int command, void *args, unsigned int args_len, void *output, unsigned int length)
Definition: rpc_client.c:173
static SifRpcClientData_t NETMAN_rpc_cd
Definition: rpc_client.c:11
static int NetManIOSemaID
Definition: rpc_client.c:30
int NetManRPCUnregisterNetworkStack(void)
Definition: rpc_client.c:142
int NetManRPCRegisterNetworkStack(void)
Definition: rpc_client.c:109
int NetManSetMainIF(const char *name)
Definition: rpc_client.c:290
static struct NetManBD * IOPFrameBufferStatus
Definition: rpc_client.c:35
static void deinitCleanup(void)
Definition: rpc_client.c:40
void NetManDeinitRPCClient(void)
Definition: rpc_client.c:160
struct NetManRegNetworkStackResult NetStackResult
Definition: rpc_client.c:24
static unsigned short int IOPFrameBufferWrPtr
Definition: rpc_client.c:33
static union @20 TransmitBuffer
struct NetManRegNetworkStack NetStack
Definition: rpc_client.c:18
struct NetManQueryMainNetIFResult QueryMainNetIFResult
Definition: rpc_client.c:26
int NetManSetLinkMode(int mode)
Definition: rpc_client.c:332
static unsigned char NETMAN_Tx_ThreadStack[0x1000]
Definition: rpc_client.c:31
static unsigned char IsProcessingTx
Definition: rpc_client.c:38
static u8 * IOPFrameBuffer
Definition: rpc_client.c:34
struct NetManIoctlResult IoctlResult
Definition: rpc_client.c:25
static unsigned char IsInitialized
Definition: rpc_client.c:38
static int NETMAN_Tx_threadID
Definition: rpc_client.c:30
void * _gp
s32 mode
Definition: rpc_client.c:15
static union @21 ReceiveBuffer
struct NetManIoctl IoctlArgs
Definition: rpc_client.c:16
int NetManInitRPCClient(void)
Definition: rpc_client.c:57
u8 buffer[128]
Definition: rpc_client.c:19
static void NETMAN_TxThread(void *arg)
Definition: rpc_client.c:197
int NetManQueryMainIF(char *name)
Definition: rpc_client.c:309
void NetManRpcNetIFXmit(void)
Definition: rpc_client.c:284
s32 result
Definition: rpc_client.c:23
static struct NetManBD * FrameBufferStatus
Definition: rpc_client.c:36
char netifName[NETMAN_NETIF_NAME_MAX_LEN]
Definition: rpc_client.c:17
unsigned int SifSendCmd(int cmd, void *packet, int packet_size, void *src_extra, void *dest_extra, int size_extra)
void SifWriteBackDCache(void *ptr, int size)
int SifBindRpc(SifRpcClientData_t *client, int rpc_number, int mode)
int SifCallRpc(SifRpcClientData_t *client, int rpc_number, int mode, void *send, int ssize, void *receive, int rsize, SifRpcEndFunc_t end_function, void *end_param)
u16 offset
Definition: netman_rpc.h:77
u16 length
Definition: netman_rpc.h:76
void * payload
Definition: netman_rpc.h:79
u32 args_len
Definition: netman_rpc.h:59
u8 args[64]
Definition: netman_rpc.h:58
void * output
Definition: netman_rpc.h:60
void * dest
Definition: sifdma.h:55
void * src
Definition: sifdma.h:54
struct t_SifRpcServerData * server
Definition: sifrpc.h:142
int init_count
Definition: kernel.h:218
int max_count
Definition: kernel.h:217
u32 option
Definition: kernel.h:221
u32 attr
Definition: kernel.h:220
void * gp_reg
Definition: kernel.h:230
u32 option
Definition: kernel.h:234
int stack_size
Definition: kernel.h:229
void * func
Definition: kernel.h:227
void * stack
Definition: kernel.h:228
u32 attr
Definition: kernel.h:233
int initial_priority
Definition: kernel.h:231
#define NULL
Definition: tamtypes.h:91
signed int s32
Definition: tamtypes.h:58
unsigned int u32
Definition: tamtypes.h:30
unsigned char u8
Definition: tamtypes.h:23