Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / systemc / niu / sharedmem.cpp
CommitLineData
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
78sharedmem::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
191void 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
197void sharedmem::receive_niu_res(void *buf, int size) {
198 sema_wait(sp_niu_pio_response);
199 memcpy(buf, data, size);
200}
201
202void sharedmem::deliver_niu_res(void *buf, int size) {
203 memcpy(data, buf, size);
204 sema_post(sp_niu_pio_response);
205}
206
207void sharedmem::receive_ncu_req(void *buf, int size) {
208 sema_wait(sp_niu_pio_request);
209 memcpy(buf, data, size);
210}
211
212
213void sharedmem::signalExit() {
214 setType(EXIT);
215 sema_post(sp_niu_pio_request);
216}
217
218
219
220void sharedmem::setType(int t) {
221 *(int*)typ = t;
222}
223
224int sharedmem::getType() {
225 return *(int*)typ;
226}
227
228void 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
237int 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
248void sharedmem::sii_write_res() {
249 sema_post(sp_sii_wr_res);
250 sema_post(sp_sii_wr_available);
251}
252
253
254
255void 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
265int 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
275void 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
281void 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
288int 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
298void sharedmem::tx0_packet_sent() {
299 sema_post(sp_xaui0_req);
300 sema_post(sp_xaui0_available);
301}
302
303void 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
310int 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
320void sharedmem::tx1_packet_sent() {
321 sema_post(sp_xaui1_req);
322 sema_post(sp_xaui1_available);
323}
324
325
326
327void 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
333void 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
339void 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
345void 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
352void 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
386void 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
401void 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
412void sharedmem::deliverInterrupt(unsigned int data) {
413 *interrupt = data;
414}
415
416void sharedmem::receiveInterrupt(unsigned int &data) {
417 data = *interrupt;
418 *interrupt = 0;
419}
420
421