+;\r
+; Copyright (c) 2011, Hewlett-Packard Company. All rights reserved.<BR>\r
+; \r
+; This program and the accompanying materials \r
+; are licensed and made available under the terms and conditions of the BSD License \r
+; which accompanies this distribution. The full text of the license may be found at \r
+; http://opensource.org/licenses/bsd-license.php \r
+; \r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+; \r
+\r
+ LOCAL &fvbase &fvsig &fvsig &ffsoffset &ffsfilesize &ffsfileaddr\r
+ ENTRY &fvbase\r
+\r
+ &fvsig=Data.Long(a:&fvbase+0x28)\r
+ if &fvsig!=0x4856465F\r
+ (\r
+ print "FV does not have proper signature, exiting"\r
+ return\r
+ )\r
+ \r
+ print "FV signature found"\r
+ \r
+ &fvlen=Data.Long(a:&fvbase+0x20)\r
+ \r
+ ; first ffs file is after fv header, use headerlength field\r
+ &ffsoffset=(Data.Long(a:&fvbase+0x30)&0xffff)\r
+ \r
+ ; loop through ffs files\r
+ &ffsfilesize=1\r
+ while (&ffsfilesize!=0)&&(&ffsoffset<(&fvlen))\r
+ (\r
+ &ffsfileaddr=&fvbase+&ffsoffset\r
+ ;print "found ffs file at &ffsfileaddr"\r
+ \r
+ ; process ffs file and increment by ffs file size field\r
+ gosub ProcessFfsFile &ffsfileaddr\r
+ \r
+ &ffsfilesize=(Data.Long(a:&ffsfileaddr+0x14)&0x00ffffff)\r
+ ;print "ffsfilesize is &ffsfilesize"\r
+ \r
+ &ffsoffset=&ffsoffset+&ffsfilesize\r
+\r
+ &ffsfilesize=(Data.Long(a:&fvbase+&ffsoffset+0x14)&0x00ffffff)\r
+ ;print "ffsfilesize now is &ffsfilesize"\r
+ if &ffsfilesize==0xffffff\r
+ (\r
+ enddo\r
+ )\r
+ \r
+ ; align to next 8 byte boundary\r
+ if (&ffsoffset&0x7)!=0\r
+ (\r
+ &ffsoffset=&ffsoffset+(0x8-(&ffsoffset&0x7))\r
+ )\r
+ \r
+ ) ; end fv ffs loop\r
+\r
+enddo\r
+\r
+ProcessFfsFile:\r
+ LOCAL &ffsfilestart &ffsfilesize &ffsfiletype &secoffset &secsize\r
+ ENTRY &ffsfilestart\r
+\r
+ ;print "processing ffs file at &ffsfilestart"\r
+ &ffsfilesize=Data.Long(a:&ffsfilestart+0x14)\r
+ &ffsfiletype=(&ffsfilesize&0xff000000)>>24.\r
+ &ffsfilesize=&ffsfilesize&0x00ffffff\r
+\r
+ if &ffsfiletype==0\r
+ (\r
+ return\r
+ )\r
+\r
+ print "ffs file at &ffsfilestart size &ffsfilesize type &ffsfiletype"\r
+\r
+ &secoffset=&ffsfilestart+0x18\r
+ \r
+ ; loop through sections in file\r
+ while &secoffset<(&ffsfilestart+&ffsfilesize)\r
+ (\r
+ print "secoffset at &secoffset"\r
+ \r
+ ; process fv section and increment section offset by size\r
+ &secsize=(Data.Long(a:&secoffset)&0x00ffffff)\r
+ \r
+ gosub ProcessFvSection &secoffset\r
+ \r
+ \r
+ &secoffset=(&secoffset+&secsize)\r
+\r
+ ;print "secsize is &secsize"\r
+ ;print "secoffset at &secoffset"\r
+ \r
+ ; align to next 4 byte boundary\r
+ if (&secoffset&0x3)!=0\r
+ (\r
+ &secoffset=&secoffset+(0x4-(&secoffset&0x3))\r
+ )\r
+ ) ; end section loop\r
+ return\r
+ \r
+ \r
+ProcessFvSection:\r
+ LOCAL &secstart §ionsize §iontype &secoffset &secsize\r
+ ENTRY &secstart\r
+\r
+ §ionsize=Data.Long(a:&secstart)\r
+ §iontype=((§ionsize&0xff000000)>>24.)\r
+ §ionsize=§ionsize&0x00ffffff;\r
+\r
+ print "fv section at &secstart size §ionsize type §iontype"\r
+\r
+ if §iontype==0x10 ; PE32\r
+ (\r
+ do EfiProcessPeImage (&secstart+0x4)\r
+ )\r
+ else\r
+ (\r
+ if §iontype==0x12 ; TE\r
+ (\r
+ do EfiProcessTeImage (&secstart+0x4)\r
+ )\r
+ else\r
+ (\r
+ print "unknown section type"\r
+ )\r
+ )\r
+ \r
+ return\r