/
sbe_update.C
4753 lines (4019 loc) · 196 KB
/
sbe_update.C
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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/sbe/sbe_update.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2013,2017 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
/* implied. See the License for the specific language governing */
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
#include <vector>
#include <trace/interface.H>
#include <vpd/mvpdenums.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
#include <errl/errlreasoncodes.H>
#include <targeting/common/predicates/predicatectm.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/target.H>
#include <util/align.H>
#include <util/crc32.H>
#include <util/misc.H>
#include <errno.h>
#include <pnor/pnorif.H>
#include <pnor/ecc.H>
#include <devicefw/driverif.H>
#include <sys/mm.h>
#include <sys/misc.h>
#include <sys/msg.h>
#include <hwas/common/deconfigGard.H>
#include <initservice/initserviceif.H>
#include <console/consoleif.H>
#include <config.h>
#include <sbe/sbeif.H>
#include <sbeio/sbeioif.H>
#include <sbe/sbereasoncodes.H>
#include "sbe_update.H"
#include "sbe_resolve_sides.H"
// fapi support
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
#include <fapi2/hwp_executor.H>
#include <fapi2/hw_access.H>
//Procedures
#include <p9_xip_customize.H>
#include <p9_xip_section_append.H>
#include <p9_xip_image.h>
#include <p9_perv_scom_addresses.H>
#include <initservice/mboxRegs.H>
// ----------------------------------------------
// Trace definitions
// ----------------------------------------------
trace_desc_t* g_trac_sbe = NULL;
TRAC_INIT( & g_trac_sbe, SBE_COMP_NAME, 4*KILOBYTE );
// ------------------------
// Macros for unit testing
//#define TRACUCOMP(args...) TRACFCOMP(args)
#define TRACUCOMP(args...)
// ----------------------------------------
// Global Variables for MBOX Ipl Query
static bool g_mbox_query_done = false;
static bool g_mbox_query_result = false;
static bool g_istep_mode = false;
static bool g_update_both_sides = false;
using namespace ERRORLOG;
using namespace TARGETING;
namespace SBE
{
errlHndl_t updateProcessorSbeSeeproms()
{
errlHndl_t err = NULL;
errlHndl_t err_cleanup = NULL;
sbeTargetState_t sbeState;
std::vector<sbeTargetState_t> sbeStates_vector;
bool l_cleanupVmmSpace = false;
bool l_restartNeeded = false;
TRACUCOMP( g_trac_sbe,
ENTER_MRK"updateProcessorSbeSeeproms()");
do{
#ifdef CONFIG_NO_SBE_UPDATES
TRACFCOMP( g_trac_sbe, INFO_MRK"updateProcessorSbeSeeproms() - "
"SBE updates not configured");
break;
#endif
#ifdef CONFIG_SBE_UPDATE_SEQUENTIAL
// Check if FSP-services are enabled and if we're running in simics
if ( !INITSERVICE::spBaseServicesEnabled() &&
!Util::isSimicsRunning() )
{
assert (false, "resolveProcessorSbeSeeproms() - "
"SBE_UPDATE_SEQUENTIAL mode, but FSP-services are not "
"enabled - Invalid Configuration");
}
// else - continue on
#endif
// Get Target Service, and the system target.
TargetService& tS = targetService();
TARGETING::Target* sys = NULL;
(void) tS.getTopLevelTarget( sys );
assert(sys, "updateProcessorSbeSeeproms() system target is NULL");
/*****************************************************************/
/* Skip Update if ATTR_SBE_UPDATE_DISABLE is set */
/*****************************************************************/
if ( sys->getAttr<ATTR_SBE_UPDATE_DISABLE>() ) // true => disable
{
TRACFCOMP( g_trac_sbe, INFO_MRK"SBE Update skipped due to "
"system attribute SBE_UPDATE_DISABLE being set");
break;
}
/*****************************************************************/
/* Skip Update if MNFG_FLAG_FSP_UPDATE_SBE_IMAGE is set */
/* AND there is a FSP present */
/*****************************************************************/
ATTR_MNFG_FLAGS_type mnfg_flags = sys->getAttr<ATTR_MNFG_FLAGS>();
if ( (mnfg_flags & MNFG_FLAG_FSP_UPDATE_SBE_IMAGE)
&& INITSERVICE::spBaseServicesEnabled() // true => FSP present
)
{
TRACFCOMP( g_trac_sbe, INFO_MRK"SBE Update skipped due to "
"FSP present and MNFG_FLAG_FSP_UPDATE_SBE_IMAGE "
"(0x%.16X) is set in MNFG Flags 0x%.16X",
MNFG_FLAG_FSP_UPDATE_SBE_IMAGE, mnfg_flags);
break;
}
// For a future check, determine if in istep mode and FSP is present
if ( sys->getAttr<ATTR_ISTEP_MODE>() && // true => istep mode
INITSERVICE::spBaseServicesEnabled() ) // true => FSP present
{
g_istep_mode = true;
}
if (mnfg_flags & MNFG_FLAG_UPDATE_BOTH_SIDES_OF_SBE)
{
TRACFCOMP(g_trac_sbe,
INFO_MRK"Update Both Sides of SBE Flag Indicated.");
bool l_isGoldenSide=true;
errlHndl_t l_err = isGoldenSide(l_isGoldenSide);
if(l_err)
{
TRACFCOMP(g_trac_sbe,
ERR_MRK"updateProcessorSbeSeeproms::isGoldenSide "
"returned an error, RC=0x%X, PLID=0x%lX",
ERRL_GETRC_SAFE(err),
ERRL_GETPLID_SAFE(err));
errlCommit( l_err, SBE_COMP_ID );
l_isGoldenSide = true;
}
if (l_isGoldenSide)
{
g_update_both_sides = false;
TRACFCOMP(g_trac_sbe,
INFO_MRK"Boot on Golden Side - Ignoring Update "
"both sides of SBE Flag");
}
else
{
g_update_both_sides = true;
}
}
//Make sure procedure constants keep within expected range.
assert((FIXED_SEEPROM_WORK_SPACE <= VMM_SBE_UPDATE_SIZE/2),
"updateProcessorSbeSeeproms() FIXED_SEEPROM_WORK_SPACE "
"too large");
assert((MAX_RING_BUF_SIZE <= VMM_SBE_UPDATE_SIZE/4),
"updateProcessorSbeSeeproms() MAX_RING_BUF_SIZE too "
"large");
// reset global variables for MBOX Ipl Query
g_mbox_query_done = false;
g_mbox_query_result = false;
// Create VMM space for p9_xip_customize() procedure
err = createSbeImageVmmSpace();
if (err)
{
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): "
"createSbeImageVmmSpace() Failed. ",
"rc=0x%.4X", err->reasonCode() );
break;
}
else
{
// Make sure cleanup gets called
l_cleanupVmmSpace = true;
}
/*****************************************************************/
/* Iterate over all the functional processors and do for each: */
/* 1) Check their SBE State (PNOR, MVPD, SEEPROMs, etc), */
/* 2) Determine the Necessary Update */
/* 3) Perform Update Action */
/*****************************************************************/
TARGETING::TargetHandleList procList;
TARGETING::getAllChips(procList,
TARGETING::TYPE_PROC,
true); // true: return functional targets
if( ( 0 == procList.size() ) ||
( NULL == procList[0] ) )
{
TRACFCOMP( g_trac_sbe, ERR_MRK"updateProcessorSbeSeeproms() - "
"No functional processors Found!" );
break;
}
// Get the Master Proc Chip Target for comparisons later
TARGETING::Target* masterProcChipTargetHandle = NULL;
err = tS.queryMasterProcChipTargetHandle(
masterProcChipTargetHandle);
if (err)
{
TRACFCOMP( g_trac_sbe, ERR_MRK"updateProcessorSbeSeeproms() - "
"queryMasterProcChipTargetHandle returned error. "
"Commit here and continue. Check below against "
"masterProcChipTargetHandle=NULL is ok, "
"RC=0x%X, PLID=0x%lX",
ERRL_GETRC_SAFE(err),
ERRL_GETPLID_SAFE(err));
errlCommit( err, SBE_COMP_ID );
err = NULL;
}
for(uint32_t i=0; i<procList.size(); i++)
{
/*********************************************/
/* Collect SBE Information for this Target */
/*********************************************/
memset(&sbeState, 0, sizeof(sbeState));
sbeState.target = procList[i];
TRACUCOMP( g_trac_sbe, "updateProcessorSbeSeeproms(): "
"Main Loop: tgt=0x%X, i=%d",
TARGETING::get_huid(sbeState.target), i);
// Check to see if current target is master processor
if ( sbeState.target == masterProcChipTargetHandle)
{
TRACUCOMP(g_trac_sbe,"sbeState.target=0x%X is MASTER. "
" (i=%d)",
TARGETING::get_huid(sbeState.target), i);
sbeState.target_is_master = true;
}
else
{
sbeState.target_is_master = false;
// If running in simics, don't do the update
if ( Util::isSimicsRunning() )
{
// Push this sbeState onto the vector
sbeStates_vector.push_back(sbeState);
break;
}
}
//Can only update the SBE once the powerbus is up (secureboot)
//Use the scom switch Xscom capability flag as a proxy for
//powerbus access. If we can't access via powerbus, then skip
TARGETING::ScomSwitches scomSetting =
sbeState.target->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
if(!(scomSetting.useXscom))
{
//Xscom is not viable on this chip, thus powerbus isn't
//up to chip -- skip it
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): "
"Power bus not established to chip 0x%X,"
" not performing update",
TARGETING::get_huid(sbeState.target));
continue;
}
err = getSbeInfoState(sbeState);
if (err)
{
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): "
"getSbeInfoState() Failed "
"rc=0x%.4X, Target UID=0x%X",
err->reasonCode(),
TARGETING::get_huid(sbeState.target));
// Don't break - handle error at the end of the loop
}
/**********************************************/
/* Determine update actions for this target */
/**********************************************/
// Skip if we got an error collecting SBE Info State
if ( err == NULL )
{
err = getTargetUpdateActions(sbeState);
if (err)
{
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): "
"getTargetUpdateActions() Failed "
"rc=0x%.4X, Target UID=0x%X",
err->reasonCode(),
TARGETING::get_huid(sbeState.target));
// Don't break - handle error at the end of the loop,
}
}
/**********************************************/
/* Perform Update Actions For This Target */
/**********************************************/
if ((err == NULL) && (sbeState.update_actions & DO_UPDATE))
{
err = performUpdateActions(sbeState);
if (err)
{
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): "
"performUpdateActions() Failed "
"rc=0x%.4X, Target UID=0x%X",
err->reasonCode(),
TARGETING::get_huid(sbeState.target));
// Don't break - handle error at the end of the loop,
}
else
{
// Target updated without failure, so set IPL_RESTART
// flag, if necessary
if (sbeState.update_actions & IPL_RESTART)
{
l_restartNeeded = true;
}
}
}
if ( err )
{
// Something failed for this target.
// Save error information
sbeState.err_plid = err->plid();
sbeState.err_eid = err->eid();
sbeState.err_rc = err->reasonCode();
// Commit the error here and move on to the next target,
// or if no targets left, will just continue the IPL
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): "
"Committing Error Log rc=0x%.4X eid=0x%.8X "
"plid=0x%.8X for Target UID=0x%X, but "
"continuing procedure",
sbeState.err_rc, sbeState.err_eid,
sbeState.err_plid,
TARGETING::get_huid(sbeState.target));
errlCommit( err, SBE_COMP_ID );
}
// Push this sbeState onto the vector
sbeStates_vector.push_back(sbeState);
} //end of Target for loop collecting each target's SBE State
/**************************************************************/
/* Perform System Operation */
/**************************************************************/
// Restart IPL if SBE Update requires it
if ( l_restartNeeded == true )
{
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): Restart "
"Needed (%d). Calling preReIplCheck()",
l_restartNeeded);
err = preReIplCheck(sbeStates_vector);
if ( err )
{
// Something failed on the check. Commit the error here
// and continue with the Re-IPL Request
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): "
"Committing Error Log rc=0x%.4X from "
"preReIplCheck(), but doing Re-IPL",
err->reasonCode());
errlCommit( err, SBE_COMP_ID );
}
#ifdef CONFIG_BMC_IPMI
err = sbePreRebootIpmiCalls();
if (err)
{
TRACFCOMP( g_trac_sbe,ERR_MRK"sbePreRebootIpmiCalls "
"failed");
break;
}
#endif
#ifdef CONFIG_CONSOLE
CONSOLE::displayf(SBE_COMP_NAME, "System Rebooting To "
"Perform SBE Update\n");
CONSOLE::flush();
#endif
#ifndef CONFIG_BMC_IPMI
// Sync all attributes to the FSP before doing the Shutdown
err = syncAllAttributesToFsp();
if( err )
{
// Something failed on the sync. Commit the error here
// and continue with the Re-IPL Request
TRACFCOMP( g_trac_sbe,
ERR_MRK"updateProcessorSbeSeeproms() - Error "
"syncing attributes to FSP, RC=0x%X, PLID=0x%lX",
ERRL_GETRC_SAFE(err),
ERRL_GETPLID_SAFE(err));
errlCommit( err, SBE_COMP_ID );
}
else
{
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms() - Sync "
"Attributes to FSP" );
}
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): Calling "
"INITSERVICE::doShutdown() with "
"SBE_UPDATE_REQUEST_REIPL = 0x%X",
SBE_UPDATE_REQUEST_REIPL );
INITSERVICE::doShutdown(SBE_UPDATE_REQUEST_REIPL);
#endif
}
/************************************************************/
/* Deconfigure any Processors that have a Version different */
/* from the Master Processor's Version */
/************************************************************/
err = masterVersionCompare(sbeStates_vector);
if ( err )
{
// Something failed on the check
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): Call to "
"masterVersionCompare() failed rc=0x%.4X",
err->reasonCode());
}
}while(0);
// Cleanup VMM Workspace
if ( l_cleanupVmmSpace == true )
{
err_cleanup = cleanupSbeImageVmmSpace();
if ( err_cleanup != NULL )
{
if ( err != NULL )
{
// 2 error logs, so commit the cleanup log here
TRACFCOMP( g_trac_sbe,
ERR_MRK"updateProcessorSbeSeeproms(): Previous "
"error (rc=0x%X) before cleanupSbeImageVmmSpace"
"() failed. Committing cleanup error (rc=0x%X) "
"and returning original error",
err->reasonCode(), err_cleanup->reasonCode() );
errlCommit( err_cleanup, SBE_COMP_ID );
}
else
{
// no previous error, so returning cleanup error
TRACFCOMP( g_trac_sbe,
ERR_MRK"updateProcessorSbeSeeproms(): "
"cleanupSbeImageVmmSpace() failed.",
"rc=0x%.4X", err_cleanup->reasonCode() );
err = err_cleanup;
}
}
}
TRACUCOMP( g_trac_sbe,
EXIT_MRK"updateProcessorSbeSeeproms()" );
return err;
}
/////////////////////////////////////////////////////////////////////
errlHndl_t findSBEInPnor(TARGETING::Target* i_target,
void*& o_imgPtr,
size_t& o_imgSize,
sbe_image_version_t* o_version)
{
errlHndl_t err = NULL;
PNOR::SectionInfo_t pnorInfo;
sbeToc_t* sbeToc = NULL;
uint8_t ec = 0;
PNOR::SectionId pnorSectionId = PNOR::INVALID_SECTION;
void* hdr_Ptr = NULL;
o_imgPtr = NULL;
o_imgSize = 0;
TRACDCOMP( g_trac_sbe,
ENTER_MRK"findSBEInPnor()" );
do{
// Get the correct PNOR Section Id
if ( i_target->getAttr<ATTR_TYPE>() == TYPE_PROC )
{
pnorSectionId = PNOR::SBE_IPL;
}
else if ( i_target->getAttr<ATTR_TYPE>() == TYPE_MEMBUF )
{
pnorSectionId = PNOR::CENTAUR_SBE;
}
else
{
// Unsupported target type was passed in
TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: Unsupported "
"target type was passed in: uid=0x%X, type=0x%X",
TARGETING::get_huid(i_target),
i_target->getAttr<ATTR_TYPE>());
/*@
* @errortype
* @moduleid SBE_FIND_IN_PNOR
* @reasoncode SBE_INVALID_INPUT
* @userdata1 Target Unit Id
* @userdata2 Target Type
* @devdesc Unsupported Target Type passed in
* @custdesc A problem occurred while updating processor
* boot code.
*/
err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
SBE_FIND_IN_PNOR,
SBE_INVALID_INPUT,
TARGETING::get_huid(i_target),
i_target->getAttr<ATTR_TYPE>());
err->collectTrace(SBE_COMP_NAME);
err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_HIGH );
break;
}
// Get SBE PNOR section info from PNOR RP
err = getSectionInfo( pnorSectionId,
pnorInfo );
if(err)
{
TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: Error calling "
"getSectionInfo() rc=0x%.4X",
err->reasonCode() );
break;
}
TRACUCOMP( g_trac_sbe,
INFO_MRK"findSBEInPnor: UID=0x%X, sectionId=0x%X. "
"pnor vaddr = 0x%.16X",
TARGETING::get_huid(i_target),
pnorSectionId, pnorInfo.vaddr);
sbeToc = reinterpret_cast<sbeToc_t*>( pnorInfo.vaddr );
if (sbeToc->eyeCatch != SBETOC_EYECATCH)
{
//The SBE partition does not have the proper eyecatcher
TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: SBE partition "
"does not have the proper eyecatcher: was: 0x%X, "
"should be: 0x%X",
sbeToc->eyeCatch, SBETOC_EYECATCH );
TRACFBIN( g_trac_sbe, "sbeToc", sbeToc, sizeof(sbeToc_t));
/*@
* @errortype
* @moduleid SBE_FIND_IN_PNOR
* @reasoncode SBE_INVALID_EYECATCHER
* @userdata1 SBE TOC EYE-CATCHER
* @userdata2 Expected EYE-CATCHER
* @devdesc Unsupported EYE-CATCHER found in TOC
* @custdesc A problem occurred while updating processor
* boot code.
*/
err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
SBE_FIND_IN_PNOR,
SBE_INVALID_EYECATCHER,
sbeToc->eyeCatch,
SBETOC_EYECATCH);
err->collectTrace(SBE_COMP_NAME);
err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE,
HWAS::SRCI_PRIORITY_HIGH );
break;
}
else
{
//Check the TOC Version
if( SUPPORTED_TOC_VER != sbeToc->tocVersion)
{
TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: Unsupported "
"SBE TOC Version in SBE Partition" );
TRACFBIN( g_trac_sbe, "sbeToc", sbeToc, sizeof(sbeToc_t));
/*@
* @errortype
* @moduleid SBE_FIND_IN_PNOR
* @reasoncode SBE_UNSUPPORTED_TOC
* @userdata1[0:31] CHIP EC
* @userdata1[32:63] Expected TOC Version
* @userdata2[0:31] SBE TOC Version
* @userdata2[32:63] SBE TOC EyeCatch
* @devdesc SBE partition contains unsupported version
* of Table of Contents
* @custdesc A problem occurred while updating processor
* boot code.
*/
err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
SBE_FIND_IN_PNOR,
SBE_UNSUPPORTED_TOC,
TWO_UINT32_TO_UINT64(ec,
SUPPORTED_TOC_VER),
TWO_UINT32_TO_UINT64(sbeToc->tocVersion,
sbeToc->eyeCatch));
err->collectTrace(SBE_COMP_NAME);
err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE,
HWAS::SRCI_PRIORITY_HIGH );
break;
}
//Walk the TOC and find our current EC
ec = i_target->getAttr<TARGETING::ATTR_EC>();
for(uint32_t i=0; i<MAX_SBE_ENTRIES; i++)
{
if(static_cast<uint32_t>(ec) == sbeToc->entries[i].ec)
{
// EC found in TOC
uint64_t offset = pnorInfo.vaddr
+ static_cast<uint64_t>(sbeToc->entries[i].offset);
hdr_Ptr = reinterpret_cast<void*>( offset );
o_imgSize = sbeToc->entries[i].size;
TRACUCOMP( g_trac_sbe, INFO_MRK"findSBEInPnor: Found "
"EC Image: ec=0x%.2X offset=0x%.16X, i=%d "
"size=0x%X",
ec, offset, i, o_imgSize );
break;
}
}
}
if(NULL == hdr_Ptr)
{
//if we get here, it's an error
TRACFCOMP( g_trac_sbe,ERR_MRK"findSBEInPnor:SBE Image not "
"located, ec=0x%.2X",ec );
TRACFBIN( g_trac_sbe, "sbeToc", sbeToc, sizeof(sbeToc_t));
/*@
* @errortype
* @moduleid SBE_FIND_IN_PNOR
* @reasoncode SBE_EC_NOT_FOUND
* @userdata1[0:31] CHIP EC
* @userdata1[32:63] PNOR Section ID
* @userdata2[0:31] SBE TOC Version
* @userdata2[32:63] SBE TOC EyeCatch
* @devdesc SBE image for current chip EC was not found
* in PNOR
* @custdesc A problem occurred while updating processor
* boot code.
*/
err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
SBE_FIND_IN_PNOR,
SBE_EC_NOT_FOUND,
TWO_UINT32_TO_UINT64(ec,
pnorSectionId),
TWO_UINT32_TO_UINT64(sbeToc->tocVersion,
sbeToc->eyeCatch));
err->collectTrace(SBE_COMP_NAME);
err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE,
HWAS::SRCI_PRIORITY_HIGH );
break;
}
// The SBE Image for the corresponding EC was found, check if
// it includes a SBE Header
if (pnorInfo.sha512perEC)
{
TRACFCOMP(g_trac_sbe,INFO_MRK"findSBEInPnor: sha512perEC "
"Found in %s", pnorInfo.name);
// Advance PNOR pointer 4k to move it past header page to the
// start of the non-customized SBE image
o_imgPtr = reinterpret_cast<void*>
(reinterpret_cast<char*>(hdr_Ptr)+0x1000);
}
if(NULL != o_version)
{
err = readPNORVersion(hdr_Ptr,
*o_version);
if(err)
{
break;
}
}
}while(0);
TRACDCOMP( g_trac_sbe,
EXIT_MRK"findSBEInPnor(): o_imgPtr=%p, o_imgSize=0x%X",
o_imgPtr, o_imgSize );
return err;
}
/////////////////////////////////////////////////////////////////////
errlHndl_t findHBBLInPnor(void*& o_imgPtr,
size_t& o_imgSize)
{
errlHndl_t err = NULL;
PNOR::SectionInfo_t pnorInfo;
hbblEndData_t* hbblEndData = NULL;
PNOR::SectionId pnorSectionId = PNOR::HB_BOOTLOADER;
o_imgPtr = NULL;
o_imgSize = 0;
TRACDCOMP( g_trac_sbe,
ENTER_MRK"findHBBLInPnor()" );
do{
// Get SBE PNOR section info from PNOR RP
err = getSectionInfo( pnorSectionId,
pnorInfo );
if(err)
{
TRACFCOMP( g_trac_sbe, ERR_MRK"findHBBLInPnor: Error calling "
"getSectionInfo() rc=0x%.4X",
err->reasonCode() );
break;
}
TRACUCOMP( g_trac_sbe,
INFO_MRK"findHBBLInPnor: sectionId=0x%X. "
"pnor vaddr = 0x%.16X",
pnorSectionId, pnorInfo.vaddr);
// Look for HBBL end data on 16-byte boundary start at offset
// HBBL_FUZZY_END_ADDRESS
// Note: Code takes up at least the first HBBL_FUZZY_END_ADDRESS
// bytes of the HBBL image, so start at that offset to search
// for this data.
uint64_t hbblAbsoluteEnd = pnorInfo.vaddr + pnorInfo.size;
uint64_t hbblAddr = pnorInfo.vaddr + HBBL_FUZZY_END_ADDRESS;
while( hbblAddr < hbblAbsoluteEnd )
{
hbblEndData = reinterpret_cast<hbblEndData_t*>(hbblAddr);
if( HBBL_END_EYECATCHER == hbblEndData->eyecatcher )
{
TRACUCOMP( g_trac_sbe,
INFO_MRK"findHBBLInPnor: hbblEndData = %p, "
"hbblEndData.address = 0x%.16X",
hbblEndData, hbblEndData->address);
break;
}
hbblAddr += sizeof(hbblEndData_t);
}
if( hbblAddr >= hbblAbsoluteEnd )
{
//The HBBL partition does not have the HBBL end data
TRACFCOMP( g_trac_sbe, ERR_MRK"findHBBLInPnor: HBBL partition "
"does not have the HBBL end data" );
/*@
* @errortype
* @moduleid HBBL_FIND_IN_PNOR
* @reasoncode HBBL_END_DATA_NOT_FOUND
* @userdata1 HBBL PNOR Section Address
* @userdata2 HBBL PNOR Section Size
* @devdesc HBBL partition did not have end data
* @custdesc A problem occurred while updating processor
* boot code.
*/
err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
HBBL_FIND_IN_PNOR,
HBBL_END_DATA_NOT_FOUND,
pnorInfo.vaddr,
pnorInfo.size);
err->collectTrace(SBE_COMP_NAME);
err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE,
HWAS::SRCI_PRIORITY_HIGH );
break;
}
o_imgPtr = reinterpret_cast<void*>( pnorInfo.vaddr );
o_imgSize = hbblEndData->address - HBBL_START_ADDRESS;
}while(0);
TRACDCOMP( g_trac_sbe,
EXIT_MRK"findHBBLInPnor(): o_imgPtr=%p, o_imgSize=0x%X",
o_imgPtr, o_imgSize );
return err;
}
/////////////////////////////////////////////////////////////////////
errlHndl_t appendHbblToSbe(void* i_section,
uint32_t i_section_size,
void* i_image,
uint32_t& io_image_size)
{
errlHndl_t err = NULL;
P9XipItem l_xipItem;
TRACFCOMP( g_trac_sbe,
ENTER_MRK"appendHbblToSbe(): i_section=%p, "
"i_section_size=0x%X, i_image=%p, "
"io_image_size=0x%X",
i_section, i_section_size,
i_image, io_image_size);
do{
// Call p9_xip_find to find HBBL image in SBE image
const char* l_sectionId = ".hbbl";
// Note - this is not a fapi2 function
int xip_rc = p9_xip_find( i_image, l_sectionId, &l_xipItem );
// Check the return code
if( xip_rc == P9_XIP_ITEM_NOT_FOUND )
{
TRACUCOMP( g_trac_sbe, "appendHbblToSbe(): "
"p9_xip_find received expected return code, item "
"not found, rc=0x%X",
xip_rc );
}
else if( xip_rc == P9_XIP_DATA_NOT_PRESENT )
{
TRACFCOMP( g_trac_sbe, "appendHbblToSbe(): "
"p9_xip_find located %s, rc=0x%X",
xip_rc ? "TOC only" : "TOC and section data",
xip_rc );
// Call p9_xip_delete_section to delete existing HBBL image
// from SBE image
void *l_imageBuf = malloc(io_image_size);
xip_rc = p9_xip_delete_section(
i_image,
l_imageBuf,
io_image_size,
P9_XIP_SECTION_SBE_HBBL );
free(l_imageBuf);
// Check for error
if( xip_rc )
{
TRACFCOMP( g_trac_sbe, "appendHbblToSbe(): "
"p9_xip_delete_section failed, rc=0x%X",
xip_rc );
/*@
* @errortype
* @moduleid SBE_APPEND_HBBL
* @reasoncode ERROR_FROM_XIP_DELETE
* @userdata1 rc from p9_xip_delete
* @userdata2 <unused>
* @devdesc Bad RC from p9_xip_delete
* @custdesc A problem occurred while updating processor
* boot code.
*/
err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
SBE_APPEND_HBBL,
ERROR_FROM_XIP_DELETE,
xip_rc,
0,
true /* SW error */);
err->collectTrace(SBE_COMP_NAME);
// exit loop
break;
}
}
else
{
TRACFCOMP( g_trac_sbe, "appendHbblToSbe(): p9_xip_find "
"received unexpected return code, rc=0x%X",
xip_rc );
/*@
* @errortype
* @moduleid SBE_APPEND_HBBL
* @reasoncode ERROR_FROM_XIP_FIND
* @userdata1 rc from p9_xip_find
* @userdata2 <unused>
* @devdesc Bad RC from p9_xip_find
* @custdesc A problem occurred while updating processor
* boot code.
*/
err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
SBE_APPEND_HBBL,
ERROR_FROM_XIP_FIND,
xip_rc,
0,
true /* SW error */);
err->collectTrace(SBE_COMP_NAME);
err->collectTrace(FAPI_IMP_TRACE_NAME,256);
err->collectTrace(FAPI_TRACE_NAME,384);
// exit loop
break;
}
// Invoke p9_xip_section_append to append HBBL image to SBE image
FAPI_INVOKE_HWP( err,
p9_xip_section_append,
i_section,
i_section_size,
P9_XIP_SECTION_SBE_HBBL,
i_image,
io_image_size );
// Check for error
if(err)
{
TRACFCOMP( g_trac_sbe, "appendHbblToSbe(): "
"p9_xip_section_append failed, rc=0x%X",
err->reasonCode() );
// exit loop
break;
}
}while(0);
TRACUCOMP( g_trac_sbe,