1 // Basic support for apmbios callbacks.
3 // Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2005 Struan Bartlett
5 // Copyright (C) 2004 Fabrice Bellard
7 // This file may be distributed under the terms of the GNU LGPLv3 license.
9 #include "biosvar.h" // GET_GLOBAL
10 #include "bregs.h" // struct bregs
11 #include "config.h" // CONFIG_*
12 #include "output.h" // dprintf
13 #include "stacks.h" // yield_toirq
14 #include "util.h" // apm_shutdown
15 #include "x86.h" // outb
17 // APM installation check
19 handle_155300(struct bregs *regs)
21 regs->ah = 1; // APM major version
22 regs->al = 2; // APM minor version
25 // bit 0 : 16 bit interface supported
26 // bit 1 : 32 bit interface supported
31 // APM real mode interface connect
33 handle_155301(struct bregs *regs)
38 // APM 16 bit protected mode interface connect
40 handle_155302(struct bregs *regs)
42 extern void entry_apm16(void);
43 regs->bx = (u32)entry_apm16;
44 regs->ax = SEG_BIOS; // 16 bit code segment base
45 regs->si = 0xfff0; // 16 bit code segment size
46 regs->cx = SEG_BIOS; // data segment address
47 regs->di = 0xfff0; // data segment length
51 // APM 32 bit protected mode interface connect
53 handle_155303(struct bregs *regs)
55 extern void entry_apm32(void);
56 regs->ax = SEG_BIOS; // 32 bit code segment base
57 regs->ebx = (u32)entry_apm32;
58 regs->cx = SEG_BIOS; // 16 bit code segment base
59 // 32 bit code segment size (low 16 bits)
60 // 16 bit code segment size (high 16 bits)
61 regs->esi = 0xfff0fff0;
62 regs->dx = SEG_BIOS; // data segment address
63 regs->di = 0xfff0; // data segment length
67 // APM interface disconnect
69 handle_155304(struct bregs *regs)
76 handle_155305(struct bregs *regs)
84 handle_155306(struct bregs *regs)
92 u16 pm1a_cnt = GET_GLOBAL(acpi_pm1a_cnt);
94 outw(0x2000, pm1a_cnt);
101 // APM Set Power State
103 handle_155307(struct bregs *regs)
111 dprintf(1, "APM standby request\n");
114 dprintf(1, "APM suspend request\n");
124 handle_155308(struct bregs *regs)
131 handle_15530a(struct bregs *regs)
133 regs->bh = 0x01; // on line
134 regs->bl = 0xff; // unknown battery status
135 regs->ch = 0x80; // no system battery
136 regs->cl = 0xff; // unknown remaining time
137 regs->dx = 0xffff; // unknown remaining time
138 regs->si = 0x00; // zero battery
142 #define RET_ENOEVENT 0x80
146 handle_15530b(struct bregs *regs)
148 set_code_invalid_silent(regs, RET_ENOEVENT);
151 // APM Driver Version
153 handle_15530e(struct bregs *regs)
160 // APM Engage / Disengage
162 handle_15530f(struct bregs *regs)
167 // APM Get Capabilities
169 handle_155310(struct bregs *regs)
177 handle_1553XX(struct bregs *regs)
179 set_unimplemented(regs);
183 handle_1553(struct bregs *regs)
185 if (! CONFIG_APMBIOS) {
186 set_code_invalid(regs, RET_EUNSUPPORTED);
192 case 0x00: handle_155300(regs); break;
193 case 0x01: handle_155301(regs); break;
194 case 0x02: handle_155302(regs); break;
195 case 0x03: handle_155303(regs); break;
196 case 0x04: handle_155304(regs); break;
197 case 0x05: handle_155305(regs); break;
198 case 0x06: handle_155306(regs); break;
199 case 0x07: handle_155307(regs); break;
200 case 0x08: handle_155308(regs); break;
201 case 0x0a: handle_15530a(regs); break;
202 case 0x0b: handle_15530b(regs); break;
203 case 0x0e: handle_15530e(regs); break;
204 case 0x0f: handle_15530f(regs); break;
205 case 0x10: handle_155310(regs); break;
206 default: handle_1553XX(regs); break;
210 void VISIBLE16 VISIBLE32SEG
211 handle_apm(struct bregs *regs)
213 debug_enter(regs, DEBUG_HDL_apm);