|
@@ -25,6 +25,19 @@ FILE_LICENCE ( GPL2_OR_LATER )
|
25
|
25
|
*/
|
26
|
26
|
#define ROM_BANNER_TIMEOUT ( 2 * ( 18 * BANNER_TIMEOUT ) / 10 )
|
27
|
27
|
|
|
28
|
+/* We can load a ROM in two ways: have the BIOS load all of it (.rom prefix)
|
|
29
|
+ * or have the BIOS load a stub that loads the rest using PCI (.xrom prefix).
|
|
30
|
+ * The latter is not as widely supported, but allows the use of large ROMs
|
|
31
|
+ * on some systems with crowded option ROM space.
|
|
32
|
+ */
|
|
33
|
+
|
|
34
|
+#ifdef LOAD_ROM_FROM_PCI
|
|
35
|
+#define ROM_SIZE_VALUE _prefix_filesz_sect /* Amount to load in BIOS */
|
|
36
|
+#else
|
|
37
|
+#define ROM_SIZE_VALUE 0 /* Load amount (before compr. fixup) */
|
|
38
|
+#endif
|
|
39
|
+
|
|
40
|
+
|
28
|
41
|
.text
|
29
|
42
|
.code16
|
30
|
43
|
.arch i386
|
|
@@ -33,10 +46,12 @@ FILE_LICENCE ( GPL2_OR_LATER )
|
33
|
46
|
.org 0x00
|
34
|
47
|
romheader:
|
35
|
48
|
.word 0xAA55 /* BIOS extension signature */
|
36
|
|
-romheader_size: .byte 0 /* Size in 512-byte blocks */
|
|
49
|
+romheader_size: .byte ROM_SIZE_VALUE /* Size in 512-byte blocks */
|
37
|
50
|
jmp init /* Initialisation vector */
|
38
|
51
|
checksum:
|
39
|
|
- .byte 0
|
|
52
|
+ .byte 0, 0
|
|
53
|
+real_size:
|
|
54
|
+ .word 0
|
40
|
55
|
.org 0x16
|
41
|
56
|
.word undiheader
|
42
|
57
|
.org 0x18
|
|
@@ -44,12 +59,18 @@ checksum:
|
44
|
59
|
.org 0x1a
|
45
|
60
|
.word pnpheader
|
46
|
61
|
.size romheader, . - romheader
|
47
|
|
-
|
|
62
|
+
|
48
|
63
|
.section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
|
|
64
|
+#ifndef LOAD_ROM_FROM_PCI
|
49
|
65
|
.ascii "ADDB"
|
50
|
66
|
.long romheader_size
|
51
|
67
|
.long 512
|
52
|
68
|
.long 0
|
|
69
|
+#endif
|
|
70
|
+ .ascii "ADDB"
|
|
71
|
+ .long real_size
|
|
72
|
+ .long 512
|
|
73
|
+ .long 0
|
53
|
74
|
.previous
|
54
|
75
|
|
55
|
76
|
pciheader:
|
|
@@ -61,17 +82,18 @@ pciheader:
|
61
|
82
|
.byte 0x03 /* PCI data structure revision */
|
62
|
83
|
.byte 0x02, 0x00, 0x00 /* Class code */
|
63
|
84
|
pciheader_image_length:
|
64
|
|
- .word 0 /* Image length */
|
|
85
|
+ .word ROM_SIZE_VALUE /* Image length */
|
65
|
86
|
.word 0x0001 /* Revision level */
|
66
|
87
|
.byte 0x00 /* Code type */
|
67
|
88
|
.byte 0x80 /* Last image indicator */
|
68
|
89
|
pciheader_runtime_length:
|
69
|
|
- .word 0 /* Maximum run-time image length */
|
|
90
|
+ .word ROM_SIZE_VALUE /* Maximum run-time image length */
|
70
|
91
|
.word 0x0000 /* Configuration utility code header */
|
71
|
92
|
.word 0x0000 /* DMTF CLP entry point */
|
72
|
93
|
.equ pciheader_len, . - pciheader
|
73
|
94
|
.size pciheader, . - pciheader
|
74
|
|
-
|
|
95
|
+
|
|
96
|
+#ifndef LOAD_ROM_FROM_PCI
|
75
|
97
|
.section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
|
76
|
98
|
.ascii "ADDW"
|
77
|
99
|
.long pciheader_image_length
|
|
@@ -82,6 +104,7 @@ pciheader_runtime_length:
|
82
|
104
|
.long 512
|
83
|
105
|
.long 0
|
84
|
106
|
.previous
|
|
107
|
+#endif
|
85
|
108
|
|
86
|
109
|
pnpheader:
|
87
|
110
|
.ascii "$PnP" /* Signature */
|
|
@@ -175,6 +198,11 @@ init:
|
175
|
198
|
call print_message
|
176
|
199
|
call print_pci_busdevfn
|
177
|
200
|
|
|
201
|
+#ifdef LOAD_ROM_FROM_PCI
|
|
202
|
+ /* Save PCI bus:dev.fn for later use */
|
|
203
|
+ movw %ax, pci_busdevfn
|
|
204
|
+#endif
|
|
205
|
+
|
178
|
206
|
/* Fill in product name string, if possible */
|
179
|
207
|
movw $prodstr_pci_id, %di
|
180
|
208
|
call print_pci_busdevfn
|
|
@@ -199,6 +227,9 @@ init:
|
199
|
227
|
jne no_pci3
|
200
|
228
|
testb %ah, %ah
|
201
|
229
|
jnz no_pci3
|
|
230
|
+#ifdef LOAD_ROM_FROM_PCI
|
|
231
|
+ incb pcibios_present
|
|
232
|
+#endif
|
202
|
233
|
movw $init_message_pci, %si
|
203
|
234
|
xorw %di, %di
|
204
|
235
|
call print_message
|
|
@@ -310,7 +341,7 @@ pmm_scan:
|
310
|
341
|
/* We have PMM and so a 1kB stack: preserve upper register halves */
|
311
|
342
|
pushal
|
312
|
343
|
/* Calculate required allocation size in %esi */
|
313
|
|
- movzbl romheader_size, %eax
|
|
344
|
+ movzwl real_size, %eax
|
314
|
345
|
shll $9, %eax
|
315
|
346
|
addl $_textdata_memsz, %eax
|
316
|
347
|
orw $0xffff, %ax /* Ensure allocation size is at least 64kB */
|
|
@@ -364,7 +395,7 @@ pmm_copy:
|
364
|
395
|
movl %edi, decompress_to
|
365
|
396
|
/* Shrink ROM */
|
366
|
397
|
movb $_prefix_memsz_sect, romheader_size
|
367
|
|
-#ifdef SHRINK_WITHOUT_PMM
|
|
398
|
+#if defined(SHRINK_WITHOUT_PMM) || defined(LOAD_ROM_FROM_PCI)
|
368
|
399
|
jmp pmm_done
|
369
|
400
|
pmm_fail:
|
370
|
401
|
/* Print marker and copy ourselves to high memory */
|
|
@@ -379,8 +410,28 @@ pmm_fail:
|
379
|
410
|
#endif
|
380
|
411
|
/* Restore upper register halves */
|
381
|
412
|
popal
|
|
413
|
+#if defined(LOAD_ROM_FROM_PCI)
|
|
414
|
+ call load_from_pci
|
|
415
|
+ jc load_err
|
|
416
|
+ jmp load_ok
|
382
|
417
|
no_pmm:
|
|
418
|
+ /* Cannot continue without PMM - print error message */
|
|
419
|
+ xorw %di, %di
|
|
420
|
+ movw $init_message_no_pmm, %si
|
|
421
|
+ call print_message
|
|
422
|
+load_err:
|
|
423
|
+ /* Wait for five seconds to let user see message */
|
|
424
|
+ movw $90, %cx
|
|
425
|
+1: call wait_for_tick
|
|
426
|
+ loop 1b
|
|
427
|
+ /* Mark environment as invalid and return */
|
|
428
|
+ movl $0, decompress_to
|
|
429
|
+ jmp out
|
383
|
430
|
|
|
431
|
+load_ok:
|
|
432
|
+#else
|
|
433
|
+no_pmm:
|
|
434
|
+#endif
|
384
|
435
|
/* Update checksum */
|
385
|
436
|
xorw %bx, %bx
|
386
|
437
|
xorw %si, %si
|
|
@@ -425,14 +476,14 @@ no_pmm:
|
425
|
476
|
movw $init_message_done, %si
|
426
|
477
|
call print_message
|
427
|
478
|
popf
|
428
|
|
- jnz 2f
|
|
479
|
+ jnz out
|
429
|
480
|
/* Ctrl-B was pressed: invoke gPXE. The keypress will be
|
430
|
481
|
* picked up by the initial shell prompt, and we will drop
|
431
|
482
|
* into a shell.
|
432
|
483
|
*/
|
433
|
484
|
pushw %cs
|
434
|
485
|
call exec
|
435
|
|
-2:
|
|
486
|
+out:
|
436
|
487
|
/* Restore registers */
|
437
|
488
|
popw %gs
|
438
|
489
|
popw %fs
|
|
@@ -479,6 +530,11 @@ init_message_bbs:
|
479
|
530
|
init_message_pmm:
|
480
|
531
|
.asciz " PMM"
|
481
|
532
|
.size init_message_pmm, . - init_message_pmm
|
|
533
|
+#ifdef LOAD_ROM_FROM_PCI
|
|
534
|
+init_message_no_pmm:
|
|
535
|
+ .asciz "\nPMM required but not present!\n"
|
|
536
|
+ .size init_message_no_pmm, . - init_message_no_pmm
|
|
537
|
+#endif
|
482
|
538
|
init_message_int19:
|
483
|
539
|
.asciz " INT19"
|
484
|
540
|
.size init_message_int19, . - init_message_int19
|
|
@@ -504,12 +560,32 @@ image_source:
|
504
|
560
|
/* Temporary decompression area
|
505
|
561
|
*
|
506
|
562
|
* May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
|
|
563
|
+ * If a PCI ROM load fails, this will be set to zero.
|
507
|
564
|
*/
|
508
|
565
|
.globl decompress_to
|
509
|
566
|
decompress_to:
|
510
|
567
|
.long HIGHMEM_LOADPOINT
|
511
|
568
|
.size decompress_to, . - decompress_to
|
512
|
569
|
|
|
570
|
+#ifdef LOAD_ROM_FROM_PCI
|
|
571
|
+
|
|
572
|
+/* Set if the PCI BIOS is present, even <3.0 */
|
|
573
|
+pcibios_present:
|
|
574
|
+ .byte 0
|
|
575
|
+ .byte 0 /* for alignment */
|
|
576
|
+ .size pcibios_present, . - pcibios_present
|
|
577
|
+
|
|
578
|
+/* PCI bus:device.function word
|
|
579
|
+ *
|
|
580
|
+ * Filled in by init in the .xrom case, so the remainder of the ROM
|
|
581
|
+ * can be located.
|
|
582
|
+ */
|
|
583
|
+pci_busdevfn:
|
|
584
|
+ .word 0
|
|
585
|
+ .size pci_busdevfn, . - pci_busdevfn
|
|
586
|
+
|
|
587
|
+#endif
|
|
588
|
+
|
513
|
589
|
/* BBS version
|
514
|
590
|
*
|
515
|
591
|
* Filled in by BBS BIOS. We ignore the value.
|
|
@@ -528,6 +604,289 @@ bev_entry:
|
528
|
604
|
lret
|
529
|
605
|
.size bev_entry, . - bev_entry
|
530
|
606
|
|
|
607
|
+
|
|
608
|
+#ifdef LOAD_ROM_FROM_PCI
|
|
609
|
+
|
|
610
|
+#define PCI_ROM_ADDRESS 0x30 /* Bits 31:11 address, 10:1 reserved */
|
|
611
|
+#define PCI_ROM_ADDRESS_ENABLE 0x00000001
|
|
612
|
+#define PCI_ROM_ADDRESS_MASK 0xfffff800
|
|
613
|
+
|
|
614
|
+#define PCIBIOS_READ_WORD 0xb109
|
|
615
|
+#define PCIBIOS_READ_DWORD 0xb10a
|
|
616
|
+#define PCIBIOS_WRITE_WORD 0xb10c
|
|
617
|
+#define PCIBIOS_WRITE_DWORD 0xb10d
|
|
618
|
+
|
|
619
|
+/* Determine size of PCI BAR
|
|
620
|
+ *
|
|
621
|
+ * %bx : PCI bus:dev.fn to probe
|
|
622
|
+ * %di : Address of BAR to find size of
|
|
623
|
+ * %edx : Mask of address bits within BAR
|
|
624
|
+ *
|
|
625
|
+ * %ecx : Size for a memory resource,
|
|
626
|
+ * 1 for an I/O resource (bit 0 set).
|
|
627
|
+ * CF : Set on error or nonexistent device (all-ones read)
|
|
628
|
+ *
|
|
629
|
+ * All other registers saved.
|
|
630
|
+ */
|
|
631
|
+pci_bar_size:
|
|
632
|
+ /* Save registers */
|
|
633
|
+ pushw %ax
|
|
634
|
+ pushl %esi
|
|
635
|
+ pushl %edx
|
|
636
|
+
|
|
637
|
+ /* Read current BAR value */
|
|
638
|
+ movw $PCIBIOS_READ_DWORD, %ax
|
|
639
|
+ int $0x1a
|
|
640
|
+
|
|
641
|
+ /* Check for device existence and save it */
|
|
642
|
+ testb $1, %cl /* I/O bit? */
|
|
643
|
+ jz 1f
|
|
644
|
+ andl $1, %ecx /* If so, exit with %ecx = 1 */
|
|
645
|
+ jmp 99f
|
|
646
|
+1: notl %ecx
|
|
647
|
+ testl %ecx, %ecx /* Set ZF iff %ecx was all-ones */
|
|
648
|
+ notl %ecx
|
|
649
|
+ jnz 1f
|
|
650
|
+ stc /* All ones - exit with CF set */
|
|
651
|
+ jmp 99f
|
|
652
|
+1: movl %ecx, %esi /* Save in %esi */
|
|
653
|
+
|
|
654
|
+ /* Write all ones to BAR */
|
|
655
|
+ movl %edx, %ecx
|
|
656
|
+ movw $PCIBIOS_WRITE_DWORD, %ax
|
|
657
|
+ int $0x1a
|
|
658
|
+
|
|
659
|
+ /* Read back BAR */
|
|
660
|
+ movw $PCIBIOS_READ_DWORD, %ax
|
|
661
|
+ int $0x1a
|
|
662
|
+
|
|
663
|
+ /* Find decode size from least set bit in mask BAR */
|
|
664
|
+ bsfl %ecx, %ecx /* Find least set bit, log2(decode size) */
|
|
665
|
+ jz 1f /* Mask BAR should not be zero */
|
|
666
|
+ xorl %edx, %edx
|
|
667
|
+ incl %edx
|
|
668
|
+ shll %cl, %edx /* %edx = decode size */
|
|
669
|
+ jmp 2f
|
|
670
|
+1: xorl %edx, %edx /* Return zero size for mask BAR zero */
|
|
671
|
+
|
|
672
|
+ /* Restore old BAR value */
|
|
673
|
+2: movl %esi, %ecx
|
|
674
|
+ movw $PCIBIOS_WRITE_DWORD, %ax
|
|
675
|
+ int $0x1a
|
|
676
|
+
|
|
677
|
+ movl %edx, %ecx /* Return size in %ecx */
|
|
678
|
+
|
|
679
|
+ /* Restore registers and return */
|
|
680
|
+99: popl %edx
|
|
681
|
+ popl %esi
|
|
682
|
+ popw %ax
|
|
683
|
+ ret
|
|
684
|
+
|
|
685
|
+ .size pci_bar_size, . - pci_bar_size
|
|
686
|
+
|
|
687
|
+/* PCI ROM loader
|
|
688
|
+ *
|
|
689
|
+ * Called from init in the .xrom case to load the non-prefix code
|
|
690
|
+ * using the PCI ROM BAR.
|
|
691
|
+ *
|
|
692
|
+ * Returns with carry flag set on error. All registers saved.
|
|
693
|
+ */
|
|
694
|
+load_from_pci:
|
|
695
|
+ /*
|
|
696
|
+ * Use PCI BIOS access to config space. The calls take
|
|
697
|
+ *
|
|
698
|
+ * %ah : 0xb1 %al : function
|
|
699
|
+ * %bx : bus/dev/fn
|
|
700
|
+ * %di : config space address
|
|
701
|
+ * %ecx : value to write (for writes)
|
|
702
|
+ *
|
|
703
|
+ * %ecx : value read (for reads)
|
|
704
|
+ * %ah : return code
|
|
705
|
+ * CF : error indication
|
|
706
|
+ *
|
|
707
|
+ * All registers not used for return are preserved.
|
|
708
|
+ */
|
|
709
|
+
|
|
710
|
+ /* Save registers and set up %es for big real mode */
|
|
711
|
+ pushal
|
|
712
|
+ pushw %es
|
|
713
|
+ xorw %ax, %ax
|
|
714
|
+ movw %ax, %es
|
|
715
|
+
|
|
716
|
+ /* Check PCI BIOS presence */
|
|
717
|
+ cmpb $0, pcibios_present
|
|
718
|
+ jz err_pcibios
|
|
719
|
+
|
|
720
|
+ /* Load existing PCI ROM BAR */
|
|
721
|
+ movw $PCIBIOS_READ_DWORD, %ax
|
|
722
|
+ movw pci_busdevfn, %bx
|
|
723
|
+ movw $PCI_ROM_ADDRESS, %di
|
|
724
|
+ int $0x1a
|
|
725
|
+
|
|
726
|
+ /* Maybe it's already enabled? */
|
|
727
|
+ testb $PCI_ROM_ADDRESS_ENABLE, %cl
|
|
728
|
+ jz 1f
|
|
729
|
+ movb $1, %dl /* Flag indicating no deinit required */
|
|
730
|
+ movl %ecx, %ebp
|
|
731
|
+ jmp check_rom
|
|
732
|
+
|
|
733
|
+ /* Determine PCI BAR decode size */
|
|
734
|
+1: movl $PCI_ROM_ADDRESS_MASK, %edx
|
|
735
|
+ call pci_bar_size /* Returns decode size in %ecx */
|
|
736
|
+ jc err_size_insane /* CF => no ROM BAR, %ecx == ffffffff */
|
|
737
|
+
|
|
738
|
+ /* Check sanity of decode size */
|
|
739
|
+ xorl %eax, %eax
|
|
740
|
+ movw real_size, %ax
|
|
741
|
+ shll $9, %eax /* %eax = ROM size */
|
|
742
|
+ cmpl %ecx, %eax
|
|
743
|
+ ja err_size_insane /* Insane if decode size < ROM size */
|
|
744
|
+ cmpl $0x100000, %ecx
|
|
745
|
+ jae err_size_insane /* Insane if decode size >= 1MB */
|
|
746
|
+
|
|
747
|
+ /* Find a place to map the BAR
|
|
748
|
+ * In theory we should examine e820 and all PCI BARs to find a
|
|
749
|
+ * free region. However, we run at POST when e820 may not be
|
|
750
|
+ * available, and memory reads of an unmapped location are
|
|
751
|
+ * de facto standardized to return all-ones. Thus, we can get
|
|
752
|
+ * away with searching high memory (0xf0000000 and up) on
|
|
753
|
+ * multiples of the ROM BAR decode size for a sufficiently
|
|
754
|
+ * large all-ones region.
|
|
755
|
+ */
|
|
756
|
+ movl %ecx, %edx /* Save ROM BAR size in %edx */
|
|
757
|
+ movl $0xf0000000, %ebp
|
|
758
|
+ xorl %eax, %eax
|
|
759
|
+ notl %eax /* %eax = all ones */
|
|
760
|
+bar_search:
|
|
761
|
+ movl %ebp, %edi
|
|
762
|
+ movl %edx, %ecx
|
|
763
|
+ shrl $2, %ecx
|
|
764
|
+ addr32 repe scasl /* Scan %es:edi for anything not all-ones */
|
|
765
|
+ jz bar_found
|
|
766
|
+ addl %edx, %ebp
|
|
767
|
+ testl $0x80000000, %ebp
|
|
768
|
+ jz err_no_bar
|
|
769
|
+ jmp bar_search
|
|
770
|
+
|
|
771
|
+bar_found:
|
|
772
|
+ movl %edi, %ebp
|
|
773
|
+ /* Save current BAR value on stack to restore later */
|
|
774
|
+ movw $PCIBIOS_READ_DWORD, %ax
|
|
775
|
+ movw $PCI_ROM_ADDRESS, %di
|
|
776
|
+ int $0x1a
|
|
777
|
+ pushl %ecx
|
|
778
|
+
|
|
779
|
+ /* Map the ROM */
|
|
780
|
+ movw $PCIBIOS_WRITE_DWORD, %ax
|
|
781
|
+ movl %ebp, %ecx
|
|
782
|
+ orb $PCI_ROM_ADDRESS_ENABLE, %cl
|
|
783
|
+ int $0x1a
|
|
784
|
+
|
|
785
|
+ xorb %dl, %dl /* %dl = 0 : ROM was not already mapped */
|
|
786
|
+check_rom:
|
|
787
|
+ /* Check and copy ROM - enter with %dl set to skip unmapping,
|
|
788
|
+ * %ebp set to mapped ROM BAR address.
|
|
789
|
+ * We check up to prodstr_separator for equality, since anything past
|
|
790
|
+ * that may have been modified. Since our check includes the checksum
|
|
791
|
+ * byte over the whole ROM stub, that should be sufficient.
|
|
792
|
+ */
|
|
793
|
+ xorb %dh, %dh /* %dh = 0 : ROM did not fail integrity check */
|
|
794
|
+
|
|
795
|
+ /* Verify ROM integrity */
|
|
796
|
+ xorl %esi, %esi
|
|
797
|
+ movl %ebp, %edi
|
|
798
|
+ movl $prodstr_separator, %ecx
|
|
799
|
+ addr32 repe cmpsb
|
|
800
|
+ jz copy_rom
|
|
801
|
+ incb %dh /* ROM failed integrity check */
|
|
802
|
+ movl %ecx, %ebp /* Save number of bytes left */
|
|
803
|
+ jmp skip_load
|
|
804
|
+
|
|
805
|
+copy_rom:
|
|
806
|
+ /* Print BAR address and indicate whether we mapped it ourselves */
|
|
807
|
+ movb $( ' ' ), %al
|
|
808
|
+ xorw %di, %di
|
|
809
|
+ call print_character
|
|
810
|
+ movl %ebp, %eax
|
|
811
|
+ call print_hex_dword
|
|
812
|
+ movb $( '-' ), %al /* '-' for self-mapped */
|
|
813
|
+ subb %dl, %al
|
|
814
|
+ subb %dl, %al /* '+' = '-' - 2 for BIOS-mapped */
|
|
815
|
+ call print_character
|
|
816
|
+
|
|
817
|
+ /* Copy ROM at %ebp to PMM or highmem block */
|
|
818
|
+ movl %ebp, %esi
|
|
819
|
+ movl image_source, %edi
|
|
820
|
+ movzwl real_size, %ecx
|
|
821
|
+ shll $9, %ecx
|
|
822
|
+ addr32 es rep movsb
|
|
823
|
+ movl %edi, decompress_to
|
|
824
|
+skip_load:
|
|
825
|
+ testb %dl, %dl /* Was ROM already mapped? */
|
|
826
|
+ jnz skip_unmap
|
|
827
|
+
|
|
828
|
+ /* Unmap the ROM by restoring old ROM BAR */
|
|
829
|
+ movw $PCIBIOS_WRITE_DWORD, %ax
|
|
830
|
+ movw $PCI_ROM_ADDRESS, %di
|
|
831
|
+ popl %ecx
|
|
832
|
+ int $0x1a
|
|
833
|
+
|
|
834
|
+skip_unmap:
|
|
835
|
+ /* Error handling */
|
|
836
|
+ testb %dh, %dh
|
|
837
|
+ jnz err_rom_invalid
|
|
838
|
+ clc
|
|
839
|
+ jmp 99f
|
|
840
|
+
|
|
841
|
+err_pcibios: /* No PCI BIOS available */
|
|
842
|
+ movw $load_message_no_pcibios, %si
|
|
843
|
+ xorl %eax, %eax /* "error code" is zero */
|
|
844
|
+ jmp 1f
|
|
845
|
+err_size_insane: /* BAR has size (%ecx) that is insane */
|
|
846
|
+ movw $load_message_size_insane, %si
|
|
847
|
+ movl %ecx, %eax
|
|
848
|
+ jmp 1f
|
|
849
|
+err_no_bar: /* No space of sufficient size (%edx) found */
|
|
850
|
+ movw $load_message_no_bar, %si
|
|
851
|
+ movl %edx, %eax
|
|
852
|
+ jmp 1f
|
|
853
|
+err_rom_invalid: /* Loaded ROM does not match (%ebp bytes left) */
|
|
854
|
+ movw $load_message_rom_invalid, %si
|
|
855
|
+ movzbl romheader_size, %eax
|
|
856
|
+ shll $9, %eax
|
|
857
|
+ subl %ebp, %eax
|
|
858
|
+ decl %eax /* %eax is now byte index of failure */
|
|
859
|
+
|
|
860
|
+1: /* Error handler - print message at %si and dword in %eax */
|
|
861
|
+ xorw %di, %di
|
|
862
|
+ call print_message
|
|
863
|
+ call print_hex_dword
|
|
864
|
+ stc
|
|
865
|
+99: popw %es
|
|
866
|
+ popal
|
|
867
|
+ ret
|
|
868
|
+
|
|
869
|
+ .size load_from_pci, . - load_from_pci
|
|
870
|
+
|
|
871
|
+load_message_no_pcibios:
|
|
872
|
+ .asciz "\nNo PCI BIOS found! "
|
|
873
|
+ .size load_message_no_pcibios, . - load_message_no_pcibios
|
|
874
|
+
|
|
875
|
+load_message_size_insane:
|
|
876
|
+ .asciz "\nROM resource has invalid size "
|
|
877
|
+ .size load_message_size_insane, . - load_message_size_insane
|
|
878
|
+
|
|
879
|
+load_message_no_bar:
|
|
880
|
+ .asciz "\nNo memory hole of sufficient size "
|
|
881
|
+ .size load_message_no_bar, . - load_message_no_bar
|
|
882
|
+
|
|
883
|
+load_message_rom_invalid:
|
|
884
|
+ .asciz "\nLoaded ROM is invalid at "
|
|
885
|
+ .size load_message_rom_invalid, . - load_message_rom_invalid
|
|
886
|
+
|
|
887
|
+#endif /* LOAD_ROM_FROM_PCI */
|
|
888
|
+
|
|
889
|
+
|
531
|
890
|
/* INT19 entry point
|
532
|
891
|
*
|
533
|
892
|
* Called via the hooked INT 19 if we detected a non-PnP BIOS. We
|
|
@@ -588,6 +947,14 @@ exec: /* Set %ds = %cs */
|
588
|
947
|
pushw %cs
|
589
|
948
|
popw %ds
|
590
|
949
|
|
|
950
|
+#ifdef LOAD_ROM_FROM_PCI
|
|
951
|
+ /* Don't execute if load was invalid */
|
|
952
|
+ cmpl $0, decompress_to
|
|
953
|
+ jne 1f
|
|
954
|
+ lret
|
|
955
|
+1:
|
|
956
|
+#endif
|
|
957
|
+
|
591
|
958
|
/* Print message as soon as possible */
|
592
|
959
|
movw $prodstr, %si
|
593
|
960
|
xorw %di, %di
|