2007-07-11 23:18:43 +04:00
/* -*- linux-c -*- ------------------------------------------------------- *
*
* Copyright ( C ) 1991 , 1992 Linus Torvalds
* Copyright 2007 rPath , Inc . - All Rights Reserved
2009-04-02 05:14:26 +04:00
* Copyright 2009 Intel Corporation ; author H . Peter Anvin
2007-07-11 23:18:43 +04:00
*
* Original APM BIOS checking by Stephen Rothwell , May 1994
* ( sfr @ canb . auug . org . au )
*
* This file is part of the Linux kernel , and is made available under
* the terms of the GNU General Public License version 2.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Get APM BIOS information
*/
# include "boot.h"
int query_apm_bios ( void )
{
2009-04-02 05:14:26 +04:00
struct biosregs ireg , oreg ;
2007-07-11 23:18:43 +04:00
/* APM BIOS installation check */
2009-04-02 05:14:26 +04:00
initregs ( & ireg ) ;
ireg . ah = 0x53 ;
intcall ( 0x15 , & ireg , & oreg ) ;
2007-07-11 23:18:43 +04:00
2009-04-02 05:14:26 +04:00
if ( oreg . flags & X86_EFLAGS_CF )
2007-07-11 23:18:43 +04:00
return - 1 ; /* No APM BIOS */
2009-04-02 05:14:26 +04:00
if ( oreg . bx ! = 0x504d ) /* "PM" signature */
2007-07-11 23:18:43 +04:00
return - 1 ;
2009-04-02 05:14:26 +04:00
if ( ! ( oreg . cx & 0x02 ) ) /* 32 bits supported? */
2007-07-11 23:18:43 +04:00
return - 1 ;
/* Disconnect first, just in case */
2009-04-02 05:14:26 +04:00
ireg . al = 0x04 ;
intcall ( 0x15 , & ireg , NULL ) ;
2007-07-11 23:18:43 +04:00
/* 32-bit connect */
2009-04-02 05:14:26 +04:00
ireg . al = 0x03 ;
intcall ( 0x15 , & ireg , & oreg ) ;
boot_params . apm_bios_info . cseg = oreg . ax ;
boot_params . apm_bios_info . offset = oreg . ebx ;
boot_params . apm_bios_info . cseg_16 = oreg . cx ;
boot_params . apm_bios_info . dseg = oreg . dx ;
boot_params . apm_bios_info . cseg_len = oreg . si ;
boot_params . apm_bios_info . cseg_16_len = oreg . hsi ;
boot_params . apm_bios_info . dseg_len = oreg . di ;
if ( oreg . flags & X86_EFLAGS_CF )
2007-07-11 23:18:43 +04:00
return - 1 ;
/* Redo the installation check as the 32-bit connect;
some BIOSes return different flags this way . . . */
2009-04-02 05:14:26 +04:00
ireg . al = 0x00 ;
intcall ( 0x15 , & ireg , & oreg ) ;
2007-07-11 23:18:43 +04:00
2009-04-02 05:14:26 +04:00
if ( ( oreg . eflags & X86_EFLAGS_CF ) | | oreg . bx ! = 0x504d ) {
2007-07-11 23:18:43 +04:00
/* Failure with 32-bit connect, try to disconect and ignore */
2009-04-02 05:14:26 +04:00
ireg . al = 0x04 ;
intcall ( 0x15 , & ireg , NULL ) ;
2007-07-11 23:18:43 +04:00
return - 1 ;
}
2009-04-02 05:14:26 +04:00
boot_params . apm_bios_info . version = oreg . ax ;
boot_params . apm_bios_info . flags = oreg . cx ;
2007-07-11 23:18:43 +04:00
return 0 ;
}