diff --git a/create_pnor_image.pl b/create_pnor_image.pl index 51ea988..3edd3c3 100755 --- a/create_pnor_image.pl +++ b/create_pnor_image.pl @@ -26,6 +26,21 @@ my $memddata_binary_filename = ""; my $hdat_binary_filename = ""; +my $SEPARATOR = ","; + +sub write_header_csv { + my ($csv, $num, $base, $flags) = @_; + my $S = $SEPARATOR; + printf $csv "\@%d${S}0x%08x${S}%s\n", $num, $base, $flags; +} + +sub write_partition_csv { + my ($csv, $name, $base, $size, $flags, $tocs, $file) = @_; + my $S = $SEPARATOR; + printf $csv "%s${S}0x%08x${S}0x%08x${S}%s${S}%s${S}%s\n", + $name, $base, $size, $flags, $tocs, $file; +} + while (@ARGV > 0){ $_ = $ARGV[0]; chomp($_); @@ -169,27 +184,178 @@ $build_pnor_command .= " --binFile_SECBOOT $scratch_dir/secboot.bin.ecc"; $build_pnor_command .= " --binFile_VERSION $scratch_dir/openpower_pnor_version.bin"; $build_pnor_command .= " --binFile_IMA_CATALOG $scratch_dir/ima_catalog.bin.ecc"; +my %filenames = ( + 'SBE' => "$scratch_dir/$sbe_binary_filename", + 'HBB' => "$scratch_dir/hostboot.header.bin.ecc", + 'HBI' => "$scratch_dir/hostboot_extended.header.bin.ecc", + 'HBRT' => "$scratch_dir/hostboot_runtime.header.bin.ecc", + 'HBEL' => "$scratch_dir/hbel.bin.ecc", + 'GUARD' => "$scratch_dir/guard.bin.ecc", + 'PAYLOAD' => "$payload", + 'BOOTKERNEL' => "$bootkernel", + 'NVRAM' => "$scratch_dir/nvram.bin", + 'MVPD' => "$scratch_dir/mvpd_fill.bin.ecc", + 'DJVPD' => "$scratch_dir/djvpd_fill.bin.ecc", + 'CVPD' => "$scratch_dir/cvpd.bin.ecc", + 'ATTR_TMP' => "$scratch_dir/attr_tmp.bin.ecc", + 'ATTR_PERM' => "$scratch_dir/attr_perm.bin.ecc", + 'OCC' => "$occ_binary_filename.ecc", + 'FIRDATA' => "$scratch_dir/firdata.bin.ecc", + 'CAPP' => "$scratch_dir/cappucode.bin.ecc", + 'SECBOOT' => "$scratch_dir/secboot.bin.ecc", + 'VERSION' => "$openpower_version_filename", + 'IMA_CATALOG' => "$scratch_dir/ima_catalog.bin.ecc" +); + +if ($does_HBD_RW_exist eq 0) { + $filenames{'HBD'} = "$scratch_dir/$targeting_binary_filename"; +} else { + $filenames{'HBD'} = "$scratch_dir/$targeting_RO_binary_filename"; + $filenames{'HBD_RW'} = "$scratch_dir/$targeting_RW_binary_filename"; +} if ($release eq "p9"){ $build_pnor_command .= " --binFile_WOFDATA $wofdata_binary_filename" if -e $wofdata_binary_filename; $build_pnor_command .= " --binFile_MEMD $memddata_binary_filename" if -e $memddata_binary_filename; $build_pnor_command .= " --binFile_HDAT $hdat_binary_filename" if -e $hdat_binary_filename; + #Sigh + $filenames{'WOFDATA'} = "$wofdata_binary_filename" if -e $wofdata_binary_filename; + $filenames{'MEMD'} = "$memddata_binary_filename" if -e $memddata_binary_filename; + $filenames{'HDAT'} = "$hdat_binary_filename" if -e $hdat_binary_filename; } if ($release eq "p8"){ $build_pnor_command .= " --binFile_SBEC $scratch_dir/$sbec_binary_filename"; $build_pnor_command .= " --binFile_WINK $scratch_dir/$wink_binary_filename"; + $filenames{'SBEC'} = "$scratch_dir/$sbec_binary_filename"; + $filenames{'WINK'} = "$scratch_dir/$wink_binary_filename"; } else { $build_pnor_command .= " --binFile_SBKT $scratch_dir/SBKT.bin"; $build_pnor_command .= " --binFile_HCODE $scratch_dir/$wink_binary_filename"; $build_pnor_command .= " --binFile_HBBL $scratch_dir/hbbl.bin.ecc"; $build_pnor_command .= " --binFile_RINGOVD $scratch_dir/ringOvd.bin"; $build_pnor_command .= " --binFile_HB_VOLATILE $scratch_dir/guard.bin.ecc"; + $filenames{'SBKT'} = "$scratch_dir/SBKT.bin"; + $filenames{'HCODE'} = "$scratch_dir/$wink_binary_filename"; + $filenames{'HBBL'} = "$scratch_dir/hbbl.bin.ecc"; + $filenames{'RINGOVD'} = "$scratch_dir/ringOvd.bin"; + $filenames{'HB_VOLATILE'} = "$scratch_dir/guard.bin.ecc"; } $build_pnor_command .= " --fpartCmd \"fpart\""; $build_pnor_command .= " --fcpCmd \"fcp\""; print "###############################"; run_command("$build_pnor_command"); +#Generate the CSV +my $ref = XMLin("$xml_layout_file", ForceArray => ['metadata', 'section'], SuppressEmpty => undef); +my $csv; +open($csv, ">", "$scratch_dir/pnor_layout.csv") or die "Can't open > $scratch_dir/pnor_layout.csv $!"; + +if (${$ref->{'metadata'}}[0]->{'arrangement'} ne "A-D-B") { + printf STDERR "Found '%s' expecting 'A-D-B'\n", + ${$ref->{'metadata'}}[0]->{'arrangement'}; + die "Unexpected tag"; +} + +my $image_size = hex (${$ref->{'metadata'}}[0]->{'imageSize'}); +my $block_size = hex (${$ref->{'metadata'}}[0]->{'blockSize'}); +my $block_count = $image_size / $block_size; +my $toc_size = hex (${$ref->{'metadata'}}[0]->{'tocSize'}); +my $side_string = "0"; +my $side_count = keys(%{${$ref->{'metadata'}}[0]->{'side'}}); + +#Please don't ask me why +my $part_offset = 0; +if ($release eq "p9") { + $part_offset = $block_size; +} + +if (@{$ref->{'metadata'}} == 1) { + if ($side_count == 1) { + write_header_csv $csv, 0, 0, ""; + write_header_csv $csv, 1, $image_size - $toc_size - $part_offset, ""; + $side_string = "01"; + } elsif ($side_count == 2) { + write_header_csv $csv, 0, 0, ""; + write_header_csv $csv, 1, ($image_size / 2) - $toc_size - $part_offset, ""; + write_header_csv $csv, 2, ($image_size / 2), "G"; + write_header_csv $csv, 3, $image_size - $toc_size - $part_offset, "G"; + $side_string = "0123"; + } else { + printf STDERR "Sides not 1 or 2, total: %d\n", $side_count; + die "Unexpected number of sides\n"; + } +} else { + printf STDERR "Found %d tags\n", @{$ref->{'metadata'}}; + die "There shouldn't be more than one \n"; +} + +foreach my $section (@{$ref->{'section'}}) { + my $name = $section->{'eyeCatch'}; + my $base = hex($section->{'physicalOffset'}); + my $size = hex($section->{'physicalRegionSize'}); + my $flags = ""; + $flags .= 'E' if (exists($section->{'ecc'})); + $flags .= 'L' if (exists($section->{'sha512Version'})); + $flags .= 'F' if (exists($section->{'reprovision'})); + $flags .= 'I' if (exists($section->{'sha512perEC'})); + $flags .= 'P' if (exists($section->{'preserved'})); + $flags .= 'R' if (exists($section->{'readOnly'})); + $flags .= 'C' if (exists($section->{'clearOnEccErr'})); + $flags .= 'V' if (exists($section->{'volatile'})); + my $side = ""; + if (exists($section->{'side'}) and $section->{'side'} ne "sideless") { + $side = "01" if ($section->{'side'} eq "A"); + $side = "23" if ($section->{'side'} eq "B"); + } else { + $side = $side_string; #Either "sideless" or no sides at all so all 0 is good + } + my $file = "/dev/zero"; + if (exists($filenames{$section->{'eyeCatch'}})) { + $file = "$filenames{$section->{'eyeCatch'}}"; + } else { + print STDERR "# Assuming partition $section->{'eyeCatch'} is blank\n"; + } + write_partition_csv $csv, $name, $base, $size, $flags, $side, $file; +} + +#BACKUP_PART should exist in the TOC before OTHER_SIDE. ffspart will +#respect the order of the CSV + +#Add the other side and backup part partitions +if ($side_count == 2) { + write_partition_csv $csv, "BACKUP_PART", + ($image_size / 2) - $toc_size - $part_offset, $toc_size, "B", 0, "/dev/zero"; + write_partition_csv $csv, "BACKUP_PART", + $image_size - $toc_size - $part_offset, $toc_size, "B", 2, "/dev/zero"; + + #BACKUP_PART for OTHER_SIDEs + write_partition_csv $csv, "BACKUP_PART", 0, $toc_size, "B", 1, "/dev/zero"; + write_partition_csv $csv, "BACKUP_PART", $image_size / 2, $toc_size, + "B", 3, "/dev/zero"; + + write_partition_csv $csv, "OTHER_SIDE", $image_size / 2, $toc_size, + "B", 0, "/dev/zero"; + write_partition_csv $csv, "OTHER_SIDE", 0, $toc_size, "B", 2, "/dev/zero"; + + #OTHER_SIDEs for BACKUP_PARTs + write_partition_csv $csv, "OTHER_SIDE", $image_size - $toc_size - $part_offset, + $toc_size, "B", 1, "/dev/zero"; + write_partition_csv $csv, "OTHER_SIDE", + ($image_size / 2) - $toc_size - $part_offset, + $toc_size, "B", 3, "/dev/zero"; +} else { + #Don't forget those pesky backup parts for the regular TOC + write_partition_csv $csv, "BACKUP_PART", + $image_size - $toc_size - $part_offset, $toc_size, + "B", 0, "/dev/zero"; + write_partition_csv $csv, "BACKUP_PART", 0, $toc_size, "B", 1, "/dev/zero"; +} + + +#ffspart should really learn to make its own output file +run_command("touch $outdir/ffspart.pnor"); +run_command("ffspart -e -s $block_size -c $block_count -i $scratch_dir/pnor_layout.csv -p $outdir/ffspart.pnor"); + #END MAIN #------------------------------------------------------------------------- sub usage { @@ -208,7 +374,6 @@ sub parse_config_file { } - #trim_string takes one string as input, trims leading and trailing whitespace # before returning that string sub trim_string {