xref: /openbmc/phosphor-mrw-tools/Util.pm (revision 44aecce4)
1package Util;
2
3#Holds common utility functions for MRW processing.
4
5use strict;
6use warnings;
7
8use mrw::Targets;
9
10#Returns the BMC target for a system.
11# param[in] $targetObj = The Targets object
12sub getBMCTarget
13{
14    my ($targetObj) = @_;
15
16    for my $target (keys %{$targetObj->getAllTargets()}) {
17        if ($targetObj->getType($target) eq "BMC") {
18           return $target;
19        }
20    }
21
22    die "Could not find BMC target in the MRW XML\n";
23}
24
25
26#Returns an array of child units based on their Target Type.
27# param[in] $targetObj = The Targets object
28# param[in] $unitTargetType = The target type of the units to find
29# param[in] $chip = The chip target to find the units on
30sub getChildUnitsWithTargetType
31{
32    my ($targetObj, $unitTargetType, $chip) = @_;
33    my @units;
34
35    my @children = $targetObj->getAllTargetChildren($chip);
36
37    for my $child (@children) {
38        if ($targetObj->getTargetType($child) eq $unitTargetType) {
39            push @units, $child;
40        }
41    }
42
43    return @units;
44}
45
46#Returns size of child units based on their Type.
47# param[in] $targetObj = The Targets object
48# param[in] $type = The type of the units to find
49# param[in] $chip = The chip target to find the units on
50sub getSizeOfChildUnitsWithType
51{
52    my ($targetObj, $type, $chip) = @_;
53    my @units;
54    my @children = $targetObj->getAllTargetChildren($chip);
55    for my $child (@children) {
56        if ($targetObj->getType($child) eq $type) {
57            push @units, $child;
58        }
59    }
60    my $size = @units;
61    return $size;
62}
63
64# Returns OBMC name corresponding to a Target name
65# param[in] \@inventory = reference to array of inventory items
66# param[in] $targetName = A Target name
67sub getObmcName
68{
69    my ($inventory_ref, $targetName) = @_;
70    my @inventory = @{ $inventory_ref };
71
72    for my $item (@inventory)
73    {
74        if($item->{TARGET} eq $targetName)
75        {
76            return $item->{OBMC_NAME};
77        }
78    }
79    return undef;
80}
81
82#Returns the array of all the device paths based on the type.
83# param[in] \@inventory = reference to array of inventory items.
84# param[in] $targetObj = The Targets object.
85# param[in] $type = The target type.
86sub getDevicePath
87{
88    my ($inventory_ref, $targetObj, $type) = @_;
89    my @inventory = @{ $inventory_ref };
90    my $fruType = "";
91    my @devices;
92    for my $item (@inventory)
93    {
94        if (!$targetObj->isBadAttribute($item->{TARGET}, "TYPE")) {
95            $fruType = $targetObj->getAttribute($item->{TARGET}, "TYPE");
96            if ($fruType eq $type) {
97                push(@devices,$item->{OBMC_NAME});
98            }
99        }
100    }
101    return @devices;
102}
103
104#Convert the MRW I2C address into the standard 7-bit format
105# $addr = the I2C Address
106sub adjustI2CAddress
107{
108    my $addr = shift;
109
110    #MRW holds the 8 bit value.  We need the 7 bit one.
111    $addr = $addr >> 1;
112    $addr = sprintf("0x%X", $addr);
113    $addr = lc $addr;
114
115    return $addr;
116}
117
118#Return nearest FRU enclosing the input target
119# $targets = the Targets object
120# $targetName = the target name
121sub getEnclosingFru
122{
123    my ($targets, $targetName) = @_;
124
125    if (($targetName eq "") || (!defined $targetName))
126    {
127        return "";
128    }
129
130    if (!$targets->isBadAttribute($targetName, "RU_TYPE"))
131    {
132        my $ruType = $targets->getAttribute($targetName, "RU_TYPE");
133        if (($ruType eq "FRU") || ($ruType eq "CRU"))
134        {
135            return $targetName;
136        }
137    }
138
139    my $parent = $targets->getTargetParent($targetName);
140    return getEnclosingFru($targets, $parent);
141}
142
143#Convert I2C port number from MRW scheme to Linux numbering scheme
144# $port = the I2C port number
145sub adjustI2CPort
146{
147    my $port = shift;
148
149    return $port - 1;
150}
151
152# Get the location code for the target passed in, like P1-C5.
153#  $targets = the targets object
154#  $target = target to get the location code of
155sub getLocationCode
156{
157    my ($targets, $passedInTarget) = @_;
158    my $locCode = undef;
159    my $target = $passedInTarget;
160    my $done = 0;
161
162    # Walk up the parent chain prepending segments until an absolute
163    # location code is found.
164    while (!$done)
165    {
166        if (!$targets->isBadAttribute($target, "LOCATION_CODE"))
167        {
168            my $loc = $targets->getAttribute($target, "LOCATION_CODE");
169            my $type = $targets->getAttribute($target, "LOCATION_CODE_TYPE");
170
171            if (length($loc) > 0 )
172            {
173                if (defined $locCode)
174                {
175                    $locCode = $loc . '-' . $locCode;
176                }
177                else
178                {
179                    $locCode = $loc;
180                }
181
182                if ($type eq "ABSOLUTE")
183                {
184                    $done = 1;
185                }
186            }
187            else
188            {
189                die "Missing location code on $target\n" if $type eq "ABSOLUTE";
190            }
191        }
192
193        if (!$done)
194        {
195            $target = $targets->getTargetParent($target);
196            if (not defined $target)
197            {
198                die "Did not find complete location " .
199                    "code for $passedInTarget\n";
200            }
201        }
202    }
203
204    return $locCode;
205}
206
2071;
208
209=head1 NAME
210
211Util
212
213=head1 DESCRIPTION
214
215Contains utility functions for the MRW parsers.
216
217=head1 METHODS
218
219=over 4
220
221=item getBMCTarget(C<TargetsObj>)
222
223Returns the target string for the BMC chip.  If it can't find one,
224it will die.  Currently supports single BMC systems.
225
226=item getChildUnitsWithTargetType(C<TargetsObj>, C<TargetType>, C<ChipTarget>)
227
228Returns an array of targets that have target-type C<TargetType>
229and are children (any level) of target C<ChipTarget>.
230
231=item getSizeOfChildUnitsWithType(C<TargetsObj>, C<Type>, C<ChipTarget>)
232
233Returns size of targets that have Type C<Type>
234and are children (any level) of target C<ChipTarget>.
235
236=item getObmcName(C<InventoryItems>, C<TargetName>)
237
238Returns an OBMC name corresponding to a Target name. Returns
239undef if the Target name is not found.
240
241=item getDevicePath(C<InventoryItems>, C<TargetsObj>, C<TargetType>)
242
243Returns an array of all device paths (OBMC names)  based on C<TargetType>.
244
245=item adjustI2CAddress(C<I2CAddress>)
246
247Returns C<I2CAddress> converted from MRW format (8-bit) to the standard 7-bit
248format.
249
250=item getEnclosingFru(C<TargetsObj>, C<Target>)
251
252Finds the nearest FRU enclosing the input Target.
253
254=item adjustI2CPort(C<I2CPort>)
255
256Returns C<I2CPort> converted from MRW numbering scheme to Linux numbering scheme.
257
258=item getLocationCode(C<TargetsObj, C<Target>)
259
260Gets the location code for the input Target.
261
262=back
263
264=cut
265