blob: cbe3bd7a95c1419f1a509211fe840cb52d40917b [file] [log] [blame]
hostbootdbfc6c12020-02-19 09:17:02 -06001From c2b2d20fdf36bff21577ca6ed6703395ebad8971 Mon Sep 17 00:00:00 2001
2From: Olsen <cmolsen@us.ibm.com>
3Date: Wed, 9 Oct 2019 08:53:07 -0400
4Subject: [PATCH] TOR API : Refactoring, traversal and buffer check
5 improvements
6
7Changes made:
8- Introduced two new internal functions: _tor_access_ring()
9 and _tor_header_check().
10- Updated tor_append_ring() to pass a max ringSectionSize arg to be
11 checked for overflow in the new _tor_access_ring() function.
12- Moved the actual appending/updating of RS4 rings out of
13 tor_append_ring() into _tor_access_ring().
14- Removed tor_access_ring().
15- All TOR chiplet and ring offsets are now referenced wrt to the
16 ringSection origin (ie, where the TOR header starts).
17- Updated TOR_VERSION to v2.
18- Refactoring of various TOR APIs to use the above changes.
19- Updates to ring_apply, ipl_customize and qme_customize to support
20 the new tor_append_ring() API.
21- Updates to Sbe and Qme TOR traversal codes and extract HOMER.
22- Various cleanups in buffer handling in p10_ipl_customize.C.
23- Removed p9_ring_apply.* files (though not at all relevant to this
24 commit)
25
26Key_Cronus_Test=XIP_REGRESS_SBE_QME
27
28Change-Id: I7bb3a76ae2454a34c7c0619e928c67706cc571e4
29Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/85899
30Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
31Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
32Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com>
33Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com>
34Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
35---
36 .../chips/common/utils/imageProcs/common_ringId.H | 25 +-
37 .../procedures/hwp/customize/p10_ipl_customize.C | 196 ++++++--
38 .../procedures/hwp/customize/p10_qme_customize.C | 152 ++----
39 .../xml/error_info/p10_ipl_customize_errors.xml | 3 +-
40 .../p10/utils/imageProcs/p10_infrastruct_help.H | 1 -
41 .../p10/utils/imageProcs/p10_scan_compression.H | 5 +-
42 src/import/chips/p10/utils/imageProcs/p10_tor.C | 526 ++++++++++-----------
43 src/import/chips/p10/utils/imageProcs/p10_tor.H | 97 ++--
44 8 files changed, 483 insertions(+), 522 deletions(-)
45
46diff --git a/src/import/chips/common/utils/imageProcs/common_ringId.H b/src/import/chips/common/utils/imageProcs/common_ringId.H
47index 1fc819a..053af8c 100644
48--- a/src/import/chips/common/utils/imageProcs/common_ringId.H
49+++ b/src/import/chips/common/utils/imageProcs/common_ringId.H
50@@ -48,7 +48,7 @@ typedef uint8_t ChipletType_t; // Type for Chiplets enum
51 typedef uint8_t ChipId_t; // Type for ChipId enum
52 typedef uint8_t RingType_t; // Type for RingType enum
53 typedef uint8_t RingRequest_t; // Type for RingRequest enum, e.g. GET_SINGLE_RING
54-typedef uint32_t TorCpltOffset_t; // Type for offset value to chiplet's CMN or INST section
55+typedef uint16_t TorOffset_t; // Type for offset value to various TOR objects (chiplet,ring)
56 typedef uint8_t MyBool_t; // false:0, true:1, undefined:UNDEFINED_BOOLEAN
57
58 #define UNDEFINED_RING_ID (RingId_t)0xffff
59@@ -61,10 +61,14 @@ typedef uint8_t MyBool_t; // false:0, true:1, undefined:UNDEFINED_BOOL
60
61 #define UNDEFINED_DD_LEVEL (uint8_t)0xff
62
63-#define MAX_TOR_RING_OFFSET (uint16_t)(256*256-1) // Max val of uint16
64-
65 #define MAX_RING_NAME_LENGTH (uint8_t)50
66
67+// Ring section defines
68+#define MAX_TOR_RING_OFFSET (uint16_t)(256*256-1) // Max val of uint16
69+#define MAX_TOR_RING_SECTION_SIZE (uint32_t)(256*256)
70+#define MAX_DYN_RING_SECTION_SIZE (uint32_t)(1024*1024)
71+
72+// Chiplet ID defines
73 #define CHIPLET_ID_MASK (uint32_t)0xFF000000
74 #define MIN_INSTANCE_ID (uint8_t)0x01
75 #define MAX_INSTANCE_ID (uint8_t)0x3F
76@@ -93,12 +97,10 @@ typedef struct
77
78 typedef struct
79 {
80- TorCpltOffset_t cmnOffset;
81- TorCpltOffset_t instOffset;
82+ TorOffset_t cmnOffset;
83+ TorOffset_t instOffset;
84 } TorCpltBlock_t;
85
86-typedef uint16_t TorRingOffset_t; // Offset value to actual ring
87-
88 // //
89 // TOR layout definitions - End //
90 ///////////////////////////////////////////////////////////////////////////////
91@@ -118,7 +120,8 @@ typedef uint16_t TorRingOffset_t; // Offset value to actual ring
92 //#define TOR_VERSION 7 // Added three more runtime risk levels (RL3/4/5)
93
94 // P10 TOR versions
95-#define TOR_VERSION 1 // Removed all ring variant support. Only BASE rings supported now.
96+//#define TOR_VERSION 1 // Removed all ring variant support. Only BASE rings supported now.
97+#define TOR_VERSION 2 // TOR ringSection offsets now wrt origin of ringSection at TOR header.
98
99
100 // TOR Magic values for top-level TOR ringSection and sub-ringSections
101@@ -263,8 +266,8 @@ enum RingType
102
103 enum RingRequest
104 {
105- GET_SINGLE_RING = 0x00,
106- PUT_SINGLE_RING = 0x01
107+ GET_SINGLE_RING = 0,
108+ PUT_SINGLE_RING = 1,
109 };
110
111 //
112@@ -327,7 +330,7 @@ typedef struct
113 #define TOR_INVALID_CHIP_ID INFRASTRUCT_NOOF_RCS + 3
114 #define TOR_INVALID_CHIPLET_TYPE INFRASTRUCT_NOOF_RCS + 4
115 #define TOR_INVALID_RING_ID INFRASTRUCT_NOOF_RCS + 5
116-#define TOR_INVALID_INSTANCE_ID INFRASTRUCT_NOOF_RCS + 6
117+#define TOR_INVALID_CHIPLET_ID INFRASTRUCT_NOOF_RCS + 6
118 #define TOR_INVALID_RING_REQUEST INFRASTRUCT_NOOF_RCS + 7
119 #define TOR_UNSUPPORTED_RING_SECTION INFRASTRUCT_NOOF_RCS + 8
120 #define TOR_RING_FILE_NOT_FOUND INFRASTRUCT_NOOF_RCS + 9
121diff --git a/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C b/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C
122index 3a114f0..b36ef65 100644
123--- a/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C
124+++ b/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C
125@@ -882,10 +882,10 @@ fapi2::ReturnCode _fetch_and_insert_vpd_rings(
126
127 l_rc = tor_append_ring(
128 i_ringSection,
129- io_ringSectionSize, // In: Exact size. Out: Updated size.
130+ i_maxRingSectionSize,
131 i_ringId,
132- l_chipletId, // Chiplet ID
133- i_vpdRing ); // The VPD RS4 ring container
134+ l_chipletId,
135+ i_vpdRing );
136
137 FAPI_ASSERT( l_rc == INFRASTRUCT_RC_SUCCESS,
138 fapi2::XIPC_TOR_APPEND_RING_FAILED().
139@@ -896,7 +896,10 @@ fapi2::ReturnCode _fetch_and_insert_vpd_rings(
140 "tor_append_ring() failed in sysPhase=%d w/rc=%d for ringId=0x%x",
141 i_sysPhase, l_rc, i_ringId );
142
143- FAPI_IMP("Successfully appended VPD ring, (ringId,chipletId)=(0x%x,0x%02x), and now ringSectionSize=%u",
144+ io_ringSectionSize = be32toh(((TorHeader_t*)i_ringSection)->size);
145+
146+ FAPI_IMP("Successfully appended VPD ring, (ringId,chipletId)=(0x%x,0x%02x), and"
147+ " now ringSectionSize=%u",
148 i_ringId, l_chipletId, io_ringSectionSize);
149 }
150 else if ((uint32_t)l_fapiRc == RC_MVPD_RING_NOT_FOUND)
151@@ -907,7 +910,7 @@ fapi2::ReturnCode _fetch_and_insert_vpd_rings(
152 // No match, do nothing. But since rare, trace out as warning since all
153 // rings we're looking for in Mvpd really should be represented there.
154 FAPI_DBG("WARNING!: _fetch_and_insert_vpd_rings(): The ring w/"
155- "(ringId,chipletId)=(0x%02x,0x%02x) was not found. (This is not a bug)",
156+ "(ringId,chipletId)=(0x%x,0x%02x) was not found. (This is not a bug)",
157 i_ringId, l_chipletId);
158
159 fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
160@@ -977,7 +980,7 @@ fapi2::ReturnCode resolve_gptr_overlays(
161 FAPI_TRY( FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC,
162 i_procTarget,
163 o_ddLevel),
164- "Error: Attribute ATTR_EC failed w/rc=0x%08x",
165+ "ERROR: Attribute ATTR_EC failed w/rc=0x%08x",
166 (uint64_t)current_err );
167
168 l_rc = p9_xip_get_section(i_hwImage, P9_XIP_SECTION_HW_OVERLAYS, &l_xipSection, o_ddLevel);
169@@ -1848,7 +1851,7 @@ fapi2::ReturnCode process_base_and_dynamic_rings(
170 set_RING_ID(i_ringId).
171 set_DD_LEVEL(i_ddlevel).
172 set_LOCAL_RC(l_rc),
173- "tor_get_single_ring() for Base ring: Failed w/rc=%i for "
174+ "ERROR: tor_get_single_ring() for Base ring: Failed w/rc=%i for "
175 "ringId=0x%x, chipletId=0xff and ddLevel=0x%x",
176 l_rc, i_ringId, i_ddlevel );
177
178@@ -1862,14 +1865,9 @@ fapi2::ReturnCode process_base_and_dynamic_rings(
179 baseTypeField = ((CompressedScanData*)baseRs4)->iv_type;
180 }
181
182-//CMO-20190902: At this point we could probably sanity check that baseTypeField ==
183-// dynTypeField. However, it's a hit-and-miss check since we can only
184-// make this check if both a Base AND a Dynamic ring is found. It's
185-// better than nothing, but we postpone for now.
186-
187 if(bBaseRingFound && bDynRingFound)
188 {
189- FAPI_DBG("Base and Dynamic rings found.");// Will delete later
190+ FAPI_DBG("ringId=0x%x: Base ring found. Dynamic ring found.", i_ringId);
191
192 // Use baseTypeField as ref input value for iv_type, but dynTypeField would be just as good
193 finalTypeField = (baseTypeField & ~RS4_IV_TYPE_SEL_MASK) |
194@@ -1891,7 +1889,7 @@ fapi2::ReturnCode process_base_and_dynamic_rings(
195 }
196 else if(!bBaseRingFound && bDynRingFound)
197 {
198- FAPI_DBG("No Base ring found. Dynamic ring found.");//Will delete later
199+ FAPI_DBG("ringId=0x%x: No Base ring found. Dynamic ring found.", i_ringId);
200
201 // We'll need these temp vars below
202 RingId_t ringIdTmp = be16toh(((CompressedScanData*)finalRs4)->iv_ringId);
203@@ -1927,7 +1925,7 @@ fapi2::ReturnCode process_base_and_dynamic_rings(
204 else if(bBaseRingFound && !bDynRingFound)
205 {
206 //In this case finalRs4 = baseRs4 = io_ringBuf1 already has the final ring
207- FAPI_DBG("Base ring found. No Dynamic ring found.");//Will delete this later
208+ FAPI_DBG("ringId=0x%x: Base ring found. No Dynamic ring found.", i_ringId);
209
210 finalTypeField = (baseTypeField & ~RS4_IV_TYPE_SEL_MASK) |
211 RS4_IV_TYPE_SEL_BASE | RS4_IV_TYPE_SEL_FINAL;
212@@ -1939,11 +1937,11 @@ fapi2::ReturnCode process_base_and_dynamic_rings(
213 }
214 else
215 {
216- FAPI_DBG("No Base or Dynamic rings found."); // Delete later
217+ FAPI_DBG("ringId=0x%x: No Base ring found. No Dynamic ring found.", i_ringId);
218 fapi2::current_err = RC_XIPC_NO_RING_FOUND;
219 }
220
221- //io_ringBuf1 has the final ring at this point.
222+ // Note that the final ring is already in io_ringBuf1 at this point.
223
224 fapi_try_exit:
225 FAPI_DBG("Exiting process_base_and_dynamic_rings");
226@@ -1990,8 +1988,9 @@ ReturnCode p10_ipl_customize (
227 uint32_t l_inputImageSize;
228 uint32_t l_imageSizeWithoutRings;
229 uint32_t l_currentImageSize;
230- uint32_t l_maxImageSize = 0; // Attrib adjusted local value of MAX_SEEPROM_IMAGE_SIZE
231- uint32_t l_maxRingSectionSize;
232+ uint32_t l_maxImageSize = 0; // Attrib adjusted local value of MAX_SEEPROM_IMAGE_SIZE
233+ uint32_t l_maxRingSectionSize; // Max size of ringSection
234+ uint32_t l_ringSectionBufSize; // Size of ringSection buffer
235 uint32_t l_sectionOffset = 1;
236 uint32_t attrMaxSbeSeepromSize = 0;
237 uint32_t l_requestedBootCoreMask = (i_sysPhase == SYSPHASE_HB_SBE) ? io_bootCoreMask : 0xFFFFFFFF;
238@@ -2016,14 +2015,13 @@ ReturnCode p10_ipl_customize (
239 void* baseRingSection = NULL;
240 void* dynamicRingSection = NULL;
241 TorHeader_t* torHeaderBase;
242- uint32_t customRingSectionSize = 0;
243 uint8_t* partialKwdData = NULL;
244 uint32_t sizeofPartialKwdData = 0;
245 uint8_t mvpdRtvFromCode = 0xff;
246 uint8_t mvpdRtvFromMvpd = 0xff;
247 MvpdKeyword mvpdKeyword;
248
249- FAPI_IMP ("Entering p10_ipl_customize w/sysPhase=%d...", i_sysPhase);
250+ FAPI_IMP("Entering p10_ipl_customize w/sysPhase=%d...", i_sysPhase);
251
252
253 // Make copy of the requested bootCoreMask
254@@ -2122,6 +2120,9 @@ ReturnCode p10_ipl_customize (
255 (uintptr_t)i_ringBufSize2,
256 (uintptr_t)i_ringBufSize3 );
257
258+ // Make local copy of the [max] io_ringSectionBufSize before we start changing it
259+ l_ringSectionBufSize = io_ringSectionBufSize;
260+
261
262 //-------------------------------------------
263 // Verify that platform and Mvpd agree on:
264@@ -2590,17 +2591,17 @@ ReturnCode p10_ipl_customize (
265 set_CHIP_TARGET(i_procTarget).
266 set_INPUT_IMAGE_SIZE(l_inputImageSize).
267 set_IMAGE_BUF_SIZE(io_imageSize).
268- set_RING_SECTION_BUF_SIZE(io_ringSectionBufSize).
269+ set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize).
270 set_RING_BUF_SIZE1(i_ringBufSize1).
271 set_RING_BUF_SIZE2(i_ringBufSize2).
272 set_OCCURRENCE(2),
273 "One or more invalid input buffer sizes for HB_SBE phase:\n"
274 " l_maxImageSize=0x%016llx\n"
275 " io_imageSize=0x%016llx\n"
276- " io_ringSectionBufSize=0x%016llx\n",
277+ " l_ringSectionBufSize=0x%016llx\n",
278 (uintptr_t)l_maxImageSize,
279 (uintptr_t)io_imageSize,
280- (uintptr_t)io_ringSectionBufSize );
281+ (uintptr_t)l_ringSectionBufSize );
282
283 }
284
285@@ -2691,7 +2692,8 @@ ReturnCode p10_ipl_customize (
286 set_CHIP_TARGET(i_procTarget).
287 set_SYSPHASE(i_sysPhase).
288 set_OCCURRENCE(1),
289- "Caller bug: Caller supplied unsupported value of sysPhase=%u (Occurrence 1)",
290+ "Caller bug: Caller supplied unsupported value of sysPhase=%u"
291+ " (Occurrence 1)",
292 i_sysPhase );
293
294 break;
295@@ -2715,6 +2717,7 @@ ReturnCode p10_ipl_customize (
296
297
298
299+
300 //////////////////////////////////////////////////////////////////////////
301 // CUSTOMIZE item: Build up a new ring section in io_ringSectionBuf
302 // based on the TOR header info in baseRingSection.
303@@ -2734,7 +2737,64 @@ ReturnCode p10_ipl_customize (
304 set_CHIP_TARGET(i_procTarget),
305 "tor_skeleton_generation failed w/rc=0x%08X", (uint32_t)l_rc );
306
307- customRingSectionSize = be32toh(((TorHeader_t*)io_ringSectionBuf)->size);
308+ // Now, start tracking the instantaneous actual custom ring section size.
309+ // (Note that we already took a copy of the [max] value of io_ringSectionBufSize
310+ // earlier on into l_ringSectionBufSize, so safe to update this now.)
311+ io_ringSectionBufSize = be32toh(((TorHeader_t*)io_ringSectionBuf)->size);
312+
313+
314+
315+
316+ //////////////////////////////////////////////////////////////////////////
317+ // CUSTOMIZE item: Determine the max allowed ringSection size
318+ // Systemp phase: All phases
319+ //////////////////////////////////////////////////////////////////////////
320+
321+ switch (i_sysPhase)
322+ {
323+
324+ case SYSPHASE_HB_SBE:
325+
326+ // Calc the max ring section size for SBE.
327+ l_maxRingSectionSize = l_maxImageSize - l_imageSizeWithoutRings;
328+
329+ break;
330+
331+ case SYSPHASE_RT_QME:
332+
333+ // Max ring section size for QME.
334+ l_maxRingSectionSize = l_ringSectionBufSize; // l_ringSectionBufSize is actual max buf size
335+
336+ break;
337+
338+ default:
339+
340+ FAPI_ASSERT( false,
341+ fapi2::XIPC_INVALID_SYSPHASE_PARM().
342+ set_CHIP_TARGET(i_procTarget).
343+ set_SYSPHASE(i_sysPhase).
344+ set_OCCURRENCE(2),
345+ "Caller bug: Caller supplied unsupported value of sysPhase=%u"
346+ " (Occurrence 2)",
347+ i_sysPhase );
348+
349+ break;
350+ }
351+
352+ // maxRingSectionSize should never exceed ringSectionBufSize which should always be allocated
353+ // to be so large that we should be able to fill out the image to its maximum capacity.
354+ FAPI_ASSERT( l_maxRingSectionSize <= l_ringSectionBufSize,
355+ fapi2::XIPC_RING_SECTION_SIZING().
356+ set_CHIP_TARGET(i_procTarget).
357+ set_RING_SECTION_SIZE(io_ringSectionBufSize).
358+ set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize).
359+ set_MAX_RING_SECTION_SIZE(l_maxRingSectionSize).
360+ set_OCCURRENCE(1),
361+ "CODE BUG : maxRingSectionSize(=%u) > ringSectionBufSize(=%u) should"
362+ " never happen. Fix your assumptions/settings about ringSection"
363+ " buffer size or max image size (=%u) (Occurrence 1)",
364+ l_maxRingSectionSize, l_ringSectionBufSize, l_maxImageSize );
365+
366
367
368
369@@ -2767,7 +2827,9 @@ ReturnCode p10_ipl_customize (
370 set_CHIP_TARGET(i_procTarget).
371 set_OCCURRENCE(5),
372 "FAPI_ATTR_GET(ATTR_DYNAMIC_INIT_FEATURE_VEC) failed."
373- " Unable to determine featureVector." );
374+ " Unable to determine featureVec." );
375+
376+ FAPI_IMP("Dynamic inits featureVec = 0x%016llx (GET from plat attribute)", featureVec);
377
378 l_fapiRc2 = FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_IPL_PHASE,
379 FAPI_SYSTEM,
380@@ -2822,6 +2884,8 @@ ReturnCode p10_ipl_customize (
381 set_OCCURRENCE(8),
382 "Failed to set the dynamic init feature vector attribute" );
383
384+ FAPI_IMP("Dynamic inits featureVec = 0x%016llx (SET to plat attribute)", featureVec);
385+
386 l_rc = p9_xip_get_section(i_hwImage, P9_XIP_SECTION_HW_DYNAMIC, &iplImgSection, attrDdLevel);
387
388 FAPI_ASSERT( l_rc == INFRASTRUCT_RC_SUCCESS,
389@@ -2848,7 +2912,7 @@ ReturnCode p10_ipl_customize (
390
391 //CMO-20190825: For the RT_QME phase we will get TOR_INVALID_CHIPLET_TYPE a lot
392 // here because we cycle through all the chiplets, when we really only
393-// shold consider the EQ chiplet for RT_QME. For now, we will be
394+// should consider the EQ chiplet for RT_QME. For now, we will be
395 // mindless, but this should probably be changed.
396 for(ringId = 0; ringId < NUM_RING_IDS; ringId++)
397 {
398@@ -2880,16 +2944,16 @@ ReturnCode p10_ipl_customize (
399 "ringId=0x%0x w/rc=0x%08x",
400 ringId, (uint32_t)l_fapiRc);
401
402- if(l_fapiRc == FAPI2_RC_SUCCESS)
403+ if (l_fapiRc == FAPI2_RC_SUCCESS)
404 {
405 l_rc = tor_append_ring(
406 io_ringSectionBuf,
407- customRingSectionSize,
408+ l_maxRingSectionSize,
409 ringId,
410 0xff,
411 i_ringBuf1 );
412
413- FAPI_ASSERT( l_rc == INFRASTRUCT_RC_SUCCESS ||
414+ FAPI_ASSERT( l_rc == TOR_SUCCESS ||
415 l_rc == TOR_INVALID_CHIPLET_TYPE ||
416 l_rc == TOR_RING_HAS_DERIVS,
417 fapi2::XIPC_TOR_APPEND_RING_FAILED().
418@@ -2902,12 +2966,45 @@ ReturnCode p10_ipl_customize (
419 "for ringId=0x%x",
420 l_rc, ringId );
421
422- FAPI_DBG("A Base or Dynamic ring w/ringId=0x%x was either appended or skipped (if"
423- " deriv ring or invalid chiplet) and now ringSectionSize=%u",
424- ringId, be32toh(((TorHeader_t*)io_ringSectionBuf)->size));
425+ io_ringSectionBufSize = be32toh(((TorHeader_t*)io_ringSectionBuf)->size);
426+
427+ switch (l_rc)
428+ {
429+ case TOR_SUCCESS:
430+ FAPI_IMP("A Base or Dynamic ring w/ringId=0x%x was appended"
431+ " and now ringSection->size=%u",
432+ ringId, io_ringSectionBufSize);
433+ break;
434+
435+ case TOR_INVALID_CHIPLET_TYPE:
436+ FAPI_IMP("A Base or Dynamic ring w/ringId=0x%x was skipped"
437+ " because its an invalid chiplet for this sysPhase=%u",
438+ ringId, i_sysPhase);
439+ break;
440+
441+ case TOR_RING_HAS_DERIVS:
442+ FAPI_IMP("A Base or Dynamic ring w/ringId=0x%x was skipped"
443+ " because its a [root] ring w/derivatives",
444+ ringId);
445+ break;
446+
447+ default:
448+ FAPI_ASSERT( false,
449+ fapi2::XIPC_CODE_BUG().
450+ set_CHIP_TARGET(i_procTarget).
451+ set_OCCURRENCE(2),
452+ "Code bug(2): Messed up RC handling in assoc code. Fix code!" );
453+ break;
454+ }
455+
456 }
457 }
458
459+ // Now create the "anticipatory" dynamic init debug ring list.
460+ // - This list lists all the ringIds that have received dynamic init overlays.
461+ // - For each ringId, the complete final feature vector is included so it can be seen
462+ // which specific features were applied to a given ringId.
463+ // - The list may come in handy in case of scanning issues with the final dynamic rings.
464 ringIdFeatListSize = ringIdFeatureVecMap.size() * (sizeof(uint64_t) + sizeof(RingId_t));
465 ringIdFeatList = new uint8_t[ringIdFeatListSize];
466
467@@ -2938,11 +3035,6 @@ ReturnCode p10_ipl_customize (
468 0 );
469
470
471- // Make a copy of the supplied max ring section buffer size before over writing it
472- l_maxRingSectionSize = io_ringSectionBufSize;
473-
474- // Now, start tracking the instantaneous actual custom ring section size
475- io_ringSectionBufSize = customRingSectionSize;
476
477 //////////////////////////////////////////////////////////////////////////
478 // CUSTOMIZE item: Append VPD rings to io_ringSectionBuf
479@@ -3019,12 +3111,8 @@ ReturnCode p10_ipl_customize (
480
481 case SYSPHASE_HB_SBE:
482
483- FAPI_DBG("Size of SBE .rings section before VPD update: %d", io_ringSectionBufSize);
484-
485- // Adjust the max ring section size
486- l_maxRingSectionSize = l_maxImageSize - l_imageSizeWithoutRings;
487-
488- FAPI_DBG("Max allowable size of .rings section: %d", l_maxRingSectionSize);
489+ FAPI_DBG("Size of SBE .rings section before VPD update: %u (max size allowed: %u)",
490+ io_ringSectionBufSize, l_maxRingSectionSize);
491
492 //----------------------------------------
493 // Append VPD Rings to the .rings section
494@@ -3107,12 +3195,13 @@ ReturnCode p10_ipl_customize (
495
496 // More size code sanity checks of section and image sizes.
497 FAPI_ASSERT( io_ringSectionBufSize <= l_maxRingSectionSize,
498- fapi2::XIPC_SECTION_SIZING().
499+ fapi2::XIPC_RING_SECTION_SIZING().
500 set_CHIP_TARGET(i_procTarget).
501 set_RING_SECTION_SIZE(io_ringSectionBufSize).
502+ set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize).
503 set_MAX_RING_SECTION_SIZE(l_maxRingSectionSize).
504- set_OCCURRENCE(1),
505- "Code bug: ringSectionBufSize(=%d) > maxRingSectionSize(=%d) in HB_SBE(1)",
506+ set_OCCURRENCE(2),
507+ "Code bug: ringSectionBufSize(=%d) > maxRingSectionSize(=%d) in HB_SBE (Occurrence 2)",
508 io_ringSectionBufSize, l_maxRingSectionSize );
509
510 FAPI_ASSERT( (l_imageSizeWithoutRings + io_ringSectionBufSize) <= l_maxImageSize,
511@@ -3219,12 +3308,14 @@ ReturnCode p10_ipl_customize (
512
513 // More size code sanity checks of section and image sizes.
514 FAPI_ASSERT( io_ringSectionBufSize <= l_maxRingSectionSize,
515- fapi2::XIPC_SECTION_SIZING().
516+ fapi2::XIPC_RING_SECTION_SIZING().
517 set_CHIP_TARGET(i_procTarget).
518 set_RING_SECTION_SIZE(io_ringSectionBufSize).
519+ set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize).
520 set_MAX_RING_SECTION_SIZE(l_maxRingSectionSize).
521 set_OCCURRENCE(3),
522- "Code bug: QME ring section size(=%d) > maxRingSectionSize(=%d) in RT_QME(3)",
523+ "Code bug: QME ring section size(=%d) > maxRingSectionSize(=%d)"
524+ " in RT_QME (Occurrence 3)",
525 io_ringSectionBufSize, l_maxRingSectionSize );
526
527 break;
528@@ -3234,8 +3325,9 @@ ReturnCode p10_ipl_customize (
529 fapi2::XIPC_INVALID_SYSPHASE_PARM().
530 set_CHIP_TARGET(i_procTarget).
531 set_SYSPHASE(i_sysPhase).
532- set_OCCURRENCE(2),
533- "Caller bug: Caller supplied unsupported value of sysPhase=%u (Occurrence 2)",
534+ set_OCCURRENCE(3),
535+ "Caller bug: Caller supplied unsupported value of sysPhase=%u"
536+ " (Occurrence 3)",
537 i_sysPhase );
538
539 break;
540diff --git a/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C b/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C
541index a87bc2b..fc645d6 100644
542--- a/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C
543+++ b/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C
544@@ -5,7 +5,7 @@
545 /* */
546 /* OpenPOWER HostBoot Project */
547 /* */
548-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
549+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
550 /* [+] International Business Machines Corp. */
551 /* */
552 /* */
553@@ -49,11 +49,10 @@ fapi2::ReturnCode p10_qme_customize(
554 uint32_t& io_bufCustRingsSize,
555 uint32_t i_dbgl)
556 {
557- FAPI_IMP(">> p10_qme_customize ");
558-
559 int rc = INFRASTRUCT_RC_SUCCESS;
560
561- TorHeader_t* torHeader = (TorHeader_t*) i_bufQmeRings;
562+ TorHeader_t* torHeaderQme = (TorHeader_t*) i_bufQmeRings;
563+ TorHeader_t* torHeaderCust = (TorHeader_t*) io_bufCustRings;
564
565 uint8_t ddLevel;
566 uint8_t torVersion;
567@@ -63,11 +62,13 @@ fapi2::ReturnCode p10_qme_customize(
568 ChipId_t chipId = UNDEFINED_CHIP_ID;
569 ChipletData_t* chipletData;
570
571- ddLevel = torHeader->ddLevel;
572- torVersion = torHeader->version;
573- torMagic = be32toh(torHeader->magic);
574- chipId = torHeader->chipId;
575- inputQmeRingsSize = be32toh(torHeader->size);
576+ FAPI_IMP(">> p10_qme_customize ");
577+
578+ ddLevel = torHeaderQme->ddLevel;
579+ torVersion = torHeaderQme->version;
580+ torMagic = be32toh(torHeaderQme->magic);
581+ chipId = torHeaderQme->chipId;
582+ inputQmeRingsSize = be32toh(torHeaderQme->size);
583
584 RingId_t numRings = UNDEFINED_RING_ID; // Number of chiplet common or instance rings
585 MyBool_t bInstCase = UNDEFINED_BOOLEAN; // 0:COMMON, 1:INSTANCE rings
586@@ -78,8 +79,11 @@ fapi2::ReturnCode p10_qme_customize(
587
588 uint8_t iRing;
589 void* nextRing = NULL;
590- uint32_t nextRingSize;
591+ uint32_t remBufSize;
592
593+ //
594+ // Step 0: Test input parameters
595+ //
596 FAPI_ASSERT(i_custOp < NUM_CUSTOMIZE_QME_ENTRIES
597 && i_bufQmeRings != NULL
598 && io_bufCustRings != NULL,
599@@ -127,6 +131,7 @@ fapi2::ReturnCode p10_qme_customize(
600 // Step 1: Create TOR skeleton ringSection
601 // Create the complete ring skeleton, but with empty TOR ring slots (ie, no ring content).
602 //
603+
604 rc = tor_skeleton_generation(io_bufCustRings,
605 torMagic,
606 torVersion,
607@@ -135,13 +140,9 @@ fapi2::ReturnCode p10_qme_customize(
608 i_dbgl);
609
610 FAPI_DBG("tor_skeleton_generation() completed w/rc=0x%08x,\n"
611- " torMagic=0x%08x and torVersion=0x%08x,\n"
612- " ddLevel=0x%08x and chipId=0x%08x.\n",
613- rc,
614- torMagic,
615- torVersion,
616- ddLevel,
617- chipId);
618+ " torMagic=0x%08x, torVersion=%u,\n"
619+ " ddLevel=0x%02x and chipId=0x%02x.\n",
620+ rc, torMagic, torVersion, ddLevel, chipId);
621
622 FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS,
623 fapi2::QMEC_TOR_SKELETON_GEN_ERROR()
624@@ -151,20 +152,13 @@ fapi2::ReturnCode p10_qme_customize(
625 .set_TOR_VER(torVersion)
626 .set_DD_LEVEL(ddLevel)
627 .set_CHIP_ID(chipId),
628- "Error: tor_skeleton_generation() failed w/rc=0x%08x,\n"
629- " torMagic=0x%08x and torVersion=0x%08x,\n"
630- " ddLevel=0x%08x and chipId=0x%08x.\n",
631- rc,
632- torMagic,
633- torVersion,
634- ddLevel,
635- chipId);
636+ "Error: tor_skeleton_generation() failed w/rc=0x%08x,"
637+ " torMagic=0x%08x, torVersion=%u, ddLevel=0x%02x and chipId=0x%02x\n",
638+ rc, torMagic, torVersion, ddLevel, chipId);
639
640 //
641 // Step 2: Add ring content
642- // Main TOR ringSection create loop
643- // - Generate RS4 container for each ring, attaching it to end of ringSection and update
644- // the ring's TOR offset slot
645+ // Append rings to the end of the [skeleton] TOR ring section and update TOR offset slot
646 //
647
648 // Get all the meta data for this chiplet and its rings
649@@ -174,13 +168,6 @@ fapi2::ReturnCode p10_qme_customize(
650 EQ_TYPE,
651 &chipletData);
652
653- FAPI_DBG("ringid_get_chipletProps() completed w/rc=0x%08x,\n"
654- " chipId=0x%08x, torMagic=0x%08x, torVersion=0x%08x.\n",
655- rc,
656- chipId,
657- torMagic,
658- torVersion);
659-
660 FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS,
661 fapi2::QMEC_RINGID_GET_CHIPLETPROPS_ERROR()
662 .set_TARGET(i_procTarget)
663@@ -188,10 +175,8 @@ fapi2::ReturnCode p10_qme_customize(
664 .set_TOR_MAGIC(torMagic)
665 .set_TOR_VER(torVersion),
666 "Error: ringid_get_chipletProps() failed w/rc=0x%08x,\n"
667- " ddLevel=0x%08x and torVersion=0x%08x.\n",
668- rc,
669- torMagic,
670- torVersion);
671+ " torMagic=0x%08x and torVersion=%u.\n",
672+ rc, torMagic, torVersion);
673
674 chipletInstId = chipletData->chipletBaseId + i_custOp;
675
676@@ -199,13 +184,6 @@ fapi2::ReturnCode p10_qme_customize(
677 chipletData->numInstanceRings :
678 chipletData->numCommonRings;
679
680- FAPI_DBG("p10_qme_customize(): chipletInstId = 0x%08x, numRings = 0x%08x,\n"
681- " numInstanceRings = 0x%08x, numCommonRings = 0x%08x.\n",
682- chipletInstId,
683- numRings,
684- chipletData->numInstanceRings,
685- chipletData->numCommonRings);
686-
687 // Loop through all rings, get ring data for each ring and
688 // append it to cust ring section.
689 for (iRing = 0; iRing < numRings; iRing++)
690@@ -219,15 +197,6 @@ fapi2::ReturnCode p10_qme_customize(
691 ringId,
692 false);
693
694- FAPI_DBG("ringidGetRingId2() completed w/rc=0x%08x,\n"
695- " torMagic=0x%08x,iRing=0x%08x,\n"
696- " bInstCase=%d, ringId=0x%08x.\n",
697- rc,
698- torMagic,
699- iRing,
700- bInstCase,
701- ringId);
702-
703 FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS,
704 fapi2::QMEC_RINGID_GET_RINGID2_ERROR()
705 .set_TARGET(i_procTarget)
706@@ -237,30 +206,26 @@ fapi2::ReturnCode p10_qme_customize(
707 .set_INST_CASE(bInstCase)
708 .set_RING_ID(ringId),
709 "Error: ringidGetRingId2() failed w/rc=0x%08x,\n"
710- " torMagic=0x%08x,iRing=0x%08x,\n"
711- " bInstCase=%d, ringId=0x%08x.\n",
712- rc,
713- torMagic,
714- iRing,
715- bInstCase,
716- ringId);
717-
718- io_bufCustRingsSize = be32toh(((TorHeader_t*) io_bufCustRings)->size);
719+ " torMagic=0x%08x, iRing=%u,\n"
720+ " bInstCase=%u and ringId=0x%x.\n",
721+ rc, torMagic, iRing, bInstCase, ringId);
722+
723+ io_bufCustRingsSize = be32toh(torHeaderCust->size);
724 nextRing = (void*) (io_bufCustRings + io_bufCustRingsSize);
725- nextRingSize = maxCustRingsSize - io_bufCustRingsSize;
726
727- // nextRing is portion of io_bufCustRings buffer, which is used as
728- // temporary memory to pass the ring in i_bufQmeRings from the
729+ // nextRing is portion of io_bufCustRings buffer which is used as
730+ // temporary buffer to pass the ring in i_bufQmeRings from the
731 // tor_get_single_ring() function.
732- // The size of nextRing is the size of temporary memory.
733+ // The size of this temporary buffer is captured by remBufSize.
734 FAPI_ASSERT(maxCustRingsSize > io_bufCustRingsSize,
735 fapi2::QMEC_RINGS_OUTPUT_BUFFER_TOO_SMALL()
736 .set_MAX_CUST_RINGS_BUF_SIZE(maxCustRingsSize)
737 .set_CUST_QME_RINGS_BUF_SIZE(io_bufCustRingsSize),
738 "Error: QME rings output buffer is not large enough to use part of it for rs4Ring,\n"
739 " maxCustRingsSize=0x%08x, io_bufCustRingsSize=0x%08x.\n",
740- maxCustRingsSize,
741- io_bufCustRingsSize);
742+ maxCustRingsSize, io_bufCustRingsSize);
743+
744+ remBufSize = maxCustRingsSize - io_bufCustRingsSize;
745
746 // Extract ring data using the ringId.
747 rc = tor_get_single_ring(i_bufQmeRings,
748@@ -268,18 +233,9 @@ fapi2::ReturnCode p10_qme_customize(
749 ringId,
750 chipletInstId, //This argument ignored for Common rings.
751 nextRing,
752- nextRingSize,
753+ remBufSize,
754 i_dbgl);
755
756- FAPI_DBG("tor_get_single_ring() completed w/rc=0x%08x,\n"
757- " ddLevel=0x%08x, ringId=0x%08x,\n"
758- " chipletInstId=0x%08x, nextRs4RingSize=%d.\n",
759- rc,
760- ddLevel,
761- ringId,
762- chipletInstId,
763- nextRingSize);
764-
765 FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS ||
766 rc == TOR_RING_IS_EMPTY,
767 fapi2::QMEC_TOR_GET_SINGLE_RING_ERROR()
768@@ -288,17 +244,12 @@ fapi2::ReturnCode p10_qme_customize(
769 .set_DD_LEVEL(ddLevel)
770 .set_RING_ID(ringId)
771 .set_CHIPLET_INST_ID(chipletInstId)
772- .set_NEXT_RS4RING_BUF_SIZE(nextRingSize),
773- "Error: tor_get_single_ring() failed w/rc=0x%08x,\n"
774- " ddLevel=0x%08x, ringId=0x%08x,\n"
775- " chipletInstId=0x%08x, nextRs4RingSize=%d.\n",
776- rc,
777- ddLevel,
778- ringId,
779- chipletInstId,
780- nextRingSize);
781-
782- // if ring is empty, loop through and check next ring.
783+ .set_NEXT_RS4RING_BUF_SIZE(remBufSize),
784+ "Error: tor_get_single_ring() failed w/rc=0x%08x, ddLevel=0x%02x,"
785+ " ringId=0x%x, chipletInstId=0x%02x, remBufSize=%u.\n",
786+ rc, ddLevel, ringId, chipletInstId, remBufSize);
787+
788+ // If ring is empty, skip and check next ring.
789 if(rc == TOR_RING_IS_EMPTY)
790 {
791 rc = INFRASTRUCT_RC_SUCCESS;
792@@ -308,17 +259,13 @@ fapi2::ReturnCode p10_qme_customize(
793 // Append ring to ring section.
794 // Note that this API also updates the header's ring size
795 rc = tor_append_ring(io_bufCustRings,
796- io_bufCustRingsSize,
797+ maxCustRingsSize,
798 ringId,
799 chipletInstId,
800- (void*) nextRing,
801+ (void*)nextRing,
802 i_dbgl);
803
804- FAPI_DBG("tor_append_ring() completed w/rc=0x%08x,\n"
805- " io_bufCustRingsSize=0x%08x, ringId=0x%x.\n",
806- rc,
807- io_bufCustRingsSize,
808- ringId);
809+ io_bufCustRingsSize = be32toh(torHeaderCust->size);
810
811 FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS,
812 fapi2::QMEC_TOR_APPEND_RING_ERROR()
813@@ -328,16 +275,13 @@ fapi2::ReturnCode p10_qme_customize(
814 .set_RING_ID(ringId),
815 "Error: tor_append_ring() failed w/rc=0x%08x,\n"
816 " io_bufCustRingsSize=0x%08x, ringId=0x%x.\n",
817- rc,
818- io_bufCustRingsSize,
819- ringId);
820+ rc, io_bufCustRingsSize, ringId);
821+
822 }
823
824- FAPI_DBG("p10_qme_customize(): io_bufCustRingsSize = 0x%08x\n",
825- io_bufCustRingsSize);
826+fapi_try_exit:
827
828 FAPI_IMP("<< p10_qme_customize ");
829
830-fapi_try_exit:
831 return fapi2::current_err;
832 }
833diff --git a/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml b/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml
834index eeb7016..838c3e6 100644
835--- a/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml
836+++ b/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml
837@@ -353,10 +353,11 @@
838 </hwpError>
839 <!-- ********************************************************************* -->
840 <hwpError>
841- <rc>RC_XIPC_SECTION_SIZING</rc>
842+ <rc>RC_XIPC_RING_SECTION_SIZING</rc>
843 <description>Code bug: Ring section size would exceed max ring section size</description>
844 <ffdc>CHIP_TARGET</ffdc>
845 <ffdc>RING_SECTION_SIZE</ffdc>
846+ <ffdc>RING_SECTION_BUF_SIZE</ffdc>
847 <ffdc>MAX_RING_SECTION_SIZE</ffdc>
848 <ffdc>OCCURRENCE</ffdc>
849 <callout>
850diff --git a/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H b/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H
851index 81df056..feffee2 100644
852--- a/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H
853+++ b/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H
854@@ -49,7 +49,6 @@ const uint32_t MAX_RT_IMAGE_SIZE = 1024 * 1024; // Max Runtime size.
855 const uint32_t MAX_RING_BUF_SIZE = 650000; // Max ring buffer size (agreed w/HB).
856 const uint32_t MAX_RING_BUF_SIZE_TOOL = 450000; // Max ring buf size for tools.
857
858-const uint32_t MAX_DYN_RING_SECTION_SIZE = 1024 * 1024; // Max dynamic ring section size.
859 const uint32_t MAX_OVERRIDES_SIZE = 2 * 1024; // Max overrides ring section size.
860 const uint32_t MAX_HBBL_SIZE = 20 * 1024; // Max hbbl bin section size.
861
862diff --git a/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H b/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H
863index 8485543..ba38835 100644
864--- a/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H
865+++ b/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H
866@@ -5,7 +5,7 @@
867 /* */
868 /* OpenPOWER HostBoot Project */
869 /* */
870-/* Contributors Listed Below - COPYRIGHT 2019 */
871+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
872 /* [+] International Business Machines Corp. */
873 /* */
874 /* */
875@@ -86,7 +86,8 @@ typedef struct
876 uint16_t iv_undefined; // Must be last (temp assumption in Mvpd accessor)
877 } CompressedScanData;
878
879-#define RS4_V3TOV4_SIZE_INC 4 // Header increase from V3 to V4 (needed by Mvpd accessor)
880+#define RS4_V3TOV4_SIZE_INC 4 // Header increase from V3 to V4 (needed by Mvpd accessor)
881+#define RS4_MIN_RING_SIZE 20 // Min value of iv_size, e.g. flush size of short ring.
882
883 /// Endian-translate a CompressedScanData structure
884 ///
885diff --git a/src/import/chips/p10/utils/imageProcs/p10_tor.C b/src/import/chips/p10/utils/imageProcs/p10_tor.C
886index 62f9462..c3f0e86 100644
887--- a/src/import/chips/p10/utils/imageProcs/p10_tor.C
888+++ b/src/import/chips/p10/utils/imageProcs/p10_tor.C
889@@ -36,37 +36,40 @@
890
891
892 ///////////////////////////////////////////////////////////////////////////////////
893-// Get Ring From Ring Section function
894+// [internal] TOR Access Ring function
895 //////////////////////////////////////////////////////////////////////////////////
896 static
897-int get_ring_from_ring_section( void* i_ringSection, // Ring section ptr
898- RingId_t i_ringId, // Ring ID
899- uint8_t& io_instanceId, // IO instance ID
900- RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING
901- void* io_rs4Ring, // IO RS4 ring buffer (caller mgd)
902- uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size
903- uint32_t i_dbgl )
904+int _tor_access_ring( void* io_ringSection, // Ring section ptr
905+ uint32_t i_maxRingSectionSize, // Max ringSection size
906+ RingId_t i_ringId, // Ring ID to extract or append
907+ uint8_t i_chipletId, // Chiplet ID (ignored for Common rings)
908+ RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING
909+ void* io_rs4Ring, // RS4 ring buffer (caller mgd)
910+ uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size
911+ uint32_t i_dbgl )
912 {
913 int rc = TOR_SUCCESS;
914 TorHeader_t* torHeader;
915 uint32_t torMagic;
916 ChipId_t chipId;
917 TorCpltBlock_t* cpltBlock;
918- TorCpltOffset_t cpltOffset; // Offset from ringSection to chiplet section
919- TorRingOffset_t ringOffset; // Offset to actual ring container
920+ TorOffset_t cpltOffsetSlot; // Offset to TOR chiplet offset slot
921+ TorOffset_t cpltOffset; // Offset from ringSection to chiplet section
922+ TorOffset_t ringOffsetSlot; // Offset to TOR ring offset slot
923+ TorOffset_t ringOffset; // Offset to actual ring container (for GET operation)
924+ TorOffset_t ringOffset16; // Offset to actual ring container (for PUT operation)
925 uint32_t torSlotNum; // TOR slot number (within a chiplet section)
926 uint32_t rs4Size; // Size of RS4 ring container/block.
927 RingId_t numRings;
928 ChipletType_t chipletType = UNDEFINED_CHIPLET_TYPE;
929 ChipletType_t chipletIndex = UNDEFINED_CHIPLET_TYPE; // Effective chiplet index
930 MyBool_t bInstCase = UNDEFINED_BOOLEAN;
931- ChipletData_t* chipletData;
932- uint8_t numInstances;
933 RingProperties_t* ringProps = NULL;
934+ ChipletData_t* chipletData = NULL;
935 uint8_t idxRingEff; // Effective chiplet ring index
936- uint8_t iInst, iRing; // Index counters for instance, chiplet rings
937+ uint32_t ringSectionSize;
938
939- torHeader = (TorHeader_t*)i_ringSection;
940+ torHeader = (TorHeader_t*)io_ringSection;
941 torMagic = be32toh(torHeader->magic);
942 chipId = torHeader->chipId;
943
944@@ -100,7 +103,7 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section
945 }
946
947 //
948- // Check the scope of chipletType and Get the effective chipletType's index
949+ // Check the scope of chipletType and get the effective chipletType's index
950 //
951 rc = ringid_get_chipletIndex( chipId,
952 torMagic,
953@@ -133,20 +136,30 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section
954 bInstCase = 0;
955 }
956
957- //
958- // Calculate various loop upper limits
959- //
960- numInstances = bInstCase ?
961- chipletData->numChipletInstances :
962- 1;
963-
964 numRings = bInstCase ?
965 chipletData->numInstanceRings :
966 chipletData->numCommonRings;
967
968 idxRingEff = ringProps[i_ringId].idxRing & INSTANCE_RING_MASK; // Always safe
969
970+ //
971+ // Check that chipletId is within chiplet's range (Note that we care only about Instance
972+ // rings here so we can identify to proper slot. For Common rings, we can ignore the
973+ // chipletId since there's only one instance slot, namely the 0'th.)
974+ //
975+ if ( bInstCase &&
976+ ( i_chipletId < chipletData->chipletBaseId ||
977+ i_chipletId > (chipletData->chipletBaseId + chipletData->numChipletInstances - 1) ) )
978+ {
979+ // TOR_INVALID_CHIPLET_ID: This is not necessarily an error. User codes may differ
980+ // in their knowledge what is an acceptable value for the chipletId. So we can't
981+ // trace out here in confidence. It's up to the caller to investigate the rc.
982+ return TOR_INVALID_CHIPLET_ID;
983+ }
984+
985+ //
986 // Unless we find a ring, then the following rc will be returned
987+ //
988 rc = TOR_RING_HAS_NO_TOR_SLOT;
989
990 //
991@@ -154,137 +167,138 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section
992 //
993 if (numRings) // Only proceed if chiplet has [Common/Instance] rings.
994 {
995- // Calc offset to chiplet's CMN or INST section, cpltOffset (steps 1-3)
996+ // Calc offset to chiplet's CMN or INST section, cpltOffset
997+ // - Note that the TOR cpltOffset is assumed to be wrt to ringSection origin
998+ //
999+ // 1. Calc offset to TOR chiplet offset slot pointing to chiplet's COM or INST section
1000+ cpltOffsetSlot = sizeof(TorHeader_t) +
1001+ chipletIndex * sizeof(TorCpltBlock_t) +
1002+ bInstCase * sizeof(cpltBlock->cmnOffset);
1003+ // 2. Retrive chiplet offset and endian convert
1004+ cpltOffset = *(TorOffset_t*)( (uint8_t*)io_ringSection + cpltOffsetSlot );
1005+ cpltOffset = be16toh(cpltOffset); // <- This is the final TOR chiplet offset
1006+
1007+ //
1008+ // Calc the effective TOR offset slot index number (within the chiplet's Common
1009+ // or Instance ring section)
1010 //
1011- // 1. Calc offset to TOR slot pointing to chiplet's COM or INST section
1012- cpltOffset = sizeof(TorHeader_t) +
1013- chipletIndex * sizeof(TorCpltBlock_t) +
1014- bInstCase * sizeof(cpltBlock->cmnOffset);
1015- // 2. Retrive offset, endian convert and make it relative to ring section origin
1016- cpltOffset = *(uint32_t*)( (uint8_t*)i_ringSection + cpltOffset );
1017- cpltOffset = be32toh(cpltOffset);
1018- // 3. Make offset relative to ring section origin
1019- cpltOffset = sizeof(TorHeader_t) + cpltOffset;
1020-
1021- torSlotNum = 0;
1022-
1023- for ( iInst = 0; iInst < numInstances; iInst++ )
1024+ torSlotNum = bInstCase * (i_chipletId - chipletData->chipletBaseId) * numRings + idxRingEff;
1025+
1026+ // Calc offset to actual ring, ringOffset
1027+ // - Note that ringOffset is assumed to be wrt to ringSection origin
1028+ //
1029+ // 1. Calc offset to the TOR ring offset slot (which points to the actual ring)
1030+ ringOffsetSlot = cpltOffset + torSlotNum * sizeof(ringOffset);
1031+ // 2. Retrieve ring offset and endian convert
1032+ ringOffset = *(TorOffset_t*)( (uint8_t*)io_ringSection + ringOffsetSlot );
1033+ ringOffset = be16toh(ringOffset); // <- This is the final TOR ring offset
1034+
1035+ if (i_ringRequest == GET_SINGLE_RING)
1036 {
1037- for ( iRing = 0; iRing < numRings; iRing++ )
1038+ rs4Size = 0;
1039+
1040+ if (ringOffset)
1041 {
1042- // Remember in the following "busy" if that we're already in the correct
1043- // chiplet ring section and that we're merely trying to determine if we have
1044- // hit the proper combination of (iRing,iInst).
1045- if ( idxRingEff == iRing &&
1046- ( !bInstCase ||
1047- ( bInstCase &&
1048- ( iInst == (io_instanceId - chipletData->chipletBaseId) ) ) ) )
1049- {
1050- // Calc offset to actual ring, ringOffset (steps 1-3)
1051- //
1052- // 1. Calc offset to TOR slot pointing to actual ring
1053- ringOffset = cpltOffset + torSlotNum * sizeof(ringOffset);
1054- // 2. Retrieve offset and endian convert
1055- ringOffset = *(TorRingOffset_t*)( (uint8_t*)i_ringSection + ringOffset );
1056- ringOffset = be16toh(ringOffset);
1057-
1058- if (i_ringRequest == GET_SINGLE_RING)
1059- {
1060- rs4Size = 0;
1061-
1062- if (ringOffset)
1063- {
1064- // 3. Make offset relative to ring section origin
1065- ringOffset = cpltOffset + ringOffset;
1066-
1067- rs4Size = be16toh( ((CompressedScanData*)
1068- ((uint8_t*)i_ringSection + ringOffset))->iv_size );
1069-
1070- if (io_ringBufSize < rs4Size)
1071- {
1072- if (i_dbgl > 0)
1073- {
1074- MY_DBG("io_ringBufSize(=%u) is less than rs4Size(=%u).\n",
1075- io_ringBufSize, rs4Size);
1076- }
1077-
1078- io_ringBufSize = rs4Size;
1079- return TOR_BUFFER_TOO_SMALL;
1080- }
1081-
1082- // Produce return parms
1083- memcpy( io_rs4Ring,
1084- (void*)((uint8_t*)i_ringSection + ringOffset),
1085- rs4Size );
1086- io_ringBufSize = rs4Size;
1087- io_instanceId = bInstCase ?
1088- io_instanceId :
1089- chipletData->chipletBaseId;
1090-
1091- if (i_dbgl > 0)
1092- {
1093- MY_DBG("Found a ring:\n" \
1094- " ringId: 0x%x\n" \
1095- " rs4Size: %d\n",
1096- i_ringId, rs4Size);
1097- }
1098-
1099- rc = TOR_SUCCESS;
1100- }
1101- else
1102- {
1103- if (i_dbgl > 0)
1104- {
1105- MY_DBG("ringId=0x%x was found but is empty\n",
1106- i_ringId);
1107- }
1108-
1109- rc = TOR_RING_IS_EMPTY;
1110- }
1111-
1112- if (i_dbgl > 0)
1113- {
1114- MY_DBG("Details for chiplet ring index=%d: \n"
1115- " Full offset to chiplet section = 0x%08x \n"
1116- " Full offset to RS4 header = 0x%08x \n"
1117- " RS4 ring size = 0x%08x \n",
1118- iRing, cpltOffset, ringOffset, rs4Size);
1119- }
1120-
1121- return rc;
1122+ rs4Size = be16toh( ((CompressedScanData*)
1123+ ((uint8_t*)io_ringSection + ringOffset))->iv_size );
1124
1125- }
1126- else if (i_ringRequest == PUT_SINGLE_RING)
1127- {
1128- if (ringOffset)
1129- {
1130- MY_ERR("Ring container is already present in image\n");
1131- MY_ERR(" Ring section addr: 0x%016lx (First 8B: 0x%016lx)\n",
1132- (uintptr_t)i_ringSection,
1133- be64toh(*((uint64_t*)i_ringSection)));
1134- MY_ERR(" cpltOffset=0x%08x, torSlotNum=0x%x, TOR offset=0x%04x\n",
1135- cpltOffset, torSlotNum, ringOffset);
1136- return TOR_RING_IS_POPULATED;
1137- }
1138-
1139- // Special [mis]use of io_rs4Ring and io_ringBufSize:
1140- // Put location of chiplet's CMN or INST section into rs4Ring
1141- memcpy(io_rs4Ring, &cpltOffset, sizeof(cpltOffset));
1142- // Put location of ringOffset slot into ringBufSize
1143- io_ringBufSize = cpltOffset + (torSlotNum * sizeof(ringOffset));
1144-
1145- return TOR_SUCCESS;
1146- }
1147- else
1148+ if (io_ringBufSize < rs4Size)
1149+ {
1150+ if (i_dbgl > 0)
1151 {
1152- MY_ERR("Ring request (i_ringRequest=%d) is not supported\n", i_ringRequest);
1153- return TOR_INVALID_RING_REQUEST;
1154+ MY_DBG("io_ringBufSize(=%u) is less than rs4Size(=%u).\n",
1155+ io_ringBufSize, rs4Size);
1156 }
1157+
1158+ io_ringBufSize = rs4Size;
1159+ return TOR_BUFFER_TOO_SMALL;
1160+ }
1161+
1162+ // Produce return parms
1163+ memcpy( io_rs4Ring,
1164+ (void*)((uint8_t*)io_ringSection + ringOffset),
1165+ rs4Size );
1166+ io_ringBufSize = rs4Size;
1167+
1168+ if (i_dbgl > 0)
1169+ {
1170+ MY_DBG("Found a ring: ringId=0x%x and rs4Size=%u\n",
1171+ i_ringId, rs4Size);
1172 }
1173
1174- torSlotNum++; // Next TOR ring slot
1175+ rc = TOR_SUCCESS;
1176+ }
1177+ else
1178+ {
1179+ rc = TOR_RING_IS_EMPTY;
1180 }
1181+
1182+ return rc;
1183+
1184+ }
1185+ else if (i_ringRequest == PUT_SINGLE_RING)
1186+ {
1187+ // We can not overwrite an existing ring
1188+ if (ringOffset)
1189+ {
1190+ MY_ERR("Ring container is already present in image\n");
1191+ MY_ERR(" Ring section addr: 0x%016lx (First 8B: 0x%016lx)\n",
1192+ (uintptr_t)io_ringSection,
1193+ be64toh(*((uint64_t*)io_ringSection)));
1194+ MY_ERR(" cpltOffset=0x%08x, torSlotNum=0x%x, ringOffset=0x%04x\n",
1195+ cpltOffset, torSlotNum, ringOffset);
1196+ return TOR_RING_IS_POPULATED;
1197+ }
1198+
1199+ // Check we can fit the ring
1200+ ringSectionSize = be32toh(torHeader->size);
1201+ rs4Size = be16toh( ((CompressedScanData*)io_rs4Ring)->iv_size );
1202+
1203+ if ( (ringSectionSize + rs4Size) > i_maxRingSectionSize )
1204+ {
1205+ MY_ERR("ERROR: _tor_access_ring() : Appending the ring would overflow"
1206+ " the max ring section size:\n"
1207+ " Current ringSectionSize: %d\n"
1208+ " Size of ring to be added: %d\n"
1209+ " Max ringSection Size: %d\n",
1210+ ringSectionSize, rs4Size, i_maxRingSectionSize);
1211+ return TOR_BUFFER_TOO_SMALL;
1212+ }
1213+
1214+ // Then calculate the TOR ring offset value and put it into the TOR ring
1215+ // slot. But first, check that the offset value can be contained within
1216+ // the 2B of the TOR ring slot.
1217+ // - Note that TOR offset value to the ring is wrt to ringSection origin
1218+ if ( ringSectionSize <= MAX_TOR_RING_OFFSET )
1219+ {
1220+ ringOffset16 = htobe16(ringSectionSize);
1221+ memcpy( (uint8_t*)io_ringSection + ringOffsetSlot,
1222+ &ringOffset16,
1223+ sizeof(ringOffset16) );
1224+ }
1225+ else
1226+ {
1227+ MY_ERR("Code bug: Ring offset (=0x%x) exceeds MAX_TOR_RING_OFFSET (=0x%x)\n",
1228+ ringSectionSize, MAX_TOR_RING_OFFSET);
1229+ return TOR_OFFSET_TOO_BIG;
1230+ }
1231+
1232+ // Finally, append the ring to the end of ringSection.
1233+ memcpy( (uint8_t*)io_ringSection + ringSectionSize,
1234+ (uint8_t*)io_rs4Ring,
1235+ rs4Size );
1236+
1237+ // Update the ring section size in the TOR header
1238+ torHeader->size = htobe32(ringSectionSize + rs4Size);
1239+
1240+ return TOR_SUCCESS;
1241+ }
1242+ else
1243+ {
1244+ MY_ERR("Ring request (i_ringRequest=%d) is not supported\n", i_ringRequest);
1245+ return TOR_INVALID_RING_REQUEST;
1246 }
1247+
1248 }
1249 else
1250 {
1251@@ -296,31 +310,22 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section
1252
1253 return rc;
1254
1255-} // End of get_ring_from_ring_section()
1256+} // End of _tor_access_ring()
1257
1258
1259
1260 //////////////////////////////////////////////////////////////////////////////////////////
1261-/// TOR ACCESS RING API
1262+/// [internal] TOR Header Check function
1263 //////////////////////////////////////////////////////////////////////////////////////////
1264-int tor_access_ring( void* i_ringSection, // Ring section ptr
1265- RingId_t i_ringId, // Ring ID
1266- uint8_t i_ddLevel, // DD level
1267- uint8_t& io_instanceId, // Instance ID
1268- RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING
1269- void* io_rs4Ring, // IO RS4 ring buffer (caller mgd)
1270- uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size
1271- uint32_t i_dbgl )
1272+int _tor_header_check( void* i_ringSection, // Ring section ptr
1273+ RingId_t i_ringId, // Ring ID
1274+ uint8_t i_ddLevel, // DD level
1275+ uint32_t i_dbgl )
1276 {
1277 int rc = TOR_SUCCESS;
1278 uint32_t torMagic;
1279 TorHeader_t* torHeader;
1280
1281- if (i_dbgl > 1)
1282- {
1283- MY_DBG("Entering tor_access_ring()...\n");
1284- }
1285-
1286 torHeader = (TorHeader_t*)i_ringSection;
1287 torMagic = be32toh(torHeader->magic);
1288
1289@@ -384,10 +389,10 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr
1290 torHeader->version != TOR_VERSION ||
1291 torHeader->rtVersion > RING_TABLE_VERSION_HWIMG )
1292 {
1293- MY_ERR("TOR header check failure:\n"
1294- " magic: 0x%08x (!= TOR_MAGIC: 0x%08x)\n"
1295- " version: %u (!= TOR_VERSION: %u)\n"
1296- " rtVersion: %u (> RING_TABLE_VERSION_HWIMG: %u)\n"
1297+ MY_ERR("ERROR: TOR header check failure:\n"
1298+ " magic: 0x%08x (TOR_MAGIC: 0x%08x)\n"
1299+ " version: %u (TOR_VERSION: %u)\n"
1300+ " rtVersion: %u (RING_TABLE_VERSION_HWIMG: %u)\n"
1301 " size: %d\n",
1302 torMagic, TOR_MAGIC,
1303 torHeader->version, TOR_VERSION,
1304@@ -400,75 +405,58 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr
1305 if ( i_ddLevel != torHeader->ddLevel &&
1306 i_ddLevel != UNDEFINED_DD_LEVEL )
1307 {
1308- MY_ERR("Requested DD level (=0x%x) doesn't match TOR header DD level (=0x%x) nor"
1309- " UNDEFINED_DD_LEVEL (=0x%x)\n",
1310+ MY_ERR("ERROR: Requested DD level (=0x%x) doesn't match TOR header DD level (=0x%x)"
1311+ " nor UNDEFINED_DD_LEVEL (=0x%x)\n",
1312 i_ddLevel, torHeader->ddLevel, UNDEFINED_DD_LEVEL);
1313 return TOR_DD_LEVEL_NOT_FOUND;
1314 }
1315
1316- rc = get_ring_from_ring_section( i_ringSection,
1317- i_ringId,
1318- io_instanceId,
1319- i_ringRequest,
1320- io_rs4Ring,
1321- io_ringBufSize,
1322- i_dbgl );
1323-
1324- // Explanation to the "list" of RCs that we exclude from tracing out:
1325- // TOR_RING_IS_EMPTY: Normal scenario (will occur frequently).
1326- // TOR_RING_HAS_NO_TOR_SLOT: Will be caused a lot by ipl_image_tool, but is an error if
1327- // called by any other user.
1328- // TOR_INVALID_CHIPLET_TYPE: Also somewhat normal scenario since the caller should,
1329- // in princple, be able to mindlessly request a ringId without
1330- // having to figure out first if that ringId belongs to a chiplet
1331- // that is valid for the context. But really this is a gray area.
1332- // For now, we omit to trace out as we will hit this rc condition
1333- // in both ipl_image_tool and ipl_customize (RT_QME phase).
1334- if (rc)
1335- {
1336- if ( rc != TOR_RING_IS_EMPTY &&
1337- rc != TOR_RING_HAS_NO_TOR_SLOT &&
1338- rc != TOR_INVALID_CHIPLET_TYPE )
1339- {
1340- MY_ERR("ERROR : tor_access_ring() : get_ring_from_ring_section() failed w/rc="
1341- "0x%08x\n", rc);
1342- }
1343-
1344- return rc;
1345- }
1346-
1347 return rc;
1348-} // End of tor_access_ring()
1349+} // End of _tor_header_check()
1350
1351
1352
1353 /////////////////////////////////////////////////////////////////////////////////////
1354-// TOR GET SINGLE RING API
1355+// TOR Get Single Ring API
1356 /////////////////////////////////////////////////////////////////////////////////////
1357 int tor_get_single_ring ( void* i_ringSection, // Ring section ptr
1358 uint8_t i_ddLevel, // DD level
1359 RingId_t i_ringId, // Ring ID
1360- uint8_t i_instanceId, // Instance ID
1361+ uint8_t i_chipletId, // Chiplet ID (ignored for Common rings)
1362 void* io_rs4Ring, // IO RS4 ring buffer (caller mgd)
1363 uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size
1364 uint32_t i_dbgl )
1365 {
1366+ int rc = TOR_SUCCESS;
1367
1368- int rc = TOR_SUCCESS;
1369+ rc = _tor_header_check( i_ringSection,
1370+ i_ringId,
1371+ i_ddLevel,
1372+ i_dbgl );
1373
1374- rc = tor_access_ring( i_ringSection,
1375- i_ringId,
1376- i_ddLevel,
1377- i_instanceId,
1378- GET_SINGLE_RING,
1379- io_rs4Ring,
1380- io_ringBufSize,
1381- i_dbgl );
1382+ if (rc)
1383+ {
1384+ MY_ERR("ERROR: tor_get_single_ring() : _tor_header_check() failed w/rc=0x%08x\n", rc);
1385+ return rc;
1386+ }
1387+
1388+ rc = _tor_access_ring( i_ringSection,
1389+ 0, // Not used. Only used when appending a ring.
1390+ i_ringId,
1391+ i_chipletId,
1392+ GET_SINGLE_RING,
1393+ io_rs4Ring,
1394+ io_ringBufSize,
1395+ i_dbgl );
1396
1397 // Explanation to the "list" of RCs that we exclude from tracing out:
1398 // TOR_RING_IS_EMPTY: Normal scenario (will occur frequently).
1399 // TOR_HOLE_RING_ID: Normal scenario when rings are removed from the ring list
1400 // and leaves behind a "hole".
1401+ // TOR_RING_HAS_NO_TOR_SLOT: Will be caused a lot by ipl_image_tool, but is an error if
1402+ // called by any other user.
1403+ // TOR_INVALID_CHIPLET_ID: Not necessarily an error as a user may be sweeping through a
1404+ // worst case range to "get all I can get".
1405 // TOR_INVALID_CHIPLET_TYPE: Also somewhat normal scenario since the caller should,
1406 // in princple, be able to mindlessly request a ringId without
1407 // having to figure out first if that ringId belongs to a chiplet
1408@@ -479,104 +467,82 @@ int tor_get_single_ring ( void* i_ringSection, // Ring section ptr
1409 {
1410 if ( rc != TOR_RING_IS_EMPTY &&
1411 rc != TOR_HOLE_RING_ID &&
1412+ rc != TOR_RING_HAS_NO_TOR_SLOT &&
1413+ rc != TOR_INVALID_CHIPLET_ID &&
1414 rc != TOR_INVALID_CHIPLET_TYPE )
1415 {
1416- MY_ERR("ERROR : tor_get_single_ring() : tor_access_ring() failed w/rc=0x%08x\n", rc);
1417+ MY_ERR("ERROR: tor_get_single_ring() : _tor_access_ring() failed w/rc=0x%08x\n", rc);
1418 }
1419
1420 return rc;
1421 }
1422
1423 return rc;
1424-}
1425+} // End of tor_get_single_ring()
1426
1427
1428
1429 ////////////////////////////////////////////////////////////////////////////////////////
1430-// TOR APPEND RING API
1431+// TOR Append Ring API
1432 ///////////////////////////////////////////////////////////////////////////////////////
1433-int tor_append_ring( void* i_ringSection, // Ring section ptr
1434- uint32_t& io_ringSectionSize, // In: Exact size of ring section.
1435- // Out: Updated size of ring section.
1436- RingId_t i_ringId, // Ring ID
1437- uint8_t i_instanceId, // Instance ID
1438- void* i_rs4Ring, // RS4 ring
1439- uint32_t i_dbgl ) // Debug option
1440+int tor_append_ring( void* io_ringSection, // Ring section ptr
1441+ uint32_t i_maxRingSectionSize, // Max ringSection size
1442+ RingId_t i_ringId, // Ring ID to append
1443+ uint8_t i_chipletId, // Chiplet ID (ignored for Common rings)
1444+ void* i_rs4Ring, // RS4 ring container
1445+ uint32_t i_dbgl ) // Debug option
1446 {
1447- int rc = TOR_SUCCESS;
1448- uint32_t buf = 0;
1449- uint32_t* cpltSection = &buf;
1450- uint32_t rs4Size = 0;
1451- TorRingOffset_t ringOffset16;
1452- uint32_t torOffsetSlot;
1453+ int rc = TOR_SUCCESS;
1454+ uint32_t ringBufSize;
1455
1456- if ( ringid_has_derivs( ((TorHeader_t*)i_ringSection)->chipId, i_ringId) )
1457+ rc = _tor_header_check( io_ringSection,
1458+ i_ringId,
1459+ UNDEFINED_DD_LEVEL,
1460+ i_dbgl );
1461+
1462+ if (rc)
1463 {
1464- MY_DBG("Can't append ringId=0x%x since it has derivatives\n",
1465+ MY_ERR("ERROR: tor_append_ring() : _tor_header_check() failed w/rc=0x%08x\n", rc);
1466+ return rc;
1467+ }
1468+
1469+ if ( ringid_has_derivs( ((TorHeader_t*)io_ringSection)->chipId, i_ringId) )
1470+ {
1471+ MY_DBG("Can't append ringId=0x%x since it has derivatives. Only the"
1472+ " derivative rings, e.g. *_bucket, can be appended.\n",
1473 i_ringId);
1474 return TOR_RING_HAS_DERIVS;
1475 }
1476
1477- rc = tor_access_ring( i_ringSection,
1478- i_ringId,
1479- UNDEFINED_DD_LEVEL,
1480- i_instanceId,
1481- PUT_SINGLE_RING,
1482- (void*)cpltSection, // On return, contains offset (wrt ringSection) of
1483- // chiplet section's common or instance section
1484- torOffsetSlot, // On return, contains offset (wrt ringSection) of
1485- // TOR offset slot
1486- i_dbgl );
1487+ rc = _tor_access_ring( io_ringSection,
1488+ i_maxRingSectionSize,
1489+ i_ringId,
1490+ i_chipletId,
1491+ PUT_SINGLE_RING,
1492+ i_rs4Ring,
1493+ ringBufSize, // Not used here
1494+ i_dbgl );
1495
1496 // Explanation to the "list" of RCs that we exclude from tracing out:
1497- // TOR_INVALID_CHIPLET_TYPE: Not really a normal scenario though it's not unreasonable that
1498- // the caller should be able to mindlessly request a ringId without
1499- // having to figure out first if that ringId belongs to a chiplet
1500- // that is valid for the context. But really this is a gray area.
1501+ // TOR_INVALID_CHIPLET_TYPE: Not really a normal scenario though it's possible a
1502+ // caller will mindlessly request a ringId to be appended without
1503+ // knowing ahead of the call if the ringId belongs to the chiplet
1504+ // indicated in ringSection's torMagic. But this is a gray area.
1505 // For now, we omit to trace out as we will hit this rc condition
1506 // in ipl_customize (RT_QME phase).
1507 if (rc)
1508 {
1509 if (rc != TOR_INVALID_CHIPLET_TYPE)
1510 {
1511- MY_ERR("ERROR : tor_append_ring() : tor_access_ring() failed w/rc=0x%08x\n", rc);
1512+ MY_ERR("ERROR: tor_append_ring() : _tor_access_ring() failed w/rc=0x%08x for"
1513+ " ringId=0x%x\n",
1514+ rc, i_ringId);
1515 }
1516
1517 return rc;
1518 }
1519
1520- // Explanation to the following:
1521- // tor_append_ring() appends a ring to the end of the ringSection. The offset value to
1522- // that ring is wrt the beginning of the chiplet's Common/Instance TOR ring offset slot
1523- // section. Below we calculate the offset value and put it into the TOR slot. But first,
1524- // check that the offset value can be contained within the 2B of the TOR slot.
1525- if ( (io_ringSectionSize - *cpltSection) <= MAX_TOR_RING_OFFSET )
1526- {
1527- ringOffset16 = htobe16(io_ringSectionSize - *cpltSection);
1528- memcpy( (uint8_t*)i_ringSection + torOffsetSlot,
1529- &ringOffset16, sizeof(ringOffset16) );
1530- }
1531- else
1532- {
1533- MY_ERR("Code bug: TOR ring offset (=0x%x) exceeds MAX_TOR_RING_OFFSET (=0x%x)\n",
1534- io_ringSectionSize - *cpltSection, MAX_TOR_RING_OFFSET);
1535- return TOR_OFFSET_TOO_BIG;
1536- }
1537-
1538- // Now append the ring to the end of ringSection.
1539- rs4Size = be16toh( ((CompressedScanData*)i_rs4Ring)->iv_size );
1540- memcpy( (uint8_t*)i_ringSection + io_ringSectionSize,
1541- (uint8_t*)i_rs4Ring,
1542- rs4Size );
1543-
1544- // Update the ringSectionSize
1545- io_ringSectionSize += rs4Size;
1546-
1547- // Update the size in the TOR header
1548- TorHeader_t* torHeader = (TorHeader_t*)i_ringSection;
1549- torHeader->size = htobe32(be32toh(torHeader->size) + rs4Size);
1550-
1551- return TOR_SUCCESS;
1552+ return rc;
1553 }
1554
1555
1556@@ -601,7 +567,6 @@ int tor_skeleton_generation( void* io_ringSection,
1557 uint32_t chipletBlockStart; // Offset from ringSection to start of chiplet offset block
1558 uint32_t sizeChipletBlock; // Size of the chiplet offset block
1559 uint32_t sizeRingSlots; // Size of ring offset block
1560- uint32_t chipletRingsStart; // Offset from ringSection to start of chiplet's ring slots
1561 RingId_t numRings = UNDEFINED_RING_ID; // Number of a chiplet common or instance rings
1562 uint8_t numInstances = 0; // Number of chiplet instances (=1 for COMMON case)
1563 uint32_t numRingSlots = 0; // Number of ring slots in chiplet's Cmn/Inst ring section
1564@@ -687,18 +652,15 @@ int tor_skeleton_generation( void* io_ringSection,
1565 continue;
1566 }
1567
1568- // Save start position of current chiplet's Common or Instance ring section
1569- // (relative to start of ringSection)
1570- chipletRingsStart = ringSectionSize;
1571-
1572 // Update the current chiplet block's offset to the Common or Instance ring section
1573+ // - Note that the TOR chiplet offsets are assumed to be wrt to ringSection origin
1574 if (bInstCase)
1575 {
1576- torChipletBlock->instOffset = htobe32(chipletRingsStart - chipletBlockStart);
1577+ torChipletBlock->instOffset = htobe16(ringSectionSize);
1578 }
1579 else
1580 {
1581- torChipletBlock->cmnOffset = htobe32(chipletRingsStart - chipletBlockStart);
1582+ torChipletBlock->cmnOffset = htobe16(ringSectionSize);
1583 }
1584
1585 // Determine total number of Instance or Common rings (TOR slots) which involves:
1586@@ -716,8 +678,8 @@ int tor_skeleton_generation( void* io_ringSection,
1587
1588 // Allocate and init offset slots for chiplet Cmn/Inst rings
1589 // Use 4B alignment of the TOR ring slots for debugging visualization.
1590- sizeRingSlots = myByteAlign(4, numRingSlots * sizeof(TorRingOffset_t));
1591- memset( (uint8_t*)io_ringSection + chipletRingsStart,
1592+ sizeRingSlots = myByteAlign(4, numRingSlots * sizeof(TorOffset_t));
1593+ memset( (uint8_t*)io_ringSection + ringSectionSize,
1594 0,
1595 sizeRingSlots );
1596
1597@@ -769,7 +731,7 @@ int dyn_append_ring( void* io_ringSection, // Ring section ptr
1598 }
1599 else
1600 {
1601- MY_ERR("ERROR in dyn_append_ring: ringSectionSize(=%d) + rs4Size(=%d)"
1602+ MY_ERR("ERROR in dyn_append_ring: ringSectionSize(=%u) + rs4Size(=%u)"
1603 " would exceed maxRingSectionSize(=%d)\n",
1604 ringSectionSize, rs4Size, i_maxRingSectionSize);
1605 return TOR_BUFFER_TOO_SMALL;
1606diff --git a/src/import/chips/p10/utils/imageProcs/p10_tor.H b/src/import/chips/p10/utils/imageProcs/p10_tor.H
1607index 929945e..093b39a 100644
1608--- a/src/import/chips/p10/utils/imageProcs/p10_tor.H
1609+++ b/src/import/chips/p10/utils/imageProcs/p10_tor.H
1610@@ -5,7 +5,7 @@
1611 /* */
1612 /* OpenPOWER HostBoot Project */
1613 /* */
1614-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
1615+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
1616 /* [+] International Business Machines Corp. */
1617 /* */
1618 /* */
1619@@ -56,66 +56,25 @@ int tor_skeleton_generation( void* io_ringSection,
1620 uint32_t dbgl = 0 );
1621
1622
1623-/// Access and perform various functions on a TOR ring section.
1624-///
1625-/// \param[in] i_ringSection A pointer to the TOR ring section.
1626-///
1627-/// \param[in] i_ringId A enum to indicate unique ID for the ring
1628-///
1629-/// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API
1630-/// uses DD level to extract single ring or block of rings from hw_image
1631-///
1632-/// \param[in/out] io_instanceId A variable to indicate chiplet instance ID.
1633-/// It returns Chiplet instance ID while doing get single ring operation
1634-///
1635-/// \param[in] i_ringRequest A enum to indicate type of operation performed
1636-/// by TOR API Option:
1637-/// GET_SINGLE_RING indicates to extract single ring container.
1638-/// PUT_SINGLE_RING indicates to extract ring absolute memory addres for
1639-/// ringTorSlot location
1640-///
1641-/// \param[in/out] io_rs4Ring A void pointer to pointer. Returns data
1642-/// which copied during extract ring operation and returns tor absolute address
1643-/// where offset slot is located while PUT_SINGLE_RING call.
1644-/// Note:- Caller's responsibility for free() to avoid memory leak
1645-///
1646-/// \param[in/out] io_ringBufSize A variable. Returns size of data copied
1647-/// into io_rs4Ring and returns absolute offset where ring RS4 starts in
1648-/// TOR during PUT_SINGLE_RING call
1649-///
1650-/// \param[in] i_debug Debug level [0:3].
1651-///
1652-/// \retval 0 Success
1653-///
1654-/// \retval non-0 See \ref TOR API RETURN errors
1655-int tor_access_ring( void* i_ringSection,
1656- RingId_t i_ringId,
1657- uint8_t i_ddLevel,
1658- uint8_t& io_instanceId, // Chiplet instance ID
1659- RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING
1660- void* io_rs4Ring,
1661- uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size
1662- uint32_t i_dbgl = 0 );
1663-
1664-
1665 /// Retrieve a single RS4 ring from a TOR ring section
1666 ///
1667-/// \param[in] i_ringSection A pointer to the ring section.
1668+/// \param[in] i_ringSection A pointer to the ring section.
1669 ///
1670-/// \param[in] i_ringId A enum to indicate unique ID for the ring
1671+/// \param[in] i_ringId A enum to indicate unique ID for the ring
1672 ///
1673-/// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API
1674-/// uses DD level to verify validity of ring section.
1675+/// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API uses
1676+/// DD level to verify validity of ring section.
1677 ///
1678-/// \param[in] io_instanceId A variable to indicate chiplet instance ID
1679+/// \param[in] i_chipletId A variable to indicate chiplet instance ID. Only
1680+/// used for Instance rings. Ignored for Common rings.
1681 ///
1682-/// \param[in/out] io_rs4Ring A void pointer. Contains copied ring.
1683-/// Note that it's caller's responsibility to manage buffer.
1684+/// \param[in/out] io_rs4Ring A void pointer. Contains copied ring. Note that
1685+/// it's caller's responsibility to manage buffer.
1686 ///
1687-/// \param[in/out] io_ringBufSize A variable that returns size of ring
1688-/// copied into io_rs4Ring
1689+/// \param[in/out] io_ringBufSize A variable that returns size of ring
1690+/// copied into io_rs4Ring
1691 ///
1692-/// \param[in] i_debug Debug level [0:3].
1693+/// \param[in] i_debug Debug level [0:3].
1694 ///
1695 /// \retval 0 Success
1696 ///
1697@@ -123,37 +82,36 @@ int tor_access_ring( void* i_ringSection,
1698 int tor_get_single_ring ( void* i_ringSection,
1699 uint8_t i_ddLevel,
1700 RingId_t i_ringId,
1701- uint8_t i_instanceId,
1702+ uint8_t i_chipletId,
1703 void* io_rs4Ring,
1704 uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size
1705 uint32_t i_dbgl = 0 );
1706
1707
1708-/// Append a single RS4 ring to the end of a TOR ring section.
1709+/// Append an RS4 ring to the end of a TOR ring section.
1710 ///
1711-/// \param[in] i_ringSection A pointer to a TOR ring section.
1712-/// Note that caller manages this buffer.
1713+/// \param[in/out] io_ringSection A pointer to a TOR ring section.
1714+/// Note that caller manages this buffer.
1715 ///
1716-/// \param[in/out] io_ringSectionSize In: Exact size of i_ringSection.
1717-/// Out: Updated size of i_ringSection.
1718+/// \param[in] i_maxRingSectionSize Max ring section size
1719 ///
1720-/// \param[in] i_ringId The unique enum ID for the ring
1721+/// \param[in] i_ringId The enum ID for the ring in rs4Ring to be appended
1722 ///
1723-/// \param[in] i_instanceId The chiplet instance ID. Only needed for
1724-/// Instance rings. Ignored for Common rings.
1725+/// \param[in] i_chipletId The chiplet instance ID. Only needed for Instance rings.
1726+/// Ignored for Common rings.
1727 ///
1728-/// \param[in] i_rs4Ring Pointer to the RS4 compressed ring container.
1729+/// \param[in] i_rs4Ring Pointer to the RS4 compressed ring container.
1730 ///
1731-/// \param[in] i_debug Debug level [0:3].
1732+/// \param[in] i_debug Debug level [0:3].
1733 ///
1734 /// \retval 0 Success
1735 ///
1736-/// \retval non-0 See \ref TOR API RETURN errors
1737+/// \retval non-0 See \ref TOR API RETURN errors
1738 ///
1739-int tor_append_ring( void* i_ringSection,
1740- uint32_t& io_ringSectionSize,
1741+int tor_append_ring( void* io_ringSection,
1742+ uint32_t i_maxRingSectionSize,
1743 RingId_t i_ringId,
1744- uint8_t i_instanceId,
1745+ uint8_t i_chipletId,
1746 void* i_rs4Ring, // Ptr to the RS4 ring container
1747 uint32_t i_dbgl = 0 );
1748
1749@@ -201,7 +159,8 @@ int dyn_get_ring( void* i_ringSection,
1750
1751 /// Append a single RS4 ring to the end of a Dynamic ring section (non-TOR layout).
1752 ///
1753-/// \param[in] i_ringSection A pointer to the Dynamic ring section.
1754+/// \param[in] io_ringSection A pointer to the Dynamic ring section.
1755+/// Note that caller manages buffer.
1756 ///
1757 /// \param[in] i_maxRingSectionSize Max size of i_ringSection.
1758 ///
1759--
17601.8.2.2
1761