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

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

479
 	cld			/* Sanity: clear the direction flag asap */
479
 	cld			/* Sanity: clear the direction flag asap */
480
 	pushfw
480
 	pushfw
481
 
481
 
482
+	/* Set up %ds for (read-only) access to .prefix */
483
+	pushw	%cs
484
+	popw	%ds
485
+
482
 	/* Copy decompression temporary area physical address to %ebp */
486
 	/* Copy decompression temporary area physical address to %ebp */
483
 	movl	%edi, %ebp
487
 	movl	%edi, %ebp
484
 
488
 
495
 	call	install_block		/* .text16.early */
499
 	call	install_block		/* .text16.early */
496
 	popl	%esi
500
 	popl	%esi
497
 
501
 
498
-	/* Open up access to payload */
499
 #ifndef KEEP_IT_REAL
502
 #ifndef KEEP_IT_REAL
500
 	/* Access high memory */
503
 	/* Access high memory */
501
 	pushw	%cs
504
 	pushw	%cs
511
 2:	jmp	2b
514
 2:	jmp	2b
512
 	.section ".prefix.data", "aw", @progbits
515
 	.section ".prefix.data", "aw", @progbits
513
 a20_death_message:
516
 a20_death_message:
514
-	.asciz	"Gate A20 stuck - cannot continue\n"
517
+	.asciz	"\nHigh memory inaccessible - cannot continue\n"
515
 	.size	a20_death_message, . - a20_death_message
518
 	.size	a20_death_message, . - a20_death_message
516
 	.previous
519
 	.previous
517
 3:
520
 3:
518
 #endif
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
 	/* Calculate physical address of payload (i.e. first source) */
544
 	/* Calculate physical address of payload (i.e. first source) */
521
 	testl	%esi, %esi
545
 	testl	%esi, %esi
522
 	jnz	1f
546
 	jnz	1f
523
 	movw	%cs, %si
547
 	movw	%cs, %si
524
 	shll	$4, %esi
548
 	shll	$4, %esi
525
-1:	addl	%cs:payload_lma, %esi
549
+1:	addl	payload_lma, %esi
526
 
550
 
527
 	/* Install .text16.late and .data16 */
551
 	/* Install .text16.late and .data16 */
528
 	movl	$_text16_late_filesz, %ecx
552
 	movl	$_text16_late_filesz, %ecx
588
 
612
 
589
 	/* Copy code to new location */
613
 	/* Copy code to new location */
590
 	pushl	%edi
614
 	pushl	%edi
615
+	pushw	%ax
591
 	xorw	%ax, %ax
616
 	xorw	%ax, %ax
592
 	movw	%ax, %es
617
 	movw	%ax, %es
593
 	es rep addr32 movsb
618
 	es rep addr32 movsb
619
+	popw	%ax
594
 	popl	%edi
620
 	popl	%edi
595
 
621
 
596
 	/* Initialise librm at new location */
622
 	/* Initialise librm at new location */
598
 skip_relocate:
624
 skip_relocate:
599
 #endif
625
 #endif
600
 
626
 
627
+	/* Close access to payload */
628
+	movw	%ax, (close_payload_vector+2)
629
+	lcall	*close_payload_vector
630
+
601
 	/* Restore registers */
631
 	/* Restore registers */
602
 	popfw
632
 	popfw
603
 	popw	%es
633
 	popw	%es
625
 	.word 0
655
 	.word 0
626
 	.size prot_call_vector, . - prot_call_vector
656
 	.size prot_call_vector, . - prot_call_vector
627
 #endif
657
 #endif
658
+close_payload_vector:
659
+	.word close_payload
660
+	.word 0
661
+	.size close_payload_vector, . - close_payload_vector
628
 
662
 
629
 	/* Payload address */
663
 	/* Payload address */
630
 	.section ".prefix.lib", "awx", @progbits
664
 	.section ".prefix.lib", "awx", @progbits
637
 	.long	0
671
 	.long	0
638
 	.previous
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
  * uninstall
686
  * uninstall
642
  *
687
  *

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

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
  */
32
  */
33
 #define ROM_BANNER_TIMEOUT ( 2 * ( 18 * BANNER_TIMEOUT ) / 10 )
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
 	.text
45
 	.text
36
 	.code16
46
 	.code16
37
 	.arch i386
47
 	.arch i386
53
 	.size romheader, . - romheader
63
 	.size romheader, . - romheader
54
 
64
 
55
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
65
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
56
-	.ascii	"ADDB"
66
+	.ascii	ZINFO_TYPE_ADxB
57
 	.long	romheader_size
67
 	.long	romheader_size
58
 	.long	512
68
 	.long	512
59
 	.long	0
69
 	.long	0
83
 	.size pciheader, . - pciheader
93
 	.size pciheader, . - pciheader
84
 
94
 
85
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
95
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
86
-	.ascii	"ADDW"
96
+	.ascii	ZINFO_TYPE_ADxW
87
 	.long	pciheader_image_length
97
 	.long	pciheader_image_length
88
 	.long	512
98
 	.long	512
89
 	.long	0
99
 	.long	0
90
-	.ascii	"ADDW"
100
+	.ascii	ZINFO_TYPE_ADxW
91
 	.long	pciheader_runtime_length
101
 	.long	pciheader_runtime_length
92
 	.long	512
102
 	.long	512
93
 	.long	0
103
 	.long	0
179
 	movw	%bx, %gs
189
 	movw	%bx, %gs
180
 	movw	%di, %bx
190
 	movw	%di, %bx
181
 
191
 
192
+	/* Store PCI bus:dev.fn address */
193
+	movw	%ax, init_pci_busdevfn
194
+
182
 	/* Print message as early as possible */
195
 	/* Print message as early as possible */
183
 	movw	$init_message, %si
196
 	movw	$init_message, %si
184
 	xorw	%di, %di
197
 	xorw	%di, %di
320
 	/* We have PMM and so a 1kB stack: preserve whole registers */
333
 	/* We have PMM and so a 1kB stack: preserve whole registers */
321
 	pushal
334
 	pushal
322
 	/* Allocate image source PMM block */
335
 	/* Allocate image source PMM block */
323
-	movzbl	romheader_size, %ecx
324
-	shll	$5, %ecx
336
+	movzwl	image_source_len_pgh, %ecx
325
 	movl	$PMM_HANDLE_BASE_IMAGE_SOURCE, %ebx
337
 	movl	$PMM_HANDLE_BASE_IMAGE_SOURCE, %ebx
326
 	movw	$get_pmm_image_source, %bp
338
 	movw	$get_pmm_image_source, %bp
327
 	call	get_pmm
339
 	call	get_pmm
552
 	.asciz	"\n\n"
564
 	.asciz	"\n\n"
553
 	.size	init_message_done, . - init_message_done
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
 /* Image source area
574
 /* Image source area
556
  *
575
  *
557
  * May be either zero (indicating to use option ROM space as source),
576
  * May be either zero (indicating to use option ROM space as source),
562
 	.long	0
581
 	.long	0
563
 	.size	image_source, . - image_source
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
 /* Shrunk ROM size (in 512-byte sectors)
597
 /* Shrunk ROM size (in 512-byte sectors)
566
  *
598
  *
567
  */
599
  */

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

349
   my $hash = shift;
349
   my $hash = shift;
350
   my $self = tied(%$hash);
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
 =pod
356
 =pod

Loading…
Cancel
Save