// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: pcg_lib.vr // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved // 4150 Network Circle, Santa Clara, California 95054, U.S.A. // // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // For the avoidance of doubt, and except that if any non-GPL license // choice is available it will apply instead, Sun elects to use only // the General Public License version 2 (GPLv2) at this time for any // software where a choice of GPL license versions is made // available with the language indicating that GPLv2 or any later version // may be used, or where a choice of which version of the GPL is applied is // otherwise unspecified. // // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, // CA 95054 USA or visit www.sun.com if you need additional information or // have any questions. // // ========== Copyright Header End ============================================ #include #include "pcg_defines.vri" #include "pcg_types.vri" #include "pcg_classes.vrh" #include "pack_db.vrh" #include "pack_db_tasks.vrh" #include "flow_db.vrh" #include "flow_db_tasks.vrh" #include "mbox_class.vrh" #include "get_mbox_id.vrh" #include "pg_top_pp.vrh" extern pack_db_entry pack_db[]; // extern flow_db_entry flow_db[]; // extern integer pack_db_index; // extern integer flow_num; // extern integer pack_db_lock; // extern integer flow_db_lock; extern mbox_class mbox_id; // extern integer quiet_on; extern flow_desc flow[]; extern class pc; extern pg ptr_to_first_pg; extern pg pack_gen[16]; extern pc pack_check[4]; /* extern class pg; extern pg ptr_to_first_pg; extern pg pack_gen[4]; */ task build_frame(integer itoken, byte_array buf, var integer len,(integer header_id=-1),(integer new_crc=0)) { integer n; integer ptr=0; integer tagged = 0; integer my_port, org_port; bit [31:0] tmp32; integer data_len, header_len; integer debug = 0; integer token; integer adj_len=0; integer min,max; bit [15:0] tx_status; tmp32 = itoken; token = tmp32[25:0]; //debug = tmp32[31]; if(debug) printf("DEBUG: build_frame: Started Build-Frame. (Input: Token: %0d, Len: %0d Hdr: %0d, NewCRC: %0d Port: %0d)\n", token,len,header_id,new_crc,my_port); if( assoc_index(CHECK, pack_db, token) == 0 ) { printf("ERROR: PG LIB: build_frame: Token (%0d) is invalid/entry could not be found in packet database.\n", token); len = 0; buf = null; return; } my_port = pack_db[token].org_port; org_port = pack_db[token].org_port; if(header_id != -1) my_port = header_id; if(INTER_FEDX) { buf.val[ptr++] = pack_db[token].ifedx_control[07:0]; buf.val[ptr++] = pack_db[token].ifedx_control[15:8]; if(debug) printf("DEBUG: build_frame: Building INTERFEDX packet\n"); } if(debug) printf("DEBUG: build_frame: (1)ptr: %0d\n",ptr); if(header_id==-1) { header_len = pack_db[token].header_len[ pack_db[token].use_hdr ]; for(n=0;n< header_len ;n++) buf.val[ptr++] = pack_db[token].header[ pack_db[token].use_hdr ].val[n]; } else { #define out_use_header pack_db[token].out_header[header_id].use_header if( assoc_index(CHECK,pack_db[token].out_header,header_id) & assoc_index(CHECK,pack_db[token].out_header[header_id].header, out_use_header) ) { header_len = pack_db[token].out_header[header_id].header_len[ out_use_header ]; for(n=0; n < header_len ; n++) buf.val[ptr++] =pack_db[token].out_header[header_id].header[out_use_header].val[n]; } else { printf("ERROR: PG LIB: build_frame: out header invalid. (Token:%0d, Out header id: %0d).\n", token,header_id); len = 0; buf = null; return; } } if(debug) printf("DEBUG: build_frame: header_len: %0d\n",header_len); if(debug) printf("DEBUG: build_frame: (2)ptr: %0d\n",ptr); if(pack_db[token].frame.data_type != DAT_FC_PAUSE) '{buf.val[ptr++], buf.val[ptr++]} = token; // Store token in payload if(pack_db[token].org_port<17 & my_port>16) adj_len += 6; if(pack_db[token].org_port>16 & my_port<17) adj_len -= 6; if(debug) printf("DEBUG: build_frame: adj_len: %0d\n",adj_len); if( pack_db[token].frame.frame_type[2] ) tagged = 1; if(debug) printf("DEBUG: build_frame: (3)ptr: DAT_LEN_EXACT: %0d\n", ptr_to_first_pg.check_option(pack_db[token].frame.data_type, DAT_LEN_EXACT) ); if(pack_db[token].data_length<0) { case(pack_db[token].data_length) { -1: pack_db[token].data_length = 64; -2: pack_db[token].data_length = 128; -3: pack_db[token].data_length = 256; -4: pack_db[token].data_length = 512; -5: pack_db[token].data_length = 1024; -6: pack_db[token].data_length = (tagged) ? 1522 : 1518; -7: { // pack_db[token].data_length = random(pack_db[token].frame.data_seed); // Vera supports only one random pack_db[token].data_length = random(); min = 64; max = (tagged) ? 1522 : 1518; while(pack_db[token].data_lengthmax) pack_db[token].data_length = random(); } -8: pack_db[token].data_length = 63; -9: pack_db[token].data_length = 65; -10: pack_db[token].data_length = (tagged) ? 1521 : 1517; -11: pack_db[token].data_length = (tagged) ? 1523 : 1519; } pack_db[token].frame.data_type = pack_db[token].frame.data_type | DAT_LEN_EXACT; } if( ptr_to_first_pg.check_option(pack_db[token].frame.data_type, DAT_LEN_EXACT) ) { // Convert exact length to actual data length, clear exact flag and use that data length from now on. // data_len = pack_db[token].data_length + header_len - pack_db[token].header_len[0] + adj_len; data_len = pack_db[token].data_length - header_len - 4; // data_len - header_len - crc_len if(INTER_FEDX) data_len = data_len - 6; pack_db[token].data_length = data_len; pack_db[token].frame.data_type = pack_db[token].frame.data_type & DAT_TYPE_MASK; } else data_len = pack_db[token].data_length; if(debug) printf("DEBUG: build_frame: (3)ptr: %0d\n",ptr); if(debug) printf("DEBUG: build_frame: data_len: %0d\n",data_len); if( pack_db[token].frame.frame_type[2] ) tagged = 1; pack_gen[my_port].data_gen( pack_db[token].frame.data_type, pack_db[token].frame.data_seed, data_len, buf, ptr, pack_db[token].options, pack_gen[my_port], tagged, INTER_FEDX); if(debug) printf("DEBUG: build_frame: (4)ptr: %0d\n",ptr); if(INTER_FEDX) tmp32 = pack_gen[my_port].crc_gen(buf, 2, ptr); // Skip Interfedx Control Word else tmp32 = pack_gen[my_port].crc_gen(buf, 0, ptr); if( pack_gen[my_port].check_option( pack_db[token].options, O_CRC_ERR) ) tmp32 = tmp32 ^ pack_gen[my_port].cfg_reg[CFG_CRC_MASK]; if(!new_crc) '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].pack_crc; else { if ( (org_port==17) | (org_port==18) ) { if(INTER_FEDX) { //packets that orginated on ifedx ports cannot be looped to another ifedx, except // in iom tests. '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].pack_crc; } else { //this pkt orginated on a ifedx port and is being sent out on a ext-port. // look at the tx_mac status word to decide whether new pkt-crc is required. tx_status = pack_db[token].mac.tx_status; if(tx_status[14]) '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].pack_crc; else '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = tmp32; } } //end of if ( (org_port==17) | (org_port==18) ) else { if(INTER_FEDX) '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].pack_crc; else '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = tmp32; } } if(INTER_FEDX) { tmp32 = pack_gen[my_port].crc_gen(buf, 0, ptr); if( pack_gen[my_port].check_option( pack_db[token].options, O_IF_CRC_ERR) ) tmp32 = tmp32 ^ pack_gen[my_port].cfg_reg[CFG_CRC_MASK]; if(new_crc) { '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = tmp32; pack_db[token].ifedx_crc = tmp32; } else '{ buf.val[ptr++], buf.val[ptr++], buf.val[ptr++], buf.val[ptr++] } = pack_db[token].ifedx_crc; } if(debug) printf("DEBUG: build_frame: (5)ptr: %0d\n",ptr); if(debug) printf("DEBUG: build_frame: Done.\n"); len = ptr; /* if(header_len>66) { printf("ERROR: build_frame: Possibly corrupted header. Header is %0d bytes long !\n",header_len); printf(" Input: Token: %0d, Len: %0d Hdr: %0d, NewCRC: %0d Port: %0d\n", token, len, header_id, new_crc,my_port); printf("----------------------------------------- \n"); printf("build_frame: displaying buffer: \n"); printf("----------------------------------------- \n"); ptr_to_first_pg.display_buf(buf, len, INTER_FEDX); } */ } task build_header(integer itoken, byte_array buf, var integer len,(integer header_id=-1),(integer new_crc=0)) { integer n; integer ptr=0; integer tagged = 0; integer my_port, org_port; bit [31:0] tmp32; integer data_len, header_len; integer debug = 1; integer token; integer adj_len=0; integer min,max; bit [15:0] tx_status; tmp32 = itoken; token = tmp32[25:0]; // debug = tmp32[31]; if(debug) printf("DEBUG: build_header: Started Build-Header (Input: Token: %0d, Len: %0d Hdr: %0d, NewCRC: %0d Port: %0d)\n", token,len,header_id,new_crc,my_port); if( assoc_index(CHECK, pack_db, token) == 0 ) { printf("ERROR: PG LIB: build_frame: Token (%0d) is invalid/entry could not be found in packet database.\n", token); len = 0; buf = null; return; } my_port = pack_db[token].org_port; org_port = pack_db[token].org_port; if(header_id != -1) my_port = header_id; if(INTER_FEDX) { buf.val[ptr++] = pack_db[token].ifedx_control[07:0]; buf.val[ptr++] = pack_db[token].ifedx_control[15:8]; if(debug) printf("DEBUG: build_frame: Building INTERFEDX packet\n"); } if(debug) printf("DEBUG: build_header: (1)ptr: %0d\n",ptr); if(header_id==-1) { header_len = pack_db[token].header_len[ pack_db[token].use_hdr ]; for(n=0;n< header_len ;n++) buf.val[ptr++] = pack_db[token].header[ pack_db[token].use_hdr ].val[n]; } else { #define out_use_header pack_db[token].out_header[header_id].use_header if( assoc_index(CHECK,pack_db[token].out_header,header_id) & assoc_index(CHECK,pack_db[token].out_header[header_id].header, out_use_header) ) { header_len = pack_db[token].out_header[header_id].header_len[ out_use_header ]; for(n=0; n < header_len ; n++) buf.val[ptr++] =pack_db[token].out_header[header_id].header[out_use_header].val[n]; } else { printf("ERROR: PG LIB: build_header: out header invalid. (Token:%0d, Out header id: %0d).\n", token,header_id); len = 0; buf = null; return; } } if(debug) printf("DEBUG: build_header: header_len: %0d\n",header_len); if(debug) printf("DEBUG: build_header: (2)ptr: %0d\n",ptr); if(pack_db[token].frame.data_type != DAT_FC_PAUSE) '{buf.val[ptr++], buf.val[ptr++]} = token; // Store token in payload /**** if(header_len>66) { printf("ERROR: build_header: Possibly corrupted header. Header is %0d bytes long !\n",header_len); printf(" Input: Token: %0d, Len: %0d Hdr: %0d, NewCRC: %0d Port: %0d\n", token, len, header_id, new_crc,my_port); printf("----------------------------------------- \n"); printf("build_header: displaying buffer: \n"); printf("----------------------------------------- \n"); ptr_to_first_pg.display_buf(buf, header_len, INTER_FEDX); } ***/ } task build_ip_segment ( integer token , var bit[7:0]pkt_data[], integer offset, integer size){ byte_array pkt_buf; integer pkt_length; integer j, k,arr_size ; //arr_size = (size -offset) + 1; arr_size = (size +offset) ; pkt_buf = new; build_frame(token, pkt_buf, pkt_length); // pack_gen[0].display_buf(pkt_buf, pkt_length); j = 0; for (k=offset;k