david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[build] Allow ISA ROMs to be built

The build process has for a long time assumed that every ROM is a PCI
ROM, and will always include the PCI header and PCI-related
functionality (such as checking the PCI BIOS version, including the
PCI bus:dev.fn address within the ROM product name string, etc.).

While real ISA cards are no longer in use, some virtualisation
environments (notably VirtualBox) have support only for ISA ROMs.
This can cause problems: in particular, VirtualBox will call our
initialisation entry point with random garbage in %ax, which we then
treat as the PCI bus:dev.fn address of the autoboot device: this
generally prevents the default boot sequence from using any network
devices.

Create .isarom and .pcirom prefixes which can be used to explicitly
specify the type of ROM to be created.  (Note that the .mrom prefix
always implies a PCI ROM, since the .mrom mechanism relies on
reconfiguring PCI BARs.)

Make .rom a magic prefix which will automatically select the
appropriate PCI or ISA ROM prefix for ROMs defined via a PCI_ROM() or
ISA_ROM() macro.  To maintain backwards compatibility, we default to
building a PCI ROM for anything which is not directly derived from a
PCI_ROM() or ISA_ROM() macro (e.g. bin/intel.rom).

Add a selection of targets to "make everything" to ensure that the
(relatively obscure) ISA ROM build process is included within the
per-commit QA checks.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2014-08-21 16:34:26 +01:00
parent 5b72cf055c
commit 705907f9a9
8 changed files with 146 additions and 30 deletions

View File

@ -147,6 +147,7 @@ all : $(ALL)
#
everything :
$(Q)$(MAKE) --no-print-directory $(ALL) \
bin/3c509.rom bin/intel.rom bin/intel.mrom \
bin-i386-efi/ipxe.efi bin-i386-efi/ipxe.efidrv \
bin-i386-efi/ipxe.efirom \
bin-x86_64-efi/ipxe.efi bin-x86_64-efi/ipxe.efidrv \

View File

@ -902,19 +902,22 @@ CLEANUP += $(BIN)/NIC # Doesn't match the $(BIN)/*.* pattern
# derive the variables:
#
# TGT_ELEMENTS : the elements of the target (e.g. "dfe538 prism2_pci")
# TGT_PREFIX : the prefix type (e.g. "rom")
# TGT_PREFIX : the prefix type (e.g. "pcirom")
# TGT_DRIVERS : the driver for each element (e.g. "rtl8139 prism2_pci")
# TGT_ROM_NAME : the ROM name (e.g. "dfe538")
#
DRIVERS_ipxe = $(DRIVERS)
CARD_DRIVER = $(firstword $(DRIVER_$(1)) $(1))
TGT_ELEMENTS = $(subst --, ,$(firstword $(subst ., ,$(notdir $@))))
TGT_PREFIX = $(word 2,$(subst ., ,$(notdir $@)))
TGT_ROM_NAME = $(firstword $(TGT_ELEMENTS))
TGT_DRIVERS = $(strip $(if $(DRIVERS_$(TGT_ROM_NAME)), \
$(DRIVERS_$(TGT_ROM_NAME)), \
$(foreach TGT_ELEMENT,$(TGT_ELEMENTS), \
$(call CARD_DRIVER,$(TGT_ELEMENT))) ))
TGT_PREFIX_NAME = $(word 2,$(subst ., ,$(notdir $@)))
TGT_PREFIX = $(strip $(if $(filter rom,$(TGT_PREFIX_NAME)), \
$(ROM_TYPE_$(TGT_ROM_NAME))rom, \
$(TGT_PREFIX_NAME)))
# Look up ROM IDs for the current target
# (e.g. "bin/dfe538--prism2_pci.rom.tmp") and derive the variables:

View File

@ -16,6 +16,8 @@ SRCDIRS += arch/i386/drivers/net
#
MEDIA += rom
MEDIA += mrom
MEDIA += pcirom
MEDIA += isarom
MEDIA += pxe
MEDIA += kpxe
MEDIA += kkpxe
@ -31,6 +33,8 @@ MEDIA += exe
#
PAD_rom = $(PERL) $(PADIMG) --blksize=512 --byte=0xff
PAD_mrom = $(PAD_rom)
PAD_pcirom = $(PAD_rom)
PAD_isarom = $(PAD_rom)
PAD_dsk = $(PERL) $(PADIMG) --blksize=512
PAD_hd = $(PERL) $(PADIMG) --blksize=32768
PAD_exe = $(PERL) $(PADIMG) --blksize=512
@ -39,11 +43,15 @@ PAD_exe = $(PERL) $(PADIMG) --blksize=512
#
FINALISE_rom = $(PERL) $(FIXROM)
FINALISE_mrom = $(FINALISE_rom)
FINALISE_pcirom = $(FINALISE_rom)
FINALISE_isarom = $(FINALISE_rom)
# Use $(ROMS) rather than $(DRIVERS) for "allroms" and "allmroms"
# Use $(ROMS) rather than $(DRIVERS) for "allroms", "allmroms", etc.
#
LIST_NAME_rom := ROMS
LIST_NAME_mrom := ROMS
LIST_NAME_pcirom := ROMS
LIST_NAME_isarom := ROMS
# rule to make a non-emulation ISO boot image
NON_AUTO_MEDIA += iso

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
*/
FILE_LICENCE ( GPL2_OR_LATER )
#define BUSTYPE "ISAR"
#define _rom_start _isarom_start
#include "romprefix.S"

View File

@ -94,6 +94,29 @@ print_character:
ret
.size print_character, . - print_character
/*****************************************************************************
* Utility function: print space
*
* Parameters:
* %ds:di : output buffer (or %di=0 to print to console)
* Returns:
* %ds:di : next character in output buffer (if applicable)
*****************************************************************************
*/
.section ".prefix.lib", "awx", @progbits
.code16
.globl print_space
print_space:
/* Preserve registers */
pushw %ax
/* Print space */
movb $( ' ' ), %al
call print_character
/* Restore registers and return */
popw %ax
ret
.size print_space, . - print_space
/*****************************************************************************
* Utility function: print a NUL-terminated string
*
@ -231,12 +254,10 @@ print_kill_line:
movb $( '\r' ), %al
call print_character
/* Print 79 spaces */
movb $( ' ' ), %al
movw $79, %cx
1: call print_character
1: call print_space
loop 1b
/* Print CR */
movb $( '\r' ), %al
call print_character
/* Restore registers and return */
popw %cx

View File

@ -32,8 +32,8 @@ FILE_LICENCE ( GPL2_OR_LATER )
#define ROMPREFIX_EXCLUDE_PAYLOAD 1
#define ROMPREFIX_MORE_IMAGES 1
#define _rom_start _mrom_start
#include "romprefix.S"
#define _pcirom_start _mrom_start
#include "pciromprefix.S"
.text
.arch i386

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
*/
FILE_LICENCE ( GPL2_OR_LATER )
#define BUSTYPE "PCIR"
#define _rom_start _pcirom_start
#include "romprefix.S"

View File

@ -44,6 +44,12 @@ FILE_LICENCE ( GPL2_OR_LATER )
#define INDICATOR 0x00
#else
#define INDICATOR 0x80
#endif
/* Default to building a PCI ROM if no bus type is specified
*/
#ifndef BUSTYPE
#define BUSTYPE "PCIR"
#endif
.text
@ -64,8 +70,10 @@ checksum:
.word ipxeheader
.org 0x16
.word undiheader
.ifeqs BUSTYPE, "PCIR"
.org 0x18
.word pciheader
.endif
.org 0x1a
.word pnpheader
.size romheader, . - romheader
@ -77,6 +85,7 @@ checksum:
.long 0
.previous
.ifeqs BUSTYPE, "PCIR"
pciheader:
.ascii "PCIR" /* Signature */
.word pci_vendor_id /* Vendor identification */
@ -107,6 +116,7 @@ pciheader_runtime_length:
.long 512
.long 0
.previous
.endif /* PCIR */
/* PnP doesn't require any particular alignment, but IBM
* BIOSes will scan on 16-byte boundaries rather than using
@ -148,11 +158,14 @@ mfgstr:
*/
prodstr:
.ascii PRODUCT_SHORT_NAME
.ifeqs BUSTYPE, "PCIR"
prodstr_separator:
.byte 0
.ascii "(PCI "
prodstr_pci_id:
.asciz "xx:xx.x)" /* Filled in by init code */
.ascii "xx:xx.x)" /* Filled in by init code */
.endif /* PCIR */
.byte 0
.size prodstr, . - prodstr
.globl undiheader
@ -167,7 +180,7 @@ undiheader:
.word _data16_memsz /* Stack segment size */
.word _data16_memsz /* Data segment size */
.word _text16_memsz /* Code segment size */
.ascii "PCIR" /* Bus type */
.ascii BUSTYPE /* Bus type */
.equ undiheader_len, . - undiheader
.size undiheader, . - undiheader
@ -208,31 +221,39 @@ init:
pushw %cs
popw %ds
/* Store PCI 3.0 runtime segment address for later use */
movw %bx, %gs
/* Store PCI bus:dev.fn address */
movw %ax, init_pci_busdevfn
/* Print message as early as possible */
movw $init_message, %si
xorw %di, %di
call print_message
call print_pci_busdevfn
/* Fill in product name string, if possible */
/* Store PCI 3.0 runtime segment address for later use, if
* applicable.
*/
.ifeqs BUSTYPE, "PCIR"
movw %bx, %gs
.endif
/* Store PCI bus:dev.fn address, print PCI bus:dev.fn, and add
* PCI bus:dev.fn to product name string, if applicable.
*/
.ifeqs BUSTYPE, "PCIR"
xorw %di, %di
call print_space
movw %ax, init_pci_busdevfn
call print_pci_busdevfn
movw $prodstr_pci_id, %di
call print_pci_busdevfn
movb $( ' ' ), prodstr_separator
.endif
/* Print segment address */
movb $( ' ' ), %al
xorw %di, %di
call print_character
call print_space
movw %cs, %ax
call print_hex_word
/* Check for PCI BIOS version */
/* Check for PCI BIOS version, if applicable */
.ifeqs BUSTYPE, "PCIR"
pushl %ebx
pushl %edx
pushl %edi
@ -283,6 +304,7 @@ no_pci3:
1: popl %edi
popl %edx
popl %ebx
.endif /* PCIR */
/* Check for PnP BIOS. Although %es:di should point to the
* PnP BIOS signature on entry, some BIOSes fail to do this.
@ -396,13 +418,13 @@ no_pmm:
loop 1b
subb %bl, checksum
/* Copy self to option ROM space. Required for PCI3.0, which
* loads us to a temporary location in low memory. Will be a
* no-op for lower PCI versions.
/* Copy self to option ROM space, if applicable. Required for
* PCI3.0, which loads us to a temporary location in low
* memory. Will be a no-op for lower PCI versions.
*/
movb $( ' ' ), %al
.ifeqs BUSTYPE, "PCIR"
xorw %di, %di
call print_character
call print_space
movw %gs, %ax
call print_hex_word
movzbw romheader_size, %cx
@ -411,10 +433,13 @@ no_pmm:
xorw %si, %si
xorw %di, %di
cs rep movsb
.endif
/* Skip prompt if this is not the first PCI function */
/* Skip prompt if this is not the first PCI function, if applicable */
.ifeqs BUSTYPE, "PCIR"
testb $PCI_FUNC_MASK, init_pci_busdevfn
jnz no_shell
.endif
/* Prompt for POST-time shell */
movw $init_message_prompt, %si
xorw %di, %di
@ -564,11 +589,13 @@ init_message:
.ascii "\n"
.ascii PRODUCT_NAME
.ascii "\n"
.asciz "iPXE (http://ipxe.org) "
.asciz "iPXE (http://ipxe.org)"
.size init_message, . - init_message
.ifeqs BUSTYPE, "PCIR"
init_message_pci:
.asciz " PCI"
.size init_message_pci, . - init_message_pci
.endif /* PCIR */
init_message_pnp:
.asciz " PnP"
.size init_message_pnp, . - init_message_pnp
@ -591,9 +618,11 @@ init_message_done:
/* PCI bus:dev.fn
*
*/
.ifeqs BUSTYPE, "PCIR"
init_pci_busdevfn:
.word 0
.size init_pci_busdevfn, . - init_pci_busdevfn
.endif /* PCIR */
/* Image source area
*
@ -732,14 +761,18 @@ exec: /* Set %ds = %cs */
lret
.section ".text16", "awx", @progbits
1:
/* Retrieve PCI bus:dev.fn */
/* Retrieve PCI bus:dev.fn, if applicable */
.ifeqs BUSTYPE, "PCIR"
movw init_pci_busdevfn, %ax
.endif
/* Set up %ds for access to .data16 */
movw %bx, %ds
/* Store PCI bus:dev.fn */
/* Store PCI bus:dev.fn, if applicable */
.ifeqs BUSTYPE, "PCIR"
movw %ax, autoboot_busdevfn
.endif
/* Call main() */
pushl $main