ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
rpc_server.c
Go to the documentation of this file.
1 #include <kernel.h>
2 #include <malloc.h>
3 #include <sifcmd.h>
4 #include <sifrpc.h>
5 #include <stdio.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <netman.h>
9 #include <netman_rpc.h>
10 
11 #include "internal.h"
12 #include "rpc_server.h"
13 
15 static unsigned char NETMAN_RpcSvr_ThreadStack[0x1000] ALIGNED(16);
16 static unsigned char NETMAN_Rx_ThreadStack[0x1000] ALIGNED(16);
17 static unsigned char IsInitialized=0, IsProcessingRx;
18 
19 static struct NetManBD *FrameBufferStatus = NULL;
21 static unsigned short int RxBufferRdPtr, RxBufferNextRdPtr;
22 extern void *_gp;
23 
24 static void NETMAN_RxThread(void *arg);
25 
26 static void ClearBufferLen(int index, void *packet, void *payload)
27 {
28  struct NetManBD *bd;
29  SifDmaTransfer_t dmat;
30 
32  bd->length = 0;
33  bd->packet = packet;
34  bd->payload = payload;
35 
36  //Transfer to IOP RAM
37  dmat.src = (void*)&FrameBufferStatus[index];
39  dmat.size = sizeof(struct NetManBD);
40  dmat.attr = 0;
41  while(SifSetDma(&dmat, 1) == 0){ };
42 }
43 
44 static s32 HandleRxEvent(s32 channel)
45 {
46  struct NetManBD *bd;
47 
49  if(bd->length > 0)
50  {
51  iSifSetDChain();
52 
53  if(!IsProcessingRx)
54  {
55  IsProcessingRx = 1;
57  }
58  }
59 
60  ExitHandler();
61  //Must allow the other SIF handlers to check their states, as it is possible for this handler to block other handlers until FrameBufferStatus is cleared.
62  return 0;
63 }
64 
66 {
67  int i;
68  void *packet, *payload;
69 
70  for(i = 0; i < NETMAN_RPC_BLOCK_SIZE; i++)
71  {
73  {
75  } else {
76  printf("NETMAN: error - unable to allocate Rx FIFO buffers.\n");
77  return -ENOMEM;
78  }
79  }
80 
81  return 0;
82 }
83 
84 /* Main EE RPC thread. */
85 static void *NETMAN_EE_RPC_Handler(int fnum, void *buffer, int NumBytes)
86 {
87  ee_thread_t thread;
88  void *result;
89 
90  switch(fnum)
91  {
93  RxIOPFrameBufferStatus = *(void**)buffer;
94 
95  //Maintain 64-byte alignment to avoid non-uncached writes to the same cache line from contaminating the line.
96  if(FrameBufferStatus == NULL) FrameBufferStatus = memalign(64, sizeof(struct NetManBD) * NETMAN_RPC_BLOCK_SIZE);
97 
98  if(FrameBufferStatus != NULL)
99  {
100  memset(UNCACHED_SEG(FrameBufferStatus), 0, sizeof(struct NetManBD) * NETMAN_RPC_BLOCK_SIZE);
101  RxBufferRdPtr = 0;
102  RxBufferNextRdPtr = 0;
103  IsProcessingRx = 0;
104 
105  thread.func=&NETMAN_RxThread;
107  thread.stack_size=sizeof(NETMAN_Rx_ThreadStack);
108  thread.gp_reg=&_gp;
109  thread.initial_priority=0x59; /* Should be given a lower priority than the protocol stack, so that the protocol stack can process incoming frames. */
110  thread.attr=thread.option=0;
111 
112  if((NETMAN_Rx_threadID=CreateThread(&thread)) >= 0)
113  {
115 
118  ((struct NetManEEInitResult *)buffer)->result = 0;
119  ((struct NetManEEInitResult *)buffer)->FrameBufferStatus = FrameBufferStatus;
120  }
121  else{
122  ((struct NetManEEInitResult *)buffer)->result = NETMAN_Rx_threadID;
123  }
124  }else{
125  ((struct NetManEEInitResult *)buffer)->result = -ENOMEM;
126  }
127  result=buffer;
128  break;
130  if(FrameBufferStatus != NULL)
131  {
132  free(FrameBufferStatus);
134  }
135  result=NULL;
136  break;
139  result=NULL;
140  break;
141  default:
142  printf("NETMAN [EE]: Unrecognized command: 0x%x\n", fnum);
143  *(int *)buffer=EINVAL;
144  result=buffer;
145  }
146 
147  return result;
148 }
149 
150 static struct t_SifRpcDataQueue cb_queue;
151 static struct t_SifRpcServerData cb_srv;
152 
153 static void NETMAN_RPC_Thread(void *arg)
154 {
155  static unsigned char cb_rpc_buffer[64] __attribute__((aligned(64)));
156 
160 }
161 
162 static void NETMAN_RxThread(void *arg)
163 {
164  volatile struct NetManBD *bd;
165  void *payload, *payloadNext;
166  u32 PacketLength, PacketLengthAligned;
167  void *packet, *packetNext;
168  u8 run;
169 
170  while(1)
171  {
173 
174  do {
175  DI();
176  PacketLength = bd->length;
177  if (PacketLength > 0)
178  {
179  run = 1;
180  } else {
181  run = 0;
182  IsProcessingRx = 0;
183  }
184  EI();
185 
186  if(!run)
187  SleepThread();
188  } while(!run);
189 
190  payload = bd->payload;
191  packet = bd->packet;
192 
193  //Must successfully allocate a replacement buffer for the input buffer.
194  while((packetNext = NetManNetProtStackAllocRxPacket(NETMAN_NETIF_FRAME_SIZE, &payloadNext)) == NULL){};
196  ClearBufferLen(RxBufferRdPtr, packetNext, payloadNext);
197 
198  //Increment read pointer by one place.
200 
201  //Now process the received packet.
202  PacketLengthAligned = (PacketLength + 63) & ~63;
203  SifWriteBackDCache(payload, PacketLengthAligned);
206  }
207 }
208 
210 {
211  int result;
212  ee_thread_t ThreadData;
213 
214  if(!IsInitialized)
215  {
216  ThreadData.func=&NETMAN_RPC_Thread;
217  ThreadData.stack=NETMAN_RpcSvr_ThreadStack;
218  ThreadData.stack_size=sizeof(NETMAN_RpcSvr_ThreadStack);
219  ThreadData.gp_reg=&_gp;
220  ThreadData.initial_priority=0x57; /* The RPC server thread should be given a higher priority than the protocol stack, so that it can issue commants to the EE and return. */
221  ThreadData.attr=ThreadData.option=0;
222 
223  if((NETMAN_RpcSvr_threadID=CreateThread(&ThreadData))>=0)
224  {
226  IsInitialized=1;
227  result=0;
228  }
230  }
231  else result=0;
232 
233  return result;
234 }
235 
237 {
238  if(IsInitialized)
239  {
243 
245  {
249  }
250 
251  if(NETMAN_Rx_threadID>=0)
252  {
255  NETMAN_Rx_threadID = -1;
256  }
257 
258  IsInitialized=0;
259  }
260 }
#define EINVAL
Definition: errno.h:62
#define ENOMEM
Definition: errno.h:42
packet_t packet
Definition: font.c:24
s32 iWakeupThread(s32 thread_id)
#define ExitHandler()
Definition: kernel.h:28
u32 SifSetDma(SifDmaTransfer_t *sdd, s32 len)
s32 CreateThread(ee_thread_t *thread)
void iSifSetDChain(void)
@ DMAC_SIF0
Definition: kernel.h:121
#define ALIGNED(x)
Definition: kernel.h:50
s32 StartThread(s32 thread_id, void *args)
#define UNCACHED_SEG(x)
Definition: kernel.h:35
s32 AddDmacHandler(s32 channel, s32(*handler)(s32 channel), s32 next)
s32 SleepThread(void)
s32 RemoveDmacHandler(s32 channel, s32 handler_id)
#define DI
Definition: kernel.h:24
#define EI
Definition: kernel.h:25
s32 TerminateThread(s32 thread_id)
s32 DeleteThread(s32 thread_id)
int EnableDmac(int dmac)
s32 index
Definition: libpad.c:194
void * NetManNetProtStackAllocRxPacket(unsigned int length, void **payload)
Definition: netman.c:114
void NetManNetProtStackReallocRxPacket(void *packet, unsigned int length)
Definition: netman.c:146
void NetManNetProtStackEnQRxPacket(void *packet)
Definition: netman.c:124
#define NETMAN_NETIF_FRAME_SIZE
Definition: netman.h:13
@ NETMAN_EE_RPC_FUNC_HANDLE_LINK_STATUS_CHANGE
Definition: netman_rpc.h:19
@ NETMAN_EE_RPC_FUNC_DEINIT
Definition: netman_rpc.h:17
@ NETMAN_EE_RPC_FUNC_INIT
Definition: netman_rpc.h:16
#define NETMAN_RPC_BLOCK_SIZE
Definition: netman_rpc.h:54
#define NETMAN_RPC_NUMBER
Definition: netman_rpc.h:12
void NetManToggleGlobalNetIFLinkState(unsigned char state)
Definition: netman.c:20
u8 buffer[128]
Definition: rpc_client.c:19
s32 result
Definition: rpc_client.c:23
static struct NetManBD * RxIOPFrameBufferStatus
Definition: rpc_server.c:20
static int SifHandlerID
Definition: rpc_server.c:14
static unsigned char NETMAN_RpcSvr_ThreadStack[0x1000]
Definition: rpc_server.c:15
static void * NETMAN_EE_RPC_Handler(int fnum, void *buffer, int NumBytes)
Definition: rpc_server.c:85
static unsigned short int RxBufferRdPtr
Definition: rpc_server.c:21
static int NETMAN_Rx_threadID
Definition: rpc_server.c:14
static unsigned char IsProcessingRx
Definition: rpc_server.c:17
static unsigned short int RxBufferNextRdPtr
Definition: rpc_server.c:21
int NetManInitRPCServer(void)
Definition: rpc_server.c:209
static int NETMAN_RpcSvr_threadID
Definition: rpc_server.c:14
static unsigned char NETMAN_Rx_ThreadStack[0x1000]
Definition: rpc_server.c:16
static unsigned char IsInitialized
Definition: rpc_server.c:17
static struct t_SifRpcServerData cb_srv
Definition: rpc_server.c:151
void * _gp
static struct t_SifRpcDataQueue cb_queue
Definition: rpc_server.c:150
static s32 HandleRxEvent(s32 channel)
Definition: rpc_server.c:44
static void NETMAN_RxThread(void *arg)
Definition: rpc_server.c:162
int NetManRPCAllocRxBuffers(void)
Definition: rpc_server.c:65
static void ClearBufferLen(int index, void *packet, void *payload)
Definition: rpc_server.c:26
static void NETMAN_RPC_Thread(void *arg)
Definition: rpc_server.c:153
void NetManDeinitRPCServer(void)
Definition: rpc_server.c:236
static struct NetManBD * FrameBufferStatus
Definition: rpc_server.c:19
void SifWriteBackDCache(void *ptr, int size)
SifRpcServerData_t * SifRegisterRpc(SifRpcServerData_t *srv, int sid, SifRpcFunc_t func, void *buff, SifRpcFunc_t cfunc, void *cbuff, SifRpcDataQueue_t *qd)
SifRpcDataQueue_t * SifSetRpcQueue(SifRpcDataQueue_t *q, int thread_id)
SifRpcServerData_t * SifRemoveRpc(SifRpcServerData_t *sd, SifRpcDataQueue_t *queue)
void SifRpcLoop(SifRpcDataQueue_t *q)
SifRpcDataQueue_t * SifRemoveRpcQueue(SifRpcDataQueue_t *qd)
u16 length
Definition: netman_rpc.h:76
void * packet
Definition: netman_rpc.h:78
void * payload
Definition: netman_rpc.h:79
void * dest
Definition: sifdma.h:55
void * src
Definition: sifdma.h:54
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