1 /* -*- linux-c -*- ------------------------------------------------------- * 2 * 3 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright 2007 rPath, Inc. - All Rights Reserved 5 * 6 * Original APM BIOS checking by Stephen Rothwell, May 1994 7 * (sfr@canb.auug.org.au) 8 * 9 * This file is part of the Linux kernel, and is made available under 10 * the terms of the GNU General Public License version 2. 11 * 12 * ----------------------------------------------------------------------- */ 13 14 /* 15 * arch/i386/boot/apm.c 16 * 17 * Get APM BIOS information 18 */ 19 20 #include "boot.h" 21 22 int query_apm_bios(void) 23 { 24 u16 ax, bx, cx, dx, di; 25 u32 ebx, esi; 26 u8 err; 27 28 /* APM BIOS installation check */ 29 ax = 0x5300; 30 bx = cx = 0; 31 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0" 32 : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx) 33 : : "esi", "edi"); 34 35 if (err) 36 return -1; /* No APM BIOS */ 37 38 if (bx != 0x504d) /* "PM" signature */ 39 return -1; 40 41 if (!(cx & 0x02)) /* 32 bits supported? */ 42 return -1; 43 44 /* Disconnect first, just in case */ 45 ax = 0x5304; 46 bx = 0; 47 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp" 48 : "+a" (ax), "+b" (bx) 49 : : "ecx", "edx", "esi", "edi"); 50 51 /* Paranoia */ 52 ebx = esi = 0; 53 cx = dx = di = 0; 54 55 /* 32-bit connect */ 56 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6" 57 : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx), 58 "+S" (esi), "+D" (di), "=m" (err) 59 : "a" (0x5303)); 60 61 boot_params.apm_bios_info.cseg = ax; 62 boot_params.apm_bios_info.offset = ebx; 63 boot_params.apm_bios_info.cseg_16 = cx; 64 boot_params.apm_bios_info.dseg = dx; 65 boot_params.apm_bios_info.cseg_len = (u16)esi; 66 boot_params.apm_bios_info.cseg_16_len = esi >> 16; 67 boot_params.apm_bios_info.dseg_len = di; 68 69 if (err) 70 return -1; 71 72 /* Redo the installation check as the 32-bit connect; 73 some BIOSes return different flags this way... */ 74 75 ax = 0x5300; 76 bx = cx = 0; 77 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0" 78 : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx) 79 : : "esi", "edi"); 80 81 if (err || bx != 0x504d) { 82 /* Failure with 32-bit connect, try to disconect and ignore */ 83 ax = 0x5304; 84 bx = 0; 85 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp" 86 : "+a" (ax), "+b" (bx) 87 : : "ecx", "edx", "esi", "edi"); 88 return -1; 89 } 90 91 boot_params.apm_bios_info.version = ax; 92 boot_params.apm_bios_info.flags = cx; 93 return 0; 94 } 95 96