Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 09 Aug 1999 01:46:12 +0900
From:      Mitsuru IWASAKI <iwasaki@jp.FreeBSD.org>
To:        mobile@freebsd.org
Cc:        freebsd-bugs@FreeBSD.org, sanpei@sanpei.org, iwasaki@jp.freebsd.org
Subject:   Re: [APM] kernel panic with apm command(Sotec WinBookPro).
Message-ID:  <199908081642.BAA01817@tasogare.imasy.or.jp>
In-Reply-To: Your message of "Mon, 9 Aug 1999 00:06:26 %2B0900 (JST)" <199908081506.AAA18497@lavender.yy.cs.keio.ac.jp>
References:  <199908081506.AAA18497@lavender.yy.cs.keio.ac.jp>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi, folks.

I found the PR that old APM cause panic in 
http://www.freebsd.org/cgi/query-pr.cgi?pr=13028

Anyone review my patch for this?

From: sanpei@sanpei.org
Subject: [APM] kernel panic with apm command(Sotec WinBookPro).
Date: Mon, 9 Aug 1999 00:06:26 +0900 (JST)
Message-ID: <199908081506.AAA18497@lavender.yy.cs.keio.ac.jp>

>   I have Sotec WinBookPro NOTE-PC(486DX4-100MHz).
> I play with apm enabled kernel.
>   But when I execute apm command, kernel panic.....
> 
> [probed message]
> apm0: <APM BIOS> on motherboard
> apm: APM BIOS version 0101
> apm: Code16 0xc00f0000, Data 0xc00f0000
> apm: Code entry 0x0000b321, Idling CPU disabled, Management disabled
> apm: CS_limit=0xffff, DS_limit=0xffff
> apm: found APM BIOS v1.1, connected at v1.0

Odd. Why it connected at v1.0???

> apm: Slow Idling CPU disabled
> 
> [command log]
> % apm
> APM version: 1.0
> APM Management: Enabled
> AC Line Status: on-line
> Battery status: charging
> Remaining battery life: unknown
> Remaining battery time: unknown
> Number of batteries: 0
> APM ioctl: cmd = 0x4040500b
> APM ioctl: cmd = 0xc018500a
> 
> Fatal trap 12: page fault while in 
> fault virtual address	= 0x2e
> fault code		= supervisor read, page not present
> instruction pointer	= 0x50:0x466
> stack pointer	        = 0x10:0xc4780d0a
> frame pointer	        = 0x10:0xc02a000c
> code segment		= base 0xc00f0000, limit 0xffff, type 0x1b
> = DPL 0, pres 1, def32 0, gran 0
> processor eflags	= interrupt enabled, resume, IOPL = 0
> current process		= 289 (apm)
> interrupt mask		= none
> trap number		= 12
> panic: page fault
> 
>   This problem was first appeared at FreeBSD-3.0.  With FreeBSD-2.2,
> I did not have any problems about apm command.

Your APM BOIS probably doesn't support v1.2 functions, and 
I've seen many APM BIOSes can cause kernel panic when attempt to 
execute unsupported APM functions.

Index: apm.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/apm/apm.c,v
retrieving revision 1.98
diff -u -r1.98 apm.c
--- apm.c	1999/08/02 18:46:34	1.98
+++ apm.c	1999/08/08 15:55:09
@@ -50,6 +50,7 @@
 static int apm_display __P((int newstate));
 static void apm_resume __P((void));
 static int apm_bioscall(void);
+static int apm_check_function_supported __P((u_int version, u_int func));
 
 static u_long	apm_version;
 
@@ -132,7 +133,16 @@
 {
 	struct apm_softc *sc = &apm_softc;
 	int errno = 0;
+	u_int apm_func = sc->bios.r.eax & 0xff;
 
+	if (!apm_check_function_supported(sc->intversion, apm_func)) {
+#ifdef APM_DEBUG
+		printf("apm_bioscall: function 0x%x is not supported in v%d.%d\n",
+			apm_func, sc->majorversion, sc->minorversion);
+#endif
+		return (-1);
+	}
+
 	sc->bios_busy = 1;
 	if (sc->connectmode == APM_PROT32CONNECT) {
 		set_bios_selectors(&sc->bios.seg,
@@ -146,6 +156,34 @@
 	return (errno);
 }
 
+/* check whether APM function is supported (1)  or not (0). */
+static int
+apm_check_function_supported(u_int version, u_int func)
+{
+	/* except driver version */
+	if (func == APM_DRVVERSION) {
+		return (1);
+	}
+
+	switch (version) {
+	case INTVERSION(1, 0):
+		if (func > APM_GETPMEVENT) {
+			return (0); /* not supported */
+		}
+		break;
+	case INTVERSION(1, 1):
+		if (func > APM_ENGAGEDISENGAGEPM &&
+		    func < APM_OEMFUNC) {
+			return (0); /* not supported */
+		}
+		break;
+	case INTVERSION(1, 2):
+		break;
+	}
+
+	return (1); /* supported */
+}
+
 /* enable/disable power management */
 static int
 apm_enable_disable_pm(int enable)
@@ -1067,6 +1105,7 @@
 	struct apm_softc *sc = &apm_softc;
 	struct apm_bios_arg *args;
 	int error = 0;
+	int ret;
 	int newstate;
 
 	if (!sc->initialized)
@@ -1135,8 +1174,13 @@
 		sc->bios.r.edx = args->edx;
 		sc->bios.r.esi = args->esi;
 		sc->bios.r.edi = args->edi;
-		if (apm_bioscall())
-			sc->bios.r.eax &= 0xff;
+		if ((ret = apm_bioscall())) {
+			if (ret == -1) {
+				error = ENOSYS;
+			} else {
+				sc->bios.r.eax &= 0xff;
+			}
+		}
 		args->eax = sc->bios.r.eax;
 		args->ebx = sc->bios.r.ebx;
 		args->ecx = sc->bios.r.ecx;


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199908081642.BAA01817>