diff options
Diffstat (limited to 'src/build/buildpnor/PnorUtils.pm')
-rw-r--r-- | src/build/buildpnor/PnorUtils.pm | 134 |
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 ################################################################################ |