diff options
Diffstat (limited to 'src/import/chips')
-rw-r--r-- | src/import/chips/p9/utils/imageProcs/p9_ringId.H | 23 | ||||
-rw-r--r-- | src/import/chips/p9/utils/imageProcs/p9_tor.C | 362 | ||||
-rw-r--r-- | src/import/chips/p9/utils/imageProcs/p9_tor.H | 97 | ||||
-rw-r--r-- | src/import/chips/p9/xip/p9_xip_tool.C | 245 |
4 files changed, 425 insertions, 302 deletions
diff --git a/src/import/chips/p9/utils/imageProcs/p9_ringId.H b/src/import/chips/p9/utils/imageProcs/p9_ringId.H index bd89194d..8c8fbdcf 100644 --- a/src/import/chips/p9/utils/imageProcs/p9_ringId.H +++ b/src/import/chips/p9/utils/imageProcs/p9_ringId.H @@ -68,9 +68,10 @@ typedef enum RingVariant // Base variables NOT_VALID = 0xff } RingVariant_t; +#define P9_RINGID_VARIANT_ORDER_SIZE 3 typedef struct { - uint8_t variant[3]; + uint8_t variant[P9_RINGID_VARIANT_ORDER_SIZE]; } RingVariantOrder; @@ -244,6 +245,7 @@ const uint8_t INSTANCE_RING_MASK = 0x7F; namespace PERV { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -289,6 +291,7 @@ static const CHIPLET_DATA g_pervData = namespace N0 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -318,12 +321,13 @@ static const CHIPLET_DATA g_n0Data = 2, // N0 Chiplet ID is 2. 9, // 9 common rings for N0 Chiplet 3, // 3 instance specific rings for N0 chiplet - 3 + 3 // FIXME: number of variants? doesn't match RingVariants below! }; }; namespace N1 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -363,6 +367,7 @@ static const CHIPLET_DATA g_n1Data = namespace N2 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -398,6 +403,7 @@ static const CHIPLET_DATA g_n2Data = namespace N3 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -434,6 +440,7 @@ static const CHIPLET_DATA g_n3Data = namespace XB { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -476,6 +483,7 @@ static const CHIPLET_DATA g_xbData = namespace MC { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -519,6 +527,7 @@ static const CHIPLET_DATA g_mcData = namespace OB0 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -551,6 +560,7 @@ static const CHIPLET_DATA g_ob0Data = namespace OB1 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -584,6 +594,7 @@ static const CHIPLET_DATA g_ob1Data = namespace OB2 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -616,6 +627,7 @@ static const CHIPLET_DATA g_ob2Data = namespace OB3 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -647,6 +659,7 @@ static const CHIPLET_DATA g_ob3Data = }; // end of namespace OB2 namespace PCI0 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -676,6 +689,7 @@ static const CHIPLET_DATA g_pci0Data = namespace PCI1 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -705,6 +719,7 @@ static const CHIPLET_DATA g_pci1Data = namespace PCI2 { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -735,6 +750,7 @@ static const CHIPLET_DATA g_pci2Data = namespace EQ { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -832,6 +848,7 @@ static const CHIPLET_DATA g_eqData = namespace EC { +// FIXME: this struct is nonsense - no one uses these fields (we only need the variant number) struct RingVariants { uint16_t iv_base; @@ -868,7 +885,7 @@ static const uint8_t INVALID_RING = 0xFF; #ifndef __PPE__ struct ringProperties_t { - uint8_t iv_torOffSet; + uint8_t iv_torOffSet; // FIXME: misnomer char iv_name[50]; CHIPLET_TYPE iv_type; }; diff --git a/src/import/chips/p9/utils/imageProcs/p9_tor.C b/src/import/chips/p9/utils/imageProcs/p9_tor.C index 05f9ff3d..827621a4 100644 --- a/src/import/chips/p9/utils/imageProcs/p9_tor.C +++ b/src/import/chips/p9/utils/imageProcs/p9_tor.C @@ -41,9 +41,7 @@ // While using tor_tor_get_block_of_rings and tor_get_single_ring API, // it is used pass by value // -#include "p9_ringId.H" #include "p9_tor.H" -#include "p9_xip_image.h" #include "p9_scan_compression.H" #include "p9_infrastruct_help.H" @@ -72,7 +70,6 @@ const char* ringVariantName[] = { "BASE", ////////////////////////////////////////////////////////////////////////////////// static int get_ring_from_sbe_image( void* i_ringSection, // Ring section ptr - uint64_t i_magic, // Image Magic Number RingID i_ringId, // Ring ID uint16_t i_ddLevelOffset, // DD level offset (wrt i_ringSection) RingType_t& io_RingType, // Common, Instance @@ -85,11 +82,13 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section uint32_t i_dbgl ) // Debug option { int rc = TOR_SUCCESS; + uint32_t torMagic; uint32_t tor_slot_no = 0; // TOR slot number (within a TOR chiplet section) uint16_t dd_level_offset; // Local DD level offset, if any (wrt i_ringSection) uint32_t acc_offset = 0; // Accumulating offset to next TOR offset - uint32_t ppe_offset = 0; // Local offset to where SBE PPE section starts - uint32_t cplt_offset = 0; // Local offset to where SBE chiplet section starts + uint32_t ppe_offset = 0; // Local offset to where SBE PPE ring section starts + uint32_t ppe_cplt_offset = 0; // Local offset to where the pool of chiplets starts + uint32_t cplt_offset = 0; // Local offset to where a specific chiplet section starts uint16_t ring_offset = 0; // Local offset to where SBE ring container/block starts uint32_t ring_size = 0; // Size of whole ring container/block. RingVariantOrder* ring_variant_order; @@ -98,23 +97,35 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section CHIPLET_DATA* l_cpltData; uint8_t l_num_variant; - if (i_magic == P9_XIP_MAGIC_HW) + torMagic = be32toh( ((TorHeader_t*)i_ringSection)->magic ); + + // Calculate the offset (wrt start of ringSection) to the SBE PPE + // ring section. This offset, ppe_offset, will point to the + // TORB header of the SBE PPE ring section. + if (torMagic == TOR_MAGIC_HW) { dd_level_offset = i_ddLevelOffset; ppe_offset = *(uint32_t*)((uint8_t*)i_ringSection + dd_level_offset); ppe_offset = be32toh(ppe_offset); } - else if (i_magic == P9_XIP_MAGIC_SEEPROM) + else if (torMagic == TOR_MAGIC_SBE || + torMagic == TOR_MAGIC_OVRD || + torMagic == TOR_MAGIC_OVLY) { ppe_offset = 0; dd_level_offset = 0; } else { - MY_ERR("Magic number i_magic=0x%016lX is not valid for SBE\n", (uintptr_t)i_magic); + MY_ERR("torMagic=0x%08x is not valid for SBE\n", torMagic); return TOR_INVALID_MAGIC_NUMBER; } + // Calculate the offset (wrt start of ringSection) to where the + // pool of chiplet offsets begins in the SBE PPE ring section, + // which is right after the TORB header. + ppe_cplt_offset = ppe_offset + sizeof(TorHeader_t); + // Looper for each SBE chiplet for (int iCplt = 0; iCplt < SBE_NOOF_CHIPLETS; iCplt++) { @@ -129,7 +140,7 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section return TOR_INVALID_CHIPLET; } - l_num_variant = (i_RingVariant == OVERRIDE || i_RingVariant == OVERLAY) ? 1 : l_num_variant; + l_num_variant = (torMagic == TOR_MAGIC_OVRD || torMagic == TOR_MAGIC_OVLY) ? 1 : l_num_variant; if (i_dbgl > 1) { @@ -154,19 +165,20 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section (ring_id_list_common + i)->ringName, i, iVariant); } - if ((strcmp( (ring_id_list_common + i)->ringName, - RING_PROPERTIES[i_ringId].iv_name) == 0) - && ( i_RingVariant == ring_variant_order->variant[iVariant] - || ( (i_RingVariant == OVERRIDE || i_RingVariant == OVERLAY) && i_magic == P9_XIP_MAGIC_SEEPROM))) + if ( ( strcmp( (ring_id_list_common + i)->ringName, + RING_PROPERTIES[i_ringId].iv_name) == 0 ) && + ( i_RingVariant == ring_variant_order->variant[iVariant] || + torMagic == TOR_MAGIC_OVRD || + torMagic == TOR_MAGIC_OVLY ) ) { strcpy(o_ringName, RING_PROPERTIES[i_ringId].iv_name); - - acc_offset = dd_level_offset + ppe_offset + iCplt * sizeof(TorPpeBlock_t); + acc_offset = dd_level_offset + + ppe_cplt_offset + + iCplt * sizeof(TorPpeBlock_t); cplt_offset = *(uint32_t*)( (uint8_t*)i_ringSection + acc_offset ); cplt_offset = be32toh(cplt_offset); - - acc_offset = dd_level_offset + ppe_offset + cplt_offset; + acc_offset = dd_level_offset + ppe_cplt_offset + cplt_offset; ring_offset = *(uint16_t*)( (uint8_t*)i_ringSection + acc_offset + tor_slot_no * sizeof(ring_offset) ); @@ -175,7 +187,7 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section if (i_RingBlockType == GET_SINGLE_RING) { acc_offset = dd_level_offset + - ppe_offset + + ppe_cplt_offset + cplt_offset + ring_offset; ring_size = be16toh( ((CompressedScanData*) @@ -233,7 +245,7 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section " Chiplet section's offset to RS4 header = 0x%08x \n" " Full offset to RS4 header = 0x%08x \n" " Ring size = 0x%08x \n", - i, dd_level_offset, ppe_offset, cplt_offset, ring_offset, acc_offset, ring_size); + i, dd_level_offset, ppe_cplt_offset, cplt_offset, ring_offset, acc_offset, ring_size); } return rc; @@ -296,14 +308,16 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section strcpy(o_ringName, RING_PROPERTIES[i_ringId].iv_name); acc_offset = dd_level_offset + - ppe_offset + + ppe_cplt_offset + iCplt * sizeof(TorPpeBlock_t) + sizeof(cplt_offset); // Jump to instance offset cplt_offset = *(uint32_t*)( (uint8_t*)i_ringSection + acc_offset ); cplt_offset = be32toh(cplt_offset); - acc_offset = cplt_offset + dd_level_offset + ppe_offset; + acc_offset = cplt_offset + + dd_level_offset + + ppe_cplt_offset; ring_offset = *(uint16_t*)( (uint8_t*)i_ringSection + acc_offset + tor_slot_no * sizeof(ring_offset) ); @@ -312,7 +326,7 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section if (i_RingBlockType == GET_SINGLE_RING) { acc_offset = dd_level_offset + - ppe_offset + + ppe_cplt_offset + cplt_offset + ring_offset; ring_size = be16toh( ((CompressedScanData*) @@ -376,7 +390,7 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section " Chiplet section's offset to RS4 header = 0x%08x \n" " Full offset to RS4 header = 0x%08x \n" " Ring size = 0x%08x \n", - i, dd_level_offset, ppe_offset, cplt_offset, ring_offset, acc_offset, ring_size); + i, dd_level_offset, ppe_cplt_offset, cplt_offset, ring_offset, acc_offset, ring_size); } return rc; @@ -441,7 +455,6 @@ int get_ring_from_sbe_image( void* i_ringSection, // Ring section /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static int get_ring_from_sgpe_image ( void* i_ringSection, // Ring section ptr - uint64_t i_magic, // Image Magic Number RingID i_ringId, // Ring ID uint16_t i_ddLevelOffset, // DD level offset RingType_t& io_RingType, // Common, Instance @@ -453,24 +466,42 @@ int get_ring_from_sgpe_image ( void* i_ringSection, // Ring sectio char* o_ringName, // Name of ring uint32_t i_dbgl ) // Debug option { + uint32_t torMagic; uint32_t acc_offset = 0; // Accumulating offset to next TOR offset slot uint32_t ring_offset = 0; uint16_t chiplet_offset = 0; uint32_t ringSize = 0; int temp = (i_ddLevelOffset >> 2) + 4; // converting byte to word counter uint32_t spge_offset = 0; + uint32_t ppe_cplt_offset = 0; // Local offset to where the pool of chiplets starts + + torMagic = be32toh( ((TorHeader_t*)i_ringSection)->magic ); - if (i_magic == P9_XIP_MAGIC_HW) + // Calculate the offset (wrt start of ringSection) to the SGPE PPE + // ring section. This offset, inappropriately denoted "temp" here + // but which needs to be renamed to "ppe_offset" asap, will point + // to the TORG header of the SGPE PPE ring section. + if (torMagic == TOR_MAGIC_HW) { spge_offset = *((uint32_t*)i_ringSection + temp); //DD level offset index temp = be32toh(spge_offset); } - else if (i_magic == P9_XIP_MAGIC_SGPE) + else if (torMagic == TOR_MAGIC_SGPE) { spge_offset = 0; i_ddLevelOffset = 0; temp = be32toh(spge_offset); } + else + { + MY_ERR("torMagic=0x%08x is not valid for SGPE\n", torMagic); + return TOR_INVALID_MAGIC_NUMBER; + } + + // Calculate the offset (wrt start of ringSection) to where the + // pool of chiplet offsets begins in the SGPE PPE ring section, + // which is right after the TORG header. + ppe_cplt_offset = temp + sizeof(TorHeader_t); GenRingIdList* ring_id_list_common = NULL; GenRingIdList* ring_id_list_instance = NULL; @@ -494,18 +525,18 @@ int get_ring_from_sgpe_image ( void* i_ringSection, // Ring sectio RING_PROPERTIES[i_ringId].iv_name) == 0) && ( i_RingVariant == j )) { strcpy(o_ringName, RING_PROPERTIES[i_ringId].iv_name); - uint32_t var = 0 + i_ddLevelOffset + temp; + uint32_t var = 0 + i_ddLevelOffset + ppe_cplt_offset; int temp1 = var / sizeof(uint32_t); ring_offset = *((uint32_t*)i_ringSection + temp1); ring_offset = be32toh(ring_offset); - var = ring_offset + i_ddLevelOffset + temp; + var = ring_offset + i_ddLevelOffset + ppe_cplt_offset; temp1 = var / sizeof(uint16_t) + local; chiplet_offset = *((uint16_t*)i_ringSection + temp1); chiplet_offset = be16toh(chiplet_offset); if (i_RingBlockType == GET_SINGLE_RING) { - var = ring_offset + chiplet_offset + i_ddLevelOffset + temp; + var = ring_offset + chiplet_offset + i_ddLevelOffset + ppe_cplt_offset; ringSize = be16toh( ((CompressedScanData*) ((uint8_t*)i_ringSection + var))->iv_size ); @@ -545,7 +576,7 @@ int get_ring_from_sgpe_image ( void* i_ringSection, // Ring sectio { MY_INF(" Hex details (SGPE): Chiplet #%d offset 0x%08x local offset 0x%08x " \ "ring offset 0x%08x start adr 0x%08x ringSize=0x%08x \n", - i, var, temp, ring_offset, chiplet_offset, ringSize); + i, var, ppe_cplt_offset, ring_offset, chiplet_offset, ringSize); } return TOR_RING_FOUND; @@ -611,18 +642,18 @@ int get_ring_from_sgpe_image ( void* i_ringSection, // Ring sectio if ( i == io_instanceId && k == i_RingVariant ) { strcpy(o_ringName, RING_PROPERTIES[i_ringId].iv_name); - uint32_t var = CPLT_OFFSET_SIZE + i_ddLevelOffset + temp; + uint32_t var = CPLT_OFFSET_SIZE + i_ddLevelOffset + ppe_cplt_offset; int temp1 = var / sizeof(uint32_t); ring_offset = *((uint32_t*)i_ringSection + temp1); ring_offset = be32toh(ring_offset); - var = ring_offset + i_ddLevelOffset + temp; + var = ring_offset + i_ddLevelOffset + ppe_cplt_offset; temp1 = var / sizeof(uint16_t) + local; chiplet_offset = *((uint16_t*)i_ringSection + temp1); chiplet_offset = be16toh(chiplet_offset); if (i_RingBlockType == GET_SINGLE_RING) { - var = ring_offset + chiplet_offset + i_ddLevelOffset + temp; + var = ring_offset + chiplet_offset + i_ddLevelOffset + ppe_cplt_offset; ringSize = be16toh( ((CompressedScanData*) ((uint8_t*)i_ringSection + var))->iv_size ); @@ -667,7 +698,7 @@ int get_ring_from_sgpe_image ( void* i_ringSection, // Ring sectio { MY_INF(" Hex details (SGPE): Chiplet #%d offset 0x%08x local offset 0x%08x " \ "ring offset 0x%08x start adr 0x%08x ringSize=0x%08x \n", - i, var, temp, ring_offset, chiplet_offset, ringSize); + i, var, ppe_cplt_offset, ring_offset, chiplet_offset, ringSize); } return TOR_RING_FOUND; @@ -735,7 +766,6 @@ int get_ring_from_sgpe_image ( void* i_ringSection, // Ring sectio ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// static int get_ring_from_cme_image ( void* i_ringSection, // Ring section ptr - uint64_t i_magic, // Image Magic Number RingID i_ringId, // Ring ID uint16_t i_ddLevelOffset, // DD level offset RingType_t& io_RingType, // Common, Instance @@ -747,24 +777,38 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section char* o_ringName, // Name of ring uint32_t i_dbgl ) // Debug option { + uint32_t torMagic; uint32_t acc_offset = 0; // Accumulating offset to next TOR offset slot uint32_t ring_offset = 0; uint16_t chiplet_offset = 0; uint32_t ringSize = 0; int temp = (i_ddLevelOffset >> 2) + 2; // converting byte to word counter uint32_t cme_offset = 0; + uint32_t ppe_cplt_offset = 0; // Local offset to where the pool of chiplets starts - if (i_magic == P9_XIP_MAGIC_HW) + torMagic = be32toh( ((TorHeader_t*)i_ringSection)->magic ); + + if (torMagic == TOR_MAGIC_HW) { cme_offset = *((uint32_t*)i_ringSection + temp); //DD level offset index temp = be32toh(cme_offset); } - else if (i_magic == P9_XIP_MAGIC_CME) + else if (torMagic == TOR_MAGIC_CME) { cme_offset = 0; i_ddLevelOffset = 0; temp = be32toh(cme_offset); } + else + { + MY_ERR("torMagic=0x%08x is not valid for CME\n", torMagic); + return TOR_INVALID_MAGIC_NUMBER; + } + + // Calculate the offset (wrt start of ringSection) to where the + // pool of chiplet offsets begins in the CME PPE ring section, + // which is right after the TORC header. + ppe_cplt_offset = temp + sizeof(TorHeader_t); GenRingIdList* ring_id_list_common = NULL; GenRingIdList* ring_id_list_instance = NULL; @@ -788,18 +832,18 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section RING_PROPERTIES[i_ringId].iv_name) == 0) && ( i_RingVariant == j )) { strcpy(o_ringName, RING_PROPERTIES[i_ringId].iv_name); - uint32_t var = 0 + i_ddLevelOffset + temp; + uint32_t var = 0 + i_ddLevelOffset + ppe_cplt_offset; int temp1 = var / sizeof(uint32_t); ring_offset = *((uint32_t*)i_ringSection + temp1); ring_offset = be32toh(ring_offset); - var = ring_offset + i_ddLevelOffset + temp; + var = ring_offset + i_ddLevelOffset + ppe_cplt_offset; temp1 = var / sizeof(uint16_t) + local; chiplet_offset = *((uint16_t*)i_ringSection + temp1); chiplet_offset = be16toh(chiplet_offset); if (i_RingBlockType == GET_SINGLE_RING) { - var = ring_offset + chiplet_offset + i_ddLevelOffset + temp; + var = ring_offset + chiplet_offset + i_ddLevelOffset + ppe_cplt_offset; ringSize = be16toh( ((CompressedScanData*) ((uint8_t*)i_ringSection + var))->iv_size ); @@ -839,7 +883,7 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section { MY_INF(" Hex details (CME): Chiplet #%d offset 0x%08x local offset 0x%08x " \ "ring offset 0x%08x start adr 0x%08x ringSize=0x%08x \n", - i, var, temp, ring_offset, chiplet_offset, ringSize); + i, var, ppe_cplt_offset, ring_offset, chiplet_offset, ringSize); } return TOR_RING_FOUND; @@ -905,18 +949,18 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section if ( i == io_instanceId && k == i_RingVariant ) { strcpy(o_ringName, RING_PROPERTIES[i_ringId].iv_name); - uint32_t var = CPLT_OFFSET_SIZE + i_ddLevelOffset + temp; + uint32_t var = i_ddLevelOffset + ppe_cplt_offset + CPLT_OFFSET_SIZE; int temp1 = var / CPLT_OFFSET_SIZE; ring_offset = *((uint32_t*)i_ringSection + temp1); ring_offset = be32toh(ring_offset); - var = ring_offset + i_ddLevelOffset + temp; + var = ring_offset + i_ddLevelOffset + ppe_cplt_offset; temp1 = var / sizeof(uint16_t) + local; chiplet_offset = *((uint16_t*)i_ringSection + temp1); chiplet_offset = be16toh(chiplet_offset); if (i_RingBlockType == GET_SINGLE_RING) { - var = ring_offset + chiplet_offset + i_ddLevelOffset + temp; + var = ring_offset + chiplet_offset + i_ddLevelOffset + ppe_cplt_offset; ringSize = be16toh( ((CompressedScanData*) ((uint8_t*)i_ringSection + var))->iv_size ); @@ -947,7 +991,7 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section { MY_INF(" Hex details (CME): Chiplet #%d offset 0x%08x local offset 0x%08x " \ "ring offset 0x%08x start adr 0x%08x ringSize=0x%08x \n", - i, var, temp, ring_offset, chiplet_offset, ringSize); + i, var, ppe_cplt_offset, ring_offset, chiplet_offset, ringSize); } memcpy( (uint8_t*)(*io_ringBlockPtr), (uint8_t*)i_ringSection + var, @@ -960,14 +1004,6 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section MY_INF(" After get_ring_from_cme_image Size %d \n", io_ringBlockSize); } - if (i_dbgl > 1) - { - MY_INF(" 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n", - var, temp, ring_offset, chiplet_offset, ringSize); - MY_INF("Chiplet %d ChipletRing TOR offset %d %d Size %d %d \t\n", - i, ring_offset, chiplet_offset, ringSize, temp); - } - return TOR_RING_FOUND; } else @@ -986,6 +1022,7 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section if (chiplet_offset) { MY_ERR("Ring container is already present in the CME section \n"); + return TOR_RING_AVAILABLE_IN_RINGSECTION; } @@ -1032,7 +1069,6 @@ int get_ring_from_cme_image ( void* i_ringSection, // Ring section /// ////////////////////////////////////////////////////////////////////////////////////////// int tor_access_ring( void* i_ringSection, // Ring section ptr - uint64_t i_magic, // Image Magic Number RingID i_ringId, // Ring ID uint16_t i_ddLevel, // DD level PpeType_t i_PpeType, // SBE, CME, SGPE @@ -1046,12 +1082,15 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr uint32_t i_dbgl ) // Debug option { int rc = 0; + uint32_t torMagic; + TorHeader_t* torHeader; + TorDdBlock_t* torDdBlock; uint8_t bDdCheck = 0; uint32_t ddLevelOffset = 0; uint32_t ddLevelCount = 0; uint32_t ddLevel = 0; uint32_t ddBlockSize = 0; - uint32_t temp = 0, local = 0; + uint32_t temp = 0; if (i_dbgl > 1) @@ -1059,10 +1098,12 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr MY_INF("Entering tor_access_ring()... \n"); } - if (i_magic == P9_XIP_MAGIC_HW) + torHeader = (TorHeader_t*)i_ringSection; + torMagic = be32toh(torHeader->magic); + + if (torMagic == TOR_MAGIC_HW) { - ddLevelCount = *((uint32_t*)i_ringSection + 0); - ddLevelCount = be32toh(ddLevelCount); + ddLevelCount = torHeader->numDdLevels; if (ddLevelCount > MAX_NOOF_DD_LEVELS_IN_IMAGE) { @@ -1078,14 +1119,14 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr MY_INF("tor_access_ring(): No of DD levels: %d \n", ddLevelCount); } - // start at one since we use that as an offset - for (uint8_t i = 1; i <= ddLevelCount; i++) + for (uint8_t i = 0; i < ddLevelCount; i++) { - local = 2 * i; - ddLevelOffset = *((uint32_t*)i_ringSection + local); - - ddLevel = be32toh(ddLevelOffset) >> 24 & 0x000000FF; - ddLevelOffset = be32toh(ddLevelOffset) & 0x00FFFFFF; + torDdBlock = (TorDdBlock_t*)( (uint8_t*)torHeader + + sizeof(TorHeader_t) + + i * sizeof(TorDdBlock_t) ); + ddLevel = torDdBlock->ddLevel; + // Local ddLevelOffset + ddLevelOffset = be32toh(torDdBlock->offset); if (i_dbgl > 1) { @@ -1095,11 +1136,10 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr if ( ddLevel == i_ddLevel) { - ddLevelOffset = ddLevelOffset + sizeof(TorNumDdLevels_t); - local = local + 1; - ddBlockSize = *((uint32_t*)i_ringSection + local); - ddBlockSize = be32toh(ddBlockSize); - + // Convert to global ddLevelOffset + ddLevelOffset = ddLevelOffset + + sizeof(TorHeader_t); + ddBlockSize = htobe32(torDdBlock->size); bDdCheck = 1; break; } @@ -1115,7 +1155,9 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr return TOR_DD_LEVEL_NOT_FOUND; } } - else if ( i_magic == P9_XIP_MAGIC_SEEPROM) + else if ( torMagic == TOR_MAGIC_SBE || + torMagic == TOR_MAGIC_OVRD || + torMagic == TOR_MAGIC_OVLY ) { if ( i_PpeType == CME || i_PpeType == SGPE || i_RingBlockType == GET_DD_LEVEL_RINGS @@ -1126,11 +1168,11 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr } else { - ddLevelOffset = 0; + ddLevelOffset = sizeof(TorHeader_t); ddBlockSize = 0; } } - else if ( i_magic == P9_XIP_MAGIC_CME) + else if (torMagic == TOR_MAGIC_CME) { if ( i_PpeType == SBE || i_PpeType == SGPE || i_RingBlockType == GET_DD_LEVEL_RINGS @@ -1141,11 +1183,11 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr } else { - ddLevelOffset = 0; + ddLevelOffset = sizeof(TorHeader_t); ddBlockSize = 0; } } - else if ( i_magic == P9_XIP_MAGIC_SGPE) + else if (torMagic == TOR_MAGIC_SGPE) { if ( i_PpeType == SBE || i_PpeType == CME || i_RingBlockType == GET_DD_LEVEL_RINGS @@ -1156,15 +1198,18 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr } else { - ddLevelOffset = 0; + ddLevelOffset = sizeof(TorHeader_t); ddBlockSize = 0; } } else { - MY_ERR("Magic number i_magic=0x%016lX\n is not valid.\n", (uintptr_t)i_magic); + if (i_dbgl > 0) + { + MY_ERR("torMagic=0x%08x is not valid\n", torMagic); + } - return TOR_AMBIGUOUS_API_PARMS; + return TOR_INVALID_MAGIC_NUMBER; } if (i_RingBlockType == GET_DD_LEVEL_RINGS) @@ -1275,22 +1320,23 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr else if ( i_RingBlockType == GET_SINGLE_RING || i_RingBlockType == PUT_SINGLE_RING ) { - if (i_PpeType == SBE && - ( i_magic == P9_XIP_MAGIC_HW || - i_magic == P9_XIP_MAGIC_SEEPROM)) + if ( i_PpeType == SBE && + ( torMagic == TOR_MAGIC_HW || + torMagic == TOR_MAGIC_SBE || + torMagic == TOR_MAGIC_OVRD || + torMagic == TOR_MAGIC_OVLY ) ) { - rc = get_ring_from_sbe_image ( i_ringSection, - i_magic, - i_ringId, - ddLevelOffset, - io_RingType, - i_RingVariant, - io_instanceId, - i_RingBlockType, - io_ringBlockPtr, - io_ringBlockSize, - o_ringName, - i_dbgl); + rc = get_ring_from_sbe_image( i_ringSection, + i_ringId, + ddLevelOffset, + io_RingType, + i_RingVariant, + io_instanceId, + i_RingBlockType, + io_ringBlockPtr, + io_ringBlockSize, + o_ringName, + i_dbgl ); if (rc) { @@ -1312,22 +1358,21 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr return TOR_RING_BLOCKS_FOUND; } } - else if (i_PpeType == CME && - ( i_magic == P9_XIP_MAGIC_HW || - i_magic == P9_XIP_MAGIC_CME)) + else if ( i_PpeType == CME && + ( torMagic == TOR_MAGIC_HW || + torMagic == TOR_MAGIC_CME ) ) { - rc = get_ring_from_cme_image ( i_ringSection, - i_magic, - i_ringId, - ddLevelOffset, - io_RingType, - i_RingVariant, - io_instanceId, - i_RingBlockType, - io_ringBlockPtr, - io_ringBlockSize, - o_ringName, - i_dbgl); + rc = get_ring_from_cme_image( i_ringSection, + i_ringId, + ddLevelOffset, + io_RingType, + i_RingVariant, + io_instanceId, + i_RingBlockType, + io_ringBlockPtr, + io_ringBlockSize, + o_ringName, + i_dbgl ); if (rc == TOR_RING_NOT_FOUND) { @@ -1379,22 +1424,21 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr return TOR_RING_BLOCKS_FOUND; } } - else if (i_PpeType == SGPE && - ( i_magic == P9_XIP_MAGIC_HW || - i_magic == P9_XIP_MAGIC_SGPE)) + else if ( i_PpeType == SGPE && + ( torMagic == TOR_MAGIC_HW || + torMagic == TOR_MAGIC_SGPE ) ) { - rc = get_ring_from_sgpe_image ( i_ringSection, - i_magic, - i_ringId, - ddLevelOffset, - io_RingType, - i_RingVariant, - io_instanceId, - i_RingBlockType, - io_ringBlockPtr, - io_ringBlockSize, - o_ringName, - i_dbgl); + rc = get_ring_from_sgpe_image( i_ringSection, + i_ringId, + ddLevelOffset, + io_RingType, + i_RingVariant, + io_instanceId, + i_RingBlockType, + io_ringBlockPtr, + io_ringBlockSize, + o_ringName, + i_dbgl ); if (rc == TOR_RING_NOT_FOUND) { @@ -1448,10 +1492,11 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr } else { - MY_ERR("\t Code bug: We are unpreparred for this input parm combination: \n" - "\t i_PpeType=%d\n" - "\t i_magic=0x%016lX\n", - i_PpeType, (uintptr_t)i_magic); + if (i_dbgl > 0) + { + MY_ERR("\t Unsupported combination of i_PpeType=%d and torMagic=0x%08x\n", + i_PpeType, torMagic); + } return TOR_AMBIGUOUS_API_PARMS; } @@ -1466,7 +1511,8 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr } return TOR_AMBIGUOUS_API_PARMS; -} + +} // End of tor_access_ring() @@ -1476,7 +1522,6 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr // ///////////////////////////////////////////////////////////////////////////////////// int tor_get_single_ring ( void* i_ringSection, // Ring section ptr - uint64_t i_magic, // Image Magic Number uint16_t i_ddLevel, // DD level RingID i_ringId, // Ring ID PpeType_t i_PpeType, // SBE, CME, SGPE @@ -1489,7 +1534,7 @@ int tor_get_single_ring ( void* i_ringSection, // Ring section ptr uint32_t rc; char i_ringName[25]; - uint8_t l_instanceId = i_instanceId; + //@FIXME: This should really be ALLRING. But it's not used as input. RingType_t l_ringType; l_ringType = COMMON; @@ -1499,13 +1544,12 @@ int tor_get_single_ring ( void* i_ringSection, // Ring section ptr } rc = tor_access_ring( i_ringSection, - i_magic, i_ringId, i_ddLevel, i_PpeType, l_ringType, i_RingVariant, - l_instanceId, + i_instanceId, GET_SINGLE_RING, io_ringBlockPtr, io_ringBlockSize, @@ -1531,7 +1575,7 @@ int tor_get_single_ring ( void* i_ringSection, // Ring section ptr int tor_get_block_of_rings ( void* i_ringSection, // Ring section ptr uint16_t i_ddLevel, // DD level PpeType_t i_PpeType, // SBE,CME,SGPE - RingType_t i_RingType, // Common, Instance + RingType_t i_ringType, // Common, Instance RingVariant_t i_RingVariant, // Base,CC, RL, Ovrd, Ovly uint8_t i_instanceId, // Instance ID void** io_ringBlockPtr, // Output ring buffer @@ -1545,20 +1589,17 @@ int tor_get_block_of_rings ( void* i_ringSection, // Ring section uint32_t rc = 0; char i_ringName[25]; - uint8_t l_instanceId = i_instanceId; - RingType_t l_ringType = i_RingType; - if (l_ringType == ALLRING && i_PpeType != NUM_PPE_TYPES) + if (i_ringType == ALLRING && i_PpeType != NUM_PPE_TYPES) { // Get block of rings specific to a PPE type rc = tor_access_ring( i_ringSection, - P9_XIP_MAGIC_HW, NUM_RING_IDS, i_ddLevel, i_PpeType, - l_ringType, + i_ringType, i_RingVariant, - l_instanceId, + i_instanceId, GET_PPE_LEVEL_RINGS, io_ringBlockPtr, io_ringBlockSize, @@ -1566,17 +1607,16 @@ int tor_get_block_of_rings ( void* i_ringSection, // Ring section i_dbgl ); } - else if (l_ringType == ALLRING && i_PpeType == NUM_PPE_TYPES) + else if (i_ringType == ALLRING && i_PpeType == NUM_PPE_TYPES) { // Get DD level block of rings rc = tor_access_ring( i_ringSection, - P9_XIP_MAGIC_HW, NUM_RING_IDS, i_ddLevel, i_PpeType, - l_ringType, + i_ringType, i_RingVariant, - l_instanceId, + i_instanceId, GET_DD_LEVEL_RINGS, io_ringBlockPtr, io_ringBlockSize, @@ -1622,39 +1662,17 @@ int tor_append_ring( void* i_ringSection, // Ring section ptr char i_ringName[25]; uint32_t l_buf = 0; uint32_t* l_cpltSection = &l_buf; - uint8_t l_instanceId = i_instanceId; - RingType_t l_RingType = i_RingType; uint32_t l_ringBlockSize; uint16_t l_ringOffset16; - uint64_t l_magic; uint32_t l_torOffsetSlot; - if (i_PpeType == SBE) // Assign i_magic variant as SBE image - { - l_magic = P9_XIP_MAGIC_SEEPROM; - } - else if (i_PpeType == CME) // Assign i_magic variant as CME image - { - l_magic = P9_XIP_MAGIC_CME; - } - else if (i_PpeType == SGPE) // Assign i_magic variant as SGPE image - { - l_magic = P9_XIP_MAGIC_SGPE; - } - else - { - MY_ERR("PPE type (i_PpeType=%d) is not supported \n", i_PpeType); - return TOR_AMBIGUOUS_API_PARMS; - } - rc = tor_access_ring( i_ringSection, - l_magic, i_ringId, 0x00, i_PpeType, - l_RingType, + i_RingType, i_RingVariant, - l_instanceId, + i_instanceId, PUT_SINGLE_RING, (void**)&l_cpltSection, // On return, contains offset (wrt ringSection) of // chiplet section's common or instance section @@ -1665,7 +1683,11 @@ int tor_append_ring( void* i_ringSection, // Ring section ptr if (rc) { - MY_ERR("tor_access_ring() failed w/rc=0x%x \n", rc); + if (i_dbgl > 0) + { + MY_ERR("tor_append_ring() failed in call to tor_access_ring w/rc=0x%x \n", rc); + } + return rc; } @@ -1700,6 +1722,10 @@ int tor_append_ring( void* i_ringSection, // Ring section ptr // Update the ringSectionSize io_ringSectionSize += l_ringBlockSize; + // Update also the size in the TOR header + TorHeader_t* torHeader = (TorHeader_t*)i_ringSection; + torHeader->size = htobe32(be32toh(torHeader->size) + l_ringBlockSize); + return TOR_SUCCESS; } diff --git a/src/import/chips/p9/utils/imageProcs/p9_tor.H b/src/import/chips/p9/utils/imageProcs/p9_tor.H index d4b4250e..7d578723 100644 --- a/src/import/chips/p9/utils/imageProcs/p9_tor.H +++ b/src/import/chips/p9/utils/imageProcs/p9_tor.H @@ -25,7 +25,6 @@ #ifndef _P9_TOR_H_ #define _P9_TOR_H_ -#include "p9_ring_id.h" #include "p9_ringId.H" #define MAX_TOR_RING_OFFSET (256*256-1) // Max value of 2Byte uint @@ -36,7 +35,7 @@ namespace P9_TOR extern const char* ppeTypeName[]; extern const char* ringVariantName[]; -#define TOR_VERSION 2 +#define TOR_VERSION 3 // // TOR Magic values for top-level TOR image and TOR sub-images @@ -53,7 +52,34 @@ enum TorMagicNum TOR_MAGIC_CEN = (uint32_t)0x544F524E, // "TORN" }; +// +// Chip types to represent p9n, p9c, centaur +// +enum ChipType +{ + CT_P9N, + CT_P9C, + CT_CEN, + NUM_CHIP_TYPES +}; + typedef uint8_t ChipType_t; +const ChipType_t INVALID_CHIP_TYPE = 0xff; + +typedef struct ChipTypeList +{ + const char* name; + ChipType_t type; +} ChipTypeList_t; + +const ChipTypeList_t CHIP_TYPE_LIST[] = +{ + {"p9n", CT_P9N}, + {"p9c", CT_P9C}, + {"cen", CT_CEN}, +}; + + // // TOR header field (appears in top of every HW, SBE, CEN, OVRD, etc ring section) @@ -65,26 +91,26 @@ typedef struct ChipType_t chipType; // Value from ChipType enum uint8_t ddLevel; // =0xff if MAGIC_HW, >0 all other MAGICs uint8_t numDdLevels; // >0 if MAGIC_HW, =1 all other MAGICs - uint32_t size; // Size of the TOR ringSection. + uint32_t size; // A place holder for now, but will be used in a later commit. } TorHeader_t; +#define UNDEFINED_DD_LEVEL (uint8_t)0xff +// +// Subsequent TOR fields (listed in order they appear in TOR for easier understanding) +// typedef struct { - uint32_t TorNumDdLevels; - uint32_t reserved; -} TorNumDdLevels_t; - -typedef struct -{ - uint32_t TorDdLevelAndOffset; - uint32_t TorDdBlockSize; -} TorDdLevelBlock_t; + uint32_t offset; + uint32_t size; + uint8_t ddLevel; + uint8_t reserved[3]; +} TorDdBlock_t; typedef struct { - uint32_t TorPpeTypeOffset; - uint32_t TorPpeBlockSize; + uint32_t offset; + uint32_t size; } TorPpeBlock_t; typedef struct @@ -95,6 +121,13 @@ typedef struct typedef uint16_t TorRingOffset_t; // Ring offset value in TOR offset slot +//@FIXME Discard asap +typedef enum TorOffsetSize +{ + RING_OFFSET_SIZE = 2, + CPLT_OFFSET_SIZE = 4 +} TorOffsetSize_t; + #define TOR_SUCCESS 0 #define TOR_RING_FOUND 0 #define TOR_RING_BLOCKS_FOUND 0 @@ -117,6 +150,7 @@ typedef uint16_t TorRingOffset_t; // Ring offset value in TOR offset slot #define TOR_BUFFER_TOO_SMALL 17 #define TOR_TOO_MANY_DD_LEVELS 18 #define TOR_OFFSET_TOO_BIG 19 +#define TOR_INVALID_VARIANT 20 // Different options to extract data using tor_access_ring API typedef enum RingBlockType @@ -142,12 +176,6 @@ typedef enum PpeType NUM_PPE_TYPES = 0x03 } PpeType_t; -typedef enum TorOffsetSize -{ - RING_OFFSET_SIZE = 2, - CPLT_OFFSET_SIZE = 4 -} TorOffsetSize_t; - /// /// **************************************************************************** /// Function declares. @@ -161,9 +189,6 @@ typedef enum TorOffsetSize /// TOR API supports two type of binary image. 1) HW image format and 2) /// SEEPROM image format binary /// -/// \param[in] i_magic A uint64_t variable to indicate XIP image format -/// ring section passed -/// /// \param[in] i_ringId A enum to indicate unique ID for the ring /// /// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API @@ -211,8 +236,7 @@ typedef enum TorOffsetSize /// and the following n number of operation based on the call. /// /// GET_SINGLE_RING (\a i_ringVariant) - traverse on \a i_ringSection buffer -/// based on the following input param \a i_magic which gives details of image -/// type, \a i_ringId which gives ring info, \a i_ddLevel which gives dd spec +/// based on \a i_ringId which gives ring info, \a i_ddLevel which gives dd spec /// (Used only for HW image/optional for other image) i_ppeType which gives ppe /// type info, \a i_ringVarint gives ring variant info and \a io_instance which /// gives chiplet instance specific while accessing instance specific ring and @@ -222,33 +246,29 @@ typedef enum TorOffsetSize /// data copied into io_ringBlockPtr. \a o_ringName returns ring string name. /// /// GET_DD_LEVEL_RINGS (\a i_ringVariant) - traverse on \a i_ringSection -/// buffer based on the following input param \a i_magic which gives details -/// of image type and \a i_ddLevel which gives dd spec(Used only for HW image +/// buffer based on \a i_ddLevel which gives dd spec (used only for HW image /// /optional for other image) On return, \a io_ringBlockPtr contains DD level /// specific ring section and \a io_ringBlockSize contains size of the data /// copied into io_ringBlockPtr. \a Other params are optional. /// This ringVariant works on HW image. /// /// GET_PPE_LEVEL_RINGS (\a i_ringVariant) - traverse on \a i_ringSection -/// buffer based on the following input param \a i_magic which gives the detail -/// of image type, i_ppeType which gives ppe type info and \a i_ddLevel which -/// gives dd spec(Used only for HW image/optional for other image) On return, +/// buffer based on \a i_ppeType which gives ppe type info and \a i_ddLevel which +/// gives dd spec used only for HW image/optional for other image) On return, /// \a io_ringBlockPtr contains PPE type specific ring section and /// \a io_ringBlockSize contains size of the data copied into io_ringBlockPtr. /// \a Other params are optional. This ringVariant works on HW image. /// /// GET_CPLT_LEVEL_RINGS (\a i_ringVariant) - traverse on \a i_ringSection -/// buffer based on the following input param \a i_magic which gives the detail -/// of image type, i_ppeType which gives ppe type info, \a i_ddLevel which gives -/// dd spec(Used only for HW image/optional for other image) and \a io_RingType +/// buffer based on \a i_ppeType which gives ppe type info, \a i_ddLevel which gives +/// dd spec (used only for HW image/optional for other image) and \a io_RingType /// which gives ring type info. On return, \a io_ringBlockPtr contains chiplet /// specific ring type ring section and \a io_ringBlockSize contains size of /// the data copied into io_ringBlockPtr. \a Other params are optional. /// /// PUT_SINGLE_RING (\a i_ringVariant) - traverse on \a i_ringSection buffer -/// based on the following input param \a i_magic which gives detail of image -/// type, \a i_ringId which gives ring info, \a i_ddLevel which gives dd spec -/// (Used only for HW image/optional for other image), i_ppeType which gives +/// based on \a i_ringId which gives ring info, \a i_ddLevel which gives dd spec +/// (used only for HW image/optional for other image), i_ppeType which gives /// ppe type info, \a i_ringVarint gives ring variant info and \a io_instance /// which gives chiplet instance specific while accessing instance specific /// ring and returns chiplet number while accessing common ring. On return, @@ -261,7 +281,6 @@ typedef enum TorOffsetSize /// /// \retval non-0 See \ref TOR API RETURN errors int tor_access_ring( void* i_ringSection, // Ring address Ptr any of .rings, .overrides and .overlays. - uint64_t i_magic, // Image Magic Number RingID i_ringId, // Unique ring ID uint16_t i_ddLevel, // DD level info PpeType_t i_PpeType, // PPE type : SBE, CME, etc @@ -282,9 +301,6 @@ int tor_access_ring( void* i_ringSection, // Ring address Ptr any of . /// It contain details of p9 Ring which is used for scanning operation. /// TOR API supports HW image format only /// -/// \param[in] i_magic A uint64_t variable to indicate XIP image format -/// ring section passed -/// /// \param[in] i_ringId A enum to indicate unique ID for the ring /// /// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API @@ -316,7 +332,6 @@ int tor_access_ring( void* i_ringSection, // Ring address Ptr any of . /// /// \retval non-0 See \ref TOR API RETURN errors int tor_get_single_ring ( void* i_ringSection, - uint64_t i_magic, // Image Magic Number uint16_t i_ddLevel, RingID i_ringId, PpeType_t i_PpeType, diff --git a/src/import/chips/p9/xip/p9_xip_tool.C b/src/import/chips/p9/xip/p9_xip_tool.C index 04555105..069cb426 100644 --- a/src/import/chips/p9/xip/p9_xip_tool.C +++ b/src/import/chips/p9/xip/p9_xip_tool.C @@ -149,9 +149,16 @@ const char* g_usage = "section of the image at the time it is deleted, or must be empty. The\n" "'delete' command writes the size of the final modified image to stdout.\n" "\n" - "The 'dissect' command dissects the ring section named by the section argument\n" - "and summarizes the content of the ring section. The second argument to\n" - "'dissect', i.e. [table,short,normal(default),long,raw], specifies how much information\n" + "The 'dissect' command dissects a ring section. It accepts two different\n" + "types of images, namely the regular XIP image and now also stand-alone\n" + "ring section images (that have the TOR header). Wrt an XIP image, the\n" + "'dissect' command dissects the ring section named by the section argument.\n" + "Wrt a stand-alone ring section image, the 'dissect' command dissects\n" + "the ring section based on the TOR magic word embedded in the top of the\n" + "image. It does so regardless of what the section argument is (so for now\n" + "pass it .rings in this argument). In both cases, 'dissect' summarizes\n" + "the content of the ring section. The second argument to 'dissect', i.e.\n" + "[table,short,normal(default),long,raw], specifies how much information\n" "is included in the listing:\n" " table: Tabular overview.\n" " short: The bare necessities.\n" @@ -1751,9 +1758,7 @@ TEST(void* io_image, const int i_argc, const char** i_argv) /// /// \param[in] i_ringSection A pointer to a TOR compliant ring section. /// -/// \param[in] i_imageMagicNo The image's MAGIC number. -/// -/// \param[in] i_listingModeId The listing mode: {table, short, normal(default), long, raw}. +/// \param[in] i_listingModeId The listing mode: {table, short, normal(default), long}. /// /// Assumptions: /// - Dissection only works with .rings section. It does not work with .overrides @@ -1761,13 +1766,14 @@ TEST(void* io_image, const int i_argc, const char** i_argv) /// static int dissectRingSectionTor( void* i_ringSection, - uint64_t i_imageMagicNo, uint8_t i_listingModeId ) { int rc = 0; uint32_t i; - uint32_t numDdLevels; - uint8_t iDdLevel, ddLevel; + uint32_t torMagic = 0xffffffff; // Undefined value + uint8_t chipType = 0xff; // Undefined value + uint32_t numDdLevels = 0; // Undefined value + uint8_t iDdLevel, ddLevel = 0xff; // Undefined value uint8_t ppeType; uint8_t ringId; RingType_t ringType; @@ -1789,6 +1795,33 @@ int dissectRingSectionTor( void* i_ringSection, double comprRate; uint8_t cmskRingIteration = 0; char ringSuffix = ' '; + uint8_t* buf = (uint8_t*)i_ringSection; + TorHeader_t* torHeader = (TorHeader_t*)i_ringSection; + int offset = sizeof(TorHeader_t); + TorDdBlock_t* torDdBlock; + + // + // Get TOR magic, chip type and DD level info from TOR header field + // + torMagic = be32toh(torHeader->magic); + chipType = torHeader->chipType; + ddLevel = torHeader->ddLevel; + numDdLevels = torHeader->numDdLevels; + + fprintf(stdout, "---------------------------------\n"); + fprintf(stdout, "* TOR header summary *\n"); + fprintf(stdout, "---------------------------------\n"); + fprintf(stdout, "TOR magic: 0x%4x=>%c%c%c%c\n", torMagic, + (uint8_t)(torMagic >> 24), + (uint8_t)(torMagic >> 16), + (uint8_t)(torMagic >> 8), + (uint8_t)(torMagic)); + fprintf(stdout, "TOR version: %d\n", torHeader->version); + fprintf(stdout, "Chip type: %d=>%s\n", chipType, CHIP_TYPE_LIST[chipType].name); + fprintf(stdout, "DD level: 0x%x\n", ddLevel); + fprintf(stdout, "Num DD levels: %d\n", numDdLevels); + fprintf(stdout, "---------------------------------\n"); + fprintf(stdout, "\n\n"); if (i_listingModeId != LMID_TABLE) { @@ -1802,20 +1835,6 @@ int dissectRingSectionTor( void* i_ringSection, ringBlockSize = RING_BUF_SIZE_MAX; ringBlockPtr = malloc(ringBlockSize); - // - // Get number of DD levels from TOR structure in ring section - // - if (i_imageMagicNo == P9_XIP_MAGIC_HW) - { - numDdLevels = htobe32( ( (TorNumDdLevels_t*)i_ringSection )->TorNumDdLevels ); - fprintf( stderr, "numDdLevels (=%d) read from top of ring section.\n", numDdLevels); - } - else - { - numDdLevels = 1; - ddLevel = 0xff; // This means it's unknown. - fprintf( stderr, "Image contains only one DD level set of rings.\n"); - } if (i_listingModeId == LMID_TABLE) { @@ -1826,11 +1845,11 @@ int dissectRingSectionTor( void* i_ringSection, // DD level loop. for (iDdLevel = 0; iDdLevel < numDdLevels; iDdLevel++) { - - if (i_imageMagicNo == P9_XIP_MAGIC_HW) + if (torMagic == TOR_MAGIC_HW) { - ddLevel = ( ( htobe32( ( ( (TorDdLevelBlock_t*)((uintptr_t)i_ringSection + sizeof(TorNumDdLevels_t)) ) + - iDdLevel )->TorDdLevelAndOffset ) & 0xff000000 ) >> 24 ); + torDdBlock = (TorDdBlock_t*)&buf[offset]; + offset += sizeof(TorDdBlock_t); + ddLevel = torDdBlock->ddLevel; } //---------------- @@ -1839,9 +1858,10 @@ int dissectRingSectionTor( void* i_ringSection, for (ppeType = 0; ppeType < NUM_PPE_TYPES; ppeType++) { - if ((i_imageMagicNo == P9_XIP_MAGIC_SGPE && ppeType != SGPE) || - (i_imageMagicNo == P9_XIP_MAGIC_CME && ppeType != CME) || - (i_imageMagicNo == P9_XIP_MAGIC_SEEPROM && ppeType != SBE)) + if ((torMagic == TOR_MAGIC_SGPE && ppeType != SGPE) || + (torMagic == TOR_MAGIC_CME && ppeType != CME) || + (torMagic == TOR_MAGIC_SBE && ppeType != SBE) || + (torMagic == TOR_MAGIC_OVRD && ppeType != SBE)) { continue; } @@ -1849,8 +1869,13 @@ int dissectRingSectionTor( void* i_ringSection, //-------------------- // Ring variant loop. // - Base, cache, risk, override, overlay - for (ringVariant = 0; ringVariant < OVERRIDE; ringVariant++) + for (ringVariant = 0; ringVariant <= OVERRIDE; ringVariant++) { + if ((torMagic != TOR_MAGIC_OVRD && ringVariant == OVERRIDE) || + (torMagic == TOR_MAGIC_OVRD && ringVariant != OVERRIDE)) + { + continue; + } //---------------------- // Unique ring ID loop. @@ -1876,7 +1901,6 @@ int dissectRingSectionTor( void* i_ringSection, ringBlockSize = RING_BUF_SIZE_MAX; rc = tor_access_ring( i_ringSection, - i_imageMagicNo, (RingID)ringId, ddLevel, (PpeType_t)ppeType, @@ -1894,12 +1918,25 @@ int dissectRingSectionTor( void* i_ringSection, if (rc == TOR_RING_FOUND) { rs4 = (CompressedScanData*)ringBlockPtr; - ringSize = be16toh(rs4->iv_size); + + // Sanity check RS4 container's ringId matches the requested. + uint16_t l_ringId = be16toh(rs4->iv_ringId); + + if ( l_ringId != ringId ) + { + fprintf(stderr, "tor_access_ring() was successful and found a ring. But " + "RS4 header's iv_ringId(=0x%x) differs from requested ringId(=0x%x).\n", + l_ringId, ringId); + exit(1); + } + // Check ring block size. + ringSize = be16toh(rs4->iv_size); + if ( ringSize != ringBlockSize || ringSize == 0 ) { - fprintf(stderr, "tor_access_ring() was successful and found a ring but " + fprintf(stderr, "tor_access_ring() was successful and found a ring. But " "RS4 header's iv_size(=0x%04x) is either zero or doesn't match " "size of ring buffer (ringBlockSize=0x%04x).\n", ringSize, ringBlockSize); @@ -2077,6 +2114,8 @@ int dissectRingSectionTor( void* i_ringSection, } else if (rc == TOR_RING_NOT_FOUND || rc == TOR_INVALID_INSTANCE_ID || + rc == TOR_INVALID_CHIPLET || + rc == TOR_INVALID_VARIANT || rc == TOR_AMBIGUOUS_API_PARMS || rc == TOR_INVALID_RING_ID) { @@ -2087,7 +2126,9 @@ int dissectRingSectionTor( void* i_ringSection, else { fprintf(stderr, "tor_access_ring() returned error code rc=%d\n", rc); - exit(1); + { + exit(1); + } } } // End of for(instanceId) @@ -2154,60 +2195,101 @@ int dissectRingSection(void* i_image, listingModeName = i_argv[1]; } - p9_xip_translate_header(&hostHeader, (P9XipHeader*)i_image); - - // Determine P9-XIP ring section ID from the section name, e.g. - // .rings => P9_XIP_SECTION_HW_RINGS - if (strcmp(sectionName, ".rings") == 0) + // Determine whether i_image is an XIP image or an isolated TOR ring section image. + // + if (be64toh(((P9XipHeader*)i_image)->iv_magic) >> 32 == P9_XIP_MAGIC) { - if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM) - { - sectionId = P9_XIP_SECTION_SBE_RINGS; - } - else if (hostHeader.iv_magic == P9_XIP_MAGIC_HW) + + p9_xip_translate_header(&hostHeader, (P9XipHeader*)i_image); + + // Determine P9-XIP ring section ID from the section name, e.g. + // .rings => P9_XIP_SECTION_HW_RINGS + if (strcmp(sectionName, ".rings") == 0) { - sectionId = P9_XIP_SECTION_HW_RINGS; + if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM) + { + sectionId = P9_XIP_SECTION_SBE_RINGS; + } + else if (hostHeader.iv_magic == P9_XIP_MAGIC_HW) + { + sectionId = P9_XIP_SECTION_HW_RINGS; + } + else + { + fprintf(stderr, "ERROR: .rings is not a valid section for image w/magic=0x%016lx\n", + hostHeader.iv_magic); + exit(1); + } } - else + else if (strcmp(sectionName, ".overrides") == 0) { - fprintf(stderr, "ERROR: .rings is not a valid section for image w/magic=0x%016lx\n", - hostHeader.iv_magic); - exit(1); + if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM) + { + sectionId = P9_XIP_SECTION_SBE_OVERRIDES; + } + else + { + fprintf(stderr, "ERROR: .overrides is not a valid section for image w/magic=0x%016lx\n", + hostHeader.iv_magic); + exit(1); + } } - } - else if (strcmp(sectionName, ".overrides") == 0) - { - if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM) + else if (strcmp(sectionName, ".overlays") == 0) { - sectionId = P9_XIP_SECTION_SBE_OVERRIDES; + if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM) + { + sectionId = P9_XIP_SECTION_SBE_OVERLAYS; + } + else + { + fprintf(stderr, "ERROR: .overlays is not a valid section for image w/magic=0x%016lx\n", + hostHeader.iv_magic); + exit(1); + } } else { - fprintf(stderr, "ERROR: .overrides is not a valid section for image w/magic=0x%016lx\n", - hostHeader.iv_magic); + fprintf(stderr, "ERROR : %s is an invalid ring section name.\n", sectionName); + fprintf(stderr, "Valid ring <section> names for the 'dissect' function are:\n"); + fprintf(stderr, "\t.rings\n"); + fprintf(stderr, "\t.overrides\n"); + fprintf(stderr, "\t.overlays\n"); exit(1); } - } - else if (strcmp(sectionName, ".overlays") == 0) - { - if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM) + + // Get ring section. + // + rc = p9_xip_get_section( i_image, sectionId, &hostSection); + + if (rc) { - sectionId = P9_XIP_SECTION_SBE_OVERLAYS; + fprintf( stderr, "p9_xip_get_section() failed : %s\n", P9_XIP_ERROR_STRING(g_errorStrings, rc)); + return P9_XIP_DISASSEMBLER_ERROR; } - else + + if (hostSection.iv_offset == 0) { - fprintf(stderr, "ERROR: .overlays is not a valid section for image w/magic=0x%016lx\n", - hostHeader.iv_magic); + fprintf( stdout, "Ring section (w/ID=%d) is empty. Nothing to do. Quitting.\n", sectionId); exit(1); } + + if (be32toh(((TorHeader_t*)i_image)->magic) >> 8 != TOR_MAGIC) + { + fprintf( stderr, + "ERROR: The XIP section is not a TOR compatible ring section. Possibly, the image is outdated and has the old TOR-headerless layout which is no longer supported. Try dissecting with an older version of p9_xip_tool.\n"); + exit(EXIT_FAILURE); + } + + ringSectionPtr = (void*)(hostSection.iv_offset + (uintptr_t)i_image); + + } + else if (be32toh(((TorHeader_t*)i_image)->magic) >> 8 == TOR_MAGIC) + { + ringSectionPtr = i_image; } else { - fprintf(stderr, "ERROR : %s is an invalid ring section name.\n", sectionName); - fprintf(stderr, "Valid ring <section> names for the 'dissect' function are:\n"); - fprintf(stderr, "\t.rings\n"); - fprintf(stderr, "\t.overrides\n"); - fprintf(stderr, "\t.overlays\n"); + fprintf(stderr, "ERROR : Input image is neither an XIP image nor an TOR ringSection image.\n"); exit(1); } @@ -2249,25 +2331,7 @@ int dissectRingSection(void* i_image, exit(1); } - // Get ring section. - // - rc = p9_xip_get_section( i_image, sectionId, &hostSection); - - if (rc) - { - fprintf( stderr, "p9_xip_get_section() failed : %s\n", P9_XIP_ERROR_STRING(g_errorStrings, rc)); - return P9_XIP_DISASSEMBLER_ERROR; - } - - if (hostSection.iv_offset == 0) - { - fprintf( stdout, "Ring section (w/ID=%d) is empty. Nothing to do. Quitting.\n", sectionId); - exit(1); - } - - ringSectionPtr = (void*)(hostSection.iv_offset + (uintptr_t)i_image); - - rc = dissectRingSectionTor(ringSectionPtr, hostHeader.iv_magic, listingModeId); + rc = dissectRingSectionTor(ringSectionPtr, listingModeId); return rc; @@ -2326,7 +2390,8 @@ openAndMap(const char* i_fileName, int i_writable, int* o_fd, void** o_image, co exit(1); } - if ( !(i_maskIgnores & P9_XIP_IGNORE_ALL) ) + if ( !(i_maskIgnores & P9_XIP_IGNORE_ALL) && + (be64toh(((P9XipHeader*)o_image)->iv_magic) >> 32 == P9_XIP_MAGIC) ) { rc = p9_xip_validate2(*o_image, g_imageSize, i_maskIgnores); |