summaryrefslogtreecommitdiffstats
path: root/src/build/buildpnor/PnorUtils.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/build/buildpnor/PnorUtils.pm')
-rw-r--r--src/build/buildpnor/PnorUtils.pm134
1 files changed, 109 insertions, 25 deletions
diff --git a/src/build/buildpnor/PnorUtils.pm b/src/build/buildpnor/PnorUtils.pm
index 3a8d22df2..e5ecbb150 100644
--- a/src/build/buildpnor/PnorUtils.pm
+++ b/src/build/buildpnor/PnorUtils.pm
@@ -39,6 +39,7 @@ my $TRAC_ERR = 0;
my $g_trace = 1;
use XML::Simple;
+
################################################################################
# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains
# bugs that result in XML parse errors that can be fixed by adjusting white-
@@ -53,7 +54,8 @@ use constant PAGE_SIZE => 4096;
################################################################################
sub loadPnorLayout
{
- my ($i_pnorFile, $i_pnorLayoutRef, $i_physicalOffsets, $i_testRun) = @_;
+ my ($i_pnorFile, $i_pnorLayoutRef, $i_physicalOffsets, $i_testRun,
+ $i_outputLayoutLocation) = @_;
my $this_func = (caller(0))[3];
unless(-e $i_pnorFile)
@@ -90,6 +92,10 @@ sub loadPnorLayout
my $numOfSides = scalar (@{$metadataEl->{side}});
my $sideSize = ($imageSize)/($numOfSides);
+ my $currOffset = 0;
+ my $sectionNum = 0;
+ my $isStartingPartition = 1;
+
trace(2, " $this_func: metadata: imageSize = $imageSize, blockSize=$blockSize, arrangement = $arrangement, numOfSides: $numOfSides, sideSize: $sideSize, tocSize: $tocSize");
#determine the TOC offsets from the arrangement and side Information
@@ -170,9 +176,44 @@ sub loadPnorLayout
$physicalOffset = getNumber($physicalOffset);
$physicalRegionSize = getNumber($physicalRegionSize);
+ # if at first section, set starting offset
+ if ($isStartingPartition == 1)
+ {
+ $currOffset = $physicalOffset;
+ $isStartingPartition = 0;
+ }
+
+ # if physical offset does not exist, calculate it and create new element
+ my $hexOffset;
+ if ($physicalOffset == 0)
+ {
+ $physicalOffset = $currOffset;
+ $hexOffset = sprintf("0x%X", $physicalOffset);
+ trace(3, "$this_func: Calculated physicalOffset = $physicalOffset, for eyeCatch = $eyeCatch");
+ push @{$xml->{section}->[$sectionNum]->{physicalOffset}}, $hexOffset;
+ $currOffset = $currOffset + $physicalRegionSize;
+ }
+ else
+ {
+ # if sections overlap, throw error
+ if ($physicalOffset < $currOffset)
+ {
+ $hexOffset = sprintf("0x%X", $physicalOffset);
+ die "ERROR: Collision between sections detected at offset ".$hexOffset."";
+ }
+ $currOffset = $physicalOffset + $physicalRegionSize;
+ }
+ $sectionNum = $sectionNum + 1;
+
+ # align partition by minimum boundary
+ if ($currOffset % PAGE_SIZE != 0)
+ {
+ $currOffset = $currOffset + (PAGE_SIZE - $currOffset % PAGE_SIZE);
+ }
+
if($physicalRegionSize + $physicalOffset > $imageSize)
{
- die "ERROR: $this_func: Image size ($imageSize) smaller than $eyeCatch's offset + $eyeCatch's size (".($physicalOffset + $physicalRegionSize)."). Aborting! ";
+ die "ERROR: $this_func: Image size ($imageSize) smaller than ".$eyeCatch."'s offset + ".$eyeCatch."'s size (".($physicalOffset + $physicalRegionSize)."). Aborting! ";
}
if (exists $$i_pnorLayoutRef{sections}{$physicalOffset})
@@ -215,6 +256,42 @@ sub loadPnorLayout
checkForOverlap($i_pnorLayoutRef);
}
+ # Write xml with offsets to new file if $i_outputLayoutLocation
+ # argument is supplied
+ if (defined $i_outputLayoutLocation && $i_outputLayoutLocation ne "")
+ {
+ my $filename = basename($i_pnorFile, ".xml");
+ $filename = "${i_outputLayoutLocation}/${filename}WithOffsets.xml";
+
+ # writing to new file with error handling
+ eval
+ {
+ print XMLout($xml, RootName => "pnor", OutputFile => $filename);
+ 1;
+ }
+ or do
+ {
+ my $err = $@;
+ die "ERROR: $this_func: Failed to create new XML file with corrected offsets, error = $err";
+ };
+
+ # Write out a helper file for our simics scripts
+ print "\nlocation = " . ${i_outputLayoutLocation} . "\n";
+ my $simfilename = "${i_outputLayoutLocation}/simpnor.py";
+ open(SIM_FILE,'>',$simfilename) or die("($simfilename) could not be opened.");
+ print SIM_FILE "def hb_get_pnor_offset(partname):\n";
+ print SIM_FILE " toc_dict={}\n";
+ #Iterate over the <section> elements.
+ foreach my $sectionEl (@{$xml->{section}})
+ {
+ my $eyeCatch = $sectionEl->{eyeCatch}[0];
+ my $physicalOffset = $sectionEl->{physicalOffset}[0];
+ print SIM_FILE " toc_dict[\"$eyeCatch\"]=$physicalOffset\n";
+ }
+ print SIM_FILE " return toc_dict[partname]\n";
+ close SIM_FILE;
+ }
+
return 0;
}
@@ -353,6 +430,8 @@ sub checkSpaceConstraints
my %sectionHash = %{$$i_pnorLayoutRef{sections}};
+ print "Note: the following metrics are not a true representation of section utilization, since some sections are substantially padded before applying ECC\n";
+
for $key ( keys %{$i_binFiles})
{
my $filesize = -s $$i_binFiles{$key};
@@ -366,18 +445,17 @@ sub checkSpaceConstraints
my $eyeCatch = $sectionHash{$layoutKey}{eyeCatch};
my $physicalRegionSize = $sectionHash{$layoutKey}{physicalRegionSize};
- my $pctUtilized = sprintf("%.2f", $filesize / $physicalRegionSize * 100);
my $freeBytes = $physicalRegionSize - $filesize;
- print "$eyeCatch is $pctUtilized% utilized ($freeBytes of $physicalRegionSize bytes free)\n";
+ print "$eyeCatch section size: $physicalRegionSize, bytes used: $filesize, bytes unused: $freeBytes\n";
if($filesize > $physicalRegionSize)
{
# If this is a test run increase HBI size by PAGE_SIZE until all test
# cases fit
- if ($testRun && $eyeCatch eq "HBI")
+ if ( $testRun && ($eyeCatch eq "HBI") )
{
- print "$this_func: Adjusting HBI size - ran out of space for test cases\n";
- adjustHbiPhysSize(\%sectionHash, $layoutKey, $filesize);
+ print "Adjusting HBI size - ran out of space for test cases\n";
+ adjustSecPhysSize(\%sectionHash, $layoutKey, $filesize);
}
else
{
@@ -388,36 +466,43 @@ sub checkSpaceConstraints
trace(1, "Done checkSpaceConstraints");
}
-
-###############################################################################
-# adjustHbiPhysSize - Adjust HBI physical size when running test cases and fix
-# up physical offsets of partitions after it
-################################################################################
-sub adjustHbiPhysSize
+# sub adjustSecPhysSize
+#
+# Adjust section physical size when running test cases and fix up physical
+# offsets between partitions (for example HBI and all partitions that follow)
+#
+# @param [in] i_sectionHashRef - PNOR layout as a hash table reference
+# @param [in] i_initPartKey - key of initial partition whose physical size will
+# be adjusted
+# @param [in] i_filesize - final file size of partition (note: actual final size
+# may be larger than this as the size is adjusted by increments of PAGE_SIZE)
+# @return - N/A
+#
+sub adjustSecPhysSize
{
- my ($i_sectionHashRef, $i_hbiKey, $i_filesize) = @_;
+ my ($i_sectionHashRef, $i_initPartKey, $i_filesize) = @_;
my $this_func = (caller(0))[3];
my %sectionHash = %$i_sectionHashRef;
- # Increment HBI physical size by PAGE_SIZE until the HBI file can fit
- my $hbi_old = $sectionHash{$i_hbiKey}{physicalRegionSize};
- while ($i_filesize > $sectionHash{$i_hbiKey}{physicalRegionSize})
+ # Increment initial partition physical size by PAGE_SIZE until the initial
+ # partition file can fit
+ my $initPart_old = $sectionHash{$i_initPartKey}{physicalRegionSize};
+ while ($i_filesize > $sectionHash{$i_initPartKey}{physicalRegionSize})
{
- $sectionHash{$i_hbiKey}{physicalRegionSize} += PAGE_SIZE;
+ $sectionHash{$i_initPartKey}{physicalRegionSize} += PAGE_SIZE;
}
- my $hbi_move = $sectionHash{$i_hbiKey}{physicalRegionSize} - $hbi_old;
- my $hbi_end = $sectionHash{$i_hbiKey}{physicalRegionSize} + $hbi_move;
+ my $initPart_move = $sectionHash{$i_initPartKey}{physicalRegionSize} - $initPart_old;
- # Fix up physical offset affected by HBI size change
+ # Fix up physical offsets affected by initial partition size change
foreach my $section (keys %sectionHash)
{
- # Only fix partitions after HBI
+ # Only fix partitions after initial partition
if ( $sectionHash{$section}{physicalOffset} >
- $sectionHash{$i_hbiKey}{physicalOffset} )
+ $sectionHash{$i_initPartKey}{physicalOffset} )
{
my $origoffset = $sectionHash{$section}{physicalOffset};
- $sectionHash{$section}{physicalOffset} += $hbi_move;
+ $sectionHash{$section}{physicalOffset} += $initPart_move;
trace(3, "$this_func: Section $sectionHash{$section}{eyeCatch} : " . sprintf("%X",$origoffset) . " --> " . sprintf("%X",$sectionHash{$section}{physicalOffset}));
}
else
@@ -562,7 +647,6 @@ sub checkForOverlap
}
}
-
###############################################################################
# Display Pnor Layout - Display XML pnor layout more simply
################################################################################
OpenPOWER on IntegriCloud