X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fapm.c;h=2029ae2487519d68ae4e1d4c44bc4c929a008cf5;hb=87b533bf71bb41e32319db0ed8f167f50171afc5;hp=9b6d1e3830a1644d4197a1172dd12fcacfcb8702;hpb=95b2f78f97a83787c5f669f349b0ea4f682d2674;p=seabios.git diff --git a/src/apm.c b/src/apm.c index 9b6d1e3..2029ae2 100644 --- a/src/apm.c +++ b/src/apm.c @@ -4,22 +4,29 @@ // Copyright (C) 2005 Struan Bartlett // Copyright (C) 2004 Fabrice Bellard // -// This file may be distributed under the terms of the GNU GPLv3 license. +// This file may be distributed under the terms of the GNU LGPLv3 license. #include "farptr.h" // GET_VAR -#include "biosvar.h" // struct bregs +#include "bregs.h" // struct bregs #include "ioport.h" // outb -#include "util.h" // irq_enable +#include "util.h" // wait_irq +#include "config.h" // CONFIG_* +#include "biosvar.h" // GET_GLOBAL static void out_str(const char *str_cs) { + if (CONFIG_COREBOOT) { + dprintf(1, "APM request '%s'\n", str_cs); + return; + } + u8 *s = (u8*)str_cs; for (;;) { - u8 c = GET_VAR(CS, *s); + u8 c = GET_GLOBAL(*s); if (!c) break; - outb(c, 0x8900); + outb(c, PORT_BIOS_APM); s++; } } @@ -35,57 +42,76 @@ handle_155300(struct bregs *regs) // bit 0 : 16 bit interface supported // bit 1 : 32 bit interface supported regs->cx = 0x03; - set_cf(regs, 0); + set_success(regs); } // APM real mode interface connect static void handle_155301(struct bregs *regs) { - set_cf(regs, 0); + set_success(regs); } +// Assembler entry points defined in romlayout.S +extern void apm16protected_entry(void); +extern void apm32protected_entry(void); + // APM 16 bit protected mode interface connect static void handle_155302(struct bregs *regs) { - regs->bx = 0; // XXX - apm16_entry + regs->bx = (u32)apm16protected_entry; regs->ax = SEG_BIOS; // 16 bit code segment base regs->si = 0xfff0; // 16 bit code segment size regs->cx = SEG_BIOS; // data segment address regs->di = 0xfff0; // data segment length - set_cf(regs, 0); + set_success(regs); } // APM 32 bit protected mode interface connect static void handle_155303(struct bregs *regs) { - regs->ax = 0xf000; // 32 bit code segment base - regs->ebx = 0; // XXX - apm32_entry - regs->cx = 0xf000; // 16 bit code segment base + regs->ax = SEG_BIOS; // 32 bit code segment base + regs->ebx = (u32)apm32protected_entry; + regs->cx = SEG_BIOS; // 16 bit code segment base // 32 bit code segment size (low 16 bits) // 16 bit code segment size (high 16 bits) regs->esi = 0xfff0fff0; - regs->dx = 0xf000; // data segment address + regs->dx = SEG_BIOS; // data segment address regs->di = 0xfff0; // data segment length - set_cf(regs, 0); + set_success(regs); } // APM interface disconnect static void handle_155304(struct bregs *regs) { - set_cf(regs, 0); + set_success(regs); } // APM cpu idle static void handle_155305(struct bregs *regs) { - irq_enable(); - hlt(); - set_cf(regs, 0); + wait_irq(); + set_success(regs); +} + +// APM cpu busy +static void +handle_155306(struct bregs *regs) +{ + set_success(regs); +} + +void +apm_shutdown(void) +{ + irq_disable(); + out_str("Shutdown"); + for (;;) + hlt(); } // APM Set Power State @@ -93,7 +119,7 @@ static void handle_155307(struct bregs *regs) { if (regs->bx != 1) { - set_cf(regs, 0); + set_success(regs); return; } switch (regs->cx) { @@ -104,19 +130,16 @@ handle_155307(struct bregs *regs) out_str("Suspend"); break; case 3: - irq_disable(); - out_str("Shutdown"); - for (;;) - hlt(); + apm_shutdown(); break; } - set_cf(regs, 0); + set_success(regs); } static void handle_155308(struct bregs *regs) { - set_cf(regs, 0); + set_success(regs); } // Get Power Status @@ -129,15 +152,16 @@ handle_15530a(struct bregs *regs) regs->cl = 0xff; // unknown remaining time regs->dx = 0xffff; // unknown remaining time regs->si = 0x00; // zero battery - set_cf(regs, 0); + set_success(regs); } +#define RET_ENOEVENT 0x80 + // Get PM Event static void handle_15530b(struct bregs *regs) { - regs->ah = 0x80; // no event pending - set_cf(regs, 1); + set_code_invalid_silent(regs, RET_ENOEVENT); } // APM Driver Version @@ -146,14 +170,14 @@ handle_15530e(struct bregs *regs) { regs->ah = 1; regs->al = 2; - set_cf(regs, 0); + set_success(regs); } // APM Engage / Disengage static void handle_15530f(struct bregs *regs) { - set_cf(regs, 0); + set_success(regs); } // APM Get Capabilities @@ -162,18 +186,24 @@ handle_155310(struct bregs *regs) { regs->bl = 0; regs->cx = 0; - set_cf(regs, 0); + set_success(regs); } static void handle_1553XX(struct bregs *regs) { - set_cf(regs, 1); + set_unimplemented(regs); } void handle_1553(struct bregs *regs) { + if (! CONFIG_APMBIOS) { + set_code_invalid(regs, RET_EUNSUPPORTED); + return; + } + + //debug_stub(regs); switch (regs->al) { case 0x00: handle_155300(regs); break; case 0x01: handle_155301(regs); break; @@ -181,6 +211,7 @@ handle_1553(struct bregs *regs) case 0x03: handle_155303(regs); break; case 0x04: handle_155304(regs); break; case 0x05: handle_155305(regs); break; + case 0x06: handle_155306(regs); break; case 0x07: handle_155307(regs); break; case 0x08: handle_155308(regs); break; case 0x0a: handle_15530a(regs); break; @@ -191,3 +222,17 @@ handle_1553(struct bregs *regs) default: handle_1553XX(regs); break; } } + +void VISIBLE16 +handle_apm16(struct bregs *regs) +{ + debug_enter(regs, DEBUG_HDL_apm); + handle_1553(regs); +} + +void VISIBLE32SEG +handle_apm32(struct bregs *regs) +{ + debug_enter(regs, DEBUG_HDL_apm); + handle_1553(regs); +}