summaryrefslogtreecommitdiffstats
path: root/src/usr/targeting/common/Targets.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/targeting/common/Targets.pm')
-rw-r--r--src/usr/targeting/common/Targets.pm688
1 files changed, 673 insertions, 15 deletions
diff --git a/src/usr/targeting/common/Targets.pm b/src/usr/targeting/common/Targets.pm
index aa1e07f7d..c106ef0fc 100644
--- a/src/usr/targeting/common/Targets.pm
+++ b/src/usr/targeting/common/Targets.pm
@@ -22,6 +22,7 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+
package Targets;
use strict;
@@ -78,12 +79,18 @@ my %maxInstance = (
"NPU" => 1,
"MC" => 2,
"MI" => 4,
+ "MCC" => 8,
+ "OMI" => 16,
+ "OCMB_CHIP" => 16,
+ "MEM_PORT" => 16,
+ "DDIMM" => 16,
"DMI" => 8,
"OCC" => 1,
"NV" => 6,
"NX" => 1,
"MEMBUF" => 8,
"SMPGROUP" => 8,
+ "OMIC" => 6,
);
sub new
{
@@ -94,6 +101,7 @@ sub new
targeting => undef,
enumerations => undef,
MAX_MCS => 0,
+ master_proc => undef,
UNIT_COUNTS => undef,
huid_idx => undef,
mru_idx => undef,
@@ -223,9 +231,17 @@ sub printTarget
return;
}
+ my $target_TYPE = $self->getAttribute($target, "TYPE");
+
+ # Only allow OMI types with MCC parent
+ # OMIC_PARENT only exists on an OMI target with MCC parent
+ if ($target_TYPE eq "OMI" && !defined($target_ptr->{ATTRIBUTES}->{"OMIC_PARENT"}->{default}))
+ {
+ return;
+ }
+
print $fh "<targetInstance>\n";
my $target_id = $self->getAttribute($target, "PHYS_PATH");
- my $target_TYPE = $self->getAttribute($target, "TYPE");
$target_id = substr($target_id, 9);
$target_id =~ s/\///g;
$target_id =~ s/\-//g;
@@ -545,6 +561,13 @@ sub buildHierarchy
},
$b
);
+ push(
+ @{
+ $self->{data}->{TARGETS}->{$source_target}->{CONNECTION}
+ ->{BUS_PARENT}
+ },
+ $key
+ );
my %bus_entry;
$bus_entry{SOURCE_TARGET} = $source_target;
$bus_entry{DEST_TARGET} = $dest_target;
@@ -643,9 +666,17 @@ sub buildAffinity
my $tpm = -1;
my $ucd = -1;
my $bmc = -1;
+ my $mcc = -1;
+ my $omi = -1;
+ my $ocmb = -1;
+ my $mem_port = -1;
+ my $i2c_mux = -1;
+ my $dimm = -1;
+ my $pmic = -1;
my $sys_phys = "";
my $node_phys = "";
my $node_aff = "";
+ my $proc_fapi = "";
my $sys_pos = 0; # There is always a single system target
my $mcbist = -1;
my $num_mc = 0 ;
@@ -776,6 +807,64 @@ sub buildAffinity
$self->deleteAttribute($target, "POSITION");
$self->deleteAttribute($target, "FRU_ID");
}
+ elsif ($type eq "MCC")
+ {
+ $mcc++;
+
+ # For a given proc, there are 2 MCs, 4 MIs, 8 MCCs, and 16 OMIs
+ # To get the corresponding proc, MC, or MI number for a given MCC
+ # divide the MCC number by the number of MCCs per unit, then mod 2
+ # to get the relative path in terms of 0 or 1
+ my $numOfMccsPerProc = $maxInstance{$type};
+ my $numOfMccsPerMc = 4;
+ my $numOfMccsPerMi = 2;
+ my $proc_num = ($mcc / $numOfMccsPerProc) % 2;
+ my $mc_num = ($mcc / $numOfMccsPerMc) % 2;
+ my $mi_num = ($mcc / $numOfMccsPerMi) % 2;
+ my $mcc_num = $mcc % 2;
+ my $path = "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num";
+ my $mcc_aff = $node_aff . $path;
+ my $mcc_phys = $node_phys . $path;
+ $self->setAttribute($target, "AFFINITY_PATH", $mcc_aff);
+ $self->setAttribute($target, "PHYS_PATH", $mcc_phys);
+
+ $self->setAttribute($target, "REL_POS", $mcc_num);
+ my $pos = $self->getAttribute($target, "CHIP_UNIT");
+ my $fapi_pos = $pos + $numOfMccsPerProc * $proc_fapi;
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "ORDINAL_ID", $mcc);
+ }
+ elsif ($type eq "OMI")
+ {
+ # We only want OMIs with MCC parent, skip over the ones with OMIC parent
+ my $parent = $self->getTargetParent($target);
+ my $parent_type = $self->getType($parent);
+ if ($parent_type eq "MCC")
+ {
+ $omi++;
+
+ # Same logic for MCC, but for OMI instead
+ my $numOfOmisPerProc = $maxInstance{$type};
+ my $numOfOmisPerMc = 8;
+ my $numOfOmisPerMi = 4;
+ my $numOfOmisPerMcc = 2;
+ my $proc_num = ($omi / $numOfOmisPerProc) % 2;
+ my $mc_num = ($omi / $numOfOmisPerMc) % 2;
+ my $mi_num = ($omi / $numOfOmisPerMi) % 2;
+ my $mcc_num = ($omi / $numOfOmisPerMcc) % 2;
+ my $omi_num = $omi % 2;
+ my $path = "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num";
+ my $omi_aff = $node_aff . $path;
+ my $omi_phys = $node_phys . $path;
+ $self->setAttribute($target, "AFFINITY_PATH", $omi_aff);
+ $self->setAttribute($target, "PHYS_PATH", $omi_phys);
+
+ my $pos = $self->getAttribute($target, "CHIP_UNIT");
+ my $fapi_pos = $pos + $numOfOmisPerProc * $proc_fapi;
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "ORDINAL_ID", $omi);
+ }
+ }
elsif ($type eq "BMC")
{
$bmc++;
@@ -801,7 +890,322 @@ sub buildAffinity
my $ddrs = $self->findConnections($target,"DDR4","");
$self->processMcaDimms($ddrs, $sys_pos, $node_phys, $node, $proc);
}
+ elsif ($type eq "OCMB_CHIP")
+ {
+ # Ocmbs are not in order, so we take the parent dimm's POSITION as
+ # our current ocmb number
+ # Ex. dimm19 = ocmb19
+ my $parent = $self->getTargetParent($target);
+ $ocmb = $self->getAttribute($parent, "POSITION");
+ $self->{targeting}{SYS}[0]{NODES}[$node]{OCMB_CHIPS}[$ocmb]{KEY} = $target;
+ $self->setHuid($target, $sys_pos, $node);
+
+ my $ocmb_phys = $node_phys . "/ocmb_chip-$ocmb";
+
+ # Find the OMI bus connection to determine target values
+ my $proc_num = -1;
+ my $mc_num = -1;
+ my $mi_num = -1;
+ my $mcc_num = -1;
+ my $omi_num = -1;
+ my $conn = $self->findConnectionsByDirection($target, "OMI", "", 1);
+
+ my $omi_chip_unit = -1;
+ if ($conn ne "")
+ {
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ if ($source =~ /omic/i)
+ {
+ next;
+ }
+ my @targets = split(/\//, $source);
+ # Split the source into proc#, mc#, mi#, mcc#, omi#
+ # Source example:
+ # /sys-#/node-#/Pallid-#/proc_socket-#/Hopper-#/p9_axone/mc#/mi#/mcc#/omi#
+ foreach my $target (@targets)
+ {
+ $target =~ s/\D//g;
+ }
+
+ # Splitting on "/" makes the first array index empty string
+ # so every value here is shifted over by 1
+ # There are only ever two targets per parent in this case,
+ # so to get the relative positions for each target, we take
+ # mod two of the source value
+ $proc_num = $targets[4] % 2;
+ $mc_num = $targets[7] % 2;
+ $mi_num = $targets[8] % 2;
+ $mcc_num = $targets[9] % 2;
+
+ # omi_num indicates the chip_unit of the corresponding omi
+ $omi_num = $targets[10];
+ $omi_chip_unit = $omi_num;
+ $omi_num %= 2;
+ }
+ }
+
+ my $ocmb_aff = $node_aff . "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num/ocmb_chip-0";
+ $self->setAttribute($target, "AFFINITY_PATH", $ocmb_aff);
+ $self->setAttribute($target, "PHYS_PATH", $ocmb_phys);
+
+ # The standard fapi_pos calculation uses the relative position to
+ # the proc instead of omi_chip_unit. However, in this case, there is
+ # no direct way to get the relative position to the proc. The
+ # relationship between ocmb and omi is 1:1, so we take the chip unit
+ # of the corresponding omi as the relative position to the proc
+ my $fapi_pos = $omi_chip_unit + ($maxInstance{$type} * $proc_num);
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+
+ my $ocmb_num = $fapi_pos;
+ # The norm for FAPI_NAME has a two digit number at the end
+ if ($fapi_pos < 10)
+ {
+ $ocmb_num = "0$fapi_pos";
+ }
+
+ $self->setAttribute($target, "MRU_ID", "0x00060000");
+ $self->setAttribute($target, "POSITION", $ocmb);
+
+ # chipunit:system:node:slot:position
+ $self->setAttribute($target, "FAPI_NAME", "ocmb:k0:n0:s0:p$ocmb_num");
+
+ $self->setAttribute($target, "REL_POS", "0");
+
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ my $master_path = "physical:sys-0/node-0/proc-$proc_num";
+ $self->setAttributeField($target, $fapi_name, "i2cMasterPath", $master_path);
+
+ my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
+ $self->setAttributeField($target, $eeprom_name, "i2cMasterPath", $master_path);
+ $self->setAttributeField($target, $eeprom_name, "chipCount", "0x01");
+ }
+ elsif ($type eq "I2C_MUX")
+ {
+ $i2c_mux++;
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{I2C_MUXS}[$i2c_mux]{KEY} = $target;
+
+ # There exists 1 i2c_mux per MC, so 2 i2c_mux per proc
+ my $numOfMuxesPerProc = 2;
+ my $proc_num = ($i2c_mux / $numOfMuxesPerProc) % 2;
+ my $i2c_aff = $node_aff . "/proc-$proc_num/i2c_mux-$i2c_mux";
+ $self->setAttribute($target, "AFFINITY_PATH", $i2c_aff);
+
+ my $i2c_phys = $node_phys . "/i2c_mux-$i2c_mux";
+ $self->setAttribute($target, "PHYS_PATH", $i2c_phys);
+ $self->setHuid($target, $sys_pos, $node);
+
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ my $master_path = $node_phys . "/proc-$proc_num";
+ $self->setAttributeField($target, $fapi_name, "i2cMasterPath", $master_path);
+ my $conn = $self->findConnectionsByDirection($target, "I2C",
+ "", 1);
+ if ($conn ne "")
+ {
+ # Get the i2c-master-omi which has the engine and port values
+ # The endpoint mux has the devAddr
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ my $dest = $conn->{DEST};
+ if ($self->getTargetParent($conn->{DEST}) eq $target)
+ {
+ $self->setAttributeField($target, $fapi_name, "engine",
+ $self->getAttribute($source, "I2C_ENGINE"));
+ $self->setAttributeField($target, $fapi_name, "port",
+ $self->getAttribute($source, "I2C_PORT"));
+ $self->setAttributeField($target, $fapi_name, "devAddr",
+ $self->getAttribute($dest, "I2C_ADDRESS"));
+ }
+ }
+ }
+ }
+ elsif ($type eq "MEM_PORT")
+ {
+ my $parent = $self->getTargetParent($target);
+ my $ocmb_num = $self->getAttribute($parent, "POSITION");
+ my $ocmb_affinity = $self->getAttribute($parent, "AFFINITY_PATH");
+ $self->setAttribute($target, "AFFINITY_PATH", "$ocmb_affinity/mem_port-0");
+ my $ocmb_phys = $self->getAttribute($parent, "PHYS_PATH");
+ $self->setAttribute($target, "PHYS_PATH", "$ocmb_phys/mem_port-0");
+ $self->setHuid($target, $sys_pos, $node);
+ $self->deleteAttribute($target, "EXP_SAFEMODE_MEM_THROTTLED_N_COMMANDS_PER_PORT");
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{OCMB_CHIPS}[$ocmb_num]{MEM_PORTS}[0]{KEY} = $target;
+ }
+ # Witherspoon has its own DIMM parsing mechanism so don't want to
+ # interfere with it
+ elsif ($type eq "DIMM" && $self->getTargetType($target) eq "lcard-dimm-ddimm")
+ {
+ # Dimms are not posted in order, so need to get the dimm's position
+ $dimm = $self->getAttribute($target, "POSITION");
+
+ # Find the OMI bus connection to determine target values
+ my $proc_num = -1;
+ my $mc_num = -1;
+ my $mi_num = -1;
+ my $mcc_num = -1;
+ my $omi_num = -1;
+ my $conn = $self->findConnectionsByDirection($target, "OMI", "", 1);
+
+ my $omi_chip_unit = -1;
+ if ($conn ne "")
+ {
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ my @targets = split(/\//, $source);
+
+ if ($source =~ /omic/i)
+ {
+ next;
+ }
+
+ # Split the source into proc#, mc#, mi#, mcc#, omi#
+ # Source example:
+ # /sys-#/node-#/Pallid-#/proc_socket-#/Hopper-#/p9_axone/mc#/mi#/mcc#/omi#
+ foreach my $target (@targets)
+ {
+ $target =~ s/\D//g;
+ }
+
+ # Splitting on "/" makes the first array index empty string
+ # so every value here is shifted over by 1
+ # There are only ever two targets per parent in this case,
+ # so to get the relative positions for each target, we take
+ # mod two of the source value
+ $proc_num = $targets[4] % 2;
+ $mc_num = $targets[7] % 2;
+ $mi_num = $targets[8] % 2;
+ $mcc_num = $targets[9] % 2;
+ $omi_num = $targets[10];
+
+ # omi_num indicates the chip_unit of the corresponding omi
+ $omi_chip_unit = $omi_num;
+ $omi_num %= 2;
+ }
+ }
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{DIMMS}[$dimm]{KEY} = $target;
+ $self->setAttribute($target, "PHYS_PATH", $node_phys . "/dimm-$dimm");
+ $self->setHuid($target, $sys_pos, $node);
+
+ # The standard fapi_pos calculation uses the relative position to
+ # the proc instead of omi_chip_unit. However, in this case, there is
+ # no direct way to get the relative position to the proc. The
+ # relationship between dimm and omi is 1:1, so we take the chip unit
+ # of the corresponding omi as the relative position to the proc
+ my $fapi_pos = $omi_chip_unit + ($maxInstance{"DDIMM"} * $proc_num);
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "ORDINAL_ID", $dimm);
+ $self->setAttribute($target, "REL_POS", 0);
+ $self->setAttribute($target, "VPD_REC_NUM", $dimm);
+
+ my $dimm_num = $fapi_pos;
+ if ($fapi_pos < 10)
+ {
+ $dimm_num = "0$fapi_pos";
+ }
+ # chipunit:slot:node:system:position
+ $self->setAttribute($target, "FAPI_NAME", "dimm:k0:n0:s0:p$dimm_num");
+
+ my $ocmb_num = 0;
+ my $mem_num = 0;
+ $dimm_num = 0;
+ my $dimm_aff = $node_aff . "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num/ocmb_chip-$ocmb_num/mem_port-$mem_num/dimm-$dimm_num";
+ $self->setAttribute($target, "AFFINITY_PATH", $dimm_aff);
+
+ my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
+ $self->setAttributeField($target, $eeprom_name, "chipCount", "0x01");
+ $self->setAttributeField($target, $eeprom_name, "i2cMasterPath", "physical:sys-0/node-0/proc-$proc_num");
+ }
+ elsif ($type eq "PMIC")
+ {
+ # Pmics are not in order, so we take the parent dimm's
+ # POSITION * 4 as our current pmic number, adding one
+ # if it's a pmic1, two if it's a pmic2, three if it's a
+ # pmic3
+ # Ex. on a pmic0, dimm19 = pmic76
+ # Ex. on a pmic1, dimm19 = pmic77
+ # Ex. on a pmic2, dimm19 = pmic78
+ # Ex. on a pmic3, dimm19 = pmic79
+ my $instance_name = $self->getInstanceName($target);
+ my $parent = $self->getTargetParent($target);
+ my $parent_fapi_pos = $self->getAttribute($parent, "FAPI_POS");
+ my $parent_pos = $self->getAttribute($parent, "POSITION");
+ my $position = $self->getAttribute($target, "POSITION");
+ $pmic = ($parent_pos * 4) + $position;
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{PMICS}[$pmic]{KEY} = $target;
+ $self->setAttribute($target, "PHYS_PATH", $node_phys . "/pmic-$pmic");
+ $self->setAttribute($target, "ORDINAL_ID", $pmic);
+ $self->setAttribute($target, "REL_POS", $pmic % 2);
+
+ # Same logic with the position, but with FAPI_POS instead
+ my $fapi_pos = ($parent_fapi_pos * 4) + $position;
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "POSITION", $pmic);
+ $self->setHuid($target, $sys_pos, $node);
+
+ my $pmic_num = $fapi_pos;
+ # The norm for FAPI_NAME has a two digit number at the end
+ if ($fapi_pos < 10)
+ {
+ $pmic_num = "0$fapi_pos";
+ }
+ # chipunit:slot:node:system:position
+ $self->setAttribute($target, "FAPI_NAME", "pmic:k0:n0:s0:p$pmic_num");
+
+ # Find the OMI bus connection to determine target values
+ my $proc_num = -1;
+ my $mc_num = -1;
+ my $mi_num = -1;
+ my $mcc_num = -1;
+ my $omi_num = -1;
+ my $conn = $self->findConnectionsByDirection($self->getTargetParent($target), "OMI", "", 1);
+ if ($conn ne "")
+ {
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ my @targets = split(/\//, $source);
+ # Split the source into proc#, mc#, mi#, mcc#, omi#
+ # Source example:
+ # /sys-#/node-#/Pallid-#/proc_socket-#/Hopper-#/p9_axone/mc#/mi#/mcc#/omi#
+ if ($source =~ /omic/i)
+ {
+ next;
+ }
+
+ foreach my $target (@targets)
+ {
+ $target =~ s/\D//g;
+ }
+ # Splitting on "/" makes the first array index empty string
+ # so every value here is shifted over by 1
+ # There are only ever two targets per parent in this case,
+ # so to get the relative positions for each target, we take
+ # mod two of the source value
+ $proc_num = $targets[4] % 2;
+ $mc_num = $targets[7] % 2;
+ $mi_num = $targets[8] % 2;
+ $mcc_num = $targets[9] % 2;
+ $omi_num = $targets[10] % 2;
+ }
+ }
+
+ my $ocmb_num = 0;
+ $pmic_num %= 2;
+ my $pmic_aff = $node_aff . "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num/ocmb_chip-$ocmb_num/pmic-$pmic_num";
+ $self->setAttribute($target, "AFFINITY_PATH", $pmic_aff);
+
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ $self->setAttributeField($target, $fapi_name, "i2cMasterPath",
+ "physical:sys-0/node-0/proc-$proc_num");
+ }
elsif ($type eq "PROC")
{
my $socket = $target;
@@ -879,14 +1283,14 @@ sub buildAffinity
$self->setAttribute($target, "POSITION", $proc);
$self->setAttribute($target, "FABRIC_GROUP_ID",
- $self->getAttribute($socket,"FABRIC_GROUP_ID"));
+ $self->getAttribute($socket,"FABRIC_GROUP_ID"));
$self->setAttribute($target, "FABRIC_CHIP_ID",
- $self->getAttribute($socket,"FABRIC_CHIP_ID"));
+ $self->getAttribute($socket,"FABRIC_CHIP_ID"));
$self->setAttribute($target, "VPD_REC_NUM", $proc);
- $self->setAttribute($target, "FAPI_POS",
- $self->getAttribute($socket,"FABRIC_GROUP_ID") *
- NUM_PROCS_PER_GROUP +
- $self->getAttribute($socket,"FABRIC_CHIP_ID"));
+ $proc_fapi = $self->getAttribute($socket, "FABRIC_GROUP_ID") *
+ NUM_PROCS_PER_GROUP +
+ $self->getAttribute($socket, "FABRIC_CHIP_ID");
+ $self->setAttribute($target, "FAPI_POS", $proc_fapi);
# Both for FSP and BMC based systems, it's good enough
# to look for processor with active LPC bus connected
@@ -1026,6 +1430,11 @@ sub iterateOverChiplets
my $tgt_ptr = $self->getTarget($target);
my $tgt_type = $self->getType($target);
+ # Previous OBUS parent
+ my $prev_obus = -1;
+ # Subtract factor for OBUS_BRICK
+ my $brick_sub = -1;
+
my $target_children = $self->getTargetChildren($target);
if ($target_children eq "")
@@ -1120,13 +1529,27 @@ sub iterateOverChiplets
#System XML has some sensor target as hidden children
#of targets. We don't care for sensors in this function
#So, we can avoid them with this conditional
-
if ($unit_type ne "PCI" && $unit_type ne "NA" &&
$unit_type ne "FSI" && $unit_type ne "PSI" &&
$unit_type ne "SYSREFCLKENDPT" && $unit_type ne "MFREFCLKENDPT")
{
+ if ($unit_type eq "OBUS_BRICK")
+ {
+ # Check to see if this is on a new obus
+ # Current obus is the CHIP_UNIT of the parent obus
+ my $curr_obus = $self->getAttribute($target,
+ "CHIP_UNIT");
+ if ($prev_obus ne $curr_obus)
+ {
+ my $brick_pos = $self->getAttribute($child,
+ "CHIP_UNIT");
+ $brick_sub = $brick_pos;
+ $prev_obus = $curr_obus;
+ }
+ }
#set common attrs for child
- $self->setCommonAttrForChiplet($child, $sys, $node, $proc);
+ $self->setCommonAttrForChiplet($child, $sys, $node, $proc,
+ $prev_obus, $brick_sub);
$self->iterateOverChiplets($child, $sys, $node, $proc);
}
}
@@ -1156,6 +1579,8 @@ sub setCommonAttrForChiplet
my $sys = shift;
my $node = shift;
my $proc = shift;
+ my $prev_obus = shift;
+ my $brick_sub = shift;
my $tgt_ptr = $self->getTarget($target);
my $tgt_type = $self->getType($target);
@@ -1194,7 +1619,15 @@ sub setCommonAttrForChiplet
}
elsif ($tgt_type eq "OBUS_BRICK")
{
- $unit_pos = $pos%3;
+ # Relative position of OBUS_BRICK is just the difference between the
+ # current position and the position of the first obus_brick of the
+ # parent obus
+ # Ex: obus3 -> obus_brick9
+ # -> obus_brick10
+ # -> obus_brick11
+ # Position of first obus_brick of parent obus = 9
+ # Relative position of obus_brick11 = 11 - 9 = 2
+ $unit_pos = $pos - $brick_sub;
}
elsif ($tgt_type eq "SMPGROUP")
{
@@ -1203,6 +1636,11 @@ sub setCommonAttrForChiplet
$self->setAttribute($target, "INSTANCE_PATH", $target);
$unit_pos = $pos%2;
}
+ elsif ($tgt_type eq "OMIC")
+ {
+ # There are 3 OMICs per MC parent
+ $unit_pos = $pos % 3;
+ }
my $parent_affinity = $self->getAttribute(
$self->getTargetParent($target),"AFFINITY_PATH");
@@ -1394,6 +1832,7 @@ sub getPervasiveForUnit
my $offset = 0;
for my $obrick (0..$maxInstance{"OBUS_BRICK"}-1)
{
+ #todo-RTC:209409-Handle Axone layout
$offset += (($obrick%3 == 0) && ($obrick != 0)) ? 1 : 0;
$unitToPervasive{"OBUS_BRICK$obrick"}
= PERVASIVE_PARENT_OBUS_OFFSET + $offset;
@@ -1412,6 +1851,7 @@ sub getPervasiveForUnit
return $pervasive
}
+
sub processMcaDimms
{
my $self = shift;
@@ -1546,6 +1986,12 @@ sub processMc
foreach my $dmi (@{ $self->getTargetChildren($mi) })
{
+ my $child_type = $self->getType($dmi);
+ if ($child_type ne "DMI")
+ {
+ next;
+ }
+
my $dmi_num = $self->getAttribute($dmi, "CHIP_UNIT");
my $membufnum = $proc * $self->{MAX_DMI} + $dmi_num;
@@ -1572,7 +2018,7 @@ sub processMc
my $parent_physical = $self->getAttribute($membuf, "PHYS_PATH");
$self->setAttribute($membuf,"FAPI_NAME",
- $self->getFapiName($membuf_type, $node, $membufnum));
+ $self->getFapiName($membuf_type, $node, $membufnum, $memCardOffset));
my $fapi_pos = (($node * $maxInstance{"PROC"}) + $proc ) * $self->{MAX_DMI} + $dmi_num;
@@ -1955,6 +2401,15 @@ sub getConnectionBus
return $target_ptr->{CONNECTION}->{BUS}->[$i];
}
+sub getConnectionBusParent
+{
+ my $self = shift;
+ my $target = shift;
+ my $i = shift;
+ my $target_ptr = $self->getTarget($target);
+ return $target_ptr->{CONNECTION}->{BUS_PARENT}->[$i];
+}
+
sub findFirstEndpoint
{
my $self = shift;
@@ -2012,6 +2467,192 @@ sub findDestConnections
}
+sub setEepromAttributesForAxone
+{
+ my $self = shift;
+ my $targetObj = shift;
+ # Expects ocmb target
+ my $target = shift;
+
+ my %connections;
+ my $num=0;
+
+ my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ # SPD contains data for EEPROM_VPD_PRIMARY_INFO and FAPI_I2C_CONTROL_INFO
+ # SPD is the child of ocmb's parent, so get ocmb's parent
+ # then look for the SPD child
+ # With the resulting info, we populate pmic0, pmic1, ocmb, and dimm
+ my $target_parent = $self->getTargetParent($target);
+
+ # Need to store pmic targets because they get parsed before we
+ # do calculations for engine, port, and muxBusSelector
+ # pmics need these values, so we store them until we need them later
+ my $address = 0;
+ my @pmic_array;
+ foreach my $child (@{ $self->getTargetChildren($target_parent) })
+ {
+ my $type = $self->getTargetType($child);
+ if ($type eq "chip-spd-device")
+ {
+ my $offset = $self->getAttribute($child, "BYTE_ADDRESS_OFFSET");
+ my $memory_size = $self->getAttribute($child, "MEMORY_SIZE_IN_KB");
+ my $cycle_time = $self->getAttribute($child, "WRITE_CYCLE_TIME");
+ my $page_size = $self->getAttribute($child, "WRITE_PAGE_SIZE");
+
+ # Populate EEPROM for ocmb
+ $targetObj->setAttributeField($target, $eeprom_name, "byteAddrOffset",
+ $offset);
+ $targetObj->setAttributeField($target, $eeprom_name, "maxMemorySizeKB",
+ $memory_size);
+ $targetObj->setAttributeField($target, $eeprom_name, "writeCycleTime",
+ $cycle_time);
+ $targetObj->setAttributeField($target, $eeprom_name, "writePageSize",
+ $page_size);
+
+ # Populate EEPROM for dimm
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "byteAddrOffset",
+ $offset);
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "maxMemorySizeKB",
+ $memory_size);
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "writeCycleTime",
+ $cycle_time);
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "writePageSize",
+ $page_size);
+
+ # spd only child is i2c-slave, which contains devAddr info
+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
+ {
+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
+ # Populate EEPROM for dimm
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "devAddr",
+ $address);
+
+ # Populate EEPROM for ocmb
+ $targetObj->setAttributeField($target, $eeprom_name, "devAddr",
+ $address);
+ }
+ }
+ elsif ($type eq "chip-vreg-generic")
+ {
+ push(@pmic_array, $child);
+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
+ {
+ $type = $self->getTargetType($i2c_slave);
+ # pmic has child i2c_slave which contains the device address
+ if ($type eq "unit-i2c-slave")
+ {
+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
+
+ # Populate FAPI for pmic
+ $targetObj->setAttributeField($child, $fapi_name, "devAddr",
+ $address);
+ last;
+ }
+ }
+ }
+ elsif ($type eq "chip-ocmb")
+ {
+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
+ {
+ # ocmb has multiple i2c-slaves, so we query with instance_name
+ my $instance_name = $self->getInstanceName($i2c_slave);
+ if ($instance_name eq "i2c-ocmb")
+ {
+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
+
+ # Populate FAPI for ocmb
+ $targetObj->setAttributeField($target, $fapi_name, "devAddr",
+ $address);
+ last;
+ }
+ }
+ }
+ }
+
+ # Get data from i2c-master-omi, which connects to the i2c_mux PCA9847
+ my $conn = $self->findConnectionsByDirection($target, "I2C", "", 1);
+ if ($conn ne "")
+ {
+ # There exists multiple i2c bus connections with chip-ocmb
+ # They are all the same connections so we just take the first one
+ # The mux channel has the i2cMuxBusSelector
+ my $conn_source = @{$conn->{CONN}}[0]->{SOURCE};
+ my $mux = $self->getAttribute($conn_source, "MUX_CHANNEL");
+
+ # Parent PCA9848 determines the mux path
+ my $parent = $self->getTargetParent($conn_source);
+ my $parent_pos = $self->getAttribute($parent, "POSITION");
+ my $i2c_mux_path = "physical:sys-0/node-0/i2c_mux-$parent_pos";
+
+ # pmics and ocmb all grab FRU_ID from parent dimm
+ my $fru = $self->getAttribute($target_parent, "FRU_ID");
+
+ my $master_i2c = $self->findConnectionsByDirection($self->getTargetParent($conn_source), "I2C", "", 1);
+ if ($master_i2c ne "")
+ {
+ # There exists multiple i2c bus connections with the PCA9847 i2c_mux
+ # They are all the same connections so we just take the first one
+ $master_i2c = @{$master_i2c->{CONN}}[0];
+ # i2c-master-omi source which has data we need
+ my $source = $master_i2c->{SOURCE};
+ my $dest = $master_i2c->{DEST};
+ my $engine = $self->getAttribute($source, "I2C_ENGINE");
+ my $port = $self->getAttribute($source, "I2C_PORT");
+
+ # Populate FAPI for ocmb
+ $self->setAttributeField($target, $fapi_name, "engine",
+ $engine);
+ $self->setAttributeField($target, $fapi_name, "port",
+ $port);
+ $self->setAttributeField($target, $fapi_name, "i2cMuxBusSelector",
+ $mux);
+ $self->setAttributeField($target, $fapi_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttribute($target, "FRU_ID",
+ $fru);
+
+ # Populate EEPROM for ocmb
+ $self->setAttributeField($target, $eeprom_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttributeField($target, $eeprom_name, "engine",
+ $engine);
+ $self->setAttributeField($target, $eeprom_name, "port",
+ $port);
+ $self->setAttributeField($target, $eeprom_name, "i2cMuxBusSelector",
+ $mux);
+
+
+ # Populate FAPI for pmics
+ foreach my $pmic (@pmic_array)
+ {
+ $self->setAttributeField($pmic, $fapi_name, "engine",
+ $engine);
+ $self->setAttributeField($pmic, $fapi_name, "port",
+ $port);
+ $self->setAttributeField($pmic, $fapi_name, "i2cMuxBusSelector",
+ $mux);
+ $self->setAttributeField($pmic, $fapi_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttribute($pmic, "FRU_ID",
+ $fru);
+ }
+
+ # Populate EEPROM for dimm
+ $self->setAttributeField($target_parent, $eeprom_name, "engine",
+ $engine);
+ $self->setAttributeField($target_parent, $eeprom_name, "port",
+ $port);
+ $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxBusSelector",
+ $mux);
+ $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttribute($target_parent, "FRU_ID",
+ $fru);
+ }
+ }
+}
+
# Find connections from/to $target (and it's children)
# $to_this_target indicates the direction to find.
sub findConnectionsByDirection
@@ -2049,6 +2690,7 @@ sub findConnectionsByDirection
{
$numOfConnections = $self->getNumConnections($child);
}
+
for (my $i = 0; $i < $numOfConnections; $i++)
{
my $other_end_target = undef;
@@ -2061,6 +2703,7 @@ sub findConnectionsByDirection
$other_end_target = $self->getConnectionDestination($child,
$i);
}
+
my $other_end_parent = $self->getTargetParent($other_end_target);
my $type = $self->getMrwType($other_end_parent);
my $dest_type = $self->getType($other_end_parent);
@@ -2079,12 +2722,10 @@ sub findConnectionsByDirection
#like unit->pingroup->muxgroup->chip where the chip has
#the interesting type.
while ($type ne $other_end_type) {
-
$other_end_parent = $self->getTargetParent($other_end_parent);
if ($other_end_parent eq "") {
last;
}
-
$type = $self->getMrwType($other_end_parent);
if ($type eq "NA") {
$type = $self->getType($other_end_parent);
@@ -2518,7 +3159,6 @@ sub setHuid
$index = $self->{huid_idx}->{$type};
}
else { $self->{huid_idx}->{$type} = 0; }
-
# Format: SSSS NNNN TTTTTTTT iiiiiiiiiiiiiiii
my $huid = sprintf("%01x%01x%02x%04x", $sys, $node, $type_id, $index);
$huid = "0x" . uc($huid);
@@ -2554,6 +3194,19 @@ sub setMruid
$self->{mru_idx}->{$node}->{$type}++;
}
+sub getMasterProc
+{
+ my $self = shift;
+ return $self->{master_proc};
+}
+
+sub setMasterProc
+{
+ my $self = shift;
+ my $target = shift;
+ $self->{master_proc}=$target;
+}
+
sub getSystemName
{
my $self = shift;
@@ -2786,11 +3439,16 @@ C<TARGET_STRING>. The bus data structure is also a target with attributes.
Returns the target string of the C<INDEX> target found connected to
C<TARGET_STRING>.
-=item getConnectionBus(C<TARGET_STRING>)
+=item getConnectionBus(C<TARGET_STRING>,C<INDEX>)
Returns the data structure of the C<INDEX> bus target found connected to
C<TARGET_STRING>.
+=item getConnectionBusParent(C<TARGET_STRING>,C<INDEX>)
+
+Returns C<PARENT_TARGET_STRING> of the parent target for the bus target found
+connected to C<TARGET_STRING>
+
=item findEndpoint(C<TARGET_STRING>,C<BUS_TYPE>,C<ENDPOINT_MRW_TYPE>)
Searches through all connections to C<TARGET_STRING>
OpenPOWER on IntegriCloud