blob: 6eecc7bda4659f42b41fb08b85fa9091978a5efd [file] [log] [blame]
Matt Ploetz940dcf62015-02-13 13:52:56 -06001From 065fd1bc3d9fcc8b06be7564f8df162580f8775e Mon Sep 17 00:00:00 2001
Matt Ploetzed8800a2015-02-10 13:12:24 -06002From: Matt Ploetz <maploetz@us.ibm.com>
Matt Ploetz940dcf62015-02-13 13:52:56 -06003Date: Fri, 13 Feb 2015 10:41:12 -0600
4Subject: [PATCH] New severwiz2 scripts up to support up to commit
5 44fde6512e834ea8f5071299ca99b35973c0f979
Matt Ploetzed8800a2015-02-10 13:12:24 -06006
Matt Ploetz940dcf62015-02-13 13:52:56 -06007Change-Id: I3df49506aad9490f5f6e1840fa5e6afe3150492d
Matt Ploetzed8800a2015-02-10 13:12:24 -06008---
9 src/build/mkrules/dist.targets.mk | 3 +-
10 src/usr/targeting/common/Targets.pm | 1446 ++++++++++++++++++++++++++++++++
Matt Ploetz940dcf62015-02-13 13:52:56 -060011 src/usr/targeting/common/processMrw.pl | 1144 +++++++++++++++++++++++++
12 3 files changed, 2592 insertions(+), 1 deletion(-)
Matt Ploetzed8800a2015-02-10 13:12:24 -060013 create mode 100755 src/usr/targeting/common/Targets.pm
14 create mode 100755 src/usr/targeting/common/processMrw.pl
15
16diff --git a/src/build/mkrules/dist.targets.mk b/src/build/mkrules/dist.targets.mk
Matt Ploetz940dcf62015-02-13 13:52:56 -060017index ca28150..4b541ce 100644
Matt Ploetzed8800a2015-02-10 13:12:24 -060018--- a/src/build/mkrules/dist.targets.mk
19+++ b/src/build/mkrules/dist.targets.mk
Matt Ploetz940dcf62015-02-13 13:52:56 -060020@@ -74,7 +74,8 @@ COPY_FILES = \
Matt Ploetzed8800a2015-02-10 13:12:24 -060021 src/usr/hwpf/hwp/initfiles/sample.initfile:tools \
22 src/build/buildpnor/buildSbePart.pl:openpower \
23 src/build/buildpnor/buildpnor.pl:openpower \
24- src/usr/targeting/common/genHwsvMrwXml.pl:openpower \
25+ src/usr/targeting/common/processMrw.pl:openpower \
26+ src/usr/targeting/common/Targets.pm:openpower \
27 src/usr/targeting/common/xmltohb/mergexml.sh:openpower \
28 src/usr/targeting/common/xmltohb/attribute_types.xml:openpower \
29 src/usr/targeting/common/xmltohb/attribute_types_hb.xml:openpower \
30diff --git a/src/usr/targeting/common/Targets.pm b/src/usr/targeting/common/Targets.pm
31new file mode 100755
Matt Ploetz940dcf62015-02-13 13:52:56 -060032index 0000000..53568cf
Matt Ploetzed8800a2015-02-10 13:12:24 -060033--- /dev/null
34+++ b/src/usr/targeting/common/Targets.pm
35@@ -0,0 +1,1446 @@
36+# IBM_PROLOG_BEGIN_TAG
37+# This is an automatically generated prolog.
38+#
39+# $Source: src/usr/targeting/common/Targets.pm $
40+#
41+# OpenPOWER HostBoot Project
42+#
43+# Contributors Listed Below - COPYRIGHT 2015
44+# [+] International Business Machines Corp.
45+#
46+#
47+# Licensed under the Apache License, Version 2.0 (the "License");
48+# you may not use this file except in compliance with the License.
49+# You may obtain a copy of the License at
50+#
51+# http://www.apache.org/licenses/LICENSE-2.0
52+#
53+# Unless required by applicable law or agreed to in writing, software
54+# distributed under the License is distributed on an "AS IS" BASIS,
55+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
56+# implied. See the License for the specific language governing
57+# permissions and limitations under the License.
58+#
59+# IBM_PROLOG_END_TAG
60+package Targets;
61+
62+use strict;
63+use XML::Simple;
64+use Data::Dumper;
65+
66+sub new
67+{
68+ my $class = shift;
69+ my $self = {
70+ xml => undef,
71+ data => undef,
72+ targeting => undef,
73+ enumerations => undef,
74+ MAX_MCS => 0,
75+ master_proc => undef,
76+ huid_idx => undef,
77+ mru_idx => undef,
78+ force => 0,
79+ debug => 0,
80+ version => "",
81+ errorsExist => 0,
82+ NUM_PROCS => 0,
83+ TOP_LEVEL => "sys-0",
84+ TOPOLOGY => undef,
85+ DMI_FSI_MAP => {
86+ '0' => '3',
87+ '1' => '2',
88+ '4' => '7',
89+ '5' => '6'
90+ }
91+ # TODO RTC: TBD
92+ # DMI_FSI_MAP is a lookup table for DMI channel to FSI and ref clock.
93+ # It is processor specific and needs to be pulled from a
94+ # processor attribute instead of being hardcoded
95+
96+ };
97+ return bless $self, $class;
98+}
99+
100+sub setVersion
101+{
102+ my $self = shift;
103+ my $version = shift;
104+
105+ $self->{version} = $version;
106+}
107+
108+sub getData
109+{
110+ my $self = shift;
111+ return $self->{data};
112+}
113+
114+## loads ServerWiz XML format
115+sub loadXML
116+{
117+ my $self = shift;
118+ my $filename = shift;
119+ $XML::Simple::PREFERRED_PARSER = 'XML::Parser';
120+ print "Loading MRW XML: $filename\n";
121+ $self->{xml} =
122+ XMLin($filename,forcearray => [ 'child_id', 'hidden_child_id', 'bus',
123+ 'property' ]);
124+ $self->storeEnumerations();
125+ $self->buildHierarchy($self->{TOP_LEVEL});
126+ $self->buildAffinity();
127+}
128+
129+################################################
130+## prints out final XML for HOSTBOOT consumption
131+
132+sub printXML
133+{
134+ my $self = shift;
135+ my $fh = shift;
136+ my $t = shift;
137+
138+ my $atTop = 0;
139+ if ($t eq "top")
140+ {
141+ $atTop = 1;
142+ $t = $self->{targeting}->{SYS};
143+ print $fh "<attributes>\n";
144+ print $fh "<version>" . $self->{version} . "</version>\n";
145+ }
146+ if (ref($t) ne "ARRAY")
147+ {
148+ return;
149+ }
150+ for (my $p = 0; $p < scalar(@{$t}); $p++)
151+ {
152+ if (ref($t->[$p]) ne "HASH") { next; }
153+ my $target = $t->[$p]->{KEY};
154+ $self->printTarget($fh, $target);
155+ my $children = $t->[$p];
156+ foreach my $u (sort(keys %{$children}))
157+ {
158+ if ($u ne "KEY")
159+ {
160+ $self->printXML($fh, $t->[$p]->{$u});
161+ }
162+ }
163+ }
164+ if ($atTop)
165+ {
166+ print $fh "</attributes>\n";
167+ }
168+}
169+
170+sub printTarget
171+{
172+ my $self = shift;
173+ my $fh = shift;
174+ my $target = shift;
175+
176+ my $target_ptr = $self->getTarget($target);
177+ print $fh "<targetInstance>\n";
178+ my $target_id = $self->getAttribute($target, "PHYS_PATH");
179+ $target_id = substr($target_id, 9);
180+ $target_id =~ s/\///g;
181+ $target_id =~ s/\-//g;
182+ print $fh "\t<id>" . $target_id . "</id>\n";
183+ print $fh "\t<type>" . $self->getTargetType($target) . "</type>\n";
184+
185+ ## get attributes
186+ foreach my $attr (sort (keys %{ $target_ptr->{ATTRIBUTES} }))
187+ {
188+ $self->printAttribute($fh, $target_ptr->{ATTRIBUTES}, $attr);
189+ }
190+ print $fh "</targetInstance>\n";
191+}
192+
193+sub printAttribute
194+{
195+ my $self = shift;
196+ my $fh = shift;
197+ my $target_ptr = shift;
198+ my $attribute = shift;
199+ my $r = "";
200+
201+ # TODO RTC: TBD
202+ # temporary until we converge attribute types
203+ my %filter;
204+ $filter{MRW_TYPE} = 1;
205+ $filter{INSTANCE_PATH} = 1;
206+ $filter{SYSTEM_NAME} = 1;
207+ $filter{BUS_TYPE} = 1;
208+ $filter{DIRECTION} = 1;
209+ $filter{ENABLE_CAPI} = 1;
210+ $filter{PCIE_CONFIG_NUM} = 1;
211+ $filter{PCIE_LANE_MASK} = 1;
212+ $filter{PCIE_LANE_SET} = 1;
213+ $filter{PCIE_NUM_LANES} = 1;
214+ $filter{PHB_NUM} = 1;
215+ $filter{IOP_NUM} = 1;
216+ $filter{LOCATION_CODE} = 1;
217+ $filter{MCS_NUM} = 1;
218+ $filter{SCHEMATIC_INTERFACE} = 1;
219+ $filter{ENTITY_ID} = 1;
220+ $filter{CLASS} = 1;
221+ $filter{MODEL} = 1;
222+ $filter{TYPE} = 1;
223+ $filter{CDM_POLICIES} = 1;
224+ $filter{ALL_MCS_IN_INTERLEAVING_GROUP} = 1;
225+ $filter{MSS_INTERLEAVE_ENABLE} = 1;
226+ $filter{CDM_POLICIES_BITMASK} = 1;
227+ $filter{ENTITY_ID_LOOKUP} = 1;
228+ $filter{ENTITY_INSTANCE} = 1;
229+ $filter{MBA_NUM} = 1;
230+ $filter{IPMI_INSTANCE} = 1;
231+ $filter{INSTANCE_ID} = 1;
Matt Ploetz940dcf62015-02-13 13:52:56 -0600232+ $filter{ADC_CHANNEL_SENSOR_NUMBERS} = 1;
Matt Ploetzed8800a2015-02-10 13:12:24 -0600233+
234+ if ($filter{$attribute} == 1)
235+ {
236+ return;
237+ }
238+ print $fh "\t<attribute>\n";
239+ print $fh "\t\t<id>$attribute</id>\n";
240+ my $value = $target_ptr->{$attribute}->{default};
241+
242+ if (ref($value) eq "HASH")
243+ {
244+ if (defined($value->{field}))
245+ {
246+ print $fh "\t\t<default>\n";
247+ foreach my $f (sort keys %{ $value->{field} })
248+ {
249+ my $v = $value->{field}->{$f}->{value};
250+ print $fh "\t\t\t<field><id>$f</id><value>$v</value></field>\n";
251+ }
252+ print $fh "\t\t</default>\n";
253+ }
254+ }
255+ else
256+ {
257+ print $fh "\t\t<default>$value</default>\n";
258+ }
259+ print $fh "\t</attribute>\n";
260+}
261+
262+## stores TYPE enumeration values which is used to generate HUIDs
263+sub storeEnumerations
264+{
265+ my $self = shift;
266+
267+ foreach my $enumType (keys(%{ $self->{xml}->{enumerationType} }))
268+ {
269+ foreach my $enum (
270+ keys(%{$self->{xml}->{enumerationType}->{$enumType}->{enumerator}}))
271+ {
272+ $self->{enumeration}->{$enumType}->{$enum} =
273+ $self->{xml}->{enumerationType}->{$enumType}->{enumerator}
274+ ->{$enum}->{value};
275+ }
276+ }
277+}
278+
279+####################################################
280+## build target hierarchy recursively
281+##
282+## creates convenient data structure
283+## for accessing targets and busses
284+## Structure:
285+##
286+##{TARGETS} # location of all targets
287+##{NSTANCE_PATH} # keeps track of hierarchy
288+## path while iterating
289+##{TARGETS} -> target_name # specific target
290+##{TARGETS} -> target_name -> {TARGET} # pointer to target data
291+## from XML data struture
292+##{TARGETS} -> target_name -> {TYPE}# special attribute
293+##{TARGETS} -> target_name -> {PARENT} # parent target name
294+##{TARGETS} -> target_name -> {CHILDREN} # array of children targets
295+##{TARGETS} -> target_name -> {CONNECTION} -> {DEST} # array of connection
296+## destination targets
297+##{TARGETS} -> target_name -> {CONNECTION} -> {BUS} # array of busses
298+##{TARGETS} -> target_name -> {CHILDREN} # array of children targets
299+##{TARGETS} -> target_name -> {ATTRIBUTES} # attributes
300+## {ENUMERATION} -> enumeration_type -> enum # value of enumeration
301+## {BUSSES} -> bus_type[] # array of busses by
302+## bus_type (I2C, FSI, etc)
303+## {BUSSES} -> bus_type[] -> {BUS} # pointer to bus target
304+## from xml structure
305+## {BUSSES} -> bus_type[] -> {SOURCE_TARGET} # source target name
306+## {BUSSES} -> bus_type[] -> {DEST_TARGET} # dest target name
307+
308+sub buildHierarchy
309+{
310+ my $self = shift;
311+ my $target = shift;
312+
313+ my $old_path = $self->{data}->{INSTANCE_PATH};
314+ my $target_xml = $self->{xml}->{'targetInstance'}{$target};
315+ my $affinity_target = $target;
316+ my $key = $self->{data}->{INSTANCE_PATH} . "/" . $target;
317+
318+ my $instance_path = $self->{data}->{INSTANCE_PATH};
319+ $instance_path = "instance:" . substr($instance_path, 1);
320+ $self->setAttribute($key, "INSTANCE_PATH", $instance_path);
321+ $self->{data}->{TARGETS}->{$key}->{TARGET} = $target_xml;
322+ $self->{data}->{INSTANCE_PATH} = $old_path . "/" . $target;
323+
324+ ## copy attributes
Matt Ploetz940dcf62015-02-13 13:52:56 -0600325+
Matt Ploetzed8800a2015-02-10 13:12:24 -0600326+ foreach my $attribute (keys %{ $target_xml->{attribute} })
327+ {
328+ my $value = $target_xml->{attribute}->{$attribute}->{default};
329+ if (ref($value) eq "HASH")
330+ {
331+ if (defined($value->{field}))
332+ {
333+ foreach my $f (keys %{ $value->{field} })
334+ {
335+ my $field_val=$value->{field}{$f}{value};
336+ if (ref($field_val)) {
337+ $self->setAttributeField($key, $attribute, $f,"");
338+ }
339+ else
340+ {
341+ $self->setAttributeField($key, $attribute, $f,
342+ $value->{field}{$f}{value});
343+ }
344+ }
345+ }
346+ else
347+ {
348+ $self->setAttribute($key, $attribute, "");
349+ }
350+ }
351+ else
352+ {
353+ $self->setAttribute($key, $attribute, $value);
354+ }
355+ }
Matt Ploetz940dcf62015-02-13 13:52:56 -0600356+ ## global attributes overwrite local
Matt Ploetzed8800a2015-02-10 13:12:24 -0600357+ foreach my $prop (keys %{$self->{xml}->{globalSetting}->{$key}->{property}})
358+ {
359+ my $val=$self->{xml}->{globalSetting}->{$key}->{property}->
360+ {$prop}->{value};
361+ $self->setAttribute($key, $prop, $val);
362+ }
363+
364+ ## Save busses
365+ if (defined($target_xml->{bus}))
366+ {
367+ foreach my $b (@{ $target_xml->{bus} })
368+ {
369+ my $source_target =
370+ $key . "/" . $b->{source_path} . $b->{source_target};
371+ my $dest_target = $key . "/" . $b->{dest_path} . $b->{dest_target};
372+ my $bus_type = $b->{bus_type};
373+ push(
374+ @{
375+ $self->{data}->{TARGETS}->{$source_target}->{CONNECTION}
376+ ->{DEST}
377+ },
378+ $dest_target
379+ );
380+ push(
381+ @{
382+ $self->{data}->{TARGETS}->{$source_target}->{CONNECTION}
383+ ->{BUS}
384+ },
385+ $b
386+ );
387+ my %bus_entry;
388+ $bus_entry{SOURCE_TARGET} = $source_target;
389+ $bus_entry{DEST_TARGET} = $dest_target;
390+ $bus_entry{BUS_TARGET} = $b;
391+ push(@{ $self->{data}->{BUSSES}->{$bus_type} }, \%bus_entry);
392+ }
393+ }
394+
395+ foreach my $child (@{ $target_xml->{child_id} })
396+ {
397+ my $child_key = $self->{data}->{INSTANCE_PATH} . "/" . $child;
398+ $self->{data}->{TARGETS}->{$child_key}->{PARENT} = $key;
399+ push(@{ $self->{data}->{TARGETS}->{$key}->{CHILDREN} }, $child_key);
400+ $self->buildHierarchy($child);
401+ }
402+ foreach my $child (@{ $target_xml->{hidden_child_id} })
403+ {
404+ my $child_key = $self->{data}->{INSTANCE_PATH} . "/" . $child;
405+ $self->{data}->{TARGETS}->{$child_key}->{PARENT} = $key;
406+ push(@{ $self->{data}->{TARGETS}->{$key}->{CHILDREN} }, $child_key);
407+ $self->buildHierarchy($child);
408+ }
409+ $self->{data}->{INSTANCE_PATH} = $old_path;
410+
411+}
412+
413+##########################################################
414+## traces busses and builds affinity hierarchy
415+## HOSTBOOT expected hierarchy: sys/node/proc/<unit>
416+## sys/node/proc/mcs/membuf/<unit>
417+## sys/node/proc/mcs/membuf/mba/dimm
418+
419+sub buildAffinity
420+{
421+ my $self = shift;
422+ my $node = -1;
423+ my $proc = -1;
424+ my $node_phys = "";
425+ my $node_aff = "";
426+ my $core_num = 0;
427+ $self->{membuf_inst_num}=0;
428+ foreach my $target (sort keys %{ $self->{data}->{TARGETS} })
429+ {
430+ my $target_ptr = $self->{data}->{TARGETS}{$target};
431+ my $type = $self->getType($target);
432+ my $type_id = $self->getEnumValue("TYPE", $type);
433+ if ($type_id eq "") { $type_id = 0; }
434+
435+ if ($type eq "SYS")
436+ {
437+ $proc = -1;
438+ $node = -1;
Matt Ploetz940dcf62015-02-13 13:52:56 -0600439+
Matt Ploetzed8800a2015-02-10 13:12:24 -0600440+ $self->{targeting}{SYS}[0]{KEY} = $target;
441+ $self->setAttribute($target, "AFFINITY_PATH", "affinity:sys-0");
442+ $self->setAttribute($target, "PHYS_PATH", "physical:sys-0");
443+ $self->setAttribute($target, "ENTITY_INSTANCE","0");
444+ }
445+ elsif ($type eq "NODE")
446+ {
447+ $core_num = 0;
448+ $proc = -1;
449+ $self->{dimm_tpos} = 0;
450+ $self->{membuf_inst_num}=0;
451+ $node++;
452+ $node_phys = "physical:sys-0/node-$node";
453+ $node_aff = "affinity:sys-0/node-$node";
454+ $self->{targeting}{SYS}[0]{NODES}[$node]{KEY} = $target;
455+ $self->setAttribute($target, "AFFINITY_PATH",
456+ "affinity:sys-0/node-$node");
457+ $self->setAttribute($target, "PHYS_PATH",
458+ "physical:sys-0/node-$node");
459+ $self->setHuid($target, 0, $node);
460+ $self->setAttribute($target, "ENTITY_INSTANCE",$node);
461+ }
462+ elsif ($type eq "PROC")
463+ {
464+ $proc++;
465+ my $num_mcs = 0;
466+ ### count number of MCSs
467+ foreach my $unit (@{ $self->{data}->{TARGETS}{$target}{CHILDREN} })
468+ {
469+ my $unit_type = $self->getType($unit);
470+ if ($unit_type eq "MCS")
471+ {
472+ $num_mcs++;
473+ }
474+ }
475+ if ($num_mcs > $self->{MAX_MCS})
476+ {
477+ $self->{MAX_MCS} = $num_mcs;
478+ }
479+ $self->{NUM_PROCS_PER_NODE} = $proc + 1;
480+ $self->{targeting}->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{KEY} =
481+ $target;
Matt Ploetz940dcf62015-02-13 13:52:56 -0600482+
Matt Ploetzed8800a2015-02-10 13:12:24 -0600483+ $self->setHuid($target, 0, $node);
484+ my $socket = $self->getTargetParent(
485+ $self->getTargetParent($target));
486+ my $parent_affinity = "affinity:sys-0/node-$node/proc-$proc";
487+ my $parent_physical = "physical:sys-0/node-$node/proc-$proc";
488+ $self->setAttribute($target, "AFFINITY_PATH", $parent_affinity);
489+ $self->setAttribute($target, "PHYS_PATH", $parent_physical);
490+ $self->setAttribute($target, "POSITION", $proc);
491+ $self->setAttribute($target, "ENTITY_INSTANCE",$proc);
492+ $self->setAttribute($target, "FABRIC_NODE_ID",
493+ $self->getAttribute($socket,"FABRIC_NODE_ID"));
494+ $self->setAttribute($target, "FABRIC_CHIP_ID",
495+ $self->getAttribute($socket,"FABRIC_CHIP_ID"));
496+
497+ $self->setAttribute($target, "VPD_REC_NUM", $proc);
498+
499+
500+ foreach my $unit (@{ $self->{data}->{TARGETS}{$target}{CHILDREN} })
501+ {
502+ my $unit_ptr = $self->getTarget($unit);
503+ my $unit_type = $self->getType($unit);
504+ my $unit_type_id = $self->getEnumValue("TYPE", $unit_type);
505+ if ( $unit_type_id eq "" || $unit_type eq "FSI"
506+ || $unit_type eq "MCS")
507+ {
508+ $unit_type_id = 0;
509+ }
510+
511+ ## don't want non-hostboot targets
512+ if ($unit_type_id > 0)
513+ {
Matt Ploetz940dcf62015-02-13 13:52:56 -0600514+
Matt Ploetzed8800a2015-02-10 13:12:24 -0600515+ push(@{$self->{targeting}
516+ ->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{$unit_type}},
517+ { 'KEY' => $unit });
518+ my $affinity_path =
519+ $parent_affinity . "/"
520+ . $self->getTarget($unit)->{TARGET}->{instance_name};
521+ my $physical_path =
522+ $parent_physical . "/"
523+ . $self->getTarget($unit)->{TARGET}->{instance_name};
524+ $self->setAttribute($unit, "AFFINITY_PATH",$affinity_path);
525+ $self->setAttribute($unit, "PHYS_PATH", $physical_path);
526+ $self->setHuid($unit, 0, $node);
527+ if ($unit_type eq "OCC")
528+ {
Matt Ploetz940dcf62015-02-13 13:52:56 -0600529+ $self->setAttribute($unit, "ENTITY_INSTANCE",$proc);
Matt Ploetzed8800a2015-02-10 13:12:24 -0600530+ }
531+ ## export core
532+ if ($unit_type eq "EX")
533+ {
534+ my $core_unit_num = $self->getAttribute($unit,
535+ "CHIP_UNIT");
536+
537+ my $core_unit =
538+ $self->{data}->{TARGETS}{$unit}{CHILDREN}[0];
539+ push(
540+ @{
541+ $self->{targeting}
542+ ->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{CORE}
543+ },
544+ { 'KEY' => $core_unit }
545+ );
546+ my $core_affinity_path =
547+ $affinity_path . "/"
548+ . $self->getTarget($core_unit)->{TARGET}
549+ ->{instance_name};
550+ my $core_physical_path =
551+ $physical_path . "/"
552+ . $self->getTarget($core_unit)->{TARGET}
553+ ->{instance_name};
554+ $self->setAttribute($core_unit, "AFFINITY_PATH",
555+ $core_affinity_path);
556+ $self->setAttribute($core_unit, "PHYS_PATH",
557+ $core_physical_path);
558+ $self->setAttribute($core_unit, "CHIP_UNIT",
559+ $core_unit_num);
560+ $self->setHuid($core_unit, 0, $node);
561+ $self->setAttribute($core_unit, "ENTITY_INSTANCE",
562+ $core_num);
563+ $core_num++;
564+ }
565+ }
566+ elsif ($unit_type eq "MCS")
567+ {
568+ $self->processMcs($unit, $node, $proc, $parent_affinity,
569+ $parent_physical, $node_phys);
570+ }
571+ }
572+ }
573+ }
574+}
575+
576+sub processMcs
577+{
578+ my $self = shift;
579+ my $unit = shift;
580+ my $node = shift;
581+ my $proc = shift;
582+ my $parent_affinity = shift;
583+ my $parent_physical = shift;
584+ my $node_phys = shift;
585+
586+ my $mcs = $self->getAttribute($unit, "CHIP_UNIT");
587+ my $membufnum = $proc * $self->{MAX_MCS} + $mcs;
588+ $self->setAttribute($unit, "AFFINITY_PATH",$parent_affinity . "/mcs-$mcs");
589+ $self->setAttribute($unit, "PHYS_PATH", $parent_physical . "/mcs-$mcs");
590+ $self->setAttribute($unit, "MCS_NUM", $mcs);
591+ $self->setHuid($unit, 0, $node);
592+ $self->{targeting}->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{MCSS}[$mcs]{KEY} =
593+ $unit;
594+
595+ $self->setAttribute($unit, "EI_BUS_TX_LANE_INVERT","0");
596+ $self->setAttribute($unit, "EI_BUS_TX_MSBSWAP","0");
597+ $self->setAttribute($unit, "DMI_REFCLOCK_SWIZZLE","0");
598+
599+ ## Find connected membufs
600+ my $membuf_dmi = $self->{data}->{TARGETS}{$unit}{CONNECTION}{DEST}[0];
601+ if (defined($membuf_dmi))
602+ {
603+ ## found membuf connected
604+ my $membuf =
605+ $self->{data}->{TARGETS}{$membuf_dmi}
606+ {PARENT}; ## get parent of dmi unit which is membuf
607+ my $dmi_bus = $self->{data}->{TARGETS}{$unit}{CONNECTION}{BUS}[0];
608+ $self->setAttribute($membuf, "POSITION",$membufnum);
609+ $self->setAttribute($membuf, "AFFINITY_PATH",
610+ $parent_affinity . "/mcs-$mcs/membuf-$membufnum");
611+ $self->setAttribute($membuf, "PHYS_PATH",
612+ $node_phys . "/membuf-$membufnum");
613+ $self->setAttribute($membuf, "VPD_REC_NUM",
614+ $self->getAttribute($membuf, "POSITION"));
615+
616+ ## copy DMI bus attributes to membuf
617+ $self->setAttribute($unit, "EI_BUS_TX_LANE_INVERT",
618+ $dmi_bus->{bus_attribute}->{PROC_TX_LANE_INVERT}->{default});
619+ $self->setAttribute($unit, "EI_BUS_TX_MSBSWAP",
620+ $dmi_bus->{bus_attribute}->{PROC_TX_MSBSWAP}->{default});
621+ $self->setAttribute($membuf, "EI_BUS_TX_LANE_INVERT",
622+ $dmi_bus->{bus_attribute}->{MEMBUF_TX_LANE_INVERT}->{default});
623+ $self->setAttribute($membuf, "EI_BUS_TX_MSBSWAP",
624+ $dmi_bus->{bus_attribute}->{MEMBUF_TX_MSBSWAP}->{default});
625+
626+ ## auto setup FSI assuming schematic symbol. If FSI busses are
627+ ## defined in serverwiz2, this will be overridden
628+ ## in the schematic symbol, the fsi port num matches dmi ref clk num
629+
630+ my $fsi_port = $self->{DMI_FSI_MAP}->{$mcs};
631+ my $proc_key =
632+ $self->{targeting}->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{KEY};
633+ my $proc_path = $self->getAttribute($proc_key,"PHYS_PATH");
634+ $self->setFsiAttributes($membuf,"FSICM",0,$proc_path,$fsi_port,0);
635+ $self->setAttribute($unit, "DMI_REFCLOCK_SWIZZLE",$fsi_port);
636+ my $dmi_swizzle =
637+ $dmi_bus->{bus_attribute}->{DMI_REFCLOCK_SWIZZLE}->{default};
638+ my $dmi_swizzle =
639+ $self->getBusAttribute($unit,0,"DMI_REFCLOCK_SWIZZLE");
640+ if ($dmi_swizzle ne "")
641+ {
642+ $self->setAttribute($unit, "DMI_REFCLOCK_SWIZZLE",$dmi_swizzle);
643+ }
644+
645+ $self->setHuid($membuf, 0, $node);
646+ $self->{targeting}
647+ ->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{MCSS}[$mcs] {MEMBUFS}[0]{KEY} =
648+ $membuf;
Matt Ploetz940dcf62015-02-13 13:52:56 -0600649+
Matt Ploetzed8800a2015-02-10 13:12:24 -0600650+ $self->setAttribute($membuf, "ENTITY_INSTANCE",
Matt Ploetz940dcf62015-02-13 13:52:56 -0600651+ $self->{membuf_inst_num});
Matt Ploetzed8800a2015-02-10 13:12:24 -0600652+ $self->{membuf_inst_num}++;
653+ ## get the mbas
654+ foreach my $child (@{ $self->{data}->{TARGETS}{$membuf}{CHILDREN} })
655+ {
656+ ## need to not hardcard the subunits
657+ if ($self->getType($child) eq "L4")
658+ {
659+ $self->{targeting}
660+ ->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{MCSS}[$mcs]{MEMBUFS}[0]
661+ {L4S}[0] {KEY} = $child;
662+ $self->setAttribute($child, "AFFINITY_PATH",
663+ $parent_affinity . "/mcs-$mcs/membuf-$membufnum/l4-0");
664+ $self->setAttribute($child, "PHYS_PATH",
665+ $node_phys . "/membuf-$membufnum/l4-0");
666+ $self->setHuid($child, 0, $node);
667+ }
Matt Ploetz940dcf62015-02-13 13:52:56 -0600668+
Matt Ploetzed8800a2015-02-10 13:12:24 -0600669+ if ($self->getType($child) eq "MBA")
670+ {
671+ my $mba = $self->getAttribute($child,"MBA_NUM");
672+ $self->setAttribute($child, "AFFINITY_PATH",
673+ $parent_affinity . "/mcs-$mcs/membuf-$membufnum/mba-$mba");
674+ $self->setAttribute($child, "PHYS_PATH",
675+ $node_phys . "/membuf-$membufnum/mba-$mba");
676+ $self->setHuid($child, 0, $node);
677+ $self->{targeting}
678+ ->{SYS}[0]{NODES}[$node]{PROCS}[$proc]{MCSS}[$mcs]{MEMBUFS}[0]
679+ {MBAS}[$mba]{KEY} = $child;
680+
681+ ## Trace the DDR busses to find connected DIMM
682+ my $ddrs = $self->findConnections($child,"DDR3","");
683+ if ($ddrs ne "")
684+ {
685+ my $affinitypos=0;
686+ foreach my $dimms (@{$ddrs->{CONN}})
687+ {
688+ my $ddr = $dimms->{SOURCE};
689+ my $port_num = $self->getAttribute($ddr,"MBA_PORT");
690+ my $dimm_num = $self->getAttribute($ddr,"MBA_DIMM");
691+ my $dimm=$dimms->{DEST_PARENT};
692+ $self->setAttribute($dimm,"MBA_PORT",$port_num);
693+ $self->setAttribute($dimm,"MBA_DIMM",$dimm_num);
694+
695+ my $aff_pos=16*$proc+$mcs*$self->{MAX_MCS}+4*$mba+
696+ 2*$port_num+$dimm_num;
697+ $self->setAttribute($dimm, "AFFINITY_PATH",
698+ $parent_affinity
699+ . "/mcs-$mcs/membuf-$membufnum/mba-$mba/dimm-$affinitypos"
700+ );
701+ $self->setAttribute($dimm, "PHYS_PATH",
702+ $node_phys . "/dimm-" . $self->{dimm_tpos});
703+ $self->setAttribute($dimm, "POSITION",
704+ $aff_pos);
705+ $self->setAttribute($dimm, "VPD_REC_NUM",
706+ $aff_pos);
707+ $self->setHuid($dimm, 0, $node);
708+ $self->{targeting}
709+ ->{SYS}[0]{NODES}[$node]{PROCS}[$proc] {MCSS}[$mcs]
Matt Ploetz940dcf62015-02-13 13:52:56 -0600710+ {MEMBUFS}[0]{MBAS}[$mba] {DIMMS}[$affinitypos]{KEY} = $dimm;
Matt Ploetzed8800a2015-02-10 13:12:24 -0600711+ $self->setAttribute($dimm, "ENTITY_INSTANCE",
Matt Ploetz940dcf62015-02-13 13:52:56 -0600712+ $self->{dimm_tpos});
Matt Ploetzed8800a2015-02-10 13:12:24 -0600713+ $self->{dimm_tpos}++;
714+ $affinitypos++;
715+ }
716+ }
717+ }
718+ }
719+ }
720+}
721+
722+sub setFsiAttributes
723+{
724+ my $self = shift;
725+ my $target = shift;
726+ my $type = shift;
727+ my $cmfsi = shift;
728+ my $phys_path = shift;
729+ my $fsi_port = shift;
730+ my $flip_port = shift;
731+
732+ $self->setAttribute($target, "FSI_MASTER_TYPE","NO_MASTER");
733+ if ($type eq "FSIM")
734+ {
735+ $self->setAttribute($target, "FSI_MASTER_TYPE","MFSI");
736+ }
737+ if ($type eq "FSICM")
738+ {
739+ $self->setAttribute($target, "FSI_MASTER_TYPE","CMFSI");
740+ }
741+ $self->setAttribute($target, "FSI_MASTER_CHIP","physical:sys");
742+ $self->setAttribute($target, "FSI_MASTER_PORT","0xFF");
743+ $self->setAttribute($target, "ALTFSI_MASTER_CHIP","physical:sys");
744+ $self->setAttribute($target, "ALTFSI_MASTER_PORT","0xFF");
745+ $self->setAttribute($target, "FSI_SLAVE_CASCADE", "0");
746+ if ($cmfsi == 0)
747+ {
748+ $self->setAttribute($target, "FSI_MASTER_CHIP",$phys_path);
749+ $self->setAttribute($target, "FSI_MASTER_PORT", $fsi_port);
750+ }
751+ else
752+ {
753+ $self->setAttribute($target, "ALTFSI_MASTER_CHIP",$phys_path);
754+ $self->setAttribute($target, "ALTFSI_MASTER_PORT", $fsi_port);
755+ }
756+
757+ #my $phys_path = $targetObj->getAttribute($parentTarget, "PHYS_PATH");
758+ $self->setAttributeField($target, "FSI_OPTION_FLAGS","flipPort",
759+ $flip_port);
760+ $self->setAttributeField($target, "FSI_OPTION_FLAGS","reserved", "0");
761+
762+}
763+
764+
765+## returns pointer to target from target name
766+sub getTarget
767+{
768+ my $self = shift;
769+ my $target = shift;
770+ return $self->{data}->{TARGETS}->{$target};
771+}
772+
773+## returns pointer to array of all targets
774+sub getAllTargets
775+{
776+ my $self = shift;
777+ my $target = shift;
778+ return $self->{data}->{TARGETS};
779+}
780+
781+## returns the target name of the parent of passed in target
782+sub getTargetParent
783+{
784+ my $self = shift;
785+ my $target = shift;
786+ my $target_ptr = $self->getTarget($target);
787+ return $target_ptr->{PARENT};
788+}
789+
790+## returns the number of connections associated with target
791+sub getNumConnections
792+{
793+ my $self = shift;
794+ my $target = shift;
795+ my $target_ptr = $self->getTarget($target);
796+ if (!defined($target_ptr->{CONNECTION}->{DEST}))
797+ {
798+ return 0;
799+ }
800+ return scalar(@{ $target_ptr->{CONNECTION}->{DEST} });
801+}
802+
803+## returns destination target name of first connection
804+## useful for point to point busses with only 1 endpoint
805+sub getFirstConnectionDestination
806+{
807+ my $self = shift;
808+ my $target = shift;
809+ my $target_ptr = $self->getTarget($target);
810+ return $target_ptr->{CONNECTION}->{DEST}->[0];
811+}
812+
813+## returns pointer to bus of first connection
814+sub getFirstConnectionBus
815+{
816+ my $self = shift;
817+ my $target = shift;
818+ my $target_ptr = $self->getTarget($target);
819+ return $target_ptr->{CONNECTION}->{BUS}->[0];
820+}
821+## returns target name of $i connection
822+sub getConnectionDestination
823+{
824+ my $self = shift;
825+ my $target = shift;
826+ my $i = shift;
827+ my $target_ptr = $self->getTarget($target);
828+ return $target_ptr->{CONNECTION}->{DEST}->[$i];
829+}
830+
831+sub getConnectionBus
832+{
833+ my $self = shift;
834+ my $target = shift;
835+ my $i = shift;
836+ my $target_ptr = $self->getTarget($target);
837+ return $target_ptr->{CONNECTION}->{BUS}->[$i];
838+}
839+
840+sub findFirstEndpoint
841+{
842+ my $self = shift;
843+ my $target = shift;
844+ my $bus_type = shift;
845+ my $end_type = shift;
846+
847+ my $target_children = $self->getTargetChildren($target);
848+ if ($target_children eq "") { return ""; }
849+
850+ foreach my $child (@{ $self->getTargetChildren($target) })
851+ {
852+ my $child_bus_type = $self->getBusType($child);
853+ if ($child_bus_type eq $bus_type)
854+ {
855+ for (my $i = 0; $i < $self->getNumConnections($child); $i++)
856+ {
857+ my $dest_target = $self->getConnectionDestination($child, $i);
858+ my $dest_parent = $self->getTargetParent($dest_target);
859+ my $type = $self->getMrwType($dest_parent);
860+ my $dest_type = $self->getType($dest_parent);
861+ if ($type eq "NA") { $type = $dest_type; }
862+ if ($type eq $end_type)
863+ {
864+ return $dest_parent;
865+ }
866+ }
867+ }
868+ }
869+ return "";
870+}
871+sub findConnections
872+{
873+ my $self = shift;
874+ my $target = shift;
875+ my $bus_type = shift;
876+ my $end_type = shift;
877+
878+ my %connections;
879+ my $num=0;
880+ my $target_children = $self->getTargetChildren($target);
881+ if ($target_children eq "")
882+ {
883+ return "";
884+ }
885+
886+ foreach my $child (@{ $self->getTargetChildren($target) })
887+ {
888+ my $child_bus_type = $self->getBusType($child);
889+ if ($child_bus_type eq $bus_type)
890+ {
891+ for (my $i = 0; $i < $self->getNumConnections($child); $i++)
892+ {
893+ my $dest_target = $self->getConnectionDestination($child, $i);
894+ my $dest_parent = $self->getTargetParent($dest_target);
895+ my $type = $self->getMrwType($dest_parent);
896+ my $dest_type = $self->getType($dest_parent);
897+ if ($type eq "NA")
898+ {
899+ $type = $dest_type;
900+ }
901+
902+ if ($type eq $end_type || $end_type eq "")
903+ {
904+ $connections{CONN}[$num]{SOURCE}=$child;
905+ $connections{CONN}[$num]{SOURCE_PARENT}=$target;
906+ $connections{CONN}[$num]{DEST}=$dest_target;
907+ $connections{CONN}[$num]{DEST_PARENT}=$dest_parent;
908+ $connections{CONN}[$num]{BUS_NUM}=$i;
909+ $num++;
910+ }
911+ }
912+ }
913+ }
914+ if ($num==0) { return ""; }
915+ return \%connections;
916+}
917+
918+
919+## returns BUS_TYPE attribute of target
920+sub getBusType
921+{
922+ my $self = shift;
923+ my $target = shift;
924+ my $type = $self->getAttribute($target, "BUS_TYPE");
925+ if ($type eq "") { $type = "NA"; }
926+ return $type;
927+}
928+
929+## return target type
930+sub getType
931+{
932+ my $self = shift;
933+ my $target = shift;
934+ my $type = $self->getAttribute($target, "TYPE");
935+ if ($type eq "") { $type = "NA"; }
936+ return $type;
937+}
938+
939+## return target type
940+sub getMrwType
941+{
942+ my $self = shift;
943+ my $target = shift;
944+ my $type = $self->getAttribute($target, "MRW_TYPE");
945+ if ($type eq "") { $type = "NA"; }
946+ return $type;
947+}
948+
949+## returns target instance name
950+sub getInstanceName
951+{
952+ my $self = shift;
953+ my $target = shift;
954+ my $target_ptr = $self->getTarget($target);
955+ return $target_ptr->{TARGET}->{instance_name};
956+}
957+
958+## returns the parent target type
959+sub getTargetType
960+{
961+ my $self = shift;
962+ my $target = shift;
963+ my $target_ptr = $self->getTarget($target);
964+ return $target_ptr->{TARGET}->{type};
965+}
966+
967+## checks if attribute is value
968+## must be defined and have a non-empty value
969+sub isBadAttribute
970+{
971+ my $self = shift;
972+ my $target = shift;
973+ my $attribute = shift;
974+ my $badvalue = shift;
975+ my $target_ptr = $self->getTarget($target);
976+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}))
977+ {
978+ return 1;
979+ }
980+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}->{default}))
981+ {
982+ return 1;
983+ }
984+ if ($target_ptr->{ATTRIBUTES}->{$attribute}->{default} eq "")
985+ {
986+ return 1;
987+ }
988+ if ($target_ptr->{ATTRIBUTES}->{$attribute}->{default} eq $badvalue)
989+ {
990+ return 1;
991+ }
992+ return 0;
993+}
994+
995+## checks if complex attribute field is
996+## defined and non-empty
997+sub isBadComplexAttribute
998+{
999+ my $self = shift;
1000+ my $target = shift;
1001+ my $attribute = shift;
1002+ my $field = shift;
1003+ my $badvalue = shift;
1004+ my $target_ptr = $self->getTarget($target);
1005+
1006+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}))
1007+ {
1008+ return 1;
1009+ }
1010+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}->{default}))
1011+ {
1012+ return 1;
1013+ }
1014+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}->{default}->{field}))
1015+ {
1016+ return 1;
1017+ }
1018+ if ($target_ptr->{ATTRIBUTES}->{$attribute}->{default}->{field}->{$field}
1019+ ->{value} eq "")
1020+ {
1021+ return 1;
1022+ }
1023+ if ($target_ptr->{ATTRIBUTES}->{$attribute}->{default}->{field}->{$field}
1024+ ->{value} eq $badvalue)
1025+ {
1026+ return 1;
1027+ }
1028+ return 0;
1029+}
1030+
1031+## returns attribute value
1032+sub getAttribute
1033+{
1034+ my $self = shift;
1035+ my $target = shift;
1036+ my $attribute = shift;
1037+ my $target_ptr = $self->getTarget($target);
1038+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}->{default}))
1039+ {
1040+ printf("ERROR: getAttribute(%s,%s) | Attribute not defined\n",
1041+ $target, $attribute);
1042+
1043+ #print Dumper($target_ptr);
1044+ $self->myExit(4);
1045+ }
1046+ return $target_ptr->{ATTRIBUTES}->{$attribute}->{default};
1047+}
1048+## renames a target attribute
1049+sub renameAttribute
1050+{
1051+ my $self = shift;
1052+ my $target = shift;
1053+ my $oldName = shift;
1054+ my $newName = shift;
1055+ my $target_ptr = $self->{data}->{TARGETS}->{$target};
1056+ if (!defined($target_ptr->{ATTRIBUTES}->{$oldName}))
1057+ {
1058+ return 1;
1059+ }
1060+ $target_ptr->{ATTRIBUTES}->{$newName}->{default} =
1061+ $target_ptr->{ATTRIBUTES}->{$oldName}->{default};
1062+ delete($target_ptr->{ATTRIBUTES}->{$oldName});
1063+ $self->log($target, "Renaming attribute: $oldName => $newName");
1064+ return 0;
1065+}
1066+
1067+## copy an attribute between targets
1068+sub copyAttribute
1069+{
1070+ my $self = shift;
1071+ my $source_target = shift;
1072+ my $dest_target = shift;
1073+ my $attribute = shift;
1074+
1075+ my $value=$self->getAttribute($source_target,$attribute);
1076+ $self->setAttribute($dest_target,$attribute,$value);
1077+
1078+ $self->log($dest_target, "Copy Attribute: $attribute=$value");
1079+}
1080+
1081+## sets an attribute
1082+sub setAttribute
1083+{
1084+ my $self = shift;
1085+ my $target = shift;
1086+ my $attribute = shift;
1087+ my $value = shift;
1088+ my $target_ptr = $self->getTarget($target);
1089+ $target_ptr->{ATTRIBUTES}->{$attribute}->{default} = $value;
1090+ $self->log($target, "Setting Attribute: $attribute=$value");
1091+}
1092+## sets the field of a complex attribute
1093+sub setAttributeField
1094+{
1095+ my $self = shift;
1096+ my $target = shift;
1097+ my $attribute = shift;
1098+ my $field = shift;
1099+ my $value = shift;
1100+ $self->{data}->{TARGETS}->{$target}->{ATTRIBUTES}->{$attribute}->{default}
1101+ ->{field}->{$field}->{value} = $value;
1102+}
1103+## returns complex attribute value
1104+sub getAttributeField
1105+{
1106+ my $self = shift;
1107+ my $target = shift;
1108+ my $attribute = shift;
1109+ my $field = shift;
1110+ my $target_ptr = $self->getTarget($target);
1111+ if (!defined($target_ptr->{ATTRIBUTES}->{$attribute}->
1112+ {default}->{field}->{$field}->{value}))
1113+ {
1114+ printf("ERROR: getAttributeField(%s,%s,%s) | Attribute not defined\n",
1115+ $target, $attribute,$field);
1116+
1117+ $self->myExit(4);
1118+ }
1119+
1120+ return $target_ptr->{ATTRIBUTES}->{$attribute}->
1121+ {default}->{field}->{$field}->{value};
1122+}
1123+
1124+## returns an attribute from a bus
1125+sub getBusAttribute
1126+{
1127+ my $self = shift;
1128+ my $target = shift;
1129+ my $busnum = shift;
1130+ my $attr = shift;
1131+ my $target_ptr = $self->getTarget($target);
1132+
1133+ if (
1134+ !defined(
1135+ $target_ptr->{CONNECTION}->{BUS}->[$busnum]->{bus_attribute}
1136+ ->{$attr}->{default}
1137+ )
1138+ )
1139+ {
1140+ printf("ERROR: getBusAttribute(%s,%d,%s) | Attribute not defined\n",
1141+ $target, $busnum, $attr);
1142+ $self->myExit(4);
1143+ }
1144+ if (ref($target_ptr->{CONNECTION}->{BUS}->[$busnum]->{bus_attribute}->{$attr}
1145+ ->{default}) eq "HASH") {
1146+ return "";
1147+ }
1148+ return $target_ptr->{CONNECTION}->{BUS}->[$busnum]->{bus_attribute}->{$attr}
1149+ ->{default};
1150+}
1151+## returns a pointer to an array of children target names
1152+sub getTargetChildren
1153+{
1154+ my $self = shift;
1155+ my $target = shift;
1156+ my $target_ptr = $self->getTarget($target);
1157+ ## this is an array
1158+ return $target_ptr->{CHILDREN};
1159+}
1160+
1161+sub getEnumValue
1162+{
1163+ my $self = shift;
1164+ my $enumType = shift;
1165+ my $enumName = shift;
1166+ if (!defined($self->{enumeration}->{$enumType}->{$enumName}))
1167+ {
1168+ printf("ERROR: getEnumValue(%s,%s) | enumType not defined\n",
1169+ $enumType, $enumName);
1170+ $self->myExit(4);
1171+ }
1172+ return $self->{enumeration}->{$enumType}->{$enumName};
1173+}
1174+
1175+sub getEnumHash
1176+{
1177+ my $self = shift;
1178+ my $enumType = shift;
1179+ my $enumName = shift;
1180+ if (!defined($self->{enumeration}->{$enumType}))
1181+ {
1182+ printf("ERROR: getEnumValue(%s) | enumType not defined\n",
1183+ $enumType);
1184+ print Dumper($self->{enumeration});
1185+ $self->myExit(4);
1186+ }
1187+ return $self->{enumeration}->{$enumType};
1188+}
1189+
1190+sub setHuid
1191+{
1192+ my $self = shift;
1193+ my $target = shift;
1194+ my $sys = shift;
1195+ my $node = shift;
1196+
1197+ my $type = $self->getType($target);
1198+ my $type_id = $self->{enumeration}->{TYPE}->{$type};
1199+ if ($type_id eq "") { $type_id = 0; }
1200+ if ($type_id == 0) { return; }
1201+ my $index = 0;
1202+ if (defined($self->{huid_idx}->{$type}))
1203+ {
1204+ $index = $self->{huid_idx}->{$type};
1205+ }
1206+ else { $self->{huid_idx}->{$type} = 0; }
1207+
1208+ # Format: SSSS NNNN TTTTTTTT iiiiiiiiiiiiiiii
1209+ my $huid = sprintf("%01x%01x%02x%04x", $sys, $node, $type_id, $index);
1210+ $huid = "0x" . uc($huid);
1211+
1212+ $self->setAttribute($target, "HUID", $huid);
1213+ $self->{huid_idx}->{$type}++;
1214+ $self->log($target, "Setting HUID: $huid");
1215+ $self->setMruid($target, $node);
1216+}
1217+
1218+sub setMruid
1219+{
1220+ my $self = shift;
1221+ my $target = shift;
1222+ my $node = shift;
1223+
1224+ my $type = $self->getType($target);
1225+ my $mru_prefix_id = $self->{enumeration}->{MRU_PREFIX}->{$type};
1226+ if ($mru_prefix_id eq "") { $mru_prefix_id = "0xFFFF"; }
1227+ if ($mru_prefix_id eq "0xFFFF") { return; }
1228+ my $index = 0;
1229+ if (defined($self->{mru_idx}->{$node}->{$type}))
1230+ {
1231+ $index = $self->{mru_idx}->{$node}->{$type};
1232+ }
1233+ else { $self->{mru_idx}->{$node}->{$type} = 0; }
1234+
1235+ my $mruid = sprintf("%s%04x", $mru_prefix_id, $index);
1236+ $self->setAttribute($target, "MRU_ID", $mruid);
1237+ $self->{mru_idx}->{$node}->{$type}++;
1238+}
1239+
1240+sub getMasterProc
1241+{
1242+ my $self = shift;
1243+ return $self->{master_proc};
1244+}
1245+
1246+sub setMasterProc
1247+{
1248+ my $self = shift;
1249+ my $target = shift;
1250+ $self->{master_proc}=$target;
1251+}
1252+
1253+sub getSystemName
1254+{
1255+ my $self = shift;
1256+ return $self->getAttribute("/".$self->{TOP_LEVEL}, "SYSTEM_NAME");
1257+}
1258+
1259+sub myExit
1260+{
1261+ my $self = shift;
1262+ my $exit_code = shift;
1263+ if ($exit_code eq "") { $exit_code = 0; }
1264+ $self->{errorsExist} = 1;
1265+ if ($self->{force} == 0)
1266+ {
1267+ exit($exit_code);
1268+ }
1269+}
1270+
1271+sub log
1272+{
1273+ my $self = shift;
1274+ my $target = shift;
1275+ my $msg = shift;
1276+ if ($self->{debug})
1277+ {
1278+ print "DEBUG: ($target) $msg\n";
1279+ }
1280+}
1281+1;
1282+
1283+=head1 NAME
1284+
1285+Targets
1286+
1287+=head1 SYNOPSIS
1288+
1289+ use Targets;
1290+
1291+ my $targets = Targets->new;
1292+ $targets->loadXML("myfile.xml");
1293+ foreach my $target ( sort keys %{ $targets->getAllTargets() } ) {
1294+ ## do stuff with targets
1295+ }
1296+
1297+ $targets->printXML( $file_handle, "top" );
1298+
1299+=head1 DESCRIPTION
1300+
1301+C<Targets> is a class that consumes XML generated by ServerWiz2. The XML
1302+describes a POWER system topology including nodes, cards, chips, and busses.
1303+
1304+=head1 OVERVIEW
1305+
1306+A simple example of a ServerWiz2 topology would be:
1307+
1308+=over 4
1309+
1310+=item Topology Example:
1311+
1312+ -system
1313+ -node
1314+ -motherboard
1315+ -processor
1316+ -pcie card
1317+ - daughtercard
1318+ - memory buffer
1319+ - dimms
1320+
1321+=back
1322+
1323+Targets->loadXML("myfile.xml") reads this topology and creates 2 data
1324+structures. One data structure simply represents the hierarchical system
1325+topology. The other data structure represents the hierarchical structure
1326+that hostboot expects (affinity path).
1327+
1328+Unlike hostboot, everything in ServerWiz2 is represented as a target.
1329+For example, FSI and I2C units are targets under the processor that have a
1330+bus type and therefore allow connections to be made.
1331+
1332+=head1 CONSTRUCTOR
1333+
1334+=over 4
1335+
1336+=item new ()
1337+
1338+There are no arguments for the constructor.
1339+
1340+=back
1341+
1342+=head1 METHODS
1343+
1344+C<TARGET> is a pointer to data structure containing all target information.
1345+C<TARGET_STRING> is the hierarchical target string used as key for data
1346+structure. An example for C<TARGET_STRING> would be:
1347+C</sys-0/node-0/motherboard-0/dimm-0>
1348+
1349+=over 4
1350+
1351+=item loadXml (C<FILENAME>)
1352+
1353+Reads ServerWiz2 XML C<FILENAME> and stores into a data structure for
1354+manipulation and printing.
1355+
1356+=item getTarget(C<TARGET_STRING>)
1357+
1358+Returns pointer to data structure (C<TARGET>)
1359+
1360+=item getAllTargets(C<TARGET_STRING>)
1361+
1362+Returns array with all existing target data structures
1363+
1364+=item getTargetParent(C<TARGET_STRING>)
1365+
1366+Returns C<TARGET_STRING> of parent target
1367+
1368+=item getNumConnections(C<TARGET_STRING>)
1369+
1370+Returns the number of bus connections to this target
1371+
1372+=item getFirstConnectionDestination(C<TARGET_STRING>)
1373+
1374+Returns the target string of the first target found connected to
1375+C<TARGET_STRING>. This is useful because many busses are guaranteed
1376+to only have one connection because they are point to point.
1377+
1378+=item getFirstConnectionBus(C<TARGET_STRING>)
1379+
1380+Returns the data structure of the bus of the first target found connected to
1381+C<TARGET_STRING>. The bus data structure is also a target with attributes.
1382+
1383+=item getConnectionDestination(C<TARGET_STRING>,C<INDEX>)
1384+
1385+Returns the target string of the C<INDEX> target found connected to
1386+C<TARGET_STRING>.
1387+
1388+=item getConnectionBus(C<TARGET_STRING>)
1389+
1390+Returns the data structure of the C<INDEX> bus target found connected to
1391+C<TARGET_STRING>.
1392+
1393+=item findEndpoint(C<TARGET_STRING>,C<BUS_TYPE>,C<ENDPOINT_MRW_TYPE>)
1394+
1395+Searches through all connections to C<TARGET_STRING>
1396+for a endpoint C<MRW_TYPE> and C<BUS_TYPE>
1397+
1398+=item getBusType(C<TARGET_STRING>)
1399+
1400+Returns the BUS_TYPE attribute of (C<TARGET_STRING>). Examples are I2C and DMI.
1401+
1402+=item getType(C<TARGET_STRING>)
1403+
1404+Returns the TYPE attribute of (C<TARGET_STRING>).
1405+Examples are PROC and MEMBUF.
1406+
1407+=item getMrwType(C<TARGET_STRING>)
1408+
1409+Returns the MRW_TYPE attribute of (C<TARGET_STRING>).
1410+Examples are CARD and PCI_CONFIG. This
1411+is an extension to the TYPE attribute and are types that hostboot does
1412+not care about.
1413+
1414+=item getTargetType(C<TARGET_STRING>)
1415+
1416+Returns the target type id of (C<TARGET_STRING>).
1417+This is not the TYPE attribute. This is the
1418+<id> from target_types.xml. Examples are unit-pci-power8 and enc-node-power8.
1419+
1420+=item isBadAttribute(C<TARGET_STRING>,C<ATTRIBUTE_NAME>)
1421+
1422+Tests where attribute (C<ATTRIBUTE_NAME>) has been set in
1423+target (C<TARGET_STRING>). Returns true if attribute is undefined or empty
1424+and false if attribute is defined and not empty.
1425+
1426+=item getAttribute(C<TARGET_STRING>,C<ATTRIBUTE_NAME>)
1427+
1428+Returns the value of attribute C<ATTRIBUTE_NAME> in target C<TARGET_STRING>.
1429+
1430+=item renameAttribute(C<TARGET_STRING>,C<ATTRIBUTE_OLDNAME>,
1431+C<ATTRIBUTE_OLDNAME>)
1432+
1433+Renames attribute C<ATTRIBUTE_OLDNAME> to C<ATTRIBUTE_NEWNAME> in target
1434+C<TARGET_STRING>.
1435+
1436+=item setAttribute(C<TARGET_STRING>,C<ATTRIBUTE_NAME>,C<VALUE>)
1437+
1438+Sets attribute C<ATTRIBUTE_NAME> of target C<TARGET_STRING> to value C<VALUE>.
1439+
1440+=item setAttributeField(C<TARGET_STRING>,C<ATTRIBUTE_NAME>,C<FIELD>,C<VALUE>)
1441+
1442+Sets attribute C<ATTRIBUTE_NAME> and field C<FIELD> of target C<TARGET_STRING>
1443+to value C<VALUE>. This is for complex attributes.
1444+
1445+=item getBusAttribute(C<TARGET_STRING>,C<INDEX>,C<ATTRIBUTE_NAME>)
1446+
1447+Gets the attribute C<ATTRIBUTE_NAME> from bus C<TARGET_STRING> bus number
1448+C<INDEX>.
1449+
1450+=item getTargetChildren(C<TARGET_STRING>)
1451+
1452+Returns an array of target strings representing all the children of target
1453+C<TARGET_STRING>.
1454+
1455+=item getEnumValue(C<ENUM_TYPE>,C<ENUM_NAME>)
1456+
1457+Returns the enum value of type C<ENUM_TYPE> and name C<ENUM_NAME>. The
1458+enumerations are also defined in ServerWiz2 XML output and are directly
1459+copied from attribute_types.xml.
1460+
1461+=item getMasterProc()
1462+
1463+Returns the target string of the master processor.
1464+
1465+=item myExit(C<EXIT_NUM>)
1466+
1467+Calls exit(C<EXIT_NUM>) when force flag is not set.
1468+
1469+=item log(C<TARGET_STRING>,C<MESSAGE>)
1470+
1471+Prints to stdout log message is debug mode is turned on.
1472+
1473+
1474+=back
1475+
1476+=head1 CREDITS
1477+
1478+Norman James <njames@us.ibm.com>
1479+
1480+=cut
1481+
1482diff --git a/src/usr/targeting/common/processMrw.pl b/src/usr/targeting/common/processMrw.pl
1483new file mode 100755
Matt Ploetz940dcf62015-02-13 13:52:56 -06001484index 0000000..1fb292f
Matt Ploetzed8800a2015-02-10 13:12:24 -06001485--- /dev/null
1486+++ b/src/usr/targeting/common/processMrw.pl
Matt Ploetz940dcf62015-02-13 13:52:56 -06001487@@ -0,0 +1,1144 @@
Matt Ploetzed8800a2015-02-10 13:12:24 -06001488+#! /usr/bin/perl
1489+# IBM_PROLOG_BEGIN_TAG
1490+# This is an automatically generated prolog.
1491+#
1492+# $Source: src/usr/targeting/common/processMrw.pl $
1493+#
1494+# OpenPOWER HostBoot Project
1495+#
1496+# Contributors Listed Below - COPYRIGHT 2015
1497+# [+] International Business Machines Corp.
1498+#
1499+#
1500+# Licensed under the Apache License, Version 2.0 (the "License");
1501+# you may not use this file except in compliance with the License.
1502+# You may obtain a copy of the License at
1503+#
1504+# http://www.apache.org/licenses/LICENSE-2.0
1505+#
1506+# Unless required by applicable law or agreed to in writing, software
1507+# distributed under the License is distributed on an "AS IS" BASIS,
1508+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1509+# implied. See the License for the specific language governing
1510+# permissions and limitations under the License.
1511+#
1512+# IBM_PROLOG_END_TAG
1513+
1514+use strict;
1515+use XML::Simple;
1516+use Data::Dumper;
1517+use Targets;
1518+use Math::BigInt;
1519+use Getopt::Long;
1520+use File::Basename;
1521+
1522+my $VERSION = "1.0.0";
1523+
1524+my $force = 0;
1525+my $serverwiz_file = "";
1526+my $version = 0;
1527+my $debug = 0;
1528+my $report = 0;
1529+my $sdr_file = "";
1530+
1531+GetOptions(
1532+ "f" => \$force, # numeric
1533+ "x=s" => \$serverwiz_file, # string
1534+ "d" => \$debug,
1535+ "v" => \$version,
1536+ "r" => \$report,
1537+ ) # flag
1538+ or printUsage();
1539+
1540+if ($version == 1)
1541+{
1542+ die "\nprocessMrw.pl\tversion $VERSION\n";
1543+}
1544+
1545+if ($serverwiz_file eq "")
1546+{
1547+ printUsage();
1548+}
1549+
1550+$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
1551+
1552+my $targetObj = Targets->new;
1553+if ($force == 1)
1554+{
1555+ $targetObj->{force} = 1;
1556+}
1557+if ($debug == 1)
1558+{
1559+ $targetObj->{debug} = 1;
1560+}
1561+
1562+$targetObj->setVersion($VERSION);
1563+my $xmldir = dirname($serverwiz_file);
1564+$targetObj->loadXML($serverwiz_file);
1565+
1566+#--------------------------------------------------
1567+## loop through all targets and do stuff
1568+foreach my $target (sort keys %{ $targetObj->getAllTargets() })
1569+{
1570+ my $type = $targetObj->getType($target);
1571+ if ($type eq "SYS")
1572+ {
1573+ processSystem($targetObj, $target);
Matt Ploetz940dcf62015-02-13 13:52:56 -06001574+ }
Matt Ploetzed8800a2015-02-10 13:12:24 -06001575+ elsif ($type eq "PROC")
1576+ {
1577+ processProcessor($targetObj, $target);
1578+ }
1579+ elsif ($type eq "MEMBUF")
1580+ {
1581+ processMembuf($targetObj, $target);
1582+ }
1583+ elsif ($type eq "FSP")
1584+ {
1585+ processBmc($targetObj, $target);
1586+ }
1587+}
1588+
1589+
1590+## check topology
1591+foreach my $n (keys %{$targetObj->{TOPOLOGY}}) {
1592+ foreach my $p (keys %{$targetObj->{TOPOLOGY}->{$n}}) {
1593+ if ($targetObj->{TOPOLOGY}->{$n}->{$p} > 1) {
1594+ print "ERROR: Fabric topology invalid. 2 targets have same ".
1595+ "FABRIC_NODE_ID,FABRIC_CHIP_ID ($n,$p)\n";
1596+ $targetObj->myExit(3);
1597+ }
1598+ }
1599+}
1600+## check for errors
1601+if ($targetObj->getMasterProc() eq "")
1602+{
1603+ print "ERROR: Master Processor not defined. Please instaitant a BMC
1604+ and connect LPC bus\n";
1605+ $targetObj->myExit(3);
1606+}
1607+foreach my $target (keys %{ $targetObj->getAllTargets() })
1608+{
1609+ errorCheck($targetObj, $target);
1610+}
1611+
1612+#--------------------------------------------------
1613+## write out final XML
1614+my $xml_fh;
1615+my $filename = $xmldir . "/" . $targetObj->getSystemName() . "_hb.mrw.xml";
1616+print "Creating XML: $filename\n";
1617+open($xml_fh, ">$filename") || die "Unable to create: $filename";
1618+$targetObj->printXML($xml_fh, "top");
1619+close $xml_fh;
1620+if (!$targetObj->{errorsExist})
1621+{
1622+ print "MRW created successfully!\n";
1623+}
1624+
1625+
1626+## optionally print out report
1627+if ($report)
1628+{
1629+ my $report_file = $xmldir . "/" . $targetObj->getSystemName() . ".rpt";
1630+ open(SUM,">$report_file") || die "Unable to create: $report_file\n";
Matt Ploetz940dcf62015-02-13 13:52:56 -06001631+ my $ref = $targetObj->{targeting}->{SYS}[0]{NODES}[0]{PROCS};
Matt Ploetzed8800a2015-02-10 13:12:24 -06001632+ foreach my $proc (@{$ref})
1633+ {
1634+ foreach my $mcs (@{$proc->{MCSS}})
1635+ {
1636+ my $mcs_target = $mcs->{KEY};
1637+ my $membuf=$mcs->{MEMBUFS}[0];
1638+ my $membuf_target = $membuf->{KEY};
Matt Ploetz940dcf62015-02-13 13:52:56 -06001639+
Matt Ploetzed8800a2015-02-10 13:12:24 -06001640+ my $sch = $targetObj->getAttribute($mcs_target,
1641+ "SCHEMATIC_INTERFACE");
1642+ my $aff = $targetObj->getAttribute($mcs_target,"AFFINITY_PATH");
1643+ my $huid = $targetObj->getAttribute($mcs_target,"HUID");
1644+ print SUM "$sch | $huid | $mcs_target | $aff\n";
1645+ if ($membuf_target ne "") {
1646+ foreach my $mba (@{$membuf->{MBAS}}) {
1647+ my $mba_target = $mba->{KEY};
Matt Ploetz940dcf62015-02-13 13:52:56 -06001648+
Matt Ploetzed8800a2015-02-10 13:12:24 -06001649+ $huid = $targetObj->getAttribute($mba_target,"HUID");
1650+ $aff = $targetObj->getAttribute($mcs_target,
1651+ "AFFINITY_PATH");
1652+ print SUM "\t | $huid | $mba_target | $aff\n";
1653+ foreach my $dimm (@{$mba->{DIMMS}}) {
1654+ my $dimm_target = $dimm->{KEY};
1655+ $aff = $targetObj->getAttribute($dimm_target,
1656+ "AFFINITY_PATH");
1657+ $huid = $targetObj->getAttribute($dimm_target,"HUID");
1658+ my $p = $targetObj->getAttribute($dimm_target,
1659+ "MBA_PORT");
1660+ my $d = $targetObj->getAttribute($dimm_target,
1661+ "MBA_DIMM");
1662+ my $i2c = $targetObj->getAttributeField($dimm_target,
1663+ "EEPROM_VPD_PRIMARY_INFO","devAddr");
1664+ my $sens = $targetObj->getAttribute($dimm_target,
1665+ "IPMI_SENSORS");
1666+ my @s = split(/\,/,$sens);
Matt Ploetz940dcf62015-02-13 13:52:56 -06001667+
Matt Ploetzed8800a2015-02-10 13:12:24 -06001668+ print SUM "\t\t$huid | $dimm_target".
1669+ " | $aff | $p | $d | $i2c | ".
1670+ "$s[0],$s[1] | $s[2],$s[3]\n";
1671+ }
1672+ }
1673+ }
1674+ }
1675+ }
1676+ close SUM;
1677+}
1678+
1679+#--------------------------------------------------
1680+#--------------------------------------------------
1681+## Processing subroutines
1682+
1683+#--------------------------------------------------
Matt Ploetzed8800a2015-02-10 13:12:24 -06001684+
1685+#--------------------------------------------------
1686+## System
1687+##
1688+
1689+sub processSystem
1690+{
1691+ my $targetObj = shift;
1692+ my $target = shift;
1693+
1694+ $targetObj->setAttribute($target, "MAX_MCS_PER_SYSTEM",
1695+ $targetObj->{NUM_PROCS_PER_NODE} * $targetObj->{MAX_MCS});
1696+ $targetObj->setAttribute($target, "MAX_PROC_CHIPS_PER_NODE",
1697+ $targetObj->{NUM_PROCS_PER_NODE});
1698+ parseBitwise($targetObj,$target,"CDM_POLICIES");
1699+}
1700+sub processBmc
1701+{
1702+ my $targetObj = shift;
1703+ my $target = shift;
1704+ my $i2cs=$targetObj->findConnections($target,"I2C","PROC");
1705+ if ($i2cs ne "")
1706+ {
1707+ foreach my $i2c (@{$i2cs->{CONN}})
1708+ {
1709+ my $addr=$targetObj->getBusAttribute(
1710+ $i2c->{SOURCE},$i2c->{BUS_NUM},"I2C_ADDRESS");
1711+ $targetObj->setAttribute(
1712+ $i2c->{DEST_PARENT},"I2C_SLAVE_ADDRESS",$addr);
1713+ }
1714+ }
1715+ my $lpcs=$targetObj->findConnections($target,"LPC","PROC");
1716+ if ($lpcs ne "")
1717+ {
1718+ my $lpc=$lpcs->{CONN}->[0];
1719+ $targetObj->setMasterProc($lpc->{DEST_PARENT});
1720+ }
1721+}
1722+
1723+
1724+sub parseBitwise
1725+{
1726+ my $targetObj = shift;
1727+ my $target = shift;
1728+ my $attribute = shift;
1729+
1730+ my $mask = 0;
1731+ foreach my $e (keys %{ $targetObj->getEnumHash($attribute) }) {
1732+ my $field = $targetObj->getAttributeField(
1733+ $target,$attribute."_BITMASK",$e);
1734+ my $val=hex($targetObj->getEnumValue($attribute,$e));
1735+ if ($field eq "true")
1736+ {
1737+ $mask=$mask | $val;
1738+ }
1739+ }
1740+ $targetObj->setAttribute($target,$attribute,$mask);
1741+ }
1742+#--------------------------------------------------
1743+## Processor
1744+##
1745+
1746+sub processProcessor
1747+{
1748+ my $targetObj = shift;
1749+ my $target = shift;
1750+
1751+ #########################
1752+ ## Copy PCIE attributes from socket
1753+ ## In serverwiz, processor instances are not unique
1754+ ## because plugged into socket
1755+ ## so processor instance unique attributes are socket level.
1756+ ## The grandparent is guaranteed to be socket.
1757+ my $socket_target =
1758+ $targetObj->getTargetParent($targetObj->getTargetParent($target));
1759+ $targetObj->copyAttribute($socket_target,$target,"LOCATION_CODE");
1760+ $targetObj->copyAttribute($socket_target,$target,"FRU_ID");
Matt Ploetz940dcf62015-02-13 13:52:56 -06001761+
Matt Ploetzed8800a2015-02-10 13:12:24 -06001762+
1763+ foreach my $attr (sort (keys
1764+ %{ $targetObj->getTarget($socket_target)->{TARGET}->{attribute} }))
1765+ {
1766+ if ($attr =~ /PROC\_PCIE/)
1767+ {
1768+ $targetObj->copyAttribute($socket_target,$target,$attr);
1769+ }
1770+ }
1771+ $targetObj->log($target, "Processing PROC");
1772+ foreach my $child (@{ $targetObj->getTargetChildren($target) })
1773+ {
1774+ $targetObj->log($target, "Processing PROC child: $child");
1775+ my $child_type = $targetObj->getType($child);
1776+ if ($child_type eq "NA" || $child_type eq "FSI")
1777+ {
1778+ $child_type = $targetObj->getMrwType($child);
1779+ }
1780+ if ($child_type eq "ABUS")
1781+ {
1782+ processAbus($targetObj, $child);
1783+ }
1784+ elsif ($child_type eq "XBUS")
1785+ {
1786+ processXbus($targetObj, $child);
1787+ }
1788+ elsif ($child_type eq "FSIM" || $child_type eq "FSICM")
1789+ {
1790+ processFsi($targetObj, $child, $target);
1791+ }
1792+ elsif ($child_type eq "PCI_CONFIGS")
1793+ {
1794+ foreach my $pci_child (@{ $targetObj->getTargetChildren($child) })
1795+ {
1796+ processPcie($targetObj, $pci_child, $target);
1797+ }
1798+ }
1799+ elsif ($child_type eq "MCS")
1800+ {
1801+ processMcs($targetObj, $child, $target);
1802+ }
1803+ elsif ($child_type eq "OCC")
1804+ {
1805+ processOcc($targetObj, $child, $target);
1806+ }
1807+ }
1808+
1809+ ## update path for mvpd's and sbe's
1810+ my $path = $targetObj->getAttribute($target, "PHYS_PATH");
1811+ my $model = $targetObj->getAttribute($target, "MODEL");
1812+
1813+ $targetObj->setAttributeField($target,
1814+ "EEPROM_VPD_PRIMARY_INFO","i2cMasterPath",$path);
1815+ $targetObj->setAttributeField($target,
1816+ "EEPROM_VPD_BACKUP_INFO","i2cMasterPath",$path);
1817+ $targetObj->setAttributeField($target,
1818+ "EEPROM_SBE_PRIMARY_INFO","i2cMasterPath",$path);
1819+ $targetObj->setAttributeField($target,
1820+ "EEPROM_SBE_BACKUP_INFO","i2cMasterPath",$path);
1821+ $targetObj->setAttributeField($target,
1822+ "EEPROM_VPD_FRU_INFO","i2cMasterPath",$path);
1823+
1824+ ## initialize master processor FSI's
1825+ $targetObj->setAttributeField($target, "FSI_OPTION_FLAGS", "flipPort", "0");
1826+
1827+ if ($target eq $targetObj->getMasterProc())
1828+ {
1829+ $targetObj->setAttributeField($target, "FSI_OPTION_FLAGS", "reserved",
1830+ "0");
1831+ $targetObj->setAttribute($target, "FSI_MASTER_CHIP", "physical:sys");
1832+ $targetObj->setAttribute($target, "FSI_MASTER_PORT", "0xFF");
1833+ $targetObj->setAttribute($target, "ALTFSI_MASTER_CHIP", "physical:sys");
1834+ $targetObj->setAttribute($target, "ALTFSI_MASTER_PORT", "0xFF");
1835+ $targetObj->setAttribute($target, "FSI_MASTER_TYPE", "NO_MASTER");
1836+ $targetObj->setAttribute($target, "FSI_SLAVE_CASCADE", "0");
1837+ $targetObj->setAttribute($target, "PROC_MASTER_TYPE", "ACTING_MASTER");
1838+ }
1839+ else
1840+ {
1841+ $targetObj->setAttribute($target, "PROC_MASTER_TYPE",
1842+ "MASTER_CANDIDATE");
1843+ }
1844+ ## Update bus speeds
1845+ processI2cSpeeds($targetObj,$target);
1846+
1847+ ## these are hardcoded because code sets them properly
1848+ $targetObj->setAttributeField($target, "SCOM_SWITCHES", "reserved", "0");
1849+ $targetObj->setAttributeField($target, "SCOM_SWITCHES", "useFsiScom", "1");
1850+ $targetObj->setAttributeField($target, "SCOM_SWITCHES", "useInbandScom",
1851+ "0");
1852+ $targetObj->setAttributeField($target, "SCOM_SWITCHES", "useXscom", "0");
1853+
1854+ processMembufVpdAssociation($targetObj,$target);
1855+ setupBars($targetObj,$target);
1856+}
1857+
1858+
1859+sub processI2cSpeeds
1860+{
1861+ my $targetObj = shift;
1862+ my $target = shift;
1863+
1864+ my @bus_speeds;
1865+ my $bus_speed_attr=$targetObj->getAttribute($target,"I2C_BUS_SPEED_ARRAY");
1866+ my @bus_speeds2 = split(/,/,$bus_speed_attr);
1867+ $bus_speeds[0][0] = $bus_speeds2[0];
1868+ $bus_speeds[0][1] = $bus_speeds2[1];
1869+ $bus_speeds[0][2] = $bus_speeds2[2];
1870+ $bus_speeds[1][0] = $bus_speeds2[3];
1871+ $bus_speeds[1][1] = $bus_speeds2[4];
1872+ $bus_speeds[1][2] = $bus_speeds2[5];
1873+
1874+ my $i2cs=$targetObj->findConnections($target,"I2C","");
1875+ if ($i2cs ne "") {
1876+ foreach my $i2c (@{$i2cs->{CONN}}) {
1877+ my $port=oct($targetObj->getAttribute($i2c->{SOURCE},"I2C_PORT"));
1878+ my $engine=oct($targetObj->getAttribute(
1879+ $i2c->{SOURCE},"I2C_ENGINE"));
1880+ my $bus_speed=$targetObj->getBusAttribute(
1881+ $i2c->{SOURCE},$i2c->{BUS_NUM},"I2C_SPEED");
1882+ if ($bus_speed eq "" || $bus_speed==0) {
1883+ print "ERROR: I2C bus speed not defined for $i2c->{SOURCE}\n";
1884+ $targetObj->myExit(3);
1885+ }
1886+ ## choose lowest bus speed
1887+ if ($bus_speeds[$engine][$port] eq "" ||
1888+ $bus_speeds[$engine][$port]==0 ||
1889+ $bus_speed < $bus_speeds[$engine][$port]) {
1890+ $bus_speeds[$engine][$port] = $bus_speed;
1891+ }
1892+ }
1893+ }
1894+ $bus_speed_attr = $bus_speeds[0][0].",".
1895+ $bus_speeds[0][1].",".
1896+ $bus_speeds[0][2].",".
1897+ $bus_speeds[1][0].",".
1898+ $bus_speeds[1][1].",".
1899+ $bus_speeds[1][2];
1900+
1901+ $targetObj->setAttribute($target,"I2C_BUS_SPEED_ARRAY",$bus_speed_attr);
1902+}
1903+
1904+################################
1905+## Setup address map
1906+
1907+sub setupBars
1908+{
1909+ my $targetObj = shift;
1910+ my $target = shift;
1911+ #--------------------------------------------------
1912+ ## Setup BARs
1913+
1914+ my $node = $targetObj->getAttribute($target, "FABRIC_NODE_ID");
1915+ my $proc = $targetObj->getAttribute($target, "FABRIC_CHIP_ID");
1916+ $targetObj->{TOPOLOGY}->{$node}->{$proc}++;
1917+
1918+ my @bars=("FSP_BASE_ADDR","PSI_BRIDGE_BASE_ADDR",
1919+ "INTP_BASE_ADDR","PHB_BASE_ADDRS","PCI_BASE_ADDRS_32",
1920+ "PCI_BASE_ADDRS_64","RNG_BASE_ADDR","IBSCOM_PROC_BASE_ADDR");
1921+
1922+ foreach my $bar (@bars)
1923+ {
1924+ my ($num,$base,$node_offset,$proc_offset,$offset) = split(/,/,
1925+ $targetObj->getAttribute($target,$bar));
1926+ my $i_base = Math::BigInt->new($base);
1927+ my $i_node_offset = Math::BigInt->new($node_offset);
1928+ my $i_proc_offset = Math::BigInt->new($proc_offset);
1929+ my $i_offset = Math::BigInt->new($offset);
1930+
1931+ my $value="";
1932+ if ($num==0)
1933+ {
1934+ $value=$base;
1935+ }
1936+ else
1937+ {
1938+ for (my $i=0;$i<$num;$i++)
1939+ {
1940+ my $b=sprintf("0x%016X",
1941+ $i_base+$i_node_offset*$node+$i_proc_offset*$proc+$i_offset*$i);
1942+ my $sep=",";
Matt Ploetz940dcf62015-02-13 13:52:56 -06001943+ if ($i==$num-1)
Matt Ploetzed8800a2015-02-10 13:12:24 -06001944+ {
1945+ $sep="";
1946+ }
1947+ $value=$value.$b.$sep;
1948+ }
1949+ }
1950+ $targetObj->setAttribute($target,$bar,$value);
1951+ }
1952+}
1953+
1954+#--------------------------------------------------
1955+## MCS
1956+##
1957+sub processMcs
1958+{
1959+ my $targetObj = shift;
1960+ my $target = shift;
1961+ my $parentTarget = shift;
1962+
1963+ my $node = $targetObj->getAttribute($parentTarget, "FABRIC_NODE_ID");
1964+ my $proc = $targetObj->getAttribute($parentTarget, "FABRIC_CHIP_ID");
1965+
1966+ my ($base,$node_offset,$proc_offset,$offset) = split(/,/,
1967+ $targetObj->getAttribute($target,"IBSCOM_MCS_BASE_ADDR"));
1968+ my $i_base = Math::BigInt->new($base);
1969+ my $i_node_offset = Math::BigInt->new($node_offset);
1970+ my $i_proc_offset = Math::BigInt->new($proc_offset);
1971+ my $i_offset = Math::BigInt->new($offset);
1972+
1973+ my $mcs = $targetObj->getAttribute($target, "MCS_NUM");
Matt Ploetz940dcf62015-02-13 13:52:56 -06001974+ my $mcsStr=sprintf("0x%016X",
Matt Ploetzed8800a2015-02-10 13:12:24 -06001975+ $i_base+$i_node_offset*$node+$i_proc_offset*$proc+$i_offset*$mcs);
1976+ $targetObj->setAttribute($target, "IBSCOM_MCS_BASE_ADDR", $mcsStr);
1977+}
1978+
1979+
1980+#--------------------------------------------------
1981+## XBUS
1982+##
1983+## Finds XBUS connections and creates PEER TARGET attributes
1984+
1985+sub processXbus
1986+{
1987+ my $targetObj = shift;
1988+ my $target = shift;
1989+
1990+ # $targetObj->setAttribute($target, "PEER_TARGET","");
Matt Ploetz940dcf62015-02-13 13:52:56 -06001991+
Matt Ploetzed8800a2015-02-10 13:12:24 -06001992+}
1993+
1994+#--------------------------------------------------
1995+## ABUS
1996+##
1997+## Finds ABUS connections and creates PEER TARGET attributes
1998+
1999+sub processAbus
2000+{
2001+ my $targetObj = shift;
2002+ my $target = shift;
2003+
2004+ my $found_abus = 0;
2005+ $targetObj->setAttribute($target, "PEER_PATH","physical:na");
2006+ $targetObj->setAttribute($target, "EI_BUS_TX_LANE_INVERT","0");
2007+ $targetObj->setAttribute($target, "EI_BUS_TX_MSBSWAP","0");
2008+ # $targetObj->setAttribute($target, "PEER_TARGET","");
Matt Ploetz940dcf62015-02-13 13:52:56 -06002009+
Matt Ploetzed8800a2015-02-10 13:12:24 -06002010+ my $abus_child_conn = $targetObj->getFirstConnectionDestination($target);
2011+ if ($abus_child_conn ne "")
2012+ {
2013+ ## set attributes for both directions
2014+ my $aff1 = $targetObj->getAttribute($target, "AFFINITY_PATH");
2015+ my $aff2 = $targetObj->getAttribute($abus_child_conn, "AFFINITY_PATH");
2016+
2017+ $targetObj->setAttribute($abus_child_conn, "PEER_TARGET",
2018+ $targetObj->getAttribute($target, "PHYS_PATH"));
2019+ $targetObj->setAttribute($target, "PEER_TARGET",
2020+ $targetObj->getAttribute($abus_child_conn, "PHYS_PATH"));
2021+
2022+ $targetObj->setAttribute($abus_child_conn, "PEER_PATH",
2023+ $targetObj->getAttribute($target, "PHYS_PATH"));
2024+ $targetObj->setAttribute($target, "PEER_PATH",
2025+ $targetObj->getAttribute($abus_child_conn, "PHYS_PATH"));
2026+
2027+ # copy Abus attributes to proc
2028+ my $abus = $targetObj->getFirstConnectionBus($target);
2029+ $targetObj->setAttribute($target, "EI_BUS_TX_LANE_INVERT",
2030+ $abus->{bus_attribute}->{SOURCE_TX_LANE_INVERT}->{default});
2031+ $targetObj->setAttribute($target, "EI_BUS_TX_MSBSWAP",
2032+ $abus->{bus_attribute}->{SOURCE_TX_MSBSWAP}->{default});
2033+ $targetObj->setAttribute($abus_child_conn, "EI_BUS_TX_LANE_INVERT",
2034+ $abus->{bus_attribute}->{DEST_TX_LANE_INVERT}->{default});
2035+ $targetObj->setAttribute($abus_child_conn, "EI_BUS_TX_MSBSWAP",
2036+ $abus->{bus_attribute}->{DEST_TX_MSBSWAP}->{default});
2037+ $found_abus = 1;
2038+ }
2039+}
2040+
2041+#--------------------------------------------------
2042+## FSI
2043+##
2044+## Finds FSI connections and creates FSI MASTER attributes at endpoint target
2045+
2046+sub processFsi
2047+{
2048+ my $targetObj = shift;
2049+ my $target = shift;
2050+ my $parentTarget = shift;
2051+ my $type = $targetObj->getBusType($target);
2052+
2053+ ## fsi can only have 1 connection
2054+ my $fsi_child_conn = $targetObj->getFirstConnectionDestination($target);
2055+
2056+ ## found something on other end
2057+ if ($fsi_child_conn ne "")
2058+ {
2059+ my $fsi_link = $targetObj->getAttribute($target, "FSI_LINK");
2060+ my $fsi_port = $targetObj->getAttribute($target, "FSI_PORT");
2061+ my $cmfsi = $targetObj->getAttribute($target, "CMFSI");
2062+ my $flip_port = 0;
2063+ my $proc_path = $targetObj->getAttribute($parentTarget,"PHYS_PATH");
2064+ my $fsi_child_target = $targetObj->getTargetParent($fsi_child_conn);
2065+ $targetObj->setFsiAttributes($fsi_child_target,
2066+ $type,$cmfsi,$proc_path,$fsi_port,$flip_port);
2067+ }
2068+}
2069+
2070+#--------------------------------------------------
2071+## PCIE
2072+##
2073+## Creates attributes from abstract PCI attributes on bus
2074+
2075+sub processPcie
2076+{
2077+ my $targetObj = shift;
2078+ my $target = shift;
2079+ my $parentTarget = shift;
2080+
2081+
2082+ ## process pcie config target
2083+ ## this is a special target whose children are the different ways
2084+ ## to configure iop/phb's
2085+
2086+ # TODO RTC: TBD
2087+ # add a 3rd IOP for Naples
2088+
2089+ ## Get config children
2090+ my @lane_swap;
2091+ $lane_swap[0][0] = 0;
2092+ $lane_swap[0][1] = 0;
2093+ $lane_swap[1][0] = 0;
2094+ $lane_swap[1][1] = 0;
2095+
2096+ my @lane_mask;
2097+ $lane_mask[0][0] = "0x0000";
2098+ $lane_mask[0][1] = "0x0000";
2099+ $lane_mask[1][0] = "0x0000";
2100+ $lane_mask[1][1] = "0x0000";
2101+
2102+ my @lane_rev;
2103+ $lane_rev[0][0] = "";
2104+ $lane_rev[0][1] = "";
2105+ $lane_rev[1][0] = "";
2106+ $lane_rev[1][1] = "";
2107+
2108+ my @is_slot;
2109+ $is_slot[0][0] = 0;
2110+ $is_slot[0][1] = 0;
2111+ $is_slot[1][0] = 0;
2112+ $is_slot[1][1] = 0;
2113+
2114+ my $phb_config = "00000000";
2115+
2116+ my %cfg_check;
2117+ my @equalization;
2118+
2119+ my $wiring_table = $targetObj->getAttribute($target,"PCIE_LANE_SWAP_TABLE");
2120+ $wiring_table=~s/\s+//g;
2121+ $wiring_table=~s/\t+//g;
2122+ $wiring_table=~s/\n+//g;
2123+
2124+ my @t = split(/,/,$wiring_table);
2125+ my %iop_swap;
2126+
2127+ #iop_swap{iop}{clk swap}{clk group reversal}
2128+ $iop_swap{0}{0}{'00'}=$t[0];
2129+ $iop_swap{0}{0}{'01'}=$t[1];
2130+ $iop_swap{0}{0}{'10'}=$t[2];
2131+ $iop_swap{0}{0}{'11'}=$t[3];
2132+ $iop_swap{0}{1}{'00'}=$t[4];
2133+ $iop_swap{0}{1}{'01'}=$t[5];
2134+ $iop_swap{0}{1}{'10'}=$t[6];
2135+ $iop_swap{0}{1}{'11'}=$t[7];
2136+
2137+ $iop_swap{1}{0}{'00'}=$t[8];
2138+ $iop_swap{1}{0}{'01'}=$t[9];
2139+ $iop_swap{1}{0}{'10'}=$t[10];
2140+ $iop_swap{1}{0}{'11'}=$t[11];
2141+ $iop_swap{1}{1}{'00'}=$t[12];
2142+ $iop_swap{1}{1}{'01'}=$t[13];
2143+ $iop_swap{1}{1}{'10'}=$t[14];
2144+ $iop_swap{1}{1}{'11'}=$t[15];
2145+
2146+ my @lane_eq;
2147+ my $NUM_PHBS=4;
2148+ for (my $p=0;$p<$NUM_PHBS;$p++)
2149+ {
2150+ for (my $lane=0;$lane<16;$lane++)
2151+ {
2152+ $equalization[$p][$lane] = "0x00,0x00";
2153+ }
2154+ }
2155+ my $found=0;
2156+ foreach my $child (@{ $targetObj->getTargetChildren($target) })
2157+ {
2158+ my $num_connections = $targetObj->getNumConnections($child);
2159+ if ($num_connections > 0)
2160+ {
2161+ $found=1;
2162+ my $pci_endpoint=$targetObj->getFirstConnectionDestination($child);
2163+
2164+ my $bus = $targetObj->getConnectionBus($target, 0);
2165+ my $iop_num = $targetObj->getAttribute($child, "IOP_NUM");
2166+ my $swap_clks=$targetObj->getBusAttribute($child, 0,
2167+ "PCIE_SWAP_CLKS");
2168+
2169+ my $lane_rev=$targetObj->getBusAttribute($child, 0,
2170+ "LANE_REVERSAL");
2171+
2172+ my $phb_num = $targetObj->getAttribute($child, "PHB_NUM");
2173+ my $lane_set = $targetObj->getAttribute($child, "PCIE_LANE_SET");
2174+ my $capi = $targetObj->getAttribute($child, "ENABLE_CAPI");
2175+
2176+ my $pci_endpoint_type =
2177+ $targetObj->getAttribute(
2178+ $targetObj->getTargetParent($pci_endpoint), "CLASS");
2179+
2180+ if ($pci_endpoint_type eq "CARD")
2181+ {
2182+ $is_slot[$iop_num][$lane_set] = 1;
2183+ }
2184+ $lane_swap[$iop_num][$lane_set] =
2185+ $targetObj->getBusAttribute($child, 0, "PCIE_SWAP_CLKS");
2186+ $lane_mask[$iop_num][$lane_set] =
2187+ $targetObj->getAttribute($child, "PCIE_LANE_MASK");
2188+ $lane_rev[$iop_num][$lane_set] =
2189+ $targetObj->getBusAttribute($child, 0, "LANE_REVERSAL");
2190+ my $eq = $targetObj->getBusAttribute($child, 0,
2191+ "PCIE_LANE_EQUALIZATION");
2192+ my @eqs = split(/\,/,$eq);
2193+ for (my $e=0;$e<@eqs;$e=$e+3)
2194+ {
2195+ if ($eqs[$e] eq "all")
2196+ {
2197+ for (my $lane=0;$lane<16;$lane++)
2198+ {
Matt Ploetz940dcf62015-02-13 13:52:56 -06002199+ $equalization[$phb_num][$lane]=$eqs[$e+1].",".$eqs[$e+2];
2200+ }
Matt Ploetzed8800a2015-02-10 13:12:24 -06002201+ }
2202+ else
2203+ {
Matt Ploetz940dcf62015-02-13 13:52:56 -06002204+ $equalization[$phb_num][$eqs[$e]] = $eqs[$e+1].",".$eqs[$e+2];
Matt Ploetzed8800a2015-02-10 13:12:24 -06002205+ }
2206+ }
2207+ substr($phb_config, $phb_num, 1, "1");
2208+ }
2209+ }
2210+ if ($found)
2211+ {
2212+ my $hex = sprintf('%X', oct("0b$phb_config"));
2213+
2214+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_PHB_ACTIVE","0x" . $hex);
2215+ my $lane_mask_attr = sprintf("%s,%s,%s,%s",
2216+ $lane_mask[0][0], $lane_mask[0][1],
2217+ $lane_mask[1][0], $lane_mask[1][1]);
2218+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_LANE_MASK",
2219+ $lane_mask_attr);
2220+ $targetObj->setAttribute($parentTarget,"PROC_PCIE_LANE_MASK_NON_BIFURCATED",
2221+ $lane_mask_attr);
2222+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_LANE_MASK_BIFURCATED",
2223+ "0,0,0,0");
2224+
2225+ my @iop_swap_lu;
2226+ my @iop_lane_swap;
2227+ for (my $iop=0;$iop<2;$iop++)
2228+ {
2229+ $iop_lane_swap[$iop] = $lane_swap[$iop][0] | $lane_swap[$iop][1];
2230+ my $lane_rev = $lane_rev[$iop][0].$lane_rev[$iop][1];
2231+ $iop_swap_lu[$iop]=
2232+ "0b".$iop_swap{$iop}{$iop_lane_swap[$iop]}{$lane_rev};
2233+ if ($iop_swap_lu[$iop] eq "") {
2234+ die "PCIE config for $iop,$iop_lane_swap[$iop],$lane_rev not found\n";
2235+ }
2236+ }
2237+ my $lane_swap_attr0 = sprintf("%s,%s",$iop_lane_swap[0],
2238+ $iop_lane_swap[1]);
2239+ my $lane_swap_attr1 = sprintf("%s,0,%s,0",$iop_lane_swap[0],
2240+ $iop_lane_swap[1]);
2241+
2242+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_IOP_SWAP",
2243+ $lane_swap_attr0);
2244+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_IOP_SWAP_NON_BIFURCATED",
2245+ $lane_swap_attr1);
2246+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_IOP_SWAP_BIFURCATED",
2247+ "0,0,0,0");
2248+
2249+ my $lane_rev_attr = sprintf("%s,0,%s,0",
2250+ oct($iop_swap_lu[0]),oct($iop_swap_lu[1]));
2251+
2252+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_IOP_REVERSAL",
2253+ $lane_rev_attr);
2254+ $targetObj->setAttribute($parentTarget,
2255+ "PROC_PCIE_IOP_REVERSAL_NON_BIFURCATED",$lane_rev_attr);
2256+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_IOP_REVERSAL_BIFURCATED",
2257+ "0,0,0,0");
2258+
2259+ my $is_slot_attr = sprintf("%s,%s,%s,%s",
2260+ $is_slot[0][0], $is_slot[0][1], $is_slot[1][0], $is_slot[1][1]);
2261+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_IS_SLOT", $is_slot_attr);
2262+
2263+ ## don't support DSMP
2264+ $targetObj->setAttribute($parentTarget, "PROC_PCIE_DSMP_CAPABLE","0,0,0,0");
2265+ my $eq_str="";
2266+ for (my $p=0;$p<$NUM_PHBS;$p++)
2267+ {
2268+ for (my $lane=0;$lane<16;$lane++)
2269+ {
2270+ $eq_str=$eq_str.$equalization[$p][$lane].",";
2271+ }
2272+ }
2273+ $eq_str = substr($eq_str,0,length($eq_str)-1);
2274+ $targetObj->setAttribute($parentTarget,"PROC_PCIE_LANE_EQUALIZATION",
2275+ $eq_str);
2276+ }
2277+}
2278+#--------------------------------------------------
2279+## OCC
2280+##
2281+sub processOcc
2282+{
2283+ my $targetObj = shift;
2284+ my $target = shift;
2285+ my $parentTarget = shift;
2286+ my $master_capable=0;
2287+ if ($parentTarget eq $targetObj->getMasterProc())
2288+ {
2289+ $master_capable=1;
2290+ }
2291+ $targetObj->setAttribute($target,"OCC_MASTER_CAPABLE",$master_capable);
2292+}
2293+
2294+sub processMembufVpdAssociation
2295+{
2296+ my $targetObj = shift;
2297+ my $target = shift;
Matt Ploetz940dcf62015-02-13 13:52:56 -06002298+
Matt Ploetzed8800a2015-02-10 13:12:24 -06002299+ my $vpds=$targetObj->findConnections($target,"I2C","VPD");
2300+ if ($vpds ne "" ) {
2301+ my $vpd = $vpds->{CONN}->[0];
2302+
2303+ my $membuf_assocs=$targetObj->findConnections($vpd->{DEST_PARENT},
2304+ "LOGICAL_ASSOCIATION","MEMBUF");
2305+ if ($membuf_assocs ne "") {
2306+ foreach my $membuf_assoc (@{$membuf_assocs->{CONN}}) {
2307+ my $membuf_target = $membuf_assoc->{DEST_PARENT};
2308+ setEepromAttributes($targetObj,
2309+ "EEPROM_VPD_PRIMARY_INFO",$membuf_target,$vpd);
2310+ setEepromAttributes($targetObj,
Matt Ploetz940dcf62015-02-13 13:52:56 -06002311+ "EEPROM_VPD_FRU_INFO",$membuf_target,$vpd,"0++");
Matt Ploetzed8800a2015-02-10 13:12:24 -06002312+ my $index = $targetObj->getBusAttribute($membuf_assoc->{SOURCE},
2313+ $membuf_assoc->{BUS_NUM}, "ISDIMM_MBVPD_INDEX");
2314+ $targetObj->setAttribute(
2315+ $membuf_target,"ISDIMM_MBVPD_INDEX",$index);
2316+ }
2317+ }
2318+ }
2319+}
2320+
2321+#--------------------------------------------------
2322+## MEMBUF
2323+##
2324+## Finds I2C connections to DIMM and creates EEPROM attributes
2325+## FYI: I had to handle DMI busses in framework because they
2326+## define affinity path
2327+
2328+sub processMembuf
2329+{
2330+ my $targetObj = shift;
2331+ my $target = shift;
Matt Ploetz940dcf62015-02-13 13:52:56 -06002332+ if ($targetObj->isBadAttribute($target, "PHYS_PATH", ""))
2333+ {
Matt Ploetzed8800a2015-02-10 13:12:24 -06002334+ ##dmi is probably not connected. will get caught in error checking
2335+ return;
2336+ }
2337+
2338+ processMembufVpdAssociation($targetObj,$target);
2339+
2340+ ## finds which gpio expander that controls vddr regs for membufs
2341+ my $gpioexp=$targetObj->findConnections($target,"I2C","GPIO_EXPANDER");
2342+ if ($gpioexp ne "" ) {
2343+ my $vreg=$targetObj->findConnections(
2344+ $gpioexp->{CONN}->[0]->{DEST_PARENT},"GPIO","VOLTAGE_REGULATOR");
2345+ if ($vreg ne "") {
2346+ my $vddPin = $targetObj->getAttribute(
2347+ $vreg->{CONN}->[0]->{SOURCE},"CHIP_UNIT");
2348+ my $membufs=$targetObj->findConnections(
2349+ $vreg->{CONN}->[0]->{DEST_PARENT},"POWER","MEMBUF");
2350+ if ($membufs ne "") {
2351+ foreach my $membuf (@{$membufs->{CONN}}) {
2352+ my $aff = $targetObj->getAttribute($membuf->{DEST_PARENT},
2353+ "PHYS_PATH");
2354+ setGpioAttributes($targetObj,$membuf->{DEST_PARENT},
2355+ $gpioexp->{CONN}->[0],$vddPin);
2356+
2357+ }
2358+ }
2359+ }
2360+ }
Matt Ploetz940dcf62015-02-13 13:52:56 -06002361+ ## find port mapping
2362+ my %dimm_portmap;
2363+ foreach my $child (@{$targetObj->getTargetChildren($target)})
2364+ {
2365+ if ($targetObj->getType($child) eq "MBA")
2366+ {
2367+ my $mba_num = $targetObj->getAttribute($child,"MBA_NUM");
2368+ my $dimms=$targetObj->findConnections($child,"DDR3","");
2369+ if ($dimms ne "")
2370+ {
2371+ foreach my $dimm (@{$dimms->{CONN}})
2372+ {
2373+ my $port_num = $targetObj->getAttribute(
2374+ $dimm->{SOURCE},"MBA_PORT");
2375+ my $dimm_num = $targetObj->getAttribute(
2376+ $dimm->{SOURCE},"MBA_DIMM");
2377+
2378+ my $map = oct("0b".$mba_num.$port_num.$dimm_num);
2379+ $dimm_portmap{$dimm->{DEST_PARENT}} = $map;
2380+ }
2381+ }
2382+ }
2383+ }
2384+
2385+
Matt Ploetzed8800a2015-02-10 13:12:24 -06002386+ ## Process MEMBUF to DIMM I2C connections
Matt Ploetz940dcf62015-02-13 13:52:56 -06002387+ my @addr_map=('0','0','0','0','0','0','0','0');
Matt Ploetzed8800a2015-02-10 13:12:24 -06002388+ my $dimms=$targetObj->findConnections($target,"I2C","SPD");
2389+ if ($dimms ne "") {
2390+ foreach my $dimm (@{$dimms->{CONN}}) {
2391+ my $dimm_target = $targetObj->getTargetParent($dimm->{DEST_PARENT});
2392+ setEepromAttributes($targetObj,
2393+ "EEPROM_VPD_PRIMARY_INFO",$dimm_target,
2394+ $dimm);
2395+ setEepromAttributes($targetObj,
2396+ "EEPROM_VPD_FRU_INFO",$dimm_target,
2397+ $dimm,"0++");
Matt Ploetz940dcf62015-02-13 13:52:56 -06002398+
2399+ my $field=getI2cMapField($targetObj,$dimm_target,$dimm);
2400+ my $map = $dimm_portmap{$dimm_target};
2401+ if ($map eq "") {
2402+ print "ERROR: $dimm_target doesn't map to a dimm/port\n";
2403+ $targetObj->myExit(3);
2404+ }
2405+ $addr_map[$map] = $field;
Matt Ploetzed8800a2015-02-10 13:12:24 -06002406+ }
2407+ }
Matt Ploetz940dcf62015-02-13 13:52:56 -06002408+ $targetObj->setAttribute($targetObj->{targeting}->{SYS}[0]->{KEY},
2409+ "MRW_MEM_SENSOR_CACHE_ADDR_MAP","0x".join("",@addr_map));
2410+
Matt Ploetzed8800a2015-02-10 13:12:24 -06002411+ ## Update bus speeds
2412+ processI2cSpeeds($targetObj,$target);
2413+
2414+ ## Do MBA port mapping
2415+ my %mba_port_map;
2416+ my $ddrs=$targetObj->findConnections($target,"DDR3","DIMM");
2417+ if ($ddrs ne "") {
2418+ my %portmap;
2419+ foreach my $ddr (@{$ddrs->{CONN}}) {
2420+ my $mba=$ddr->{SOURCE};
2421+ my $dimm=$ddr->{DEST_PARENT};
Matt Ploetz940dcf62015-02-13 13:52:56 -06002422+ my ($dimmnum,$port)=split(//,sprintf("%02b\n",$portmap{$mba}));
Matt Ploetzed8800a2015-02-10 13:12:24 -06002423+ $targetObj->setAttribute($dimm, "MBA_DIMM",$dimmnum);
2424+ $targetObj->setAttribute($dimm, "MBA_PORT",$port);
2425+ $portmap{$mba}++;
2426+
2427+ ## Copy connector attributes
2428+ my $dimmconn=$targetObj->getTargetParent($dimm);
2429+ }
2430+ }
2431+}
2432+
Matt Ploetz940dcf62015-02-13 13:52:56 -06002433+sub getI2cMapField
2434+{
2435+ my $targetObj = shift;
2436+ my $target = shift;
2437+ my $conn_target = shift;
2438+
2439+
2440+ my $port = $targetObj->getAttribute($conn_target->{SOURCE}, "I2C_PORT");
2441+ my $engine = $targetObj->getAttribute($conn_target->{SOURCE}, "I2C_ENGINE");
2442+ my $addr = $targetObj->getBusAttribute($conn_target->{SOURCE},
2443+ $conn_target->{BUS_NUM}, "I2C_ADDRESS");
2444+
2445+ my $bits=sprintf("%08b",hex($addr));
2446+ my $field=sprintf("%d%3s",oct($port),substr($bits,4,3));
2447+ my $hexfield = sprintf("%X",oct("0b$field"));
2448+ return $hexfield;
2449+}
2450+
Matt Ploetzed8800a2015-02-10 13:12:24 -06002451+
2452+sub setEepromAttributes
2453+{
2454+ my $targetObj = shift;
2455+ my $name = shift;
2456+ my $target = shift;
2457+ my $conn_target = shift;
2458+ my $fru = shift;
2459+
2460+ my $port = $targetObj->getAttribute($conn_target->{SOURCE}, "I2C_PORT");
2461+ my $engine = $targetObj->getAttribute($conn_target->{SOURCE}, "I2C_ENGINE");
2462+ my $addr = $targetObj->getBusAttribute($conn_target->{SOURCE},
2463+ $conn_target->{BUS_NUM}, "I2C_ADDRESS");
2464+
2465+ my $path = $targetObj->getAttribute($conn_target->{SOURCE_PARENT},
2466+ "PHYS_PATH");
2467+ my $mem = $targetObj->getAttribute($conn_target->{DEST_PARENT},
2468+ "MEMORY_SIZE_IN_KB");
2469+ my $cycle = $targetObj->getAttribute($conn_target->{DEST_PARENT},
2470+ "WRITE_CYCLE_TIME");
2471+ my $page = $targetObj->getAttribute($conn_target->{DEST_PARENT},
2472+ "WRITE_PAGE_SIZE");
2473+ my $offset = $targetObj->getAttribute($conn_target->{DEST_PARENT},
2474+ "BYTE_ADDRESS_OFFSET");
2475+
2476+ $targetObj->setAttributeField($target, $name, "i2cMasterPath", $path);
2477+ $targetObj->setAttributeField($target, $name, "port", $port);
2478+ $targetObj->setAttributeField($target, $name, "devAddr", $addr);
2479+ $targetObj->setAttributeField($target, $name, "engine", $engine);
2480+ $targetObj->setAttributeField($target, $name, "byteAddrOffset", $offset);
2481+ $targetObj->setAttributeField($target, $name, "maxMemorySizeKB", $mem);
2482+ $targetObj->setAttributeField($target, $name, "writePageSize", $page);
2483+ $targetObj->setAttributeField($target, $name, "writeCycleTime", $cycle);
2484+
2485+ if ($fru ne "")
2486+ {
2487+ $targetObj->setAttributeField($target, $name, "fruId", $fru);
2488+ }
2489+}
2490+
2491+
2492+sub setGpioAttributes
2493+{
2494+ my $targetObj = shift;
2495+ my $target = shift;
2496+ my $conn_target = shift;
2497+ my $vddrPin = shift;
2498+
2499+ my $port = $targetObj->getAttribute($conn_target->{SOURCE}, "I2C_PORT");
2500+ my $engine = $targetObj->getAttribute($conn_target->{SOURCE}, "I2C_ENGINE");
2501+ my $addr = $targetObj->getBusAttribute($conn_target->{SOURCE},
2502+ $conn_target->{BUS_NUM}, "I2C_ADDRESS");
Matt Ploetz940dcf62015-02-13 13:52:56 -06002503+ my $path = $targetObj->getAttribute($conn_target->{SOURCE_PARENT},
Matt Ploetzed8800a2015-02-10 13:12:24 -06002504+ "PHYS_PATH");
2505+
2506+
2507+ my $name="GPIO_INFO";
2508+ $targetObj->setAttributeField($target, $name, "i2cMasterPath", $path);
2509+ $targetObj->setAttributeField($target, $name, "port", $port);
2510+ $targetObj->setAttributeField($target, $name, "devAddr", $addr);
2511+ $targetObj->setAttributeField($target, $name, "engine", $engine);
2512+ $targetObj->setAttributeField($target, $name, "vddrPin", $vddrPin);
2513+}
2514+
2515+#--------------------------------------------------
2516+## ERROR checking
2517+sub errorCheck
2518+{
2519+ my $targetObj = shift;
2520+ my $target = shift;
2521+ my $type = $targetObj->getType($target);
2522+
2523+ ## error checking even for connections are done with attribute checks
2524+ ## since connections simply create attributes at source and/or destination
2525+ ##
2526+ ## also error checking after processing is complete vs during
2527+ ## processing is easier
2528+ my %attribute_checks = (
2529+ SYS => ['SYSTEM_NAME','OPAL_MODEL'],
2530+ PROC_MASTER => ['I2C_SLAVE_ADDRESS'],
2531+ PROC => ['FSI_MASTER_CHIP','I2C_SLAVE_ADDRESS'],
2532+ MEMBUF => [ 'PHYS_PATH', 'EI_BUS_TX_MSBSWAP', 'FSI_MASTER_PORT|0xFF' ],
2533+ DIMM => ['EEPROM_VPD_PRIMARY_INFO/devAddr'],
2534+ );
2535+ my %error_msg = (
2536+ 'EEPROM_VPD_PRIMARY_INFO/devAddr' =>
2537+ 'I2C connection to target is not defined',
2538+ 'FSI_MASTER_PORT' => 'This target is missing a required FSI connection',
2539+ 'FSI_MASTER_CHIP' => 'This target is missing a required FSI connection',
2540+ 'EI_BUS_TX_MSBSWAP' =>
2541+ 'DMI connection is missing to this membuf from processor',
2542+ 'PHYS_PATH' =>'DMI connection is missing to this membuf from processor',
2543+ 'I2C_SLAVE_ADDRESS' =>'I2C connection is missing from BMC to processor',
2544+ );
2545+
2546+ my @errors;
2547+ if ($targetObj->getMasterProc() eq $target)
2548+ {
2549+ $type = "PROC_MASTER";
2550+ }
2551+ foreach my $attr (@{ $attribute_checks{$type} })
2552+ {
2553+ my ($a, $v) = split(/\|/, $attr);
2554+ my ($a_complex, $field) = split(/\//, $a);
2555+ if ($field ne "")
2556+ {
2557+ if ($targetObj->isBadComplexAttribute(
2558+ $target, $a_complex, $field, $v) )
2559+ {
2560+ push(@errors,sprintf(
2561+ "$a attribute is invalid (Target=%s)\n\t%s\n",
2562+ $target, $error_msg{$a}));
2563+ }
2564+ }
2565+ else
2566+ {
2567+ if ($targetObj->isBadAttribute($target, $a, $v))
2568+ {
2569+ push(@errors,sprintf(
2570+ "$a attribute is invalid (Target=%s)\n\t%s\n",
2571+ $target, $error_msg{$a}));
2572+ }
2573+ }
2574+ }
2575+ if ($type eq "PROC")
2576+ {
2577+ ## note: DMI is checked on membuf side so don't need to check that here
2578+ ## this checks if at least 1 abus is connected
2579+ my $found_abus = 0;
2580+ my $abus_error = "";
2581+ foreach my $child (@{ $targetObj->getTargetChildren($target) })
2582+ {
2583+ my $child_type = $targetObj->getBusType($child);
2584+ if ($child_type eq "ABUS" || $child_type eq "XBUS")
2585+ {
2586+ if ($targetObj->getMasterProc() ne $target)
2587+ {
2588+ if (!$targetObj->isBadAttribute($child, "PEER_TARGET"))
2589+ {
2590+ $found_abus = 1;
2591+ }
2592+ else
2593+ {
2594+ $abus_error = sprintf(
2595+"proc not connected to proc via Abus or Xbus (Target=%s)",$child);
2596+ }
2597+ }
2598+ }
2599+ }
2600+ if ($found_abus)
2601+ {
2602+ $abus_error = "";
2603+ }
2604+ else
2605+ {
2606+ push(@errors, $abus_error);
2607+ }
2608+ }
2609+ if ($errors[0])
2610+ {
2611+ foreach my $err (@errors)
2612+ {
2613+ print "ERROR: $err\n";
2614+ }
2615+ $targetObj->myExit(3);
2616+ }
2617+}
2618+
2619+sub printUsage
2620+{
2621+ print "
2622+processMrwl.pl -x [XML filename] [OPTIONS]
2623+Options:
2624+ -f = force output file creation even when errors
2625+ -d = debug mode
2626+ -s [SDR XML file] = import SDRs
2627+ -r = create report and save to [system_name].rpt
2628+ -v = version
2629+";
2630+ exit(1);
2631+}
2632--
26331.8.2.2
2634