summaryrefslogtreecommitdiff
path: root/os/pc/apm.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/pc/apm.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/pc/apm.c')
-rw-r--r--os/pc/apm.c151
1 files changed, 0 insertions, 151 deletions
diff --git a/os/pc/apm.c b/os/pc/apm.c
deleted file mode 100644
index 2ea18b4d..00000000
--- a/os/pc/apm.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Interface to Advanced Power Management 1.2 BIOS
- *
- * This is, in many ways, a giant hack, and when things settle down
- * a bit and standardize, hopefully we can write a driver that deals
- * more directly with the hardware and thus might be a bit cleaner.
- *
- * ACPI might be the answer, but at the moment this is simpler
- * and more widespread.
- */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-
-extern int apmfarcall(ushort, ulong, Ureg*); /* apmjump.s */
-
-static int
-getreg(ulong *reg, ISAConf *isa, char *name)
-{
- int i;
- int nl;
-
- nl = strlen(name);
- for(i=0; i<isa->nopt; i++){
- if(cistrncmp(isa->opt[i], name, nl)==0 && isa->opt[i][nl] == '='){
- *reg = strtoul(isa->opt[i]+nl+1, nil, 16);
- return 0;
- }
- }
- return -1;
-}
-
-/*
- * Segment descriptors look like this.
- *
- * d1: [base 31:24] [gran] [is32bit] [0] [unused] [limit 19:16]
- [present] [privlev] [type 3:0] [base 23:16]
- * d0: [base 15:00] [limit 15:00]
- *
- * gran is 0 for 1-byte granularity, 1 for 4k granularity
- * type is 0 for system segment, 1 for code/data.
- *
- * clearly we know way too much about the memory unit.
- * however, knowing this much about the memory unit
- * means that the memory unit need not know anything
- * about us.
- *
- * what a crock.
- */
-static void
-setgdt(int sel, ulong base, ulong limit, int flag)
-{
- if(sel < 0 || sel >= NGDT)
- panic("setgdt");
-
- base = (ulong)KADDR(base);
- m->gdt[sel].d0 = (base<<16) | (limit&0xFFFF);
- m->gdt[sel].d1 = (base&0xFF000000) | (limit&0x000F0000) |
- ((base>>16)&0xFF) | SEGP | SEGPL(0) | flag;
-}
-
-static ulong ax, cx, dx, di, ebx, esi;
-static Ureg apmu;
-static long
-apmread(Chan*, void *a, long n, vlong off)
-{
- if(off < 0)
- error("badarg");
-
- if(n+off > sizeof apmu)
- n = sizeof apmu - off;
- if(n <= 0)
- return 0;
- memmove(a, (char*)&apmu+off, n);
- return n;
-}
-
-static long
-apmwrite(Chan*, void *a, long n, vlong off)
-{
- int s;
- if(off || n != sizeof apmu)
- error("write a Ureg");
-
- memmove(&apmu, a, sizeof apmu);
- s = splhi();
- apmfarcall(APMCSEL, ebx, &apmu);
- splx(s);
- return n;
-}
-
-void
-apmlink(void)
-{
- ISAConf isa;
- char *s;
-
- if(isaconfig("apm", 0, &isa) == 0)
- return;
-
- /*
- * APM info passed from boot loader.
- * Now we need to set up the GDT entries for APM.
- *
- * AX = 32-bit code segment base address
- * EBX = 32-bit code segment offset
- * CX = 16-bit code segment base address
- * DX = 32-bit data segment base address
- * ESI = <16-bit code segment length> <32-bit code segment length> (hi then lo)
- * DI = 32-bit data segment length
- */
-
- if(getreg(&ax, &isa, s="ax") < 0
- || getreg(&ebx, &isa, s="ebx") < 0
- || getreg(&cx, &isa, s="cx") < 0
- || getreg(&dx, &isa, s="dx") < 0
- || getreg(&esi, &isa, s="esi") < 0
- || getreg(&di, &isa, s="di") < 0){
- print("apm: missing register %s\n", s);
- return;
- }
-
- /*
- * The NEC Versa SX bios does not report the correct 16-bit code
- * segment length when loaded directly from mbr -> 9load (as compared
- * with going through ld.com). We'll make both code segments 64k-1 bytes.
- */
- esi = 0xFFFFFFFF;
-
- /*
- * We are required by the BIOS to set up three consecutive segments,
- * one for the APM 32-bit code, one for the APM 16-bit code, and
- * one for the APM data. The BIOS handler uses the code segment it
- * get called with to determine the other two segment selector.
- */
- setgdt(APMCSEG, ax<<4, ((esi&0xFFFF)-1)&0xFFFF, SEGEXEC|SEGR|SEGD);
- setgdt(APMCSEG16, cx<<4, ((esi>>16)-1)&0xFFFF, SEGEXEC|SEGR);
- setgdt(APMDSEG, dx<<4, (di-1)&0xFFFF, SEGDATA|SEGW|SEGD);
-
- addarchfile("apm", 0660, apmread, apmwrite);
-
-print("apm0: configured cbase %.8lux off %.8lux\n", ax<<4, ebx);
-
- return;
-}
-