diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/alpha/config.in | 7 | ||||
-rw-r--r-- | arch/alpha/kernel/alpha_ksyms.c | 4 | ||||
-rw-r--r-- | arch/alpha/kernel/core_cia.c | 6 | ||||
-rw-r--r-- | arch/alpha/kernel/core_mcpcia.c | 1 | ||||
-rw-r--r-- | arch/alpha/kernel/head.S | 81 | ||||
-rw-r--r-- | arch/alpha/kernel/machvec.h | 3 | ||||
-rw-r--r-- | arch/alpha/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/alpha/kernel/proto.h | 2 | ||||
-rw-r--r-- | arch/alpha/kernel/setup.c | 10 | ||||
-rw-r--r-- | arch/alpha/kernel/smp.c | 88 | ||||
-rw-r--r-- | arch/alpha/kernel/sys_dp264.c | 261 | ||||
-rw-r--r-- | arch/alpha/kernel/sys_takara.c | 90 | ||||
-rw-r--r-- | arch/alpha/kernel/time.c | 4 | ||||
-rw-r--r-- | arch/alpha/mm/fault.c | 62 | ||||
-rw-r--r-- | arch/alpha/mm/init.c | 2 |
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"); |