blob: e014d7da728c8e9e16908613c47f78624fef82b8 [file] [log] [blame]
Nick Bofferdingf390b6f2019-10-08 11:55:42 -05001From c69095d5359b800068c258819014f0bb684046f6 Mon Sep 17 00:00:00 2001
2From: Roland Veloz <rveloz@us.ibm.com>
3Date: Fri, 6 Sep 2019 13:52:32 -0500
4Subject: [PATCH] P10 MRW parsing: Changes to the parser scripts
5
6This commit deals with refactoring and modularizing the processMrw.pl
7and Targets.pm scripts. This commit is not about the artifact that
8gets produced by these files but the act of parsing an MRW file.
9
10Change-Id: I359afeebd9aa00ec6db2857a03ba0d9684c0858e
11RTC: 215164
12---
13 src/usr/targeting/common/Targets.pm | 637 +++++++++++------
14 src/usr/targeting/common/processMrw.pl | 1183 +++++++++++++++++++++-----------
15 2 files changed, 1218 insertions(+), 602 deletions(-)
16
17diff --git a/src/usr/targeting/common/Targets.pm b/src/usr/targeting/common/Targets.pm
18index dfd65d6..fb0bcbb 100644
19--- a/src/usr/targeting/common/Targets.pm
20+++ b/src/usr/targeting/common/Targets.pm
21@@ -91,10 +91,29 @@ my %maxInstance = (
22 "SMPGROUP" => 8,
23 "OMIC" => 6,
24 );
25+
26+#--------------------------------------------------
27+# @brief The constructor for the object Target
28+#--------------------------------------------------
29 sub new
30 {
31 my $class = shift;
32 my $self = {
33+ # The following data are associated with the
34+ # user command line options
35+ build => "hb", # default to HB
36+ force => 0,
37+ serverwiz_file => "", # input xml file
38+ serverwiz_dir => "", # directory of input xml file
39+ debug => 0,
40+ system_config => "",
41+ output_file => "",
42+ version => 0,
43+ report => 0,
44+ run_self_test => 0, # run internal test
45+
46+ # The following data are associated with the
47+ # xml itself
48 xml => undef,
49 data => undef,
50 targeting => undef,
51@@ -103,13 +122,11 @@ sub new
52 UNIT_COUNTS => undef,
53 huid_idx => undef,
54 mru_idx => undef,
55- force => 0,
56- debug => 0,
57- version => "",
58 xml_version => 0,
59 errorsExist => 0,
60 NUM_PROCS => 0,
61 TOP_LEVEL => "",
62+ TOP_LEVEL_HANDLE => undef,
63 TOPOLOGY => undef,
64 report_log => "",
65 vpd_num => 0,
66@@ -388,6 +405,162 @@ sub storeGroups
67 }
68 }
69
70+#--------------------------------------------------
71+# @brief Initialize a handle to the target instance.
72+#
73+# @details This method locates where the target instance
74+# resides and caches it for fast retrieval.
75+#
76+# @post A handle to the target instance is cached or exit
77+# stating that the target instance cannot be found.
78+#
79+# @param [in] $self - The global target object.
80+#--------------------------------------------------
81+sub initializeTargetInstanceHandle
82+{
83+ my $self = shift;
84+
85+ if ( (!defined $self->{TARGET_INST_HANDLE}) ||
86+ ($self->{TARGET_INST_HANDLE} eq "") )
87+ {
88+ # Find the location of where target instances reside
89+ my $targetInstances = $self->{xml}->{'targetInstance'};
90+ if (!defined $targetInstances)
91+ {
92+ # Check one more level for the target instances
93+ $targetInstances = $self->{xml}->{'targetInstances'}
94+ ->{'targetInstance'};
95+ }
96+
97+ # If can't find the target instances, then state so and exit
98+ if (!defined $targetInstances)
99+ {
100+ die "No target instances defined\n";
101+ }
102+
103+ $self->setTargetInstanceHandle($targetInstances);
104+ } # end if ( (!defined $self->{TARGET_INST_HANDLE}) || ...
105+}
106+
107+#--------------------------------------------------
108+# @brief Return a handle to the target instances.
109+#
110+# @details This method will initialize the target instances
111+# if has not been already initialized.
112+#
113+# @param [in] $self - The global target object.
114+#
115+# @return - A handle to the target instance.
116+#--------------------------------------------------
117+sub getTargetInstanceHandle
118+{
119+ my $self = shift;
120+
121+ # If handle to target instances is not already cached, then initialize it
122+ if ( (!defined $self->{TARGET_INST_HANDLE}) ||
123+ ($self->{TARGET_INST_HANDLE} eq "") )
124+ {
125+ $self->initializeTargetInstanceHandle();
126+ }
127+
128+ return ($self->{TARGET_INST_HANDLE});
129+}
130+
131+#--------------------------------------------------
132+# @brief Set the target instance handle to the given target handle
133+#
134+# @param [in] $self - The global target object.
135+# @param [in] $targetHndl - The value the target instance handle is set to.
136+#--------------------------------------------------
137+sub setTargetInstanceHandle
138+{
139+ my $self = shift;
140+ my $targetHndl = shift;
141+
142+ # Dynamically create and cache a handle to the target instance
143+ $self->{TARGET_INST_HANDLE} = $targetHndl;
144+}
145+
146+#--------------------------------------------------
147+# @brief Initialize the top level target.
148+#
149+# @details This method locate the top level target
150+# and cache it for fast retrieval.
151+#
152+# @post The top level target is cached or exit stating that
153+# top level target not found.
154+#
155+# @param [in] $self - The global target object.
156+#--------------------------------------------------
157+sub initalizeTopLevel
158+{
159+ my $self = shift;
160+
161+ # If the top level target instance has not been found and set,
162+ # then find that target and set top level to it
163+ if ((!defined $self->{TOP_LEVEL}) || ($self->{TOP_LEVEL} eq ""))
164+ {
165+ # Get a handle to the target instances
166+ my $targetInstancesHandle = $self->getTargetInstanceHandle();
167+
168+ # Find the system target which is the top level target
169+ foreach my $target (keys(%{$targetInstancesHandle}))
170+ {
171+ # If target is of type 'SYS' then we found the top level target
172+ if ($targetInstancesHandle->{$target}->{attribute}
173+ ->{TYPE}->{default} eq "SYS")
174+ {
175+ # Set the top level target and search no more
176+ $self->setTopLevel($target);
177+ # YOU SHALL NOT PASS!!!
178+ last;
179+ }
180+ }
181+
182+ # If unable to find top level target, then state so and exit
183+ if ((!defined $self->{TOP_LEVEL}) || ($self->{TOP_LEVEL} eq ""))
184+ {
185+ die "Unable to find system top level target\n";
186+ }
187+ } # end if ((!defined $self->{TOP_LEVEL}) || ($self->{TOP_LEVEL} eq ""))
188+}
189+
190+#--------------------------------------------------
191+# @brief Return the top level target.
192+#
193+# @details This method will initialize the top level
194+# target if has not been already initialized.
195+#
196+# @param [in] $self - The global target object.
197+#
198+# @return - The top level target.
199+#--------------------------------------------------
200+sub getTopLevel
201+{
202+ my $self = shift;
203+
204+ # If the top level target is not already cached, then initialize it
205+ if ((!defined $self->{TOP_LEVEL}) || ($self->{TOP_LEVEL} eq ""))
206+ {
207+ $self->initalizeTopLevel();
208+ }
209+ return ($self->{TOP_LEVEL});
210+}
211+
212+#--------------------------------------------------
213+# @brief Set the top level target to the given target.
214+#
215+# @param [in] $self - The global target object.
216+# @param [in] $target - The value the top level target is set to.
217+#--------------------------------------------------
218+sub setTopLevel
219+{
220+ my $self = shift;
221+ my $target = shift;
222+
223+ $self->{TOP_LEVEL} = $target;
224+}
225+
226 ####################################################
227 ## build target hierarchy recursively
228 ##
229@@ -422,34 +595,23 @@ sub buildHierarchy
230 my $self = shift;
231 my $target = shift;
232
233- my $instance_path = $self->{data}->{INSTANCE_PATH};
234- if (!defined $instance_path)
235- {
236- $instance_path = "";
237- }
238- my $baseptr = $self->{xml}->{'targetInstance'};
239- if ($self->{xml_version} == 1)
240- {
241- $baseptr = $self->{xml}->{'targetInstances'}->{'targetInstance'};
242- }
243+ # Get a handle to the target instances
244+ my $targetInstanceRef = $self->getTargetInstanceHandle();
245+
246+ # If caller did not provide a target, then use the top level target
247 if ($target eq "")
248 {
249- ## find system target
250- foreach my $t (keys(%{$baseptr}))
251- {
252- if ($baseptr->{$t}->{attribute}->{TYPE}->{default} eq "SYS")
253- {
254- $self->{TOP_LEVEL} = $t;
255- $target = $t;
256- }
257- }
258+ $target = $self->getTopLevel();
259 }
260- if ($target eq "")
261+
262+ my $instance_path = $self->{data}->{INSTANCE_PATH};
263+ if (!defined $instance_path)
264 {
265- die "Unable to find system top level target\n";
266+ $instance_path = "";
267 }
268+
269 my $old_path = $instance_path;
270- my $target_xml = $baseptr->{$target};
271+ my $target_xml = $targetInstanceRef->{$target};
272 my $affinity_target = $target;
273 my $key = $instance_path . "/" . $target;
274
275@@ -466,7 +628,6 @@ sub buildHierarchy
276 $self->{data}->{INSTANCE_PATH} = $old_path . "/" . $target;
277
278 ## copy attributes
279-
280 foreach my $attribute (keys %{ $target_xml->{attribute} })
281 {
282 my $value = $target_xml->{attribute}->{$attribute}->{default};
283@@ -2448,192 +2609,6 @@ sub findDestConnections
284
285 }
286
287-sub setEepromAttributesForAxone
288-{
289- my $self = shift;
290- my $targetObj = shift;
291- # Expects ocmb target
292- my $target = shift;
293-
294- my %connections;
295- my $num=0;
296-
297- my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
298- my $fapi_name = "FAPI_I2C_CONTROL_INFO";
299- # SPD contains data for EEPROM_VPD_PRIMARY_INFO and FAPI_I2C_CONTROL_INFO
300- # SPD is the child of ocmb's parent, so get ocmb's parent
301- # then look for the SPD child
302- # With the resulting info, we populate pmic0, pmic1, ocmb, and dimm
303- my $target_parent = $self->getTargetParent($target);
304-
305- # Need to store pmic targets because they get parsed before we
306- # do calculations for engine, port, and muxBusSelector
307- # pmics need these values, so we store them until we need them later
308- my $address = 0;
309- my @pmic_array;
310- foreach my $child (@{ $self->getTargetChildren($target_parent) })
311- {
312- my $type = $self->getTargetType($child);
313- if ($type eq "chip-spd-device")
314- {
315- my $offset = $self->getAttribute($child, "BYTE_ADDRESS_OFFSET");
316- my $memory_size = $self->getAttribute($child, "MEMORY_SIZE_IN_KB");
317- my $cycle_time = $self->getAttribute($child, "WRITE_CYCLE_TIME");
318- my $page_size = $self->getAttribute($child, "WRITE_PAGE_SIZE");
319-
320- # Populate EEPROM for ocmb
321- $targetObj->setAttributeField($target, $eeprom_name, "byteAddrOffset",
322- $offset);
323- $targetObj->setAttributeField($target, $eeprom_name, "maxMemorySizeKB",
324- $memory_size);
325- $targetObj->setAttributeField($target, $eeprom_name, "writeCycleTime",
326- $cycle_time);
327- $targetObj->setAttributeField($target, $eeprom_name, "writePageSize",
328- $page_size);
329-
330- # Populate EEPROM for dimm
331- $targetObj->setAttributeField($target_parent, $eeprom_name, "byteAddrOffset",
332- $offset);
333- $targetObj->setAttributeField($target_parent, $eeprom_name, "maxMemorySizeKB",
334- $memory_size);
335- $targetObj->setAttributeField($target_parent, $eeprom_name, "writeCycleTime",
336- $cycle_time);
337- $targetObj->setAttributeField($target_parent, $eeprom_name, "writePageSize",
338- $page_size);
339-
340- # spd only child is i2c-slave, which contains devAddr info
341- foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
342- {
343- $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
344- # Populate EEPROM for dimm
345- $targetObj->setAttributeField($target_parent, $eeprom_name, "devAddr",
346- $address);
347-
348- # Populate EEPROM for ocmb
349- $targetObj->setAttributeField($target, $eeprom_name, "devAddr",
350- $address);
351- }
352- }
353- elsif ($type eq "chip-vreg-generic")
354- {
355- push(@pmic_array, $child);
356- foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
357- {
358- $type = $self->getTargetType($i2c_slave);
359- # pmic has child i2c_slave which contains the device address
360- if ($type eq "unit-i2c-slave")
361- {
362- $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
363-
364- # Populate FAPI for pmic
365- $targetObj->setAttributeField($child, $fapi_name, "devAddr",
366- $address);
367- last;
368- }
369- }
370- }
371- elsif ($type eq "chip-ocmb")
372- {
373- foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
374- {
375- # ocmb has multiple i2c-slaves, so we query with instance_name
376- my $instance_name = $self->getInstanceName($i2c_slave);
377- if ($instance_name eq "i2c-ocmb")
378- {
379- $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
380-
381- # Populate FAPI for ocmb
382- $targetObj->setAttributeField($target, $fapi_name, "devAddr",
383- $address);
384- last;
385- }
386- }
387- }
388- }
389-
390- # Get data from i2c-master-omi, which connects to the i2c_mux PCA9847
391- my $conn = $self->findConnectionsByDirection($target, "I2C", "", 1);
392- if ($conn ne "")
393- {
394- # There exists multiple i2c bus connections with chip-ocmb
395- # They are all the same connections so we just take the first one
396- # The mux channel has the i2cMuxBusSelector
397- my $conn_source = @{$conn->{CONN}}[0]->{SOURCE};
398- my $mux = $self->getAttribute($conn_source, "MUX_CHANNEL");
399-
400- # Parent PCA9848 determines the mux path
401- my $parent = $self->getTargetParent($conn_source);
402- my $parent_pos = $self->getAttribute($parent, "POSITION");
403- my $i2c_mux_path = "physical:sys-0/node-0/i2c_mux-$parent_pos";
404-
405- # pmics and ocmb all grab FRU_ID from parent dimm
406- my $fru = $self->getAttribute($target_parent, "FRU_ID");
407-
408- my $master_i2c = $self->findConnectionsByDirection($self->getTargetParent($conn_source), "I2C", "", 1);
409- if ($master_i2c ne "")
410- {
411- # There exists multiple i2c bus connections with the PCA9847 i2c_mux
412- # They are all the same connections so we just take the first one
413- $master_i2c = @{$master_i2c->{CONN}}[0];
414- # i2c-master-omi source which has data we need
415- my $source = $master_i2c->{SOURCE};
416- my $dest = $master_i2c->{DEST};
417- my $engine = $self->getAttribute($source, "I2C_ENGINE");
418- my $port = $self->getAttribute($source, "I2C_PORT");
419-
420- # Populate FAPI for ocmb
421- $self->setAttributeField($target, $fapi_name, "engine",
422- $engine);
423- $self->setAttributeField($target, $fapi_name, "port",
424- $port);
425- $self->setAttributeField($target, $fapi_name, "i2cMuxBusSelector",
426- $mux);
427- $self->setAttributeField($target, $fapi_name, "i2cMuxPath",
428- $i2c_mux_path);
429- $self->setAttribute($target, "FRU_ID",
430- $fru);
431-
432- # Populate EEPROM for ocmb
433- $self->setAttributeField($target, $eeprom_name, "i2cMuxPath",
434- $i2c_mux_path);
435- $self->setAttributeField($target, $eeprom_name, "engine",
436- $engine);
437- $self->setAttributeField($target, $eeprom_name, "port",
438- $port);
439- $self->setAttributeField($target, $eeprom_name, "i2cMuxBusSelector",
440- $mux);
441-
442-
443- # Populate FAPI for pmics
444- foreach my $pmic (@pmic_array)
445- {
446- $self->setAttributeField($pmic, $fapi_name, "engine",
447- $engine);
448- $self->setAttributeField($pmic, $fapi_name, "port",
449- $port);
450- $self->setAttributeField($pmic, $fapi_name, "i2cMuxBusSelector",
451- $mux);
452- $self->setAttributeField($pmic, $fapi_name, "i2cMuxPath",
453- $i2c_mux_path);
454- $self->setAttribute($pmic, "FRU_ID",
455- $fru);
456- }
457-
458- # Populate EEPROM for dimm
459- $self->setAttributeField($target_parent, $eeprom_name, "engine",
460- $engine);
461- $self->setAttributeField($target_parent, $eeprom_name, "port",
462- $port);
463- $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxBusSelector",
464- $mux);
465- $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxPath",
466- $i2c_mux_path);
467- $self->setAttribute($target_parent, "FRU_ID",
468- $fru);
469- }
470- }
471-}
472-
473 # Find connections from/to $target (and it's children)
474 # $to_this_target indicates the direction to find.
475 sub findConnectionsByDirection
476@@ -2792,6 +2767,41 @@ sub getTargetType
477 return $target_ptr->{TARGET}->{type};
478 }
479
480+
481+#--------------------------------------------------
482+# @brief Checks the given target for given attribute
483+#
484+# @details Will check the target for the given attribute.
485+# If attribute does not exist for target then
486+# return 0 (false), else if attribute does exist
487+# for target then return 1 (true). This methods
488+# does not check the validity of the attribute
489+# or it's value.
490+#
491+# @param [in] $self - The global target object.
492+# @param [in] $target - target to locate attribute on
493+# @param [in] $attribut - attribute to locate
494+#
495+# @return true if attribute found, else false
496+#--------------------------------------------------
497+sub doesAttributeExistForTarget
498+{
499+ my $self = shift;
500+ my $target = shift;
501+ my $attribute = shift;
502+
503+ my $target_ptr = $self->getTarget($target);
504+
505+ # If can't locate attribute for target then return back 0 (false)
506+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}))
507+ {
508+ return 0;
509+ }
510+
511+ # Attribute for target was found, return back 1 (true)
512+ return 1;
513+}
514+
515 ## checks if attribute is value
516 ## must be defined and have a non-empty value
517 sub isBadAttribute
518@@ -2818,6 +2828,7 @@ sub isBadAttribute
519 {
520 return 1;
521 }
522+
523 return 0;
524 }
525
526@@ -2864,6 +2875,7 @@ sub getAttribute
527 my $target = shift;
528 my $attribute = shift;
529 my $target_ptr = $self->getTarget($target);
530+
531 if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}->{default}))
532 {
533 printf("ERROR: getAttribute(%s,%s) | Attribute not defined\n",
534@@ -3296,6 +3308,207 @@ sub writeReportFile
535 close R;
536 }
537
538+#--------------------------------------------------
539+# @brief Populates the EEPROM attributes for DDIMS
540+#
541+# @param [in] $self - The global target object.
542+# @param [in] $target - An OCMB target
543+#--------------------------------------------------
544+sub setEepromAttributesForDDIMs
545+{
546+ my $self = shift;
547+ my $target = shift; # Expects ocmb target
548+
549+ my %connections;
550+ my $num=0;
551+
552+ my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
553+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
554+ # SPD contains data for EEPROM_VPD_PRIMARY_INFO and FAPI_I2C_CONTROL_INFO
555+ # SPD is the child of ocmb's parent, so get ocmb's parent
556+ # then look for the SPD child
557+ # With the resulting info, we populate pmic0, pmic1, ocmb, and dimm
558+ my $target_parent = $self->getTargetParent($target);
559+
560+ # Need to store pmic targets because they get parsed before we
561+ # do calculations for engine, port, etc
562+ # pmics need these values, so we store them until we need them later
563+ my $address = 0;
564+ my @pmic_array;
565+ foreach my $child (@{ $self->getTargetChildren($target_parent) })
566+ {
567+ my $type = $self->getTargetType($child);
568+ if ($type eq "chip-spd-device")
569+ {
570+ my $offset = $self->getAttribute($child, "BYTE_ADDRESS_OFFSET");
571+ my $memory_size = $self->getAttribute($child, "MEMORY_SIZE_IN_KB");
572+ my $cycle_time = $self->getAttribute($child, "WRITE_CYCLE_TIME");
573+ my $page_size = $self->getAttribute($child, "WRITE_PAGE_SIZE");
574+
575+ # Populate EEPROM for ocmb
576+ $self->setAttributeField($target, $eeprom_name, "byteAddrOffset",
577+ $offset);
578+ $self->setAttributeField($target, $eeprom_name, "maxMemorySizeKB",
579+ $memory_size);
580+ $self->setAttributeField($target, $eeprom_name, "writeCycleTime",
581+ $cycle_time);
582+ $self->setAttributeField($target, $eeprom_name, "writePageSize",
583+ $page_size);
584+
585+ # Populate EEPROM for dimm
586+ $self->setAttributeField($target_parent, $eeprom_name, "byteAddrOffset",
587+ $offset);
588+ $self->setAttributeField($target_parent, $eeprom_name, "maxMemorySizeKB",
589+ $memory_size);
590+ $self->setAttributeField($target_parent, $eeprom_name, "writeCycleTime",
591+ $cycle_time);
592+ $self->setAttributeField($target_parent, $eeprom_name, "writePageSize",
593+ $page_size);
594+
595+ # spd only child is i2c-slave, which contains devAddr info
596+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
597+ {
598+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
599+ # Populate EEPROM for dimm
600+ $self->setAttributeField($target_parent, $eeprom_name, "devAddr",
601+ $address);
602+
603+ # Populate EEPROM for ocmb
604+ $self->setAttributeField($target, $eeprom_name, "devAddr",
605+ $address);
606+ }
607+ } # end if ($type eq "chip-spd-device") ...
608+ elsif ($type eq "chip-vreg-generic")
609+ {
610+ push(@pmic_array, $child);
611+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
612+ {
613+ $type = $self->getTargetType($i2c_slave);
614+ # pmic has child i2c_slave which contains the device address
615+ if ($type eq "unit-i2c-slave")
616+ {
617+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
618+
619+ # Populate FAPI for pmic
620+ $self->setAttributeField($child, $fapi_name, "devAddr",
621+ $address);
622+ last;
623+ }
624+ }
625+ } # end elsif ($type eq "chip-vreg-generic")
626+ elsif ($type eq "chip-ocmb")
627+ {
628+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
629+ {
630+ # ocmb has multiple i2c-slaves, so we query with instance_name
631+ my $instance_name = $self->getInstanceName($i2c_slave);
632+ if ($instance_name eq "i2c-ocmb")
633+ {
634+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
635+
636+ # Populate FAPI for ocmb
637+ $self->setAttributeField($target, $fapi_name, "devAddr",
638+ $address);
639+ last;
640+ }
641+ }
642+ } # end elsif ($type eq "chip-ocmb")
643+ } # end foreach my $child ...
644+
645+ # Get data from i2c-master-omi, which connects to the i2c_mux PCA9847
646+ my $conn = $self->findConnectionsByDirection($target, "I2C", "", 1);
647+ if ($conn ne "")
648+ {
649+ # There exists multiple i2c bus connections with chip-ocmb
650+ # They are all the same connections so we just take the first one
651+ # The mux channel has the i2cMuxBusSelector
652+ my $conn_source = @{$conn->{CONN}}[0]->{SOURCE};
653+# TODO FIX ROLAND
654+# Will fix later in the process
655+# ROLAND causing errors:
656+# ERROR: getAttribute(/sys-0/node-0/nisqually-0/proc_socket-0/godel-0/power10-0/i2c-master-op3b,MUX_CHANNEL) | Attribute not defined
657+# I only found MUX_CHANNEL on attributes /sys-0/node-0/nisqually-0/PCA9849-[0-7]/PCA9849.i2cm-[0..3]
658+#
659+# my $mux = $self->getAttribute($conn_source, "MUX_CHANNEL");
660+ my $mux = 0;
661+
662+ # Parent PCA9848 determines the mux path
663+ my $parent = $self->getTargetParent($conn_source);
664+ my $parent_pos = $self->getAttribute($parent, "POSITION");
665+ my $i2c_mux_path = "physical:sys-0/node-0/i2c_mux-$parent_pos";
666+
667+ # pmics and ocmb all grab FRU_ID from parent dimm
668+ my $fru = $self->getAttribute($target_parent, "FRU_ID");
669+
670+ my $master_i2c = $self->findConnectionsByDirection($self->getTargetParent($conn_source), "I2C", "", 1);
671+ if ($master_i2c ne "")
672+ {
673+ # There exists multiple i2c bus connections with the PCA9847 i2c_mux
674+ # They are all the same connections so we just take the first one
675+ $master_i2c = @{$master_i2c->{CONN}}[0];
676+ # i2c-master-omi source which has data we need
677+ my $source = $master_i2c->{SOURCE};
678+ my $dest = $master_i2c->{DEST};
679+ my $engine = $self->getAttribute($source, "I2C_ENGINE");
680+ my $port = $self->getAttribute($source, "I2C_PORT");
681+
682+ # Populate FAPI for ocmb
683+ $self->setAttributeField($target, $fapi_name, "engine",
684+ $engine);
685+ $self->setAttributeField($target, $fapi_name, "port",
686+ $port);
687+ $self->setAttributeField($target, $fapi_name, "i2cMuxBusSelector",
688+ $mux);
689+ $self->setAttributeField($target, $fapi_name, "i2cMuxPath",
690+ $i2c_mux_path);
691+ $self->setAttribute($target, "FRU_ID",
692+ $fru);
693+
694+ # Populate EEPROM for ocmb
695+ $self->setAttributeField($target, $eeprom_name, "i2cMuxPath",
696+ $i2c_mux_path);
697+ $self->setAttributeField($target, $eeprom_name, "engine",
698+ $engine);
699+ $self->setAttributeField($target, $eeprom_name, "port",
700+ $port);
701+ $self->setAttributeField($target, $eeprom_name, "i2cMuxBusSelector",
702+ $mux);
703+
704+ # Populate FAPI for pmics
705+ foreach my $pmic (@pmic_array)
706+ {
707+ $self->setAttributeField($pmic, $fapi_name, "engine",
708+ $engine);
709+ $self->setAttributeField($pmic, $fapi_name, "port",
710+ $port);
711+ $self->setAttributeField($pmic, $fapi_name, "i2cMuxBusSelector",
712+ $mux);
713+ $self->setAttributeField($pmic, $fapi_name, "i2cMuxPath",
714+ $i2c_mux_path);
715+ $self->setAttribute($pmic, "FRU_ID",
716+ $fru);
717+ }
718+
719+ # Populate EEPROM for dimm
720+ $self->setAttributeField($target_parent, $eeprom_name, "engine",
721+ $engine);
722+ $self->setAttributeField($target_parent, $eeprom_name, "port",
723+ $port);
724+ $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxBusSelector",
725+ $mux);
726+ $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxPath",
727+ $i2c_mux_path);
728+ $self->setAttribute($target_parent, "FRU_ID",
729+ $fru);
730+ } # end if ($master_i2c ne "")
731+ } # end if ($conn ne "")
732+}
733+
734+#--------------------------------------------------
735+# @brief The end of the executable elements of this PERL module
736+#
737+# @details Don't forget to return the true value from this file
738+#--------------------------------------------------
739 1;
740
741 =head1 NAME
742diff --git a/src/usr/targeting/common/processMrw.pl b/src/usr/targeting/common/processMrw.pl
743index 7a63791..cd84b14 100755
744--- a/src/usr/targeting/common/processMrw.pl
745+++ b/src/usr/targeting/common/processMrw.pl
746@@ -24,6 +24,9 @@
747 #
748 # IBM_PROLOG_END_TAG
749
750+###############################################################################
751+# Include these libraries
752+###############################################################################
753 use strict;
754 use XML::Simple;
755 use Data::Dumper;
756@@ -32,112 +35,168 @@ use Math::BigInt;
757 use Getopt::Long;
758 use File::Basename;
759
760-use constant HZ_PER_KHZ=>1000;
761-use constant MAX_MCS_PER_PROC => 4; # 4 MCS per Nimbus
762
763+###############################################################################
764+# Define some global constants
765+###############################################################################
766 my $VERSION = "1.0.0";
767+my $targetObj = Targets->new;
768
769-my $force = 0;
770-my $serverwiz_file = "";
771-my $version = 0;
772-my $debug = 0;
773-my $report = 0;
774-my $sdr_file = "";
775-my $build = "hb";
776-my $system_config = "";
777-my $output_filename = "";
778-
779-# Map the OMI instance to its corresponding OMIC parent
780-my %omi_map = (4 => "omic-0",
781- 5 => "omic-0",
782- 6 => "omic-0",
783- 7 => "omic-1",
784- 2 => "omic-1",
785- 3 => "omic-1",
786- 0 => "omic-2",
787- 1 => "omic-2",
788- 12 => "omic-0",
789- 13 => "omic-0",
790- 14 => "omic-0",
791- 15 => "omic-1",
792- 10 => "omic-1",
793- 11 => "omic-1",
794- 8 => "omic-2",
795- 9 => "omic-2");
796+# Define a true an false keyword
797+use constant { true => 1, false => 0 };
798+
799+use constant HZ_PER_KHZ=>1000;
800+use constant MAX_MCS_PER_PROC => 4; # 4 MCS per Nimbus
801
802 # TODO RTC:170860 - Remove this after dimm connector defines VDDR_ID
803-my $num_voltage_rails_per_proc = 1;
804-
805-GetOptions(
806- "build=s" => \$build,
807- "f" => \$force, # numeric
808- "x=s" => \$serverwiz_file, # string
809- "d" => \$debug,
810- "c=s" => \$system_config, #string
811- "o=s" => \$output_filename, #string
812- "v" => \$version,
813- "r" => \$report,
814- ) # flag
815- or printUsage();
816-
817-if ($version == 1)
818-{
819- die "\nprocessMrw.pl\tversion $VERSION\n";
820-}
821+my $NUM_VOLTAGE_RAILS_PER_PROC = 1;
822
823-if ($serverwiz_file eq "")
824-{
825- printUsage();
826-}
827+## Used to setup GPU sensors on processors
828+# key: OBUS slot target,
829+# value: (GPU#, Function, Temp, MemTemp IPMI name/ids,
830+my %GPU_SENSORS;
831
832-$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
833+# key: OBUS slot string
834+# value: processor target string
835+my %SLOT_TO_PROC;
836
837-my $targetObj = Targets->new;
838-if ($force == 1)
839+our %hwsvmrw_plugins;
840+
841+###############################################################################
842+# The starting point for this script
843+###############################################################################
844+main($targetObj);
845+
846+sub main
847 {
848- $targetObj->{force} = 1;
849+ my $targetObj = shift;
850+
851+ # Extract the caller's options off the command and validate.
852+ # Will exit if options are not valid.
853+ getAndValidateCallerInputOptions();
854+
855+
856+ # Run tests if asked to do so
857+ if ($targetObj->{run_self_test} == 1)
858+ {
859+ runTests($targetObj);
860+ return 0;
861+ }
862+
863+ # Load the XML and process the file, extracting targets and associating
864+ # attributes, with their data, to the targets
865+ loadXmlFile();
866+
867+ if ($targetObj->{build} eq "fsp")
868+ {
869+ doFspBuild();
870+ }
871+
872+ # Process the targets - set some needed attribute values
873+ processTargets();
874+
875+ # Check for errors in the targets
876+ errorCheckTheTargets($targetObj);
877+
878+ # Write the results of processing the targets to an XML file
879+ writeResultsToXml($targetObj);
880 }
881-if ($debug == 1)
882+
883+###############################################################################
884+# Supporting subroutines
885+###############################################################################
886+#--------------------------------------------------
887+# @brief Extract caller's command line options
888+#
889+# @details Extract caller's command line options and
890+# validate them. If valid then store in the
891+# global Target object for easy retrieval.
892+# If options are not valid, then print
893+# usage statement and exit script.
894+#--------------------------------------------------
895+sub getAndValidateCallerInputOptions
896 {
897- $targetObj->{debug} = 1;
898-}
899+ # Local variables, and their defaults, to cache the command line options to
900+ my $build = "hb";
901+ my $force = 0;
902+ my $serverwiz_file = "";
903+ my $debug = 0;
904+ my $system_config = "";
905+ my $output_file = "";
906+ my $version = 0;
907+ my $report = 0;
908+ my $run_self_test = 0;
909+
910+ # Grab the user's command line options. If options not recognized
911+ # print usage statement and exit script.
912+ GetOptions(
913+ "build=s" => \$build, # string
914+ "f" => \$force, # numeric
915+ "x=s" => \$serverwiz_file, # string
916+ "d" => \$debug, # flag
917+ "c=s" => \$system_config, # string
918+ "o=s" => \$output_file, # string
919+ "v" => \$version, # flag
920+ "r" => \$report, # flag
921+ "t" => \$run_self_test, # flag
922+ )
923+ or printUsage();
924+
925+ # Display current version of file
926+ if ($version == 1)
927+ {
928+ die "\nprocessMrw.pl\tversion $VERSION\n";
929+ }
930+
931+ # If caller did not specify an input file, then print usage and die
932+ if ($serverwiz_file eq "")
933+ {
934+ printUsage();
935+ }
936+
937+ # Save the caller's input options to global storage for easy retrieval
938+ $targetObj->{build} = $build;
939+ $targetObj->{force} = $force;
940+ $targetObj->{serverwiz_file} = $serverwiz_file;
941+ $targetObj->{serverwiz_dir} = dirname($serverwiz_file);
942+ $targetObj->{debug} = $debug;
943+ $targetObj->{system_config} = $system_config;
944+ $targetObj->{output_file} = $output_file;
945+ $targetObj->setVersion($VERSION);
946+ $targetObj->{report} = $report;
947+ $targetObj->{run_self_test} = $run_self_test;
948+
949+} # end getAndValidateCallerInputOptions
950+
951+# loadXmlFile
952+sub loadXmlFile
953+{
954+ $XML::Simple::PREFERRED_PARSER = 'XML::Parser';
955+ $targetObj->loadXML($targetObj->{serverwiz_file});
956
957-$targetObj->setVersion($VERSION);
958-my $xmldir = dirname($serverwiz_file);
959-$targetObj->loadXML($serverwiz_file);
960+ my $str=sprintf(
961+ " %30s | %10s | %6s | %4s | %9s | %4s | %4s | %4s | %10s | %s\n",
962+ "Sensor Name","FRU Name","Ent ID","Type","Evt Type","ID","Inst","FRU",
963+ "HUID","Target");
964+
965+ $targetObj->writeReport($str);
966+ my $str=sprintf(
967+ " %30s | %10s | %6s | %4s | %9s | %4s | %4s | %4s | %10s | %s\n",
968+ "------------------------------","----------",
969+ "------","----","---------","----","----","----","----------",
970+ "----------");
971+
972+ $targetObj->writeReport($str);
973+} # end loadXmlFile
974
975-our %hwsvmrw_plugins;
976 # FSP-specific functions
977-if ($build eq "fsp")
978+sub doFspBuild
979 {
980 eval ("use processMrw_fsp; return 1;");
981 processMrw_fsp::return_plugins();
982-}
983-
984-my $str=sprintf(
985- " %30s | %10s | %6s | %4s | %9s | %4s | %4s | %4s | %10s | %s\n",
986- "Sensor Name","FRU Name","Ent ID","Type","Evt Type","ID","Inst","FRU",
987- "HUID","Target");
988+} # end doFspBuild
989
990-$targetObj->writeReport($str);
991-my $str=sprintf(
992- " %30s | %10s | %6s | %4s | %9s | %4s | %4s | %4s | %10s | %s\n",
993- "------------------------------","----------",
994- "------","----","---------","----","----","----","----------",
995- "----------");
996-
997-$targetObj->writeReport($str);
998-
999-########################
1000-## Used to setup GPU sensors on processors
1001-my %G_gpu_sensors;
1002-# key: obusslot target,
1003-# value: (GPU#, Function, Temp, MemTemp IPMI name/ids,
1004
1005-my %G_slot_to_proc;
1006-# key: obusslot string
1007-# value: processor target string
1008-#########################
1009
1010 # convert a number string into a bit-position number
1011 # example: "0x02" --> 0b0100 = 4
1012@@ -151,7 +210,7 @@ sub numToBitPositionNum
1013 return $newNum;
1014 }
1015
1016-# Used to populate G_gpu_sensors hash of array references
1017+# Used to populate GPU_SENSORS hash of array references
1018 #
1019 # Each array reference will be composed of 3 sensors +
1020 # board cfg ID which together makes up a GPU.
1021@@ -167,7 +226,7 @@ sub addSensorToGpuSensors
1022 my $GPU_SENSORS_TEMP_OFFSET = 2;
1023 my $GPU_SENSORS_MEM_TEMP_OFFSET = 4;
1024
1025- my $rSensorArray = $G_gpu_sensors{$obusslot_str};
1026+ my $rSensorArray = $GPU_SENSORS{$obusslot_str};
1027 unless ($rSensorArray) {
1028 $rSensorArray = [ "0xFFFF","0xFF","0xFFFF","0xFF",
1029 "0xFFFF","0xFF","0x00" ];
1030@@ -192,11 +251,11 @@ sub addSensorToGpuSensors
1031 $rSensorArray->[$GPU_SENSORS_TEMP_OFFSET+1] = $sensorID;
1032 }
1033
1034- $G_gpu_sensors{$obusslot_str} = $rSensorArray;
1035+ $GPU_SENSORS{$obusslot_str} = $rSensorArray;
1036 }
1037
1038
1039-# Populates the G_slot_to_proc hash and updates the cfgID in G_gpu_sensors
1040+# Populates the SLOT_TO_PROC hash and updates the cfgID in GPU_SENSORS
1041 # This is how we map the obusslot to the GPU sensors
1042 sub addObusCfgToGpuSensors
1043 {
1044@@ -205,14 +264,14 @@ sub addObusCfgToGpuSensors
1045
1046 my $foundSlot = 0;
1047
1048- $G_slot_to_proc{$obusslot_str} = $proc_target;
1049+ $SLOT_TO_PROC{$obusslot_str} = $proc_target;
1050
1051- foreach my $obusslot (keys %G_gpu_sensors)
1052+ foreach my $obusslot (keys %GPU_SENSORS)
1053 {
1054 if ($obusslot =~ m/$obusslot_str/)
1055 {
1056 # Add in the cfg number
1057- my $rSensorArray = $G_gpu_sensors{$obusslot_str};
1058+ my $rSensorArray = $GPU_SENSORS{$obusslot_str};
1059 $rSensorArray->[$GPU_SENSORS_OBUS_CFG_OFFSET] =
1060 sprintf("0x%02X",
1061 (oct($rSensorArray->[$GPU_SENSORS_OBUS_CFG_OFFSET]) |
1062@@ -225,10 +284,10 @@ sub addObusCfgToGpuSensors
1063 {
1064 print STDOUT sprintf("%s:%d ", __FILE__,__LINE__);
1065 print STDOUT "Found obus slot ($obusslot_str - processor $proc_target)".
1066- " not in G_gpu_sensors hash\n";
1067+ " not in GPU_SENSORS hash\n";
1068
1069 my $cfg_bit_num = numToBitPositionNum($cfg);
1070- $G_gpu_sensors{$obusslot_str} =
1071+ $GPU_SENSORS{$obusslot_str} =
1072 ["0xFFFF","0xFF","0xFFFF","0xFF","0xFFFF",
1073 "0xFF", sprintf("0x02X",oct($cfg_bit_num))];
1074 }
1075@@ -273,17 +332,207 @@ sub isMultiTpmSystem
1076 }
1077
1078 #--------------------------------------------------
1079-## loop through all targets and do stuff
1080-my @targets = sort keys %{ $targetObj->getAllTargets() };
1081-my $isMultiTpmSys = isMultiTpmSystem(\@targets);
1082-foreach my $target (@targets)
1083+# @brief Loop through all targets and set attributes as needed
1084+#
1085+# @param [in] $targetObj - The global target object.
1086+#--------------------------------------------------
1087+sub processTargets
1088+{
1089+ my @targets = sort keys %{ $targetObj->getAllTargets() };
1090+ my $isMultiTpmSys = isMultiTpmSystem(\@targets);
1091+ foreach my $target (@targets)
1092+{
1093+ my $type = $targetObj->getType($target);
1094+ if ($type eq "SYS")
1095+ {
1096+ processSystem($targetObj, $target);
1097+
1098+ my $maxComputeNodes = get_max_compute_nodes($targetObj , $target);
1099+ $targetObj->setAttribute($target, "MAX_COMPUTE_NODES_PER_SYSTEM", $maxComputeNodes);
1100+
1101+ #handle enumeration changes
1102+ my $enum_val = $targetObj->getAttribute($target,"PROC_FABRIC_PUMP_MODE");
1103+ if ( $enum_val =~ /MODE1/i)
1104+ {
1105+ $targetObj->setAttribute($target,"PROC_FABRIC_PUMP_MODE","CHIP_IS_NODE");
1106+ }
1107+ elsif ( $enum_val =~ /MODE2/i)
1108+ {
1109+ $targetObj->setAttribute($target,"PROC_FABRIC_PUMP_MODE","CHIP_IS_GROUP");
1110+ }
1111+ }
1112+ elsif ($type eq "PROC")
1113+ {
1114+ processProcessor($targetObj, $target);
1115+ if ($targetObj->{build} eq "fsp")
1116+ {
1117+ do_plugin("fsp_proc", $targetObj, $target);
1118+ }
1119+ }
1120+ elsif ($type eq "APSS")
1121+ {
1122+ processApss($targetObj, $target);
1123+ }
1124+
1125+ # @TODO RTC: 189374 Remove multiple TPMs filter when all platforms' MRW
1126+ # supports dynamically determining the processor driving it.
1127+ elsif (($type eq "TPM") && $isMultiTpmSys)
1128+ {
1129+ processTpm($targetObj, $target);
1130+ }
1131+ elsif ($type eq "POWER_SEQUENCER")
1132+ {
1133+ my $target_type = $targetObj->getTargetType($target);
1134+
1135+ # Strip off the chip- part of the target type name
1136+ $target_type =~ s/chip\-//g;
1137+
1138+ # Currently only UCD9090 and UCD90120A on FSP systems are supported.
1139+ # All other UCD types are skipped.
1140+ if (($target_type eq "UCD9090")
1141+ || ($target_type eq "UCD90120A"))
1142+ {
1143+ processUcd($targetObj, $target);
1144+ }
1145+ }
1146+ elsif ($type eq "OCMB_CHIP")
1147+ {
1148+ processOcmbChip($targetObj, $target);
1149+ }
1150+
1151+ # Once processing of the target type is complete, remove
1152+ # deprecated and un-needed attributes for this type
1153+ pruneTargetAttributes($targetObj, $target, $type);
1154+
1155+ processIpmiSensors($targetObj,$target);
1156+ } # end foreach my $target (@targets)
1157+
1158+
1159+ if ($targetObj->{build} eq "fsp")
1160+ {
1161+ processMrw_fsp::loadFSP($targetObj);
1162+ }
1163+} # end processTargets
1164+
1165+#--------------------------------------------------
1166+# @brief Check the processed targets for errors
1167+#
1168+# @param [in] $targetObj - The global target object.
1169+#--------------------------------------------------
1170+sub errorCheckTheTargets
1171 {
1172- my $type = $targetObj->getType($target);
1173+ my $targetObj = shift;
1174+
1175+# TODO FIX ROLAND
1176+# Will fix later in the process
1177+# check topology
1178+# ROLAND Having issues with the topology:
1179+# ERROR: Fabric topology invalid. 2 targets have same FABRIC_TOPOLOGY_ID (0x0)
1180+# Once resolved, add this check back in
1181+# The MRW XML has 2 procs: power10-0 of type chip-processor-power10 and
1182+# power10-1 of type chip-processor-power10 and
1183+# In the loadXmlFile method, it produces 4 procs, 2 on a socket:
1184+# '/sys-0/node-0/nisqually-0/proc_socket-0/godel-0/power10-0';
1185+# '/sys-0/node-0/nisqually-0/proc_socket-1/godel-0/power10-0';
1186+# '/sys-0/node-0/nisqually-0/proc_socket-0/godel-0/power10-1';
1187+# '/sys-0/node-0/nisqually-0/proc_socket-1/godel-0/power10-1';
1188+# For both power10-0 procs it uses topologoy ID 0
1189+# For both power10-1 procs it uses topologoy ID 1
1190+# So this end up in duplicates being used
1191+
1192+# foreach my $n (keys %{$targetObj->{TOPOLOGY}})
1193+# {
1194+# if ($targetObj->{TOPOLOGY}->{$n} > 1)
1195+# {
1196+# print "ERROR: Fabric topology invalid. 2 targets have same ".
1197+# "FABRIC_TOPOLOGY_ID ($n)\n";
1198+# $targetObj->myExit(3);
1199+# }
1200+# }
1201+
1202+ foreach my $target (keys %{ $targetObj->getAllTargets() })
1203+ {
1204+ # TODO FIX ROLAND
1205+ # Will fix later in the process
1206+ # ROLAND Having issues with power10-0 so wrapped errorCheck with if statement:
1207+ # ERROR: EEPROM_VPD_PRIMARY_INFO/devAddr attribute is invalid (Target=/sys-0/node-0/nisqually-0/proc_socket-0/godel-0/power10-0)
1208+ # I2C connection to target is not defined
1209+ ## Once resolved, will remove if statement
1210+ if ($target != "/sys-0/node-0/nisqually-0/proc_socket-0/godel-0/power10-0")
1211+ {
1212+ errorCheck($targetObj, $target);
1213+ }
1214+ }
1215+} # end sub errorCheckTheTargets
1216+
1217+#--------------------------------------------------
1218+# @brief Write out the results to an XML file
1219+#
1220+# @param [in] $targetObj - The global target object.
1221+#--------------------------------------------------
1222+sub writeResultsToXml
1223+{
1224+ my $targetObj = shift;
1225+
1226+ my $xml_fh;
1227+ my $filename;
1228+ my $config_str = $targetObj->{system_config};
1229+
1230+ #If user did not specify the output filename, then build one up by using
1231+ #config and build parameters
1232+ if ($targetObj->{output_file} eq "")
1233+ {
1234+ if ($config_str ne "")
1235+ {
1236+ $config_str = "_" . $config_str;
1237+ }
1238+
1239+ $filename = $targetObj->{serverwiz_dir} . "/" . $targetObj->getSystemName() . $config_str . "_" . $targetObj->{build} . ".mrw.xml";
1240+ }
1241+ else
1242+ {
1243+ $filename = $targetObj->{output_file};
1244+ }
1245+
1246+ print "Creating XML: $filename\n";
1247+ open($xml_fh, ">$filename") || die "Unable to create: $filename";
1248+
1249+ $targetObj->printXML($xml_fh, "top", $targetObj->{build});
1250+ close $xml_fh;
1251+ if (!$targetObj->{errorsExist})
1252+ {
1253+ ## optionally print out report
1254+ if ($targetObj->{report})
1255+ {
1256+ print "Writing report to: ".$targetObj->{report_filename}."\n";
1257+ $targetObj->writeReportFile();
1258+ }
1259+ print "MRW created successfully!\n";
1260+ }
1261+} # end sub writeResultsToXml
1262+
1263+#--------------------------------------------------
1264+# @brief Remove attributes associated with target.
1265+# Either because they have been deprecated
1266+# or simply not used/needed.
1267+# @param[in] $targetObj - The global target object
1268+# blob
1269+# @param[in] $target - The target to remove attributes
1270+# from
1271+# @param[in] $type - The type of the target
1272+#
1273+# TODO RTC: 178351 Remove depricated Attribute from HB XML
1274+# these are obsolete
1275+#
1276+#--------------------------------------------------
1277+sub pruneTargetAttributes
1278+{
1279+ my $targetObj = shift;
1280+ my $target = shift;
1281+ my $type = shift;
1282+
1283 if ($type eq "SYS")
1284 {
1285- processSystem($targetObj, $target);
1286- #TODO RTC: 178351 Remove depricated Attribute from HB XML
1287- #these are obsolete
1288 $targetObj->deleteAttribute($target,"FUSED_CORE_MODE");
1289 $targetObj->deleteAttribute($target,"MRW_CDIMM_MASTER_I2C_TEMP_SENSOR_ENABLE");
1290 $targetObj->deleteAttribute($target,"MRW_CDIMM_SPARE_I2C_TEMP_SENSOR_ENABLE");
1291@@ -302,31 +551,9 @@ foreach my $target (@targets)
1292 $targetObj->deleteAttribute($target,"SYSTEM_WOF_ENABLED");
1293 $targetObj->deleteAttribute($target,"VDM_ENABLE");
1294 $targetObj->deleteAttribute($target,"CHIP_HAS_SBE");
1295-
1296- my $maxComputeNodes = get_max_compute_nodes($targetObj , $target);
1297- $targetObj->setAttribute($target, "MAX_COMPUTE_NODES_PER_SYSTEM", $maxComputeNodes);
1298-
1299- #handle enumeration changes
1300- my $enum_val = $targetObj->getAttribute($target,"PROC_FABRIC_PUMP_MODE");
1301- if ( $enum_val =~ /MODE1/i)
1302- {
1303- $targetObj->setAttribute($target,"PROC_FABRIC_PUMP_MODE","CHIP_IS_NODE");
1304- }
1305- elsif ( $enum_val =~ /MODE2/i)
1306- {
1307- $targetObj->setAttribute($target,"PROC_FABRIC_PUMP_MODE","CHIP_IS_GROUP");
1308- }
1309-
1310 }
1311 elsif ($type eq "PROC")
1312 {
1313- processProcessor($targetObj, $target);
1314- if ($build eq "fsp")
1315- {
1316- do_plugin("fsp_proc", $targetObj, $target);
1317- }
1318- #TODO RTC: 178351 Remove depricated Attribute from HB XML
1319- #these are obsolete
1320 $targetObj->deleteAttribute($target,"CHIP_HAS_SBE");
1321 $targetObj->deleteAttribute($target,"FSI_GP_REG_SCOM_ACCESS");
1322 $targetObj->deleteAttribute($target,"I2C_SLAVE_ADDRESS");
1323@@ -349,18 +576,8 @@ foreach my $target (@targets)
1324 $targetObj->deleteAttribute($target,"PROC_SECURITY_SETUP_VECTOR");
1325 $targetObj->deleteAttribute($target,"SBE_SEEPROM_I2C_ADDRESS_BYTES");
1326 }
1327- elsif ($type eq "APSS")
1328- {
1329- processApss($targetObj, $target);
1330- }
1331- elsif ($type eq "MEMBUF")
1332- {
1333- processMembuf($targetObj, $target);
1334- $targetObj->deleteAttribute($target,"CEN_MSS_VREF_CAL_CNTL");
1335- }
1336 elsif ($type eq "PHB")
1337 {
1338- #TODO RTC: 178351 Remove depricated Attribute from HB XML
1339 $targetObj->deleteAttribute($target,"DEVICE_ID");
1340 $targetObj->deleteAttribute($target,"HDDW_ORDER");
1341 $targetObj->deleteAttribute($target,"MAX_POWER");
1342@@ -376,91 +593,7 @@ foreach my $target (@targets)
1343 $targetObj->deleteAttribute($target,"SLOT_NAME");
1344 $targetObj->deleteAttribute($target,"VENDOR_ID");
1345 }
1346- # @TODO RTC: 189374 Remove multiple TPMs filter when all platforms' MRW
1347- # supports dynamically determining the processor driving it.
1348- elsif (($type eq "TPM") && $isMultiTpmSys)
1349- {
1350- processTpm($targetObj, $target);
1351- }
1352- elsif ($type eq "POWER_SEQUENCER")
1353- {
1354- my $target_type = $targetObj->getTargetType($target);
1355-
1356- # Strip off the chip- part of the target type name
1357- $target_type =~ s/chip\-//g;
1358-
1359- # Currently only UCD9090 and UCD90120A on FSP systems are supported.
1360- # All other UCD types are skipped.
1361- if (($target_type eq "UCD9090")
1362- || ($target_type eq "UCD90120A"))
1363- {
1364- processUcd($targetObj, $target);
1365- }
1366- }
1367- elsif ($type eq "OCMB_CHIP")
1368- {
1369- processOcmbChip($targetObj, $target);
1370- }
1371-
1372- processIpmiSensors($targetObj,$target);
1373-}
1374-
1375-if ($build eq "fsp")
1376-{
1377- processMrw_fsp::loadFSP($targetObj);
1378-}
1379-## check topology
1380-foreach my $n (keys %{$targetObj->{TOPOLOGY}}) {
1381- if ($targetObj->{TOPOLOGY}->{$n} > 1) {
1382- print "ERROR: Fabric topology invalid. 2 targets have same ".
1383- "FABRIC_TOPOLOGY_ID ($n)\n";
1384- $targetObj->myExit(3);
1385- }
1386-}
1387-## check for errors
1388-foreach my $target (keys %{ $targetObj->getAllTargets() })
1389-{
1390- errorCheck($targetObj, $target);
1391-}
1392-
1393-#--------------------------------------------------
1394-## write out final XML
1395-my $xml_fh;
1396-my $filename;
1397-my $config_str = $system_config;
1398-
1399-#If user did not specify the output filename, then build one up by using
1400-#config and build parameters
1401-if ($output_filename eq "")
1402-{
1403- if ($config_str ne "")
1404- {
1405- $config_str = "_" . $config_str;
1406- }
1407-
1408- $filename = $xmldir . "/" . $targetObj->getSystemName() . $config_str . "_" . $build . ".mrw.xml";
1409-}
1410-else
1411-{
1412- $filename = $output_filename;
1413-}
1414-
1415-print "Creating XML: $filename\n";
1416-open($xml_fh, ">$filename") || die "Unable to create: $filename";
1417-
1418-$targetObj->printXML($xml_fh, "top", $build);
1419-close $xml_fh;
1420-if (!$targetObj->{errorsExist})
1421-{
1422- ## optionally print out report
1423- if ($report)
1424- {
1425- print "Writing report to: ".$targetObj->{report_filename}."\n";
1426- $targetObj->writeReportFile();
1427- }
1428- print "MRW created successfully!\n";
1429-}
1430-
1431+} # end pruneTargetAttributes
1432
1433 #--------------------------------------------------
1434 #--------------------------------------------------
1435@@ -493,7 +626,7 @@ sub processSystem
1436 my $system_name = $targetObj->getAttribute($target,"SYSTEM_NAME");
1437 if ($system_name =~ /ZAIUS/i)
1438 {
1439- $num_voltage_rails_per_proc = 2;
1440+ $NUM_VOLTAGE_RAILS_PER_PROC = 2;
1441 }
1442
1443 # TODO RTC:182764 -- right now there is no support for CDIMMs. So,
1444@@ -940,9 +1073,9 @@ sub processUcd
1445 }
1446
1447 #--------------------------------------------------
1448-## Processor
1449-##
1450-
1451+# @brief Process processors
1452+#
1453+#--------------------------------------------------
1454 sub processProcessor
1455 {
1456 my $targetObj = shift;
1457@@ -998,7 +1131,6 @@ sub processProcessor
1458 }
1459 }
1460
1461-
1462 # I2C arrays
1463 my @engine = ();
1464 my @port = ();
1465@@ -1051,11 +1183,11 @@ sub processProcessor
1466 # contain this information and this can be removed
1467 my $socket_pos = $targetObj->getAttribute($socket_target,
1468 "POSITION");
1469- if ($num_voltage_rails_per_proc > 1)
1470+ if ($NUM_VOLTAGE_RAILS_PER_PROC > 1)
1471 {
1472 my $mcbist_pos = $targetObj->getAttribute($child, "CHIP_UNIT");
1473 $targetObj->setAttribute($child, "VDDR_ID",
1474- $socket_pos*$num_voltage_rails_per_proc + $mcbist_pos);
1475+ $socket_pos*$NUM_VOLTAGE_RAILS_PER_PROC + $mcbist_pos);
1476 }
1477 else
1478 {
1479@@ -1097,16 +1229,16 @@ sub processProcessor
1480
1481 # Add GPU sensors to processor
1482 my @aGpuSensors = ();
1483- foreach my $obusslot (sort keys %G_gpu_sensors)
1484+ foreach my $obusslot (sort keys %GPU_SENSORS)
1485 {
1486 # find matching obusslot to processor
1487- my $proc_target = $G_slot_to_proc{$obusslot};
1488+ my $proc_target = $SLOT_TO_PROC{$obusslot};
1489
1490 # if a processor target is found and it is the same as this target
1491 if ($proc_target && ($target =~ m/$proc_target/))
1492 {
1493 # Add this GPU's sensors to the processor's array of GPU sensors
1494- push (@aGpuSensors, @{ $G_gpu_sensors{$obusslot} });
1495+ push (@aGpuSensors, @{ $GPU_SENSORS{$obusslot} });
1496 }
1497 }
1498 if (@aGpuSensors)
1499@@ -1216,10 +1348,11 @@ sub processProcessor
1500 $targetObj->getAttribute($target,
1501 "FABRIC_CHIP_ID"));
1502
1503- processMembufVpdAssociation($targetObj,$target);
1504+
1505 #TODO RTC: 191762 -- Need a generic way to source FABRIC_GROUP_ID and
1506 #FABRIC_CHIP_ID from the MRW and select the right value in processMRW
1507 #based on the system configuration we are compiling for.
1508+ my $system_config = $targetObj->{system_config};
1509 if ($system_config eq "w")
1510 {
1511 my $huid_str = $targetObj->getAttribute($target, "HUID");
1512@@ -1412,36 +1545,21 @@ sub processI2cSpeeds
1513 $targetObj->setAttribute($target,"I2C_BUS_SPEED_ARRAY",$bus_speed_attr);
1514 }
1515
1516-################################
1517-## Setup address map
1518-
1519+#--------------------------------------------------
1520+# @brief Setup address map
1521+#--------------------------------------------------
1522 sub setupBars
1523 {
1524 my $targetObj = shift;
1525 my $target = shift;
1526- #--------------------------------------------------
1527- ## Setup BARs
1528-
1529- #The topology ID is a 4 bit value that must be converted to
1530- #a 5-bit topology index before we can use it to calculate the
1531- #address offset.
1532- #The conversion method depends on the topology mode.
1533- my $topoId = $targetObj->getAttribute($target, "PROC_FABRIC_TOPOLOGY_ID");
1534- my $topoMode = $targetObj->getAttribute($target, "PROC_FABRIC_TOPOLOGY_MODE");
1535-
1536- #Assume topo mode 1 (GGCC -> 0GGCC)
1537- my $topoIndex = $topoId;
1538-
1539- #Check for topo mode 0
1540- if ($topoMode == 0)
1541- {
1542- # GGGC -> GGG0C
1543- $topoIndex = (($topoIndex & 0xE) << 1) | ($topoIndex & 0x1);
1544- }
1545
1546- #keep track of which topology ID's have been used
1547+ # Keep track of which topology ID's have been used
1548+ my $topoId = getTopologyId($targetObj, $target);
1549 $targetObj->{TOPOLOGY}->{$topoId}++;
1550
1551+ # Get the topology index
1552+ my $topologyIndex = getTopologyIndex($targetObj, $target);
1553+
1554 #P10 has a defined memory map for all configurations,
1555 #these are the base addresses for topology ID 0 (group0-chip0).
1556 my %bars=( "FSP_BASE_ADDR" => 0x0006030100000000,
1557@@ -1466,9 +1584,147 @@ sub setupBars
1558 {
1559 my $i_base = Math::BigInt->new($bars{$bar});
1560 my $value=sprintf("0x%016s",substr((
1561- $i_base+$topoIndexOffset*$topoIndex)->as_hex(),2));
1562+ $i_base+$topoIndexOffset*$topologyIndex)->as_hex(),2));
1563 $targetObj->setAttribute($target,$bar,$value);
1564 }
1565+} # end setupBars
1566+
1567+#--------------------------------------------------
1568+# @brief Retrieve the fabric topolgy mode
1569+#
1570+# @details The fabric topology mode, attribute PROC_FABRIC_TOPOLOGY_MODE,
1571+# is an attribute of the top level target (sys-0), but retrieving
1572+# the value from the attribute returns a string (MODE0 or MODE1).
1573+# This string is used to get the actual value, tied that mode,
1574+# within the enumeration types.
1575+#
1576+# @param[in] $targetObj - The global target object, needed to get topology mode
1577+#
1578+# @return the numerical value of the topology mode in base 10
1579+#--------------------------------------------------
1580+sub getTopologyMode
1581+{
1582+ my $targetObj = shift;
1583+
1584+ use constant TOPOLOGY_MODE_ATTRIBUTE => "PROC_FABRIC_TOPOLOGY_MODE";
1585+
1586+ # Get topology mode from top level target
1587+ # Need to prepend "/" to the returned top level target because targets
1588+ # are mapped slightly different in the TARGETS hash vs the xml hash.
1589+ my $topologoyMode = $targetObj->getAttribute("/".$targetObj->{TOP_LEVEL},
1590+ TOPOLOGY_MODE_ATTRIBUTE);
1591+
1592+ # Return the value of the mode as defined in
1593+ # enumeration type PROC_FABRIC_TOPOLOGY_MODE
1594+ # Convert the value from hex to base 10
1595+ return hex($targetObj->{xml}->{enumerationTypes}->{enumerationType}
1596+ ->{PROC_FABRIC_TOPOLOGY_MODE}
1597+ ->{enumerator}->{$topologoyMode}->{value});
1598+}
1599+
1600+#--------------------------------------------------
1601+# @brief Convert the topology ID to a topology index.
1602+#
1603+# @details The topology ID is a 4 bit value that will be converted to a 5 bit
1604+# topology index. The topology index is an index into the topology
1605+# table.
1606+# The conversion method depends on the topology mode.
1607+# Mode ID index
1608+# MODE 0 => GGGC --> GGG0C
1609+# MODE 1 => GGCC --> GG0CC
1610+#
1611+# @param[in] $topologyId - The topology ID to convert to an index
1612+# @param[in] $topologyMode - The topology mode that determines the conversion
1613+# method. Needs to be a base 10 numeral value.
1614+#
1615+# @return a toplogy index, that is a base 10 numeral value.
1616+#--------------------------------------------------
1617+sub convertTopologyIdToIndex
1618+{
1619+ my $topologyId = shift;
1620+ my $topologyMode = shift;
1621+
1622+ use constant TOPOLOGY_MODE_1 => 1;
1623+
1624+ # Assume topology mode 0 (GGGC -> GGG0C)
1625+ my $groupMask = 0xE; # Use 0xE, 1110b, to extract 'GGG' from 'GGGC'
1626+ my $chipMask = 0x1; # Use 0x1, 0001b, to extract 'C' from 'GGGC'
1627+
1628+ # If topology mode 1 (GGCC -> GG0CC)
1629+ if (TOPOLOGY_MODE_1 == $topologyMode)
1630+ {
1631+ $groupMask = 0xC; # Use 0xC, 1100b, to extract 'GG' from 'GGCC'
1632+ $chipMask = 0x3; # Use 0x3, 0011b, to extract 'CC' from 'GGCC'
1633+ }
1634+
1635+ # Set topology index to topology ID before doing conversion
1636+ my $topologyIndex = $topologyId;
1637+
1638+ ## Turn the 4 bit topology ID into a 5 bit index
1639+ ## convert GGGC to GGG0C
1640+ ## OR GGCC to GG0CC
1641+ # If group mask equal to 0xE (mode 0) then extract 'GGG' from 'GGGC':
1642+ # 1) GGGC & 0xE (1110b) returns GGG0 then shift to left (<< 1) to get GGG00
1643+ # 2) extract C from GGGC: GGGC & 0x1 (0001b) returns C
1644+ # If group mask equal to 0xC (mode 1) then extract 'GG' from 'GGCC':
1645+ # 1) GGCC & 0xC (1100b) returns GG00 then shift to left (<< 1) to get GG000
1646+ # 2) extract CC from GGCC: GGCC & 0x3 (0011b) returns CC
1647+ # Bitwise 'OR' 1 and 2 together to produce a 5 bit index value: GGG0C OR GG0CC
1648+ # Index = 1 'OR' 2
1649+ $topologyIndex = (($topologyIndex & $groupMask) << 1) | ($topologyIndex & $chipMask);
1650+
1651+ return ($topologyIndex);
1652+}
1653+
1654+#--------------------------------------------------
1655+# @brief Get the topology ID from processor
1656+#
1657+#
1658+# @param[in] $targetObj - The global target object, needed to get topology mode
1659+# @param[in] $processorTarget - The processor target, has the attribute topology ID
1660+#
1661+# @return topology ID, that is a base 10 numeral value.
1662+#--------------------------------------------------
1663+sub getTopologyId
1664+{
1665+ my $targetObj = shift;
1666+ my $processorTarget = shift;
1667+
1668+ use constant TOPOLOGY_ID_ATTRIBUTE => "PROC_FABRIC_TOPOLOGY_ID";
1669+
1670+ # Get the topology ID from the processor.
1671+ # Convert hex value to base 10 numerical value
1672+ return hex($targetObj->getAttribute($processorTarget,
1673+ TOPOLOGY_ID_ATTRIBUTE));
1674+
1675+}
1676+
1677+#--------------------------------------------------
1678+# @brief Get the topology index, an index into the topology table.
1679+#
1680+# @details The topology index needs to be calculated using the topology mode
1681+# and the topology ID. @see convertTopologyIdToIndex for
1682+# more details
1683+#
1684+# @param[in] $targetObj - The global target object, needed to get topology mode
1685+# @param[in] $processorTarget - The processor target has the attribute topology ID
1686+#
1687+# @return a topology index, that is base 10 numeral value.
1688+#--------------------------------------------------
1689+sub getTopologyIndex
1690+{
1691+ my $targetObj = shift;
1692+ my $processorTarget = shift;
1693+
1694+ # Get the topology mode: MODE 0 (0) or MODE 1 (1)
1695+ my $topologyMode = getTopologyMode($targetObj);
1696+
1697+ # Get the topology ID from the processor.
1698+ my $topologyId = getTopologyId($targetObj, $processorTarget);
1699+
1700+ # Convert the topology ID to a topology index. The conversion method is
1701+ # based on the topology mode.
1702+ return (convertTopologyIdToIndex($topologyId, $topologyMode));
1703 }
1704
1705 #--------------------------------------------------
1706@@ -1572,10 +1828,14 @@ sub processEq
1707 $targetObj->log($target,
1708 "Processing EQ child: $child Type: $child_type");
1709
1710- if ($child_type eq "EX")
1711+ if ($child_type eq "EQ")
1712 {
1713 processEx($targetObj, $child, $chip_unit);
1714 }
1715+ elsif ($child_type eq "FC")
1716+ {
1717+ processFc($targetObj, $child, $chip_unit);
1718+ }
1719 }
1720
1721 my $value = sprintf("0x%x",
1722@@ -1584,6 +1844,35 @@ sub processEq
1723 $targetObj->setAttribute( $target, "CHIPLET_ID", $value);
1724 }
1725
1726+## FC
1727+sub processFc
1728+{
1729+ my $targetObj = shift;
1730+ my $target = shift;
1731+ my $parent_chip_unit = shift;
1732+
1733+ foreach my $child (@{ $targetObj->getTargetChildren($target) })
1734+ {
1735+ my $child_type = $targetObj->getType($child);
1736+
1737+ $targetObj->log($target,
1738+ "Processing EX child: $child Type: $child_type");
1739+
1740+ if ($child_type eq "CORE")
1741+ {
1742+ processCore($targetObj, $child);
1743+ }
1744+ }
1745+
1746+ my $value = sprintf("0x%x",
1747+ Targets::PERVASIVE_PARENT_EQ_OFFSET
1748+ + $parent_chip_unit);
1749+
1750+ $targetObj->setAttribute( $target, "CHIPLET_ID", $value);
1751+}
1752+
1753+
1754+
1755 ## EX
1756 sub processEx
1757 {
1758@@ -1672,9 +1961,9 @@ sub processMcbist
1759 ##
1760 sub processMc
1761 {
1762- # NOTE: OMI_INBAND_BAR_BASE_ADDR_OFFSET will be set for the MC
1763- # targets via a specific child OMI Target. View the
1764- # processOmi function for further details.
1765+ # NOTE: OMI_INBAND_BAR_BASE_ADDR_OFFSET will be set for the MC
1766+ # targets via a specific child OMI Target. View the
1767+ # processOmi function for further details.
1768 my $targetObj = shift;
1769 my $target = shift;
1770
1771@@ -1751,8 +2040,28 @@ sub processMcc
1772 ##
1773 sub processOmi
1774 {
1775- my $mrwObj = shift;
1776- my $omitarg = shift;
1777+ my $mrwObj = shift;
1778+ my $omitarg = shift;
1779+
1780+# TODO This may need to be updated if layout is different
1781+# ROLAND investigate this
1782+ # Map the OMI instance to its corresponding OMIC parent
1783+ my %omi_map = (4 => "omic-0",
1784+ 5 => "omic-0",
1785+ 6 => "omic-0",
1786+ 7 => "omic-1",
1787+ 2 => "omic-1",
1788+ 3 => "omic-1",
1789+ 0 => "omic-2",
1790+ 1 => "omic-2",
1791+ 12 => "omic-0",
1792+ 13 => "omic-0",
1793+ 14 => "omic-0",
1794+ 15 => "omic-1",
1795+ 10 => "omic-1",
1796+ 11 => "omic-1",
1797+ 8 => "omic-2",
1798+ 9 => "omic-2");
1799
1800 use integer;
1801 # There are a total of eight OMI units on an MC unit. So, to
1802@@ -1834,15 +2143,15 @@ sub processOmic
1803 }
1804
1805 #--------------------------------------------------
1806-## OCMB_CHIP
1807-##
1808-##
1809+# @brief OCMB_CHIP
1810+#
1811+#--------------------------------------------------
1812 sub processOcmbChip
1813 {
1814 my $targetObj = shift;
1815 my $target = shift;
1816
1817- $targetObj->setEepromAttributesForAxone($targetObj, $target);
1818+ $targetObj->setEepromAttributesForDDIMs($target);
1819 }
1820
1821 #-------------------------------------------------g
1822@@ -2032,6 +2341,7 @@ sub processXbus
1823 #For example, in wrap config, CONFIG_APPLY is expected to have "w"
1824 #If "w" is not there, then we skip the connection and mark peers
1825 #as NULL
1826+ my $system_config = $targetObj->{system_config};
1827 if (($system_config eq $wrap_config && $config =~ /$wrap_config/) ||
1828 ($system_config ne $wrap_config && $config =~ /$default_config/))
1829 {
1830@@ -2098,7 +2408,7 @@ sub processAbus
1831 # A-bus connection has to be conisdered or not
1832 # If user has passed 2N as argument, then we consider only those
1833 # A-bus connections where token "2" is present
1834-
1835+ my $system_config = $targetObj->{system_config};
1836 if($system_config eq "2N" && $config =~ /$twonode/)
1837 {
1838 #Looking for Abus connections pertaining to 2 node system only
1839@@ -2634,123 +2944,6 @@ sub processOcc
1840 $targetObj->setAttribute($target,"OCC_MASTER_CAPABLE",$master_capable);
1841 }
1842
1843-sub processMembufVpdAssociation
1844-{
1845- my $targetObj = shift;
1846- my $target = shift;
1847-
1848- my $vpds=$targetObj->findConnections($target,"I2C","VPD");
1849- if ($vpds ne "" ) {
1850- my $vpd = $vpds->{CONN}->[0];
1851- my $membuf_assocs=$targetObj->findConnections($vpd->{DEST_PARENT},
1852- "LOGICAL_ASSOCIATION","MEMBUF");
1853-
1854- if ($membuf_assocs ne "") {
1855- foreach my $membuf_assoc (@{$membuf_assocs->{CONN}}) {
1856- my $membuf_target = $membuf_assoc->{DEST_PARENT};
1857- setEepromAttributes($targetObj,
1858- "EEPROM_VPD_PRIMARY_INFO",$membuf_target,$vpd);
1859- my $index = $targetObj->getBusAttribute($membuf_assoc->{SOURCE},
1860- $membuf_assoc->{BUS_NUM}, "ISDIMM_MBVPD_INDEX");
1861- $targetObj->setAttribute(
1862- $membuf_target,"ISDIMM_MBVPD_INDEX",$index);
1863- $targetObj->setAttribute($membuf_target,
1864- "VPD_REC_NUM",$targetObj->{vpd_num});
1865- }
1866- }
1867- my $group_assocs=$targetObj->findConnections($vpd->{DEST_PARENT},
1868- "LOGICAL_ASSOCIATION","CARD");
1869-
1870- if ($group_assocs ne "") {
1871- foreach my $group_assoc (@{$group_assocs->{CONN}}) {
1872- my $mb_target = $group_assoc->{DEST_PARENT};
1873- my $group_target = $targetObj->getTargetParent($mb_target);
1874- $targetObj->setAttribute($group_target,
1875- "VPD_REC_NUM",$targetObj->{vpd_num});
1876- }
1877- }
1878- $targetObj->{vpd_num}++;
1879- }
1880-}
1881-
1882-#--------------------------------------------------
1883-## MEMBUF
1884-##
1885-## Finds I2C connections to DIMM and creates EEPROM attributes
1886-## FYI: I had to handle DMI busses in framework because they
1887-## define affinity path
1888-sub processMembuf
1889-{
1890- my $targetObj = shift;
1891- my $membufTarg = shift;
1892- if ($targetObj->isBadAttribute($membufTarg, "PHYS_PATH", ""))
1893- {
1894- ##dmi is probably not connected. will get caught in error checking
1895- return;
1896- }
1897-
1898- processMembufVpdAssociation($targetObj,$membufTarg);
1899-
1900- ## find port mapping
1901- my %dimm_portmap;
1902- foreach my $child (@{$targetObj->getTargetChildren($membufTarg)})
1903- {
1904- if ($targetObj->getType($child) eq "MBA")
1905- {
1906- # find this MBA's position relative to the membuf
1907- my $mba_num = $targetObj->getAttribute($child,"MBA_NUM");
1908- # follow the DDR4 bus connection to find the 'ddr' targets
1909- my $ddrs = $targetObj->findConnections($child,"DDR4","");
1910-
1911- if($ddrs eq "")
1912- {
1913- # on multi node system there is a possibility that either
1914- # DDR4 or DDR3 dimms are connected under a node
1915- my $ddrs = $targetObj->findConnections($child,"DDR3","");
1916- }
1917-
1918- if ($ddrs ne "")
1919- {
1920- foreach my $ddr (@{$ddrs->{CONN}})
1921- {
1922- my $port_num = $targetObj->getDimmPort($ddr->{SOURCE});
1923- my $dimm_num = $targetObj->getDimmPos($ddr->{SOURCE});
1924- my $map = oct("0b".$mba_num.$port_num.$dimm_num);
1925- $dimm_portmap{$ddr->{DEST_PARENT}} = $map;
1926- }
1927- }
1928- }
1929- }
1930-
1931-
1932- ## Process MEMBUF to DIMM I2C connections
1933- my @addr_map=('0','0','0','0','0','0','0','0');
1934- my $dimms=$targetObj->findConnections($membufTarg,"I2C","SPD");
1935- if ($dimms ne "") {
1936- foreach my $dimm (@{$dimms->{CONN}}) {
1937- my $dimm_target = $targetObj->getTargetParent($dimm->{DEST_PARENT});
1938- setEepromAttributes($targetObj,
1939- "EEPROM_VPD_PRIMARY_INFO",$dimm_target,
1940- $dimm);
1941-
1942- my $field=getI2cMapField($targetObj,$dimm_target,$dimm);
1943- my $map = $dimm_portmap{$dimm_target};
1944-
1945- if ($map eq "") {
1946- print "ERROR: $dimm_target doesn't map to a dimm/port\n";
1947- $targetObj->myExit(3);
1948- }
1949- $addr_map[$map] = $field;
1950- }
1951- }
1952- $targetObj->setAttribute($membufTarg,
1953- "MRW_MEM_SENSOR_CACHE_ADDR_MAP","0x".join("",@addr_map));
1954-
1955- ## Update bus speeds
1956- processI2cSpeeds($targetObj,$membufTarg);
1957-
1958- processPowerRails($targetObj, $membufTarg);
1959-}
1960
1961 sub getI2cMapField
1962 {
1963@@ -2794,7 +2987,7 @@ sub getI2cMapField
1964 return $hexfield;
1965 }
1966
1967-#------------------------------------------------------------------------------
1968+#--------------------------------------------------
1969 # I2C
1970 #
1971 sub processI2C
1972@@ -3253,7 +3446,9 @@ sub get_max_compute_nodes
1973 }
1974
1975 #--------------------------------------------------
1976-## ERROR checking
1977+# @brief Error checking
1978+#
1979+#--------------------------------------------------
1980 sub errorCheck
1981 {
1982 my $targetObj = shift;
1983@@ -3363,9 +3558,9 @@ Options:
1984 2N = special 2 node config with extra ABUS links
1985 w = Special MST wrap config
1986 -o = output filename
1987- -s [SDR XML file] = import SDRs
1988 -r = create report and save to [system_name].rpt
1989- -v = version
1990+ -v = display current version
1991+ -t = run self test
1992 ";
1993 exit(1);
1994 }
1995@@ -3380,8 +3575,216 @@ sub do_plugin
1996 {
1997 $hwsvmrw_plugins{$step}(@_);
1998 }
1999- elsif ($debug && ($build eq "fsp"))
2000+ elsif ($targetObj->{debug} && ($targetObj->{build} eq "fsp"))
2001+ {
2002+ print STDERR "build is $targetObj->{build} but no plugin for $step\n";
2003+ }
2004+}
2005+
2006+###############################################################################
2007+# Self tests
2008+###############################################################################
2009+#--------------------------------------------------
2010+# @brief The main procedure to run the tests
2011+#
2012+# @param[in] $targetObj - The global target object
2013+#--------------------------------------------------
2014+sub runTests
2015+{
2016+ print "\nRunning tests: \n\n";
2017+ my $targetObj = shift;
2018+
2019+ # Load the XML and process the file, extracting targets and associating
2020+ # attributes, with their data, to the targets
2021+ loadXmlFile();
2022+
2023+ # Process the targets, setting the targets attributes.
2024+ processTargets();
2025+
2026+ # Each one of the test build on each other, if one fails then no point in
2027+ # running the other
2028+ testGetTopologyMode($targetObj) &&
2029+ testTopologyIdToTopologyIndex() &&
2030+ testGetTopologyIndex($targetObj);
2031+}
2032+
2033+#--------------------------------------------------
2034+# @brief Test the method that gets the topology mode.
2035+#
2036+# @param[in] $targetObj - The global target object
2037+#
2038+# @return true if test passed, false other wise
2039+#--------------------------------------------------
2040+sub testGetTopologyMode
2041+{
2042+ print ">> Running testgetTopologyMode \n";
2043+ my $targetObj = shift;
2044+
2045+ my $testPassed = true;
2046+
2047+ use constant TOPOLOGY_MODE_ATTRIBUTE => "PROC_FABRIC_TOPOLOGY_MODE";
2048+ use constant TOPOLOGY_MODES => qw/ MODE0 MODE1 /;
2049+ my @topologyModes = (TOPOLOGY_MODES);
2050+
2051+ # Cache the current mode to restore later
2052+ my $persistMode = $targetObj->getAttribute("/".$targetObj->{TOP_LEVEL},
2053+ TOPOLOGY_MODE_ATTRIBUTE);
2054+
2055+ # Test getting the topology mode
2056+ foreach my $topologyMode (@topologyModes)
2057 {
2058- print STDERR "build is $build but no plugin for $step\n";
2059+ $targetObj->setAttribute("/".$targetObj->{TOP_LEVEL},
2060+ TOPOLOGY_MODE_ATTRIBUTE,
2061+ $topologyMode);
2062+ my $topologyModeNumber = chop($topologyMode);
2063+ if (getTopologyMode($targetObj) != $topologyModeNumber)
2064+ {
2065+
2066+ $testPassed = false;
2067+ print "ERROR: Expected topology mode '$topologyModeNumber' but got " .
2068+ getTopologyMode($targetObj) . "\n";
2069+ }
2070 }
2071+
2072+ # Restore mode
2073+ $targetObj->setAttribute("/".$targetObj->{TOP_LEVEL},
2074+ TOPOLOGY_MODE_ATTRIBUTE,
2075+ $persistMode);
2076+
2077+ print "<< Running testgetTopologyMode: test " .
2078+ getPassFailString($testPassed) . "\n";
2079+
2080+ return $testPassed;
2081 }
2082+
2083+#--------------------------------------------------
2084+# @brief Tests the conversion method that converts the topology ID,
2085+# with given topology mode, to the topology index.
2086+#
2087+# @return true if test passed, false other wise
2088+#--------------------------------------------------
2089+sub testTopologyIdToTopologyIndex
2090+{
2091+ print ">> Running testTopologyIdToTopologyIndex \n";
2092+
2093+ my $testPassed = true;
2094+
2095+ # The different values expected when mode is 0 or 1
2096+ use constant TOPOLOGY_MODE_0_ARRAY => qw/ 0 1 4 5 8 9 12 13 16 17 20 21 24 25 28 29 /;
2097+ use constant TOPOLOGY_MODE_1_ARRAY => qw/ 0 1 2 3 8 9 10 11 16 17 18 19 24 25 26 27 /;
2098+
2099+ # The different topology modes
2100+ use constant TOPOLOGY_MODES => qw/ MODE0 MODE1 /;
2101+ my @topologyModes = (TOPOLOGY_MODES);
2102+
2103+ # Default with mode 0
2104+ my @toplogyModeArray = (TOPOLOGY_MODE_0_ARRAY);
2105+
2106+ # Test the conversion on the different IDs and modes
2107+ for my $topologyMode (@topologyModes)
2108+ {
2109+ my $topologyModeNumber = chop($topologyMode);
2110+ if (1 == $topologyModeNumber)
2111+ {
2112+ @toplogyModeArray = (TOPOLOGY_MODE_1_ARRAY);
2113+ }
2114+
2115+ # Needed variable
2116+ my $topologyIndex = 0;
2117+
2118+ # Iterate thru each permutation of the topology ID and
2119+ # test conversion to index
2120+ for (my $topologyId = 0; $topologyId < 16; ++$topologyId)
2121+ {
2122+ $topologyIndex = convertTopologyIdToIndex($topologyId,
2123+ $topologyModeNumber);
2124+ if ($topologyIndex != $toplogyModeArray[$topologyId])
2125+ {
2126+ $testPassed = false;
2127+ print "ERROR: conversion on topology Id($topologyId) with ";
2128+ print "topology mode($topologyMode) returned ";
2129+ print "topology index($topologyIndex), but expected ";
2130+ print "topology index($toplogyModeArray[$topologyId]) \n";
2131+ }
2132+ } # end for (my $topologyId = 0 ...
2133+ } # end foreach my $topologyMode (@topologyModes)
2134+
2135+ print "<< Running testTopologyIdToTopologyIndex: test " .
2136+ getPassFailString($testPassed) . "\n";
2137+
2138+ return $testPassed;
2139+}
2140+
2141+#--------------------------------------------------
2142+# @brief Test the method that gets the topology index based
2143+# based on the current processors within the MRW XML
2144+#
2145+# @param[in] $targetObj - The global target object
2146+#
2147+# @return true if test passed, false other wise
2148+#--------------------------------------------------
2149+sub testGetTopologyIndex
2150+{
2151+ my $targetObj = shift;
2152+
2153+ my $testPassed = true;
2154+
2155+ my $system_name = $targetObj->getAttribute('/sys-0',"SYSTEM_NAME");
2156+ if ($system_name =~ /RAINIER/i)
2157+ {
2158+ print ">> Running testGetTopologyIndex \n";
2159+
2160+ # The different procs available
2161+ use constant PROC_0 => "/sys-0/node-0/nisqually-0/proc_socket-0/godel-0/power10-0";
2162+ use constant PROC_1 => "/sys-0/node-0/nisqually-0/proc_socket-0/godel-0/power10-1";
2163+
2164+ # Get processor 1's index
2165+ my $processorTarget = PROC_0;
2166+ my $topologyIndex = getTopologyIndex($targetObj, $processorTarget);
2167+
2168+ # For the current MRW, proc 0 has index 0 with mode 0
2169+ my $expectedTopologyIndex = 0;
2170+ if ($topologyIndex != $expectedTopologyIndex)
2171+ {
2172+ $testPassed = false;
2173+ my @fullProc = split(/\//, $processorTarget);
2174+ print "ERROR: retrieved topology index $topologyIndex for processor " .
2175+ "@fullProc[-1] but expected $expectedTopologyIndex \n";
2176+ }
2177+
2178+ # Get processor 2's index
2179+ $processorTarget = PROC_1;
2180+ $topologyIndex = getTopologyIndex($targetObj, $processorTarget);
2181+
2182+ # For the current MRW, proc 1 has index 4 with mode 0
2183+ $expectedTopologyIndex = 4;
2184+ if ($topologyIndex != $expectedTopologyIndex)
2185+ {
2186+ $testPassed = false;
2187+ my @fullProc = split(/\//, $processorTarget);
2188+ print "ERROR: retrieved topology index $topologyIndex for processor " .
2189+ "@fullProc[-1] but expected $expectedTopologyIndex \n";
2190+ }
2191+
2192+ print "<< Running testGetTopologyIndex: test " .
2193+ getPassFailString($testPassed) . "\n";
2194+
2195+ } # end if ($system_name =~ /RAINIER/i)
2196+
2197+ return $testPassed;
2198+}
2199+
2200+sub getPassFailString
2201+{
2202+ my $passFailBoolean = shift;
2203+ my $failPassString = "passed";
2204+
2205+ if ($passFailBoolean == false)
2206+ {
2207+ $failPassString = "failed";
2208+ }
2209+
2210+ return $failPassString;
2211+}
2212+
2213+
2214--
22151.8.2.2
2216