1/*
2 *  GRUB  --  GRand Unified Bootloader
3 *  Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4 *
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20/* This is stolen from arch/i386/boot/setup.S in Linux 2.2.17 */
21/*
22!       setup.S         Copyright (C) 1991, 1992 Linus Torvalds
23*/
24
25ENTRY(get_apm_info)
26	pushl	%ebp
27	pushl	%ebx
28	pushl	%edi
29	pushl	%esi
30
31	call	EXT_C(prot_to_real)
32	.code16
33
34	/* APM BIOS installation check */
35	movw	$0x5300, %ax
36	xorw	%bx, %bx
37	int	$0x15
38	/* error -> no APM BIOS */
39	jc	done_apm_bios
40
41	/* check for "PM" signature */
42	cmpw	$0x504d, %bx
43	/* no signature -> no APM BIOS */
44	jne	done_apm_bios
45
46	/* Is 32 bit supported? */
47	andw	$0x0002, %cx
48	/* no ... */
49	je	done_apm_bios
50
51	/* Disconnect first just in case */
52	movw	$0x5304, %ax
53	xorw	%bx, %bx
54	/* ignore return code */
55	int	$0x15
56
57	/* 32 bit connect */
58	movw	$0x5303, %ax
59	xorl	%ebx, %ebx
60	/* paranoia */
61	xorw	%cx, %cx
62	xorw	%dx, %dx
63	xorl	%esi, %esi
64	xorw	%di, %di
65	int	$0x15
66	/* error */
67	jc	no_32_apm_bios
68
69	/* BIOS code segment */
70	movw	%ax, ABS(EXT_C(apm_bios_info)) + 2
71	/* BIOS entry point offset */
72	movl	%ebx, ABS(EXT_C(apm_bios_info)) + 4
73	/* BIOS 16 bit code segment */
74	movw	%cx, ABS(EXT_C(apm_bios_info)) + 8
75	/* BIOS data segment */
76	movw	%dx, ABS(EXT_C(apm_bios_info)) + 10
77	/* BIOS code segment length */
78	movl	%esi, ABS(EXT_C(apm_bios_info)) + 14
79	/* BIOS data segment length */
80	movw	%di, ABS(EXT_C(apm_bios_info)) + 18
81
82	/*
83	 * Redo the installation check as the 32 bit connect
84	 * modifies the flags returned on some BIOSs
85	 */
86
87	/* APM BIOS installation check */
88	movw	$0x5300, %ax
89	xorw	%bx, %bx
90	/* paranoia */
91	xorw	%cx, %cx
92	int     $0x15
93	/* error -> should not happen, tidy up */
94	jc	done_apm_bios
95
96	/* check for "PM" signature */
97	cmpw	$0x504d, %bx
98	/* no signature -> should not happen, tidy up */
99	jne	done_apm_bios
100
101	/* record the APM BIOS version */
102	movw	%ax, ABS(EXT_C(apm_bios_info))
103	/* and flags */
104	movw	%cx, ABS(EXT_C(apm_bios_info)) + 12
105	jmp	done_apm_bios
106
107no_32_apm_bios:
108	/* remove 32 bit support bit */
109	andw     $0xfffd, ABS(EXT_C(apm_bios_info)) + 12
110
111done_apm_bios:
112	/* Some paranoia here: Always Disconnect from APM */
113	movw	$0x5304, %ax
114	xorw	%bx, %bx
115	/* ignore return code */
116	int     $0x15
117
118	DATA32	call	EXT_C(real_to_prot)
119	.code32
120
121	popl	%esi
122	popl	%edi
123	popl	%ebx
124	popl	%ebp
125	ret
126