Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: sharedmem.cpp | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | // ========== Copyright Header Begin ========================================== | |
36 | // | |
37 | // OpenSPARC T2 Processor File: sharedmem.cpp | |
38 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
39 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
40 | // | |
41 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
42 | // | |
43 | // This program is free software; you can redistribute it and/or modify | |
44 | // it under the terms of the GNU General Public License as published by | |
45 | // the Free Software Foundation; version 2 of the License. | |
46 | // | |
47 | // This program is distributed in the hope that it will be useful, | |
48 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
49 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
50 | // GNU General Public License for more details. | |
51 | // | |
52 | // You should have received a copy of the GNU General Public License | |
53 | // along with this program; if not, write to the Free Software | |
54 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
55 | // | |
56 | // For the avoidance of doubt, and except that if any non-GPL license | |
57 | // choice is available it will apply instead, Sun elects to use only | |
58 | // the General Public License version 2 (GPLv2) at this time for any | |
59 | // software where a choice of GPL license versions is made | |
60 | // available with the language indicating that GPLv2 or any later version | |
61 | // may be used, or where a choice of which version of the GPL is applied is | |
62 | // otherwise unspecified. | |
63 | // | |
64 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
65 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
66 | // have any questions. | |
67 | // | |
68 | // ========== Copyright Header End ============================================ | |
69 | #include <stdio.h> | |
70 | #include <stdlib.h> | |
71 | #include <string.h> | |
72 | ||
73 | #include "sharedmem.h" | |
74 | ||
75 | #define RX_FIFO_DEPTH 50 | |
76 | #define RX_FIFO_SIZE (RX_FIFO_DEPTH * 9650) | |
77 | ||
78 | sharedmem::sharedmem(key_t key, int create) { | |
79 | int size = RX_FIFO_SIZE * 2 + 200000; | |
80 | #if 0 | |
81 | int shmid; | |
82 | if ((shmid = shmget(key, size, 0666 | (create ? IPC_CREAT : 0))) < 0) { | |
83 | perror(" -shmget"); | |
84 | exit(1); | |
85 | } | |
86 | if ((shm = (char*)shmat(shmid, NULL, 0)) == (char *) -1) { | |
87 | perror("shmat"); | |
88 | exit(1); | |
89 | } | |
90 | #else | |
91 | shm = (char*)malloc(size * sizeof(char)); | |
92 | #endif | |
93 | ||
94 | xaui0_size = (int *) shm; | |
95 | xaui1_size = xaui0_size + 1; | |
96 | interrupt = (unsigned int *)(xaui1_size + 1); | |
97 | *xaui0_size = *xaui1_size = 0; | |
98 | *interrupt = 0; | |
99 | ||
100 | shm = (char *) (interrupt + 1); | |
101 | ||
102 | sp_niu_pio_request = (sema_t*) (shm + 0 * sizeof(sema_t)); | |
103 | sp_niu_pio_response = (sema_t*) (shm + 1 * sizeof(sema_t)); | |
104 | sp_sii_rd_req = (sema_t*) (shm + 2 * sizeof(sema_t)); | |
105 | sp_sii_rd_res = (sema_t*) (shm + 3 * sizeof(sema_t)); | |
106 | sp_sii_rd_available = (sema_t*) (shm + 4 * sizeof(sema_t)); | |
107 | sp_sii_wr_available = (sema_t*) (shm + 5 * sizeof(sema_t)); | |
108 | sp_xaui0_available = (sema_t*) (shm + 6 * sizeof(sema_t)); | |
109 | sp_xaui1_available = (sema_t*) (shm + 7 * sizeof(sema_t)); | |
110 | sp_xaui0_req = (sema_t*) (shm + 8 * sizeof(sema_t)); | |
111 | sp_xaui1_req = (sema_t*) (shm + 9 * sizeof(sema_t)); | |
112 | sp_rx0_available = (sema_t*) (shm +10 * sizeof(sema_t)); | |
113 | sp_rx1_available = (sema_t*) (shm +11 * sizeof(sema_t)); | |
114 | sp_sii_wr_req = (sema_t*) (shm +12 * sizeof(sema_t)); | |
115 | sp_sii_wr_res = (sema_t*) (shm +13 * sizeof(sema_t)); | |
116 | ||
117 | if(create) { | |
118 | sema_init(sp_niu_pio_request, 0, USYNC_PROCESS , NULL); | |
119 | sema_init(sp_niu_pio_response, 0, USYNC_PROCESS , NULL); | |
120 | sema_init(sp_sii_rd_req, 0, USYNC_PROCESS , NULL); | |
121 | sema_init(sp_sii_rd_res, 0, USYNC_PROCESS , NULL); | |
122 | sema_init(sp_sii_wr_req, 0, USYNC_PROCESS , NULL); | |
123 | sema_init(sp_sii_wr_res, 0, USYNC_PROCESS , NULL); | |
124 | sema_init(sp_sii_rd_available, 1, USYNC_PROCESS , NULL); | |
125 | sema_init(sp_sii_wr_available, 1, USYNC_PROCESS , NULL); | |
126 | sema_init(sp_xaui0_available, 1, USYNC_PROCESS , NULL); | |
127 | sema_init(sp_xaui1_available, 1, USYNC_PROCESS , NULL); | |
128 | sema_init(sp_xaui0_req, 0, USYNC_PROCESS , NULL); | |
129 | sema_init(sp_xaui1_req, 0, USYNC_PROCESS , NULL); | |
130 | sema_init(sp_rx0_available, 0, USYNC_PROCESS , NULL); | |
131 | sema_init(sp_rx1_available, 0, USYNC_PROCESS , NULL); | |
132 | } | |
133 | ||
134 | typ = (int*)(shm + 14 * sizeof(sema_t)); | |
135 | data = (char*)(typ + 1); | |
136 | sii_wr_data = (char *)((char *)data + 16); | |
137 | sii_wr_size = (int *)(((char *)sii_wr_data) + 10000); | |
138 | ||
139 | sii_wr_addr = (unsigned long long int *)(sii_wr_size + 1); | |
140 | pa_read = (unsigned long long int*) (sii_wr_addr + 1); | |
141 | ||
142 | niu_read = (int*)(pa_read + 1); | |
143 | niu_write = niu_read + 1; | |
144 | read_size = niu_write + 1; | |
145 | sio_data = (void *) (read_size + 1); | |
146 | *niu_read = 0; | |
147 | *sii_wr_size = 0; | |
148 | ||
149 | xaui_rx_pointer[0] = (int *)(((char*)sio_data) + 20000); | |
150 | xaui_rx_head[0] = xaui_rx_pointer[0] + RX_FIFO_DEPTH; | |
151 | xaui_rx_tail[0] = xaui_rx_head[0] + 1; | |
152 | ||
153 | xaui_rx_pointer[1] = xaui_rx_tail[0] + 1; | |
154 | xaui_rx_head[1] = xaui_rx_pointer[1] + RX_FIFO_DEPTH; | |
155 | xaui_rx_tail[1] = xaui_rx_head[1] + 1; | |
156 | ||
157 | *xaui_rx_head[0] = *xaui_rx_tail[0] = 0; | |
158 | *xaui_rx_head[1] = *xaui_rx_tail[1] = 0; | |
159 | xaui_rx_pointer[0][0] = xaui_rx_pointer[1][0] = 0; | |
160 | ||
161 | ||
162 | xaui0_data = (void *) (xaui_rx_tail[1] + 1); | |
163 | xaui1_data = (void *) ((char *)xaui0_data + 10000); | |
164 | xaui_rx_data[0] = (unsigned char *) ((char *)xaui1_data + 10000); | |
165 | xaui_rx_data[1] = (unsigned char *) ((char *)xaui_rx_data[0] + RX_FIFO_SIZE); | |
166 | ||
167 | /* | |
168 | printf("sp_niu_pio_request : %x\n",(void*)sp_niu_pio_request); | |
169 | printf("sp_niu_pio_response : %x\n",(void *)sp_niu_pio_response); | |
170 | printf("sp_sii_rd_req : %x\n",(void *)sp_sii_rd_req); | |
171 | printf("sp_sii_rd_res : %x\n",(void *)sp_sii_rd_res); | |
172 | printf("sp_sii_rd_available : %x\n",(void *)sp_sii_rd_available); | |
173 | printf("sp_sii_wr_available : %x\n",(void *)sp_sii_wr_available); | |
174 | printf("sp_xaui0_available : %x\n", (void *)sp_xaui0_available); | |
175 | printf("sp_xaui1_available : %x\n", (void *)sp_xaui1_available); | |
176 | printf("sp_xaui0_req : %x\n", (void *)sp_xaui0_req); | |
177 | printf("sp_xaui1_req : %x\n", (void *)sp_xaui1_req); | |
178 | ||
179 | printf("typ : %x\n",(void *)typ); | |
180 | printf("data : %x\n",(void *)data); | |
181 | printf("niu_read : %x\n",(void *)niu_read); | |
182 | printf("niu_write : %x\n",(void *)niu_write); | |
183 | printf("read_size : %x\n",(void *)read_size); | |
184 | printf("pa_read : %x\n",(void *)pa_read); | |
185 | printf("sio_data : %x\n",(void *)sio_data); | |
186 | */ | |
187 | ||
188 | ||
189 | } | |
190 | ||
191 | void sharedmem::deliver_ncu_req(void *buf, int size) { | |
192 | ncu_interface((unsigned int *)buf); | |
193 | //memcpy(data, buf, size); | |
194 | //sema_post(sp_niu_pio_request); | |
195 | } | |
196 | ||
197 | void sharedmem::receive_niu_res(void *buf, int size) { | |
198 | sema_wait(sp_niu_pio_response); | |
199 | memcpy(buf, data, size); | |
200 | } | |
201 | ||
202 | void sharedmem::deliver_niu_res(void *buf, int size) { | |
203 | memcpy(data, buf, size); | |
204 | sema_post(sp_niu_pio_response); | |
205 | } | |
206 | ||
207 | void sharedmem::receive_ncu_req(void *buf, int size) { | |
208 | sema_wait(sp_niu_pio_request); | |
209 | memcpy(buf, data, size); | |
210 | } | |
211 | ||
212 | ||
213 | void sharedmem::signalExit() { | |
214 | setType(EXIT); | |
215 | sema_post(sp_niu_pio_request); | |
216 | } | |
217 | ||
218 | ||
219 | ||
220 | void sharedmem::setType(int t) { | |
221 | *(int*)typ = t; | |
222 | } | |
223 | ||
224 | int sharedmem::getType() { | |
225 | return *(int*)typ; | |
226 | } | |
227 | ||
228 | void sharedmem::sii_write_req(uint64_t paddr, uint8_t * data, uint64_t size) { | |
229 | sema_wait(sp_sii_wr_available); | |
230 | memcpy(sii_wr_data, data, size); | |
231 | *niu_write = 1; | |
232 | *sii_wr_addr = paddr; | |
233 | *sii_wr_size = size; | |
234 | sema_wait(sp_sii_wr_res); | |
235 | } | |
236 | ||
237 | int sharedmem::sii_receive_write_req(uint64_t &paddr, uint8_t * data, uint64_t &size) { | |
238 | paddr = *sii_wr_addr; | |
239 | size = *sii_wr_size; | |
240 | memcpy(data, sii_wr_data, size); | |
241 | if(*niu_write != 0) { | |
242 | *niu_write = 0; | |
243 | return 1; | |
244 | } | |
245 | return 0; | |
246 | } | |
247 | ||
248 | void sharedmem::sii_write_res() { | |
249 | sema_post(sp_sii_wr_res); | |
250 | sema_post(sp_sii_wr_available); | |
251 | } | |
252 | ||
253 | ||
254 | ||
255 | void sharedmem::sii_read_req(uint64_t paddr, uint8_t * data, uint64_t size) { | |
256 | sema_wait(sp_sii_rd_available); | |
257 | *niu_read = 1; | |
258 | *read_size = size; | |
259 | *pa_read = paddr; | |
260 | sema_wait(sp_sii_rd_res); | |
261 | memcpy(data, sio_data, size); | |
262 | sema_post(sp_sii_rd_available); | |
263 | } | |
264 | ||
265 | int sharedmem::sii_receive_read_req(uint64_t &paddr, uint64_t &size) { | |
266 | paddr = *pa_read; | |
267 | size = *read_size; | |
268 | if(*niu_read) { | |
269 | *niu_read = 0; | |
270 | return 1; | |
271 | } | |
272 | return 0; | |
273 | } | |
274 | ||
275 | void sharedmem::sii_read_res(uint8_t * data, uint64_t size) { | |
276 | memcpy(sio_data, data, size); | |
277 | sema_post(sp_sii_rd_res); | |
278 | } | |
279 | ||
280 | ||
281 | void sharedmem::tx0_send_packet(int size, uint8_t * data) { | |
282 | sema_wait(sp_xaui0_available); | |
283 | memcpy(xaui0_data, data, size); | |
284 | *xaui0_size = size; | |
285 | sema_wait(sp_xaui0_req); | |
286 | } | |
287 | ||
288 | int sharedmem::tx0_wait_packet(int &size, uint8_t * data) { | |
289 | if(*xaui0_size) { | |
290 | memcpy(data, xaui0_data, *xaui0_size); | |
291 | size = *xaui0_size; | |
292 | *xaui0_size = 0; | |
293 | return 1; | |
294 | } | |
295 | return 0; | |
296 | } | |
297 | ||
298 | void sharedmem::tx0_packet_sent() { | |
299 | sema_post(sp_xaui0_req); | |
300 | sema_post(sp_xaui0_available); | |
301 | } | |
302 | ||
303 | void sharedmem::tx1_send_packet(int size, uint8_t * data) { | |
304 | sema_wait(sp_xaui1_available); | |
305 | memcpy(xaui1_data, data, size); | |
306 | *xaui1_size = size; | |
307 | sema_wait(sp_xaui1_req); | |
308 | } | |
309 | ||
310 | int sharedmem::tx1_wait_packet(int &size, uint8_t * data) { | |
311 | if(*xaui1_size) { | |
312 | memcpy(data, xaui1_data, *xaui1_size); | |
313 | size = *xaui1_size; | |
314 | *xaui1_size = 0; | |
315 | return 1; | |
316 | } | |
317 | return 0; | |
318 | } | |
319 | ||
320 | void sharedmem::tx1_packet_sent() { | |
321 | sema_post(sp_xaui1_req); | |
322 | sema_post(sp_xaui1_available); | |
323 | } | |
324 | ||
325 | ||
326 | ||
327 | void sharedmem::rx0_wait_packet(int &size, uint8_t * data) { | |
328 | sema_wait(sp_rx0_available); | |
329 | remove_rx_packet(0, data, size); | |
330 | //display_rx_packet_queue(0); | |
331 | } | |
332 | ||
333 | void sharedmem::rx1_wait_packet(int &size, uint8_t * data) { | |
334 | sema_wait(sp_rx1_available); | |
335 | remove_rx_packet(1, data, size); | |
336 | //display_rx_packet_queue(1); | |
337 | } | |
338 | ||
339 | void sharedmem::rx0_packet_rec(int size, uint8_t * data) { | |
340 | add_rx_packet(0, data, size); | |
341 | //display_rx_packet_queue(0); | |
342 | sema_post(sp_rx0_available); | |
343 | } | |
344 | ||
345 | void sharedmem::rx1_packet_rec(int size, uint8_t * data) { | |
346 | add_rx_packet(1, data, size); | |
347 | //display_rx_packet_queue(1); | |
348 | sema_post(sp_rx1_available); | |
349 | } | |
350 | ||
351 | ||
352 | void sharedmem::add_rx_packet(int port, void *data, int size) { | |
353 | //if not enough data in the buffer, use 2 pointers for it | |
354 | //move to the beginning of the buffer | |
355 | int head = *xaui_rx_head[port]; | |
356 | int tail = *xaui_rx_tail[port]; | |
357 | //printf("RX PACKET QUEUE: Port:%d - Head:%d Tail:%d\n", port, head, tail); | |
358 | if((xaui_rx_pointer[port][head] + size) > RX_FIFO_SIZE) { | |
359 | head = (head + 1) % RX_FIFO_DEPTH; | |
360 | if(head == tail) { | |
361 | //Too many packets buffered, need to discard current packet | |
362 | printf("WARNING: Congestion! too many packets waiting in the queue, dropping the packet!\n"); | |
363 | return; | |
364 | } | |
365 | memcpy((void*)(xaui_rx_data[port] + xaui_rx_pointer[port][head]), data, size); | |
366 | head = (head + 1) % RX_FIFO_DEPTH; | |
367 | if(head == tail) { | |
368 | //Too many packets buffered, need to discard current packet | |
369 | printf("WARNING: Congestion! too many packets waiting in the queue, dropping the packet!\n"); | |
370 | return; | |
371 | } | |
372 | xaui_rx_pointer[port][head] = xaui_rx_pointer[port][*xaui_rx_head[port]] + size; | |
373 | } else { | |
374 | memcpy(xaui_rx_data[port] + xaui_rx_pointer[port][head], data, size); | |
375 | head = (head + 1) % RX_FIFO_DEPTH; | |
376 | if(head == tail) { | |
377 | //Too many packets buffered, need to discard current packet | |
378 | printf("WARNING: Congestion! too many packets waiting in the queue, dropping the packet!\n"); | |
379 | return; | |
380 | } | |
381 | xaui_rx_pointer[port][head] = xaui_rx_pointer[port][*xaui_rx_head[port]] + size; | |
382 | } | |
383 | *xaui_rx_head[port] = head; | |
384 | } | |
385 | ||
386 | void sharedmem::remove_rx_packet(int port, void *data, int &size) { | |
387 | //assume that data is available // checked through semaphores | |
388 | //make sure that simultaneous add/remove does not create a problem | |
389 | int tail = *xaui_rx_tail[port]; | |
390 | //printf("RX PACKET QUEUE: Port:%d - Tail:%d\n", port, tail); | |
391 | tail = (tail + 1) % RX_FIFO_DEPTH; | |
392 | if(xaui_rx_pointer[port][tail] == 0) { | |
393 | *xaui_rx_tail[port] = tail; | |
394 | tail = (tail + 1) % RX_FIFO_DEPTH; | |
395 | } | |
396 | size = xaui_rx_pointer[port][tail] - xaui_rx_pointer[port][*xaui_rx_tail[port]]; | |
397 | memcpy(data, xaui_rx_data[port] + xaui_rx_pointer[port][*xaui_rx_tail[port]], size); | |
398 | *xaui_rx_tail[port] = tail; | |
399 | } | |
400 | ||
401 | void sharedmem::display_rx_packet_queue(int port) { | |
402 | int head = *xaui_rx_head[port]; | |
403 | int tail = *xaui_rx_tail[port]; | |
404 | printf("display_rx%d_packet_queue: head:%d tail:%d\n", port, head, tail); | |
405 | while(head != tail) { | |
406 | if(xaui_rx_pointer[port][(tail + 1) % RX_FIFO_DEPTH] == 0) tail = (tail + 1) % RX_FIFO_DEPTH; | |
407 | printf("Packet Size: %d - %d\n", xaui_rx_pointer[port][(tail + 1) % RX_FIFO_DEPTH] - xaui_rx_pointer[port][tail], tail); | |
408 | tail = (tail + 1) % RX_FIFO_DEPTH; | |
409 | } | |
410 | } | |
411 | ||
412 | void sharedmem::deliverInterrupt(unsigned int data) { | |
413 | *interrupt = data; | |
414 | } | |
415 | ||
416 | void sharedmem::receiveInterrupt(unsigned int &data) { | |
417 | data = *interrupt; | |
418 | *interrupt = 0; | |
419 | } | |
420 | ||
421 |