|  | /* | 
|  | *  GRUB  --  GRand Unified Bootloader | 
|  | *  Copyright (C) 2000, 2001 Free Software Foundation, Inc. | 
|  | * | 
|  | *  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 | 
|  | *  (at your option) 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., 675 Mass Ave, Cambridge, MA 02139, USA. | 
|  | */ | 
|  |  | 
|  | /* This is stolen from arch/i386/boot/setup.S in Linux 2.2.17 */ | 
|  | /* | 
|  | !       setup.S         Copyright (C) 1991, 1992 Linus Torvalds | 
|  | */ | 
|  |  | 
|  | ENTRY(get_apm_info) | 
|  | pushl	%ebp | 
|  | pushl	%ebx | 
|  | pushl	%edi | 
|  | pushl	%esi | 
|  |  | 
|  | call	EXT_C(prot_to_real) | 
|  | .code16 | 
|  |  | 
|  | /* APM BIOS installation check */ | 
|  | movw	$0x5300, %ax | 
|  | xorw	%bx, %bx | 
|  | int	$0x15 | 
|  | /* error -> no APM BIOS */ | 
|  | jc	done_apm_bios | 
|  |  | 
|  | /* check for "PM" signature */ | 
|  | cmpw	$0x504d, %bx | 
|  | /* no signature -> no APM BIOS */ | 
|  | jne	done_apm_bios | 
|  |  | 
|  | /* Is 32 bit supported? */ | 
|  | andw	$0x0002, %cx | 
|  | /* no ... */ | 
|  | je	done_apm_bios | 
|  |  | 
|  | /* Disconnect first just in case */ | 
|  | movw	$0x5304, %ax | 
|  | xorw	%bx, %bx | 
|  | /* ignore return code */ | 
|  | int	$0x15 | 
|  |  | 
|  | /* 32 bit connect */ | 
|  | movw	$0x5303, %ax | 
|  | xorl	%ebx, %ebx | 
|  | /* paranoia */ | 
|  | xorw	%cx, %cx | 
|  | xorw	%dx, %dx | 
|  | xorl	%esi, %esi | 
|  | xorw	%di, %di | 
|  | int	$0x15 | 
|  | /* error */ | 
|  | jc	no_32_apm_bios | 
|  |  | 
|  | /* BIOS code segment */ | 
|  | movw	%ax, ABS(EXT_C(apm_bios_info)) + 2 | 
|  | /* BIOS entry point offset */ | 
|  | movl	%ebx, ABS(EXT_C(apm_bios_info)) + 4 | 
|  | /* BIOS 16 bit code segment */ | 
|  | movw	%cx, ABS(EXT_C(apm_bios_info)) + 8 | 
|  | /* BIOS data segment */ | 
|  | movw	%dx, ABS(EXT_C(apm_bios_info)) + 10 | 
|  | /* BIOS code segment length */ | 
|  | movl	%esi, ABS(EXT_C(apm_bios_info)) + 14 | 
|  | /* BIOS data segment length */ | 
|  | movw	%di, ABS(EXT_C(apm_bios_info)) + 18 | 
|  |  | 
|  | /* | 
|  | * Redo the installation check as the 32 bit connect | 
|  | * modifies the flags returned on some BIOSs | 
|  | */ | 
|  |  | 
|  | /* APM BIOS installation check */ | 
|  | movw	$0x5300, %ax | 
|  | xorw	%bx, %bx | 
|  | /* paranoia */ | 
|  | xorw	%cx, %cx | 
|  | int     $0x15 | 
|  | /* error -> should not happen, tidy up */ | 
|  | jc	done_apm_bios | 
|  |  | 
|  | /* check for "PM" signature */ | 
|  | cmpw	$0x504d, %bx | 
|  | /* no signature -> should not happen, tidy up */ | 
|  | jne	done_apm_bios | 
|  |  | 
|  | /* record the APM BIOS version */ | 
|  | movw	%ax, ABS(EXT_C(apm_bios_info)) | 
|  | /* and flags */ | 
|  | movw	%cx, ABS(EXT_C(apm_bios_info)) + 12 | 
|  | jmp	done_apm_bios | 
|  |  | 
|  | no_32_apm_bios: | 
|  | /* remove 32 bit support bit */ | 
|  | andw     $0xfffd, ABS(EXT_C(apm_bios_info)) + 12 | 
|  |  | 
|  | done_apm_bios: | 
|  | /* Some paranoia here: Always Disconnect from APM */ | 
|  | movw	$0x5304, %ax | 
|  | xorw	%bx, %bx | 
|  | /* ignore return code */ | 
|  | int     $0x15 | 
|  |  | 
|  | DATA32	call	EXT_C(real_to_prot) | 
|  | .code32 | 
|  |  | 
|  | popl	%esi | 
|  | popl	%edi | 
|  | popl	%ebx | 
|  | popl	%ebp | 
|  | ret |