John Goerzen <jgoerzen@southwind.net> writes:
>
> I really prefer to work in Linux but I'm leaving FreeBSD on there for
> the moment since I have no better option right now. Anyway, it seems
> that FreeBSD is somehow getting around this problem. What I don't
> know is HOW they are getting around it. I am not a kernel hacker so I
> unfortunately won't be much use analyzing their code, but I can try and
> find their APM code and mail it to anybody interested.
OK, I wouldn't want to leave you stranded on FreeBSD :-) Can you try
the following patch for me. It is against 2.0.33. 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.
> > OK, there is not much work going on with the APM driver for various
> > reasons - the biggy being that APM is now defunct :-( There is a new
>
> Hmm, weird. AFAIK, all current laptops still use APM.
What I should have said is that M$ and Intel have made up another
standard for power management. APM is still used by everyone,
but ACPI(?) is on the horizon.
> > API for doing power management that I know nothing about (yet). Also
> > there have not been any major revisions of teh APM BIOS specifiation anyway.
>
> It seems, though, that some support for certain "buggy" BIOSes might be
> warranted. (Like is present for CMS640, etc.) I much perfer
> my Debian to FreeBSD :-)
Try the patch - we will see if we can help you back into the "real" world.
> > I think the only solution is to complain to IBM and get it fixed.
> > There may already be an updated BIOS available (I don't know).
>
> I have looked at their webpage and they apparently do have a BIOS
> update. Looking at their changelog, they do not say that they have
> dealt with an issue like this, but it is possible that they did and
> just didn't mention it. I will flash the image this afternoon and let
> everyone know how it works.
>
> Even if it works, I would still say that it might be beneficial to
> adopt whatever workaround FreeBSD is using for this bug. From my
> limited understanding of it, it may prove useful for desktop machines
> with APM support as well.
I had a quick look at teh FreeBSD code, but couldn't see any difference.
Maybe they do just what I am trying, but somewhere else.
Cheers,
Stephen
--
Stephen Rothwell Stephen.Rothwell@canb.auug.org.au
------------------------------------------------------------------------
diff -ruN linux-2.0.33/arch/i386/kernel/head.S linux.test/arch/i386/kernel/head.S
--- linux-2.0.33/arch/i386/kernel/head.S Sun Feb 8 12:26:59 1998
+++ linux.test/arch/i386/kernel/head.S Sun Feb 8 14:07:13 1998
@@ -12,7 +12,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
@@ -386,11 +385,7 @@
ALIGN
.word 0
gdt_descr:
-#ifdef CONFIG_APM
- .word (11+2*NR_TASKS)*8-1
-#else
- .word (8+2*NR_TASKS)*8-1
-#endif
+ .word (12+2*NR_TASKS)*8-1
.long 0xc0000000+SYMBOL_NAME(gdt)
/*
@@ -406,9 +401,8 @@
.quad 0x00cbf2000000ffff /* 0x2b user 3GB 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-2.0.33/drivers/char/apm_bios.c linux.test/drivers/char/apm_bios.c
--- linux-2.0.33/drivers/char/apm_bios.c Wed May 15 16:06:55 1996
+++ linux.test/drivers/char/apm_bios.c Sun Feb 8 14:24:32 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
@@ -40,6 +41,7 @@
* is only incorrect by 30-60mS (vs. 1S previously) (Gabor J. Toth
* <jtoth@princeton.edu>); improve interaction between
* screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
+ * 1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
*
* Reference:
*
@@ -160,8 +162,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
@@ -339,7 +341,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[] = {
@@ -1107,6 +1109,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;
diff -ruN linux-2.0.33/include/asm-i386/system.h linux.test/include/asm-i386/system.h
--- linux-2.0.33/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-2.0.33/include/linux/apm_bios.h linux.test/include/linux/apm_bios.h
--- linux-2.0.33/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)
------------------------------------------------------------------------
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu