]>
Commit | Line | Data |
---|---|---|
49df18fa PA |
1 | /* -*- linux-c -*- ------------------------------------------------------- * |
2 | * | |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | |
4 | * Copyright 2007 rPath, Inc. - All Rights Reserved | |
d54ea252 | 5 | * Copyright 2009 Intel Corporation; author H. Peter Anvin |
49df18fa PA |
6 | * |
7 | * Original APM BIOS checking by Stephen Rothwell, May 1994 | |
8 | * (sfr@canb.auug.org.au) | |
9 | * | |
10 | * This file is part of the Linux kernel, and is made available under | |
11 | * the terms of the GNU General Public License version 2. | |
12 | * | |
13 | * ----------------------------------------------------------------------- */ | |
14 | ||
15 | /* | |
49df18fa PA |
16 | * Get APM BIOS information |
17 | */ | |
18 | ||
19 | #include "boot.h" | |
20 | ||
49df18fa PA |
21 | int query_apm_bios(void) |
22 | { | |
d54ea252 | 23 | struct biosregs ireg, oreg; |
49df18fa PA |
24 | |
25 | /* APM BIOS installation check */ | |
d54ea252 PA |
26 | initregs(&ireg); |
27 | ireg.ah = 0x53; | |
28 | intcall(0x15, &ireg, &oreg); | |
49df18fa | 29 | |
d54ea252 | 30 | if (oreg.flags & X86_EFLAGS_CF) |
49df18fa PA |
31 | return -1; /* No APM BIOS */ |
32 | ||
d54ea252 | 33 | if (oreg.bx != 0x504d) /* "PM" signature */ |
49df18fa PA |
34 | return -1; |
35 | ||
d54ea252 | 36 | if (!(oreg.cx & 0x02)) /* 32 bits supported? */ |
49df18fa PA |
37 | return -1; |
38 | ||
39 | /* Disconnect first, just in case */ | |
d54ea252 PA |
40 | ireg.al = 0x04; |
41 | intcall(0x15, &ireg, NULL); | |
49df18fa PA |
42 | |
43 | /* 32-bit connect */ | |
d54ea252 PA |
44 | ireg.al = 0x03; |
45 | intcall(0x15, &ireg, &oreg); | |
46 | ||
47 | boot_params.apm_bios_info.cseg = oreg.ax; | |
48 | boot_params.apm_bios_info.offset = oreg.ebx; | |
49 | boot_params.apm_bios_info.cseg_16 = oreg.cx; | |
50 | boot_params.apm_bios_info.dseg = oreg.dx; | |
51 | boot_params.apm_bios_info.cseg_len = oreg.si; | |
52 | boot_params.apm_bios_info.cseg_16_len = oreg.hsi; | |
53 | boot_params.apm_bios_info.dseg_len = oreg.di; | |
54 | ||
55 | if (oreg.flags & X86_EFLAGS_CF) | |
49df18fa PA |
56 | return -1; |
57 | ||
58 | /* Redo the installation check as the 32-bit connect; | |
59 | some BIOSes return different flags this way... */ | |
60 | ||
d54ea252 PA |
61 | ireg.al = 0x00; |
62 | intcall(0x15, &ireg, &oreg); | |
49df18fa | 63 | |
d54ea252 | 64 | if ((oreg.eflags & X86_EFLAGS_CF) || oreg.bx != 0x504d) { |
49df18fa | 65 | /* Failure with 32-bit connect, try to disconect and ignore */ |
d54ea252 PA |
66 | ireg.al = 0x04; |
67 | intcall(0x15, &ireg, NULL); | |
49df18fa PA |
68 | return -1; |
69 | } | |
70 | ||
d54ea252 PA |
71 | boot_params.apm_bios_info.version = oreg.ax; |
72 | boot_params.apm_bios_info.flags = oreg.cx; | |
49df18fa PA |
73 | return 0; |
74 | } | |
75 |