mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-15 07:41:45 +00:00
ef37f78cbe
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.
186 lines
4.6 KiB
ArmAsm
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
|