summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-22 23:49:01 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-22 23:49:01 +0000
commitd221c44b7afefd8f77f8595af468dfacb3b21cc2 (patch)
treeef1c7aa4fe157c9f63be777cc6809f292da1f5d5 /arch
parent51d3b7814cdccef9188240fe0cbd8d97ff2c7470 (diff)
Merge with Linux 2.3.8.
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/config.in7
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c4
-rw-r--r--arch/alpha/kernel/core_cia.c6
-rw-r--r--arch/alpha/kernel/core_mcpcia.c1
-rw-r--r--arch/alpha/kernel/head.S81
-rw-r--r--arch/alpha/kernel/machvec.h3
-rw-r--r--arch/alpha/kernel/process.c2
-rw-r--r--arch/alpha/kernel/proto.h2
-rw-r--r--arch/alpha/kernel/setup.c10
-rw-r--r--arch/alpha/kernel/smp.c88
-rw-r--r--arch/alpha/kernel/sys_dp264.c261
-rw-r--r--arch/alpha/kernel/sys_takara.c90
-rw-r--r--arch/alpha/kernel/time.c4
-rw-r--r--arch/alpha/mm/fault.c62
-rw-r--r--arch/alpha/mm/init.c2
15 files changed, 326 insertions, 297 deletions
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index d632cdbb9..4a0da0cbc 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -142,6 +142,7 @@ fi
if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_JENSEN" = "y" \
+ -o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \
-o "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_ALCOR" = "y" \
-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
-o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
@@ -166,7 +167,11 @@ then
define_bool CONFIG_ALPHA_AVANTI y
fi
-bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
+ -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_GENERIC" = "y" ]
+then
+ bool 'Symmetric multi-processing support' CONFIG_SMP
+fi
if [ "$CONFIG_PCI" = "y" ]; then
bool 'PCI quirks' CONFIG_PCI_QUIRKS
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index ce949d722..cba493d09 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -171,8 +171,8 @@ EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL(__global_restore_flags);
#if DEBUG_SPINLOCK
EXPORT_SYMBOL(spin_unlock);
-EXPORT_SYMBOL(spin_lock);
-EXPORT_SYMBOL(spin_trylock);
+EXPORT_SYMBOL(debug_spin_lock);
+EXPORT_SYMBOL(debug_spin_trylock);
#endif
#if DEBUG_RWLOCK
EXPORT_SYMBOL(write_lock);
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index e0f52cb8e..eef315826 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -598,7 +598,7 @@ cia_pci_clr_err(void)
{
CIA_jd = *(vuip)CIA_IOC_CIA_ERR;
DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
- *(vuip)CIA_IOC_CIA_ERR = 0x0180;
+ *(vuip)CIA_IOC_CIA_ERR = CIA_jd;
mb();
return 0;
}
@@ -698,6 +698,10 @@ cia_machine_check(unsigned long vector, unsigned long la_ptr,
reason = buf;
break;
}
+ mb();
+ mb(); /* magic */
+ draina();
+ cia_pci_clr_err();
wrmces(rdmces()); /* reset machine check pending flag */
mb();
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 72d2a62c9..6e24dca07 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -18,7 +18,6 @@
#include <asm/system.h>
#include <asm/pci.h>
#include <asm/hwrpb.h>
-#include <asm/mmu_context.h>
#define __EXTERN_INLINE inline
#include <asm/io.h>
diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S
index 3fcbdbcda..3b004b7f6 100644
--- a/arch/alpha/kernel/head.S
+++ b/arch/alpha/kernel/head.S
@@ -54,87 +54,6 @@ __smp_callin:
.end __smp_callin
#endif /* __SMP__ */
- .align 3
- .globl wrent
- .ent wrent
-wrent:
- .prologue 0
- call_pal PAL_wrent
- ret ($26)
- .end wrent
-
- .align 3
- .globl wrkgp
- .ent wrkgp
-wrkgp:
- .prologue 0
- call_pal PAL_wrkgp
- ret ($26)
- .end wrkgp
-
- .align 3
- .globl wrusp
- .ent wrusp
-wrusp:
- .prologue 0
- call_pal PAL_wrusp
- ret ($26)
- .end wrusp
-
- .align 3
- .globl rdusp
- .ent rdusp
-rdusp:
- .prologue 0
- call_pal PAL_rdusp
- ret ($26)
- .end rdusp
-
- .align 3
- .globl rdmces
- .ent rdmces
-rdmces:
- .prologue 0
- call_pal PAL_rdmces
- ret ($26)
- .end rdmces
-
- .align 3
- .globl wrmces
- .ent wrmces
-wrmces:
- .prologue 0
- call_pal PAL_wrmces
- ret ($26)
- .end wrmces
-
- .align 3
- .globl whami
- .ent whami
-whami:
- .prologue 0
- call_pal PAL_whami
- ret ($26)
- .end whami
-
- .align 3
- .globl wripir
- .ent wripir
-wripir:
- .prologue 0
- call_pal PAL_wripir
- ret ($26)
- .end wripir
-
- .align 3
- .globl wrvptptr
- .ent wrvptptr
-wrvptptr:
- .prologue 0
- call_pal PAL_wrvptptr
- ret ($26)
- .end wrvptptr
-
#
# The following two functions are needed for supporting SRM PALcode
# on the PC164 (at least), since that PALcode manages the interrupt
diff --git a/arch/alpha/kernel/machvec.h b/arch/alpha/kernel/machvec.h
index 8420aaf9c..1e11c046e 100644
--- a/arch/alpha/kernel/machvec.h
+++ b/arch/alpha/kernel/machvec.h
@@ -36,7 +36,6 @@
#define DO_EV4_MMU \
max_asn: EV4_MAX_ASN, \
- mmu_context_mask: ~0UL, \
mv_get_mmu_context: ev4_get_mmu_context, \
mv_flush_tlb_current: ev4_flush_tlb_current, \
mv_flush_tlb_other: ev4_flush_tlb_other, \
@@ -44,7 +43,6 @@
#define DO_EV5_MMU \
max_asn: EV5_MAX_ASN, \
- mmu_context_mask: ~0UL, \
mv_get_mmu_context: ev5_get_mmu_context, \
mv_flush_tlb_current: ev5_flush_tlb_current, \
mv_flush_tlb_other: ev5_flush_tlb_other, \
@@ -52,7 +50,6 @@
#define DO_EV6_MMU \
max_asn: EV6_MAX_ASN, \
- mmu_context_mask: 0xfffffffffful, \
mv_get_mmu_context: ev5_get_mmu_context, \
mv_flush_tlb_current: ev5_flush_tlb_current, \
mv_flush_tlb_other: ev5_flush_tlb_other, \
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 1993ed3b4..ecd4387ae 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -329,7 +329,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->tss.ksp = (unsigned long) childstack;
p->tss.pal_flags = 1; /* set FEN, clear everything else */
p->tss.flags = current->tss.flags;
- p->mm->context = 0;
+ p->tss.mm_context = p->tss.asn = 0;
return 0;
}
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index f7e54a982..8fa1fd7ea 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -180,7 +180,7 @@ extern unsigned long alpha_read_fp_reg (unsigned long reg);
extern void wrmces(unsigned long mces);
extern void cserve_ena(unsigned long);
extern void cserve_dis(unsigned long);
-extern void __smp_callin(void);
+extern void __smp_callin(unsigned long);
/* entry.S */
extern void entArith(void);
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 1c9e5a345..6c13fea3f 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -106,6 +106,7 @@ WEAK(alcor_mv);
WEAK(alphabook1_mv);
WEAK(avanti_mv);
WEAK(cabriolet_mv);
+WEAK(clipper_mv);
WEAK(dp264_mv);
WEAK(eb164_mv);
WEAK(eb64p_mv);
@@ -330,6 +331,10 @@ find_end_memory(void)
/* Round it up to an even number of pages. */
high = (high + PAGE_SIZE) & (PAGE_MASK*2);
+
+ /* Enforce maximum of 2GB even if there is more. Blah. */
+ if (high > 0x80000000UL)
+ high = 0x80000000UL;
return PAGE_OFFSET + high;
}
@@ -448,11 +453,11 @@ get_sysvec(long type, long variation, long cpu)
static struct alpha_machine_vector *tsunami_vecs[] __initlocaldata =
{
NULL,
- &dp264_mv, /* dp164 */
+ &dp264_mv, /* dp264 */
&dp264_mv, /* warhol */
&dp264_mv, /* windjammer */
&monet_mv, /* monet */
- &dp264_mv, /* clipper */
+ &clipper_mv, /* clipper */
&dp264_mv, /* goldrush */
&webbrick_mv, /* webbrick */
&dp264_mv, /* catamaran */
@@ -537,6 +542,7 @@ get_sysvec_byname(const char *name)
&alphabook1_mv,
&avanti_mv,
&cabriolet_mv,
+ &clipper_mv,
&dp264_mv,
&eb164_mv,
&eb64p_mv,
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index f01c0e55d..e97021869 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -95,6 +95,8 @@ static inline void __init
smp_store_cpu_info(int cpuid)
{
cpu_data[cpuid].loops_per_sec = loops_per_sec;
+ cpu_data[cpuid].last_asn
+ = (cpuid << WIDTH_HARDWARE_ASN) + ASN_FIRST_VERSION;
}
/*
@@ -151,8 +153,8 @@ smp_callin(void)
while (!smp_threads_ready)
barrier();
- printk(KERN_INFO "SMP: commencing CPU %d current %p\n",
- cpuid, current);
+ DBGS(("smp_callin: commencing CPU %d current %p\n",
+ cpuid, current));
/* Do nothing. */
cpu_idle(NULL);
@@ -293,9 +295,9 @@ recv_secondary_console_msg(void)
+ hwrpb->processor_offset
+ i * hwrpb->processor_size);
- printk(KERN_INFO "recv_secondary_console_msg: on %d from %d"
- " HALT_REASON 0x%lx FLAGS 0x%lx\n",
- mycpu, i, cpu->halt_reason, cpu->flags);
+ DBGS(("recv_secondary_console_msg: on %d from %d"
+ " HALT_REASON 0x%lx FLAGS 0x%lx\n",
+ mycpu, i, cpu->halt_reason, cpu->flags));
cnt = cpu->ipc_buffer[0] >> 32;
if (cnt <= 0 || cnt >= 80)
@@ -790,6 +792,11 @@ handle_ipi(struct pt_regs *regs)
void
smp_send_reschedule(int cpu)
{
+#if DEBUG_IPI_MSG
+ if (cpu == hard_smp_processor_id())
+ printk(KERN_WARNING
+ "smp_send_reschedule: Sending IPI to self.\n");
+#endif
send_ipi_message(1L << cpu, IPI_RESCHEDULE);
}
@@ -797,6 +804,10 @@ void
smp_send_stop(void)
{
unsigned long to_whom = cpu_present_mask ^ (1L << smp_processor_id());
+#if DEBUG_IPI_MSG
+ if (hard_smp_processor_id() != boot_cpu_id)
+ printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n");
+#endif
send_ipi_message(to_whom, IPI_CPU_STOP);
}
@@ -862,13 +873,13 @@ ipi_flush_tlb_all(void *ignored)
void
flush_tlb_all(void)
{
- tbia();
-
/* Although we don't have any data to pass, we do want to
synchronize with the other processors. */
if (smp_call_function(ipi_flush_tlb_all, NULL, 1, 1)) {
printk(KERN_CRIT "flush_tlb_all: timed out\n");
}
+
+ tbia();
}
static void
@@ -948,43 +959,21 @@ smp_info(char *buffer)
#if DEBUG_SPINLOCK
-
-#ifdef MANAGE_SPINLOCK_IPL
-
-static inline long
-spinlock_raise_ipl(spinlock_t * lock)
-{
- long min_ipl = lock->target_ipl;
- long last_ipl = swpipl(7);
- if (last_ipl < 7 && min_ipl < 7)
- setipl(min_ipl < last_ipl ? last_ipl : min_ipl);
- return last_ipl;
-}
-
-static inline void
-spinlock_restore_ipl(long prev)
-{
- setipl(prev);
-}
-
-#else
-
-#define spinlock_raise_ipl(LOCK) ((void)(LOCK), 0)
-#define spinlock_restore_ipl(PREV) ((void)(PREV))
-
-#endif /* MANAGE_SPINLOCK_IPL */
-
void
spin_unlock(spinlock_t * lock)
{
- long old_ipl = lock->saved_ipl;
mb();
lock->lock = 0;
- spinlock_restore_ipl(old_ipl);
+
+ lock->on_cpu = -1;
+ lock->previous = NULL;
+ lock->task = NULL;
+ lock->base_file = "none";
+ lock->line_no = 0;
}
void
-spin_lock(spinlock_t * lock)
+debug_spin_lock(spinlock_t * lock, const char *base_file, int line_no)
{
long tmp;
long stuck;
@@ -992,7 +981,6 @@ spin_lock(spinlock_t * lock)
unsigned long started = jiffies;
int printed = 0;
int cpu = smp_processor_id();
- long old_ipl = spinlock_raise_ipl(lock);
stuck = 1L << 28;
try_again:
@@ -1020,39 +1008,43 @@ spin_lock(spinlock_t * lock)
if (stuck < 0) {
printk(KERN_WARNING
- "spinlock stuck at %p(%d) owner %s at %p(%d) st %ld\n",
- inline_pc, cpu, lock->task->comm, lock->previous,
- lock->task->processor, lock->task->state);
+ "%s:%d spinlock stuck in %s at %p(%d)"
+ " owner %s at %p(%d) %s:%d\n",
+ base_file, line_no,
+ current->comm, inline_pc, cpu,
+ lock->task->comm, lock->previous,
+ lock->on_cpu, lock->base_file, lock->line_no);
stuck = 1L << 36;
printed = 1;
goto try_again;
}
/* Exiting. Got the lock. */
- lock->saved_ipl = old_ipl;
lock->on_cpu = cpu;
lock->previous = inline_pc;
lock->task = current;
+ lock->base_file = base_file;
+ lock->line_no = line_no;
if (printed) {
- printk(KERN_WARNING "spinlock grabbed at %p(%d) %ld ticks\n",
- inline_pc, cpu, jiffies - started);
+ printk(KERN_WARNING
+ "%s:%d spinlock grabbed in %s at %p(%d) %ld ticks\n",
+ base_file, line_no, current->comm, inline_pc,
+ cpu, jiffies - started);
}
}
int
-spin_trylock(spinlock_t * lock)
+debug_spin_trylock(spinlock_t * lock, const char *base_file, int line_no)
{
- long old_ipl = spinlock_raise_ipl(lock);
int ret;
if ((ret = !test_and_set_bit(0, lock))) {
- mb();
- lock->saved_ipl = old_ipl;
lock->on_cpu = smp_processor_id();
lock->previous = __builtin_return_address(0);
lock->task = current;
} else {
- spinlock_restore_ipl(old_ipl);
+ lock->base_file = base_file;
+ lock->line_no = line_no;
}
return ret;
}
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index c464c37ec..f465b3b4e 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -2,8 +2,8 @@
* linux/arch/alpha/kernel/sys_dp264.c
*
* Copyright (C) 1995 David A Rusling
- * Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1996, 1999 Jay A Estabrook
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the DP264 (EV6+TSUNAMI).
*/
@@ -35,7 +35,7 @@
#define dev2hose(d) (bus2hose[(d)->bus->number]->pci_hose_index)
/*
- * HACK ALERT! only CPU#0 is used currently
+ * HACK ALERT! only the boot cpu is used for interrupts.
*/
static void
@@ -66,34 +66,60 @@ dp264_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
}
static void
+clipper_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+ if (irq >= 16) {
+ volatile unsigned long *csr;
+
+ if (TSUNAMI_bootcpu < 2)
+ if (!TSUNAMI_bootcpu)
+ csr = &TSUNAMI_cchip->dim0.csr;
+ else
+ csr = &TSUNAMI_cchip->dim1.csr;
+ else
+ if (TSUNAMI_bootcpu == 2)
+ csr = &TSUNAMI_cchip->dim2.csr;
+ else
+ csr = &TSUNAMI_cchip->dim3.csr;
+
+ *csr = (~mask >> 16) | (1UL << 55); /* master ISA enable */
+ mb();
+ *csr;
+ }
+ else if (irq >= 8)
+ outb(mask >> 8, 0xA1); /* ISA PIC2 */
+ else
+ outb(mask, 0x21); /* ISA PIC1 */
+}
+
+static void
dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
#if 1
printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
#else
- unsigned long pld;
- unsigned int i;
-
- /* Read the interrupt summary register of TSUNAMI */
- pld = TSUNAMI_cchip->dir0.csr;
-
- /*
- * Now for every possible bit set, work through them and call
- * the appropriate interrupt handler.
- */
- while (pld) {
- i = ffz(~pld);
- pld &= pld - 1; /* clear least bit set */
- if (i == 55) {
- isa_device_interrupt(vector, regs);
- } else { /* if not timer int */
- handle_irq(16 + i, 16 + i, regs);
- }
+ unsigned long pld;
+ unsigned int i;
+
+ /* Read the interrupt summary register of TSUNAMI */
+ pld = TSUNAMI_cchip->dir0.csr;
+
+ /*
+ * Now for every possible bit set, work through them and call
+ * the appropriate interrupt handler.
+ */
+ while (pld) {
+ i = ffz(~pld);
+ pld &= pld - 1; /* clear least bit set */
+ if (i == 55)
+ isa_device_interrupt(vector, regs);
+ else
+ handle_irq(16 + i, 16 + i, regs);
#if 0
TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
tmp = TSUNAMI_cchip->dir0.csr;
#endif
- }
+ }
#endif
}
@@ -104,24 +130,48 @@ dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
ack = irq = (vector - 0x800) >> 4;
- /*
- * The DP264 SRM console reports PCI interrupts with a vector
- * 0x100 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
- * shows up as IRQ 16, etc, etc. We adjust it down by 16 to have
- * it line up with the actual bit numbers from the DIM registers,
- * which is how we manage the interrupts/mask. Sigh...
- */
- if (irq >= 32)
- ack = irq = irq - 16;
+ /*
+ * The SRM console reports PCI interrupts with a vector calculated by:
+ *
+ * 0x900 + (0x10 * DRIR-bit)
+ *
+ * So bit 16 shows up as IRQ 32, etc.
+ *
+ * On DP264/BRICK/MONET, we adjust it down by 16 because at least
+ * that many of the low order bits of the DRIR are not used, and
+ * so we don't count them.
+ */
+ if (irq >= 32)
+ ack = irq = irq - 16;
+
+ handle_irq(irq, ack, regs);
+}
+
+static void
+clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ int irq, ack;
+
+ ack = irq = (vector - 0x800) >> 4;
+ /*
+ * The SRM console reports PCI interrupts with a vector calculated by:
+ *
+ * 0x900 + (0x10 * DRIR-bit)
+ *
+ * So bit 16 shows up as IRQ 32, etc.
+ *
+ * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need
+ * to scale down the vector reported, we just use it.
+ *
+ * Eg IRQ 24 is DRIR bit 8, etc, etc
+ */
handle_irq(irq, ack, regs);
}
static void __init
dp264_init_irq(void)
{
- volatile unsigned long *csr;
-
outb(0, DMA1_RESET_REG);
outb(0, DMA2_RESET_REG);
outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
@@ -130,23 +180,26 @@ dp264_init_irq(void)
if (alpha_using_srm)
alpha_mv.device_interrupt = dp264_srm_device_interrupt;
- if (TSUNAMI_bootcpu < 2)
- if (!TSUNAMI_bootcpu)
- csr = &TSUNAMI_cchip->dim0.csr;
- else
- csr = &TSUNAMI_cchip->dim1.csr;
- else
- if (TSUNAMI_bootcpu == 2)
- csr = &TSUNAMI_cchip->dim2.csr;
- else
- csr = &TSUNAMI_cchip->dim3.csr;
-
- /* Note invert on MASK bits. */
- *csr = ~(alpha_irq_mask);
- mb();
- *csr;
+ dp264_update_irq_hw(16, alpha_irq_mask, 0);
- enable_irq(55); /* Enable CYPRESS interrupt controller (ISA). */
+ enable_irq(55); /* Enable ISA interrupt controller. */
+ enable_irq(2);
+}
+
+static void __init
+clipper_init_irq(void)
+{
+ outb(0, DMA1_RESET_REG);
+ outb(0, DMA2_RESET_REG);
+ outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+ outb(0, DMA2_MASK_REG);
+
+ if (alpha_using_srm)
+ alpha_mv.device_interrupt = clipper_srm_device_interrupt;
+
+ clipper_update_irq_hw(16, alpha_irq_mask, 0);
+
+ enable_irq(55); /* Enable ISA interrupt controller. */
enable_irq(2);
}
@@ -221,7 +274,7 @@ dp264_map_irq(struct pci_dev *dev, int slot, int pin)
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
int irq = COMMON_TABLE_LOOKUP;
- if (irq >= 0)
+ if (irq > 0)
irq += 16 * dev2hose(dev);
return irq;
@@ -250,42 +303,38 @@ monet_map_irq(struct pci_dev *dev, int slot, int pin)
{ 32, 32, 33, 34, 35}, /* IdSel 13 slot 3 PCI0*/
{ 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/
{ 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/
-};
+ };
const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
- int irq = COMMON_TABLE_LOOKUP;
-
- return irq;
+ return COMMON_TABLE_LOOKUP;
}
static int __init
monet_swizzle(struct pci_dev *dev, int *pinp)
{
- int slot, pin = *pinp;
-
- /* Check first for the built-in bridge on hose 1. */
- if (dev2hose(dev) == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
- slot = PCI_SLOT(dev->devfn);
- }
- else
- {
- /* Must be a card-based bridge. */
- do {
+ int slot, pin = *pinp;
+
+ /* Check first for the built-in bridge on hose 1. */
+ if (dev2hose(dev) == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
+ slot = PCI_SLOT(dev->devfn);
+ } else {
+ /* Must be a card-based bridge. */
+ do {
/* Check for built-in bridge on hose 1. */
- if (dev2hose(dev) == 1 &&
+ if (dev2hose(dev) == 1 &&
PCI_SLOT(dev->bus->self->devfn) == 8) {
slot = PCI_SLOT(dev->devfn);
break;
- }
- pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
-
- /* Move up the chain of bridges. */
- dev = dev->bus->self;
- /* Slot of the next bridge. */
- slot = PCI_SLOT(dev->devfn);
- } while (dev->bus->self);
- }
- *pinp = pin;
- return slot;
+ }
+ pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
+
+ /* Move up the chain of bridges. */
+ dev = dev->bus->self;
+ /* Slot of the next bridge. */
+ slot = PCI_SLOT(dev->devfn);
+ } while (dev->bus->self);
+ }
+ *pinp = pin;
+ return slot;
}
static int __init
@@ -300,14 +349,34 @@ webbrick_map_irq(struct pci_dev *dev, int slot, int pin)
{ 30, 30, 30, 30, 30}, /* IdSel 11 21143 #2 */
{ -1, -1, -1, -1, -1}, /* IdSel 12 unused */
{ -1, -1, -1, -1, -1}, /* IdSel 13 unused */
- { 47, 47, 46, 45, 44}, /* IdSel 14 slot 0 */
+ { 35, 35, 34, 33, 32}, /* IdSel 14 slot 0 */
{ 39, 39, 38, 37, 36}, /* IdSel 15 slot 1 */
{ 43, 43, 42, 41, 40}, /* IdSel 16 slot 2 */
- { 35, 35, 34, 33, 32}, /* IdSel 17 slot 3 */
-};
+ { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */
+ };
const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
+ return COMMON_TABLE_LOOKUP;
+}
+
+static int __init
+clipper_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+ static char irq_tab[7][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
+ { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */
+ { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */
+ { 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */
+ { 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */
+ { 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */
+ { 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */
+ { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */
+ };
+ const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
int irq = COMMON_TABLE_LOOKUP;
+ if (irq > 0)
+ irq += 16 * dev2hose(dev);
+
return irq;
}
@@ -336,6 +405,13 @@ webbrick_pci_fixup(void)
SMC669_Init(0);
}
+static void __init
+clipper_pci_fixup(void)
+{
+ layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+ common_pci_fixup(clipper_map_irq, common_swizzle);
+}
+
/*
* The System Vectors
@@ -407,5 +483,28 @@ struct alpha_machine_vector webbrick_mv __initmv = {
pci_fixup: webbrick_pci_fixup,
kill_arch: generic_kill_arch,
};
-/* No alpha_mv alias for webbrick, since we compile it in unconditionally
- with DP264; setup_arch knows how to cope. */
+
+struct alpha_machine_vector clipper_mv __initmv = {
+ vector_name: "Clipper",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_TSUNAMI_IO,
+ DO_TSUNAMI_BUS,
+ machine_check: tsunami_machine_check,
+ max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+
+ nr_irqs: 64,
+ irq_probe_mask: _PROBE_MASK(64),
+ update_irq_hw: clipper_update_irq_hw,
+ ack_irq: generic_ack_irq,
+ device_interrupt: dp264_device_interrupt,
+
+ init_arch: tsunami_init_arch,
+ init_irq: clipper_init_irq,
+ init_pit: generic_init_pit,
+ pci_fixup: clipper_pci_fixup,
+ kill_arch: generic_kill_arch,
+};
+
+/* No alpha_mv alias for webbrick/monet/clipper, since we compile them
+ in unconditionally with DP264; setup_arch knows how to cope. */
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index 95adc3b39..c554a9fa1 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the TAKARA.
*/
@@ -30,11 +30,21 @@
#include "machvec.h"
-/*
- * WARNING WARNING WARNING
- *
- * This port is missing an update_irq_hw implementation.
- */
+static void
+takara_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+ unsigned int regaddr;
+
+ if (irq <= 15) {
+ if (irq <= 7)
+ outb(mask, 0x21); /* ISA PIC1 */
+ else
+ outb(mask >> 8, 0xA1); /* ISA PIC2 */
+ } else if (irq <= 31) {
+ regaddr = 0x510 + ((irq - 16) & 0x0c);
+ outl((mask >> ((irq - 16) & 0x0c)) & 0xf0000Ul, regaddr);
+ }
+}
static void
takara_device_interrupt(unsigned long vector, struct pt_regs *regs)
@@ -68,28 +78,45 @@ takara_device_interrupt(unsigned long vector, struct pt_regs *regs)
if (intstatus & 4) handle_irq(16+2, 16+2, regs);
if (intstatus & 2) handle_irq(16+1, 16+1, regs);
if (intstatus & 1) handle_irq(16+0, 16+0, regs);
- } else
+ } else {
isa_device_interrupt (vector, regs);
+ }
+}
+
+static void
+takara_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ int irq = (vector - 0x800) >> 4;
+
+ if (irq > 15)
+ irq = ((vector - 0x800) >> 6) + 12;
+
+ handle_irq(irq, irq, regs);
}
static void __init
takara_init_irq(void)
{
- unsigned int ctlreg;
-
STANDARD_INIT_IRQ_PROLOG;
- ctlreg = inl(0x500);
- ctlreg &= ~0x8000; /* return to non-accelerated mode */
- outw(ctlreg >> 16, 0x502);
- outw(ctlreg & 0xFFFF, 0x500);
- ctlreg = 0x05107c00; /* enable the PCI interrupt register */
- outw(ctlreg >> 16, 0x502);
- outw(ctlreg & 0xFFFF, 0x500);
+ if (alpha_using_srm)
+ alpha_mv.device_interrupt = takara_srm_device_interrupt;
+
+ if (!alpha_using_srm) {
+ unsigned int ctlreg = inl(0x500);
+
+ /* Return to non-accelerated mode. */
+ ctlreg &= ~0x8000;
+ outl(ctlreg, 0x500);
+
+ /* Enable the PCI interrupt register. */
+ ctlreg = 0x05107c00;
+ outl(ctlreg, 0x500);
+ }
+
enable_irq(2);
}
-
/*
* The Takara has PCI devices 1, 2, and 3 configured to slots 20,
* 19, and 18 respectively, in the default configuration. They can
@@ -123,12 +150,35 @@ takara_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
+static int __init
+takara_swizzle(struct pci_dev *dev, int *pinp)
+{
+ int slot = PCI_SLOT(dev->devfn);
+ int pin = *pinp;
+ unsigned int ctlreg = inl(0x500);
+ unsigned int busslot = PCI_SLOT(dev->bus->self->devfn);
+
+ /* Check first for built-in bridges. */
+ if (busslot > 16 && ((1<<(36-busslot)) & ctlreg)) {
+ if (pin == 1)
+ pin += (20 - busslot);
+ else {
+ /* Must be a card-based bridge. */
+ printk(KERN_WARNING "takara_swizzle: cannot handle "
+ "card-bridge behind builtin bridge yet.\n");
+ }
+ }
+
+ *pinp = pin;
+ return slot;
+}
+
static void __init
takara_pci_fixup(void)
{
layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(takara_map_irq, common_swizzle);
- enable_ide(0x26e);
+ common_pci_fixup(takara_map_irq, takara_swizzle);
+ /* enable_ide(0x26e); */
}
@@ -147,7 +197,7 @@ struct alpha_machine_vector takara_mv __initmv = {
nr_irqs: 20,
irq_probe_mask: _PROBE_MASK(20),
- update_irq_hw: NULL,
+ update_irq_hw: takara_update_irq_hw,
ack_irq: generic_ack_irq,
device_interrupt: takara_device_interrupt,
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 927ca201f..e7f32dc9a 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -1,7 +1,7 @@
/*
* linux/arch/alpha/kernel/time.c
*
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ * Copyright (C) 1991, 1992, 1995, 1999 Linus Torvalds
*
* This file contains the PC-specific time handling details:
* reading the RTC at bootup, etc..
@@ -43,7 +43,7 @@
#include "irq.h"
extern rwlock_t xtime_lock;
-extern volatile unsigned long lost_ticks; /*kernel/sched.c*/
+extern volatile unsigned long lost_ticks; /* kernel/sched.c */
static int set_rtc_mmss(unsigned long);
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index e991fdf83..5cf6e4ab0 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <asm/io.h>
#define __EXTERN_INLINE inline
#include <asm/mmu_context.h>
@@ -28,66 +29,23 @@
extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *);
-#ifdef __SMP__
-unsigned long last_asn[NR_CPUS] = { /* gag */
- ASN_FIRST_VERSION + (0 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (1 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (2 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (3 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (4 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (5 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (6 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (7 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (8 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (9 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (10 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (11 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (12 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (13 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (14 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (15 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (16 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (17 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (18 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (19 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (20 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (21 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (22 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (23 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (24 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (25 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (26 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (27 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (28 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (29 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (30 << WIDTH_HARDWARE_ASN),
- ASN_FIRST_VERSION + (31 << WIDTH_HARDWARE_ASN)
-};
-#else
-unsigned long asn_cache = ASN_FIRST_VERSION;
-#endif /* __SMP__ */
-
/*
- * Select a new ASN for a task.
+ * Force a new ASN for a task.
*/
+#ifndef __SMP__
+unsigned long last_asn = ASN_FIRST_VERSION;
+#endif
+
void
get_new_mmu_context(struct task_struct *p, struct mm_struct *mm)
{
- unsigned long asn = asn_cache;
-
- if ((asn & HARDWARE_ASN_MASK) < MAX_ASN)
- ++asn;
- else {
- tbiap();
- imb();
- asn = (asn & ~HARDWARE_ASN_MASK) + ASN_FIRST_VERSION;
- }
- asn_cache = asn;
- mm->context = asn; /* full version + asn */
- p->tss.asn = asn & HARDWARE_ASN_MASK; /* just asn */
+ unsigned long new = __get_new_mmu_context(p, mm);
+ p->tss.mm_context = new;
+ p->tss.asn = new & HARDWARE_ASN_MASK;
}
+
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to handle_mm_fault().
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 43d21186b..7b70d4a4e 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -174,7 +174,7 @@ show_mem(void)
extern unsigned long free_area_init(unsigned long, unsigned long);
-static struct thread_struct *
+static inline struct thread_struct *
load_PCB(struct thread_struct * pcb)
{
register unsigned long sp __asm__("$30");