|
|
1.1 ! root 1: // Basic support for apmbios callbacks. ! 2: // ! 3: // Copyright (C) 2008 Kevin O'Connor <[email protected]> ! 4: // Copyright (C) 2005 Struan Bartlett ! 5: // Copyright (C) 2004 Fabrice Bellard ! 6: // ! 7: // This file may be distributed under the terms of the GNU LGPLv3 license. ! 8: ! 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 ! 15: ! 16: static void ! 17: out_str(const char *str_cs) ! 18: { ! 19: if (CONFIG_COREBOOT) { ! 20: dprintf(1, "APM request '%s'\n", str_cs); ! 21: return; ! 22: } ! 23: ! 24: u8 *s = (u8*)str_cs; ! 25: for (;;) { ! 26: u8 c = GET_GLOBAL(*s); ! 27: if (!c) ! 28: break; ! 29: outb(c, PORT_BIOS_APM); ! 30: s++; ! 31: } ! 32: } ! 33: ! 34: // APM installation check ! 35: static void ! 36: handle_155300(struct bregs *regs) ! 37: { ! 38: regs->ah = 1; // APM major version ! 39: regs->al = 2; // APM minor version ! 40: regs->bh = 'P'; ! 41: regs->bl = 'M'; ! 42: // bit 0 : 16 bit interface supported ! 43: // bit 1 : 32 bit interface supported ! 44: regs->cx = 0x03; ! 45: set_success(regs); ! 46: } ! 47: ! 48: // APM real mode interface connect ! 49: static void ! 50: handle_155301(struct bregs *regs) ! 51: { ! 52: set_success(regs); ! 53: } ! 54: ! 55: // Assembler entry points defined in romlayout.S ! 56: extern void apm16protected_entry(); ! 57: extern void apm32protected_entry(); ! 58: ! 59: // APM 16 bit protected mode interface connect ! 60: static void ! 61: handle_155302(struct bregs *regs) ! 62: { ! 63: regs->bx = (u32)apm16protected_entry; ! 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 ! 68: set_success(regs); ! 69: } ! 70: ! 71: // APM 32 bit protected mode interface connect ! 72: static void ! 73: handle_155303(struct bregs *regs) ! 74: { ! 75: regs->ax = SEG_BIOS; // 32 bit code segment base ! 76: regs->ebx = (u32)apm32protected_entry; ! 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 ! 83: set_success(regs); ! 84: } ! 85: ! 86: // APM interface disconnect ! 87: static void ! 88: handle_155304(struct bregs *regs) ! 89: { ! 90: set_success(regs); ! 91: } ! 92: ! 93: // APM cpu idle ! 94: static void ! 95: handle_155305(struct bregs *regs) ! 96: { ! 97: wait_irq(); ! 98: set_success(regs); ! 99: } ! 100: ! 101: // APM cpu busy ! 102: static void ! 103: handle_155306(struct bregs *regs) ! 104: { ! 105: set_success(regs); ! 106: } ! 107: ! 108: // APM Set Power State ! 109: static void ! 110: handle_155307(struct bregs *regs) ! 111: { ! 112: if (regs->bx != 1) { ! 113: set_success(regs); ! 114: return; ! 115: } ! 116: switch (regs->cx) { ! 117: case 1: ! 118: out_str("Standby"); ! 119: break; ! 120: case 2: ! 121: out_str("Suspend"); ! 122: break; ! 123: case 3: ! 124: irq_disable(); ! 125: out_str("Shutdown"); ! 126: for (;;) ! 127: hlt(); ! 128: break; ! 129: } ! 130: set_success(regs); ! 131: } ! 132: ! 133: static void ! 134: handle_155308(struct bregs *regs) ! 135: { ! 136: set_success(regs); ! 137: } ! 138: ! 139: // Get Power Status ! 140: static void ! 141: handle_15530a(struct bregs *regs) ! 142: { ! 143: regs->bh = 0x01; // on line ! 144: regs->bl = 0xff; // unknown battery status ! 145: regs->ch = 0x80; // no system battery ! 146: regs->cl = 0xff; // unknown remaining time ! 147: regs->dx = 0xffff; // unknown remaining time ! 148: regs->si = 0x00; // zero battery ! 149: set_success(regs); ! 150: } ! 151: ! 152: #define RET_ENOEVENT 0x80 ! 153: ! 154: // Get PM Event ! 155: static void ! 156: handle_15530b(struct bregs *regs) ! 157: { ! 158: set_code_invalid_silent(regs, RET_ENOEVENT); ! 159: } ! 160: ! 161: // APM Driver Version ! 162: static void ! 163: handle_15530e(struct bregs *regs) ! 164: { ! 165: regs->ah = 1; ! 166: regs->al = 2; ! 167: set_success(regs); ! 168: } ! 169: ! 170: // APM Engage / Disengage ! 171: static void ! 172: handle_15530f(struct bregs *regs) ! 173: { ! 174: set_success(regs); ! 175: } ! 176: ! 177: // APM Get Capabilities ! 178: static void ! 179: handle_155310(struct bregs *regs) ! 180: { ! 181: regs->bl = 0; ! 182: regs->cx = 0; ! 183: set_success(regs); ! 184: } ! 185: ! 186: static void ! 187: handle_1553XX(struct bregs *regs) ! 188: { ! 189: set_unimplemented(regs); ! 190: } ! 191: ! 192: void VISIBLE16 ! 193: handle_1553(struct bregs *regs) ! 194: { ! 195: if (! CONFIG_APMBIOS) { ! 196: set_code_invalid(regs, RET_EUNSUPPORTED); ! 197: return; ! 198: } ! 199: ! 200: //debug_stub(regs); ! 201: switch (regs->al) { ! 202: case 0x00: handle_155300(regs); break; ! 203: case 0x01: handle_155301(regs); break; ! 204: case 0x02: handle_155302(regs); break; ! 205: case 0x03: handle_155303(regs); break; ! 206: case 0x04: handle_155304(regs); break; ! 207: case 0x05: handle_155305(regs); break; ! 208: case 0x06: handle_155306(regs); break; ! 209: case 0x07: handle_155307(regs); break; ! 210: case 0x08: handle_155308(regs); break; ! 211: case 0x0a: handle_15530a(regs); break; ! 212: case 0x0b: handle_15530b(regs); break; ! 213: case 0x0e: handle_15530e(regs); break; ! 214: case 0x0f: handle_15530f(regs); break; ! 215: case 0x10: handle_155310(regs); break; ! 216: default: handle_1553XX(regs); break; ! 217: } ! 218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.