Browse Source

[romprefix] Add .mrom format, allowing loading of large ROMs

Add an infrastructure allowing the prefix to provide an open_payload()
method for obtaining out-of-band access to the whole iPXE image.  Add
a mechanism within this infrastructure that allows raw access to the
expansion ROM BAR by temporarily borrowing an address from a suitable
memory BAR on the same PCI card.

For cards that have a memory BAR that is at least as large as their
expansion ROM BAR, this allows large iPXE ROMs to be supported even on
systems where PMM fails, or where option ROM space pressure makes it
impossible to use PMM shrinking.  The BIOS sees only a stub ROM of
approximately 3kB in size; the remainder (which can be well over 64kB)
is loaded only at the time iPXE is invoked.

As a nice side-effect, an iPXE .mrom image will continue to work even
if its PMM-allocated areas are overwritten between initialisation and
invocation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
132c391712

+ 3
- 0
src/arch/i386/Makefile.pcbios View File

@@ -11,6 +11,7 @@ LDFLAGS		+= -N --no-check-sections
11 11
 # Media types.
12 12
 #
13 13
 MEDIA		+= rom
14
+MEDIA		+= mrom
14 15
 MEDIA		+= pxe
15 16
 MEDIA		+= kpxe
16 17
 MEDIA		+= kkpxe
@@ -23,12 +24,14 @@ MEDIA		+= raw
23 24
 # Padding rules
24 25
 #
25 26
 PAD_rom		= $(PADIMG) --blksize=512 --byte=0xff $@
27
+PAD_mrom	= $(PAD_rom)
26 28
 PAD_dsk		= $(PADIMG) --blksize=512 $@
27 29
 PAD_hd		= $(PADIMG) --blksize=32768 $@
28 30
 
29 31
 # Finalisation rules
30 32
 #
31 33
 FINALISE_rom	= $(FIXROM) $@
34
+FINALISE_mrom	= $(FINALISE_rom)
32 35
 
33 36
 # rule to make a non-emulation ISO boot image
34 37
 NON_AUTO_MEDIA	+= iso

+ 48
- 3
src/arch/i386/prefix/libprefix.S View File

@@ -479,6 +479,10 @@ install_prealloc:
479 479
 	cld			/* Sanity: clear the direction flag asap */
480 480
 	pushfw
481 481
 
482
+	/* Set up %ds for (read-only) access to .prefix */
483
+	pushw	%cs
484
+	popw	%ds
485
+
482 486
 	/* Copy decompression temporary area physical address to %ebp */
483 487
 	movl	%edi, %ebp
484 488
 
@@ -495,7 +499,6 @@ install_prealloc:
495 499
 	call	install_block		/* .text16.early */
496 500
 	popl	%esi
497 501
 
498
-	/* Open up access to payload */
499 502
 #ifndef KEEP_IT_REAL
500 503
 	/* Access high memory */
501 504
 	pushw	%cs
@@ -511,18 +514,39 @@ install_prealloc:
511 514
 2:	jmp	2b
512 515
 	.section ".prefix.data", "aw", @progbits
513 516
 a20_death_message:
514
-	.asciz	"Gate A20 stuck - cannot continue\n"
517
+	.asciz	"\nHigh memory inaccessible - cannot continue\n"
515 518
 	.size	a20_death_message, . - a20_death_message
516 519
 	.previous
517 520
 3:
518 521
 #endif
519 522
 
523
+	/* Open payload (which may not yet be in memory) */
524
+	pushw	%cs
525
+	pushw	$1f
526
+	pushw	%ax
527
+	pushw	$open_payload
528
+	lret
529
+1:	/* Die if we could not access the payload */
530
+	jnc	3f
531
+	xorw	%di, %di
532
+	movl	%esi, %eax
533
+	call	print_hex_dword
534
+	movw	$payload_death_message, %si
535
+	call	print_message
536
+2:	jmp	2b
537
+	.section ".prefix.data", "aw", @progbits
538
+payload_death_message:
539
+	.asciz	"\nPayload inaccessible - cannot continue\n"
540
+	.size	payload_death_message, . - payload_death_message
541
+	.previous
542
+3:
543
+
520 544
 	/* Calculate physical address of payload (i.e. first source) */
521 545
 	testl	%esi, %esi
522 546
 	jnz	1f
523 547
 	movw	%cs, %si
524 548
 	shll	$4, %esi
525
-1:	addl	%cs:payload_lma, %esi
549
+1:	addl	payload_lma, %esi
526 550
 
527 551
 	/* Install .text16.late and .data16 */
528 552
 	movl	$_text16_late_filesz, %ecx
@@ -588,9 +612,11 @@ a20_death_message:
588 612
 
589 613
 	/* Copy code to new location */
590 614
 	pushl	%edi
615
+	pushw	%ax
591 616
 	xorw	%ax, %ax
592 617
 	movw	%ax, %es
593 618
 	es rep addr32 movsb
619
+	popw	%ax
594 620
 	popl	%edi
595 621
 
596 622
 	/* Initialise librm at new location */
@@ -598,6 +624,10 @@ a20_death_message:
598 624
 skip_relocate:
599 625
 #endif
600 626
 
627
+	/* Close access to payload */
628
+	movw	%ax, (close_payload_vector+2)
629
+	lcall	*close_payload_vector
630
+
601 631
 	/* Restore registers */
602 632
 	popfw
603 633
 	popw	%es
@@ -625,6 +655,10 @@ prot_call_vector:
625 655
 	.word 0
626 656
 	.size prot_call_vector, . - prot_call_vector
627 657
 #endif
658
+close_payload_vector:
659
+	.word close_payload
660
+	.word 0
661
+	.size close_payload_vector, . - close_payload_vector
628 662
 
629 663
 	/* Payload address */
630 664
 	.section ".prefix.lib", "awx", @progbits
@@ -637,6 +671,17 @@ payload_lma:
637 671
 	.long	0
638 672
 	.previous
639 673
 
674
+	/* Dummy routines to open and close payload */
675
+	.section ".text16.early.data", "aw", @progbits
676
+	.weak	open_payload
677
+	.weak	close_payload
678
+open_payload:
679
+close_payload:
680
+	clc
681
+	lret
682
+	.size	open_payload, . - open_payload
683
+	.size	close_payload, . - close_payload
684
+
640 685
 /****************************************************************************
641 686
  * uninstall
642 687
  *

+ 428
- 0
src/arch/i386/prefix/mromprefix.S View File

@@ -0,0 +1,428 @@
1
+/*
2
+ * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ *
18
+ */
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER )
21
+
22
+#define PCIBIOS_READ_CONFIG_WORD	0xb109
23
+#define PCIBIOS_READ_CONFIG_DWORD	0xb10a
24
+#define PCIBIOS_WRITE_CONFIG_WORD	0xb10c
25
+#define PCIBIOS_WRITE_CONFIG_DWORD	0xb10d
26
+#define PCI_COMMAND			0x04
27
+#define PCI_COMMAND_MEM				0x02
28
+#define PCI_BAR_0			0x10
29
+#define PCI_BAR_5			0x24
30
+#define PCI_BAR_EXPROM			0x30
31
+
32
+#define ROMPREFIX_EXCLUDE_PAYLOAD 1
33
+#include "romprefix.S"
34
+
35
+	.text
36
+	.arch i386
37
+	.code16
38
+
39
+/* Obtain access to payload by exposing the expansion ROM BAR at the
40
+ * address currently used by a suitably large memory BAR on the same
41
+ * device.  The memory BAR is temporarily disabled.  Using a memory
42
+ * BAR on the same device means that we don't have to worry about the
43
+ * configuration of any intermediate PCI bridges.
44
+ *
45
+ * Parameters:
46
+ *   %ds:0000 : Prefix
47
+ *   %esi : Buffer for copy of image source (or zero if no buffer available)
48
+ * Returns:
49
+ *   %esi : Valid image source address (buffered or unbuffered)
50
+ *   CF set on error
51
+ */
52
+	.section ".text16.early", "awx", @progbits
53
+	.globl	open_payload
54
+open_payload:
55
+	/* Preserve registers */
56
+	pushl	%eax
57
+	pushw	%bx
58
+	pushl	%ecx
59
+	pushl	%edx
60
+	pushl	%edi
61
+	pushw	%bp
62
+	pushw	%ds
63
+
64
+	/* Retrieve bus:dev.fn and image source length from .prefix */
65
+	movw	init_pci_busdevfn, %bx
66
+	movl	image_source_len_dword, %ecx
67
+
68
+	/* Set up %ds for access to .text16.early */
69
+	pushw	%cs
70
+	popw	%ds
71
+
72
+	/* Store bus:dev.fn and image source length to .text16.early */
73
+	movw	%bx, payload_pci_busdevfn
74
+	movl	%ecx, rom_bar_copy_len_dword
75
+
76
+	/* Get expansion ROM BAR current value */
77
+	movw	$PCI_BAR_EXPROM, %di
78
+	call	pci_read_bar
79
+	movl	%eax, rom_bar_orig_value
80
+
81
+	/* Get expansion ROM BAR size */
82
+	call	pci_size_mem_bar_low
83
+	movl	%ecx, rom_bar_size
84
+
85
+	/* Find a suitable memory BAR to use */
86
+	movw	$PCI_BAR_0, %di		/* %di is PCI BAR register */
87
+	xorw	%bp, %bp		/* %bp is increment */
88
+find_mem_bar:
89
+	/* Move to next BAR */
90
+	addw	%bp, %di
91
+	cmpw	$PCI_BAR_5, %di
92
+	jle	1f
93
+	stc
94
+	jmp	99f
95
+1:	movw	$4, %bp
96
+
97
+	/* Get BAR current value */
98
+	call	pci_read_bar
99
+
100
+	/* Skip non-existent BARs */
101
+	notl	%eax
102
+	testl	%eax, %eax
103
+	notl	%eax
104
+	jz	find_mem_bar
105
+
106
+	/* Skip I/O BARs */
107
+	testb	$0x01, %al
108
+	jnz	find_mem_bar
109
+
110
+	/* Set increment to 8 for 64-bit BARs */
111
+	testb	$0x04, %al
112
+	jz	1f
113
+	movw	$8, %bp
114
+1:
115
+	/* Skip 64-bit BARs with high dword set; we couldn't use this
116
+	 * address for the (32-bit) expansion ROM BAR anyway
117
+	 */
118
+	testl	%edx, %edx
119
+	jnz	find_mem_bar
120
+
121
+	/* Get low dword of BAR size */
122
+	call	pci_size_mem_bar_low
123
+
124
+	/* Skip BARs smaller than the expansion ROM BAR */
125
+	cmpl	%ecx, rom_bar_size
126
+	ja	find_mem_bar
127
+
128
+	/* We have a memory BAR with a 32-bit address that is large
129
+	 * enough to use.  Store BAR number and original value.
130
+	 */
131
+	movw	%di, stolen_bar_register
132
+	movl	%eax, stolen_bar_orig_value
133
+
134
+	/* Remove flags from BAR address */
135
+	xorb	%al, %al
136
+
137
+	/* Write zero to our stolen BAR.  This doesn't technically
138
+	 * disable it, but it's a pretty safe bet that the PCI bridge
139
+	 * won't pass through accesses to this region anyway.  Note
140
+	 * that the high dword (if any) must already be zero.
141
+	 */
142
+	xorl	%ecx, %ecx
143
+	call	pci_write_config_dword
144
+
145
+	/* Enable expansion ROM BAR at stolen BAR's address */
146
+	movl	%eax, %ecx
147
+	orb	$0x1, %cl
148
+	movw	$PCI_BAR_EXPROM, %di
149
+	call	pci_write_config_dword
150
+
151
+	/* Copy payload to buffer, or set buffer address to BAR address */
152
+	testl	%esi, %esi
153
+	jz	1f
154
+	/* We have a buffer; copy payload to it */
155
+	pushl	%esi
156
+	pushw	%es
157
+	movl	%esi, %edi
158
+	movl	%eax, %esi
159
+	movl	rom_bar_copy_len_dword, %ecx
160
+	xorw	%ax, %ax
161
+	movw	%ax, %es
162
+	addr32 es rep movsl
163
+	popw	%es
164
+	popl	%esi
165
+	jmp	2f
166
+1:	/* We have no buffer; set %esi to the BAR address */
167
+	movl	%eax, %esi
168
+2:
169
+
170
+	clc
171
+	/* Restore registers and return */
172
+99:	popw	%ds
173
+	popw	%bp
174
+	popl	%edi
175
+	popl	%edx
176
+	popl	%ecx
177
+	popw	%bx
178
+	popl	%eax
179
+	lret
180
+	.size	open_payload, . - open_payload
181
+
182
+	.section ".text16.early.data", "aw", @progbits
183
+payload_pci_busdevfn:
184
+	.word	0
185
+	.size	payload_pci_busdevfn, . - payload_pci_busdevfn
186
+
187
+	.section ".text16.early.data", "aw", @progbits
188
+rom_bar_orig_value:
189
+	.long	0
190
+	.size	rom_bar_orig_value, . - rom_bar_orig_value
191
+
192
+	.section ".text16.early.data", "aw", @progbits
193
+rom_bar_size:
194
+	.long	0
195
+	.size	rom_bar_size, . - rom_bar_size
196
+
197
+	.section ".text16.early.data", "aw", @progbits
198
+rom_bar_copy_len_dword:
199
+	.long	0
200
+	.size	rom_bar_copy_len_dword, . - rom_bar_copy_len_dword
201
+
202
+	.section ".text16.early.data", "aw", @progbits
203
+stolen_bar_register:
204
+	.word	0
205
+	.size	stolen_bar_register, . - stolen_bar_register
206
+
207
+	.section ".text16.early.data", "aw", @progbits
208
+stolen_bar_orig_value:
209
+	.long	0
210
+	.size	stolen_bar_orig_value, . - stolen_bar_orig_value
211
+
212
+/* Restore original BAR values
213
+ *
214
+ * Parameters:
215
+ *   none
216
+ * Returns:
217
+ *   none
218
+ */
219
+	.section ".text16.early", "awx", @progbits
220
+	.globl	close_payload
221
+close_payload:
222
+	/* Preserve registers */
223
+	pushw	%bx
224
+	pushw	%di
225
+	pushl	%ecx
226
+	pushw	%ds
227
+
228
+	/* Set up %ds for access to .text16.early */
229
+	pushw	%cs
230
+	popw	%ds
231
+
232
+	/* Retrieve stored bus:dev.fn */
233
+	movw	payload_pci_busdevfn, %bx
234
+
235
+	/* Restore expansion ROM BAR original value */
236
+	movw	$PCI_BAR_EXPROM, %di
237
+	movl	rom_bar_orig_value, %ecx
238
+	call	pci_write_config_dword
239
+
240
+	/* Restore stolen BAR original value */
241
+	movw	stolen_bar_register, %di
242
+	movl	stolen_bar_orig_value, %ecx
243
+	call	pci_write_config_dword
244
+
245
+	/* Restore registers and return */
246
+	popw	%ds
247
+	popl	%ecx
248
+	popw	%di
249
+	popw	%bx
250
+	lret
251
+	.size	close_payload, . - close_payload
252
+
253
+/* Get PCI BAR value
254
+ *
255
+ * Parameters:
256
+ *   %bx : PCI bus:dev.fn
257
+ *   %di : PCI BAR register number
258
+ * Returns:
259
+ *   %edx:%eax : PCI BAR value
260
+ */
261
+	.section ".text16.early", "awx", @progbits
262
+pci_read_bar:
263
+	/* Preserve registers */
264
+	pushl	%ecx
265
+	pushw	%di
266
+
267
+	/* Read low dword value */
268
+	call	pci_read_config_dword
269
+	movl	%ecx, %eax
270
+
271
+	/* Read high dword value, if applicable */
272
+	xorl	%edx, %edx
273
+	andb	$0x07, %cl
274
+	cmpb	$0x04, %cl
275
+	jne	1f
276
+	addw	$4, %di
277
+	call	pci_read_config_dword
278
+	movl	%ecx, %edx
279
+1:
280
+	/* Restore registers and return */
281
+	popw	%di
282
+	popl	%ecx
283
+	ret
284
+	.size	pci_read_bar, . - pci_read_bar
285
+
286
+/* Get low dword of PCI memory BAR size
287
+ *
288
+ * Parameters:
289
+ *   %bx : PCI bus:dev.fn
290
+ *   %di : PCI BAR register number
291
+ *   %eax : Low dword of current PCI BAR value
292
+ * Returns:
293
+ *   %ecx : PCI BAR size
294
+ */
295
+	.section ".text16.early", "awx", @progbits
296
+pci_size_mem_bar_low:
297
+	/* Preserve registers */
298
+	pushw	%dx
299
+
300
+	/* Disable memory accesses */
301
+	xorw	%dx, %dx
302
+	call	pci_set_mem_access
303
+
304
+	/* Write all ones to BAR */
305
+	xorl	%ecx, %ecx
306
+	decl	%ecx
307
+	call	pci_write_config_dword
308
+
309
+	/* Read back BAR */
310
+	call	pci_read_config_dword
311
+
312
+	/* Calculate size */
313
+	notl	%ecx
314
+	orb	$0x0f, %cl
315
+	incl	%ecx
316
+
317
+	/* Restore original value */
318
+	pushl	%ecx
319
+	movl	%eax, %ecx
320
+	call	pci_write_config_dword
321
+	popl	%ecx
322
+
323
+	/* Enable memory accesses */
324
+	movw	$PCI_COMMAND_MEM, %dx
325
+	call	pci_set_mem_access
326
+
327
+	/* Restore registers and return */
328
+	popw	%dx
329
+	ret
330
+	.size	pci_size_mem_bar_low, . - pci_size_mem_bar_low
331
+
332
+/* Read PCI config dword
333
+ *
334
+ * Parameters:
335
+ *   %bx : PCI bus:dev.fn
336
+ *   %di : PCI register number
337
+ * Returns:
338
+ *   %ecx : Dword value
339
+ */
340
+	.section ".text16.early", "awx", @progbits
341
+pci_read_config_dword:
342
+	/* Preserve registers */
343
+	pushl	%eax
344
+	pushl	%ebx
345
+	pushl	%edx
346
+
347
+	/* Issue INT 0x1a,b10a */
348
+	movw	$PCIBIOS_READ_CONFIG_DWORD, %ax
349
+	int	$0x1a
350
+
351
+	/* Restore registers and return */
352
+	popl	%edx
353
+	popl	%ebx
354
+	popl	%eax
355
+	ret
356
+	.size	pci_read_config_dword, . - pci_read_config_dword
357
+
358
+/* Write PCI config dword
359
+ *
360
+ * Parameters:
361
+ *   %bx : PCI bus:dev.fn
362
+ *   %di : PCI register number
363
+ *   %ecx : PCI BAR value
364
+ * Returns:
365
+ *   none
366
+ */
367
+	.section ".text16.early", "awx", @progbits
368
+pci_write_config_dword:
369
+	/* Preserve registers */
370
+	pushal
371
+
372
+	/* Issue INT 0x1a,b10d */
373
+	movw	$PCIBIOS_WRITE_CONFIG_DWORD, %ax
374
+	int	$0x1a
375
+
376
+	/* Restore registers and return */
377
+	popal
378
+	ret
379
+	.size	pci_write_config_dword, . - pci_write_config_dword
380
+
381
+/* Enable/disable memory access response in PCI command word
382
+ *
383
+ * Parameters:
384
+ *   %bx : PCI bus:dev.fn
385
+ *   %dx : PCI_COMMAND_MEM, or zero
386
+ * Returns:
387
+ *   none
388
+ */
389
+	.section ".text16.early", "awx", @progbits
390
+pci_set_mem_access:
391
+	/* Preserve registers */
392
+	pushal
393
+
394
+	/* Read current value of command register */
395
+	pushw	%bx
396
+	pushw	%dx
397
+	movw	$PCI_COMMAND, %di
398
+	movw	$PCIBIOS_READ_CONFIG_WORD, %ax
399
+	int	$0x1a
400
+	popw	%dx
401
+	popw	%bx
402
+
403
+	/* Set memory access enable as appropriate */
404
+	andw	$~PCI_COMMAND_MEM, %cx
405
+	orw	%dx, %cx
406
+
407
+	/* Write new value of command register */
408
+	movw	$PCIBIOS_WRITE_CONFIG_WORD, %ax
409
+	int	$0x1a
410
+
411
+	/* Restore registers and return */
412
+	popal
413
+	ret
414
+	.size	pci_set_mem_access, . - pci_set_mem_access
415
+
416
+/* Image source area length (in dwords)
417
+ *
418
+ */
419
+	.section ".prefix", "ax", @progbits
420
+image_source_len_dword:
421
+	.long	0
422
+	.size	image_source_len_dword, . - image_source_len_dword
423
+	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
424
+	.ascii	"ADDL"
425
+	.long	image_source_len_dword
426
+	.long	4
427
+	.long	0
428
+	.previous

+ 37
- 5
src/arch/i386/prefix/romprefix.S View File

@@ -32,6 +32,16 @@ FILE_LICENCE ( GPL2_OR_LATER )
32 32
  */
33 33
 #define ROM_BANNER_TIMEOUT ( 2 * ( 18 * BANNER_TIMEOUT ) / 10 )
34 34
 
35
+/* Allow payload to be excluded from ROM size
36
+ */
37
+#if ROMPREFIX_EXCLUDE_PAYLOAD
38
+#define	ZINFO_TYPE_ADxB "ADHB"
39
+#define	ZINFO_TYPE_ADxW "ADHW"
40
+#else
41
+#define	ZINFO_TYPE_ADxB "ADDB"
42
+#define	ZINFO_TYPE_ADxW "ADDW"
43
+#endif
44
+
35 45
 	.text
36 46
 	.code16
37 47
 	.arch i386
@@ -53,7 +63,7 @@ checksum:
53 63
 	.size romheader, . - romheader
54 64
 
55 65
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
56
-	.ascii	"ADDB"
66
+	.ascii	ZINFO_TYPE_ADxB
57 67
 	.long	romheader_size
58 68
 	.long	512
59 69
 	.long	0
@@ -83,11 +93,11 @@ pciheader_runtime_length:
83 93
 	.size pciheader, . - pciheader
84 94
 
85 95
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
86
-	.ascii	"ADDW"
96
+	.ascii	ZINFO_TYPE_ADxW
87 97
 	.long	pciheader_image_length
88 98
 	.long	512
89 99
 	.long	0
90
-	.ascii	"ADDW"
100
+	.ascii	ZINFO_TYPE_ADxW
91 101
 	.long	pciheader_runtime_length
92 102
 	.long	512
93 103
 	.long	0
@@ -179,6 +189,9 @@ init:
179 189
 	movw	%bx, %gs
180 190
 	movw	%di, %bx
181 191
 
192
+	/* Store PCI bus:dev.fn address */
193
+	movw	%ax, init_pci_busdevfn
194
+
182 195
 	/* Print message as early as possible */
183 196
 	movw	$init_message, %si
184 197
 	xorw	%di, %di
@@ -320,8 +333,7 @@ pmm_scan:
320 333
 	/* We have PMM and so a 1kB stack: preserve whole registers */
321 334
 	pushal
322 335
 	/* Allocate image source PMM block */
323
-	movzbl	romheader_size, %ecx
324
-	shll	$5, %ecx
336
+	movzwl	image_source_len_pgh, %ecx
325 337
 	movl	$PMM_HANDLE_BASE_IMAGE_SOURCE, %ebx
326 338
 	movw	$get_pmm_image_source, %bp
327 339
 	call	get_pmm
@@ -552,6 +564,13 @@ init_message_done:
552 564
 	.asciz	"\n\n"
553 565
 	.size	init_message_done, . - init_message_done
554 566
 
567
+/* PCI bus:dev.fn
568
+ *
569
+ */
570
+init_pci_busdevfn:
571
+	.word	0xffff
572
+	.size	init_pci_busdevfn, . - init_pci_busdevfn
573
+
555 574
 /* Image source area
556 575
  *
557 576
  * May be either zero (indicating to use option ROM space as source),
@@ -562,6 +581,19 @@ image_source:
562 581
 	.long	0
563 582
 	.size	image_source, . - image_source
564 583
 
584
+/* Image source area length (in paragraphs)
585
+ *
586
+ */
587
+image_source_len_pgh:
588
+	.word	0
589
+	.size	image_source_len_pgh, . - image_source_len_pgh
590
+	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
591
+	.ascii	"ADDW"
592
+	.long	image_source_len_pgh
593
+	.long	16
594
+	.long	0
595
+	.previous
596
+
565 597
 /* Shrunk ROM size (in 512-byte sectors)
566 598
  *
567 599
  */

+ 2
- 1
src/util/Option/ROM.pm View File

@@ -349,7 +349,8 @@ sub checksum {
349 349
   my $hash = shift;
350 350
   my $self = tied(%$hash);
351 351
 
352
-  return unpack ( "%8C*", ${$self->{data}} );
352
+  my $raw = substr ( ${$self->{data}}, 0, ( $hash->{length} * 512 ) );
353
+  return unpack ( "%8C*", $raw );
353 354
 }
354 355
 
355 356
 =pod

Loading…
Cancel
Save