diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-15 01:55:58 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-15 01:55:58 +0000 |
commit | 53b3988d474435254a3b053a68bb24ce9e439295 (patch) | |
tree | f8da8e40f01f4ad02bbd76b8c9920749b118235f /arch/i386 | |
parent | b0cb48abe83d1a4389ea938bf624f8baa82c5047 (diff) |
Merge with 2.3.99-pre9.
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/config.in | 1 | ||||
-rw-r--r-- | arch/i386/defconfig | 8 | ||||
-rw-r--r-- | arch/i386/kernel/acpi.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/apic.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/apm.c | 50 | ||||
-rw-r--r-- | arch/i386/kernel/i8259.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 32 | ||||
-rw-r--r-- | arch/i386/kernel/irq.c | 8 | ||||
-rw-r--r-- | arch/i386/kernel/ldt.c | 1 | ||||
-rw-r--r-- | arch/i386/kernel/mpparse.c | 15 | ||||
-rw-r--r-- | arch/i386/kernel/pci-i386.c | 22 | ||||
-rw-r--r-- | arch/i386/kernel/pci-irq.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/pci-pc.c | 11 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 58 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 54 |
16 files changed, 158 insertions, 116 deletions
diff --git a/arch/i386/config.in b/arch/i386/config.in index 8f4782ca8..1208a6b82 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -180,7 +180,6 @@ if [ "$CONFIG_APM" != "n" ]; then bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK - bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT bool ' Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS diff --git a/arch/i386/defconfig b/arch/i386/defconfig index f618cac4b..e00ac753a 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -111,7 +111,6 @@ CONFIG_BLK_DEV_FD=y # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set -# CONFIG_RAID15_DANGEROUS is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set @@ -169,6 +168,13 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set # CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c index d9dabac2f..2e220bc06 100644 --- a/arch/i386/kernel/acpi.c +++ b/arch/i386/kernel/acpi.c @@ -829,7 +829,7 @@ const static struct pci_device_id acpi_pci_tbl[] = {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4}, {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586}, {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A}, - {0,}, /* terminate list */ + {0,} /* terminate list */ }; static int __init acpi_probe(struct pci_dev *dev, diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index bf3d3c0af..eab365e26 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -30,11 +30,6 @@ int prof_multiplier[NR_CPUS] = { 1, }; int prof_old_multiplier[NR_CPUS] = { 1, }; int prof_counter[NR_CPUS] = { 1, }; -/* - * IA s/w dev Vol 3, Section 7.4 - */ -#define APIC_DEFAULT_PHYS_BASE 0xfee00000 - int get_maxlvt(void) { unsigned int v, ver, maxlvt; diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 99e258756..b1e0e8b7c 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -132,6 +132,9 @@ * 1.13: Changes for new pm_ interfaces (Andy Henroid * <andy_henroid@yahoo.com>). * Modularize the code. + * Fix the Thinkpad (again) :-( (CONFIG_APM_IGNORE_MULTIPLE_SUSPENDS + * is now the way life works). + * Fix thinko in suspend() (wrong return). * * APM 1.1 Reference: * @@ -308,9 +311,7 @@ static int clock_slowed = 0; #endif static int suspends_pending = 0; static int standbys_pending = 0; -#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND static int waiting_for_resume = 0; -#endif #ifdef CONFIG_APM_RTC_IS_GMT # define clock_cmos_diff 0 @@ -866,22 +867,22 @@ static void reinit_timer(void) static int suspend(void) { int err; - int ret; struct apm_user *as; get_time_diff(); err = apm_set_power_state(APM_STATE_SUSPEND); reinit_timer(); set_time(); - ret = (err == APM_SUCCESS) || (err == APM_NO_ERROR); - if (!ret) + if (err == APM_NO_ERROR) + err = APM_SUCCESS; + if (err != APM_SUCCESS) apm_error("suspend", err); for (as = user_list; as != NULL; as = as->next) { as->suspend_wait = 0; - as->suspend_result = (ret ? 0 : -EIO); + as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO); } wake_up_interruptible(&apm_suspend_waitqueue); - return ret; + return err; } static void standby(void) @@ -962,14 +963,7 @@ static void check_events(void) switch (event) { case APM_SYS_STANDBY: case APM_USER_STANDBY: -#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND - if (waiting_for_resume) - break; -#endif if (send_event(event, NULL)) { -#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND - waiting_for_resume = 1; -#endif if (standbys_pending <= 0) standby(); } @@ -986,14 +980,18 @@ static void check_events(void) if (ignore_bounce) break; #endif -#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + /* + * If we are already processing a SUSPEND, + * then further SUSPEND events from the BIOS + * will be ignored. We also return here to + * cope with the fact that the Thinkpads keep + * sending a SUSPEND event until something else + * happens! + */ if (waiting_for_resume) - break; -#endif + return; if (send_event(event, NULL)) { -#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND waiting_for_resume = 1; -#endif if (suspends_pending <= 0) (void) suspend(); } @@ -1002,9 +1000,7 @@ static void check_events(void) case APM_NORMAL_RESUME: case APM_CRITICAL_RESUME: case APM_STANDBY_RESUME: -#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND waiting_for_resume = 0; -#endif #ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE last_resume = jiffies; ignore_bounce = 1; @@ -1036,8 +1032,10 @@ static void apm_event_handler(void) int err; if ((standbys_pending > 0) || (suspends_pending > 0)) { - if ((apm_bios_info.version > 0x100) && (pending_count-- < 0)) { + if ((apm_bios_info.version > 0x100) && (pending_count-- <= 0)) { pending_count = 4; + if (debug) + printk(KERN_DEBUG "apm: setting state busy\n"); err = apm_set_power_state(APM_STATE_BUSY); if (err) apm_error("busy", err); @@ -1097,7 +1095,7 @@ static void apm_mainloop(void) static int check_apm_user(struct apm_user *as, const char *func) { if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) { - printk(KERN_ERR "apm: %s passed bad filp", func); + printk(KERN_ERR "apm: %s passed bad filp\n", func); return 1; } return 0; @@ -1200,7 +1198,7 @@ static int do_ioctl(struct inode * inode, struct file *filp, } else if (!send_event(APM_USER_SUSPEND, as)) return -EAGAIN; if (suspends_pending <= 0) { - if (!suspend()) + if (suspend() != APM_SUCCESS) return -EIO; } else { as->suspend_wait = 1; @@ -1251,7 +1249,7 @@ static int do_release(struct inode * inode, struct file * filp) as1 = as1->next) ; if (as1 == NULL) - printk(KERN_ERR "apm: filp not in user list"); + printk(KERN_ERR "apm: filp not in user list\n"); else as1->next = as->next; } @@ -1268,7 +1266,7 @@ static int do_open(struct inode * inode, struct file * filp) as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL); if (as == NULL) { - printk(KERN_ERR "apm: cannot allocate struct of size %d bytes", + printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n", sizeof(*as)); MOD_DEC_USE_COUNT; return -ENOMEM; diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 334a75f88..e88fa9022 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -456,7 +456,7 @@ void __init init_IRQ(void) * IRQ0 must be given a fixed assignment and initialized, * because it's used before the IO-APIC is set up. */ - set_intr_gate(IRQ0_TRAP_VECTOR, interrupt[0]); + set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]); /* * The reschedule interrupt is a CPU-to-CPU reschedule-helper diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index dfee6e4d5..7bf275c14 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -48,6 +48,11 @@ struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; /* MP IRQ source entries */ int mp_irq_entries = 0; +#if CONFIG_SMP +# define TARGET_CPUS cpu_online_map +#else +# define TARGET_CPUS 0x01 +#endif /* * Rough estimation of how many shared IRQs there are, can * be changed anytime. @@ -89,7 +94,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) entry->pin = pin; } -#define __DO_ACTION(name,R,ACTION, FINAL) \ +#define __DO_ACTION(R, ACTION, FINAL) \ \ { \ int pin; \ @@ -112,8 +117,8 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) #define DO_ACTION(name,R,ACTION, FINAL) \ \ -static void name##_IO_APIC_irq(unsigned int irq) \ -__DO_ACTION(name,R,ACTION, FINAL) + static void name##_IO_APIC_irq (unsigned int irq) \ + __DO_ACTION(R, ACTION, FINAL) DO_ACTION( __mask, 0, |= 0x00010000, io_apic_sync(entry->apic))/* mask = 1 */ DO_ACTION( __unmask, 0, &= 0xfffeffff, ) /* mask = 0 */ @@ -542,25 +547,26 @@ static inline int IO_APIC_irq_trigger(int irq) return 0; } -int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 }; +int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; static int __init assign_irq_vector(int irq) { - static int current_vector = IRQ0_TRAP_VECTOR, offset = 0; + static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; if (IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); - if (current_vector == 0xFF) - panic("ran out of interrupt sources!"); next: current_vector += 8; if (current_vector == SYSCALL_VECTOR) goto next; - if (current_vector > 0xFF) { + if (current_vector > FIRST_SYSTEM_VECTOR) { offset++; - current_vector = IRQ0_TRAP_VECTOR + offset; + current_vector = FIRST_DEVICE_VECTOR + offset; } + if (current_vector == FIRST_SYSTEM_VECTOR) + panic("ran out of interrupt sources!"); + IO_APIC_VECTOR(irq) = current_vector; return current_vector; } @@ -587,7 +593,7 @@ void __init setup_IO_APIC_irqs(void) entry.delivery_mode = dest_LowestPrio; entry.dest_mode = 1; /* logical delivery */ entry.mask = 0; /* enable IRQ */ - entry.dest.logical.logical_dest = APIC_ALL_CPUS; + entry.dest.logical.logical_dest = TARGET_CPUS; idx = find_irq_entry(apic,pin,mp_INT); if (idx == -1) { @@ -605,7 +611,7 @@ void __init setup_IO_APIC_irqs(void) if (irq_trigger(idx)) { entry.trigger = 1; entry.mask = 1; - entry.dest.logical.logical_dest = APIC_ALL_CPUS; + entry.dest.logical.logical_dest = TARGET_CPUS; } irq = pin_2_irq(idx, apic, pin); @@ -660,7 +666,7 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) */ entry.dest_mode = 1; /* logical delivery */ entry.mask = 0; /* unmask IRQ now */ - entry.dest.logical.logical_dest = APIC_ALL_CPUS; + entry.dest.logical.logical_dest = TARGET_CPUS; entry.delivery_mode = dest_LowestPrio; entry.polarity = 0; entry.trigger = 0; @@ -1167,7 +1173,7 @@ static void set_ioapic_affinity (unsigned int irq, unsigned long mask) mask = mask << 24; spin_lock_irqsave(&ioapic_lock, flags); - __DO_ACTION( target, 1, = mask, ) + __DO_ACTION(1, = mask, ) spin_unlock_irqrestore(&ioapic_lock, flags); } diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 79155a326..fb0fe277c 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -1117,7 +1117,8 @@ static void register_irq_proc (unsigned int irq) struct proc_dir_entry *entry; char name [MAX_NAMELEN]; - if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type)) + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) || + irq_dir[irq]) return; memset(name, 0, MAX_NAMELEN); @@ -1158,10 +1159,7 @@ void init_irq_proc (void) /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) { - if (irq_desc[i].handler == &no_irq_type) - continue; + for (i = 0; i < NR_IRQS; i++) register_irq_proc(i); - } } diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c index 1c359b4f4..e3b5c2f75 100644 --- a/arch/i386/kernel/ldt.c +++ b/arch/i386/kernel/ldt.c @@ -93,6 +93,7 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) mm->segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); if (!mm->segments) goto out_unlock; + memset(mm->segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); if (atomic_read(&mm->mm_users) > 1) printk(KERN_WARNING "LDT allocated for cloned task!\n"); diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 5df83a10a..9455d2e3a 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -50,11 +50,6 @@ static unsigned int num_processors = 0; unsigned long phys_cpu_present_map = 0; /* - * IA s/w dev Vol 3, Section 7.4 - */ -#define APIC_DEFAULT_PHYS_BASE 0xfee00000 - -/* * Intel MP BIOS table parsing routines: */ @@ -65,10 +60,12 @@ unsigned long phys_cpu_present_map = 0; static int __init mpf_checksum(unsigned char *mp, int len) { - int sum=0; - while(len--) - sum+=*mp++; - return sum&0xFF; + int sum = 0; + + while (len--) + sum += *mp++; + + return sum & 0xFF; } /* diff --git a/arch/i386/kernel/pci-i386.c b/arch/i386/kernel/pci-i386.c index afb90ab12..53349bd0a 100644 --- a/arch/i386/kernel/pci-i386.c +++ b/arch/i386/kernel/pci-i386.c @@ -121,6 +121,19 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, } } +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ void pcibios_align_resource(void *data, struct resource *res, unsigned long size) { @@ -129,17 +142,16 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size) if (res->flags & IORESOURCE_IO) { unsigned long start = res->start; - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" " (%ld bytes)\n", dev->slot_name, dev->resource - res, size); } - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } } } diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c index d678801b6..cd16c78a5 100644 --- a/arch/i386/kernel/pci-irq.c +++ b/arch/i386/kernel/pci-irq.c @@ -222,6 +222,7 @@ static struct irq_router pirq_routers[] = { { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set }, { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set }, { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set }, + { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82440MX_1, pirq_piix_get, pirq_piix_set }, { "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set }, { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set }, { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set }, @@ -345,7 +346,7 @@ int pcibios_lookup_irq(struct pci_dev *dev, int assign) if (!irq) { DBG(" ... failed\n"); - if (newirq && mask == (1 << newirq)) { + if (assign && newirq && mask == (1 << newirq)) { msg = "Guessed"; irq = newirq; } else diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c index d1f41ff0d..404a49868 100644 --- a/arch/i386/kernel/pci-pc.c +++ b/arch/i386/kernel/pci-pc.c @@ -844,15 +844,15 @@ static void __init pci_fixup_i450gx(struct pci_dev *d) pcibios_last_bus = -1; } -static void __init pci_fixup_rcc(struct pci_dev *d) +static void __init pci_fixup_serverworks(struct pci_dev *d) { /* - * RCC host bridges -- Find and scan all secondary buses. + * ServerWorks host bridges -- Find and scan all secondary buses. * Register 0x44 contains first, 0x45 last bus number routed there. */ u8 busno; pci_read_config_byte(d, 0x44, &busno); - printk("PCI: RCC host bridge: secondary bus %02x\n", busno); + printk("PCI: ServerWorks host bridge: secondary bus %02x\n", busno); pci_scan_bus(busno, pci_root_ops, NULL); pcibios_last_bus = -1; } @@ -928,8 +928,9 @@ static void __init pci_fixup_latency(struct pci_dev *d) struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx }, - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_RCC, PCI_DEVICE_ID_RCC_HE, pci_fixup_rcc }, - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_RCC, PCI_DEVICE_ID_RCC_LE, pci_fixup_rcc }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HE, pci_fixup_serverworks }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, pci_fixup_serverworks }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CMIC_HE, pci_fixup_serverworks }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_6010, pci_fixup_compaq }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash }, diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index e3e043b23..358d9f917 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -406,6 +406,32 @@ void __init add_memory_region(unsigned long start, e820.nr_map++; } /* add_memory_region */ +#define E820_DEBUG 1 + +static void __init print_e820_map(void) +{ + int i; + + for (i = 0; i < e820.nr_map; i++) { + printk(" e820: %016Lx @ %016Lx ", + e820.map[i].size, e820.map[i].addr); + switch (e820.map[i].type) { + case E820_RAM: printk("(usable)\n"); + break; + case E820_RESERVED: + printk("(reserved)\n"); + break; + case E820_ACPI: + printk("(ACPI data)\n"); + break; + case E820_NVS: + printk("(ACPI NVS)\n"); + break; + default: printk("type %lu\n", e820.map[i].type); + break; + } + } +} /* * Do NOT EVER look at the BIOS memory size location. @@ -415,11 +441,6 @@ void __init add_memory_region(unsigned long start, void __init setup_memory_region(void) { -#define E820_DEBUG 1 -#ifdef E820_DEBUG - int i; -#endif - /* * If we're lucky and live on a modern system, the setup code * will have given us a memory map that we can use to properly @@ -439,27 +460,6 @@ void __init setup_memory_region(void) if (e820.nr_map > E820MAX) e820.nr_map = E820MAX; memcpy(e820.map, E820_MAP, e820.nr_map * sizeof e820.map[0]); -#ifdef E820_DEBUG - for (i=0; i < e820.nr_map; i++) { - printk("e820: %08x @ %08x ", (int)e820.map[i].size, - (int)e820.map[i].addr); - switch (e820.map[i].type) { - case E820_RAM: printk("(usable)\n"); - break; - case E820_RESERVED: - printk("(reserved)\n"); - break; - case E820_ACPI: - printk("(ACPI data)\n"); - break; - case E820_NVS: - printk("(ACPI NVS)\n"); - break; - default: printk("type %lu\n", e820.map[i].type); - break; - } - } -#endif } else { /* otherwise fake a memory map; one section from 0k->640k, @@ -472,6 +472,8 @@ void __init setup_memory_region(void) add_memory_region(0, LOWMEMSIZE(), E820_RAM); add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); } + printk("BIOS-provided physical RAM map:\n"); + print_e820_map(); } /* setup_memory_region */ @@ -538,6 +540,10 @@ static inline void parse_mem_cmdline (char ** cmdline_p) } *to = '\0'; *cmdline_p = command_line; + if (usermem) { + printk("user-defined physical RAM map:\n"); + print_e820_map(); + } } void __init setup_arch(char **cmdline_p) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index e25f50cfd..7fb5ebc61 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -790,7 +790,7 @@ cobalt_init(void) * On normal SMP PC this is used only with SMP, but we have to * use it and set it up here to start the Cobalt clock */ - set_fixmap(FIX_APIC_BASE, APIC_PHYS_BASE); + set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); printk("Local APIC ID %lx\n", apic_read(APIC_ID)); printk("Local APIC Version %lx\n", apic_read(APIC_LVR)); diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index c801285eb..af72d1581 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -242,8 +242,18 @@ static inline void set_pte_phys (unsigned long vaddr, pte_t *pte; pgd = swapper_pg_dir + __pgd_offset(vaddr); + if (pgd_none(*pgd)) { + printk("PAE BUG #00!\n"); + return; + } pmd = pmd_offset(pgd, vaddr); + if (pmd_none(*pmd)) { + printk("PAE BUG #01!\n"); + return; + } pte = pte_offset(pmd, vaddr); + if (pte_val(*pte)) + pte_ERROR(*pte); pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags); set_pte(pte, mk_pte_phys(phys, prot)); @@ -271,53 +281,65 @@ static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t pmd_t *pmd; pte_t *pte; int i, j; + unsigned long vaddr; - i = __pgd_offset(start); - j = __pmd_offset(start); + vaddr = start; + i = __pgd_offset(vaddr); + j = __pmd_offset(vaddr); pgd = pgd_base + i; - for ( ; (i < PTRS_PER_PGD) && (start != end); pgd++, i++) { + for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { #if CONFIG_X86_PAE if (pgd_none(*pgd)) { pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pgd(pgd, __pgd(__pa(pmd) + 0x1)); - if (pmd != pmd_offset(pgd, start)) - BUG(); + if (pmd != pmd_offset(pgd, 0)) + printk("PAE BUG #02!\n"); } - pmd = pmd_offset(pgd, start); + pmd = pmd_offset(pgd, vaddr); #else pmd = (pmd_t *)pgd; #endif - for (; (j < PTRS_PER_PMD) && start; pmd++, j++) { + for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); if (pte != pte_offset(pmd, 0)) BUG(); } - start += PMD_SIZE; + vaddr += PMD_SIZE; } j = 0; } } -static void __init pagetable_init(void) +static void __init pagetable_init (void) { + unsigned long vaddr, end; pgd_t *pgd, *pgd_base; + int i, j, k; pmd_t *pmd; pte_t *pte; - int i, j, k; - unsigned long vaddr, end; - end = (unsigned long)__va(max_low_pfn*PAGE_SIZE) - 1; + /* + * This can be zero as well - no problem, in that case we exit + * the loops anyway due to the PTRS_PER_* conditions. + */ + end = (unsigned long)__va(max_low_pfn*PAGE_SIZE); - i = __pgd_offset(PAGE_OFFSET); pgd_base = swapper_pg_dir; +#if CONFIG_X86_PAE + for (i = 0; i < PTRS_PER_PGD; i++) { + pgd = pgd_base + i; + __pgd_clear(pgd); + } +#endif + i = __pgd_offset(PAGE_OFFSET); pgd = pgd_base + i; for (; i < PTRS_PER_PGD; pgd++, i++) { vaddr = i*PGDIR_SIZE; - if (vaddr >= end) + if (end && (vaddr >= end)) break; #if CONFIG_X86_PAE pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); @@ -329,7 +351,7 @@ static void __init pagetable_init(void) BUG(); for (j = 0; j < PTRS_PER_PMD; pmd++, j++) { vaddr = i*PGDIR_SIZE + j*PMD_SIZE; - if (vaddr >= end) + if (end && (vaddr >= end)) break; if (cpu_has_pse) { unsigned long __pe; @@ -354,7 +376,7 @@ static void __init pagetable_init(void) for (k = 0; k < PTRS_PER_PTE; pte++, k++) { vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE; - if (vaddr >= end) + if (end && (vaddr >= end)) break; *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL); } |