| /* -*- linux-c -*- ------------------------------------------------------- * | |
| * | |
| * Copyright (C) 1991, 1992 Linus Torvalds | |
| * Copyright 2007 rPath, Inc. - All Rights Reserved | |
| * Copyright 2009 Intel Corporation; author H. Peter Anvin | |
| * | |
| * 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) | |
| { | |
| struct biosregs ireg, oreg; | |
| /* APM BIOS installation check */ | |
| initregs(&ireg); | |
| ireg.ah = 0x53; | |
| intcall(0x15, &ireg, &oreg); | |
| if (oreg.flags & X86_EFLAGS_CF) | |
| return -1; /* No APM BIOS */ | |
| if (oreg.bx != 0x504d) /* "PM" signature */ | |
| return -1; | |
| if (!(oreg.cx & 0x02)) /* 32 bits supported? */ | |
| return -1; | |
| /* Disconnect first, just in case */ | |
| ireg.al = 0x04; | |
| intcall(0x15, &ireg, NULL); | |
| /* 32-bit connect */ | |
| 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) | |
| return -1; | |
| /* Redo the installation check as the 32-bit connect; | |
| some BIOSes return different flags this way... */ | |
| ireg.al = 0x00; | |
| intcall(0x15, &ireg, &oreg); | |
| if ((oreg.eflags & X86_EFLAGS_CF) || oreg.bx != 0x504d) { | |
| /* Failure with 32-bit connect, try to disconect and ignore */ | |
| ireg.al = 0x04; | |
| intcall(0x15, &ireg, NULL); | |
| return -1; | |
| } | |
| boot_params.apm_bios_info.version = oreg.ax; | |
| boot_params.apm_bios_info.flags = oreg.cx; | |
| return 0; | |
| } | |