diff options
Diffstat (limited to 'src/usr/targeting/common/Targets.pm')
-rw-r--r-- | src/usr/targeting/common/Targets.pm | 688 |
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> |