summaryrefslogblamecommitdiffstats
path: root/src/arch/i386/prefix/romprefix.S
blob: 52001699623edf0145cb9d56aaae7bc24ab04f17 (plain) (tree)
1
2
3
4
5
6
7
8







                                                                        


                  
                                           
        




                                                                      
                    
                          
                    











































                                                                               
 









                                                                 

                                                                













                                                                      
   


                                        
                      
                                        
                      


                                   
       
                   
                  
                   








                                    
            
                                          
 





                                                     
 









                                                                     
        

                                  
 
                       
 



                                    
                                     
                   




                                            
                   

                                  
 

                              

                 


                                             
 









                                                       
                   
                   
                   


                            
                  


                                                                  




                                              
/* 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

	/* Set up real-mode stack */
	movw	%bx, %ss
	movw	$_estack16, %sp

	/* 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