Re: Laptops (APM) & 0040 crashes

John Goerzen (jgoerzen@alexanderwohl.complete.org)
Sun, 8 Feb 1998 15:38:16 -0600 (CST)


Stephen,

I have good news for me but bad news for you :-)

Since I wrote you, I applied the latest BIOS update from IBM. This update
solved the oops on boot problem, so I unfortunately cannot test your
patch.

However, this laptop still refuses to suspend (hibernate) in Linux but
works under FreeBSD and Win95. Just in case your patch would fix it, I
tried the patch, but it did not fix that problem. I have tried it both
with and without having apmd running.

So at the moment I am still stuck with FreeBSD, until I can get hibernate
to work under Linux. I am, as always, still willing to alpha-test any
code you care to throw my way :-)

Thanks,
John

On Mon, 9 Feb 1998 Stephen.Rothwell@nec.com.au wrote:

> Hi John,
>
> 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