diff options
Diffstat (limited to 'src/build')
-rwxr-xr-x | src/build/buildpnor/buildSbePart.pl | 348 | ||||
-rw-r--r-- | src/build/mkrules/dist.targets.mk | 1 | ||||
-rwxr-xr-x | src/build/mkrules/hbfw/img/makefile | 72 |
3 files changed, 416 insertions, 5 deletions
diff --git a/src/build/buildpnor/buildSbePart.pl b/src/build/buildpnor/buildSbePart.pl new file mode 100755 index 000000000..11269bcfe --- /dev/null +++ b/src/build/buildpnor/buildSbePart.pl @@ -0,0 +1,348 @@ +#!/usr/bin/perl +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/buildpnor/buildSbePart.pl $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2013 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG + +#Builds an SBE partition for PNOR based on user-provided SBE images +#It works for both Processor SBE-IPL images and Centaur SBE images + +use strict; +use File::Basename; +use File::Temp qw/ tempfile tempdir /; + +my $TRAC_ERR = 0; +# 0=errors, >0 for more traces, leaving at 1 to keep key milestone traces. +my $g_trace = 1; + +my $progName = File::Basename::basename $0; +my $outBin = ""; +my %ecImgs; +my $injectVerHdrs = undef; +my $tocVersion = 1; #Only version 1 currently defined + +if ($#ARGV < 0) { + usage(); + exit; +} + + +#Parse the commandline args +for (my $i=0; $i < $#ARGV + 1; $i++) +{ + if ($ARGV[$i] =~ /-h/) { + usage(); + exit 0; + } + elsif($ARGV[$i] =~ /--injectVersionHeaders/) { + $injectVerHdrs = 1; + trace(2, "injectVersionHeaders flag specified"); + } + elsif($ARGV[$i] =~ /--sbeOutBin/) { + $outBin = $ARGV[++$i]; + trace(2, "SBE output Binary File=$outBin"); + } + elsif($ARGV[$i] =~ /--ecImg/) { + my $argName = $ARGV[$i]; + my $argVal = $ARGV[++$i]; + saveInputFile("--ecImg", $argName, $argVal, \%ecImgs); + } + else { + traceErr("Unrecognized Input: $ARGV[$i]"); + exit 1; + } +} + + +#Verify all the SBE images exist +my $rc = verifyFilesExist(\%ecImgs); +if($rc != 0) +{ + trace(0, "$progName: Error detected from call to verifyFilesExist(). Exiting"); + exit 1; +} + +#Generate the output image +my $rc = genOutputImage($injectVerHdrs, $tocVersion, $outBin, \%ecImgs); +if($rc != 0) +{ + trace(0, "$progName: Error detected from call to genOutputImage(). Exiting"); + exit 1; +} + + +################################################################################ +# saveInputFile - save inputfile name into ecImgss array +################################################################################ +sub saveInputFile +{ + my ($i_argPrefix, $i_argName, $i_argVal, $i_ecImgs) = @_; + my $this_func = (caller(0))[3]; + + #$i_argName will be something like --ecIMG_10 + #This substr command should return just the 10, which is the image EC Level + my $ecLevel = substr($i_argName, + length($i_argPrefix)+1, + length($i_argName)-length($i_argPrefix)); + + trace(10, "$this_func: $ecLevel=$i_argVal"); + + $$i_ecImgs{$ecLevel} = $i_argVal; + + trace(10, "$this_func: $$i_ecImgs{$ecLevel}"); + + #no return code expected +} + +################################################################################ +# verifyFilesExist - Verify all the input files exist +################################################################################ +sub verifyFilesExist +{ + my ($i_ecImgs) = @_; + my $this_func = (caller(0))[3]; + my $key; + my $rc = 0; + + for $key ( keys %$i_ecImgs) + { + unless(-e $$i_ecImgs{$key}) + { + my $inputFile = $$i_ecImgs{$key}; + trace(0, "$this_func: Specified input file ($inputFile) for key ($key) does not exist. Aborting!"); + $rc = 1; + last; + } + else + { + trace(10, "$this_func: $$i_ecImgs{$key} exists"); + } + } + + return $rc; +} + +################################################################################ +# genOutputImage - Generate output image +# -Build SBE TOC in first 128 bytes +# -Insert 4K header in front of each image with SHA512 as version +# -Insert each SBE image after corresponding header +################################################################################ +#Output image layout (Defined in Hostboot SBE Layout document) +#word 0: 'SBE\0' eyecatcher +#word 1: SBE TOC Layout version - currently only 1 is defined +#word 2: SBE image EC +#word 3: Sbe image offset in partition +#word 4: SBE image size +#Repeat words 2-4 for each supported EC + +#Actual SBE Images start at offset 0x1000 and must always be on a 4k boundary. +################################################################################ +sub genOutputImage +{ + my ($i_injectVerHdrs, $i_tocVersion, $i_outBin, $i_ecImgs) = @_; + my $this_func = (caller(0))[3]; + my $key; + my %ecOffsets; + my $rc = 0; + my $FILEHANDLE; + my $curOffset = 0x1000; #first offset is at 4k + trace(4, "$this_func: >>Enter"); + +#open output file + open( $FILEHANDLE, ">:raw", $i_outBin) + or die "Can't open $i_outBin file for writing"; + + #Build the TOC + #WORD 0: EyeCatcher - "SBE\0" in ASCII + my @charArray = split //, 'SBE'; + my $curChar; + foreach $curChar (@charArray) + { + print $FILEHANDLE pack('C', ord($curChar)); + } + + #Pad byte for null character after SBE + insertPadBytes($FILEHANDLE, 1); + + #WORD 1: Version = 0x00000001 + print $FILEHANDLE pack('N', 1); + + #Insert header data for each EC provided + for $key ( keys %{$i_ecImgs}) + { + trace(2, "$this_func: Inserting header for EC=$key"); + my $filesize = -s $$i_ecImgs{$key}; + + if($i_injectVerHdrs) + { + $filesize += 0x1000; + } + + #EC Word + print $FILEHANDLE pack('N', hex($key)); + + #Offset Word + print $FILEHANDLE pack('N', $curOffset); + + #Size Word + print $FILEHANDLE pack('N', $filesize); + + #safe offset for inserting images + $ecOffsets{$key} = $curOffset; + + #generate next to 4k offset + $curOffset += $filesize; + if (($curOffset & 0x00000FFF) != 0) + { + $curOffset = $curOffset & 0xFFFFF000; + $curOffset += 0x1000; + } + } + + close $FILEHANDLE; + + #Insert actual image for each EC provided + for $key ( keys %{$i_ecImgs}) + { + trace(2, "$this_func: Inserting data for EC=$key, offset=$ecOffsets{$key}"); + + my $seekOffset = $ecOffsets{$key}; + my $inFile = $$i_ecImgs{$key}; + + #Image is prefixed with 4k header containing version + if($i_injectVerHdrs) + { + my $headerOffset = $seekOffset; + $seekOffset += 0x1000; + + my $headerFh; + my $headerFile; + ($headerFh, $headerFile) = tempfile(UNLINK => 1); + #Disable file handle buffering + + trace(0, "$this_func: headerFile=$headerFile"); + + + #Insert 'VERSION\0' Eyecatcher + my @eyeCatchArray = split //, 'VERSION'; + foreach $curChar (@eyeCatchArray) + { + print $headerFh pack('C', ord($curChar)); + } + #Pad byte for null character after VERSION + insertPadBytes($headerFh, 1); + + #make sure date written to file handle is flushed to disk + close $headerFh; + + #Create the SHA512 hash + my $cmd = "sha512sum $inFile \| awk \'\{print $1\}\' \| xxd -ps -r \>> $headerFile"; + system( $cmd ) == 0 or die "Creating $headerFile failed!"; + + #Write to output file + my $hdrdd = "dd if=$headerFile of=$i_outBin bs=1 seek=$headerOffset"; + system ( $hdrdd ) == 0 or die "Couldn't Write $headerFile to $i_outBin!"; + } + my $ddCmd = "dd if=$inFile of=$i_outBin bs=1 seek=$seekOffset"; + system ( $ddCmd ) == 0 or die "Couldn't Write $inFile to $i_outBin!"; + + } + + trace(4, "$this_func: <<Exit"); + + return $rc; +} + +################################################# +# Insert specifed number of pad bytes into file +# +################################################# +sub insertPadBytes +{ + my ($i_FILEHANDLE, $i_padBytes) = @_; + my $i; + print $i_FILEHANDLE pack("C[$i_padBytes]", map { 0 } 1..$i_padBytes); + +} + + + +################################################################################ +# trace +################################################################################ +sub traceErr +{ + my $i_string = shift; + trace($TRAC_ERR, $i_string); +} + +################################################################################ +# trace +################################################################################ +sub trace +{ + my $i_traceLevel; + my $i_string; + + ($i_traceLevel, $i_string) = @_; + + #traceLevel 0 is for errors + if($i_traceLevel == 0) + { + print "ERROR: ".$i_string."\n"; + } + elsif ($g_trace >= $i_traceLevel) + { + print "TRACE: ".$i_string."\n"; + } +} + + + +################################################################################ +# print usage instructions +################################################################################ +sub usage +{ +print <<"ENDUSAGE"; + $progName = Creates SBE partition with SBE TOC based on input data. + + Usage: + $progName --sbeOutBin <complete SBE Partition image> + [--ecImg_10 <EC 10 SBE image>] [--ecImg_20 <EC_20_SBE_image>] + [--injectVersionHeaders] + + Parms: + -h Print this help text + --sbeOutBin <file> Name of output file for PNOR Binary + --ecImg_<EC> <file> This is a special paramater. It is used to specify + input files to use for populating the partition with + supported SBE EC specific images + Examples: --binFile_10 s1_10.sbe_seeprom.bin + --binFile_13 s1_13.sbe_seeprom.bin + --binFile_20 s1_20.sbe_seeprom.bin + --injectVersionHeaders Injects a 4k header at the top of each image + containing a SHA512 Hash computed over the image. + + +ENDUSAGE +} diff --git a/src/build/mkrules/dist.targets.mk b/src/build/mkrules/dist.targets.mk index 44405b6a2..a17e95c0c 100644 --- a/src/build/mkrules/dist.targets.mk +++ b/src/build/mkrules/dist.targets.mk @@ -169,6 +169,7 @@ simics.tar_CONTENTS = \ fsp.tar_CONTENTS = \ obj/genfiles/hwp_id.html \ src/build/mkrules/hbfw/fsp/makefile \ + src/build/buildpnor/buildSbePart.pl \ src/build/buildpnor/buildpnor.pl \ src/build/buildpnor/defaultPnorLayout.xml \ img/simics_MURANO_targeting.bin \ diff --git a/src/build/mkrules/hbfw/img/makefile b/src/build/mkrules/hbfw/img/makefile index 94647f827..4e6aa8179 100755 --- a/src/build/mkrules/hbfw/img/makefile +++ b/src/build/mkrules/hbfw/img/makefile @@ -36,8 +36,13 @@ VPATH += ../fsp DEFAULT_PATH = ${.PATH} SRCPATH = ${DEFAULT_PATH:M*src*} -build_all: cp_hbfiles -install_all: build_pnor_images +build_all: cp_hbfiles +install_all: build_sbe_partitions build_pnor_images + +#Some useful search paths +HBFW_OBJPATH = ${.PATH:M*obj*} +ENGD_OBJPATH = ${HBFW_OBJPATH:S/hbfw\/img/engd\/href/g} + ################################################# # Copy Hostboot binary images to obj dir to be grabbed @@ -96,6 +101,57 @@ clobber_cp_hbfiles: rm -f ${ALL_HB_IMAGES} \ sbe.header secureboot.header hb.footer hostboot.stage.bin +################################################# +### SAMPLE for building an SBE Partition with multiple ECs +################################################# +#S1_EC10_BIN = ${ENGD_OBJPATH:Fs1_10.sbe_seeprom.bin} +#s1SbePartition.bin: ${SBE_BUILD_SCRIPT} ${S1_EC10_BIN} +# ${buildSbePart.pl:P} --sbeOutBin s1SbePartition.bin \ +# --ecImg_10 ${S1_EC10_BIN} +################################################# +SBE_BUILD_SCRIPT = ${buildSbePart.pl:P} + +S1_EC10_BIN = ${ENGD_OBJPATH:Fs1_10.sbe_seeprom.hdr.bin} +S1_EC12_BIN = ${ENGD_OBJPATH:Fs1_12.sbe_seeprom.hdr.bin} +S1_EC13_BIN = ${ENGD_OBJPATH:Fs1_13.sbe_seeprom.hdr.bin} +S1_EC20_BIN = ${ENGD_OBJPATH:Fs1_20.sbe_seeprom.hdr.bin} +P8_EC10_BIN = ${ENGD_OBJPATH:Fp8_10.sbe_seeprom.hdr.bin} +CENT_EC10_BIN = ${ENGD_OBJPATH:Fcentaur_10.sbe_seeprom.hdr.bin} +CENT_EC20_BIN = ${ENGD_OBJPATH:Fcentaur_20.sbe_seeprom.hdr.bin} + +SBE_PART_INFO = \ + s1SbePartition.bin:10=${S1_EC10_BIN},12=${S1_EC12_BIN},13=${S1_EC13_BIN},20=${S1_EC20_BIN} \ + p8SbePartition.bin:10=${P8_EC10_BIN} \ + centSbePartition.bin:10=${CENT_EC10_BIN},20=${CENT_EC20_BIN} + + +__SBE_PART_BUILD/% : .SPECTARG .PMAKE + @${MAKE:T:R} BUILD_SPECIFIC_SBEPART \ + "SBE_PART_PARAMS=${.TARGET:s/__SBE_PART_BUILD\///:s/:/ /g}" + +.ifdef SBE_PART_PARAMS + +SBEPART_TARGET = ${SBE_PART_PARAMS:xs/ .*//} +SBEPART_SECTIONS = ${SBE_PART_PARAMS:xs/[^ ]* //:xs/ .*//} +SBEPART_BINS = ${SBEPART_SECTIONS:s/,/ /g:xS/[^=]*=//g} +SBEPART_BIN_OPTION = ${SBEPART_SECTIONS:s/,/ /g:S/^/--ecImg_/g:s/=/ /g:p} + +BUILD_SPECIFIC_SBEPART: .SPECTARG ${SBEPART_TARGET} + #@echo TARGET ${SBEPART_TARGET} + #@echo LAYOUT ${SBEPART_LAYOUT} + #@echo BINARIES ${SBEPART_BINS} + #@echo BIN_OPTION ${SBEPART_BIN_OPTION} + +${SBEPART_TARGET}: ${SBEPART_LAYOUT} ${SBEPART_BINS} ${PNOR_BUILD_SCRIPT} + ${SBE_BUILD_SCRIPT} --sbeOutBin ${SBEPART_TARGET} \ + ${SBEPART_BIN_OPTION} + +.endif + +build_sbe_partitions: .SPECTARG ${SBE_PART_INFO:S/^/__SBE_PART_BUILD\//g} + +clobber_build_sbe_partitions: + ${SBE_PART_INFO:@image@${pnorimg:!rm -f ${image:s/:/ /g:xs/ .*//};!e}@} ################################################# ### SAMPLE for building a PNOR image @@ -123,10 +179,16 @@ HOSTBOOT_DEFAULT_SECTIONS = HBB=${BASE_W_HEADER_ECC_IMAGE},HBI=${EXT_HEADER_IMAG HBFW_OBJPATH = ${.PATH:M*obj*} ENGD_OBJPATH = ${HBFW_OBJPATH:S/hbfw\/img/engd\/href/g} +MURANO_TARG_IMG = simics_MURANO_targeting.bin +VENICE_TARG_IMG = simics_VENICE_targeting.bin MURANO_SLW_IMG = ${ENGD_OBJPATH:Fs1.ref_image.bin} VENICE_SLW_IMG = ${ENGD_OBJPATH:Fp8.ref_image.bin} -MURANO_SECT = HBD=simics_MURANO_targeting.bin,WINK=${MURANO_SLW_IMG} -VENICE_SECT = HBD=simics_VENICE_targeting.bin,WINK=${VENICE_SLW_IMG} +MURANO_SBE_IMG = s1SbePartition.bin +VENICE_SBE_IMG = p8SbePartition.bin +SBEC_IMG = centSbePartition.bin +MURANO_SECT = HBD=${MURANO_TARG_IMG},SBE=${MURANO_SBE_IMG},SBEC=${SBEC_IMG},WINK=${MURANO_SLW_IMG} +VENICE_SECT = HBD=${VENICE_TARG_IMG},SBE=${VENICE_SBE_IMG},SBEC=${SBEC_IMG},WINK=${VENICE_SLW_IMG} + PNOR_IMG_INFO = \ murano.pnor:defaultPnorLayout.xml:${MURANO_SECT},${HOSTBOOT_DEFAULT_SECTIONS} \ @@ -180,7 +242,7 @@ clobber_build_pnor_images: FLASH_DEST = $(MAKETOP)$(OBJECTDIRTOP)../images/$(CONTEXT)/lab/flash FLASH_IMG = ${BASE_IMAGE} ${BASE_ECC_IMAGE} -update_images_for_sandbox: build_pnor_images +update_images_for_sandbox: build_sbe_partitions build_pnor_images mkdir -p ${FLASH_DEST} #Copy hostboot base image to flash dir ${FLASH_IMG:@image@${baseimg:!cd ${FLASH_DEST}; cp -f ${.PATH:F${image}} ${image};!e}@} |