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 "farptr.h" // GET_VAR
10 #include "bregs.h" // struct bregs
11 #include "ioport.h" // outb
12 #include "util.h" // wait_irq
13 #include "config.h" // CONFIG_*
14 #include "biosvar.h" // GET_GLOBAL
17 out_str(const char *str_cs)
19 if (CONFIG_COREBOOT) {
20 dprintf(1, "APM request '%s'\n", str_cs);
26 u8 c = GET_GLOBAL(*s);
29 outb(c, PORT_BIOS_APM);
34 // APM installation check
36 handle_155300(struct bregs *regs)
38 regs->ah = 1; // APM major version
39 regs->al = 2; // APM minor version
42 // bit 0 : 16 bit interface supported
43 // bit 1 : 32 bit interface supported
48 // APM real mode interface connect
50 handle_155301(struct bregs *regs)
55 // Assembler entry points defined in romlayout.S
56 extern void entry_apm16(void);
57 extern void entry_apm32(void);
59 // APM 16 bit protected mode interface connect
61 handle_155302(struct bregs *regs)
63 regs->bx = (u32)entry_apm16;
64 regs->ax = SEG_BIOS; // 16 bit code segment base
65 regs->si = 0xfff0; // 16 bit code segment size
66 regs->cx = SEG_BIOS; // data segment address
67 regs->di = 0xfff0; // data segment length
71 // APM 32 bit protected mode interface connect
73 handle_155303(struct bregs *regs)
75 regs->ax = SEG_BIOS; // 32 bit code segment base
76 regs->ebx = (u32)entry_apm32;
77 regs->cx = SEG_BIOS; // 16 bit code segment base
78 // 32 bit code segment size (low 16 bits)
79 // 16 bit code segment size (high 16 bits)
80 regs->esi = 0xfff0fff0;
81 regs->dx = SEG_BIOS; // data segment address
82 regs->di = 0xfff0; // data segment length
86 // APM interface disconnect
88 handle_155304(struct bregs *regs)
95 handle_155305(struct bregs *regs)
103 handle_155306(struct bregs *regs)
117 // APM Set Power State
119 handle_155307(struct bregs *regs)
140 handle_155308(struct bregs *regs)
147 handle_15530a(struct bregs *regs)
149 regs->bh = 0x01; // on line
150 regs->bl = 0xff; // unknown battery status
151 regs->ch = 0x80; // no system battery
152 regs->cl = 0xff; // unknown remaining time
153 regs->dx = 0xffff; // unknown remaining time
154 regs->si = 0x00; // zero battery
158 #define RET_ENOEVENT 0x80
162 handle_15530b(struct bregs *regs)
164 set_code_invalid_silent(regs, RET_ENOEVENT);
167 // APM Driver Version
169 handle_15530e(struct bregs *regs)
176 // APM Engage / Disengage
178 handle_15530f(struct bregs *regs)
183 // APM Get Capabilities
185 handle_155310(struct bregs *regs)
193 handle_1553XX(struct bregs *regs)
195 set_unimplemented(regs);
199 handle_1553(struct bregs *regs)
201 if (! CONFIG_APMBIOS) {
202 set_code_invalid(regs, RET_EUNSUPPORTED);
208 case 0x00: handle_155300(regs); break;
209 case 0x01: handle_155301(regs); break;
210 case 0x02: handle_155302(regs); break;
211 case 0x03: handle_155303(regs); break;
212 case 0x04: handle_155304(regs); break;
213 case 0x05: handle_155305(regs); break;
214 case 0x06: handle_155306(regs); break;
215 case 0x07: handle_155307(regs); break;
216 case 0x08: handle_155308(regs); break;
217 case 0x0a: handle_15530a(regs); break;
218 case 0x0b: handle_15530b(regs); break;
219 case 0x0e: handle_15530e(regs); break;
220 case 0x0f: handle_15530f(regs); break;
221 case 0x10: handle_155310(regs); break;
222 default: handle_1553XX(regs); break;
227 handle_apm16(struct bregs *regs)
229 debug_enter(regs, DEBUG_HDL_apm);
234 handle_apm32(struct bregs *regs)
236 debug_enter(regs, DEBUG_HDL_apm);