2
0
mirror of https://github.com/xcat2/xNBA.git synced 2024-12-15 07:41:45 +00:00
xNBA/src/arch/i386/prefix/romprefix.S
Michael Brown ef37f78cbe Cut out almost all the optional code paths, drastically simplifying the
flow of control through this code.

We now always add PCI and PnP headers even for ISA ROMs; there's no harm
in doing so.

UNDI loader is still missing.
2006-06-06 15:33:39 +00:00

186 lines
4.6 KiB
ArmAsm

/* At entry, the processor is in 16 bit real mode and the code is being
* executed from an address it was not linked to. Code must be pic and
* 32 bit sensitive until things are fixed up.
*
* Also be very careful as the stack is at the rear end of the interrupt
* table so using a noticeable amount of stack space is a no-no.
*/
.text
.code16
.arch i386
.section ".prefix", "ax", @progbits
.org 0x00
romheader:
.word 0xAA55 /* BIOS extension signature */
.byte _rom_size /* Size in 512-byte blocks */
jmp init_vector /* Initialisation vector */
.org 0x16
.word undiheader
.org 0x18
.word pciheader
.org 0x1a
.word pnpheader
.size romheader, . - romheader
pciheader:
.ascii "PCIR" /* Signature */
.word pci_vendor_id /* Vendor ID */
.word pci_device_id /* Device ID */
.word 0x0000 /* pointer to vital product data */
.word pciheader_len /* PCI data structure length */
.byte 0x00 /* PCI data structure revision */
.byte 0x02 /* Device Base Type code */
.byte 0x00 /* Device Sub-Type code */
.byte 0x00 /* Device Interface Type code */
.word _rom_size /* Image length same as offset 02h */
.word 0x0001 /* revision level of code/data */
.byte 0x00 /* code type */
.byte 0x80 /* Flags (last PCI data structure) */
.word 0x0000 /* reserved */
.equ pciheader_len, . - pciheader
.size pciheader, . - pciheader
pnpheader:
.ascii "$PnP" /* Signature */
.byte 0x01 /* Structure revision */
.byte ( pnpheader_len / 16 ) /* Length (in 16 byte increments) */
.word 0x0000 /* Offset of next header */
.byte 0x00 /* Reserved */
.byte 0x00 /* Checksum */
.long 0x00000000 /* Device identifier */
.word mfgstr /* Manufacturer string */
.word prodstr /* Product name */
.byte 0x02 /* Device base type code */
.byte 0x00 /* Device sub-type code */
.byte 0x00 /* Device interface type code */
.byte 0x54 /* Device indicator */
.word 0x0000 /* Boot connection vector */
.word 0x0000 /* Disconnect vector */
.word exec_vector /* Boot execution vector */
.word 0x0000 /* Reserved */
.word 0x0000 /* Static resource information vector*/
.equ pnpheader_len, . - pnpheader
.size pnpheader, . - pnpheader
mfgstr:
.asciz "http://etherboot.org"
.size mfgstr, . - mfgstr
prodstr:
.asciz "Etherboot"
.size prodstr, . - prodstr
undiheader:
.ascii "UNDI" /* Signature */
.byte undiheader_len /* Length of structure */
.byte 0 /* Checksum */
.byte 0 /* Structure revision */
.byte 0,1,2 /* PXE version: 2.1.0 */
.word undiloader /* Offset to loader routine */
.word _data16_size /* Stack segment size */
.word _data16_size /* Data segment size */
.word _text16_size /* Code segment size */
.equ undiheader_len, . - undiheader
.size undiheader, . - undiheader
/* Initialisation vector
*
* Determine whether or not this is a PnP system via a signature
* check. If it is PnP, return to the PnP BIOS indicating that we are
* a boot-capable device; the BIOS will call our boot execution vector
* if it wants to boot us. If it is not PnP, hook INT 19.
*/
init_vector:
pushw %si
cmpw $'$'+'P'*256, %es:0(%di)
jne notpnp
cmpw $'n'+'P'*256, %es:2(%di)
jne notpnp
ispnp:
movw $ispnp_message, %si
jmp 99f
notpnp:
pushw %ds
pushw $0
popw %ds
pushw %cs
pushw $exec_vector
popl ( 0x19 * 4 )
popw %ds
movw $notpnp_message, %si
99:
call print_message
movw $0x20, %ax
popw %si
lret
.size init_vector, . - init_vector
ispnp_message:
.asciz "Etherboot detected PnP BIOS\r\n"
.size ispnp_message, . - ispnp_message
notpnp_message:
.asciz "Etherboot detected non-PnP BIOS\r\n"
.size notpnp_message, . - notpnp_message
/* Boot execution vector
*
* Called by the PnP BIOS when it wants to boot us, or via the hooked
* INT 19 if we detected a non-PnP BIOS.
*/
exec_vector:
/* Obtain a reasonably-sized stack */
xorw %ax, %ax
movw %ax, %ss
movw $0x7c00, %sp
movw $exec_message, %si
call print_message
call install
/* Jump to .text16 segment */
pushw %ax
pushw $1f
lret
.section ".text16", "awx", @progbits
1:
pushl $main
pushw %cs
call prot_call
popl %eax /* discard */
/* Boot next device */
int $0x18
.previous
exec_message:
.asciz "Etherboot starting boot\r\n"
.size exec_message, . - exec_message
/* UNDI loader
*
* Called by an external program to load our PXE stack.
*/
undiloader:
.size undiloader, . - undiloader
/* Utility function: print string
*/
print_message:
pushw %ax
pushw %bx
pushw %bp
movw $0x0007, %bx
1: cs lodsb
testb %al, %al
je 2f
movb $0x0e, %ah /* write char, tty mode */
int $0x10
jmp 1b
2: popw %bp
popw %bx
popw %ax
ret
.size print_message, . - print_message