Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / util / mergerom.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation; either version 2 of the
8 # License, or any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
19
20 use strict;
21 use warnings;
22
23 use FindBin;
24 use lib "$FindBin::Bin";
25 use Option::ROM qw ( :all );
26
27 sub merge_entry_points {
28   my $baserom_entry = \shift;
29   my $rom_entry = \shift;
30   my $offset = shift;
31
32   if ( $$rom_entry ) {
33     my $old_entry = $$baserom_entry;
34     $$baserom_entry = ( $offset + $$rom_entry );
35     $$rom_entry = $old_entry;
36   }
37 }
38
39 my @romfiles = @ARGV;
40 my @roms = map { my $rom = new Option::ROM; $rom->load($_); $rom } @romfiles;
41
42 my $baserom = shift @roms;
43 my $offset = $baserom->length;
44
45 foreach my $rom ( @roms ) {
46
47   # Merge initialisation entry point
48   merge_entry_points ( $baserom->{init}, $rom->{init}, $offset );
49
50   # Merge BOFM header
51   merge_entry_points ( $baserom->{bofm_header}, $rom->{bofm_header}, $offset );
52
53   # Update PCI header, if present in both
54   my $baserom_pci = $baserom->pci_header;
55   my $rom_pci = $rom->pci_header;
56   if ( $baserom_pci && $rom_pci ) {
57
58     # Update PCI lengths
59     $baserom_pci->{image_length} += $rom_pci->{image_length};
60     if ( exists $baserom_pci->{runtime_length} ) {
61       if ( exists $rom_pci->{runtime_length} ) {
62         $baserom_pci->{runtime_length} += $rom_pci->{runtime_length};
63       } else {
64         $baserom_pci->{runtime_length} += $rom_pci->{image_length};
65       }
66     }
67
68     # Merge CLP entry point
69     if ( exists ( $baserom_pci->{clp_entry} ) &&
70          exists ( $rom_pci->{clp_entry} ) ) {
71       merge_entry_points ( $baserom_pci->{clp_entry}, $rom_pci->{clp_entry},
72                            $offset );
73     }
74   }
75
76   # Update PnP header, if present in both
77   my $baserom_pnp = $baserom->pnp_header;
78   my $rom_pnp = $rom->pnp_header;
79   if ( $baserom_pnp && $rom_pnp ) {
80     merge_entry_points ( $baserom_pnp->{bcv}, $rom_pnp->{bcv}, $offset );
81     merge_entry_points ( $baserom_pnp->{bdv}, $rom_pnp->{bdv}, $offset );
82     merge_entry_points ( $baserom_pnp->{bev}, $rom_pnp->{bev}, $offset );
83   }
84
85   # Update iPXE header, if present
86   my $baserom_ipxe = $baserom->ipxe_header;
87   my $rom_ipxe = $rom->ipxe_header;
88   if ( $baserom_ipxe ) {
89
90     # Update shrunk length
91     $baserom_ipxe->{shrunk_length} = ( $baserom->{length} +
92                                        ( $rom_ipxe ?
93                                          $rom_ipxe->{shrunk_length} :
94                                          $rom->{length} ) );
95
96     # Fix checksum
97     $baserom_ipxe->fix_checksum();
98   }
99
100   # Update base length
101   $baserom->{length} += $rom->{length};
102
103   # Fix checksum for this ROM segment
104   $rom->fix_checksum();
105
106   # Add this ROM to base ROM
107   my $data = substr ( $baserom->get(), 0, $baserom->length() );
108   $data .= $rom->get();
109   $data .= $baserom->next_image()->get() if $baserom->next_image();
110   $baserom->set ( $data );
111
112   $offset += $rom->length;
113 }
114
115 $baserom->pnp_header->fix_checksum() if $baserom->pnp_header;
116 $baserom->fix_checksum();
117 $baserom->save ( "-" );