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