summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/sbe_centaur_init/cen_xip_customize.C
blob: b51f0e4be43117581d991d522bedf6191275d70b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/hwpf/hwp/sbe_centaur_init/cen_xip_customize.C $       */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2013,2014              */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// $Id: cen_xip_customize.C,v 1.12 2013/12/03 05:46:24 cmolsen Exp $
/*------------------------------------------------------------------------------*/
/* *! TITLE : cen_xip_customize.C                                               */
/* *! DESCRIPTION : Customizes Centaur images from a Centaur reference image.   */
/* *! OWNER NAME : Michael Olsen                  cmolsen@us.ibm.com            */
//
/* *! EXTENDED DESCRIPTION :                                                    */
//
/* *! USAGE : 
              To build (for Hostboot) -
              buildfapiprcd   -c "sbe_xip_image.c,pore_inline_assembler.c,p8_ring_identification.c"   -C "p8_image_help.C,p8_image_help_base.C,p8_pore_table_gen_api_fixed.C,p8_scan_compression.C"   -e "../../xml/error_info/cen_xip_customize_errors.xml,../../xml/error_info/proc_sbe_decompress_scan_halt_codes.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml"   cen_xip_customize.C                                               */
//
/* *! ASSUMPTIONS :                                                             */
//
/* *! COMMENTS :                                                                */
//
/*------------------------------------------------------------------------------*/
#define __CEN_XIP_CUSTOMIZE_C
#include <cen_xip_customize.H>
#include <p8_delta_scan_rw.h>
#include <p8_pore_table_gen_api.H>

extern "C"  {

using namespace fapi;

//  Parameter list:
//  const fapi::Target &i_target:  Processor chip target.
//  void      *i_imageIn:      Ptr to input image.
//  void      *i_imageOut:     Ptr to output img.
//  uint32_t  io_sizeImageOut: In: Max size of img. Out: Final size.
//  void      *i_buf1:         Temp buffer 1 for dexed RS4 ring. Caller allocs/frees.
//  uint32_t  i_sizeBuf1:      Size of buf1.
//  void      *i_buf2:         Temp buffer 2 for WF ring. Caller allocs/frees.
//  uint32_t  i_sizeBuf22      Size of buf2.
//
ReturnCode cen_xip_customize(const fapi::Target &i_target,
                             void            *i_imageIn,
                             void            *i_imageOut,
                             uint32_t        &io_sizeImageOut,
                             void            *i_buf1,
                             const uint32_t  i_sizeBuf1,
                             void            *i_buf2,
                             const uint32_t  i_sizeBuf2 )
{
  fapi::ReturnCode rc;
  uint32_t  rcLoc=0;
  uint32_t  sizeImage, sizeImageIn, sizeImageOutMax;

  sizeImageOutMax = io_sizeImageOut;
  
  // ==========================================================================
  // Check and copy input image.
  // ==========================================================================
  //
  // First, check supplied size and validation of input image.
  //
  sbe_xip_image_size(i_imageIn, &sizeImageIn);
  rcLoc = sbe_xip_validate(i_imageIn, sizeImageIn);
  if (rcLoc)  {
    FAPI_ERR("xip_validate() failed w/rcLoc=%i",rcLoc);
    uint32_t & RC_LOCAL = rcLoc;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_UNSPECIFIED_IMAGE_ERR);
    return rc;
  }
  
  // Second, copy input image to supplied output image location.
  //    
  memcpy( i_imageOut, i_imageIn, sizeImageIn);
  sbe_xip_image_size(i_imageOut, &sizeImage);
  rcLoc = sbe_xip_validate(i_imageOut, sizeImage);
  if (rcLoc)  {
    FAPI_ERR("xip_validate() failed w/rcLoc=%i",rcLoc);
    uint32_t & RC_LOCAL=rcLoc;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_UNSPECIFIED_IMAGE_ERR);
    return rc;
  }
  if (sizeImage!=sizeImageIn)  {
    FAPI_ERR("Size obtained from image's header (=%i) differs from supplied size (=%i).",
      sizeImage,sizeImageIn);
    uint32_t & DATA_IMG_SIZE_INP = sizeImageIn;
    uint32_t & DATA_IMG_SIZE = sizeImage;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_IMAGE_SIZE_MISMATCH);
    return rc;
  }
  FAPI_DBG("Input image (w/location=0x%016llx) copied to output image and validated w/size=%i bytes and location=0x%016llx",
    (uint64_t)i_imageIn, sizeImageIn, (uint64_t)i_imageOut);

  // --------------------------------------------------------------------------
  // CUSTOMIZE item:    Update PLL ring (tp_pll_bndy_ring_alt).
  // Retrieval method:  Attribute.
  // --------------------------------------------------------------------------
  uint32_t  tmp32Const1, tmp32Const2;
  uint8_t   attrRingFlush[MAX_CEN_PLL_RING_SIZE]={0};
  uint8_t   attrRingData[MAX_CEN_PLL_RING_SIZE]={0};
  uint8_t   attrChipletId=0xff;
  uint32_t  attrScanSelect=0;
  uint32_t  attrRingDataSize=0; // Ring bit size
  uint32_t  sizeDeltaPllRingAlt=0;
  uint8_t   *bufDeltaPllRingAlt;
  uint64_t  scanMaxRotate=SCAN_ROTATE_DEFAULT;
  uint32_t  *wfInline=NULL;
  uint32_t  wfInlineLenInWords;
  uint32_t  bufLC=0;

  //
  // Retrieve the raw PLL rings state from attributes.
  //
  FAPI_INF("PLL update: Retrieve the raw PLL ring state from attributes.");
  // Get ring size.
  rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_LENGTH, &i_target, attrRingDataSize); // This better be in bits.
  if (rc)  {
    FAPI_ERR("FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_LENGTH) returned error.");
    return rc;
  }
  FAPI_DBG("PLL update: PLL ring length (bits) = %i",attrRingDataSize);
  FAPI_DBG("PLL update: Size of buf1, i_sizeBuf1 (bytes) = %i",i_sizeBuf1);
  if (attrRingDataSize>MAX_CEN_PLL_RING_SIZE*8 || attrRingDataSize>i_sizeBuf1*8)  {
    FAPI_ERR("FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_LENGTH) returned ring size =%i bits.\n",
              attrRingDataSize);
    FAPI_ERR("But that exceeds either:\n");
    FAPI_ERR("  the max pll ring size =%i bits, or\n",MAX_CEN_PLL_RING_SIZE*8);
    FAPI_ERR("  the size of the pre-allocated buf1 =%i bits.", i_sizeBuf1*8);
    uint32_t &DATA_ATTRIBUTE_RING_SIZE=attrRingDataSize;
    tmp32Const1=8*MAX_CEN_PLL_RING_SIZE;
    tmp32Const2=8*(uint32_t)i_sizeBuf1;
    uint32_t &DATA_MAX_PLL_RING_SIZE=tmp32Const1;
    uint32_t &DATA_SIZE_OF_BUF1=tmp32Const2;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_PLL_RING_SIZE_TOO_LARGE);
    return rc;
  }
  sizeDeltaPllRingAlt = attrRingDataSize; // We've already checked it'll fit into buf1.
  // Get flush and alter (desired) ring state data.
  rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_FLUSH, &i_target, attrRingFlush);
  if (rc)  {
    FAPI_ERR("FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_FLUSH) returned error.");
    return rc;
  }
  rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_DATA, &i_target, attrRingData);
  if (rc)  {
    FAPI_ERR("FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_DATA) returned error.");
    return rc;
  }
  rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_SCAN_SELECT, &i_target, attrScanSelect);
  if (rc)  {
    FAPI_ERR("FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_SCAN_SELECT) returned error.");
    return rc;
  }
/*
  rc = FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_CHIPLET_ID, &i_target, attrChipletId);
  if (rc)  {
    FAPI_ERR("FAPI_ATTR_GET(ATTR_MEMB_TP_BNDY_PLL_CHIPLET_ID) returned error.");
    return rc;
  }
*/

  //
  // Calculate the delta scan ring.
  //
  FAPI_INF("PLL update: Calculate the delta scan ring.");
  bufDeltaPllRingAlt = (uint8_t*)i_buf1;
  rcLoc = calc_ring_delta_state( (uint32_t*)attrRingFlush,
                                  (uint32_t*)attrRingData,
                                  (uint32_t*)bufDeltaPllRingAlt, // Pre-allocated buffer.
                                  sizeDeltaPllRingAlt );
  if (rcLoc)  {
    FAPI_ERR("calc_ring_delta_state() returned error w/rcLoc=%i",rcLoc);
    FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code.");
    uint32_t &RC_LOCAL=rcLoc;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_IMGBUILD_ERROR);
    return rc;
  }

  //
	// Create wiggle-flip (WF) program.
	//
  //scanMaxRotate = SCAN_MAX_ROTATE; // Max out on rotate length. P8 PLL running.
  scanMaxRotate = SCAN_ROTATE_DEFAULT; // Max out on rotate length. P8 PLL running.
/*
  rcLoc = sbe_xip_get_scalar( i_imageOut, SCAN_MAX_ROTATE_38XXX_NAME, &scanMaxRotate);
	if (rcLoc)  {
	  FAPI_ERR("Strange error from sbe_xip_get_scalar(SCAN_MAX_ROTATE_38XXX_NAME) w/rcLoc=%i; ",rcLoc);
	  FAPI_ERR("Already retrieved SCAN_MAX_ROTATE_38XXX_NAME in slw_build() w/o trouble; ");
	  uint32_t &RC_LOCAL=rcLoc;
	  FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_UNSPECIFIED_IMAGE_ERR);
	  return rc;
	}
	if (scanMaxRotate<0x20 || scanMaxRotate>SCAN_MAX_ROTATE)  {
	  FAPI_INF("WARNING: Value of key word SCAN_MAX_ROTATE_38XXX_NAME=0x%llx is not permitted; ",scanMaxRotate);
    scanMaxRotate = SCAN_ROTATE_DEFAULT;
		FAPI_INF("scanMaxRotate set to 0x%llx; ", scanMaxRotate);
		FAPI_INF("Continuing...; ");
	}
*/
	wfInline = (uint32_t*)i_buf2;  // Use HB buf2 for wiggle-flip prg.
	wfInlineLenInWords = i_sizeBuf2/4;
	rcLoc = create_wiggle_flip_prg((uint32_t*)bufDeltaPllRingAlt,
	                            sizeDeltaPllRingAlt,
	                            attrScanSelect, //=0x00100008,  // addr=0x00030088 ?
	                            attrChipletId, //=0xff,
	                            &wfInline,
	                            &wfInlineLenInWords, // Is 8-byte aligned on return.
                              1,  // Always do flush optimization.
	                            (uint32_t)scanMaxRotate,
                              0,  // No need to use waits for Centaur.
                              0x00000010); // Centaur doesn't support scan polling.
	if (rcLoc)  {
	  FAPI_ERR("create_wiggle_flip_prg() failed w/rcLoc=%i",rcLoc);
	  uint32_t &RC_LOCAL=rcLoc;
	  FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_IMGBUILD_ERROR);
	  return rc;
	}

  //
  // Populate ring header and put ring header and Wf ring into 
  // proper spots in pre-allocated bufWfRingBlock buffer (HB buf1).
  //
  DeltaRingLayout *bufWfRingBlock;
  uint64_t entryOffsetWfRingBlock;
  uint32_t sizeWfRingBlock, sizeWfRingBlockMax;

  bufWfRingBlock = (DeltaRingLayout*)i_buf1; // Reuse HB buf1 for WF ring block.
  sizeWfRingBlockMax = i_sizeBuf1;
  entryOffsetWfRingBlock      = calc_ring_layout_entry_offset( 1, 0);
  bufWfRingBlock->entryOffset = myRev64(entryOffsetWfRingBlock);
  bufWfRingBlock->backItemPtr	= 0; // Will be updated below, as we don't know yet.
	sizeWfRingBlock     	      =	entryOffsetWfRingBlock +  // Must be 8-byte aligned.
  												      wfInlineLenInWords*4;     // Must be 8-byte aligned.
	// Quick check to see if final ring block size will fit in HB buffer.
	if (sizeWfRingBlock>sizeWfRingBlockMax)  {
    FAPI_ERR("WF PLL _alt ring block size (=%i) exceeds pre-allocated buf1 size (=%i).",
      sizeWfRingBlock, sizeWfRingBlockMax);
    uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeWfRingBlock;
    uint32_t &DATA_SIZE_OF_BUF1=sizeWfRingBlock;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_PLL_RING_BLOCK_TOO_LARGE);
    return rc;
	}
	bufWfRingBlock->sizeOfThis  = myRev32(sizeWfRingBlock);
	bufWfRingBlock->sizeOfMeta	=	0;
	bufLC = (uint32_t)entryOffsetWfRingBlock;
	// Copy over meta data which is zero, so nothing to do in this case!
	// Copy over WF ring prg which is already 8-byte aligned.
	memcpy( (uint8_t*)bufWfRingBlock+bufLC, wfInline, (size_t)wfInlineLenInWords*4);

  // Now, some post-sanity checks on alignments.
	if ( entryOffsetWfRingBlock%8 || 
	     sizeWfRingBlock%8)  {
		FAPI_ERR("Member(s) of WF ring block are not 8-byte aligned:");
    FAPI_ERR("  Entry offset            = %i", (uint32_t)entryOffsetWfRingBlock);
		FAPI_ERR("  Size of ring block      = %i", sizeWfRingBlock);
    tmp32Const1=(uint32_t)entryOffsetWfRingBlock;
    uint32_t &DATA_RING_BLOCK_ENTRYOFFSET=tmp32Const1;
    uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeWfRingBlock;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_RING_BLOCK_ALIGN_ERROR);
    return rc;
	}

  //
  // Append PLL _alt ring to image.
  //
  FAPI_INF("PLL update: Appending WF PLL ring block to .rings section.");
  rcLoc = write_ring_block_to_image( i_imageOut,
                                     TP_PLL_BNDY_RING_ALT_TOC_NAME,
                                     bufWfRingBlock,
                                     0,
                                     0,
                                     0,
                                     sizeImageOutMax,
                                     SBE_XIP_SECTION_RINGS,
                                     i_buf2,      // Use buf2 as temp buf.
                                     i_sizeBuf2 );
  if (rcLoc)  {
    FAPI_ERR("write_ring_block_to_image() failed w/rc=%i",rcLoc);
    FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code.");
    uint32_t &RC_LOCAL=rcLoc;
    FAPI_SET_HWP_ERROR(rc, RC_CEN_XIPC_IMGBUILD_ERROR);
    return rc;
  }

  sbe_xip_image_size( i_imageOut, &io_sizeImageOut);
  
  return rc;
  
}


} // End of extern C
OpenPOWER on IntegriCloud