diff -urN --exclude-from=/home/davej/.exclude linux-2.4.15pre6/arch/i386/kernel/bootflag.c linux-ac/arch/i386/kernel/bootflag.c --- linux-2.4.15pre6/arch/i386/kernel/bootflag.c Thu Jan 1 00:00:00 1970 +++ linux-ac/arch/i386/kernel/bootflag.c Mon Nov 19 14:09:18 2001 @@ -0,0 +1,253 @@ +/* + * Implement 'Simple Boot Flag Specification 1.0' + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define SBF_RESERVED (0x78) +#define SBF_PNPOS (1<<0) +#define SBF_BOOTING (1<<1) +#define SBF_DIAG (1<<2) +#define SBF_PARITY (1<<7) + + +struct sbf_boot +{ + u8 sbf_signature[4]; + u32 sbf_len; + u8 sbf_revision __attribute((packed)); + u8 sbf_csum __attribute((packed)); + u8 sbf_oemid[6] __attribute((packed)); + u8 sbf_oemtable[8] __attribute((packed)); + u8 sbf_revdata[4] __attribute((packed)); + u8 sbf_creator[4] __attribute((packed)); + u8 sbf_crearev[4] __attribute((packed)); + u8 sbf_cmos __attribute((packed)); + u8 sbf_spare[3] __attribute((packed)); +}; + + +static int sbf_port __initdata = -1; + +static int __init sbf_struct_valid(unsigned long tptr) +{ + u8 *ap; + u8 v; + unsigned int i; + struct sbf_boot sb; + + memcpy_fromio(&sb, tptr, sizeof(sb)); + + if(sb.sbf_len != 40 && sb.sbf_len != 39) + // 39 on IBM ThinkPad A21m, BIOS version 1.02b (KXET24WW; 2000-12-19). + return 0; + + ap = (u8 *)&sb; + v= 0; + + for(i=0;i>=1; + } + return x; +} + +static void __init sbf_write(u8 v) +{ + unsigned long flags; + if(sbf_port != -1) + { + v &= ~SBF_PARITY; + if(!parity(v)) + v|=SBF_PARITY; + + printk(KERN_INFO "SBF: Setting boot flags 0x%x\n",v); + + spin_lock_irqsave(&rtc_lock, flags); + CMOS_WRITE(v, sbf_port); + spin_unlock_irqrestore(&rtc_lock, flags); + } +} + +static u8 __init sbf_read(void) +{ + u8 v; + unsigned long flags; + if(sbf_port == -1) + return 0; + spin_lock_irqsave(&rtc_lock, flags); + v = CMOS_READ(sbf_port); + spin_unlock_irqrestore(&rtc_lock, flags); + return v; +} + +static int __init sbf_value_valid(u8 v) +{ + if(v&SBF_RESERVED) /* Reserved bits */ + return 0; + if(!parity(v)) + return 0; + return 1; +} + + +static void __init sbf_bootup(void) +{ + u8 v; + if(sbf_port == -1) + return; + v = sbf_read(); + if(!sbf_value_valid(v)) + printk(KERN_WARNING "SBF: Simple boot flag value 0x%x read from CMOS RAM was invalid\n",v); + v &= ~SBF_RESERVED; + v &= ~SBF_BOOTING; + v &= ~SBF_DIAG; +#if defined(CONFIG_PNPBIOS) + v |= SBF_PNPOS; +#endif + sbf_write(v); +} + +static int __init sbf_init(void) +{ + unsigned int i; + void *rsdt; + u32 rsdtlen = 0; + u32 rsdtbase = 0; + u8 sum = 0; + int n; + + u8 *p; + + for(i=0xE0000; i <= 0xFFFE0; i+=16) + { + p = phys_to_virt(i); + + if(memcmp(p, "RSD PTR ", 8)) + continue; + + sum = 0; + for(n=0; n<20; n++) + sum+=p[n]; + + if(sum != 0) + continue; + + /* So it says RSD PTR and it checksums... */ + + /* + * Process the RDSP pointer + */ + + rsdtbase = *(u32 *)(p+16); + + /* + * RSDT length is ACPI 2 only, for ACPI 1 we must map + * and remap. + */ + + if(p[15]>1) + rsdtlen = *(u32 *)(p+20); + else + rsdtlen = 36; + + if(rsdtlen < 36 || rsdtlen > 1024) + continue; + break; + } + if(i>0xFFFE0) + return 0; + + + rsdt = ioremap(rsdtbase, rsdtlen); + if(rsdt == 0) + return 0; + + i = readl(rsdt + 4); + + /* + * Remap if needed + */ + + if(i > rsdtlen) + { + rsdtlen = i; + iounmap(rsdt); + rsdt = ioremap(rsdtbase, rsdtlen); + if(rsdt == 0) + return 0; + } + + for(n = 0; n < i; n++) + sum += readb(rsdt + n); + + if(sum) + { + iounmap(rsdt); + return 0; + } + + /* Ok the RSDT checksums too */ + + for(n = 36; n+3 < i; n += 4) + { + unsigned long rp = readl(rsdt+n); + int len = 4096; + + if(rp > 0xFFFFFFFFUL - len) + len = 0xFFFFFFFFUL - rp; + + /* Too close to the end!! */ + if(len < 20) + continue; + rp = (unsigned long)ioremap(rp, 4096); + if(rp == 0) + continue; + if(sbf_struct_valid(rp)) + { + /* Found the BOOT table and processed it */ + printk(KERN_INFO "SBF: Simple Boot Flag extension found and enabled.\n"); + } + iounmap((void *)rp); + } + iounmap(rsdt); + sbf_bootup(); + return 0; +} + +module_init(sbf_init); diff -urN --exclude-from=/home/davej/.exclude linux-2.4.15pre6/arch/i386/kernel/Makefile linux-ac/arch/i386/kernel/Makefile --- linux-2.4.15pre6/arch/i386/kernel/Makefile Mon Nov 19 13:40:53 2001 +++ linux-ac/arch/i386/kernel/Makefile Mon Nov 19 14:09:18 2001 @@ -18,7 +18,8 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ - pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o + pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o \ + bootflag.o ifdef CONFIG_PCI