Re: Laptops (APM) & 0040 crashes

C. Scott Ananian (cananian@lcs.mit.edu)
Mon, 9 Feb 1998 16:16:48 -0500 (EST)


On Sun, 8 Feb 1998 Pavel Machek <pavel@elf.ucw.cz> wrote:

> Also, 2.1.X patch might be nice: this is not likely to be adopted in
> 2.0.X, but IMO it could well go into 2.1.86 [Well- if it works. Did it
> actually help somebody so far?]

I ported the patch to 2.1.85. It is attached. The same caveats of the
original hold (ie, I haven't "fixed" anything). These warnings are
repeated below:

> Stephen Rothwell <Stephen.Rothwell@canb.auug.org.au> wrote:
> > ... I can only say that
> > it doesn't stop my APM enabled desktop from running - I don't have a
> > machine with an APM BIOS with the 0x40 access bug.
>
> Did you make sure that GDT is not overfilled? (I.e. 12+NUM_TASKS being
> more than you can fit in GDT?)

Hope this helps someone. I'm currently running the patch on 2.1.85
without any problems; I *think* it helped fix the suspend
functionality on my laptop, but there are so many CMOS setup options
for this that I can't say I'm certain. At least it did no harm. My
laptop's fancy 'save to disk' suspend is still broken, though (freezes
with a black screen). Does anyone have any suggestions on how I could
track this problem down? It works under Windows =(.

--Scott
@ @
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-oOO-(_)-OOo-=-=-=-=-=
C. Scott Ananian: cananian@lcs.mit.edu / Declare the Truth boldly and
Laboratory for Computer Science/Crypto / without hindrance.
Massachusetts Institute of Technology /META-PARRESIAS AKOLUTOS:Acts 28:31
-.-. .-.. .. ..-. ..-. --- .-. -.. ... -.-. --- - - .- -. .- -. .. .- -.
PGP key available via finger and from http://www.pdos.lcs.mit.edu/~cananian

diff -ruN linux/include/asm-i386/system.h linux.test/include/asm-i386/system.h
--- linux/include/asm-i386/system.h Mon Aug 19 22:00:11 1996
+++ linux.test/include/asm-i386/system.h Sun Feb 8 13:54:28 1998
@@ -11,13 +11,18 @@
* 3 - kernel data segment
* 4 - user code segment
* 5 - user data segment
- * ...
- * 8 - TSS #0
- * 9 - LDT #0
- * 10 - TSS #1
- * 11 - LDT #1
+ * 6 - not used
+ * 7 - not used
+ * 8 - APM BIOS support
+ * 9 - APM BIOS support
+ * 10 - APM BIOS support
+ * 11 - APM BIOS support
+ * 12 - TSS #0
+ * 13 - LDT #0
+ * 14 - TSS #1
+ * 15 - LDT #1
*/
-#define FIRST_TSS_ENTRY 8
+#define FIRST_TSS_ENTRY 12
#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
diff -ruN linux/include/linux/apm_bios.h linux.test/include/linux/apm_bios.h
--- linux/include/linux/apm_bios.h Sun Feb 8 12:31:21 1998
+++ linux.test/include/linux/apm_bios.h Sun Feb 8 14:08:19 1998
@@ -22,10 +22,8 @@

#ifdef __KERNEL__

-#include <linux/tasks.h> /* for NR_TASKS */
-#include <linux/sched.h> /* for _TSS */
-
-#define APM_CS _TSS(NR_TASKS)
+#define APM_40 0x40
+#define APM_CS (APM_40 + 8)
#define APM_CS_16 (APM_CS + 8)
#define APM_DS (APM_CS_16 + 8)

diff -ruN linux/arch/i386/kernel/head.S.orig linux/arch/i386/kernel/head.S
--- linux/arch/i386/kernel/head.S.orig Tue Dec 23 13:45:12 1997
+++ linux/arch/i386/kernel/head.S Mon Feb 9 11:25:15 1998
@@ -11,7 +11,6 @@
#include <linux/tasks.h>
#include <linux/linkage.h>
#include <asm/segment.h>
-#include <linux/config.h>

#define CL_MAGIC_ADDR 0x90020
#define CL_MAGIC 0xA33F
@@ -423,11 +422,7 @@
* of tasks we can have..
*/
#define IDT_ENTRIES 256
-#ifdef CONFIG_APM
-#define GDT_ENTRIES (11+2*NR_TASKS)
-#else
-#define GDT_ENTRIES (8+2*NR_TASKS)
-#endif
+#define GDT_ENTRIES (12+2*NR_TASKS)


.globl SYMBOL_NAME(idt)
@@ -637,9 +632,8 @@
.quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */
.quad 0x0000000000000000 /* not used */
.quad 0x0000000000000000 /* not used */
+ .quad 0x00c0920000000000 /* 0x40 APM set up for bad BIOS's */
+ .quad 0x00c09a0000000000 /* 0x48 APM CS code */
+ .quad 0x00809a0000000000 /* 0x50 APM CS 16 code (16 bit) */
+ .quad 0x00c0920000000000 /* 0x58 APM DS data */
.fill 2*NR_TASKS,8,0 /* space for LDT's and TSS's etc */
-#ifdef CONFIG_APM
- .quad 0x00c09a0000000000 /* APM CS code */
- .quad 0x00809a0000000000 /* APM CS 16 code (16 bit) */
- .quad 0x00c0920000000000 /* APM DS data */
-#endif
diff -ruN linux/drivers/char/apm_bios.c.orig linux/drivers/char/apm_bios.c
--- linux/drivers/char/apm_bios.c.orig Sun Dec 21 20:41:24 1997
+++ linux/drivers/char/apm_bios.c Mon Feb 9 11:30:21 1998
@@ -26,6 +26,7 @@
* April 1996, Stephen Rothwell (Stephen.Rothwell@canb.auug.org.au)
* Version 1.0 and 1.1
* May 1996, Version 1.2
+ * Feb 1998, Version 1.3
*
* History:
* 0.6b: first version in official kernel, Linux 1.3.46
@@ -44,6 +45,7 @@
* levels to the printk calls. APM is not defined for SMP machines.
* The new replacment for it is, but Linux doesn't yet support this.
* Alan Cox Linux 2.1.55
+ * 1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
*
* Reference:
*
@@ -162,8 +164,8 @@
#define APM_NOINTS

/*
- * Define to make the APM BIOS calls zero all data segment registers (do
- * that if an incorrect BIOS implementation will cause a kernel panic if it
+ * Define to make the APM BIOS calls zero all data segment registers (so
+ * that an incorrect BIOS implementation will cause a kernel panic if it
* tries to write to arbitrary memory).
*/
#define APM_ZERO_SEGS
@@ -340,7 +342,7 @@

static struct timer_list apm_timer;

-static char driver_version[] = "1.2";/* no spaces */
+static char driver_version[] = "1.3"; /* no spaces */

#ifdef APM_DEBUG
static char * apm_event_name[] = {
@@ -1111,6 +1113,16 @@
printk(" cseg len %x, dseg len %x",
apm_bios_info.cseg_len, apm_bios_info.dseg_len);
printk("\n");
+
+ /*
+ * Set up a segment that references the real mode segment 0x40
+ * that extends up to the end of page zero (that we have reserved).
+ * This is for buggy BIOS's that refer to (real mode) segment 0x40
+ * even though they are called in protected mode.
+ */
+ set_base(gdt[APM_40 >> 3],
+ 0xc0000000 + ((unsigned long)0x40 << 4));
+ set_limit(gdt[APM_40 >> 3], 4096 - (0x40 << 4));

apm_bios_entry.offset = apm_bios_info.offset;
apm_bios_entry.segment = APM_CS;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu