2007-07-11 23:18:43 +04:00
/* -*- linux-c -*- ------------------------------------------------------- *
*
* Copyright ( C ) 1991 , 1992 Linus Torvalds
* Copyright 2007 rPath , Inc . - All Rights Reserved
*
* 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 )
{
u16 ax , bx , cx , dx , di ;
u32 ebx , esi ;
u8 err ;
/* APM BIOS installation check */
ax = 0x5300 ;
bx = cx = 0 ;
asm volatile ( " pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0 "
: " =d " ( err ) , " +a " ( ax ) , " +b " ( bx ) , " +c " ( cx )
: : " esi " , " edi " ) ;
if ( err )
return - 1 ; /* No APM BIOS */
if ( bx ! = 0x504d ) /* "PM" signature */
return - 1 ;
2007-07-24 02:25:59 +04:00
if ( ! ( cx & 0x02 ) ) /* 32 bits supported? */
2007-07-11 23:18:43 +04:00
return - 1 ;
/* Disconnect first, just in case */
ax = 0x5304 ;
2007-07-24 02:37:14 +04:00
bx = 0 ;
2007-07-11 23:18:43 +04:00
asm volatile ( " pushl %%ebp ; int $0x15 ; popl %%ebp "
2007-07-24 02:37:14 +04:00
: " +a " ( ax ) , " +b " ( bx )
: : " ecx " , " edx " , " esi " , " edi " ) ;
2007-07-11 23:18:43 +04:00
/* Paranoia */
ebx = esi = 0 ;
cx = dx = di = 0 ;
/* 32-bit connect */
asm volatile ( " pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6 "
: " =a " ( ax ) , " +b " ( ebx ) , " +c " ( cx ) , " +d " ( dx ) ,
" +S " ( esi ) , " +D " ( di ) , " =m " ( err )
: " a " ( 0x5303 ) ) ;
boot_params . apm_bios_info . cseg = ax ;
boot_params . apm_bios_info . offset = ebx ;
boot_params . apm_bios_info . cseg_16 = cx ;
boot_params . apm_bios_info . dseg = dx ;
boot_params . apm_bios_info . cseg_len = ( u16 ) esi ;
boot_params . apm_bios_info . cseg_16_len = esi > > 16 ;
boot_params . apm_bios_info . dseg_len = di ;
if ( err )
return - 1 ;
/* Redo the installation check as the 32-bit connect;
some BIOSes return different flags this way . . . */
ax = 0x5300 ;
bx = cx = 0 ;
asm volatile ( " pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0 "
: " =d " ( err ) , " +a " ( ax ) , " +b " ( bx ) , " +c " ( cx )
: : " esi " , " edi " ) ;
if ( err | | bx ! = 0x504d ) {
/* Failure with 32-bit connect, try to disconect and ignore */
ax = 0x5304 ;
bx = 0 ;
asm volatile ( " pushl %%ebp ; int $0x15 ; popl %%ebp "
: " +a " ( ax ) , " +b " ( bx )
: : " ecx " , " edx " , " esi " , " edi " ) ;
return - 1 ;
}
boot_params . apm_bios_info . version = ax ;
boot_params . apm_bios_info . flags = cx ;
return 0 ;
}