Skip to content

Use ffspart alongside hostboot code to generate PNORs #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 166 additions & 1 deletion create_pnor_image.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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($_);
Expand Down Expand Up @@ -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 <arrangement> 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 <metadata> tags\n", @{$ref->{'metadata'}};
die "There shouldn't be more than one <metadata>\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 {
Expand All @@ -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 {
Expand Down