summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/utils
diff options
context:
space:
mode:
authorRichard J. Knight <rjknight@us.ibm.com>2017-06-27 12:16:16 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-11-27 18:33:49 -0500
commitc2c5d0e657f6229b9d248fde3195708e303adce1 (patch)
tree6094abfe532c901f3431242b19d49fcf11cc0e1d /src/import/chips/p9/utils
parent0d63966b43335de13cf1c84531e2ca8259cec928 (diff)
downloadtalos-hostboot-c2c5d0e657f6229b9d248fde3195708e303adce1.tar.gz
talos-hostboot-c2c5d0e657f6229b9d248fde3195708e303adce1.zip
p9_xip_tool support for DD level section parsing
- Currently supports only .overlays section. - Fixed an heap problem causing segmentation fault after repetitive use of malloc in rs4_decompress() and rs4_extract_cmsk(). Now allocating buffers locally and calling _rs4_decompress() and _rs4_extract_cmsk() instead so only have to use malloc once. - Fixed a bug in the usage of the ringBlockPtr which got moved away from pointing to its initially allocated buffer after the first CMSK ring is processed. - Even though malloc() can be used in a C++ context, we really should be using the new() operator. So, I replaced all malloc() and free() with new() and delete() instead in both p9_xip_tool.C and p9_scan_compression.C. Change-Id: I2da7509ed7aaa13345185dc07bce57f71c3740fd Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42531 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Richard J. Knight <rjknight@us.ibm.com> Reviewed-by: Sumit Kumar <sumit_kumar@in.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42803 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/utils')
-rw-r--r--src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H4
-rw-r--r--src/import/chips/p9/utils/imageProcs/p9_scan_compression.C157
-rw-r--r--src/import/chips/p9/utils/imageProcs/p9_scan_compression.H63
3 files changed, 151 insertions, 73 deletions
diff --git a/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H b/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H
index 284765273..bb8ab5c1f 100644
--- a/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H
+++ b/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H
@@ -43,6 +43,10 @@ const uint32_t MAX_SEEPROM_IMAGE_SIZE = 4 * ((64 * 1024) / 9 * 8) -
256; // Max Seeprom image size, excl ECC bits (4 banks).
const uint32_t MAX_RT_IMAGE_SIZE = 1024 * 1024; // Max Runtime size.
const uint32_t MAX_RING_BUF_SIZE = 60000; // Max ring buffer size.
+const uint32_t MAX_RING_BUF_SIZE_TOOL = 200000; // Max ring buf size for tools.
+// (i.e., n3_fure.bin.srd is some
+// 346,000B x 4b/B = 1,384,000b =
+// 173,000B binary w 8b/B)
const uint32_t MAX_OVERRIDES_SIZE = 2 * 1024; // Max overrides section size.
const uint32_t MAX_HBBL_SIZE = 20 * 1024; // Max hbbl section size.
diff --git a/src/import/chips/p9/utils/imageProcs/p9_scan_compression.C b/src/import/chips/p9/utils/imageProcs/p9_scan_compression.C
index f5332b8c6..50c6c627f 100644
--- a/src/import/chips/p9/utils/imageProcs/p9_scan_compression.C
+++ b/src/import/chips/p9/utils/imageProcs/p9_scan_compression.C
@@ -674,7 +674,7 @@ rs4_compress(CompressedScanData** o_rs4,
uint32_t nibbles = rs4_max_compressed_nibbles(i_length);
uint32_t bytes = rs4_max_compressed_bytes(nibbles);
- *o_rs4 = (CompressedScanData*)malloc(bytes);
+ *o_rs4 = (CompressedScanData*)(operator new(bytes));
if (*o_rs4 == 0)
{
@@ -693,15 +693,15 @@ rs4_compress(CompressedScanData** o_rs4,
// Returns a scan compression return code.
static int
-__rs4_decompress(uint8_t* io_data_str,
- uint8_t* io_care_str,
+__rs4_decompress(uint8_t* o_data_str,
+ uint8_t* o_care_str,
uint32_t i_size,
uint32_t* o_length,
const uint8_t* i_rs4_str)
{
int state; /* 0 : Rotate, 1 : Scan */
uint32_t i; /* Nibble index in i_rs4_str */
- uint32_t j; /* Nibble index in io_data_str/io_care_str */
+ uint32_t j; /* Nibble index in o_data_str/o_care_str */
uint32_t k; /* Loop index */
uint32_t bits; /* Number of output bits decoded so far */
uint32_t count; /* Count of rotate nibbles */
@@ -715,7 +715,6 @@ __rs4_decompress(uint8_t* io_data_str,
state = 0;
// Decompress the bulk of the string
-
do
{
if (state == 0)
@@ -757,9 +756,9 @@ __rs4_decompress(uint8_t* io_data_str,
for (k = 0; k < nibbles; k++)
{
- rs4_set_nibble(io_care_str, j, rs4_get_nibble(i_rs4_str, i));
+ rs4_set_nibble(o_care_str, j, rs4_get_nibble(i_rs4_str, i));
i = (masked ? i + 1 : i);
- rs4_set_nibble(io_data_str, j, rs4_get_nibble(i_rs4_str, i));
+ rs4_set_nibble(o_data_str, j, rs4_get_nibble(i_rs4_str, i));
i++;
j++;
}
@@ -785,9 +784,9 @@ __rs4_decompress(uint8_t* io_data_str,
if (r != 0)
{
- rs4_set_nibble(io_care_str, j, rs4_get_nibble(i_rs4_str, i));
+ rs4_set_nibble(o_care_str, j, rs4_get_nibble(i_rs4_str, i));
i = (masked ? i + 1 : i);
- rs4_set_nibble(io_data_str, j, rs4_get_nibble(i_rs4_str, i));
+ rs4_set_nibble(o_data_str, j, rs4_get_nibble(i_rs4_str, i));
}
*o_length = bits;
@@ -796,8 +795,8 @@ __rs4_decompress(uint8_t* io_data_str,
int
-_rs4_decompress(uint8_t* io_data_str,
- uint8_t* io_care_str,
+_rs4_decompress(uint8_t* o_data_str,
+ uint8_t* o_care_str,
uint32_t i_size,
uint32_t* o_length,
const CompressedScanData* i_rs4)
@@ -814,10 +813,10 @@ _rs4_decompress(uint8_t* io_data_str,
return BUG(SCAN_COMPRESSION_VERSION_ERROR);
}
- memset(io_data_str, 0, i_size);
- memset(io_care_str, 0, i_size);
+ memset(o_data_str, 0, i_size);
+ memset(o_care_str, 0, i_size);
- return __rs4_decompress(io_data_str, io_care_str, i_size,
+ return __rs4_decompress(o_data_str, o_care_str, i_size,
o_length, rs4_str);
}
@@ -828,21 +827,21 @@ rs4_decompress(uint8_t** o_data_str,
uint32_t* o_length,
const CompressedScanData* i_rs4)
{
- uint32_t size = 400000;
+ uint32_t size = MAX_RING_BUF_SIZE_TOOL;
int rc;
- *o_data_str = (uint8_t*)malloc(size);
+ *o_data_str = (uint8_t*)(operator new(size));
if (*o_data_str == NULL)
{
return BUG(SCAN_COMPRESSION_NO_MEMORY);
}
- *o_care_str = (uint8_t*)malloc(size);
+ *o_care_str = (uint8_t*)(operator new(size));
if (*o_care_str == NULL)
{
- free(*o_data_str);
+ operator delete(*o_data_str);
*o_data_str = NULL;
return BUG(SCAN_COMPRESSION_NO_MEMORY);
}
@@ -851,8 +850,8 @@ rs4_decompress(uint8_t** o_data_str,
if (rc != SCAN_COMPRESSION_OK)
{
- free(*o_data_str);
- free(*o_care_str);
+ operator delete(*o_data_str);
+ operator delete(*o_care_str);
*o_data_str = NULL;
*o_care_str = NULL;
}
@@ -905,7 +904,7 @@ rs4_redundant(const CompressedScanData* i_data, int* o_redundant)
// Check for RS4 contains CMSK ring
int
-rs4_is_cmsk(CompressedScanData* i_rs4)
+rs4_is_cmsk(const CompressedScanData* i_rs4)
{
return(i_rs4->iv_type == RS4_SCAN_DATA_TYPE_CMSK);
}
@@ -915,16 +914,17 @@ rs4_is_cmsk(CompressedScanData* i_rs4)
// |------RS4 Header------|
// |-----CMSK Header------|
// |-----CMSK RS4 Data----|
-// |-------RS4 Data-------|
+// |----Stump RS4 Data----|
int
-rs4_embed_cmsk(CompressedScanData** io_rs4, CompressedScanData* i_rs4_cmsk)
+rs4_embed_cmsk( CompressedScanData** io_rs4,
+ CompressedScanData* i_rs4Cmsk )
{
- char* embedded_addr = (char*)(*io_rs4 + 1);
- size_t embedded_size = be16toh(i_rs4_cmsk->iv_size);
- size_t total_size = be16toh((*io_rs4)->iv_size) + embedded_size;
+ char* embeddedAddr = (char*)(*io_rs4 + 1);
+ size_t embeddedSize = be16toh(i_rs4Cmsk->iv_size);
+ size_t totalSize = be16toh((*io_rs4)->iv_size) + embeddedSize;
// Enlarge RS4 container to accomodate cmsk ring
- *io_rs4 = (CompressedScanData*)realloc(*io_rs4, total_size);
+ *io_rs4 = (CompressedScanData*)realloc(*io_rs4, totalSize);
if (!*io_rs4)
{
@@ -932,66 +932,113 @@ rs4_embed_cmsk(CompressedScanData** io_rs4, CompressedScanData* i_rs4_cmsk)
}
// Make space for cmsk ring
- memmove(embedded_addr + embedded_size,
- embedded_addr,
+ memmove(embeddedAddr + embeddedSize,
+ embeddedAddr,
be16toh((*io_rs4)->iv_size) - sizeof(CompressedScanData));
// Copy cmsk ring into rs4
- memcpy(embedded_addr,
- i_rs4_cmsk,
- embedded_size);
+ memcpy(embeddedAddr,
+ i_rs4Cmsk,
+ embeddedSize);
// Update header fields
- (*io_rs4)->iv_size = htobe16(total_size);
+ (*io_rs4)->iv_size = htobe16(totalSize);
(*io_rs4)->iv_type = RS4_SCAN_DATA_TYPE_CMSK;
return SCAN_COMPRESSION_OK;
}
-// Extract Stump & Cmsk ring containers
+// Extract Stump & Cmsk ring containers (assumes pre-allocation of ring buffers)
int
-rs4_extract_cmsk(CompressedScanData* i_rs4,
- CompressedScanData** io_rs4_stump,
- CompressedScanData** io_rs4_cmsk)
+_rs4_extract_cmsk( const CompressedScanData* i_rs4,
+ size_t i_size,
+ CompressedScanData* o_rs4Stump,
+ CompressedScanData* o_rs4Cmsk )
{
- CompressedScanData* embedded_addr = (CompressedScanData*)(i_rs4 + 1);
+ if (be16toh(i_rs4->iv_magic) != RS4_MAGIC)
+ {
+ return BUG(SCAN_DECOMPRESSION_MAGIC_ERROR);
+ }
- // Get size of Stump and Cmsk rings
- size_t embedded_size = be16toh(embedded_addr->iv_size);
- size_t stump_size = be16toh(i_rs4->iv_size) - embedded_size;
+ if (i_rs4->iv_version != RS4_VERSION)
+ {
+ return BUG(SCAN_COMPRESSION_VERSION_ERROR);
+ }
- // Allocate memory for Stump and Cmsk rings
- *io_rs4_stump = (CompressedScanData*)malloc(stump_size);
- *io_rs4_cmsk = (CompressedScanData*)malloc(embedded_size);
+ memset((uint8_t*)o_rs4Stump, 0, i_size);
+ memset((uint8_t*)o_rs4Cmsk, 0, i_size);
+
+ const CompressedScanData* embeddedAddr = i_rs4 + 1;
+
+ // Get size of Stump and Cmsk rings
+ size_t embeddedSize = be16toh(embeddedAddr->iv_size);
+ size_t stumpSize = be16toh(i_rs4->iv_size) - embeddedSize;
- if (!*io_rs4_stump || !*io_rs4_cmsk)
+ if (stumpSize > i_size || embeddedSize > i_size)
{
- return BUG(SCAN_COMPRESSION_NO_MEMORY);
+ return BUG(SCAN_COMPRESSION_BUFFER_OVERFLOW);
}
// Copy Cmsk ring - (header+data)
- memcpy(*io_rs4_cmsk,
- embedded_addr,
- embedded_size);
+ memcpy(o_rs4Cmsk,
+ embeddedAddr,
+ embeddedSize);
// Copy Stump ring - header
- memcpy(*io_rs4_stump,
+ memcpy(o_rs4Stump,
i_rs4,
sizeof(CompressedScanData));
// Copy Stump ring - data
- memcpy(((CompressedScanData*)(*io_rs4_stump) + 1),
- (uint8_t*)embedded_addr + embedded_size,
- stump_size - sizeof(CompressedScanData));
+ memcpy(o_rs4Stump + 1,
+ (uint8_t*)embeddedAddr + embeddedSize,
+ stumpSize - sizeof(CompressedScanData));
// Update header fields - stump
- (*io_rs4_stump)->iv_size = htobe16(stump_size);
- (*io_rs4_stump)->iv_type = RS4_SCAN_DATA_TYPE_NON_CMSK;
+ o_rs4Stump->iv_size = htobe16(stumpSize);
+ o_rs4Stump->iv_type = RS4_SCAN_DATA_TYPE_NON_CMSK;
return SCAN_COMPRESSION_OK;
}
+
+// Extract Stump & Cmsk ring containers (local allocation of ring buffers)
+int
+rs4_extract_cmsk( const CompressedScanData* i_rs4,
+ CompressedScanData** o_rs4Stump,
+ CompressedScanData** o_rs4Cmsk )
+{
+ int rc;
+ uint32_t size = MAX_RING_BUF_SIZE_TOOL;
+
+ // Allocate memory for Stump and Cmsk rings
+ *o_rs4Stump = (CompressedScanData*)(operator new(size));
+ *o_rs4Cmsk = (CompressedScanData*)(operator new(size));
+
+ if (!*o_rs4Stump || !*o_rs4Cmsk)
+ {
+ operator delete(*o_rs4Stump);
+ operator delete(*o_rs4Cmsk);
+ *o_rs4Stump = NULL;
+ *o_rs4Cmsk = NULL;
+ return BUG(SCAN_COMPRESSION_NO_MEMORY);
+ }
+
+ rc = _rs4_extract_cmsk(i_rs4, size, *o_rs4Stump, *o_rs4Cmsk);
+
+ if (rc != SCAN_COMPRESSION_OK)
+ {
+ operator delete(*o_rs4Stump);
+ operator delete(*o_rs4Cmsk);
+ *o_rs4Stump = NULL;
+ *o_rs4Cmsk = NULL;
+ }
+
+ return rc;
+}
+
+
// Prints out the raw decompressed RS4 ring content
void print_raw_ring( uint8_t* data,
uint32_t bits )
diff --git a/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H b/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H
index 158e5ec14..2a76c3088 100644
--- a/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H
+++ b/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H
@@ -123,8 +123,9 @@ compressed_scan_data_translate(CompressedScanData* o_data,
/// <ChipType> ring ID header files for more info.)
///
/// This API is required for integration with PHYP which does not support
-/// malloc(). Applications in environments supporting malloc() can use
-/// rs4_compress() instead.
+/// local memory allocation, like malloc() and new(). Applications in
+/// environments supporting local memory allocation can use rs4_compress()
+/// instead.
///
/// We always require the worst-case amount of memory including the header and
/// any rounding required to guarantee that the data size is a multiple of 8
@@ -145,7 +146,7 @@ _rs4_compress(CompressedScanData* io_rs4,
/// Compress a scan string using the RS4 compression algorithm
///
-/// \param[out] o_rs4 This algorithm uses malloc() to allocate memory for the
+/// \param[out] o_rs4 This algorithm uses new() to allocate memory for the
/// compressed data, and returns a pointer to this memory in \a o_rs4. After
/// the call this memory is owned by the caller who is responsible for
/// free()-ing the data area once it is no longer required. Note that the
@@ -189,7 +190,9 @@ rs4_compress(CompressedScanData** o_rs4,
/// the decompressed care mask, which is the size of the original string in
/// bits rounded up to the nearest byte.
///
-/// \param[in] i_size The size in \e bytes of \a io_data_str and \a io_care_str.
+/// \param[in] i_size The size in \e bytes of \a o_data_str and \a o_care_str
+/// buffers and which represents the max number of raw ring bits x 8 that may
+/// fit into the two raw ring buffers.
///
/// \param[out] o_length The length of the decompressed string in \e bits.
///
@@ -197,13 +200,14 @@ rs4_compress(CompressedScanData** o_rs4,
/// decompressed.
///
/// This API is required for integration with PHYP which does not support
-/// malloc(). Applications in environments supporting malloc() can use
-/// rs4_decompress() instead.
+/// local memory allocation, such as malloc() and new(). Applications in
+/// environments supporting local memory allocation can use rs4_decompress()
+/// instead.
///
/// \returns See \ref scan_compression_codes
int
-_rs4_decompress(uint8_t* io_data_str,
- uint8_t* io_care_str,
+_rs4_decompress(uint8_t* o_data_str,
+ uint8_t* o_care_str,
uint32_t i_size,
uint32_t* o_length,
const CompressedScanData* i_rs4);
@@ -211,11 +215,11 @@ _rs4_decompress(uint8_t* io_data_str,
/// Decompress a scan string compressed using the RS4 compression algorithm
///
-/// \param[out] o_data_str The API malloc()-s this data area to contain the
+/// \param[out] o_data_str The API new() allocs this data area to contain the
/// decompressed string. After this call the caller owns \a o_data_str and is
/// responsible for free()-ing this data area once it is no longer required.
///
-/// \param[out] o_care_str The API malloc()-s this data area to contain the
+/// \param[out] o_care_str The API new() allocs this data area to contain the
/// decompressed care mask. After this call the caller owns \a o_care_str and
/// is responsible for free()-ing this data area once it is no longer required.
///
@@ -251,7 +255,7 @@ rs4_redundant(const CompressedScanData* i_data, int* o_redundant);
/// \param[in] i_rs4 A pointer to the RS4 CompressedScanData [header + data]
///
/// \returns 1 if CMSK ring found, 0 otherwise
-int rs4_is_cmsk(CompressedScanData* i_rs4);
+int rs4_is_cmsk(const CompressedScanData* i_rs4);
/// Embed CMSK ring into an RS4 ring
@@ -265,18 +269,41 @@ int rs4_embed_cmsk(CompressedScanData** io_rs4,
CompressedScanData* i_rs4_cmsk);
-/// Extract Stump & CMSK rings from an RS4 ring
+/// Extract Stump & CMSK rings from an RS4 ring (assumes pre-allocated ring buffers)
///
-/// \param[in] i_rs4 A pointer to the CompressedScanData [header + data]
+/// \param[in] i_rs4 A pointer to the input hybrid CMSK RS4 ring and which must contain
+/// boto CompressedScanData header + RS4 encoded data string.
///
-/// \param[inout] i_rs4_stump A pointer to the Stump CompressedScanData [header + data]
+/// \param[in] i_size Size of buffers to hold the output Stump and CMSK RS4 rings.
///
-/// \param[inout] i_rs4_cmsk A pointer to the Cmsk CompressedScanData [header + data]
+/// \param[out] o_rs4_stump A pointer to a pre-allocated buffer that must be big
+/// enough to hold the Stump CompressedScanData [header + data].
+///
+/// \param[out] o_rs4_cmsk A pointer to a pre-allocated buffer that must be big
+/// enough to hold the Cmsk CompressedScanData [header + data].
+///
+/// \returns See \ref scan_compression_codes
+int _rs4_extract_cmsk( const CompressedScanData* i_rs4,
+ size_t i_size,
+ CompressedScanData* o_rs4_stump,
+ CompressedScanData* o_rs4_cmsk );
+
+
+/// Extract Stump & CMSK rings from an RS4 ring (local allocation of ring buffers)
+///
+/// \param[in] i_rs4 A pointer to the input hybrid CMSK RS4 ring and which must contain
+/// boto CompressedScanData header + RS4 encoded data string.
+///
+/// \param[out] o_rs4_stump A pointer to a locally allocated buffer that holds the
+/// Stump CompressedScanData [header + data]. The calling code must free the buffer.
+///
+/// \param[out] o_rs4_cmsk A pointer to a locally allocated buffer that holds the
+/// Cmsk CompressedScanData [header + data]. The calling code must free the buffer.
///
/// \returns See \ref scan_compression_codes
-int rs4_extract_cmsk(CompressedScanData* i_rs4,
- CompressedScanData** io_rs4_stump,
- CompressedScanData** io_rs4_cmsk);
+int rs4_extract_cmsk( const CompressedScanData* i_rs4,
+ CompressedScanData** o_rs4_stump,
+ CompressedScanData** o_rs4_cmsk );
#endif // __ASSEMBLER__
OpenPOWER on IntegriCloud