diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/head.S | 14 | ||||
-rw-r--r-- | arch/i386/kernel/hpet.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/irq.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 32 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 27 | ||||
-rw-r--r-- | arch/i386/pci/common.c | 5 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 34 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 3 |
8 files changed, 52 insertions, 70 deletions
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index eb79aa2fa8bb..a6b8bd89aa27 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -317,20 +317,14 @@ is386: movl $2,%ecx # set MP | |||
317 | movl %eax,%gs | 317 | movl %eax,%gs |
318 | lldt %ax | 318 | lldt %ax |
319 | cld # gcc2 wants the direction flag cleared at all times | 319 | cld # gcc2 wants the direction flag cleared at all times |
320 | pushl %eax # fake return address | ||
320 | #ifdef CONFIG_SMP | 321 | #ifdef CONFIG_SMP |
321 | movb ready, %cl | 322 | movb ready, %cl |
322 | movb $1, ready | 323 | movb $1, ready |
323 | cmpb $0,%cl | 324 | cmpb $0,%cl # the first CPU calls start_kernel |
324 | je 1f # the first CPU calls start_kernel | 325 | jne initialize_secondary # all other CPUs call initialize_secondary |
325 | # all other CPUs call initialize_secondary | ||
326 | call initialize_secondary | ||
327 | jmp L6 | ||
328 | 1: | ||
329 | #endif /* CONFIG_SMP */ | 326 | #endif /* CONFIG_SMP */ |
330 | call start_kernel | 327 | jmp start_kernel |
331 | L6: | ||
332 | jmp L6 # main should never return here, but | ||
333 | # just in case, we know what happens. | ||
334 | 328 | ||
335 | /* | 329 | /* |
336 | * We depend on ET to be correct. This checks for 287/387. | 330 | * We depend on ET to be correct. This checks for 287/387. |
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c index c6737c35815d..17647a530b2f 100644 --- a/arch/i386/kernel/hpet.c +++ b/arch/i386/kernel/hpet.c | |||
@@ -35,7 +35,7 @@ static int __init init_hpet_clocksource(void) | |||
35 | void __iomem* hpet_base; | 35 | void __iomem* hpet_base; |
36 | u64 tmp; | 36 | u64 tmp; |
37 | 37 | ||
38 | if (!hpet_address) | 38 | if (!is_hpet_enabled()) |
39 | return -ENODEV; | 39 | return -ENODEV; |
40 | 40 | ||
41 | /* calculate the hpet address: */ | 41 | /* calculate the hpet address: */ |
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 6cb529f60dcc..5fe547cd8f9f 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c | |||
@@ -82,10 +82,6 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
82 | } | 82 | } |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | if (!irq_desc[irq].handle_irq) { | ||
86 | __do_IRQ(irq, regs); | ||
87 | goto out_exit; | ||
88 | } | ||
89 | #ifdef CONFIG_4KSTACKS | 85 | #ifdef CONFIG_4KSTACKS |
90 | 86 | ||
91 | curctx = (union irq_ctx *) current_thread_info(); | 87 | curctx = (union irq_ctx *) current_thread_info(); |
@@ -125,7 +121,6 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
125 | #endif | 121 | #endif |
126 | __do_IRQ(irq, regs); | 122 | __do_IRQ(irq, regs); |
127 | 123 | ||
128 | out_exit: | ||
129 | irq_exit(); | 124 | irq_exit(); |
130 | 125 | ||
131 | return 1; | 126 | return 1; |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index f1682206d304..345ffb7d904d 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -956,38 +956,6 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) | |||
956 | return 0; | 956 | return 0; |
957 | } | 957 | } |
958 | 958 | ||
959 | /* | ||
960 | * This function checks if the entire range <start,end> is mapped with type. | ||
961 | * | ||
962 | * Note: this function only works correct if the e820 table is sorted and | ||
963 | * not-overlapping, which is the case | ||
964 | */ | ||
965 | int __init | ||
966 | e820_all_mapped(unsigned long s, unsigned long e, unsigned type) | ||
967 | { | ||
968 | u64 start = s; | ||
969 | u64 end = e; | ||
970 | int i; | ||
971 | for (i = 0; i < e820.nr_map; i++) { | ||
972 | struct e820entry *ei = &e820.map[i]; | ||
973 | if (type && ei->type != type) | ||
974 | continue; | ||
975 | /* is the region (part) in overlap with the current region ?*/ | ||
976 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
977 | continue; | ||
978 | /* if the region is at the beginning of <start,end> we move | ||
979 | * start to the end of the region since it's ok until there | ||
980 | */ | ||
981 | if (ei->addr <= start) | ||
982 | start = ei->addr + ei->size; | ||
983 | /* if start is now at or beyond end, we're done, full | ||
984 | * coverage */ | ||
985 | if (start >= end) | ||
986 | return 1; /* we're done */ | ||
987 | } | ||
988 | return 0; | ||
989 | } | ||
990 | |||
991 | /* | 959 | /* |
992 | * Find the highest page frame number we have available | 960 | * Find the highest page frame number we have available |
993 | */ | 961 | */ |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 82e0fd02af1c..7e9edafffd8a 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -92,7 +92,11 @@ asmlinkage void spurious_interrupt_bug(void); | |||
92 | asmlinkage void machine_check(void); | 92 | asmlinkage void machine_check(void); |
93 | 93 | ||
94 | static int kstack_depth_to_print = 24; | 94 | static int kstack_depth_to_print = 24; |
95 | #ifdef CONFIG_STACK_UNWIND | ||
95 | static int call_trace = 1; | 96 | static int call_trace = 1; |
97 | #else | ||
98 | #define call_trace (-1) | ||
99 | #endif | ||
96 | ATOMIC_NOTIFIER_HEAD(i386die_chain); | 100 | ATOMIC_NOTIFIER_HEAD(i386die_chain); |
97 | 101 | ||
98 | int register_die_notifier(struct notifier_block *nb) | 102 | int register_die_notifier(struct notifier_block *nb) |
@@ -187,22 +191,21 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
187 | if (unwind_init_blocked(&info, task) == 0) | 191 | if (unwind_init_blocked(&info, task) == 0) |
188 | unw_ret = show_trace_unwind(&info, log_lvl); | 192 | unw_ret = show_trace_unwind(&info, log_lvl); |
189 | } | 193 | } |
190 | if (unw_ret > 0 && !arch_unw_user_mode(&info)) { | 194 | if (unw_ret > 0) { |
191 | #ifdef CONFIG_STACK_UNWIND | 195 | if (call_trace == 1 && !arch_unw_user_mode(&info)) { |
192 | print_symbol("DWARF2 unwinder stuck at %s\n", | 196 | print_symbol("DWARF2 unwinder stuck at %s\n", |
193 | UNW_PC(&info)); | 197 | UNW_PC(&info)); |
194 | if (call_trace == 1) { | 198 | if (UNW_SP(&info) >= PAGE_OFFSET) { |
195 | printk("Leftover inexact backtrace:\n"); | 199 | printk("Leftover inexact backtrace:\n"); |
196 | if (UNW_SP(&info)) | ||
197 | stack = (void *)UNW_SP(&info); | 200 | stack = (void *)UNW_SP(&info); |
198 | } else if (call_trace > 1) | 201 | } else |
202 | printk("Full inexact backtrace again:\n"); | ||
203 | } else if (call_trace >= 1) | ||
199 | return; | 204 | return; |
200 | else | 205 | else |
201 | printk("Full inexact backtrace again:\n"); | 206 | printk("Full inexact backtrace again:\n"); |
202 | #else | 207 | } else |
203 | printk("Inexact backtrace:\n"); | 208 | printk("Inexact backtrace:\n"); |
204 | #endif | ||
205 | } | ||
206 | } | 209 | } |
207 | 210 | ||
208 | if (task == current) { | 211 | if (task == current) { |
@@ -1241,6 +1244,7 @@ static int __init kstack_setup(char *s) | |||
1241 | } | 1244 | } |
1242 | __setup("kstack=", kstack_setup); | 1245 | __setup("kstack=", kstack_setup); |
1243 | 1246 | ||
1247 | #ifdef CONFIG_STACK_UNWIND | ||
1244 | static int __init call_trace_setup(char *s) | 1248 | static int __init call_trace_setup(char *s) |
1245 | { | 1249 | { |
1246 | if (strcmp(s, "old") == 0) | 1250 | if (strcmp(s, "old") == 0) |
@@ -1254,3 +1258,4 @@ static int __init call_trace_setup(char *s) | |||
1254 | return 1; | 1258 | return 1; |
1255 | } | 1259 | } |
1256 | __setup("call_trace=", call_trace_setup); | 1260 | __setup("call_trace=", call_trace_setup); |
1261 | #endif | ||
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 0a362e3aeac5..1220dd828ce3 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -237,6 +237,11 @@ char * __devinit pcibios_setup(char *str) | |||
237 | pci_probe &= ~PCI_PROBE_MMCONF; | 237 | pci_probe &= ~PCI_PROBE_MMCONF; |
238 | return NULL; | 238 | return NULL; |
239 | } | 239 | } |
240 | /* override DMI blacklist */ | ||
241 | else if (!strcmp(str, "mmconf")) { | ||
242 | pci_probe |= PCI_PROBE_MMCONF_FORCE; | ||
243 | return NULL; | ||
244 | } | ||
240 | #endif | 245 | #endif |
241 | else if (!strcmp(str, "noacpi")) { | 246 | else if (!strcmp(str, "noacpi")) { |
242 | acpi_noirq_set(); | 247 | acpi_noirq_set(); |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 972180f738d9..ef5a2faa7d82 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/dmi.h> | ||
15 | #include <asm/e820.h> | 16 | #include <asm/e820.h> |
16 | #include "pci.h" | 17 | #include "pci.h" |
17 | 18 | ||
@@ -187,9 +188,31 @@ static __init void unreachable_devices(void) | |||
187 | } | 188 | } |
188 | } | 189 | } |
189 | 190 | ||
191 | static int disable_mcfg(struct dmi_system_id *d) | ||
192 | { | ||
193 | printk("PCI: %s detected. Disabling MCFG.\n", d->ident); | ||
194 | pci_probe &= ~PCI_PROBE_MMCONF; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static struct dmi_system_id __initdata dmi_bad_mcfg[] = { | ||
199 | /* Has broken MCFG table that makes the system hang when used */ | ||
200 | { | ||
201 | .callback = disable_mcfg, | ||
202 | .ident = "Intel D3C5105 SDV", | ||
203 | .matches = { | ||
204 | DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), | ||
205 | DMI_MATCH(DMI_BOARD_NAME, "D26928"), | ||
206 | }, | ||
207 | }, | ||
208 | {} | ||
209 | }; | ||
210 | |||
190 | void __init pci_mmcfg_init(void) | 211 | void __init pci_mmcfg_init(void) |
191 | { | 212 | { |
192 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 213 | dmi_check_system(dmi_bad_mcfg); |
214 | |||
215 | if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0) | ||
193 | return; | 216 | return; |
194 | 217 | ||
195 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | 218 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); |
@@ -198,15 +221,6 @@ void __init pci_mmcfg_init(void) | |||
198 | (pci_mmcfg_config[0].base_address == 0)) | 221 | (pci_mmcfg_config[0].base_address == 0)) |
199 | return; | 222 | return; |
200 | 223 | ||
201 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
202 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, | ||
203 | E820_RESERVED)) { | ||
204 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", | ||
205 | pci_mmcfg_config[0].base_address); | ||
206 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
207 | return; | ||
208 | } | ||
209 | |||
210 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); | 224 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); |
211 | raw_pci_ops = &pci_mmcfg; | 225 | raw_pci_ops = &pci_mmcfg; |
212 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 226 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index bf4e79335388..49a849b3a241 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -16,7 +16,8 @@ | |||
16 | #define PCI_PROBE_CONF1 0x0002 | 16 | #define PCI_PROBE_CONF1 0x0002 |
17 | #define PCI_PROBE_CONF2 0x0004 | 17 | #define PCI_PROBE_CONF2 0x0004 |
18 | #define PCI_PROBE_MMCONF 0x0008 | 18 | #define PCI_PROBE_MMCONF 0x0008 |
19 | #define PCI_PROBE_MASK 0x000f | 19 | #define PCI_PROBE_MMCONF_FORCE 0x0010 |
20 | #define PCI_PROBE_MASK 0x00ff | ||
20 | 21 | ||
21 | #define PCI_NO_SORT 0x0100 | 22 | #define PCI_NO_SORT 0x0100 |
22 | #define PCI_BIOS_SORT 0x0200 | 23 | #define PCI_BIOS_SORT 0x0200 |