summaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r--arch/i386/kernel/head.S160
-rw-r--r--arch/i386/kernel/irq.c1
-rw-r--r--arch/i386/kernel/pci-i386.c54
-rw-r--r--arch/i386/kernel/pci-i386.h5
-rw-r--r--arch/i386/kernel/pci-pc.c77
-rw-r--r--arch/i386/kernel/pci-visws.c6
-rw-r--r--arch/i386/kernel/setup.c252
-rw-r--r--arch/i386/kernel/smpboot.c55
-rw-r--r--arch/i386/kernel/traps.c8
-rw-r--r--arch/i386/kernel/visws_apic.c2
-rw-r--r--arch/i386/kernel/vm86.c4
11 files changed, 449 insertions, 175 deletions
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index f1aa50586..423308aae 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -367,11 +367,13 @@ SYMBOL_NAME(gdt):
.org 0x1000
ENTRY(swapper_pg_dir)
.long 0x00102007
- .fill __USER_PGD_PTRS-1,4,0
- /* default: 767 entries */
+ .long 0x00103007
+ .fill BOOT_USER_PGD_PTRS-2,4,0
+ /* default: 766 entries */
.long 0x00102007
- /* default: 255 entries */
- .fill __KERNEL_PGD_PTRS-1,4,0
+ .long 0x00103007
+ /* default: 254 entries */
+ .fill BOOT_KERNEL_PGD_PTRS-2,4,0
/*
* The page tables are initialized to only 4MB here - the final page
@@ -509,16 +511,156 @@ ENTRY(pg0)
.long 0x3f0007,0x3f1007,0x3f2007,0x3f3007,0x3f4007,0x3f5007,0x3f6007,0x3f7007
.long 0x3f8007,0x3f9007,0x3fa007,0x3fb007,0x3fc007,0x3fd007,0x3fe007,0x3ff007
-.org 0x3000
-ENTRY(empty_bad_page)
-
+ENTRY(pg1)
+ .long 0x400007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007
+ .long 0x408007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007
+ .long 0x410007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007
+ .long 0x418007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007
+ .long 0x420007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007
+ .long 0x428007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007
+ .long 0x430007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007
+ .long 0x438007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007
+ .long 0x440007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007
+ .long 0x448007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007
+ .long 0x450007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007
+ .long 0x458007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007
+ .long 0x460007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007
+ .long 0x468007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007
+ .long 0x470007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007
+ .long 0x478007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007
+ .long 0x480007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007
+ .long 0x488007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007
+ .long 0x490007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007
+ .long 0x498007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007
+ .long 0x4a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007
+ .long 0x4a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007
+ .long 0x4b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007
+ .long 0x4b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007
+ .long 0x4c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007
+ .long 0x4c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007
+ .long 0x4d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007
+ .long 0x4d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007
+ .long 0x4e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007
+ .long 0x4e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007
+ .long 0x4f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007
+ .long 0x4f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007
+ .long 0x500007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007
+ .long 0x508007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007
+ .long 0x510007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007
+ .long 0x518007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007
+ .long 0x520007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007
+ .long 0x528007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007
+ .long 0x530007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007
+ .long 0x538007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007
+ .long 0x540007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007
+ .long 0x548007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007
+ .long 0x550007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007
+ .long 0x558007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007
+ .long 0x560007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007
+ .long 0x568007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007
+ .long 0x570007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007
+ .long 0x578007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007
+ .long 0x580007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007
+ .long 0x588007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007
+ .long 0x590007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007
+ .long 0x598007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007
+ .long 0x5a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007
+ .long 0x5a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007
+ .long 0x5b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007
+ .long 0x5b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007
+ .long 0x5c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007
+ .long 0x5c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007
+ .long 0x5d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007
+ .long 0x5d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007
+ .long 0x5e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007
+ .long 0x5e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007
+ .long 0x5f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007
+ .long 0x5f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007
+ .long 0x600007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007
+ .long 0x608007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007
+ .long 0x610007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007
+ .long 0x618007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007
+ .long 0x620007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007
+ .long 0x628007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007
+ .long 0x630007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007
+ .long 0x638007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007
+ .long 0x640007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007
+ .long 0x648007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007
+ .long 0x650007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007
+ .long 0x658007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007
+ .long 0x660007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007
+ .long 0x668007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007
+ .long 0x670007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007
+ .long 0x678007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007
+ .long 0x680007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007
+ .long 0x688007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007
+ .long 0x690007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007
+ .long 0x698007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007
+ .long 0x6a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007
+ .long 0x6a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007
+ .long 0x6b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007
+ .long 0x6b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007
+ .long 0x6c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007
+ .long 0x6c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007
+ .long 0x6d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007
+ .long 0x6d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007
+ .long 0x6e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007
+ .long 0x6e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007
+ .long 0x6f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007
+ .long 0x6f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007
+ .long 0x700007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007
+ .long 0x708007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007
+ .long 0x710007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007
+ .long 0x718007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007
+ .long 0x720007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007
+ .long 0x728007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007
+ .long 0x730007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007
+ .long 0x738007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007
+ .long 0x740007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007
+ .long 0x748007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007
+ .long 0x750007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007
+ .long 0x758007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007
+ .long 0x760007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007
+ .long 0x768007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007
+ .long 0x770007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007
+ .long 0x778007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007
+ .long 0x780007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007
+ .long 0x788007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007
+ .long 0x790007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007
+ .long 0x798007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007
+ .long 0x7a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007
+ .long 0x7a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007
+ .long 0x7b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007
+ .long 0x7b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007
+ .long 0x7c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007
+ .long 0x7c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007
+ .long 0x7d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007
+ .long 0x7d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007
+ .long 0x7e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007
+ .long 0x7e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007
+ .long 0x7f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007
+ .long 0x7f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007
.org 0x4000
-ENTRY(empty_bad_page_table)
+ENTRY(empty_zero_page)
.org 0x5000
-ENTRY(empty_zero_page)
+ENTRY(empty_bad_page)
.org 0x6000
+ENTRY(empty_bad_pte_table)
+
+#if CONFIG_X86_PAE
+
+ .org 0x7000
+ ENTRY(empty_bad_pmd_table)
+
+ .org 0x8000
+
+#else
+
+ .org 0x7000
+
+#endif
/*
* This starts the data section. Note that the above is all
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 8ec329287..75659aac4 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -20,6 +20,7 @@
* Naturally it's not a 1:1 relation, but there are similarities.
*/
+#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/signal.h>
diff --git a/arch/i386/kernel/pci-i386.c b/arch/i386/kernel/pci-i386.c
index af362611d..8e609ec36 100644
--- a/arch/i386/kernel/pci-i386.c
+++ b/arch/i386/kernel/pci-i386.c
@@ -177,7 +177,7 @@ static int __init pcibios_assign_resource(struct pci_dev *dev, int i)
* (4) Assign new addresses to resources which were either
* not configured at all or misconfigured. If explicitly
* requested by the user, configure expansion ROM address
- * as well. Finally enable the I/O and Memory bits.
+ * as well.
*/
static void __init pcibios_allocate_bus_resources(struct pci_bus *bus)
@@ -252,21 +252,18 @@ static void __init pcibios_allocate_resources(int pass)
static void __init pcibios_assign_resources(void)
{
struct pci_dev *dev;
- u16 cmd, old_cmd;
int idx;
- int fault = 0;
struct resource *r;
for(dev=pci_devices; dev; dev=dev->next) {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
for(idx=0; idx<6; idx++) {
r = &dev->resource[idx];
if (((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && idx < 4) ||
- ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+ ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)) ||
+ !dev->class || (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
/*
* Don't touch IDE controllers and I/O ports of video cards!
- * Neither enable anything in their command registers.
+ * Also avoid classless devices and host bridges.
*/
continue;
if (!r->start && r->end) {
@@ -275,24 +272,9 @@ static void __init pcibios_assign_resources(void)
* the BIOS forgot to do so or because we have decided the old
* address was unusable for some reason.
*/
- if (pcibios_assign_resource(dev, idx) < 0)
- fault = 1;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
-
- if (cmd != old_cmd) {
- if (fault)
- printk("PCI: Not enabling device %s because of resource collisions\n", dev->slot_name);
- else {
- printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pcibios_assign_resource(dev, idx);
}
}
-
if (pci_probe & PCI_ASSIGN_ROMS) {
r = &dev->resource[PCI_ROM_RESOURCE];
r->end -= r->start;
@@ -310,3 +292,29 @@ void __init pcibios_resource_survey(void)
pcibios_allocate_resources(1);
pcibios_assign_resources();
}
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for(idx=0; idx<6; idx++) {
+ r = &dev->resource[idx];
+ if (!r->start && r->end) {
+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
diff --git a/arch/i386/kernel/pci-i386.h b/arch/i386/kernel/pci-i386.h
index 41ac2b856..1be988b6c 100644
--- a/arch/i386/kernel/pci-i386.h
+++ b/arch/i386/kernel/pci-i386.h
@@ -18,12 +18,13 @@
#define PCI_NO_SORT 0x100
#define PCI_BIOS_SORT 0x200
#define PCI_NO_CHECKS 0x400
-#define PCI_NO_PEER_FIXUP 0x800
+#define PCI_PEER_FIXUP 0x800
#define PCI_ASSIGN_ROMS 0x1000
-#define PCI_NO_IRQ_SCAN 0x2000
+#define PCI_BIOS_IRQ_SCAN 0x2000
extern unsigned int pci_probe;
/* pci-i386.c */
void pcibios_resource_survey(void);
+int pcibios_enable_resources(struct pci_dev *);
diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c
index 8ce187d3f..61d13af55 100644
--- a/arch/i386/kernel/pci-pc.c
+++ b/arch/i386/kernel/pci-pc.c
@@ -688,7 +688,7 @@ static struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
struct irq_routing_table *rt;
int ret, map;
- if (pci_probe & PCI_NO_IRQ_SCAN)
+ if (!(pci_probe & PCI_BIOS_IRQ_SCAN))
return NULL;
pcibios_irq_page = __get_free_page(GFP_KERNEL);
if (!pcibios_irq_page)
@@ -868,7 +868,30 @@ static void __init pci_fixup_i450nx(struct pci_dev *d)
if (suba < subb)
pci_scan_bus(suba+1, pci_root->ops, NULL); /* Bus B */
}
- pci_probe |= PCI_NO_PEER_FIXUP;
+}
+
+static void __init pci_fixup_rcc(struct pci_dev *d)
+{
+ /*
+ * RCC 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);
+ pci_scan_bus(busno, pci_root->ops, NULL);
+}
+
+static void __init pci_fixup_compaq(struct pci_dev *d)
+{
+ /*
+ * Compaq host bridges -- Find and scan all secondary buses.
+ * This time registers 0xc8 and 0xc9.
+ */
+ u8 busno;
+ pci_read_config_byte(d, 0xc8, &busno);
+ printk("PCI: Compaq host bridge: secondary bus %02x\n", busno);
+ pci_scan_bus(busno, pci_root->ops, NULL);
}
static void __init pci_fixup_umc_ide(struct pci_dev *d)
@@ -905,6 +928,9 @@ static void __init pci_fixup_ide_bases(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_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_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_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
{ 0 }
@@ -919,6 +945,8 @@ extern int skip_ioapic_setup;
#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
#define PIRQ_VERSION 0x0100
+static struct irq_routing_table *pirq_table;
+
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -974,7 +1002,6 @@ static void __init pcibios_irq_peer_trick(struct irq_routing_table *rt)
*/
if (busmap[i] && pci_scan_bus(i, pci_root->ops, NULL))
printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i);
- pci_probe |= PCI_NO_PEER_FIXUP;
}
/*
@@ -982,7 +1009,7 @@ static void __init pcibios_irq_peer_trick(struct irq_routing_table *rt)
* table, but unfortunately we have to know the interrupt router chip.
*/
-static char * __init pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *rt, int pin)
+static char *pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *rt, int pin, int assign)
{
struct irq_info *q;
struct pci_dev *router;
@@ -1012,9 +1039,9 @@ static char * __init pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_
return NULL;
}
DBG(" -> PIRQ %02x, mask %04x", pirq, mask);
- if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+ if (!assign || (dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
newirq = 0;
- else for(newirq = 15; newirq && !(mask & (1 << newirq)); newirq--)
+ else for(newirq = 13; newirq && !(mask & (1 << newirq)); newirq--)
;
if (!(router = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
DBG(" -> router not found\n");
@@ -1068,7 +1095,7 @@ static void __init pcibios_fixup_irqs(void)
struct pci_dev *dev;
u8 pin;
- rtable = pcibios_find_irq_routing_table();
+ rtable = pirq_table = pcibios_find_irq_routing_table();
#ifdef CONFIG_PCI_BIOS
if (!rtable && pci_bios_present)
rtable = pcibios_get_irq_routing_table();
@@ -1106,7 +1133,7 @@ static void __init pcibios_fixup_irqs(void)
dev->irq = irq;
}
}
- rtable = NULL; /* Avoid IRQ assignment below */
+ pirq_table = NULL; /* Avoid automatic IRQ assignment */
}
#endif
/*
@@ -1114,10 +1141,10 @@ static void __init pcibios_fixup_irqs(void)
*/
if (dev->irq >= NR_IRQS)
dev->irq = 0;
- if (pin && !dev->irq && rtable && rtable->version) {
- char *msg = pcibios_lookup_irq(dev, rtable, pin);
+ if (pin && !dev->irq && pirq_table) {
+ char *msg = pcibios_lookup_irq(dev, pirq_table, pin, 0);
if (msg)
- printk("PCI: Assigned IRQ %d to device %s [%s]\n", dev->irq, dev->slot_name, msg);
+ printk("PCI: Found IRQ %d for device %s [%s]\n", dev->irq, dev->slot_name, msg);
}
}
@@ -1173,7 +1200,7 @@ void __init pcibios_init(void)
pci_scan_bus(0, ops, NULL);
pcibios_fixup_irqs();
- if (!(pci_probe & PCI_NO_PEER_FIXUP))
+ if (pci_probe & PCI_PEER_FIXUP)
pcibios_fixup_peer_bridges();
pcibios_resource_survey();
@@ -1199,8 +1226,8 @@ char * __init pcibios_setup(char *str)
} else if (!strcmp(str, "nosort")) {
pci_probe |= PCI_NO_SORT;
return NULL;
- } else if (!strcmp(str, "noirq")) {
- pci_probe |= PCI_NO_IRQ_SCAN;
+ } else if (!strcmp(str, "biosirq")) {
+ pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
}
#endif
@@ -1214,8 +1241,8 @@ char * __init pcibios_setup(char *str)
return NULL;
}
#endif
- else if (!strcmp(str, "nopeer")) {
- pci_probe |= PCI_NO_PEER_FIXUP;
+ else if (!strcmp(str, "peer")) {
+ pci_probe |= PCI_PEER_FIXUP;
return NULL;
} else if (!strcmp(str, "rom")) {
pci_probe |= PCI_ASSIGN_ROMS;
@@ -1223,3 +1250,21 @@ char * __init pcibios_setup(char *str)
}
return str;
}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+ int err;
+
+ if ((err = pcibios_enable_resources(dev)) < 0)
+ return err;
+ if (!dev->irq && pirq_table) {
+ u8 pin;
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+ if (pin) {
+ char *msg = pcibios_lookup_irq(dev, pirq_table, pin, 1);
+ if (msg)
+ printk("PCI: Assigned IRQ %d to device %s [%s]\n", dev->irq, dev->slot_name, msg);
+ }
+ }
+ return 0;
+}
diff --git a/arch/i386/kernel/pci-visws.c b/arch/i386/kernel/pci-visws.c
index 31a767a22..8a954ce8b 100644
--- a/arch/i386/kernel/pci-visws.c
+++ b/arch/i386/kernel/pci-visws.c
@@ -14,6 +14,7 @@
#include <asm/smp.h>
#include <asm/lithium.h>
+#include <asm/io.h>
#include "pci-i386.h"
@@ -129,3 +130,8 @@ char * __init pcibios_setup(char *str)
{
return str;
}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+ return pcibios_enable_resources(dev);
+}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 734cfca65..31c77bb1d 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -54,7 +54,8 @@
#ifdef CONFIG_BLK_DEV_RAM
#include <linux/blk.h>
#endif
-#include <linux/bigmem.h>
+#include <linux/highmem.h>
+#include <linux/bootmem.h>
#include <asm/processor.h>
#include <linux/console.h>
#include <asm/uaccess.h>
@@ -401,12 +402,15 @@ void __init add_memory_region(unsigned long start,
} /* add_memory_region */
-#define LOWMEMSIZE() ((*(unsigned short *)__va(0x413)) * 1024)
-
+/*
+ * Do NOT EVER look at the BIOS memory size location.
+ * It does not work on many machines.
+ */
+#define LOWMEMSIZE() (0x9f000)
void __init setup_memory_region(void)
{
-#define E820_DEBUG 0
+#define E820_DEBUG 1
#ifdef E820_DEBUG
int i;
#endif
@@ -432,9 +436,8 @@ void __init setup_memory_region(void)
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: %ld @ %08lx ",
- (unsigned long)(e820.map[i].size),
- (unsigned long)(e820.map[i].addr));
+ 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;
@@ -464,48 +467,11 @@ void __init setup_memory_region(void)
} /* setup_memory_region */
-void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)
+static inline void parse_mem_cmdline (char ** cmdline_p)
{
- unsigned long high_pfn, max_pfn;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
- int i;
- int usermem=0;
-
-#ifdef CONFIG_VISWS
- visws_get_board_type_and_rev();
-#endif
-
- ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
- drive_info = DRIVE_INFO;
- screen_info = SCREEN_INFO;
- apm_bios_info = APM_BIOS_INFO;
- if( SYS_DESC_TABLE.length != 0 ) {
- MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
- machine_id = SYS_DESC_TABLE.table[0];
- machine_submodel_id = SYS_DESC_TABLE.table[1];
- BIOS_revision = SYS_DESC_TABLE.table[2];
- }
- aux_device_present = AUX_DEVICE_INFO;
-
-#ifdef CONFIG_BLK_DEV_RAM
- rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
- setup_memory_region();
-
- if (!MOUNT_ROOT_RDONLY)
- root_mountflags &= ~MS_RDONLY;
- init_mm.start_code = (unsigned long) &_text;
- init_mm.end_code = (unsigned long) &_etext;
- init_mm.end_data = (unsigned long) &_edata;
- init_mm.brk = (unsigned long) &_end;
-
- code_resource.start = virt_to_bus(&_text);
- code_resource.end = virt_to_bus(&_etext)-1;
- data_resource.start = virt_to_bus(&_etext);
- data_resource.end = virt_to_bus(&_edata)-1;
+ int usermem = 0;
/* Save unparsed command line copy for /proc/cmdline */
memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
@@ -519,8 +485,9 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
* "mem=XXX[KkmM]@XXX[KkmM]" defines a memory region from
* <start> to <start>+<mem>, overriding the bios size.
*/
- if (c == ' ' && *(const unsigned long *)from == *(const unsigned long *)"mem=") {
- if (to != command_line) to--;
+ if (c == ' ' && !memcmp(from, "mem=", 4)) {
+ if (to != command_line)
+ to--;
if (!memcmp(from+4, "nopentium", 9)) {
from += 9+4;
boot_cpu_data.x86_capability &= ~X86_FEATURE_PSE;
@@ -542,7 +509,7 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
}
mem_size = memparse(from+4, &from);
if (*from == '@')
- start_at = memparse(from+1,&from);
+ start_at = memparse(from+1, &from);
else {
start_at = HIGH_MEMORY;
mem_size -= HIGH_MEMORY;
@@ -559,54 +526,166 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
}
*to = '\0';
*cmdline_p = command_line;
+}
- /* Find the highest page frame number we have available */
- max_pfn = 0;
- for (i=0; i < e820.nr_map; i++) {
- /* RAM? */
- if (e820.map[i].type == E820_RAM) {
- unsigned long end_pfn = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT;
+void __init setup_arch(char **cmdline_p)
+{
+ unsigned long bootmap_size;
+ unsigned long start_pfn, max_pfn, max_low_pfn;
+ int i;
- if (end_pfn > max_pfn)
- max_pfn = end_pfn;
- }
+#ifdef CONFIG_VISWS
+ visws_get_board_type_and_rev();
+#endif
+
+ ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
+ drive_info = DRIVE_INFO;
+ screen_info = SCREEN_INFO;
+ apm_bios_info = APM_BIOS_INFO;
+ if( SYS_DESC_TABLE.length != 0 ) {
+ MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
+ machine_id = SYS_DESC_TABLE.table[0];
+ machine_submodel_id = SYS_DESC_TABLE.table[1];
+ BIOS_revision = SYS_DESC_TABLE.table[2];
}
+ aux_device_present = AUX_DEVICE_INFO;
-/*
- * We can only allocate a limited amount of direct-mapped memory
- */
-#define VMALLOC_RESERVE (128 << 20) /* 128MB for vmalloc and initrd */
-#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
-#define MAXMEM_PFN (MAXMEM >> PAGE_SHIFT)
+#ifdef CONFIG_BLK_DEV_RAM
+ rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
+ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+#endif
+ setup_memory_region();
+
+ if (!MOUNT_ROOT_RDONLY)
+ root_mountflags &= ~MS_RDONLY;
+ init_mm.start_code = (unsigned long) &_text;
+ init_mm.end_code = (unsigned long) &_etext;
+ init_mm.end_data = (unsigned long) &_edata;
+ init_mm.brk = (unsigned long) &_end;
- high_pfn = MAXMEM_PFN;
- if (max_pfn < high_pfn)
- high_pfn = max_pfn;
+ code_resource.start = virt_to_bus(&_text);
+ code_resource.end = virt_to_bus(&_etext)-1;
+ data_resource.start = virt_to_bus(&_etext);
+ data_resource.end = virt_to_bus(&_edata)-1;
+
+ parse_mem_cmdline(cmdline_p);
+
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
/*
- * But the bigmem stuff may be able to use more of it
- * (but currently only up to about 4GB)
+ * 128MB for vmalloc and initrd
*/
-#ifdef CONFIG_BIGMEM
- #define MAXBIGMEM ((unsigned long)(~(VMALLOC_RESERVE-1)))
- #define MAXBIGMEM_PFN (MAXBIGMEM >> PAGE_SHIFT)
- if (max_pfn > MAX_PFN)
- max_pfn = MAX_PFN;
-
-/* When debugging, make half of "normal" memory be BIGMEM memory instead */
-#ifdef BIGMEM_DEBUG
- high_pfn >>= 1;
-#endif
+#define VMALLOC_RESERVE (unsigned long)(128 << 20)
+#define MAXMEM (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
+#define MAXMEM_PFN PFN_DOWN(MAXMEM)
+
+ /*
+ * partially used pages are not usable - thus
+ * we are rounding upwards:
+ */
+ start_pfn = PFN_UP(__pa(&_end));
- bigmem_start = high_pfn << PAGE_SHIFT;
- bigmem_end = max_pfn << PAGE_SHIFT;
- printk(KERN_NOTICE "%ldMB BIGMEM available.\n", (bigmem_end-bigmem_start) >> 20);
+ /*
+ * Find the highest page frame number we have available
+ */
+ max_pfn = 0;
+ for (i = 0; i < e820.nr_map; i++) {
+ unsigned long curr_pfn;
+ /* RAM? */
+ if (e820.map[i].type != E820_RAM)
+ continue;
+ curr_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
+ if (curr_pfn > max_pfn)
+ max_pfn = curr_pfn;
+ }
+
+ /*
+ * Determine low and high memory ranges:
+ */
+ max_low_pfn = max_pfn;
+ if (max_low_pfn > MAXMEM_PFN)
+ max_low_pfn = MAXMEM_PFN;
+
+#ifdef CONFIG_HIGHMEM
+ highstart_pfn = highend_pfn = max_pfn;
+ if (max_pfn > MAXMEM_PFN) {
+ highstart_pfn = MAXMEM_PFN;
+ highend_pfn = max_pfn;
+ printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+ pages_to_mb(highend_pfn - highstart_pfn));
+ }
#endif
+ /*
+ * Initialize the boot-time allocator (with low memory only):
+ */
+ bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+
+ /*
+ * FIXME: what about high memory?
+ */
+ ram_resources[1].end = PFN_PHYS(max_low_pfn);
+
+ /*
+ * Register fully available low RAM pages with the bootmem allocator.
+ */
+ for (i = 0; i < e820.nr_map; i++) {
+ unsigned long curr_pfn, last_pfn, size;
+ /*
+ * Reserve usable low memory
+ */
+ if (e820.map[i].type != E820_RAM)
+ continue;
+ /*
+ * We are rounding up the start address of usable memory:
+ */
+ curr_pfn = PFN_UP(e820.map[i].addr);
+ if (curr_pfn >= max_low_pfn)
+ continue;
+ /*
+ * ... and at the end of the usable range downwards:
+ */
+ last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
- ram_resources[1].end = (high_pfn << PAGE_SHIFT)-1;
+ if (last_pfn > max_low_pfn)
+ last_pfn = max_low_pfn;
- *memory_start_p = (unsigned long) &_end;
- *memory_end_p = PAGE_OFFSET + (high_pfn << PAGE_SHIFT);
+ /*
+ * .. finally, did all the rounding and playing
+ * around just make the area go away?
+ */
+ if (last_pfn <= curr_pfn)
+ continue;
+
+ size = last_pfn - curr_pfn;
+ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
+ }
+ /*
+ * Reserve the bootmem bitmap itself as well. We do this in two
+ * steps (first step was init_bootmem()) because this catches
+ * the (very unlikely) case of us accidentally initializing the
+ * bootmem allocator with an invalid RAM area.
+ */
+ reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
+ bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
+
+ /*
+ * reserve physical page 0 - it's a special BIOS page on many boxes,
+ * enabling clean reboots, SMP operation, laptop functions.
+ */
+ reserve_bootmem(0, PAGE_SIZE);
+
+#ifdef __SMP__
+ /*
+ * But first pinch a few for the stack/trampoline stuff
+ * FIXME: Don't need the extra page at 4K, but need to fix
+ * trampoline before removing it. (see the GDT stuff)
+ */
+ reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
+ smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
+#endif
#ifdef __SMP__
/*
@@ -616,10 +695,11 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
#endif
#ifdef CONFIG_BLK_DEV_INITRD
+// FIXME needs to do the new bootmem alloc stuff
if (LOADER_TYPE) {
initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
initrd_end = initrd_start+INITRD_SIZE;
- if (initrd_end > memory_end) {
+ if (initrd_end > (max_low_pfn << PAGE_SHIFT)) {
printk("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
initrd_end,memory_end);
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 46335ee8f..4386e8dd0 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -39,6 +39,7 @@
#include <linux/kernel_stat.h>
#include <linux/smp_lock.h>
#include <linux/irq.h>
+#include <linux/bootmem.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
@@ -630,12 +631,15 @@ static unsigned long __init setup_trampoline(void)
* We are called very early to get the low memory for the
* SMP bootup trampoline page.
*/
-unsigned long __init smp_alloc_memory(unsigned long mem_base)
+void __init smp_alloc_memory(void)
{
- if (virt_to_phys((void *)mem_base) >= 0x9F000)
+ trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE);
+ /*
+ * Has to be in very low memory so we can execute
+ * real-mode AP code.
+ */
+ if (__pa(trampoline_base) >= 0x9F000)
BUG();
- trampoline_base = (void *)mem_base;
- return mem_base + PAGE_SIZE;
}
/*
@@ -804,11 +808,10 @@ void __init setup_local_APIC(void)
apic_write(APIC_DFR, value);
}
-unsigned long __init init_smp_mappings(unsigned long memory_start)
+void __init init_smp_mappings(void)
{
unsigned long apic_phys;
- memory_start = PAGE_ALIGN(memory_start);
if (smp_found_config) {
apic_phys = mp_lapic_addr;
} else {
@@ -818,11 +821,10 @@ unsigned long __init init_smp_mappings(unsigned long memory_start)
* could use the real zero-page, but it's safer
* this way if some buggy code writes to this page ...
*/
- apic_phys = __pa(memory_start);
- memset((void *)memory_start, 0, PAGE_SIZE);
- memory_start += PAGE_SIZE;
+ apic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE));
+ memset((void *)apic_phys, 0, PAGE_SIZE);
}
- set_fixmap(FIX_APIC_BASE,apic_phys);
+ set_fixmap(FIX_APIC_BASE, apic_phys);
dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
#ifdef CONFIG_X86_IO_APIC
@@ -834,9 +836,8 @@ unsigned long __init init_smp_mappings(unsigned long memory_start)
if (smp_found_config) {
ioapic_phys = mp_ioapics[i].mpc_apicaddr;
} else {
- ioapic_phys = __pa(memory_start);
- memset((void *)memory_start, 0, PAGE_SIZE);
- memory_start += PAGE_SIZE;
+ ioapic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE));
+ memset((void *)ioapic_phys, 0, PAGE_SIZE);
}
set_fixmap(idx,ioapic_phys);
dprintk("mapped IOAPIC to %08lx (%08lx)\n",
@@ -845,8 +846,6 @@ unsigned long __init init_smp_mappings(unsigned long memory_start)
}
}
#endif
-
- return memory_start;
}
/*
@@ -1112,6 +1111,12 @@ int __init start_secondary(void *unused)
smp_callin();
while (!atomic_read(&smp_commenced))
/* nothing */ ;
+ /*
+ * low-memory mappings have been cleared, flush them from
+ * the local TLBs too.
+ */
+ local_flush_tlb();
+
return cpu_idle();
}
@@ -1153,7 +1158,6 @@ static int __init fork_by_hand(void)
static void __init do_boot_cpu(int i)
{
unsigned long cfg;
- pgd_t maincfg;
struct task_struct *idle;
unsigned long send_status, accept_status;
int timeout, num_starts, j;
@@ -1207,9 +1211,6 @@ static void __init do_boot_cpu(int i)
*((volatile unsigned short *) phys_to_virt(0x467)) = start_eip & 0xf;
dprintk("3.\n");
- maincfg=swapper_pg_dir[0];
- ((unsigned long *)swapper_pg_dir)[0]=0x102007;
-
/*
* Be paranoid about clearing APIC errors.
*/
@@ -1367,9 +1368,6 @@ static void __init do_boot_cpu(int i)
cpucount--;
}
- swapper_pg_dir[0]=maincfg;
- local_flush_tlb();
-
/* mark "stuck" area as not stuck */
*((volatile unsigned long *)phys_to_virt(8192)) = 0;
}
@@ -1567,14 +1565,9 @@ void __init smp_boot_cpus(void)
#ifndef CONFIG_VISWS
{
- unsigned long cfg;
-
/*
* Install writable page 0 entry to set BIOS data area.
*/
- cfg = pg0[0];
- /* writeable, present, addr 0 */
- pg0[0] = _PAGE_RW | _PAGE_PRESENT | 0;
local_flush_tlb();
/*
@@ -1584,12 +1577,6 @@ void __init smp_boot_cpus(void)
CMOS_WRITE(0, 0xf);
*((volatile long *) phys_to_virt(0x467)) = 0;
-
- /*
- * Restore old page 0 entry.
- */
- pg0[0] = cfg;
- local_flush_tlb();
}
#endif
@@ -1646,5 +1633,7 @@ smp_done:
*/
if (cpu_has_tsc && cpucount)
synchronize_tsc_bp();
+
+ zap_low_mappings();
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index ebd1cd002..f66f2363c 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -581,6 +581,7 @@ asmlinkage void math_emulate(long arg)
#endif /* CONFIG_MATH_EMULATION */
+#ifndef CONFIG_M686
void __init trap_init_f00f_bug(void)
{
unsigned long page;
@@ -596,8 +597,8 @@ void __init trap_init_f00f_bug(void)
pgd = pgd_offset(&init_mm, page);
pmd = pmd_offset(pgd, page);
pte = pte_offset(pmd, page);
- free_page(pte_page(*pte));
- *pte = mk_pte(&idt_table, PAGE_KERNEL_RO);
+ __free_page(pte_page(*pte));
+ *pte = mk_pte_phys(__pa(&idt_table), PAGE_KERNEL_RO);
local_flush_tlb();
/*
@@ -608,6 +609,7 @@ void __init trap_init_f00f_bug(void)
idt = (struct desc_struct *)page;
__asm__ __volatile__("lidt %0": "=m" (idt_descr));
}
+#endif
#define _set_gate(gate_addr,type,dpl,addr) \
do { \
@@ -772,7 +774,7 @@ cobalt_init(void)
#endif
void __init trap_init(void)
{
- if (readl(0x0FFFD9) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
+ if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24))
EISA_bus = 1;
set_trap_gate(0,&divide_error);
diff --git a/arch/i386/kernel/visws_apic.c b/arch/i386/kernel/visws_apic.c
index de79fe61e..6c767d0eb 100644
--- a/arch/i386/kernel/visws_apic.c
+++ b/arch/i386/kernel/visws_apic.c
@@ -37,7 +37,7 @@
#include <asm/cobalt.h>
-#include "irq.h"
+#include <linux/irq.h>
/*
* This is the PIIX4-based 8259 that is wired up indirectly to Cobalt
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 65dd7e9da..3fd5262ac 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -102,7 +102,7 @@ static void mark_screen_rdonly(struct task_struct * tsk)
if (pgd_none(*pgd))
return;
if (pgd_bad(*pgd)) {
- printk("vm86: bad pgd entry [%p]:%08lx\n", pgd, pgd_val(*pgd));
+ pgd_ERROR(*pgd);
pgd_clear(pgd);
return;
}
@@ -110,7 +110,7 @@ static void mark_screen_rdonly(struct task_struct * tsk)
if (pmd_none(*pmd))
return;
if (pmd_bad(*pmd)) {
- printk("vm86: bad pmd entry [%p]:%08lx\n", pmd, pmd_val(*pmd));
+ pmd_ERROR(*pmd);
pmd_clear(pmd);
return;
}