summaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-01-11 04:02:40 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-01-11 04:02:40 +0000
commite47f00743fc4776491344f2c618cc8dc2c23bcbc (patch)
tree13e03a113a82a184c51c19c209867cfd3a59b3b9 /arch/i386
parentb2ad5f821b1381492d792ca10b1eb7a107b48f14 (diff)
Merge with Linux 2.4.0.
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/pci-irq.c71
-rw-r--r--arch/i386/kernel/process.c15
-rw-r--r--arch/i386/kernel/traps.c51
-rw-r--r--arch/i386/vmlinux.lds5
4 files changed, 62 insertions, 80 deletions
diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c
index af0757e01..bd2bf22d3 100644
--- a/arch/i386/kernel/pci-irq.c
+++ b/arch/i386/kernel/pci-irq.c
@@ -157,25 +157,7 @@ static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
- switch (pirq) {
- case 0x00:
- return 0;
- default:
- return irqmap[read_config_nybble(router, 0x48, pirq-1)];
- case 0xfe:
- return irqmap[read_config_nybble(router, 0x44, 0)];
- case 0xff:
- return irqmap[read_config_nybble(router, 0x75, 0)];
- }
-}
-
-static void pirq_ali_ide_interrupt(struct pci_dev *router, unsigned reg, unsigned val, unsigned irq)
-{
- u8 x;
-
- pci_read_config_byte(router, reg, &x);
- x = (x & 0xe0) | val; /* clear the level->edge transform */
- pci_write_config_byte(router, reg, x);
+ return irqmap[read_config_nybble(router, 0x48, pirq-1)];
}
static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
@@ -184,17 +166,7 @@ static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
unsigned int val = irqmap[irq];
if (val) {
- switch (pirq) {
- default:
- write_config_nybble(router, 0x48, pirq-1, val);
- break;
- case 0xfe:
- pirq_ali_ide_interrupt(router, 0x44, val, irq);
- break;
- case 0xff:
- pirq_ali_ide_interrupt(router, 0x75, val, irq);
- break;
- }
+ write_config_nybble(router, 0x48, pirq-1, val);
return 1;
}
return 0;
@@ -202,40 +174,25 @@ static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
/*
* The Intel PIIX4 pirq rules are fairly simple: "pirq" is
- * just a pointer to the config space. However, something
- * funny is going on with 0xfe/0xff, and apparently they
- * should handle IDE irq routing. Ignore them for now.
+ * just a pointer to the config space.
*/
static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
u8 x;
- switch (pirq) {
- case 0xfe:
- case 0xff:
- return 0;
- default:
- pci_read_config_byte(router, pirq, &x);
- return (x < 16) ? x : 0;
- }
+ pci_read_config_byte(router, pirq, &x);
+ return (x < 16) ? x : 0;
}
static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
- switch (pirq) {
- case 0xfe:
- case 0xff:
- return 0;
- default:
- pci_write_config_byte(router, pirq, irq);
- return 1;
- }
+ pci_write_config_byte(router, pirq, irq);
+ return 1;
}
/*
* The VIA pirq rules are nibble-based, like ALI,
- * but without the ugly irq number munging or the
- * strange special cases..
+ * but without the ugly irq number munging.
*/
static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
@@ -500,8 +457,16 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
}
DBG(" -> newirq=%d", newirq);
- /* Try to get current IRQ */
- if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) {
+ /* Check if it is hardcoded */
+ if ((pirq & 0xf0) == 0xf0) {
+ irq = pirq & 0xf;
+ DBG(" -> hardcoded IRQ %d\n", irq);
+ msg = "Hardcoded";
+ if (dev->irq && dev->irq != irq) {
+ printk("IRQ routing conflict in pirq table! Try 'pci=autoirq'\n");
+ return 0;
+ }
+ } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) {
DBG(" -> got IRQ %d\n", irq);
msg = "Found";
/* We refuse to override the dev->irq information. Give a warning! */
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index ab052e2ff..35f11f20f 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -32,6 +32,7 @@
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/mc146818rtc.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -257,6 +258,8 @@ static inline void kb_wait(void)
*/
void machine_real_restart(unsigned char *code, int length)
{
+ unsigned long flags;
+
cli();
/* Write zero to CMOS register number 0x0f, which the BIOS POST
@@ -266,10 +269,12 @@ void machine_real_restart(unsigned char *code, int length)
disable NMIs by setting the top bit in the CMOS address register,
as we're about to do peculiar things to the CPU. I'm not sure if
`outb_p' is needed instead of just `outb'. Use it to be on the
- safe side. */
+ safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
+ */
- outb_p (0x8f, 0x70);
- outb_p (0x00, 0x71);
+ spin_lock_irqsave(&rtc_lock, flags);
+ CMOS_WRITE(0x00, 0x8f);
+ spin_unlock_irqrestore(&rtc_lock, flags);
/* Remap the kernel at virtual address zero, as well as offset zero
from the kernel segment. This assumes the kernel segment starts at
@@ -379,13 +384,14 @@ void machine_power_off(void)
pm_power_off();
}
+extern void show_trace(unsigned long* esp);
void show_regs(struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
printk("\n");
- printk("EIP: %04x:[<%08lx>]",0xffff & regs->xcs,regs->eip);
+ printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, smp_processor_id());
if (regs->xcs & 3)
printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
printk(" EFLAGS: %08lx\n",regs->eflags);
@@ -407,6 +413,7 @@ void show_regs(struct pt_regs * regs)
".previous \n"
: "=r" (cr4): "0" (0));
printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
+ show_trace(&regs->esp);
}
/*
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index f2077f2f2..158d183b8 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -89,33 +89,18 @@ int kstack_depth_to_print = 24;
/*
* These constants are for searching for possible module text
- * segments. MODULE_RANGE is a guess of how much space is likely
- * to be vmalloced.
+ * segments.
*/
-#define MODULE_RANGE (8*1024*1024)
-void show_stack(unsigned long * esp)
+void show_trace(unsigned long * stack)
{
- unsigned long *stack, addr, module_start, module_end;
int i;
+ unsigned long addr, module_start, module_end;
- // debugging aid: "show_stack(NULL);" prints the
- // back trace for this cpu.
-
- if(esp==NULL)
- esp=(unsigned long*)&esp;
+ if (!stack)
+ stack = (unsigned long*)&stack;
- stack = esp;
- for(i=0; i < kstack_depth_to_print; i++) {
- if (((long) stack & (THREAD_SIZE-1)) == 0)
- break;
- if (i && ((i % 8) == 0))
- printk("\n ");
- printk("%08lx ", *stack++);
- }
-
- printk("\nCall Trace: ");
- stack = esp;
+ printk("Call Trace: ");
i = 1;
module_start = VMALLOC_START;
module_end = VMALLOC_END;
@@ -138,6 +123,30 @@ void show_stack(unsigned long * esp)
i++;
}
}
+ printk("\n");
+}
+
+void show_stack(unsigned long * esp)
+{
+ unsigned long *stack;
+ int i;
+
+ // debugging aid: "show_stack(NULL);" prints the
+ // back trace for this cpu.
+
+ if(esp==NULL)
+ esp=(unsigned long*)&esp;
+
+ stack = esp;
+ for(i=0; i < kstack_depth_to_print; i++) {
+ if (((long) stack & (THREAD_SIZE-1)) == 0)
+ break;
+ if (i && ((i % 8) == 0))
+ printk("\n ");
+ printk("%08lx ", *stack++);
+ }
+ printk("\n");
+ show_trace(esp);
}
static void show_registers(struct pt_regs *regs)
diff --git a/arch/i386/vmlinux.lds b/arch/i386/vmlinux.lds
index da64e9aa3..73dc2a25e 100644
--- a/arch/i386/vmlinux.lds
+++ b/arch/i386/vmlinux.lds
@@ -14,6 +14,9 @@ SECTIONS
*(.gnu.warning)
} = 0x9090
.text.lock : { *(.text.lock) } /* out-of-line lock text */
+
+ _etext = .; /* End of text section */
+
.rodata : { *(.rodata) }
.kstrtab : { *(.kstrtab) }
@@ -26,8 +29,6 @@ SECTIONS
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
- _etext = .; /* End of text section */
-
.data : { /* Data */
*(.data)
CONSTRUCTORS