pcbios.s

来自「linux下从网卡远程启动」· S 代码 · 共 636 行

S
636
字号
#ifdef PCBIOS#ifdef GAS291#define DATA32 data32;#else#define DATA32 data32#endif	.section ".text"	.section ".text16", "ax", @progbits	.previous	.code32	.arch i386#if defined(CONFIG_TSC_CURRTICKS)#undef CONFIG_BIOS_CURRTICKS#else#define CONFIG_BIOS_CURRTICKS 1#endif#if defined(CONFIG_BIOS_CURRTICKS)/**************************************************************************CURRTICKS - Get TimeUse direct memory access to BIOS variables, longword 0040:006C (tickstoday) and byte 0040:0070 (midnight crossover flag) instead of callingtimeofday BIOS interrupt.**************************************************************************/	.globl	currtickscurrticks:	pushl	%ebp	pushl	%ebx	pushl	%esi	pushl	%edi#ifdef FREEBSD_PXEEMU	cmpb	$0, pxeemu_nbp_active	jne	currticks_postswitch#endif	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	ret20:	.code32	.previous#ifdef FREEBSD_PXEEMUcurrticks_postswitch:#endif	movl	virt_offset, %ebp	negl	%ebp			/* Physical address 0 */	movl	0x46C(%ebp), %eax	movb	0x470(%ebp), %bl	cmpb	$0, %bl	je	notmidnite	movb	$0, 0x470(%ebp)		/* clear the flag */	addl	$0x1800b0,days		/* 0x1800b0 ticks per day */notmidnite:	addl	days,%eax	popl	%edi	popl	%esi	popl	%ebx	popl	%ebp	ret#endif	/* CONFIG_BIOS_CURRTICKS *//**************************************************************************CONSOLE_PUTC - Print a character on console**************************************************************************/	.globl	console_putcconsole_putc:#ifdef FREEBSD_PXEEMU	.globl	pxeemu_console_putc	cmpb	$0, pxeemu_nbp_active	je	console_putc_switch	movb	$0x0e, %ah	movb	%cl, %al	pushl	%eax	call	pxeemu_console_putc	addl	$4, %esp	retconsole_putc_switch:#endif	pushl	%ebp	movl	%esp,%ebp	pushl	%ebx	pushl	%esi	pushl	%edi	movb	8(%ebp),%cl	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	movl	$1,%ebx	movb	$0x0e,%ah	movb	%cl,%al	int	$0x10	ret20:	.code32	.previous#ifdef FREEBSD_PXEEMUconsole_putc_exit:#endif	popl	%edi	popl	%esi	popl	%ebx	popl	%ebp	ret/**************************************************************************CONSOLE_GETC - Get a character from console**************************************************************************/	.globl	console_getcconsole_getc:	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16		movb	$0x0,%ah	int	$0x16	movb	%al,%bl	ret20:	.code32	.previous	xor	%eax,%eax	movzbl	%bl,%eax	popl	%edi	popl	%esi	popl	%ebx	ret/**************************************************************************CONSOLE_ISCHAR - Check for keyboard interrupt**************************************************************************/	.globl	console_ischarconsole_ischar:	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16		xorw	%bx,%bx	movb	$0x1,%ah	int	$0x16	jz	2f	movb	%al,%bl2:	ret20:	.code32	.previous	movzbl	%bl,%eax	popl	%edi	popl	%esi	popl	%ebx	ret/**************************************************************************GETSHIFT - Get keyboard shift state**************************************************************************/	.globl	getshiftgetshift:	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	$ 10f	pushl	$ 20f - 10f	.section ".text16"10:	.code16		movb	$2,%ah	int	$0x16	andb	$0xdf,%al	movw	%ax,%bx	ret20:	.code32	.previous	movzbl	%bl,%eax	popl	%edi	popl	%esi	popl	%ebx	ret/**************************************************************************INT15 - Call Interrupt 0x15**************************************************************************/	.globl	int15int15:	pushl	%ebp	movl	%esp,%ebp	pushl	%ebx	pushl	%esi	pushl	%edi	movl	8(%ebp),%ecx	/* _real_call destroys %eax */	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	movw	%cx,%ax	stc			/* in case function not supported */	int	$0x15	jc	int15status	movb	$0,%ahint15status:	movb	%ah,%bl		/* _real_call destroys %eax */	ret20:	.code32	.previous	movzbl	%bl,%eax	popl	%edi	popl	%esi	popl	%ebx	popl	%ebp	ret#ifdef	POWERSAVE/**************************************************************************CPU_NAP - Save power by halting the CPU until the next interrupt**************************************************************************/	.globl	cpu_napcpu_nap:	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	hlt	ret20:	.code32	.previous	popl	%edi	popl	%esi	popl	%ebx	ret#endif	/* POWERSAVE *//**************************************************************************E820_MEMSIZE - Get a listing of memory regions**************************************************************************/	.globl meme820#define SMAP	0x534d4150meme820:	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx	pushl	%esi	pushl	%edi	movl	8(%ebp), %edi	/* Address to return e820 structures at */	movl	12(%ebp), %esi	/* Maximum number of e820 structurs to return */	pushl	%esi	/* Multiply %esi by 20 */	movl	%esi, %eax	movl	%esi, %ebx	shll	$2, %eax	shll	$4, %ebx	addl	%eax, %ebx	pushl	%ebx		pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	/* Allocate space on the stack for the maximum # of e820 structures */	popw	%ax	subw	%bx, %sp	movw	%sp, %di		/* point to the e820 array list */	pushw	%ax	xorl	%ebx, %ebx 		/* continuation pointer */jmpe820:	movl	$0xe820, %eax		/* e820, upper word zeroed */	movl	$SMAP, %edx		/* ascii `SMAP' */	movl	$20, %ecx		/* size of e820rec */	pushw	%ss	popw	%es	/* %di was setup earlier */	int	$0x15			/* Make the call */	jc	bail820				cmpl	$SMAP, %eax		/* check the return is `SMAP' */	jne	bail820good820:		/* If this is useable memory, we save it by simply advancing %di by	 * sizeof(e820rec)	 */	decl	%esi			/* up to 32 entries */	testl	%esi,%esi	jz	bail820	addw	$20, %diagain820:	cmpl	$0, %ebx		/* check to see if %ebx is set to EOF */	jne	jmpe820bail820:	ret20:	.code32	.previous	popl	%ecx		/* Get the maximum return size */	pushl	%esi		/* Save the structure count */	/* Copy the structures to the return buffer */	movl	%eax, %esi	movl	8(%ebp), %edi	rep	movsb	popl	%esi	popl	%eax	subl	%esi, %eax	/* Compute how many structure we read */	/* Restore everything else */		popl	%edi	popl	%esi	popl	%ebx	movl	%ebp, %esp	popl	%ebp	ret	/**************************************************************************MEMSIZE - Determine size of extended memory**************************************************************************/	.globl	memsizememsize:	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	stc					# fix to work around buggy	xorw	%cx,%cx				# BIOSes which dont clear/set	xorw	%dx,%dx				# carry on pass/error of						# e801h memory size call						# or merely pass cx,dx though						# without changing them.	movw	$0xe801,%ax	int	$0x15	jc	3f	cmpw	$0,%cx				# Kludge to handle BIOSes	jne	1f				# which report their extended	cmpw	$0,%dx				# memory in AX/BX rather than	je	2f				# CX/DX.  The spec I have read1:	movw	%cx,%ax				# seems to indicate AX/BX 	movw	%dx,%bx				# are more reasonable anyway...2:	andl	$0xffff,%eax	andl	$0xffff,%ebx	shll	$6,%ebx	addl	%ebx,%eax	jmp	4f3:	movw	$0x8800,%ax	int	$0x15	andl	$0xffff,%eax4:	movl	%eax,%esi	ret20:	.code32	.previous	movl	%esi,%eax	popl	%edi	popl	%esi	popl	%ebx	ret/**************************************************************************BASEMEMSIZE - Get size of the conventional (base) memory**************************************************************************/	.globl	basememsizebasememsize:	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	int	$0x12	movw	%ax,%cx	ret20:	.code32	.previous	movw	%cx,%ax	popl	%edi	popl	%esi	popl	%ebx	ret/**************************************************************************DISK_INIT - Initialize the disk system**************************************************************************/#ifdef	CAN_BOOT_DISK	.globl	disk_initdisk_init:	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	xorw	%ax,%ax	movb	$0x80,%dl	int	$0x13	ret20:	.code32	.previous	popl	%edi	popl	%esi	popl	%ebx	ret#endif/**************************************************************************DISK_READ - Read a sector from disk**************************************************************************/#ifdef	CAN_BOOT_DISK	.globl	pcbios_disk_readpcbios_disk_read:	pushl	%ebp	movl	%esp,%ebp	pushl	%ebx	pushl	%esi	pushl	%edi	movb	8(%ebp),%dl	/* drive number */	movb	16(%ebp),%dh	/* head number */	movb	12(%ebp),%ch	/* cylinder number */	movb	13(%ebp),%cl	/* cylinder number */	shl	$6,%cl	orb	20(%ebp),%cl	/* sector number */	movw	26(%ebp),%si	rorw	$4,%si	movw	24(%ebp),%bx	/* buffer */	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	movw	$0x0201,%ax	movw	%si,%es	int	$0x13	jc	1f	xorw	%ax,%ax1:	movw	%ax,%bx	ret20:	.code32	.previous	movzwl	%bx,%eax	popl	%edi	popl	%esi	popl	%ebx	popl	%ebp	ret#endif#ifdef FREEBSD_PXEEMU.globl initsp.globl pxeemu_nbp_activepxeemu_nbp_active: 	.byte	0#endifdays:	.long	0#ifndef CONFIG_PCI_DIRECT	.globl bios32_callbios32_call:	pushl	%ebp	pushl	%eax	call	_virt_to_phys	pushl	%ebp	movl	8(%esp), %ebp	movl	4(%esp), %eax	pushl	%cs	call	%esi	cli	cld	movl	%ebp, 8(%esp)	movl	%eax, 4(%esp)	popl	%ebp	pushfl	call	_phys_to_virt	popfl	popl	%eax	popl	%ebp	ret#endif /* CONFIG_PCI_DIRECT *//**************************************************************************UNDI_CALL - wrapper around real-mode UNDI API calls**************************************************************************/	.globl	__undi_call__undi_call:	pushl	%ebp	movl	%esp,%ebp	pushl	%esi	pushl	%edi	pushl	%ebx		movw	8(%ebp),%cx	/* Seg:off addr of undi_call_info_t struct */	movw	12(%ebp),%dx	/* Pass to 16-bit code in %cx:%dx */	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16	movw	%cx,%es		/* Seg:off addr of undi_call_info_t struct */	movw	%dx,%bx		/* into %es:%bx */	movw	%es:8(%bx),%ax	/* Transfer contents of undi_call_info_t */	pushw	%ax		/* structure to the real-mode stack */	movw	%es:6(%bx),%ax	pushw	%ax	movw	%es:4(%bx),%ax	pushw	%ax		lcall	*%es:0(%bx)	/* Do the UNDI call */	cld			/* Don't know whether or not we need this */				/* but pxelinux includes it for some reason, */				/* so we put it in just in case. */	popw	%cx		/* Tidy up the stack */	popw	%cx	popw	%cx	movw	%ax,%cx		/* Return %ax via %cx */	ret	20:	.code32	.previous	xorl	%eax,%eax	/* %ax is returned via %cx */	movw	%cx,%ax	popl	%ebx	popl	%edi	popl	%esi	popl	%ebp	ret/**************************************************************************TRIVIAL_IRQ_HANDLER - simple IRQ handler that just increments a counter**************************************************************************/	.globl	_trivial_irq_handler_start	.globl	_trivial_irq_handler	.globl	_trivial_irq_trigger_count	.globl	_trivial_irq_chain_to	.globl	_trivial_irq_chain	.globl	_trivial_irq_handler_end	.code16_trivial_irq_handler_start:_trivial_irq_handler:	pushw	%bx	call	1f		/* Position-independent access to */1:	popw	%bx		/* irq_triggered.		  */	incw	%cs:(_trivial_irq_trigger_count-1b)(%bx)	popw	%bx	iret_trivial_irq_trigger_count:	.word	0_trivial_irq_chain_to:	.long	0_trivial_irq_chain:	.byte	0_trivial_irq_handler_end:	.code32/**************************************************************************FAKE_IRQ - fake a hardware IRQ**************************************************************************/	.globl	fake_irqfake_irq:	pushl	%ebp	movl	%esp,%ebp	pushl	%esi	pushl	%edi	pushl	%ebx	movb	8(%ebp),%cl	/* Convert IRQ number to INT number: */	subb	$0x08,%cl	/* Invert bit 3, set bits 4-7 iff irq < 8*/	xorb	$0x70,%cl	/* Invert bits 4-6 */	andb	$0x7f,%cl	/* Clear bit 7 */	movb	%cl,fake_irq_int_instruction+1 /* Store in int instruction */	pushl	$ 10f	pushl	$ 20f - 10f	call	_real_call	.section ".text16"10:	.code16fake_irq_int_instruction:	int	$0x00		/* Int no. gets replaced */	ret20:	.code32	.previous	popl	%ebx	popl	%edi	popl	%esi	popl	%ebp	ret		#endif /* PCBIOS */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?