summaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-06-15 01:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-06-15 01:55:58 +0000
commit53b3988d474435254a3b053a68bb24ce9e439295 (patch)
treef8da8e40f01f4ad02bbd76b8c9920749b118235f /arch/i386
parentb0cb48abe83d1a4389ea938bf624f8baa82c5047 (diff)
Merge with 2.3.99-pre9.
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/config.in1
-rw-r--r--arch/i386/defconfig8
-rw-r--r--arch/i386/kernel/acpi.c2
-rw-r--r--arch/i386/kernel/apic.c5
-rw-r--r--arch/i386/kernel/apm.c50
-rw-r--r--arch/i386/kernel/i8259.c2
-rw-r--r--arch/i386/kernel/io_apic.c32
-rw-r--r--arch/i386/kernel/irq.c8
-rw-r--r--arch/i386/kernel/ldt.c1
-rw-r--r--arch/i386/kernel/mpparse.c15
-rw-r--r--arch/i386/kernel/pci-i386.c22
-rw-r--r--arch/i386/kernel/pci-irq.c3
-rw-r--r--arch/i386/kernel/pci-pc.c11
-rw-r--r--arch/i386/kernel/setup.c58
-rw-r--r--arch/i386/kernel/traps.c2
-rw-r--r--arch/i386/mm/init.c54
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);
}