summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorPrachi Gupta <pragupta@us.ibm.com>2014-08-20 15:25:18 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-11-13 08:05:26 -0600
commit520e2dae589df58d9e50f8d6a3828d620e4c4783 (patch)
tree2c3a5882cb5f5d5aab397a3cc5512b7df0c74cbf /src/usr
parent71a92d99bc32fe35a5b87cf321c0e4cf5e8f6e9c (diff)
downloadtalos-hostboot-520e2dae589df58d9e50f8d6a3828d620e4c4783.tar.gz
talos-hostboot-520e2dae589df58d9e50f8d6a3828d620e4c4783.zip
ISDIMM to C4 DQ/DQS standalone compression tool (Rosetta Stone)
Change-Id: I8e5adf282d82085f504e64a0ffc8d913b7cb237b RTC:109474 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/12907 Tested-by: Jenkins Server Reviewed-by: STEPHEN M. CPREK <smcprek@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionConsts.H48
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionLib.C392
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionReasonCodes.H39
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/compressionTool/EncodeDQMapping.C292
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/compressionTool/makefile47
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk6
-rw-r--r--src/usr/hwpf/test/hwpDQCompressionTest.H224
-rw-r--r--src/usr/hwpf/test/makefile1
8 files changed, 1047 insertions, 2 deletions
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionConsts.H b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionConsts.H
new file mode 100644
index 000000000..6eafef167
--- /dev/null
+++ b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionConsts.H
@@ -0,0 +1,48 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/hwpf/working/hwp/mvpd_accessors/compressionTool/DQCompressionConsts.H,v $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: DQCompressionConsts.H,v 1.1 2014/11/12 19:55:07 pragupta Exp $
+#ifndef _DQCOMPRESSIONCONSTS_H_
+#define _DQCOMPRESSIONCONSTS_H_
+
+namespace DQCompression
+{
+/* Constants to be used by compression and decompression */
+ const uint32_t DQarray_size = 80;
+ const uint32_t DQSarray_size = 20;
+ const uint32_t BYTE_LENGTH = 8;
+ const uint32_t BYTE_CODE_LENGTH = 3; //bytes
+ const uint32_t NIBBLE_SWAP_LENGTH = 2; //bytes
+ const uint32_t NIBBLE_PERM_LENGTH = 5; //bits
+ const uint32_t DQ_CODE_LENGTH = 17;//bytes
+ const uint32_t DQS_CODE_LENGTH = 2; //bytes
+ const uint32_t SIX_BIT_ZERO_PADDING = 6;
+
+ const uint32_t DQ_GROUP_SIZE = 8;
+ const uint32_t DQS_GROUP_SIZE = 2;
+ //DQ and DQS Flag - to determine the input type
+ const uint8_t DQ = 1;
+ const uint8_t DQS= 2;
+}
+#endif
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionLib.C b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionLib.C
new file mode 100644
index 000000000..e4f7f81e0
--- /dev/null
+++ b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionLib.C
@@ -0,0 +1,392 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/hwpf/working/hwp/mvpd_accessors/compressionTool/DQCompressionLib.C,v $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//$Id: DQCompressionLib.C,v 1.6 2014/11/12 19:53:08 pragupta Exp $
+/**
+ * @file DQCompressionLib.C
+ * @brief Defines utility functions which calculates the encoding for DQ
+ * or DQS arrays
+ *
+ * Wiring Rules:
+ * - On a port any byte may be wired to any byte on the DIMM connector
+ * i.e. bytes must remain whole and undivided
+ *
+ * - In a Byte the Upper and Lower Nibble my be swapped.
+ * This includes the DQ and the DQS
+ *
+ * - In a Nibble any connection of the DQ is allowed.
+ * i.e. Nibbles must remain whole and undivided
+ *
+ * - The DQS may be swapped from the upper and lower nibbles
+ * in a byte without swapping the DQ.
+ */
+#include <DQCompressionLib.H>
+#include "DQCompressionConsts.H"
+
+using namespace DQCompression;
+/**
+ * @brief Checks whether the input follows the wiring rules or not
+ * @param i_data DQ or DQS array as a vector
+ * @param i_arrayType DQ = 1 and DQS = 2
+ */
+int validateInputData (const std::vector<uint8_t>& i_data,
+ uint32_t i_arrayType)
+{
+ int l_rc = NO_ERR;
+ do
+ {
+ l_rc = ((i_data.size() == 80) || (i_data.size() == 20)) ?
+ NO_ERR : INVALID_INPUT;
+ if (l_rc != NO_ERR)
+ {
+ DQ_TRAC("Input data size is: %d. Size should be 80 or 20\n",
+ (int)i_data.size());
+ break;
+ }
+ uint32_t l_grpSize = (i_arrayType == DQS) ? 2: BYTE_LENGTH;
+
+ //Check that the bytes are whole and undivided
+ //Check that the nibbles are whole and undivided
+ std::vector<uint8_t> l_data (i_data);
+
+ std::vector<uint8_t>::iterator l_itBegin = l_data.begin();
+ std::vector<uint8_t>::iterator l_itMiddle = l_itBegin + (l_grpSize/2);
+ std::vector<uint8_t>::iterator l_itEnd = l_itBegin + l_grpSize;
+
+ uint32_t l_loopCnts = l_data.size()-l_grpSize;
+ for(uint32_t i = 0; (i < l_loopCnts); i += l_grpSize)
+ {
+ //Sort nibbles at a time
+ std::sort(l_itBegin, l_itMiddle);
+ std::sort(l_itMiddle,l_itEnd);
+
+ //Check the first nibble
+ for (std::vector<uint8_t>::iterator j = l_itBegin;
+ j < l_itMiddle-1; j++)
+ {
+ if (*(j+1) != (*j)+1)
+ {
+ l_rc = INVALID_INPUT;
+ DQ_TRAC("First nibble of byte %d is not together\n",i);
+ break;
+ }
+ }
+ if (l_rc)
+ {
+ break;
+ }
+
+ //Check the second nibble
+ for (std::vector<uint8_t>::iterator j = l_itMiddle;
+ (j < l_itEnd-1); j++)
+ {
+ if (*(j+1) != (*j)+1)
+ {
+ l_rc = INVALID_INPUT;
+ DQ_TRAC("Second nibble of byte %d is not together\n",i);
+ break;
+ }
+ }
+ if (l_rc)
+ {
+ break;
+ }
+
+ //Check that first and second nibble are part of the same byte
+ uint8_t l_inc = l_grpSize/2;
+ if (((*l_itBegin+l_inc) != *l_itMiddle) &&
+ ((*l_itBegin-l_inc) != *l_itMiddle))
+ {
+ l_rc = INVALID_INPUT;
+ DQ_TRAC("Byte %d is not together\n", i);
+ break;
+ }
+
+ l_itBegin += l_grpSize;
+ l_itMiddle+= l_grpSize;
+ l_itEnd += l_grpSize;
+ } //end for loop
+ } while (0);
+ return l_rc;
+}
+
+
+/**
+ * @brief Calculates the byte-to-byte mapping for ISDIMM to Centaur
+ * @param i_data DQ or DQS array as a vector
+ * @param o_byteMap: vector that will hold the byte-to-byte mapping
+ */
+void byte_mapping (std::vector<uint8_t>& i_data,
+ std::vector<uint8_t>& o_byteMap)
+{
+ uint32_t l_size = i_data.size() - BYTE_LENGTH;
+
+ for(uint32_t i = 0; i < l_size; i += BYTE_LENGTH)
+ {
+ o_byteMap.push_back(i_data[i]/BYTE_LENGTH);
+ }
+}
+
+/**
+ * @brief Calculates the permutation of a sequence between two iterators
+ * @param i_itBegin iterator to the beginning of the sequence
+ * @param i_itEnd iterator to the end of the sequence
+ * @retval uint32_t code: 24 bits of code for byte permuatation
+ * and 5 bits of code for nibble permutation
+ */
+uint32_t permutation (const std::vector<uint8_t>::iterator i_itBegin,
+ const std::vector<uint8_t>::iterator i_itEnd)
+{
+ std::vector<uint8_t> l_sequence (i_itBegin, i_itEnd);
+ std::vector<uint8_t> l_permutation;
+ std::vector<uint8_t> l_index (l_sequence);
+ size_t l_seqSize = l_sequence.size();
+
+ //We want the sorted list of sequence to determine
+ //the index for lehmer's code
+ std::sort(l_index.begin(), l_index.end());
+
+ for(uint32_t i = 0; i < l_seqSize; i++)
+ {
+ //find the index of the value in sequence in the index array
+ std::vector<uint8_t> ::iterator it = std::find (l_index.begin(),
+ l_index.end(), l_sequence.at(i));
+
+ //Add that index to another array
+ uint8_t l_idx = it-l_index.begin();
+ l_permutation.push_back(l_idx);
+
+ //Delete that value from the array and shift
+ //This will change the indices for the rest of
+ //the values each iteration
+ l_index.erase(l_index.begin() + l_idx);
+ }
+
+ //Skip the last element as it is always zero
+ l_permutation.pop_back();
+
+ uint32_t l_code = 0;
+ uint32_t l_factorial = 1;
+
+ //Generate the variable base code
+ //Since, the last element will always be zero.
+ //we start multiplying by 1!
+ for (uint32_t i = 1; i < l_seqSize; i++)
+ {
+ l_factorial *= i;
+ l_code += l_factorial * l_permutation.back();
+ l_permutation.pop_back();
+ }
+ return l_code;
+}
+
+/**
+ * @brief Figures out if the nibbles within a byte are swapped or not
+ * @param i_data DQ or DQS array as a vector
+ * @param l_grpSize: 8 for DQ and 2 for DQS
+ * @retval uint32_t which has 1 for the byte whose nibble is swapped
+ * or 0 if the nibbles are not swapped
+ */
+uint32_t nibble_swap (std::vector<uint8_t>& i_data, uint32_t l_grpSize)
+{
+ uint32_t o_swap = 0;
+ //Skip the last one as it is unused
+ for(uint32_t i = 0; i < i_data.size() - l_grpSize; i+= l_grpSize)
+ {
+ if (i_data.at(i) > i_data.at(i+(l_grpSize/2)))
+ {
+ o_swap |= 1;
+ }
+ o_swap <<= 1;
+ }
+ return (o_swap>>1);
+}
+
+/**
+ * @brief Insert data in ecmdDataBuffer one byte at a time to preserve
+ * endianess
+ * @param o_encodedData: buffer to insert the data into
+ * @param i_data: value to be inserted in ecmdDataBuffer
+ * @param i_size: number of bytes to insert
+ * @param i_startBit: Bit to start inserting the data from
+ * @retval errl: NULL for no-err and BUFFER_OVERFLOW
+ * if error inserting in ecmdDataBuffer
+ */
+int insertEncodedData (ecmdDataBufferBase& o_encodedData, uint32_t i_data,
+ uint32_t i_size, uint32_t i_startBit)
+{
+ DQ_TRAC("Entering insertEncodedData i_data:%X, i_size:%d, i_startBit:%d\n",
+ i_data, i_size, i_startBit);
+ int l_rc = NO_ERR;
+ //Insert one byte at a time to take care of endianess
+ for(int i = i_size; i > 0; i--)
+ {
+ uint32_t l_datatobeinserted = (i_data>>((i-1)*BYTE_LENGTH))&0xFF;
+ l_rc = o_encodedData.insertFromRight(l_datatobeinserted,
+ i_startBit, BYTE_LENGTH);
+ if (l_rc)
+ {
+ l_rc = ECMD_OPER_ERROR;
+ DQ_TRAC("ECMD errored while writing %d data ;startbit=%d\n",
+ l_datatobeinserted, i_startBit);
+ break;
+ }
+ i_startBit += BYTE_LENGTH;
+ }
+ return l_rc;
+}
+
+/**
+ * @brief Calculates the encoding for ISDIMM to C4DQ or C4DQS
+ * @param i_data DQ or DQS array as a vector
+ * @param i_arrayType DQ = 1 and DQS = 2
+ * @param o_encodedData buffer to insert the encoded data into
+ * @retval error codes
+ */
+int DQCompression::encodeDQ (std::vector<uint8_t>& i_data,
+ uint32_t i_arrayType, ecmdDataBufferBase& o_encodedData)
+{
+ int l_rc = NO_ERR;
+ uint8_t l_grpSize;
+
+ DQ_TRAC("Entering encodeDQ\n");
+ do
+ {
+ l_rc = validateInputData (i_data, i_arrayType);
+ if(l_rc)
+ {
+ DQ_TRAC ("validateInputData errored\n");
+ break;
+ }
+ if (i_arrayType == DQ)
+ {
+ l_grpSize = DQ_GROUP_SIZE;
+ //allocate the buffers with right length
+ o_encodedData.setByteLength(DQ_CODE_LENGTH);
+
+ //Determine the byte-to-byte mapping
+ std::vector<uint8_t> l_byteMap;
+ byte_mapping(i_data, l_byteMap);
+
+ //Determine the permutation for byte mapping
+ uint32_t l_byteCode = permutation(l_byteMap.begin(),
+ l_byteMap.end());
+
+ //Check if the nibbles are swapped within a byte
+ uint32_t l_nibbleSwap = nibble_swap(i_data, l_grpSize);
+
+ //Copy everything into the o_encodedData buffer
+ //Copy encoded data for byte-to-byte mapping
+ uint32_t l_startBit = 0;
+ DQ_TRAC("Writing byte-to-byte mapping to ecmdBuffer\n");
+ l_rc = insertEncodedData (o_encodedData, l_byteCode,
+ BYTE_CODE_LENGTH,l_startBit);
+ if (l_rc)
+ {
+ DQ_TRAC("Error writing byte-to-byte mapping to ecmdBuffer\n");
+ break;
+ }
+
+ //Copy the data for nibbleSwap
+ DQ_TRAC("Writing nibbleSwap data to ecmdBuffer\n");
+ l_startBit += (BYTE_CODE_LENGTH * BYTE_LENGTH);
+ l_rc = insertEncodedData (o_encodedData, l_nibbleSwap,
+ NIBBLE_SWAP_LENGTH,l_startBit);
+ if (l_rc)
+ {
+ DQ_TRAC("Error writing nibbleSwap data to ecmdBuffer\n");
+ break;
+ }
+
+ //Nibble Permutations - setup
+ std::vector<uint8_t>::iterator l_itBegin = i_data.begin();
+ std::vector<uint8_t>::iterator l_itEnd = l_itBegin +
+ (l_grpSize/2);
+
+ int l_numNibbles = ((i_data.size()/l_grpSize) - 1)*2;
+ l_startBit += NIBBLE_SWAP_LENGTH*BYTE_LENGTH;
+
+ //Add 0 padding - to round up the nibble perms to next byte
+ DQ_TRAC("Writing the 0 padding\n");
+ uint32_t l_temp = 0;
+ l_rc = o_encodedData.insertFromRight(l_temp,l_startBit,
+ SIX_BIT_ZERO_PADDING);
+ if (l_rc)
+ {
+ DQ_TRAC("Error writing 6-bit 0 padding to ecmdDataBuffer\n");
+ break;
+ }
+ l_startBit += SIX_BIT_ZERO_PADDING;
+
+ DQ_TRAC("Starting nibble permutations\n");
+ for(int i = 0; i < l_numNibbles; i++)
+ {
+ //Find the permutation of the nibble
+ uint32_t l_nibblePerm = permutation(l_itBegin, l_itEnd);
+ //Store it in the encode data buffer
+ l_rc = o_encodedData.insertFromRight(l_nibblePerm,
+ l_startBit,NIBBLE_PERM_LENGTH);
+ if (l_rc)
+ {
+ DQ_TRAC("Error writing nibblePerm data to ecmdBuffer\n",
+ i);
+ break;
+ }
+ l_startBit += NIBBLE_PERM_LENGTH;
+
+ //Setup iterators for the next iteration
+ l_itBegin += (l_grpSize/2);
+ l_itEnd += (l_grpSize/2);
+ }
+
+ if (l_rc)
+ {
+ break;
+ }
+ }
+ else if (i_arrayType == DQS)
+ {
+ l_grpSize = DQS_GROUP_SIZE;
+
+ o_encodedData.setByteLength(DQS_CODE_LENGTH);
+ uint32_t l_nibbleSwap = nibble_swap(i_data, l_grpSize);
+ l_rc = insertEncodedData (o_encodedData, l_nibbleSwap,
+ NIBBLE_SWAP_LENGTH,0);
+ if (l_rc)
+ {
+ DQ_TRAC("Error writing DQS data to ecmdDataBuffer\n");
+ break;
+ }
+ }
+ else
+ {
+ l_rc = INVALID_ARRAY_TYPE;
+ DQ_TRAC("Data type does not match DQ or DQS\n");
+ break;
+ }
+ } while (0);
+
+ DQ_TRAC("Exiting encodeDQ\n");
+ return l_rc;
+}
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionReasonCodes.H b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionReasonCodes.H
new file mode 100644
index 000000000..ce519624f
--- /dev/null
+++ b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/DQCompressionReasonCodes.H
@@ -0,0 +1,39 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/hwpf/working/hwp/mvpd_accessors/compressionTool/DQCompressionReasonCodes.H,v $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//$Id: DQCompressionReasonCodes.H,v 1.4 2014/11/12 19:53:08 pragupta Exp $
+/* @file DQCompressionReasonCodes.H
+ *
+ * @brief Reason Codes files for DQCompressionLib
+ */
+#ifndef __DQCOMPRESSIONREASONCODES_H
+#define __DQCOMPRESSIONREASONCODES_H
+ const char* ReasonCodes [] =
+ {
+ "NO_ERR",
+ "ECMD_OPER_ERROR",
+ "INVALID_INPUT",
+ "INVALID_ARRAY_TYPE"
+ };
+#endif
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/EncodeDQMapping.C b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/EncodeDQMapping.C
new file mode 100644
index 000000000..d2d861308
--- /dev/null
+++ b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/EncodeDQMapping.C
@@ -0,0 +1,292 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/hwpf/working/hwp/mvpd_accessors/compressionTool/EncodeDQMapping.C,v $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//$Id: EncodeDQMapping.C,v 1.5 2014/11/12 19:53:08 pragupta Exp $
+
+/*
+ * @file EncodeDQMapping.C
+ * @brief computes the encoding for ISDIMM to DQ or DQS mapping
+ *
+ *
+ * @param first input is a csv file that has the contents of DQ or DQS array
+ * It can have upto 4 ports. If there are less than 4 ports passed in,
+ * the algorithm will assume one-to-one mapping for the rest of the
+ * ports, meaning zeros for encoded data.
+ *
+ *
+ * @param second input is a file that will hold the encoded data
+ * (one byte of hex data separated with a space)
+ *
+ *
+ */
+#include <DQCompressionLib.H>
+#include "DQCompressionReasonCodes.H"
+#include "DQCompressionConsts.H"
+#include <stdio.h>
+
+using namespace DQCompression;
+
+void parseInput (FILE* i_ptrFile, std::vector <std::vector<uint8_t> >& i_dqData,
+ std::vector<std::vector<uint8_t> >& i_dqsData)
+{
+ const uint32_t l_MAX_STR_LENGTH = 300;
+ char l_inputStr [l_MAX_STR_LENGTH];
+ char* l_splitStr;
+
+ int l_dqRowNum = 0;
+ int l_dqsRowNum = 0;
+ uint8_t l_arrayType = 0;
+
+ //Read the file
+ while (fgets(l_inputStr,l_MAX_STR_LENGTH,i_ptrFile))
+ {
+ //convert l_inputStr to a vector of uint8_t
+ l_splitStr = strtok (l_inputStr, ",");
+ //# means it is a comment: the comment can say whether it is DQ or DQS
+ if (*l_splitStr == '#')
+ {
+ //Look for DQ or DQS in the comment
+ char* l_dqPos = strstr(l_splitStr, "DQ");
+ if (l_dqPos != NULL)
+ {
+ l_arrayType = (*(l_dqPos+2) == 'S') ? DQS : DQ;
+ }
+ }
+ //Skip empty lines
+ else if (*l_splitStr != '\n')
+ {
+ std::vector <uint8_t> l_col;
+ //Add DQ arrays to the i_dqData vector
+ if(l_arrayType == DQ)
+ {
+ i_dqData.push_back (l_col);
+ while (l_splitStr != NULL)
+ {
+ i_dqData.at(l_dqRowNum).push_back(atoi(l_splitStr));
+ l_splitStr = strtok (NULL, ",");
+ }
+ l_dqRowNum += 1;
+ }
+
+ else if(l_arrayType == DQS)
+ {
+ //Add DQS arrays to the i_dqsData vector
+ i_dqsData.push_back (l_col);
+ while (l_splitStr != NULL)
+ {
+ i_dqsData.at(l_dqsRowNum).push_back(atoi(l_splitStr));
+ l_splitStr = strtok (NULL, ",");
+ }
+ l_dqsRowNum += 1;
+ }
+ else
+ {
+ fprintf(stderr,"Couldn't determixe DQ or DQS from comment\n");
+ exit(1);
+ }
+ } // end outer else if
+ } //end while
+}
+int writeEncodedData (FILE* i_ptrFile,
+ std::vector <std::vector<uint8_t> >& i_data, uint8_t i_arrayType)
+{
+ size_t l_numPorts = i_data.size();
+ uint32_t l_dataSize;
+ int l_rc = 0;
+ for (uint32_t i = 0; i < l_numPorts; i++)
+ {
+ DQ_TRAC ("Input Data: \n");
+ for (uint32_t j = 0; j < i_data.at(i).size(); j++)
+ {
+ DQ_TRAC("%d ", i_data.at(i).at(j));
+ }
+ DQ_TRAC ("\n");
+
+
+ ecmdDataBufferBase l_encodedData;
+ l_rc = encodeDQ (i_data.at(i), i_arrayType,
+ l_encodedData);
+ if(l_rc)
+ {
+ //Check l_rc and print meaningful msgs
+ fprintf(stderr, "Error Encoding Data %s \n", ReasonCodes[l_rc]);
+ exit(1);
+ }
+
+ l_dataSize = l_encodedData.getByteLength();
+ char l_buffer [4];
+ //Write the data to a text file
+ for (uint32_t j = 0; j < l_dataSize; j++)
+ {
+ if (j == 0)
+ {
+ sprintf(l_buffer,"%02X", l_encodedData.getByte(j));
+ }
+ else
+ {
+ sprintf(l_buffer," %02X", l_encodedData.getByte(j));
+ }
+ l_rc = fputs(l_buffer, i_ptrFile);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("Unable to write data to the output file.\n");
+ break;
+ }
+ }
+ if (l_rc == EOF)
+ {
+ break;
+ }
+ l_rc = fputs("\n", i_ptrFile);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("Unable to write newline char to the output file\n");
+ break;
+ }
+ }
+
+ //If less than 4 ports are passed in as an input, we assume
+ //that the rest of the ports have one to one mapping, which
+ //leads to all zeros for the encoded data.
+ if (l_numPorts < 4)
+ {
+ for (uint32_t i = 0; i < (4 - l_numPorts); i++)
+ {
+ for (uint32_t j = 0; j < l_dataSize; j++)
+ {
+ if(j == 0)
+ {
+ l_rc = fputs("00", i_ptrFile);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("Unable to write data '00' to the output file");
+ break;
+ }
+ }
+ else
+ {
+ l_rc = fputs(" 00", i_ptrFile);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("Unable to write data '00' to the output file");
+ break;
+ }
+ }
+ } //end inner for loop
+ if (l_rc == EOF)
+ {
+ break;
+ }
+ l_rc = fputs("\n", i_ptrFile);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("Unable to write newline char to the output file");
+ break;
+ }
+ } //end for loop
+ } // end if statement
+}
+
+
+
+int main (int argc, char* argv [])
+{
+ int l_rc = 0;
+ do {
+ if (argc > 3)
+ {
+ fprintf(stderr, "There should only be two parameters\n");
+ exit(1);
+ }
+ //Open the input file
+ FILE* l_prInFile = fopen (argv[1], "r");
+ if (l_prInFile == NULL)
+ {
+ fprintf(stderr, "Can't open the input file for reading\n");
+ exit(1);
+ }
+
+ //parse the inputs
+ std::vector <std::vector<uint8_t> > l_dqData;
+ std::vector <std::vector<uint8_t> > l_dqsData;
+ parseInput(l_prInFile, l_dqData, l_dqsData);
+ fclose(l_prInFile);
+
+ //Open the output file
+ FILE* l_prOutFile = fopen (argv[2], "w");
+ if (l_prOutFile == NULL)
+ {
+ fprintf(stderr, "Can't open the output file for writing\n");
+ exit(1);
+ }
+
+ //process DQ arrays
+ if (!(l_dqData.empty()))
+ {
+ l_rc = fputs("DQ\n", l_prOutFile);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("Unable to write DQ to the file\n");
+ break;
+ }
+ if(l_dqData.at(0).size() != DQarray_size)
+ {
+ fprintf(stderr, "DQ arrays must have 80 elements\n");
+ exit(1);
+ }
+ l_rc = writeEncodedData (l_prOutFile, l_dqData, DQ);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC ("writeEncodedData for DQ failed l_rc: %d\n", l_rc);
+ break;
+ }
+ }
+
+ //process DQS arrays
+ if (!(l_dqsData.empty()))
+ {
+ l_rc = fputs("DQS\n", l_prOutFile);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("Unable to write DQS to the file\n");
+ break;
+ }
+ if(l_dqsData.at(0).size() != DQSarray_size)
+ {
+ fprintf(stderr, "DQS arrays must have 20 elements\n");
+ exit(1);
+ }
+ l_rc = writeEncodedData (l_prOutFile, l_dqsData, DQS);
+ if (l_rc == EOF)
+ {
+ DQ_TRAC("writeEncodedData for DQS failed\n");
+ break;
+ }
+ }
+
+ fclose(l_prOutFile);
+ } while (0);
+
+ return ((l_rc == EOF) ? EOF : 0);
+}
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/makefile b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/makefile
new file mode 100644
index 000000000..ad4f49996
--- /dev/null
+++ b/src/usr/hwpf/hwp/mvpd_accessors/compressionTool/makefile
@@ -0,0 +1,47 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/hwpf/hwp/mvpd_accessors/compressionTool/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2014
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+ROOTPATH = ../../../../../..
+
+OUT_FILE += $(ROOTPATH)/obj/modules/compression/compression
+
+GEN_PASS_BODY += compression
+CLEAN_TARGETS += $(OUT_FILE) compression.o
+
+INC_DIRS += $(ROOTPATH)/src/include/usr/ecmddatabuffer
+INC_DIRS += $(ROOTPATH)/src/include/usr/hwpf/hwp/mvpd_accessors
+INC_DIRS += $(ROOTPATH)/src/usr/hwpf/hwp/mvpd_accessors/compressionTool
+vpath %.C $(ROOTPATH)/src/usr/ecmddatabuffer
+
+HCFLAGS += -DPRDF_COMPRESSBUFFER_COMPRESS_FUNCTIONS=1
+HCFLAGS += -DPRDF_COMPRESSBUFFER_UNCOMPRESS_FUNCTIONS=1
+HCFLAGS += -lz
+HCFLAGS += -Di386=1
+
+include $(ROOTPATH)/config.mk
+
+compression: ecmdDataBufferBase.C DQCompressionLib.C EncodeDQMapping.C
+ $(C2) " CC $(notdir $@)"
+ $(C1)$(CCACHE) $(HOST_PREFIX)g++ -O3 -g $^ -o $(OUT_FILE)\
+ $(foreach dir,$(INC_DIRS), -I $(dir)) $(HCFLAGS)
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk b/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk
index 447584e3c..985327bea 100644
--- a/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk
+++ b/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk
@@ -22,11 +22,13 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+CFLAGS += -DDQCOMPRESSION_TEST=1
+
EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mvpd_accessors
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp/mvpd_accessors
VPATH += ${HWPPATH}/mvpd_accessors
-
+VPATH += ${HWPPATH}/mvpd_accessors/compressionTool
OBJS += getMvpdRing.o
OBJS += getMBvpdRing.o
OBJS += setMvpdRing.o
@@ -44,4 +46,4 @@ OBJS += getControlCapableData.o
OBJS += accessMBvpdL4BankDelete.o
OBJS += getDecompressedISDIMMAttrs.o
OBJS += getISDIMMTOC4DAttrs.o
-
+OBJS += DQCompressionLib.o
diff --git a/src/usr/hwpf/test/hwpDQCompressionTest.H b/src/usr/hwpf/test/hwpDQCompressionTest.H
new file mode 100644
index 000000000..7da111eba
--- /dev/null
+++ b/src/usr/hwpf/test/hwpDQCompressionTest.H
@@ -0,0 +1,224 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/test/hwpDQCompressionTest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _HWPDQCOMPRESSIONTEST_H
+#define _HWPDQCOMPRESSIONTEST_H
+
+/**
+ * @file hwpDQCompressionTest.H
+ *
+ * @brief Tests for DQ and DQS compression and decompression
+ *
+ */
+
+#include <cxxtest/TestSuite.H>
+#include <hwpf/hwp/mvpd_accessors/DQCompressionLib.H>
+#include "../hwp/mvpd_accessors/compressionTool/DQCompressionReasonCodes.H"
+#include "../hwp/mvpd_accessors/compressionTool/DQCompressionConsts.H"
+#include <hwpf/hwp/mvpd_accessors/getDecompressedISDIMMAttrs.H>
+
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/common/trace.H>
+
+using namespace TARGETING;
+using namespace DQCompression;
+
+class HwpDQCompressionTest: public CxxTest::TestSuite
+{
+public:
+ void testDQCompression1()
+ {
+ int l_errl = NO_ERR;
+ do
+ {
+ TRACFCOMP(g_trac_targeting, "Starting DQ Test 1");
+ //Input DQ array
+ uint8_t l_isdimmToC4DQ_P0 [DQarray_size]={8,9,10,11,12,13,14,15,
+ 0,1,2,3,4,5,6,7,
+ 16,17,18,19,20,21,22,23,
+ 64,65,66,67,68,69,70,71,
+ 32,33,34,35,36,37,38,39,
+ 40,41,42,43,44,45,46,47,
+ 48,49,50,51,52,53,54,55,
+ 56,57,58,59,60,61,62,63,
+ 24,25,26,27,28,29,30,31,
+ 255,255,255,255,255,255,
+ 255,255};
+
+ //convert array to a vector
+ std::vector<uint8_t> l_isdimmToC4DQ_0 (l_isdimmToC4DQ_P0,
+ l_isdimmToC4DQ_P0+(sizeof(l_isdimmToC4DQ_P0)/
+ sizeof(uint8_t)));
+
+ //Pass the vector to the encode function
+ ecmdDataBufferBase l_encodedDQData;
+ l_errl = encodeDQ(l_isdimmToC4DQ_0, DQ, l_encodedDQData);
+
+ if (l_errl)
+ {
+ TS_FAIL("Error Encoding DQ Data set1 %s",
+ ReasonCodes[l_errl]);
+ break;
+ }
+
+ //Input DQS Array
+ uint8_t l_isdimmToC4DQS_P0 [DQSarray_size]= {2,3,0,1,
+ 4,5,16,17,
+ 8,9,10,11,
+ 12,13,14,15,
+ 6,7,255,255};
+ //Convert DQS array to a vector
+ std::vector<uint8_t> l_isdimmToC4DQS_0 (l_isdimmToC4DQS_P0,
+ l_isdimmToC4DQS_P0+(sizeof(l_isdimmToC4DQS_P0)/
+ sizeof(uint8_t)));
+
+ //encode
+ ecmdDataBufferBase l_encodedDQSData;
+ l_errl = encodeDQ(l_isdimmToC4DQS_0, DQS, l_encodedDQSData);
+ if (l_errl)
+ {
+ TS_FAIL("Error Encoding DQS Data1 %s",
+ ReasonCodes[l_errl]);
+ break;
+ }
+
+ //Pass the output to decode
+ uint8_t l_decDQArray [DQarray_size];
+ uint8_t l_decDQSArray[DQSarray_size];
+ decodeISDIMMAttrs(l_encodedDQData, l_encodedDQSData,
+ l_decDQArray, l_decDQSArray);
+
+ //Check if the initial vector is obtained.
+ //If not, throw an error
+ //First, check DQ
+ for (uint8_t i = 0; i < DQarray_size; i++)
+ {
+ if(l_decDQArray[i] != l_isdimmToC4DQ_P0[i])
+ {
+ TS_FAIL("Decoded Output differs from initial array DQ test1");
+ break;
+ }
+ }
+
+ //Check DQS
+ for (uint8_t i = 0; i < DQSarray_size; i++)
+ {
+ if(l_decDQSArray[i] != l_isdimmToC4DQS_P0[i])
+ {
+ TS_FAIL("Decoded Output differs from initial array DQS test1");
+ break;
+ }
+ }
+
+ TRACFCOMP(g_trac_targeting, "DQ Test 1 ended successfully");
+ } while (0);
+
+ }
+
+ void testDQCompression2 ()
+ {
+ int l_errl = NO_ERR;
+ do
+ {
+ TRACFCOMP(g_trac_targeting, "Starting DQ Test 2");
+ uint8_t l_isdimmToC4DQ_P1[DQarray_size]={24,25,26,27,28,29,30,31,
+ 4,5,6,7,0,1,2,3,
+ 20,21,22,23,16,17,18,19,
+ 68,69,70,71,64,65,66,67,
+ 36,37,38,39,32,33,34,35,
+ 43,41,42,40,44,45,46,47,
+ 48,49,50,51,52,53,54,55,
+ 56,57,58,59,60,61,62,63,
+ 15,13,14,12,10,9,11,8,
+ 255,255,255,255,255,255,
+ 255,255};
+
+ //Convert to a vector
+ std::vector<uint8_t> l_isdimmToC4DQ_1 (l_isdimmToC4DQ_P1,
+ l_isdimmToC4DQ_P1+(sizeof(l_isdimmToC4DQ_P1)/
+ sizeof(uint8_t)));
+
+ //Pass the vector to encode function
+ ecmdDataBufferBase l_encodedDQData;
+ l_errl = encodeDQ(l_isdimmToC4DQ_1, DQ, l_encodedDQData);
+
+ if (l_errl)
+ {
+ TS_FAIL("Error Encoding DQ Data2 %s",
+ ReasonCodes[l_errl]);
+ break;
+ }
+ uint8_t l_isdimmToC4DQS_P1 [DQSarray_size]= {7,6,1,0,
+ 4,5,17,16,
+ 9,8,10,11,
+ 13,12,14,15,
+ 2,3,255,255};
+ std::vector<uint8_t> l_isdimmToC4DQS_1 (l_isdimmToC4DQS_P1,
+ l_isdimmToC4DQS_P1+(sizeof(l_isdimmToC4DQS_P1)/sizeof
+ (uint8_t)));
+
+ //encode
+ ecmdDataBufferBase l_encodedDQSData;
+ l_errl = encodeDQ(l_isdimmToC4DQS_1, DQS, l_encodedDQSData);
+ if (l_errl)
+ {
+ TS_FAIL("Error Encoding DQS Data2 %s",
+ ReasonCodes[l_errl]);
+ break;
+ }
+
+ //Pass the output to decode
+ uint8_t l_decDQArray [DQarray_size];
+ uint8_t l_decDQSArray[DQSarray_size];
+ decodeISDIMMAttrs (l_encodedDQData, l_encodedDQSData,
+ l_decDQArray, l_decDQSArray);
+
+ //Check if the initial vector is obtained.
+ //If not, throw an error
+ //First, check DQ
+ for (uint8_t i = 0; i < DQarray_size; i++)
+ {
+ if(l_decDQArray[i] != l_isdimmToC4DQ_P1[i])
+ {
+ TS_FAIL("Decoded Output differs initial array DQ test2");
+ break;
+ }
+ }
+
+ //Check DQS
+ for (uint8_t i = 0; i < DQSarray_size; i++)
+ {
+ if(l_decDQSArray[i] != l_isdimmToC4DQS_P1[i])
+ {
+ TS_FAIL("Decoded Output differs initial array DQS test2");
+ break;
+ }
+ }
+
+ TRACFCOMP(g_trac_targeting, "DQ Test 2 ended successfully");
+ } while (0);
+ }
+};
+#endif
diff --git a/src/usr/hwpf/test/makefile b/src/usr/hwpf/test/makefile
index f1760b904..05f04c657 100644
--- a/src/usr/hwpf/test/makefile
+++ b/src/usr/hwpf/test/makefile
@@ -34,6 +34,7 @@ TESTS += hwpftest.H
TESTS += hwpisteperrortest.H
TESTS += hwpMBvpdAccessorTest.H
TESTS += hwpMvpdAccessorTest.H
+TESTS += hwpDQCompressionTest.H
TESTS += $(if $(CONFIG_HTMGT),occAccessTest.H)
SUBDIRS += runtime.d
OpenPOWER on IntegriCloud